]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Fixed login processes' core dump handling.
authorTimo Sirainen <tss@iki.fi>
Tue, 20 Oct 2009 23:41:50 +0000 (19:41 -0400)
committerTimo Sirainen <tss@iki.fi>
Tue, 20 Oct 2009 23:41:50 +0000 (19:41 -0400)
--HG--
branch : HEAD

src/login-common/main.c
src/master/master-settings.c
src/master/master-settings.h
src/master/service-process.c

index a843117d4c6ba934aae554001084213136c7f4ce..e30d50f23ae3d6cecd18f0ecf8d53c303bb1f957 100644 (file)
@@ -93,7 +93,7 @@ static int anvil_connect(void)
        return fd;
 }
 
-static void main_preinit(void)
+static void main_preinit(bool allow_core_dumps)
 {
        unsigned int max_fds;
 
@@ -125,6 +125,8 @@ static void main_preinit(void)
                anvil_fd = anvil_connect();
 
        restrict_access_by_env(NULL, TRUE);
+       if (allow_core_dumps)
+               restrict_access_allow_coredumps(TRUE);
 }
 
 static void main_init(void)
@@ -171,6 +173,7 @@ int main(int argc, char *argv[], char *envp[])
                MASTER_SERVICE_FLAG_TRACK_LOGIN_STATE;
        const char *getopt_str;
        pool_t set_pool;
+       bool allow_core_dumps = FALSE;
        int c;
 
        master_service = master_service_init(login_process_name, service_flags,
@@ -182,7 +185,7 @@ int main(int argc, char *argv[], char *envp[])
        while ((c = getopt(argc, argv, getopt_str)) > 0) {
                switch (c) {
                case 'D':
-                       restrict_access_allow_coredumps(TRUE);
+                       allow_core_dumps = TRUE;
                        break;
                case 'S':
                        ssl_connections = TRUE;
@@ -206,7 +209,7 @@ int main(int argc, char *argv[], char *envp[])
        /* main_preinit() needs to know the client limit, which is set by
           this. so call it first. */
        master_service_init_finish(master_service);
-       main_preinit();
+       main_preinit(allow_core_dumps);
        main_init();
 
        master_service_run(master_service, client_connected);
index c29a748cef41ede47f54c11272ff17d2d06f3346..59ac6d439f4e1c387575642bb4b525394a1d0231 100644 (file)
@@ -267,6 +267,18 @@ static bool master_settings_parse_type(struct service_settings *set,
        return TRUE;
 }
 
+static void service_set_login_dump_core(struct service_settings *set)
+{
+       const char *p;
+
+       if (set->parsed_type != SERVICE_TYPE_LOGIN)
+               return;
+
+       p = strstr(set->executable, " -D");
+       if (p != NULL && (p[3] == '\0' || p[3] == ' '))
+               set->login_dump_core = TRUE;
+}
+
 static bool
 master_settings_verify(void *_set, pool_t pool, const char **error_r)
 {
@@ -311,6 +323,7 @@ master_settings_verify(void *_set, pool_t pool, const char **error_r)
                                return FALSE;
                        }
                }
+               service_set_login_dump_core(service);
        }
        for (i = 0; i < count; i++) {
                struct service_settings *service = services[i];
@@ -361,8 +374,8 @@ login_want_core_dumps(const struct master_settings *set, gid_t *gid_r)
 
        services = array_get(&set->services, &count);
        for (i = 0; i < count; i++) {
-               if (strcmp(services[i]->type, "login") == 0) {
-                       if (strstr(services[i]->executable, " -D") != NULL)
+               if (services[i]->parsed_type == SERVICE_TYPE_LOGIN) {
+                       if (services[i]->login_dump_core)
                                cores = TRUE;
                        (void)get_uidgid(services[i]->user, &uid, gid_r, &error);
                        if (*services[i]->group != '\0')
index 98f0c8fbf366424dc47423143e5b7ad16b9ffe21..ff524c794f4db01ff390a3d2237c159cc2cce480 100644 (file)
@@ -51,6 +51,7 @@ struct service_settings {
        ARRAY_DEFINE(inet_listeners, struct inet_listener_settings *);
 
        enum service_type parsed_type;
+       unsigned int login_dump_core:1;
 };
 
 struct master_settings {
index 488db44b28b3d7cc34206615071925bfabe228f3..5630bf1adba4ece92034fda478ff7a5be15eabb5 100644 (file)
@@ -382,7 +382,7 @@ static void log_coredump(struct service *service ATTR_UNUSED,
                return;
        }
 
-#ifdef HAVE_PR_SET_DUMPABLE
+#ifndef HAVE_PR_SET_DUMPABLE
        if (!service->set->drop_priv_before_exec) {
                str_append(str, " (core not dumped - set drop_priv_before_exec=yes)");
                return;
@@ -391,6 +391,11 @@ static void log_coredump(struct service *service ATTR_UNUSED,
                str_append(str, " (core not dumped - privileged_group prevented it)");
                return;
        }
+#else
+       if (!service->set->login_dump_core) {
+               str_append(str, " (core not dumped - add -D parameter to service executable");
+               return;
+       }
 #endif
 
        str_append(str, " (core not dumped)");