changeset 7852:53604857c7d2 HEAD

Change fd limit in login process after it's execed. This fixes OSes which don't allow setting fd limit below what's already used (e.g. HP-UX).
author Timo Sirainen <tss@iki.fi>
date Fri, 13 Jun 2008 00:48:58 +0300
parents 560611fa3d68
children 98aa72f63578
files src/login-common/main.c src/master/login-process.c
diffstat 2 files changed, 20 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/login-common/main.c	Fri Jun 13 00:36:23 2008 +0300
+++ b/src/login-common/main.c	Fri Jun 13 00:48:58 2008 +0300
@@ -250,21 +250,21 @@
 
 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 @@
 	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 @@
         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 @@
         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.. */
--- a/src/master/login-process.c	Fri Jun 13 00:36:23 2008 +0300
+++ b/src/master/login-process.c	Fri Jun 13 00:48:58 2008 +0300
@@ -590,7 +590,7 @@
 	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 @@
 	}
 
 	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);