Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/master/login-process.c @ 666:36ac2fd352ff HEAD
Added ssl_disable setting.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 25 Nov 2002 12:45:40 +0200 |
parents | 90a65c017bf0 |
children | 7814b29d0862 |
rev | line source |
---|---|
0 | 1 /* Copyright (C) 2002 Timo Sirainen */ |
2 | |
3 #include "common.h" | |
532
3b53dd1280c6
I/O buffers now use real blocking instead of setting up a sub-ioloop to
Timo Sirainen <tss@iki.fi>
parents:
410
diff
changeset
|
4 #include "ioloop.h" |
0 | 5 #include "network.h" |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
6 #include "obuffer.h" |
0 | 7 #include "fdpass.h" |
8 #include "restrict-access.h" | |
9 #include "login-process.h" | |
10 #include "auth-process.h" | |
11 #include "master-interface.h" | |
12 | |
13 #include <stdlib.h> | |
14 #include <unistd.h> | |
15 #include <syslog.h> | |
16 | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
17 typedef struct _LoginProcess LoginProcess; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
18 |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
19 struct _LoginProcess { |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
20 LoginProcess *prev_nonlisten, *next_nonlisten; |
0 | 21 int refcount; |
22 | |
23 pid_t pid; | |
24 int fd; | |
25 IO io; | |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
26 OBuffer *outbuf; |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
27 unsigned int listening:1; |
0 | 28 unsigned int destroyed:1; |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
29 }; |
0 | 30 |
31 typedef struct { | |
32 LoginProcess *process; | |
33 int login_id; | |
34 int auth_id; | |
35 int fd; | |
36 | |
596
ab3590c3a7d9
Added verbose_proctitle setting: Show more verbose process titles (in ps).
Timo Sirainen <tss@iki.fi>
parents:
532
diff
changeset
|
37 IPADDR ip; |
0 | 38 char login_tag[LOGIN_TAG_SIZE]; |
39 } LoginAuthRequest; | |
40 | |
41 static int auth_id_counter; | |
42 static Timeout to; | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
43 |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
44 static HashTable *processes; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
45 static LoginProcess *oldest_nonlisten_process, *newest_nonlisten_process; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
46 static unsigned int listening_processes; |
614
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
47 static unsigned int wanted_processes_count; |
0 | 48 |
49 static void login_process_destroy(LoginProcess *p); | |
50 static void login_process_unref(LoginProcess *p); | |
51 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
52 static void auth_callback(AuthCookieReplyData *cookie_reply, void *context) |
0 | 53 { |
54 const char *env[] = { | |
55 "MAIL", NULL, | |
56 "LOGIN_TAG", NULL, | |
57 NULL | |
58 }; | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
59 LoginAuthRequest *request = context; |
0 | 60 LoginProcess *process; |
61 MasterReply reply; | |
62 | |
63 env[1] = cookie_reply->mail; | |
64 env[3] = request->login_tag; | |
65 | |
66 if (cookie_reply == NULL || !cookie_reply->success) | |
67 reply.result = MASTER_RESULT_FAILURE; | |
68 else { | |
69 reply.result = create_imap_process(request->fd, | |
596
ab3590c3a7d9
Added verbose_proctitle setting: Show more verbose process titles (in ps).
Timo Sirainen <tss@iki.fi>
parents:
532
diff
changeset
|
70 &request->ip, |
0 | 71 cookie_reply->user, |
72 cookie_reply->uid, | |
73 cookie_reply->gid, | |
74 cookie_reply->home, | |
75 cookie_reply->chroot, env); | |
76 } | |
77 | |
78 /* reply to login */ | |
79 reply.id = request->login_id; | |
80 | |
81 process = request->process; | |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
82 if (o_buffer_send(process->outbuf, &reply, sizeof(reply)) < 0) |
0 | 83 login_process_destroy(process); |
84 | |
85 (void)close(request->fd); | |
86 login_process_unref(process); | |
87 i_free(request); | |
88 } | |
89 | |
614
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
90 void login_process_mark_nonlistening(LoginProcess *p) |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
91 { |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
92 if (!p->listening) { |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
93 i_error("login: received another \"not listening\" " |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
94 "notification"); |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
95 return; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
96 } |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
97 |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
98 p->listening = FALSE; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
99 listening_processes--; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
100 |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
101 p->prev_nonlisten = newest_nonlisten_process; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
102 |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
103 if (newest_nonlisten_process != NULL) |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
104 newest_nonlisten_process->next_nonlisten = p; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
105 newest_nonlisten_process = p; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
106 |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
107 if (oldest_nonlisten_process == NULL) |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
108 oldest_nonlisten_process = p; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
109 } |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
110 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
111 static void login_process_input(void *context, int fd __attr_unused__, |
0 | 112 IO io __attr_unused__) |
113 { | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
114 LoginProcess *p = context; |
0 | 115 AuthProcess *auth_process; |
116 LoginAuthRequest *authreq; | |
117 MasterRequest req; | |
118 int client_fd, ret; | |
119 | |
120 ret = fd_read(p->fd, &req, sizeof(req), &client_fd); | |
121 if (ret != sizeof(req)) { | |
122 if (ret == 0) { | |
123 /* disconnected, ie. the login process died */ | |
124 } else if (ret > 0) { | |
125 /* req wasn't fully read */ | |
126 i_error("login: fd_read() couldn't read all req"); | |
127 } else { | |
128 i_error("login: fd_read() failed: %m"); | |
129 } | |
130 | |
131 login_process_destroy(p); | |
132 return; | |
133 } | |
134 | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
135 if (client_fd == -1) { |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
136 /* just a notification that the login process isn't |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
137 listening for new connections anymore */ |
614
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
138 login_process_mark_nonlistening(p); |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
139 return; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
140 } |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
141 |
0 | 142 /* login process isn't trusted, validate all data to make sure |
143 it's not trying to exploit us */ | |
144 if (!VALIDATE_STR(req.login_tag)) { | |
145 i_error("login: Received corrupted data"); | |
146 login_process_destroy(p); | |
147 return; | |
148 } | |
149 | |
150 /* ask the cookie from the auth process */ | |
151 authreq = i_new(LoginAuthRequest, 1); | |
152 p->refcount++; | |
153 authreq->process = p; | |
154 authreq->login_id = req.id; | |
155 authreq->auth_id = ++auth_id_counter; | |
156 authreq->fd = client_fd; | |
596
ab3590c3a7d9
Added verbose_proctitle setting: Show more verbose process titles (in ps).
Timo Sirainen <tss@iki.fi>
parents:
532
diff
changeset
|
157 memcpy(&authreq->ip, &req.ip, sizeof(IPADDR)); |
0 | 158 strcpy(authreq->login_tag, req.login_tag); |
159 | |
160 auth_process = auth_process_find(req.auth_process); | |
161 if (auth_process == NULL) { | |
162 i_error("login: Authentication process %u doesn't exist", | |
163 req.auth_process); | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
164 auth_callback(NULL, authreq); |
0 | 165 } else { |
166 auth_process_request(auth_process, authreq->auth_id, req.cookie, | |
167 auth_callback, authreq); | |
168 } | |
169 } | |
170 | |
171 static LoginProcess *login_process_new(pid_t pid, int fd) | |
172 { | |
173 LoginProcess *p; | |
174 | |
175 PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_LOGIN); | |
176 | |
177 p = i_new(LoginProcess, 1); | |
178 p->refcount = 1; | |
179 p->pid = pid; | |
180 p->fd = fd; | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
181 p->listening = TRUE; |
0 | 182 p->io = io_add(fd, IO_READ, login_process_input, p); |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
183 p->outbuf = o_buffer_create_file(fd, default_pool, |
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
184 sizeof(MasterReply)*10, |
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
185 IO_PRIORITY_DEFAULT, FALSE); |
0 | 186 |
195
db6e288be0e9
Replaced INT_TO_POINTER and POINTER_TO_INT macros with POINTER_CAST and
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
187 hash_insert(processes, POINTER_CAST(pid), p); |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
188 listening_processes++; |
0 | 189 return p; |
190 } | |
191 | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
192 void login_process_remove_from_lists(LoginProcess *p) |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
193 { |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
194 if (p == oldest_nonlisten_process) |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
195 oldest_nonlisten_process = p->next_nonlisten; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
196 else |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
197 p->prev_nonlisten->next_nonlisten = p->next_nonlisten; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
198 |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
199 if (p == newest_nonlisten_process) |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
200 newest_nonlisten_process = p->prev_nonlisten; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
201 else |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
202 p->next_nonlisten->prev_nonlisten = p->prev_nonlisten; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
203 |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
204 p->next_nonlisten = p->prev_nonlisten = NULL; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
205 } |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
206 |
0 | 207 static void login_process_destroy(LoginProcess *p) |
208 { | |
209 if (p->destroyed) | |
210 return; | |
211 p->destroyed = TRUE; | |
212 | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
213 if (p->listening) |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
214 listening_processes--; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
215 |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
216 o_buffer_close(p->outbuf); |
0 | 217 io_remove(p->io); |
218 (void)close(p->fd); | |
219 | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
220 if (!p->listening) |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
221 login_process_remove_from_lists(p); |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
222 |
195
db6e288be0e9
Replaced INT_TO_POINTER and POINTER_TO_INT macros with POINTER_CAST and
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
223 hash_remove(processes, POINTER_CAST(p->pid)); |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
224 |
0 | 225 login_process_unref(p); |
226 } | |
227 | |
228 static void login_process_unref(LoginProcess *p) | |
229 { | |
230 if (--p->refcount > 0) | |
231 return; | |
232 | |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
233 o_buffer_unref(p->outbuf); |
0 | 234 i_free(p); |
235 } | |
236 | |
237 static pid_t create_login_process(void) | |
238 { | |
239 static const char *argv[] = { NULL, NULL }; | |
240 pid_t pid; | |
241 int fd[2]; | |
242 | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
243 if (set_login_process_per_connection && |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
244 hash_size(processes)-listening_processes >= set_max_logging_users) { |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
245 if (oldest_nonlisten_process != NULL) |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
246 login_process_destroy(oldest_nonlisten_process); |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
247 } |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
248 |
0 | 249 if (set_login_uid == 0) |
250 i_fatal("Login process must not run as root"); | |
251 | |
252 /* create communication to process with a socket pair */ | |
253 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) { | |
254 i_error("socketpair() failed: %m"); | |
255 return -1; | |
256 } | |
257 | |
258 pid = fork(); | |
259 if (pid < 0) { | |
260 (void)close(fd[0]); | |
261 (void)close(fd[1]); | |
262 i_error("fork() failed: %m"); | |
263 return -1; | |
264 } | |
265 | |
266 if (pid != 0) { | |
267 /* master */ | |
268 login_process_new(pid, fd[0]); | |
269 (void)close(fd[1]); | |
270 return pid; | |
271 } | |
272 | |
273 /* move communication handle */ | |
274 if (dup2(fd[1], LOGIN_MASTER_SOCKET_FD) < 0) | |
275 i_fatal("login: dup2() failed: %m"); | |
276 | |
277 /* move the listen handle */ | |
278 if (dup2(imap_fd, LOGIN_IMAP_LISTEN_FD) < 0) | |
279 i_fatal("login: dup2() failed: %m"); | |
280 | |
281 /* move the SSL listen handle */ | |
282 if (dup2(imaps_fd, LOGIN_IMAPS_LISTEN_FD) < 0) | |
283 i_fatal("login: dup2() failed: %m"); | |
284 | |
285 /* imap_fd and imaps_fd are closed by clean_child_process() */ | |
286 | |
287 (void)close(fd[0]); | |
288 (void)close(fd[1]); | |
289 | |
290 clean_child_process(); | |
291 | |
292 /* setup access environment - needs to be done after | |
293 clean_child_process() since it clears environment */ | |
294 restrict_access_set_env(set_login_user, set_login_uid, set_login_gid, | |
295 set_login_chroot ? set_login_dir : NULL); | |
296 | |
297 if (!set_login_chroot) { | |
298 /* no chrooting, but still change to the directory */ | |
299 if (chdir(set_login_dir) < 0) { | |
300 i_fatal("chdir(%s) failed: %m", | |
301 set_login_dir); | |
302 } | |
303 } | |
304 | |
666 | 305 if (!set_ssl_disable) { |
0 | 306 putenv((char *) t_strconcat("SSL_CERT_FILE=", |
307 set_ssl_cert_file, NULL)); | |
308 putenv((char *) t_strconcat("SSL_KEY_FILE=", | |
309 set_ssl_key_file, NULL)); | |
615
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
310 putenv((char *) t_strconcat("SSL_PARAM_FILE=", |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
311 set_ssl_parameters_file, NULL)); |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
312 } |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
313 |
0 | 314 if (set_disable_plaintext_auth) |
315 putenv("DISABLE_PLAINTEXT_AUTH=1"); | |
316 | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
317 if (set_login_process_per_connection) { |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
318 putenv("PROCESS_PER_CONNECTION=1"); |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
319 putenv("MAX_LOGGING_USERS=1"); |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
320 } else { |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
321 putenv((char *) t_strdup_printf("MAX_LOGGING_USERS=%d", |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
322 set_max_logging_users)); |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
323 } |
0 | 324 |
325 /* hide the path, it's ugly */ | |
326 argv[0] = strrchr(set_login_executable, '/'); | |
327 if (argv[0] == NULL) argv[0] = set_login_executable; else argv[0]++; | |
328 | |
329 execv(set_login_executable, (char **) argv); | |
330 | |
331 i_fatal("execv(%s) failed: %m", argv[0]); | |
332 return -1; | |
333 } | |
334 | |
615
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
335 void login_process_abormal_exit(pid_t pid __attr_unused__) |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
336 { |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
337 /* don't start raising the process count if they're dying all |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
338 the time */ |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
339 wanted_processes_count = 0; |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
340 } |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
614
diff
changeset
|
341 |
0 | 342 static void login_hash_cleanup(void *key __attr_unused__, void *value, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
343 void *context __attr_unused__) |
0 | 344 { |
345 LoginProcess *p = value; | |
346 | |
347 (void)close(p->fd); | |
348 } | |
349 | |
350 void login_processes_cleanup(void) | |
351 { | |
352 hash_foreach(processes, login_hash_cleanup, NULL); | |
353 } | |
354 | |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
355 static void login_hash_destroy(void *key __attr_unused__, void *value, |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
356 void *context __attr_unused__) |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
357 { |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
358 login_process_destroy(value); |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
359 } |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
360 |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
361 void login_processes_destroy_all(void) |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
362 { |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
363 hash_foreach(processes, login_hash_destroy, NULL); |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
364 |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
365 /* don't double their amount when restarting */ |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
366 wanted_processes_count = 0; |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
367 } |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
368 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
369 static void login_processes_start_missing(void *context __attr_unused__, |
0 | 370 Timeout timeout __attr_unused__) |
371 { | |
614
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
372 if (!set_login_process_per_connection) { |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
373 /* create max. one process every second, that way if it keeps |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
374 dying all the time we don't eat all cpu with fork()ing. */ |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
375 if (listening_processes < set_login_processes_count) |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
376 (void)create_login_process(); |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
377 } else { |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
378 /* we want to respond fast when multiple clients are connecting |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
379 at once, but we also want to prevent fork-bombing. use the |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
380 same method as apache: check once a second if we need new |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
381 processes. if yes and we've used all the existing processes, |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
382 double their amount (unless we've hit the high limit). |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
383 Then for each second that didn't use all existing processes, |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
384 drop the max. process count by one. */ |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
385 if (wanted_processes_count < set_login_processes_count) |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
386 wanted_processes_count = set_login_processes_count; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
387 else if (listening_processes == 0) |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
388 wanted_processes_count *= 2; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
389 else if (wanted_processes_count > set_login_processes_count) |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
390 wanted_processes_count--; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
391 |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
392 if (wanted_processes_count > set_login_max_processes_count) |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
393 wanted_processes_count = set_login_max_processes_count; |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
394 |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
395 while (listening_processes < wanted_processes_count) |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
396 (void)create_login_process(); |
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
397 } |
0 | 398 } |
399 | |
400 void login_processes_init(void) | |
401 { | |
402 auth_id_counter = 0; | |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
403 listening_processes = 0; |
614
e60620644af3
login_process_per_connection = yes scales now better when multiple users are
Timo Sirainen <tss@iki.fi>
parents:
613
diff
changeset
|
404 wanted_processes_count = 0; |
613
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
405 oldest_nonlisten_process = newest_nonlisten_process = NULL; |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
406 |
1906116a62ce
Finally support for handling each login connection in it's own process.
Timo Sirainen <tss@iki.fi>
parents:
596
diff
changeset
|
407 processes = hash_create(default_pool, 128, NULL, NULL); |
0 | 408 to = timeout_add(1000, login_processes_start_missing, NULL); |
409 } | |
410 | |
411 void login_processes_deinit(void) | |
412 { | |
413 timeout_remove(to); | |
414 | |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
415 login_processes_destroy_all(); |
0 | 416 hash_destroy(processes); |
417 } |