62
62
struct auth_master_user_list_ctx {
63
63
struct auth_master_connection *conn;
65
ARRAY_TYPE(const_string) users;
66
const char *const *user_strings;
67
unsigned int idx, user_count;
192
190
array_append(&new_args, &args[i], 1);
195
(void)array_append_space(&new_args);
193
array_append_zero(&new_args);
196
194
return array_idx(&new_args, 0);
290
288
while ((line = i_stream_next_line(conn->input)) != NULL) {
290
io_loop_set_current(conn->prev_ioloop);
292
291
ret = auth_handle_line(conn, line);
292
io_loop_set_current(conn->ioloop);
336
336
static void auth_master_set_io(struct auth_master_connection *conn)
338
if (conn->ioloop != NULL)
338
341
if (conn->to != NULL)
339
342
timeout_remove(&conn->to);
344
conn->prev_ioloop = current_ioloop;
341
345
conn->ioloop = io_loop_create();
342
346
conn->input = i_stream_create_fd(conn->fd, MAX_INBUF_SIZE, FALSE);
343
347
conn->output = o_stream_create_fd(conn->fd, MAX_OUTBUF_SIZE, FALSE);
347
351
lib_signals_reset_ioloop();
350
static void auth_master_unset_io(struct auth_master_connection *conn,
351
struct ioloop *prev_ioloop)
354
static void auth_master_unset_io(struct auth_master_connection *conn)
353
if (prev_ioloop != NULL) {
354
io_loop_set_current(prev_ioloop);
356
if (conn->prev_ioloop != NULL) {
357
io_loop_set_current(conn->prev_ioloop);
355
358
lib_signals_reset_ioloop();
357
io_loop_set_current(conn->ioloop);
360
if (conn->ioloop != NULL) {
361
io_loop_set_current(conn->ioloop);
359
timeout_remove(&conn->to);
360
io_remove(&conn->io);
361
i_stream_unref(&conn->input);
362
o_stream_unref(&conn->output);
363
io_loop_destroy(&conn->ioloop);
363
timeout_remove(&conn->to);
364
io_remove(&conn->io);
365
i_stream_unref(&conn->input);
366
o_stream_unref(&conn->output);
367
io_loop_destroy(&conn->ioloop);
365
370
if ((conn->flags & AUTH_MASTER_FLAG_NO_IDLE_TIMEOUT) == 0) {
366
if (prev_ioloop == NULL)
371
if (conn->prev_ioloop == NULL)
367
372
auth_connection_close(conn);
374
i_assert(conn->to == NULL);
369
375
conn->to = timeout_add(1000*AUTH_MASTER_IDLE_SECS,
370
376
auth_idle_timeout, conn);
388
static int auth_master_run_cmd(struct auth_master_connection *conn,
394
static int auth_master_run_cmd_pre(struct auth_master_connection *conn,
391
struct ioloop *prev_ioloop;
394
399
if (conn->fd == -1) {
395
400
if (auth_master_connect(conn) < 0)
399
prev_ioloop = current_ioloop;
400
403
auth_master_set_io(conn);
402
405
o_stream_cork(conn->output);
403
406
if (!conn->sent_handshake) {
404
407
str = t_strdup_printf("VERSION\t%d\t%d\n",
405
408
AUTH_PROTOCOL_MAJOR, AUTH_PROTOCOL_MINOR);
406
o_stream_send_str(conn->output, str);
409
o_stream_nsend_str(conn->output, str);
407
410
conn->sent_handshake = TRUE;
410
o_stream_send_str(conn->output, cmd);
413
o_stream_nsend_str(conn->output, cmd);
411
414
o_stream_uncork(conn->output);
413
if (conn->output->stream_errno != 0) {
414
errno = conn->output->stream_errno;
416
if (o_stream_nfinish(conn->output) < 0) {
415
417
i_error("write(auth socket) failed: %m");
416
conn->aborted = TRUE;
418
io_loop_run(conn->ioloop);
418
auth_master_unset_io(conn);
419
auth_connection_close(conn);
421
auth_master_unset_io(conn, prev_ioloop);
425
static int auth_master_run_cmd_post(struct auth_master_connection *conn)
427
auth_master_unset_io(conn);
422
428
if (conn->aborted) {
423
429
conn->aborted = FALSE;
424
430
auth_connection_close(conn);
436
static int auth_master_run_cmd(struct auth_master_connection *conn,
439
if (auth_master_run_cmd_pre(conn, cmd) < 0)
441
io_loop_run(conn->ioloop);
442
return auth_master_run_cmd_post(conn);
430
445
static unsigned int
431
446
auth_master_next_request_id(struct auth_master_connection *conn)
524
539
reply_r->home = p_strdup(pool, *fields + 5);
525
540
else if (strncmp(*fields, "chroot=", 7) == 0)
526
541
reply_r->chroot = p_strdup(pool, *fields + 7);
542
else if (strcmp(*fields, "anonymous") == 0)
543
reply_r->anonymous = TRUE;
528
545
const char *field = p_strdup(pool, *fields);
529
546
array_append(&reply_r->extra_fields, &field, 1);
576
593
unsigned int *countp = context;
578
595
if (strcmp(cmd, "OK") != 0)
580
597
else if (args[0] == NULL || str_to_uint(args[0], countp) < 0)
583
600
io_loop_stop(current_ioloop);
608
625
(void)auth_master_run_cmd(conn, str_c(str));
609
626
conn->prefix = DEFAULT_USERDB_LOOKUP_PREFIX;
611
return *count_r == -1U ? -1 : 0;
628
return *count_r == UINT_MAX ? -1 : 0;
618
635
struct auth_master_user_list_ctx *ctx = context;
621
637
timeout_reset(ctx->conn->to);
638
str_truncate(ctx->username, 0);
639
io_loop_stop(ctx->conn->ioloop);
623
641
if (strcmp(cmd, "DONE") == 0) {
624
io_loop_stop(ctx->conn->ioloop);
625
642
if (args[0] != NULL && strcmp(args[0], "fail") == 0) {
626
643
i_error("User listing returned failure");
627
644
ctx->failed = TRUE;
631
if (strcmp(cmd, "LIST") == 0 && args[0] != NULL) {
646
ctx->finished = TRUE;
647
} else if (strcmp(cmd, "LIST") == 0 && args[0] != NULL) {
632
648
/* we'll just read all the users into memory. otherwise we'd
633
649
have to use a separate connection for listing and there's
634
650
a higher chance of a failure since the connection could be
635
651
open to dovecot-auth for a long time. */
636
user = p_strdup(ctx->pool, args[0]);
637
array_append(&ctx->users, &user, 1);
652
str_append(ctx->username, args[0]);
654
i_error("User listing returned invalid input");
648
665
struct auth_master_user_list_ctx *ctx;
652
pool = pool_alloconly_create("auth master user list", 10240);
653
ctx = p_new(pool, struct auth_master_user_list_ctx, 1);
668
ctx = i_new(struct auth_master_user_list_ctx, 1);
655
669
ctx->conn = conn;
656
i_array_init(&ctx->users, 128);
670
ctx->username = str_new(default_pool, 128);
658
672
conn->reply_callback = auth_user_list_reply_callback;
659
673
conn->reply_context = ctx;
661
675
str = t_str_new(128);
662
676
str_printfa(str, "LIST\t%u",
663
677
auth_master_next_request_id(conn));
664
if (user_mask != NULL && *user_mask != '\0')
678
if (*user_mask != '\0')
665
679
str_printfa(str, "\tuser=%s", user_mask);
666
680
if (info != NULL)
667
681
auth_user_info_export(str, info);
668
682
str_append_c(str, '\n');
670
684
conn->prefix = "userdb list";
671
if (auth_master_run_cmd(conn, str_c(str)) < 0)
686
if (auth_master_run_cmd_pre(conn, str_c(str)) < 0)
672
687
ctx->failed = TRUE;
673
ctx->user_strings = array_get(&ctx->users, &ctx->user_count);
688
io_loop_set_current(conn->prev_ioloop);
674
689
conn->prefix = DEFAULT_USERDB_LOOKUP_PREFIX;
678
693
const char *auth_master_user_list_next(struct auth_master_user_list_ctx *ctx)
680
if (ctx->idx == ctx->user_count)
682
return ctx->user_strings[ctx->idx++];
685
unsigned int auth_master_user_list_count(struct auth_master_user_list_ctx *ctx)
687
return ctx->user_count;
697
if (ctx->conn->input == NULL)
700
/* try to read already buffered input */
701
line = i_stream_next_line(ctx->conn->input);
704
auth_handle_line(ctx->conn, line);
707
/* wait for more data */
708
io_loop_set_current(ctx->conn->ioloop);
709
io_loop_run(ctx->conn->ioloop);
710
io_loop_set_current(ctx->conn->prev_ioloop);
713
if (ctx->finished || ctx->failed)
715
return str_c(ctx->username);
690
718
int auth_master_user_list_deinit(struct auth_master_user_list_ctx **_ctx)