Mercurial > dovecot > core-2.2
comparison src/lib-master/master-login-auth.c @ 12405:e72ab743b8df
lib-master: Don't wait for handshake before sending auth-master request.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 09 Nov 2010 19:48:47 +0000 |
parents | 9f179255b796 |
children | aec1f1614028 |
comparison
equal
deleted
inserted
replaced
12404:d1cf770dbef5 | 12405:e72ab743b8df |
---|---|
29 unsigned int client_pid; | 29 unsigned int client_pid; |
30 uint8_t cookie[MASTER_AUTH_COOKIE_SIZE]; | 30 uint8_t cookie[MASTER_AUTH_COOKIE_SIZE]; |
31 | 31 |
32 master_login_auth_request_callback_t *callback; | 32 master_login_auth_request_callback_t *callback; |
33 void *context; | 33 void *context; |
34 | |
35 unsigned int aborted:1; | |
34 }; | 36 }; |
35 | 37 |
36 struct master_login_auth { | 38 struct master_login_auth { |
37 pool_t pool; | 39 pool_t pool; |
38 const char *auth_socket_path; | 40 const char *auth_socket_path; |
54 unsigned int version_received:1; | 56 unsigned int version_received:1; |
55 unsigned int spid_received:1; | 57 unsigned int spid_received:1; |
56 }; | 58 }; |
57 | 59 |
58 static void master_login_auth_set_timeout(struct master_login_auth *auth); | 60 static void master_login_auth_set_timeout(struct master_login_auth *auth); |
59 static void master_login_auth_send_all_requests(struct master_login_auth *auth); | 61 static void master_login_auth_check_spids(struct master_login_auth *auth); |
60 | 62 |
61 struct master_login_auth *master_login_auth_init(const char *auth_socket_path) | 63 struct master_login_auth *master_login_auth_init(const char *auth_socket_path) |
62 { | 64 { |
63 struct master_login_auth *auth; | 65 struct master_login_auth *auth; |
64 pool_t pool; | 66 pool_t pool; |
193 if (request == NULL) { | 195 if (request == NULL) { |
194 i_error("Auth server sent reply with unknown ID %u", id); | 196 i_error("Auth server sent reply with unknown ID %u", id); |
195 return NULL; | 197 return NULL; |
196 } | 198 } |
197 master_login_auth_request_remove(auth, request); | 199 master_login_auth_request_remove(auth, request); |
200 if (request->aborted) { | |
201 request->callback(NULL, MASTER_AUTH_ERRMSG_INTERNAL_FAILURE, | |
202 request->context); | |
203 i_free(request); | |
204 return NULL; | |
205 } | |
198 return request; | 206 return request; |
199 } | 207 } |
200 | 208 |
201 static bool | 209 static bool |
202 master_login_auth_input_user(struct master_login_auth *auth, const char *args) | 210 master_login_auth_input_user(struct master_login_auth *auth, const char *args) |
323 "send valid SPID as expected: %s", line); | 331 "send valid SPID as expected: %s", line); |
324 master_login_auth_disconnect(auth); | 332 master_login_auth_disconnect(auth); |
325 return; | 333 return; |
326 } | 334 } |
327 auth->spid_received = TRUE; | 335 auth->spid_received = TRUE; |
328 master_login_auth_send_all_requests(auth); | 336 master_login_auth_check_spids(auth); |
329 } | 337 } |
330 | 338 |
331 auth->refcount++; | 339 auth->refcount++; |
332 while ((line = i_stream_next_line(auth->input)) != NULL) { | 340 while ((line = i_stream_next_line(auth->input)) != NULL) { |
333 if (strncmp(line, "USER\t", 5) == 0) | 341 if (strncmp(line, "USER\t", 5) == 0) |
365 auth->output = o_stream_create_fd(fd, (size_t)-1, FALSE); | 373 auth->output = o_stream_create_fd(fd, (size_t)-1, FALSE); |
366 auth->io = io_add(fd, IO_READ, master_login_auth_input, auth); | 374 auth->io = io_add(fd, IO_READ, master_login_auth_input, auth); |
367 return 0; | 375 return 0; |
368 } | 376 } |
369 | 377 |
370 static void | 378 static bool |
371 master_login_auth_send_request(struct master_login_auth *auth, | 379 auth_request_check_spid(struct master_login_auth *auth, |
372 struct master_login_auth_request *req) | 380 struct master_login_auth_request *req) |
373 { | 381 { |
374 string_t *str; | 382 if (auth->auth_server_pid != req->auth_pid && auth->spid_received) { |
375 | |
376 i_assert(auth->spid_received); | |
377 | |
378 if (auth->auth_server_pid != req->auth_pid) { | |
379 /* auth server was restarted. don't even attempt a login. */ | 383 /* auth server was restarted. don't even attempt a login. */ |
380 i_warning("Auth server restarted (pid %u -> %u), aborting auth", | 384 i_warning("Auth server restarted (pid %u -> %u), aborting auth", |
381 (unsigned int)req->auth_pid, | 385 (unsigned int)req->auth_pid, |
382 (unsigned int)auth->auth_server_pid); | 386 (unsigned int)auth->auth_server_pid); |
387 return FALSE; | |
388 } | |
389 return TRUE; | |
390 } | |
391 | |
392 static void master_login_auth_check_spids(struct master_login_auth *auth) | |
393 { | |
394 struct master_login_auth_request *req, *next; | |
395 | |
396 for (req = auth->request_head; req != NULL; req = next) { | |
397 next = req->next; | |
398 if (!auth_request_check_spid(auth, req)) | |
399 req->aborted = TRUE; | |
400 } | |
401 } | |
402 | |
403 static void | |
404 master_login_auth_send_request(struct master_login_auth *auth, | |
405 struct master_login_auth_request *req) | |
406 { | |
407 string_t *str; | |
408 | |
409 if (!auth_request_check_spid(auth, req)) { | |
383 master_login_auth_request_remove(auth, req); | 410 master_login_auth_request_remove(auth, req); |
384 req->callback(NULL, MASTER_AUTH_ERRMSG_INTERNAL_FAILURE, | 411 req->callback(NULL, MASTER_AUTH_ERRMSG_INTERNAL_FAILURE, |
385 req->context); | 412 req->context); |
386 i_free(req); | 413 i_free(req); |
387 return; | 414 return; |
391 str_printfa(str, "REQUEST\t%u\t%u\t%u\t", req->id, | 418 str_printfa(str, "REQUEST\t%u\t%u\t%u\t", req->id, |
392 req->client_pid, req->auth_id); | 419 req->client_pid, req->auth_id); |
393 binary_to_hex_append(str, req->cookie, sizeof(req->cookie)); | 420 binary_to_hex_append(str, req->cookie, sizeof(req->cookie)); |
394 str_append_c(str, '\n'); | 421 str_append_c(str, '\n'); |
395 o_stream_send(auth->output, str_data(str), str_len(str)); | 422 o_stream_send(auth->output, str_data(str), str_len(str)); |
396 } | |
397 | |
398 static void master_login_auth_send_all_requests(struct master_login_auth *auth) | |
399 { | |
400 struct master_login_auth_request *req, *next; | |
401 | |
402 for (req = auth->request_head; req != NULL; req = next) { | |
403 next = req->next; | |
404 master_login_auth_send_request(auth, req); | |
405 } | |
406 } | 423 } |
407 | 424 |
408 void master_login_auth_request(struct master_login_auth *auth, | 425 void master_login_auth_request(struct master_login_auth *auth, |
409 const struct master_auth_request *req, | 426 const struct master_auth_request *req, |
410 master_login_auth_request_callback_t *callback, | 427 master_login_auth_request_callback_t *callback, |
445 DLLIST2_APPEND(&auth->request_head, &auth->request_tail, login_req); | 462 DLLIST2_APPEND(&auth->request_head, &auth->request_tail, login_req); |
446 | 463 |
447 if (auth->to == NULL) | 464 if (auth->to == NULL) |
448 master_login_auth_set_timeout(auth); | 465 master_login_auth_set_timeout(auth); |
449 | 466 |
450 if (auth->spid_received) | 467 master_login_auth_send_request(auth, login_req); |
451 master_login_auth_send_request(auth, login_req); | |
452 } | 468 } |
453 | 469 |
454 unsigned int master_login_auth_request_count(struct master_login_auth *auth) | 470 unsigned int master_login_auth_request_count(struct master_login_auth *auth) |
455 { | 471 { |
456 return hash_table_count(auth->requests); | 472 return hash_table_count(auth->requests); |