master-settings.c revision 27cd7a142ed0bb77cb87294d475c73250c84affe
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "common.h"
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen#include "array.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "env-util.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "istream.h"
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mkdir-parents.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "safe-mkdir.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "settings-parser.h"
463e82bdf0e990f4f2252d2b53ea23a5abe5883cTimo Sirainen#include "master-settings.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen#include <stddef.h>
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen#include <dirent.h>
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen#include <unistd.h>
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen#include <sys/stat.h>
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#include <sys/wait.h>
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainenstatic bool master_settings_verify(void *_set, pool_t pool,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen const char **error_r);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainenextern struct setting_parser_info service_setting_parser_info;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#undef DEF
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#define DEF(type, name) \
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen { type, #name, offsetof(struct file_listener_settings, name), NULL }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic struct setting_define file_listener_setting_defines[] = {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen DEF(SET_STR, path),
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen DEF(SET_UINT, mode),
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen DEF(SET_STR, user),
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen DEF(SET_STR, group),
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen SETTING_DEFINE_LIST_END
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen};
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainenstatic struct file_listener_settings file_listener_default_settings = {
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen MEMBER(path) "",
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen MEMBER(mode) 0600,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen MEMBER(user) "",
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen MEMBER(group) "",
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen};
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainenstatic struct setting_parser_info file_listener_setting_parser_info = {
c21c33a8c98972c45349066fc76ac9e2c05013c1Timo Sirainen MEMBER(defines) file_listener_setting_defines,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen MEMBER(defaults) &file_listener_default_settings,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
7bd3f5614e0dd2324dd1015f084de72c0b069a1aTimo Sirainen MEMBER(parent) &service_setting_parser_info,
7bd3f5614e0dd2324dd1015f084de72c0b069a1aTimo Sirainen MEMBER(parent_offset) (size_t)-1,
7bd3f5614e0dd2324dd1015f084de72c0b069a1aTimo Sirainen MEMBER(type_offset) (size_t)-1,
7bd3f5614e0dd2324dd1015f084de72c0b069a1aTimo Sirainen MEMBER(struct_size) sizeof(struct file_listener_settings)
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen};
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#undef DEF
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#define DEF(type, name) \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen { type, #name, offsetof(struct inet_listener_settings, name), NULL }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenstatic struct setting_define inet_listener_setting_defines[] = {
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen DEF(SET_STR, address),
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen DEF(SET_UINT, port),
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen DEF(SET_BOOL, ssl),
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen SETTING_DEFINE_LIST_END
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen};
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainenstatic struct inet_listener_settings inet_listener_default_settings = {
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen MEMBER(address) "*",
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen MEMBER(port) 0,
7de1c472fd23ddac6b4dc5cbeee6fa6a8418b071Timo Sirainen MEMBER(ssl) FALSE
7de1c472fd23ddac6b4dc5cbeee6fa6a8418b071Timo Sirainen};
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
538c58fc95200fcc5e91abdda8b912b574a2f968Timo Sirainenstatic struct setting_parser_info inet_listener_setting_parser_info = {
b99f3f908d51f4d1f7628bdf2cc6100cd8587656Timo Sirainen MEMBER(defines) inet_listener_setting_defines,
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen MEMBER(defaults) &inet_listener_default_settings,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen MEMBER(parent) &service_setting_parser_info,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen MEMBER(parent_offset) (size_t)-1,
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen MEMBER(type_offset) (size_t)-1,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen MEMBER(struct_size) sizeof(struct inet_listener_settings)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen};
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen#undef DEF
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen#undef DEFLIST
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen#define DEF(type, name) \
7de1c472fd23ddac6b4dc5cbeee6fa6a8418b071Timo Sirainen { type, #name, offsetof(struct service_settings, name), NULL }
b99f3f908d51f4d1f7628bdf2cc6100cd8587656Timo Sirainen#define DEFLIST(field, name, defines) \
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen { SET_DEFLIST, name, offsetof(struct service_settings, field), defines }
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic struct setting_define service_setting_defines[] = {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen DEF(SET_STR, name),
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen DEF(SET_STR, protocol),
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen DEF(SET_STR, type),
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen DEF(SET_STR, executable),
7de1c472fd23ddac6b4dc5cbeee6fa6a8418b071Timo Sirainen DEF(SET_STR, user),
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen DEF(SET_STR, group),
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen DEF(SET_STR, privileged_group),
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen DEF(SET_STR, extra_groups),
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen DEF(SET_STR, chroot),
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen DEF(SET_STR, auth_dest_service),
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen DEF(SET_BOOL, drop_priv_before_exec),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_UINT, process_min_avail),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_UINT, process_limit),
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen DEF(SET_UINT, client_limit),
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen DEF(SET_UINT, service_count),
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen DEF(SET_UINT, vsz_limit),
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen DEFLIST(unix_listeners, "unix_listener",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen &file_listener_setting_parser_info),
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen DEFLIST(fifo_listeners, "fifo_listener",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen &file_listener_setting_parser_info),
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen DEFLIST(inet_listeners, "inet_listener",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen &inet_listener_setting_parser_info),
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen SETTING_DEFINE_LIST_END
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen};
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenstatic struct service_settings service_default_settings = {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(master_set) NULL,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(name) "",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(protocol) "",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(type) "",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(executable) "",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(user) "",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(group) "",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(privileged_group) "",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(extra_groups) "",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(chroot) "",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(auth_dest_service) "",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(drop_priv_before_exec) FALSE,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(process_min_avail) 0,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(process_limit) (unsigned int)-1,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(client_limit) 0,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(service_count) 0,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(vsz_limit) 256,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen MEMBER(unix_listeners) ARRAY_INIT,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(fifo_listeners) ARRAY_INIT,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(inet_listeners) ARRAY_INIT
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen};
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainenstruct setting_parser_info service_setting_parser_info = {
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen MEMBER(defines) service_setting_defines,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen MEMBER(defaults) &service_default_settings,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen MEMBER(parent) &master_setting_parser_info,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen MEMBER(dynamic_parsers) NULL,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen MEMBER(parent_offset) offsetof(struct service_settings, master_set),
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen MEMBER(type_offset) offsetof(struct service_settings, name),
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen MEMBER(struct_size) sizeof(struct service_settings)
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen};
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen#undef DEF
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen#undef DEFLIST
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen#define DEF(type, name) \
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen { type, #name, offsetof(struct master_settings, name), NULL }
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen#define DEFLIST(field, name, defines) \
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen { SET_DEFLIST, name, offsetof(struct master_settings, field), defines }
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic struct setting_define master_setting_defines[] = {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen DEF(SET_STR, base_dir),
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen DEF(SET_STR, libexec_dir),
b9ec0443d7d8afebfe61c17a9d692d6fad30c276Timo Sirainen DEF(SET_STR, protocols),
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen DEF(SET_ENUM, ssl),
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen DEF(SET_UINT, default_process_limit),
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen DEF(SET_UINT, default_client_limit),
b9ec0443d7d8afebfe61c17a9d692d6fad30c276Timo Sirainen
23079bf0a6e7489c5f542b0b897a71bdfd884a51Timo Sirainen DEF(SET_BOOL, version_ignore),
23079bf0a6e7489c5f542b0b897a71bdfd884a51Timo Sirainen DEF(SET_BOOL, mail_debug),
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen DEF(SET_BOOL, auth_debug),
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen DEF(SET_UINT, first_valid_uid),
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen DEF(SET_UINT, last_valid_uid),
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen DEF(SET_UINT, first_valid_gid),
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen DEF(SET_UINT, last_valid_gid),
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen DEFLIST(services, "service", &service_setting_parser_info),
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen SETTING_DEFINE_LIST_END
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainenstatic struct master_settings master_default_settings = {
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen MEMBER(base_dir) PKG_RUNDIR,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen MEMBER(libexec_dir) PKG_LIBEXECDIR,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen MEMBER(protocols) "imap pop3 lmtp",
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen MEMBER(ssl) "yes:no:required",
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen MEMBER(default_process_limit) 100,
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen MEMBER(default_client_limit) 1000,
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen MEMBER(version_ignore) FALSE,
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen MEMBER(mail_debug) FALSE,
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen MEMBER(auth_debug) FALSE,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(first_valid_uid) 500,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(last_valid_uid) 0,
31050c3df6cbe403e8ced8ef11b5c4e12124d354Timo Sirainen MEMBER(first_valid_gid) 1,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen MEMBER(last_valid_gid) 0,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(services) ARRAY_INIT
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
68b3667c9ee95951d7c3e03b19b2d37abbaa5736Timo Sirainenstruct setting_parser_info master_setting_parser_info = {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen MEMBER(defines) master_setting_defines,
e20e638805c4bd54e039891a3e92760b1dfa189aTimo Sirainen MEMBER(defaults) &master_default_settings,
68b3667c9ee95951d7c3e03b19b2d37abbaa5736Timo Sirainen
1df526903ed039e8ff966a223c43b8d04eddf3c7Phil Carmody MEMBER(parent) NULL,
31050c3df6cbe403e8ced8ef11b5c4e12124d354Timo Sirainen MEMBER(parent_offset) (size_t)-1,
31050c3df6cbe403e8ced8ef11b5c4e12124d354Timo Sirainen MEMBER(type_offset) (size_t)-1,
31050c3df6cbe403e8ced8ef11b5c4e12124d354Timo Sirainen MEMBER(struct_size) sizeof(struct master_settings),
31050c3df6cbe403e8ced8ef11b5c4e12124d354Timo Sirainen MEMBER(check_func) master_settings_verify
68b3667c9ee95951d7c3e03b19b2d37abbaa5736Timo Sirainen};
31050c3df6cbe403e8ced8ef11b5c4e12124d354Timo Sirainen
31050c3df6cbe403e8ced8ef11b5c4e12124d354Timo Sirainen/* <settings checks> */
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainenstatic void fix_file_listener_paths(ARRAY_TYPE(file_listener_settings) *l,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen pool_t pool, const char *base_dir)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct file_listener_settings *const *sets;
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody unsigned int i, count;
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody if (!array_is_created(l))
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody return;
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody sets = array_get(l, &count);
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody for (i = 0; i < count; i++) {
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody if (*sets[i]->path != '/') {
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody sets[i]->path = p_strconcat(pool, base_dir, "/",
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody sets[i]->path, NULL);
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody }
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody }
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody}
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmody
b32de04eb77234b25e2e411884a2503a1bf3c255Phil Carmodystatic bool
dfdd228ab20092705da0e8812b3cd0a039319375Timo Sirainenmaster_settings_verify(void *_set, pool_t pool, const char **error_r)
dfdd228ab20092705da0e8812b3cd0a039319375Timo Sirainen{
dfdd228ab20092705da0e8812b3cd0a039319375Timo Sirainen struct master_settings *set = _set;
070df93a3014ad4b2eb8754af65128c9f9a72e4ePhil Carmody struct service_settings *const *services;
dfdd228ab20092705da0e8812b3cd0a039319375Timo Sirainen unsigned int i, j, count;
dfdd228ab20092705da0e8812b3cd0a039319375Timo Sirainen
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody if (set->last_valid_uid != 0 &&
dfdd228ab20092705da0e8812b3cd0a039319375Timo Sirainen set->first_valid_uid > set->last_valid_uid) {
458b283a2f3db6e5aff20b4df1bbd18ada3900ddTimo Sirainen *error_r = "first_valid_uid can't be larger than last_valid_uid";
458b283a2f3db6e5aff20b4df1bbd18ada3900ddTimo Sirainen return FALSE;
458b283a2f3db6e5aff20b4df1bbd18ada3900ddTimo Sirainen }
458b283a2f3db6e5aff20b4df1bbd18ada3900ddTimo Sirainen if (set->last_valid_gid != 0 &&
070df93a3014ad4b2eb8754af65128c9f9a72e4ePhil Carmody set->first_valid_gid > set->last_valid_gid) {
070df93a3014ad4b2eb8754af65128c9f9a72e4ePhil Carmody *error_r = "first_valid_gid can't be larger than last_valid_gid";
74896b89e1d82819d710f9322cf7c9e72d5841adPhil Carmody return FALSE;
74896b89e1d82819d710f9322cf7c9e72d5841adPhil Carmody }
74896b89e1d82819d710f9322cf7c9e72d5841adPhil Carmody
74896b89e1d82819d710f9322cf7c9e72d5841adPhil Carmody /* check that we have at least one service. the actual service
74896b89e1d82819d710f9322cf7c9e72d5841adPhil Carmody structure validity is checked later while creating them. */
74896b89e1d82819d710f9322cf7c9e72d5841adPhil Carmody if (!array_is_created(&set->services) ||
74896b89e1d82819d710f9322cf7c9e72d5841adPhil Carmody array_count(&set->services) == 0) {
74896b89e1d82819d710f9322cf7c9e72d5841adPhil Carmody *error_r = "No services defined";
4e6629cb5d5e7f67d5023eda540105d32df5f2baPhil Carmody return FALSE;
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody }
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody services = array_get(&set->services, &count);
aba9cc9bf97576c0ca653d4e218567e617061029Phil Carmody for (i = 0; i < count; i++) {
aba9cc9bf97576c0ca653d4e218567e617061029Phil Carmody struct service_settings *service = services[i];
aba9cc9bf97576c0ca653d4e218567e617061029Phil Carmody
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody if (*service->name == '\0') {
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody *error_r = t_strdup_printf(
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody "Service #%d is missing name", i);
4e6629cb5d5e7f67d5023eda540105d32df5f2baPhil Carmody return FALSE;
4e6629cb5d5e7f67d5023eda540105d32df5f2baPhil Carmody }
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody if (*service->type != '\0' &&
1df526903ed039e8ff966a223c43b8d04eddf3c7Phil Carmody strcmp(service->type, "log") != 0 &&
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody strcmp(service->type, "config") != 0 &&
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody strcmp(service->type, "anvil") != 0 &&
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody strcmp(service->type, "auth") != 0 &&
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody strcmp(service->type, "auth-source") != 0) {
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody *error_r = t_strconcat("Unknown service type: ",
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody service->type, NULL);
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody return FALSE;
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody }
1df526903ed039e8ff966a223c43b8d04eddf3c7Phil Carmody for (j = 0; j < i; j++) {
1df526903ed039e8ff966a223c43b8d04eddf3c7Phil Carmody if (strcmp(service->name, services[j]->name) == 0) {
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody *error_r = t_strdup_printf(
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody "Duplicate service name: %s",
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody service->name);
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody return FALSE;
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody }
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody }
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody }
4e6629cb5d5e7f67d5023eda540105d32df5f2baPhil Carmody for (i = 0; i < count; i++) {
89b7d6ce9266288c156e3513f5798680f1e33572Phil Carmody struct service_settings *service = services[i];
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody if (*service->executable != '/') {
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody service->executable =
1df526903ed039e8ff966a223c43b8d04eddf3c7Phil Carmody p_strconcat(pool, set->libexec_dir, "/",
1df526903ed039e8ff966a223c43b8d04eddf3c7Phil Carmody service->executable, NULL);
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody }
53e0e6889bf659b86e4c7d2e83e27d69fd9d6bcbPhil Carmody if (*service->chroot != '/' && *service->chroot != '\0') {
dfdd228ab20092705da0e8812b3cd0a039319375Timo Sirainen service->chroot =
dfdd228ab20092705da0e8812b3cd0a039319375Timo Sirainen p_strconcat(pool, set->base_dir, "/",
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen service->chroot, NULL);
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen }
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen if (service->drop_priv_before_exec &&
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen *service->chroot != '\0') {
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen *error_r = t_strdup_printf("service(%s): "
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen "drop_priv_before_exec=yes can't be "
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen "used with chroot", service->name);
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen return FALSE;
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen }
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen if (service->process_min_avail > service->process_limit) {
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen *error_r = t_strdup_printf("service(%s): "
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen "process_min_avail is higher than process_limit",
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen service->name);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen return FALSE;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen }
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen fix_file_listener_paths(&service->unix_listeners,
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen pool, set->base_dir);
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainen fix_file_listener_paths(&service->fifo_listeners,
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainen pool, set->base_dir);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen }
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen set->protocols_split = p_strsplit(pool, set->protocols, " ");
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen return TRUE;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen}
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainen/* </settings checks> */
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainen
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainenstatic bool
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainenlogin_want_core_dumps(const struct master_settings *set, gid_t *gid_r)
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainen{
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen struct service_settings *const *services;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen unsigned int i, count;
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainen const char *error;
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainen bool cores = FALSE;
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainen uid_t uid;
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainen
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen *gid_r = (gid_t)-1;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen services = array_get(&set->services, &count);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen for (i = 0; i < count; i++) {
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen if (strcmp(services[i]->type, "auth-source") == 0 &&
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen strstr(services[i]->name, "-login") != NULL) {
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen if (strstr(services[i]->executable, " -D") != NULL)
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen cores = TRUE;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen (void)get_uidgid(services[i]->user, &uid, gid_r, &error);
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen if (*services[i]->group != '\0')
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen (void)get_gid(services[i]->group, gid_r, &error);
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen }
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen }
2b170a01b7e966c584fc7573034180d75b321d0dTimo Sirainen return cores;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen}
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainenstatic bool
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainensettings_have_auth_unix_listeners_in(const struct master_settings *set,
4b89231f4ec9cc69f4aea715e1d34f405c7e317dTimo Sirainen const char *dir)
4b89231f4ec9cc69f4aea715e1d34f405c7e317dTimo Sirainen{
4b89231f4ec9cc69f4aea715e1d34f405c7e317dTimo Sirainen struct service_settings *const *services;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen struct file_listener_settings *const *u;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen unsigned int i, j, count, count2;
76959d3d6fed45d5f5e1397fcdcf09a5adb87f24Timo Sirainen
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen services = array_get(&set->services, &count);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen for (i = 0; i < count; i++) {
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen if (strcmp(services[i]->type, "auth") == 0 &&
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen array_is_created(&services[i]->unix_listeners)) {
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen u = array_get(&services[i]->unix_listeners, &count2);
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen for (j = 0; j < count2; j++) {
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen if (strncmp(u[j]->path, dir, strlen(dir)) == 0)
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen return TRUE;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen }
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen }
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen }
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen return FALSE;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen}
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainenstatic void unlink_sockets(const char *path, const char *prefix)
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen{
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen DIR *dirp;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen struct dirent *dp;
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen struct stat st;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen string_t *str;
1032e5427bf10566098f3b3bb9110e2bc1227e85Timo Sirainen unsigned int prefix_len;
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen dirp = opendir(path);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen if (dirp == NULL) {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen i_error("opendir(%s) failed: %m", path);
9887c39c5ba429169389153ca99de49e084a73f0Timo Sirainen return;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen prefix_len = strlen(prefix);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen str = t_str_new(256);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen while ((dp = readdir(dirp)) != NULL) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (dp->d_name[0] == '.')
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen continue;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
b99f3f908d51f4d1f7628bdf2cc6100cd8587656Timo Sirainen if (strncmp(dp->d_name, prefix, prefix_len) != 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen continue;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen str_truncate(str, 0);
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen str_printfa(str, "%s/%s", path, dp->d_name);
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen if (lstat(str_c(str), &st) < 0) {
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen if (errno != ENOENT)
1032e5427bf10566098f3b3bb9110e2bc1227e85Timo Sirainen i_error("lstat(%s) failed: %m", str_c(str));
1032e5427bf10566098f3b3bb9110e2bc1227e85Timo Sirainen continue;
1032e5427bf10566098f3b3bb9110e2bc1227e85Timo Sirainen }
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen if (!S_ISSOCK(st.st_mode))
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen continue;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen /* try to avoid unlinking sockets if someone's already
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen listening in them. do this only at startup, because
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen when SIGHUPing a child process might catch the new
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen connection before it notices that it's supposed
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen to die. null_fd == -1 check is a bit kludgy, but works.. */
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen if (null_fd == -1) {
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen int fd = net_connect_unix(str_c(str));
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen if (fd != -1 || errno != ECONNREFUSED) {
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen i_fatal("Dovecot is already running? "
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen "Socket already exists: %s",
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen str_c(str));
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
41bb0aa8e357876bc9a1916a37c9e3e78e5f8185Timo Sirainen if (unlink(str_c(str)) < 0 && errno != ENOENT)
945565e0c9cf979b5feeba6fbd4efce3bf4484adTimo Sirainen i_error("unlink(%s) failed: %m", str_c(str));
945565e0c9cf979b5feeba6fbd4efce3bf4484adTimo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen (void)closedir(dirp);
dd8de60250511cc729b67249e61dfc6b4debff11Timo Sirainen}
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen
b9ec0443d7d8afebfe61c17a9d692d6fad30c276Timo Sirainenbool master_settings_do_fixes(const struct master_settings *set)
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *login_dir, *empty_dir;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct stat st;
20b9283d4af31e45e588014da427fb2dbcd3227aTimo Sirainen gid_t gid;
20b9283d4af31e45e588014da427fb2dbcd3227aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* since base dir is under /var/run by default, it may have been
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen deleted. */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (mkdir_parents(set->base_dir, 0777) < 0 && errno != EEXIST) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("mkdir(%s) failed: %m", set->base_dir);
be8c8479f918875eda871c5685ab2b4067228e26Phil Carmody return FALSE;
20b9283d4af31e45e588014da427fb2dbcd3227aTimo Sirainen }
20b9283d4af31e45e588014da427fb2dbcd3227aTimo Sirainen /* allow base_dir to be a symlink, so don't use lstat() */
20b9283d4af31e45e588014da427fb2dbcd3227aTimo Sirainen if (stat(set->base_dir, &st) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("stat(%s) failed: %m", set->base_dir);
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen return FALSE;
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen }
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen if (!S_ISDIR(st.st_mode)) {
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen i_error("%s is not a directory", set->base_dir);
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen return FALSE;
41bb0aa8e357876bc9a1916a37c9e3e78e5f8185Timo Sirainen }
945565e0c9cf979b5feeba6fbd4efce3bf4484adTimo Sirainen
945565e0c9cf979b5feeba6fbd4efce3bf4484adTimo Sirainen /* Make sure our permanent state directory exists */
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if (mkdir_parents(PKG_STATEDIR, 0750) < 0 && errno != EEXIST) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen i_error("mkdir(%s) failed: %m", PKG_STATEDIR);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen return FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen /* remove auth worker sockets left by unclean exits */
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen unlink_sockets(set->base_dir, "auth-worker.");
be8c8479f918875eda871c5685ab2b4067228e26Phil Carmody
be8c8479f918875eda871c5685ab2b4067228e26Phil Carmody login_dir = t_strconcat(set->base_dir, "/login", NULL);
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen if (settings_have_auth_unix_listeners_in(set, login_dir)) {
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen /* we are not using external authentication, so make sure the
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen login directory exists with correct permissions and it's
be8c8479f918875eda871c5685ab2b4067228e26Phil Carmody empty. with external auth we wouldn't want to delete
be8c8479f918875eda871c5685ab2b4067228e26Phil Carmody existing sockets or break the permissions required by the
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth server. */
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen mode_t mode = login_want_core_dumps(set, &gid) ? 0770 : 0750;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen if (gid != (gid_t)-1 &&
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen safe_mkdir(login_dir, mode, master_uid, gid) == 0) {
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen i_warning("Corrected permissions for login directory "
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen "%s", login_dir);
b9ec0443d7d8afebfe61c17a9d692d6fad30c276Timo Sirainen }
b9ec0443d7d8afebfe61c17a9d692d6fad30c276Timo Sirainen
b9ec0443d7d8afebfe61c17a9d692d6fad30c276Timo Sirainen unlink_sockets(login_dir, "");
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* still make sure that login directory exists */
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (mkdir(login_dir, 0755) < 0 && errno != EEXIST) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen i_error("mkdir(%s) failed: %m", login_dir);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen return FALSE;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
fd2118e34f4d1d65cffdccc40d74dda931fae81eTimo Sirainen empty_dir = t_strconcat(set->base_dir, "/empty", NULL);
fd2118e34f4d1d65cffdccc40d74dda931fae81eTimo Sirainen if (safe_mkdir(empty_dir, 0755, master_uid, getegid()) == 0) {
fd2118e34f4d1d65cffdccc40d74dda931fae81eTimo Sirainen i_warning("Corrected permissions for empty directory "
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen "%s", empty_dir);
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen }
d647e72663b52cb2301df5eaf93e67ee873a41f8Timo Sirainen return TRUE;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen}
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen