From: Timo Sirainen Date: Mon, 19 Oct 2009 19:02:04 +0000 (-0400) Subject: lib-auth: Changed auth_master_user_lookup() API. X-Git-Tag: 2.0.alpha2~65 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9f10cc61ec303351b43e54155c86699ef53cb8be;p=thirdparty%2Fdovecot%2Fcore.git lib-auth: Changed auth_master_user_lookup() API. --HG-- branch : HEAD --- diff --git a/src/doveadm/doveadm-auth.c b/src/doveadm/doveadm-auth.c index f52ec41831..2077b6e2bf 100644 --- a/src/doveadm/doveadm-auth.c +++ b/src/doveadm/doveadm-auth.c @@ -26,9 +26,7 @@ cmd_user_input(const char *auth_socket_path, const struct authtest_input *input) { struct auth_master_connection *conn; pool_t pool; - struct auth_user_reply reply; - const char *const *fields; - unsigned int i, count; + const char *username, *const *fields, *p; int ret; if (auth_socket_path == NULL) @@ -38,7 +36,7 @@ cmd_user_input(const char *auth_socket_path, const struct authtest_input *input) conn = auth_master_init(auth_socket_path, FALSE); ret = auth_master_user_lookup(conn, input->username, &input->info, - pool, &reply); + pool, &username, &fields); if (ret < 0) i_fatal("userdb lookup failed"); else if (ret == 0) { @@ -47,21 +45,14 @@ cmd_user_input(const char *auth_socket_path, const struct authtest_input *input) } else { printf("userdb: %s\n", input->username); - if (reply.uid != (uid_t)-1) - printf("uid : %s\n", dec2str(reply.uid)); - if (reply.gid != (gid_t)-1) - printf("gid : %s\n", dec2str(reply.gid)); - if (reply.user != NULL) - printf("user : %s\n", reply.user); - if (reply.home != NULL) - printf("home : %s\n", reply.home); - if (reply.chroot != NULL) - printf("chroot: %s\n", reply.chroot); - fields = array_get(&reply.extra_fields, &count); - if (count > 0) { - printf("extra fields:\n"); - for (i = 0; i < count; i++) - printf(" %s\n", fields[i]); + for (; *fields; fields++) { + p = strchr(*fields, '='); + if (p == NULL) + printf(" %-10s\n", *fields); + else { + printf(" %-10s: %s\n", + t_strcut(*fields, '='), p + 1); + } } } auth_master_deinit(&conn); diff --git a/src/lib-auth/auth-master.c b/src/lib-auth/auth-master.c index c4864aa81f..042449128b 100644 --- a/src/lib-auth/auth-master.c +++ b/src/lib-auth/auth-master.c @@ -48,15 +48,9 @@ struct auth_master_connection { unsigned int aborted:1; }; -struct auth_master_user_lookup_ctx { - struct auth_master_connection *conn; - pool_t pool; - struct auth_user_reply *user_reply; - int return_value; -}; - -struct auth_master_pass_lookup_ctx { +struct auth_master_lookup_ctx { struct auth_master_connection *conn; + const char *expected_reply; int return_value; pool_t pool; @@ -117,36 +111,6 @@ static void auth_request_lookup_abort(struct auth_master_connection *conn) conn->aborted = TRUE; } -static void auth_parse_input(struct auth_master_user_lookup_ctx *ctx, - const char *const *args) -{ - struct auth_user_reply *reply = ctx->user_reply; - - memset(reply, 0, sizeof(*reply)); - reply->uid = (uid_t)-1; - reply->gid = (gid_t)-1; - p_array_init(&reply->extra_fields, ctx->pool, 64); - - reply->user = p_strdup(ctx->pool, *args); - for (args++; *args != NULL; args++) { - if (ctx->conn->debug) - i_debug("auth input: %s", *args); - - if (strncmp(*args, "uid=", 4) == 0) - reply->uid = strtoul(*args + 4, NULL, 10); - else if (strncmp(*args, "gid=", 4) == 0) - reply->gid = strtoul(*args + 4, NULL, 10); - else if (strncmp(*args, "home=", 5) == 0) - reply->home = p_strdup(ctx->pool, *args + 5); - else if (strncmp(*args, "chroot=", 7) == 0) - reply->chroot = p_strdup(ctx->pool, *args + 7); - else { - const char *field = p_strdup(ctx->pool, *args); - array_append(&reply->extra_fields, &field, 1); - } - } -} - static int auth_input_handshake(struct auth_master_connection *conn) { const char *line, *const *tmp; @@ -190,14 +154,24 @@ static int parse_reply(struct auth_master_connection *conn, return -1; } -static bool auth_user_reply_callback(const char *cmd, const char *const *args, - void *context) +static bool auth_lookup_reply_callback(const char *cmd, const char *const *args, + void *context) { - struct auth_master_user_lookup_ctx *ctx = context; + struct auth_master_lookup_ctx *ctx = context; + unsigned int i, len; + + ctx->return_value = + parse_reply(ctx->conn, cmd, args, ctx->expected_reply); + if (ctx->return_value > 0) { + len = str_array_length(args); + ctx->fields = p_new(ctx->pool, const char *, len + 1); + for (i = 0; i < len; i++) { + if (ctx->conn->debug) + i_debug("auth input: %s", *args); - ctx->return_value = parse_reply(ctx->conn, cmd, args, "USER"); - if (ctx->return_value > 0) - auth_parse_input(ctx, args); + ctx->fields[i] = p_strdup(ctx->pool, args[i]); + } + } return TRUE; } @@ -423,9 +397,10 @@ auth_user_info_export(string_t *str, const struct auth_user_info *info) int auth_master_user_lookup(struct auth_master_connection *conn, const char *user, const struct auth_user_info *info, - pool_t pool, struct auth_user_reply *reply_r) + pool_t pool, const char **username_r, + const char *const **fields_r) { - struct auth_master_user_lookup_ctx ctx; + struct auth_master_lookup_ctx ctx; string_t *str; if (!is_valid_string(user) || !is_valid_string(info->service)) { @@ -437,9 +412,9 @@ int auth_master_user_lookup(struct auth_master_connection *conn, ctx.conn = conn; ctx.return_value = -1; ctx.pool = pool; - ctx.user_reply = reply_r; + ctx.expected_reply = "USER"; - conn->reply_callback = auth_user_reply_callback; + conn->reply_callback = auth_lookup_reply_callback; conn->reply_context = &ctx; str = t_str_new(128); @@ -452,30 +427,49 @@ int auth_master_user_lookup(struct auth_master_connection *conn, (void)auth_master_run_cmd(conn, str_c(str)); conn->prefix = DEFAULT_USERDB_LOOKUP_PREFIX; + if (ctx.return_value <= 0 || ctx.fields[0] == NULL) { + *username_r = NULL; + *fields_r = NULL; + if (ctx.return_value > 0) { + i_error("Userdb lookup didn't return username"); + ctx.return_value = -1; + } + } else { + *username_r = ctx.fields[0]; + *fields_r = ctx.fields + 1; + } return ctx.return_value; } -static bool auth_pass_reply_callback(const char *cmd, const char *const *args, - void *context) +void auth_user_fields_parse(const char *const *fields, pool_t pool, + struct auth_user_reply *reply_r) { - struct auth_master_pass_lookup_ctx *ctx = context; - unsigned int i, len; - - ctx->return_value = parse_reply(ctx->conn, cmd, args, "PASS"); - if (ctx->return_value > 0) { - len = str_array_length(args); - ctx->fields = p_new(ctx->pool, const char *, len + 1); - for (i = 0; i < len; i++) - ctx->fields[i] = p_strdup(ctx->pool, args[i]); + memset(reply_r, 0, sizeof(*reply_r)); + reply_r->uid = (uid_t)-1; + reply_r->gid = (gid_t)-1; + p_array_init(&reply_r->extra_fields, pool, 64); + + for (; *fields != NULL; fields++) { + if (strncmp(*fields, "uid=", 4) == 0) + reply_r->uid = strtoul(*fields + 4, NULL, 10); + else if (strncmp(*fields, "gid=", 4) == 0) + reply_r->gid = strtoul(*fields + 4, NULL, 10); + else if (strncmp(*fields, "home=", 5) == 0) + reply_r->home = p_strdup(pool, *fields + 5); + else if (strncmp(*fields, "chroot=", 7) == 0) + reply_r->chroot = p_strdup(pool, *fields + 7); + else { + const char *field = p_strdup(pool, *fields); + array_append(&reply_r->extra_fields, &field, 1); + } } - return TRUE; } int auth_master_pass_lookup(struct auth_master_connection *conn, const char *user, const struct auth_user_info *info, pool_t pool, const char *const **fields_r) { - struct auth_master_pass_lookup_ctx ctx; + struct auth_master_lookup_ctx ctx; string_t *str; if (!is_valid_string(user) || !is_valid_string(info->service)) { @@ -487,8 +481,9 @@ int auth_master_pass_lookup(struct auth_master_connection *conn, ctx.conn = conn; ctx.return_value = -1; ctx.pool = pool; + ctx.expected_reply = "PASS"; - conn->reply_callback = auth_pass_reply_callback; + conn->reply_callback = auth_lookup_reply_callback; conn->reply_context = &ctx; str = t_str_new(128); diff --git a/src/lib-auth/auth-master.h b/src/lib-auth/auth-master.h index b12043b9e1..4eaf578b97 100644 --- a/src/lib-auth/auth-master.h +++ b/src/lib-auth/auth-master.h @@ -12,7 +12,7 @@ struct auth_user_info { struct auth_user_reply { uid_t uid; gid_t gid; - const char *user, *home, *chroot; + const char *home, *chroot; ARRAY_TYPE(const_string) extra_fields; }; @@ -23,12 +23,17 @@ void auth_master_deinit(struct auth_master_connection **conn); /* Do a USER lookup. Returns -1 = error, 0 = user not found, 1 = ok */ int auth_master_user_lookup(struct auth_master_connection *conn, const char *user, const struct auth_user_info *info, - pool_t pool, struct auth_user_reply *reply_r); + pool_t pool, const char **username_r, + const char *const **fields_r); /* Do a PASS lookup (the actual password isn't returned). */ int auth_master_pass_lookup(struct auth_master_connection *conn, const char *user, const struct auth_user_info *info, pool_t pool, const char *const **fields_r); +/* Parse userdb extra fields into auth_user_reply structure. */ +void auth_user_fields_parse(const char *const *fields, pool_t pool, + struct auth_user_reply *reply_r); + /* Iterate through all users. */ struct auth_master_user_list_ctx * auth_master_user_list_init(struct auth_master_connection *conn); diff --git a/src/lib-storage/mail-storage-service.c b/src/lib-storage/mail-storage-service.c index 94fec2b346..134d955f69 100644 --- a/src/lib-storage/mail-storage-service.c +++ b/src/lib-storage/mail-storage-service.c @@ -159,6 +159,7 @@ service_auth_userdb_lookup(struct auth_master_connection *conn, struct auth_user_info info; struct auth_user_reply reply; const char *system_groups_user, *orig_user = *user; + const char *new_username, *const *fields; unsigned int len; pool_t pool; int ret; @@ -169,11 +170,13 @@ service_auth_userdb_lookup(struct auth_master_connection *conn, info.remote_ip = input->remote_ip; pool = pool_alloconly_create("userdb lookup", 1024); - ret = auth_master_user_lookup(conn, *user, &info, pool, &reply); + ret = auth_master_user_lookup(conn, *user, &info, pool, + &new_username, &fields); if (ret > 0) { + auth_user_fields_parse(fields, pool, &reply); len = reply.chroot == NULL ? 0 : strlen(reply.chroot); - *user = t_strdup(reply.user); + *user = t_strdup(new_username); if (user_reply_handle(set_parser, user_set, &reply, &system_groups_user, error_r) < 0) ret = -1; diff --git a/src/lib-storage/mail-user.c b/src/lib-storage/mail-user.c index e9afeac1b7..013c85f489 100644 --- a/src/lib-storage/mail-user.c +++ b/src/lib-storage/mail-user.c @@ -244,6 +244,7 @@ int mail_user_get_home(struct mail_user *user, const char **home_r) struct auth_user_info info; struct auth_user_reply reply; pool_t userdb_pool; + const char *username, *const *fields; int ret; memset(&info, 0, sizeof(info)); @@ -260,10 +261,11 @@ int mail_user_get_home(struct mail_user *user, const char **home_r) userdb_pool = pool_alloconly_create("userdb lookup", 512); ret = auth_master_user_lookup(auth_master_conn, user->username, - &info, userdb_pool, &reply); + &info, userdb_pool, &username, &fields); if (ret < 0) *home_r = NULL; else { + auth_user_fields_parse(fields, userdb_pool, &reply); user->_home = ret == 0 ? NULL : p_strdup(user->pool, reply.home); user->home_looked_up = TRUE;