]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Change fd limit in login process after it's execed. This fixes OSes which
authorTimo Sirainen <tss@iki.fi>
Thu, 12 Jun 2008 21:48:58 +0000 (00:48 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 12 Jun 2008 21:48:58 +0000 (00:48 +0300)
don't allow setting fd limit below what's already used (e.g. HP-UX).

--HG--
branch : HEAD

src/login-common/main.c
src/master/login-process.c

index 80cb12788045c88a2cc11a80b33efbcecf86f42c..42778073c8c4ddfc92fd52f815b66dd46554110e 100644 (file)
@@ -250,21 +250,21 @@ static void auth_connect_notify(struct auth_client *client ATTR_UNUSED,
 
 static void drop_privileges(void)
 {
-       const char *env;
+       const char *value;
 
        if (!is_inetd)
                i_set_failure_internal();
        else {
                /* log to syslog */
-               env = getenv("SYSLOG_FACILITY");
+               value = getenv("SYSLOG_FACILITY");
                i_set_failure_syslog(process_name, LOG_NDELAY,
-                                    env == NULL ? LOG_MAIL : atoi(env));
+                                    value == NULL ? LOG_MAIL : atoi(value));
 
                /* if we don't chroot, we must chdir */
-               env = getenv("LOGIN_DIR");
-               if (env != NULL) {
-                       if (chdir(env) < 0)
-                               i_error("chdir(%s) failed: %m", env);
+               value = getenv("LOGIN_DIR");
+               if (value != NULL) {
+                       if (chdir(value) < 0)
+                               i_error("chdir(%s) failed: %m", value);
                }
        }
 
@@ -273,6 +273,18 @@ static void drop_privileges(void)
        random_init();
        ssl_proxy_init();
 
+       value = getenv("LISTEN_FDS");
+       listen_count = value == NULL ? 0 : atoi(value);
+       value = getenv("SSL_LISTEN_FDS");
+       ssl_listen_count = value == NULL ? 0 : atoi(value);
+       value = getenv("MAX_CONNECTIONS");
+       max_connections = value == NULL ? 1 : strtoul(value, NULL, 10);
+
+       /* set the number of fds we want to use. it may get increased or
+          decreased. leave a couple of extra fds for auth sockets and such */
+       restrict_fd_limit(LOGIN_MASTER_SOCKET_FD + 16 +
+                         listen_count + ssl_listen_count + max_connections);
+
        /* Refuse to run as root - we should never need it and it's
           dangerous with SSL. */
        restrict_access_by_env(TRUE);
@@ -303,9 +315,6 @@ static void main_init(void)
         verbose_ssl = getenv("VERBOSE_SSL") != NULL;
         verbose_auth = getenv("VERBOSE_AUTH") != NULL;
 
-       value = getenv("MAX_CONNECTIONS");
-       max_connections = value == NULL ? 1 : strtoul(value, NULL, 10);
-
        greeting = getenv("GREETING");
        if (greeting == NULL)
                greeting = PACKAGE" ready.";
@@ -339,12 +348,6 @@ static void main_init(void)
         auth_client_set_connect_notify(auth_client, auth_connect_notify, NULL);
        clients_init();
 
-       value = getenv("LISTEN_FDS");
-       listen_count = value == NULL ? 0 : atoi(value);
-
-       value = getenv("SSL_LISTEN_FDS");
-       ssl_listen_count = value == NULL ? 0 : atoi(value);
-
        if (!ssl_initialized && ssl_listen_count > 0) {
                /* this shouldn't happen, master should have
                   disabled the ssl socket.. */
index 8c2c207c5cadf1ff86e26aaa2a0ee04d3a3d42e7..7e5c422af3833dc61c67f3e6e0eb052cdfdf29d7 100644 (file)
@@ -590,7 +590,7 @@ static pid_t create_login_process(struct login_group *group)
        const char *prefix;
        pid_t pid;
        ARRAY_TYPE(dup2) dups;
-       unsigned int i, fd_limit, listen_count = 0, ssl_listen_count = 0;
+       unsigned int i, listen_count = 0, ssl_listen_count = 0;
        int fd[2], log_fd, cur_fd, tmp_fd;
 
        if (group->set->login_uid == 0)
@@ -686,25 +686,11 @@ static pid_t create_login_process(struct login_group *group)
        }
 
        restrict_process_size(group->set->login_process_size, (unsigned int)-1);
-       /* +16 is just for some extra things the process might want */
-       fd_limit = 16 + cur_fd +
-               2 * (group->set->login_process_per_connection ? 1 :
-                    group->set->login_max_connections);
-#ifdef DEBUG
-       if (!gdb)
-#endif
-               restrict_fd_limit(fd_limit);
 
        /* make sure we don't leak syslog fd, but do it last so that
           any errors above will be logged */
        closelog();
 
-       /* execv() needs at least one file descriptor. we might have all fds
-          up to fd_limit used already, so close one we don't care about.
-          either it succeeds or fails with EBADF, doesn't matter. */
-       i_assert(fd_limit > (unsigned int)cur_fd+1);
-       (void)close(cur_fd+1);
-
        client_process_exec(group->set->login_executable, "");
        i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m",
                       group->set->login_executable);