# HG changeset patch # User Timo Sirainen # Date 1127564725 -10800 # Node ID a2dd3d895e00200a2807fb1370617c529466a39d # Parent 8a8352cda514e2abacd85880c18b1c9ef4a8a4ce Several fixes to make running from inetd working again diff -r 8a8352cda514 -r a2dd3d895e00 src/login-common/main.c --- a/src/login-common/main.c Sat Sep 24 13:50:38 2005 +0300 +++ b/src/login-common/main.c Sat Sep 24 15:25:25 2005 +0300 @@ -26,6 +26,7 @@ unsigned int login_process_uid; struct auth_client *auth_client; +static const char *process_name; static struct ioloop *ioloop; static struct io *io_listen, *io_ssl_listen; static int main_refcount; @@ -134,9 +135,23 @@ clients_notify_auth_connected(); } -static void drop_privileges() +static void drop_privileges(void) { - i_set_failure_internal(); + const char *env; + + if (!is_inetd) + i_set_failure_internal(); + else { + /* log to syslog */ + i_set_failure_syslog(process_name, LOG_NDELAY, LOG_MAIL); + + /* 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); + } + } /* Initialize SSL proxy so it can read certificate and private key file. */ @@ -190,7 +205,7 @@ closing_down = FALSE; main_refcount = 0; - auth_client = auth_client_new((unsigned int)getpid()); + auth_client = auth_client_new(login_process_uid); auth_client_set_connect_notify(auth_client, auth_connect_notify, NULL); clients_init(); @@ -243,6 +258,7 @@ { const char *name, *group_name; struct ip_addr ip, local_ip; + unsigned int local_port; struct ssl_proxy *proxy = NULL; struct client *client; int i, fd = -1, master_fd = -1, ssl = FALSE; @@ -260,9 +276,9 @@ if (is_inetd) { /* running from inetd. create master process before dropping privileges. */ - group_name = strrchr(argv[0], '/'); - group_name = group_name == NULL ? argv[0] : group_name+1; - group_name = t_strcut(group_name, '-'); + process_name = strrchr(argv[0], '/'); + process_name = process_name == NULL ? argv[0] : process_name+1; + group_name = t_strcut(process_name, '-'); for (i = 1; i < argc; i++) { if (strncmp(argv[i], "--group=", 8) == 0) { @@ -286,20 +302,27 @@ i_fatal("%s can be started only through dovecot " "master process, inetd or equilevant", argv[0]); } - if (net_getsockname(1, &local_ip, NULL) < 0) + if (net_getsockname(1, &local_ip, &local_port) < 0) { memset(&local_ip, 0, sizeof(local_ip)); + local_port = 0; + } fd = 1; for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "--ssl") == 0) { - fd = ssl_proxy_new(fd, &ip, &proxy); - if (fd == -1) - return 1; + if (strcmp(argv[i], "--ssl") == 0) ssl = TRUE; - } else if (strncmp(argv[i], "--group=", 8) != 0) + else if (strncmp(argv[i], "--group=", 8) != 0) i_fatal("Unknown parameter: %s", argv[i]); } + /* hardcoded imaps and pop3s ports to be SSL by default */ + if (local_port == 993 || local_port == 995 || ssl) { + ssl = TRUE; + fd = ssl_proxy_new(fd, &ip, &proxy); + if (fd == -1) + return 1; + } + master_init(master_fd, FALSE); closing_down = TRUE; diff -r 8a8352cda514 -r a2dd3d895e00 src/master/login-process.c --- a/src/master/login-process.c Sat Sep 24 13:50:38 2005 +0300 +++ b/src/master/login-process.c Sat Sep 24 15:25:25 2005 +0300 @@ -192,13 +192,13 @@ i_error("login: Server name wasn't sent"); else { name = t_strndup(buf, len); - proto = strchr(buf, '/'); + proto = strchr(name, '/'); if (proto == NULL) { - i_error("login: Missing protocol from server name '%s'", - name); - return FALSE; + proto = name; + name = "default"; + } else { + name = t_strdup_until(name, proto++); } - name = t_strdup_until(buf, proto++); if (strcmp(proto, "imap") == 0) protocol = MAIL_PROTOCOL_IMAP; @@ -632,7 +632,7 @@ { extern char **environ; char **env; - size_t len; + ssize_t len; int ret = 0; /* this will clear our environment. luckily we don't need it. */ @@ -641,13 +641,23 @@ for (env = environ; *env != NULL; env++) { len = strlen(*env); - if (o_stream_send(p->output, *env, len) != (ssize_t)len || + if (o_stream_send(p->output, *env, len) != len || o_stream_send(p->output, "\n", 1) != 1) { ret = -1; break; } } + if (!p->group->set->login_chroot) { + /* if we're not chrooting, we need to tell login process + where its base directory is */ + const char *str = t_strdup_printf("LOGIN_DIR=%s\n", + p->group->set->login_dir); + len = strlen(str); + if (o_stream_send(p->output, str, len) != len) + ret = -1; + } + if (ret == 0 && o_stream_send(p->output, "\n", 1) != 1) ret = -1;