From: Timo Sirainen Date: Mon, 3 Aug 2020 11:56:12 +0000 (+0300) Subject: auth: Move imported/exported fields to struct auth_request_fields X-Git-Tag: 2.3.13~337 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5ff7299c9d85b1bab0c7d53d9459dbb31a2bd9d6;p=thirdparty%2Fdovecot%2Fcore.git auth: Move imported/exported fields to struct auth_request_fields This makes it clearer what fields are being passed between auth master and worker processes. --- diff --git a/src/auth/auth-cache.c b/src/auth/auth-cache.c index 931f6b4257..68842b23a1 100644 --- a/src/auth/auth-cache.c +++ b/src/auth/auth-cache.c @@ -346,8 +346,8 @@ auth_request_expand_cache_key(const struct auth_request *request, /* Uniquely identify the request's passdb/userdb with the P/U prefix and by "%!", which expands to the passdb/userdb ID number. */ key = t_strconcat(request->userdb_lookup ? "U" : "P", "%!", - request->master_user == NULL ? "" : "+%{master_user}", - "\t", key, NULL); + request->fields.master_user == NULL ? "" : "+%{master_user}", + "\t", key, NULL); /* It's fine to have unknown %variables in the cache key. For example db-ldap can have pass_attrs containing @@ -423,16 +423,16 @@ void auth_cache_insert(struct auth_cache *cache, struct auth_request *request, /* store into cache using the translated username, except if we're doing a master user login */ - current_username = request->user; - if (request->translated_username != NULL && - request->requested_login_user == NULL && - request->master_user == NULL) - request->user = t_strdup_noconst(request->translated_username); + current_username = request->fields.user; + if (request->fields.translated_username != NULL && + request->fields.requested_login_user == NULL && + request->fields.master_user == NULL) + request->fields.user = t_strdup_noconst(request->fields.translated_username); key = auth_request_expand_cache_key(request, key); key_len = strlen(key); - request->user = current_username; + request->fields.user = current_username; data_size = key_len + 1 + value_len + 1; alloc_size = sizeof(struct auth_cache_node) - diff --git a/src/auth/auth-master-connection.c b/src/auth/auth-master-connection.c index d878231113..6e7a8c6c2e 100644 --- a/src/auth/auth-master-connection.c +++ b/src/auth/auth-master-connection.c @@ -217,7 +217,7 @@ master_input_auth_request(struct auth_master_connection *conn, const char *args, (void)auth_request_import_info(auth_request, name, arg); } - if (auth_request->service == NULL) { + if (auth_request->fields.service == NULL) { auth_master_log_error(conn, "BUG: Master sent %s request without service", cmd); auth_request_unref(&auth_request); @@ -239,7 +239,7 @@ static int user_verify_restricted_uid(struct auth_request *auth_request) { struct auth_master_connection *conn = auth_request->master; - struct auth_fields *reply = auth_request->userdb_reply; + struct auth_fields *reply = auth_request->fields.userdb_reply; const char *value, *reason; uid_t uid; @@ -287,7 +287,7 @@ user_callback(enum userdb_result result, case USERDB_RESULT_INTERNAL_FAILURE: str_printfa(str, "FAIL\t%u", auth_request->id); if (auth_request->userdb_lookup_tempfailed) { - value = auth_fields_find(auth_request->userdb_reply, + value = auth_fields_find(auth_request->fields.userdb_reply, "reason"); if (value != NULL) str_printfa(str, "\treason=%s", value); @@ -298,9 +298,9 @@ user_callback(enum userdb_result result, break; case USERDB_RESULT_OK: str_printfa(str, "USER\t%u\t", auth_request->id); - str_append_tabescaped(str, auth_request->user); + str_append_tabescaped(str, auth_request->fields.user); str_append_c(str, '\t'); - auth_fields_append(auth_request->userdb_reply, str, + auth_fields_append(auth_request->fields.userdb_reply, str, AUTH_FIELD_FLAG_HIDDEN, 0); break; } @@ -350,10 +350,10 @@ static void pass_callback_finish(struct auth_request *auth_request, break; } str_printfa(str, "PASS\t%u\tuser=", auth_request->id); - str_append_tabescaped(str, auth_request->user); - if (!auth_fields_is_empty(auth_request->extra_fields)) { + str_append_tabescaped(str, auth_request->fields.user); + if (!auth_fields_is_empty(auth_request->fields.extra_fields)) { str_append_c(str, '\t'); - auth_fields_append(auth_request->extra_fields, + auth_fields_append(auth_request->fields.extra_fields, str, AUTH_FIELD_FLAG_HIDDEN, 0); } break; @@ -603,15 +603,16 @@ master_input_list(struct auth_master_connection *conn, const char *args) if (!auth_request_import_info(auth_request, name, arg) && strcmp(name, "user") == 0) { /* username mask */ - auth_request->user = p_strdup(auth_request->pool, arg); + auth_request->fields.user = + p_strdup(auth_request->pool, arg); } } /* rest of the code doesn't like NULL user or service */ - if (auth_request->user == NULL) - auth_request->user = ""; - if (auth_request->service == NULL) - auth_request->service = ""; + if (auth_request->fields.user == NULL) + auth_request->fields.user = ""; + if (auth_request->fields.service == NULL) + auth_request->fields.service = ""; ctx = i_new(struct master_list_iter_ctx, 1); ctx->conn = conn; diff --git a/src/auth/auth-penalty.c b/src/auth/auth-penalty.c index ab562b63b0..8fdc98dba0 100644 --- a/src/auth/auth-penalty.c +++ b/src/auth/auth-penalty.c @@ -104,7 +104,7 @@ auth_penalty_get_ident(struct auth_request *auth_request) { struct ip_addr ip; - ip = auth_request->remote_ip; + ip = auth_request->fields.remote_ip; if (IPADDR_IS_V6(&ip)) { memset(ip.u.ip6.s6_addr + PENALTY_IPV6_MASK_BITS/CHAR_BIT, 0, sizeof(ip.u.ip6.s6_addr) - @@ -121,7 +121,8 @@ void auth_penalty_lookup(struct auth_penalty *penalty, const char *ident; ident = auth_penalty_get_ident(auth_request); - if (penalty->disabled || ident == NULL || auth_request->no_penalty) { + if (penalty->disabled || ident == NULL || + auth_request->fields.no_penalty) { callback(0, auth_request); return; } @@ -144,7 +145,7 @@ get_userpass_checksum(struct auth_request *auth_request) { return auth_request->mech_password == NULL ? 0 : crc32_str_more(crc32_str(auth_request->mech_password), - auth_request->user); + auth_request->fields.user); } void auth_penalty_update(struct auth_penalty *penalty, @@ -153,7 +154,8 @@ void auth_penalty_update(struct auth_penalty *penalty, const char *ident; ident = auth_penalty_get_ident(auth_request); - if (penalty->disabled || ident == NULL || auth_request->no_penalty) + if (penalty->disabled || ident == NULL || + auth_request->fields.no_penalty) return; if (value > AUTH_PENALTY_MAX_PENALTY) { diff --git a/src/auth/auth-policy.c b/src/auth/auth-policy.c index e714a08e4d..397fa18c50 100644 --- a/src/auth/auth-policy.c +++ b/src/auth/auth-policy.c @@ -503,10 +503,10 @@ void auth_policy_create_json(struct policy_lookup_ctx *context, digest->loop(ctx, context->set->policy_hash_nonce, strlen(context->set->policy_hash_nonce)); - if (context->request->requested_login_user != NULL) - requested_username = context->request->requested_login_user; - else if (context->request->user != NULL) - requested_username = context->request->user; + if (context->request->fields.requested_login_user != NULL) + requested_username = context->request->fields.requested_login_user; + else if (context->request->fields.user != NULL) + requested_username = context->request->fields.user; else requested_username = ""; /* use +1 to make sure \0 gets included */ @@ -531,7 +531,8 @@ void auth_policy_create_json(struct policy_lookup_ctx *context, } if (include_success) { str_append(context->json, ",\"success\":"); - if (!context->request->failed && context->request->successful && + if (!context->request->failed && + context->request->fields.successful && !context->request->internal_failure) str_append(context->json, "true"); else @@ -540,7 +541,7 @@ void auth_policy_create_json(struct policy_lookup_ctx *context, str_append(context->json, context->request->policy_refusal ? "true" : "false"); } str_append(context->json, ",\"tls\":"); - if (context->request->secured == AUTH_REQUEST_SECURED_TLS) + if (context->request->fields.secured == AUTH_REQUEST_SECURED_TLS) str_append(context->json, "true"); else str_append(context->json, "false"); diff --git a/src/auth/auth-request-handler.c b/src/auth/auth-request-handler.c index f10aa54e4b..d9a084d990 100644 --- a/src/auth/auth-request-handler.c +++ b/src/auth/auth-request-handler.c @@ -169,43 +169,45 @@ auth_str_add_keyvalue(string_t *dest, const char *key, const char *value) static void auth_str_append_extra_fields(struct auth_request *request, string_t *dest) { - if (!auth_fields_is_empty(request->extra_fields)) { + const struct auth_request_fields *fields = &request->fields; + + if (!auth_fields_is_empty(fields->extra_fields)) { str_append_c(dest, '\t'); - auth_fields_append(request->extra_fields, dest, + auth_fields_append(fields->extra_fields, dest, AUTH_FIELD_FLAG_HIDDEN, 0); } - if (request->original_username != NULL && - null_strcmp(request->original_username, request->user) != 0 && - !auth_fields_exists(request->extra_fields, "original_user")) { + if (fields->original_username != NULL && + null_strcmp(fields->original_username, fields->user) != 0 && + !auth_fields_exists(fields->extra_fields, "original_user")) { auth_str_add_keyvalue(dest, "original_user", - request->original_username); + fields->original_username); } - if (request->master_user != NULL && - !auth_fields_exists(request->extra_fields, "auth_user")) - auth_str_add_keyvalue(dest, "auth_user", request->master_user); + if (fields->master_user != NULL && + !auth_fields_exists(fields->extra_fields, "auth_user")) + auth_str_add_keyvalue(dest, "auth_user", fields->master_user); if (*request->set->anonymous_username != '\0' && - null_strcmp(request->user, request->set->anonymous_username) == 0) { + null_strcmp(fields->user, request->set->anonymous_username) == 0) { /* this is an anonymous login, either via ANONYMOUS SASL mechanism or simply logging in as the anonymous user via another mechanism */ str_append(dest, "\tanonymous"); } if (!request->auth_only && - auth_fields_exists(request->extra_fields, "proxy")) { + auth_fields_exists(fields->extra_fields, "proxy")) { /* we're proxying */ - if (!auth_fields_exists(request->extra_fields, "pass") && + if (!auth_fields_exists(fields->extra_fields, "pass") && request->mech_password != NULL) { /* send back the password that was sent by user (not the password in passdb). */ auth_str_add_keyvalue(dest, "pass", request->mech_password); } - if (request->master_user != NULL && - !auth_fields_exists(request->extra_fields, "master")) { + if (fields->master_user != NULL && + !auth_fields_exists(fields->extra_fields, "master")) { /* the master username needs to be forwarded */ auth_str_add_keyvalue(dest, "master", - request->master_user); + fields->master_user); } } } @@ -231,7 +233,7 @@ auth_request_handle_failure(struct auth_request *request, const char *reply) if (request->set->policy_report_after_auth) auth_policy_report(request); - if (auth_fields_exists(request->extra_fields, "nodelay")) { + if (auth_fields_exists(request->fields.extra_fields, "nodelay")) { /* passdb specifically requested not to delay the reply. */ handler->callback(reply, handler->conn); auth_request_unref(&request); @@ -272,19 +274,19 @@ auth_request_handler_reply_success_finish(struct auth_request *request) /* sanitize these fields, since the login code currently assumes they are exactly in this format. */ - auth_fields_booleanize(request->extra_fields, "nologin"); - auth_fields_booleanize(request->extra_fields, "proxy"); + auth_fields_booleanize(request->fields.extra_fields, "nologin"); + auth_fields_booleanize(request->fields.extra_fields, "proxy"); str_printfa(str, "OK\t%u\tuser=", request->id); - str_append_tabescaped(str, request->user); + str_append_tabescaped(str, request->fields.user); auth_str_append_extra_fields(request, str); if (request->set->policy_report_after_auth) auth_policy_report(request); if (handler->master_callback == NULL || - auth_fields_exists(request->extra_fields, "nologin") || - auth_fields_exists(request->extra_fields, "proxy")) { + auth_fields_exists(request->fields.extra_fields, "nologin") || + auth_fields_exists(request->fields.extra_fields, "proxy")) { /* this request doesn't have to wait for master process to pick it up. delete it */ auth_request_handler_remove(handler, request); @@ -299,19 +301,19 @@ auth_request_handler_reply_failure_finish(struct auth_request *request) const char *code = NULL; string_t *str = t_str_new(128); - auth_fields_remove(request->extra_fields, "nologin"); + auth_fields_remove(request->fields.extra_fields, "nologin"); str_printfa(str, "FAIL\t%u", request->id); - if (request->user != NULL) - auth_str_add_keyvalue(str, "user", request->user); - else if (request->original_username != NULL) { + if (request->fields.user != NULL) + auth_str_add_keyvalue(str, "user", request->fields.user); + else if (request->fields.original_username != NULL) { auth_str_add_keyvalue(str, "user", - request->original_username); + request->fields.original_username); } if (request->internal_failure) { code = AUTH_CLIENT_FAIL_CODE_TEMPFAIL; - } else if (request->master_user != NULL) { + } else if (request->fields.master_user != NULL) { /* authentication succeeded, but we can't log in as the wanted user */ code = AUTH_CLIENT_FAIL_CODE_AUTHZFAILED; @@ -333,7 +335,7 @@ auth_request_handler_reply_failure_finish(struct auth_request *request) } } - if (auth_fields_exists(request->extra_fields, "nodelay")) { + if (auth_fields_exists(request->fields.extra_fields, "nodelay")) { /* this is normally a hidden field, need to add it explicitly */ str_append(str, "\tnodelay"); } @@ -400,7 +402,7 @@ auth_request_handler_default_reply_callback(struct auth_request *request, if (reply_size > 0) { str = t_str_new(MAX_BASE64_ENCODED_SIZE(reply_size)); base64_encode(auth_reply, reply_size, str); - auth_fields_add(request->extra_fields, "resp", + auth_fields_add(request->fields.extra_fields, "resp", str_c(str), 0); } ret = auth_request_proxy_finish(request, @@ -585,7 +587,7 @@ bool auth_request_handler_auth_begin(struct auth_request_handler *handler, return FALSE; } - if (request->service == NULL) { + if (request->fields.service == NULL) { i_error("BUG: Authentication client %u " "didn't specify service in request", handler->client_pid); @@ -605,7 +607,7 @@ bool auth_request_handler_auth_begin(struct auth_request_handler *handler, hash_table_insert(handler->requests, POINTER_CAST(id), request); if (request->set->ssl_require_client_cert && - !request->valid_client_cert) { + !request->fields.valid_client_cert) { /* we fail without valid certificate */ auth_request_handler_auth_fail(handler, request, "Client didn't present valid SSL certificate"); @@ -614,7 +616,7 @@ bool auth_request_handler_auth_begin(struct auth_request_handler *handler, if (request->set->ssl_require_client_cert && request->set->ssl_username_from_cert && - !request->cert_username) { + !request->fields.cert_username) { auth_request_handler_auth_fail(handler, request, "SSL certificate didn't contain username"); return TRUE; @@ -721,17 +723,17 @@ static void auth_str_append_userdb_extra_fields(struct auth_request *request, string_t *dest) { str_append_c(dest, '\t'); - auth_fields_append(request->userdb_reply, dest, + auth_fields_append(request->fields.userdb_reply, dest, AUTH_FIELD_FLAG_HIDDEN, 0); - if (request->master_user != NULL && - !auth_fields_exists(request->userdb_reply, "master_user")) { + if (request->fields.master_user != NULL && + !auth_fields_exists(request->fields.userdb_reply, "master_user")) { auth_str_add_keyvalue(dest, "master_user", - request->master_user); + request->fields.master_user); } auth_str_add_keyvalue(dest, "auth_mech", request->mech->mech_name); if (*request->set->anonymous_username != '\0' && - strcmp(request->user, request->set->anonymous_username) == 0) { + strcmp(request->fields.user, request->set->anonymous_username) == 0) { /* this is an anonymous login, either via ANONYMOUS SASL mechanism or simply logging in as the anonymous user via another mechanism */ @@ -741,18 +743,20 @@ static void auth_str_append_userdb_extra_fields(struct auth_request *request, if (request->request_auth_token && request->session_pid != (pid_t)-1) { const char *auth_token = - auth_token_get(request->service, + auth_token_get(request->fields.service, dec2str(request->session_pid), - request->user, - request->session_id); + request->fields.user, + request->fields.session_id); auth_str_add_keyvalue(dest, "auth_token", auth_token); } - if (request->master_user != NULL) { - auth_str_add_keyvalue(dest, "auth_user", request->master_user); - } else if (request->original_username != NULL && - strcmp(request->original_username, request->user) != 0) { + if (request->fields.master_user != NULL) { + auth_str_add_keyvalue(dest, "auth_user", + request->fields.master_user); + } else if (request->fields.original_username != NULL && + strcmp(request->fields.original_username, + request->fields.user) != 0) { auth_str_add_keyvalue(dest, "auth_user", - request->original_username); + request->fields.original_username); } } @@ -775,7 +779,8 @@ static void userdb_callback(enum userdb_result result, case USERDB_RESULT_INTERNAL_FAILURE: str_printfa(str, "FAIL\t%u", request->id); if (request->userdb_lookup_tempfailed) { - value = auth_fields_find(request->userdb_reply, "reason"); + value = auth_fields_find(request->fields.userdb_reply, + "reason"); if (value != NULL) auth_str_add_keyvalue(str, "reason", value); } @@ -785,7 +790,7 @@ static void userdb_callback(enum userdb_result result, break; case USERDB_RESULT_OK: str_printfa(str, "USER\t%u\t", request->id); - str_append_tabescaped(str, request->user); + str_append_tabescaped(str, request->fields.user); auth_str_append_userdb_extra_fields(request, str); break; } @@ -853,7 +858,7 @@ bool auth_request_handler_master_request(struct auth_request_handler *handler, } if (request->state != AUTH_REQUEST_STATE_FINISHED || - !request->successful) { + !request->fields.successful) { auth_master_log_error(master, "Master requested unfinished authentication request " "%u.%u", handler->client_pid, client_id); diff --git a/src/auth/auth-request-stats.c b/src/auth/auth-request-stats.c index 6042ee6232..7af4e9a893 100644 --- a/src/auth/auth-request-stats.c +++ b/src/auth/auth-request-stats.c @@ -53,10 +53,10 @@ void auth_request_stats_send(struct auth_request *request) str = t_str_new(256); str_append(str, "ADD-USER\t"); - if (request->user != NULL) - str_append_tabescaped(str, request->user); + if (request->fields.user != NULL) + str_append_tabescaped(str, request->fields.user); str_append_c(str, '\t'); - str_append_tabescaped(str, request->service); + str_append_tabescaped(str, request->fields.service); str_append_c(str, '\t'); base64_encode(buf->data, buf->used, str); diff --git a/src/auth/auth-request-var-expand.c b/src/auth/auth-request-var-expand.c index b4eea8e063..7b79c90281 100644 --- a/src/auth/auth-request-var-expand.c +++ b/src/auth/auth-request-var-expand.c @@ -70,6 +70,7 @@ auth_request_get_var_expand_table_full(const struct auth_request *auth_request, auth_request_escape_func_t *escape_func, unsigned int *count) { + const struct auth_request_fields *fields = &auth_request->fields; const unsigned int auth_count = N_ELEMENTS(auth_request_var_expand_static_tab); struct var_expand_table *tab, *ret_tab; @@ -88,19 +89,19 @@ auth_request_get_var_expand_table_full(const struct auth_request *auth_request, memcpy(tab, auth_request_var_expand_static_tab, auth_count * sizeof(*tab)); - username = auth_request->user != NULL ? auth_request->user : ""; + username = fields->user != NULL ? fields->user : ""; tab[0].value = escape_func(username, auth_request); tab[1].value = escape_func(t_strcut(username, '@'), auth_request); tab[2].value = i_strchr_to_next(username, '@'); if (tab[2].value != NULL) tab[2].value = escape_func(tab[2].value, auth_request); - tab[3].value = escape_func(auth_request->service, auth_request); + tab[3].value = escape_func(fields->service, auth_request); /* tab[4] = we have no home dir */ - if (auth_request->local_ip.family != 0) - tab[5].value = net_ip2addr(&auth_request->local_ip); - if (auth_request->remote_ip.family != 0) - tab[6].value = net_ip2addr(&auth_request->remote_ip); + if (fields->local_ip.family != 0) + tab[5].value = net_ip2addr(&fields->local_ip); + if (fields->remote_ip.family != 0) + tab[6].value = net_ip2addr(&fields->remote_ip); tab[7].value = dec2str(auth_request->client_pid); if (auth_request->mech_password != NULL) { tab[8].value = escape_func(auth_request->mech_password, @@ -113,20 +114,20 @@ auth_request_get_var_expand_table_full(const struct auth_request *auth_request, tab[9].value = auth_request->passdb == NULL ? "" : dec2str(auth_request->passdb->passdb->id); } - tab[10].value = auth_request->mech_name == NULL ? "" : - escape_func(auth_request->mech_name, auth_request); - switch(auth_request->secured) { + tab[10].value = fields->mech_name == NULL ? "" : + escape_func(fields->mech_name, auth_request); + switch (fields->secured) { case AUTH_REQUEST_SECURED_NONE: tab[11].value = ""; break; case AUTH_REQUEST_SECURED: tab[11].value = "secured"; break; case AUTH_REQUEST_SECURED_TLS: tab[11].value = "TLS"; break; default: tab[11].value = ""; break; }; - tab[12].value = dec2str(auth_request->local_port); - tab[13].value = dec2str(auth_request->remote_port); - tab[14].value = auth_request->valid_client_cert ? "valid" : ""; + tab[12].value = dec2str(fields->local_port); + tab[13].value = dec2str(fields->remote_port); + tab[14].value = fields->valid_client_cert ? "valid" : ""; - if (auth_request->requested_login_user != NULL) { - const char *login_user = auth_request->requested_login_user; + if (fields->requested_login_user != NULL) { + const char *login_user = fields->requested_login_user; tab[15].value = escape_func(login_user, auth_request); tab[16].value = escape_func(t_strcut(login_user, '@'), @@ -137,14 +138,14 @@ auth_request_get_var_expand_table_full(const struct auth_request *auth_request, auth_request); } } - tab[18].value = auth_request->session_id == NULL ? NULL : - escape_func(auth_request->session_id, auth_request); - if (auth_request->real_local_ip.family != 0) - tab[19].value = net_ip2addr(&auth_request->real_local_ip); - if (auth_request->real_remote_ip.family != 0) - tab[20].value = net_ip2addr(&auth_request->real_remote_ip); - tab[21].value = dec2str(auth_request->real_local_port); - tab[22].value = dec2str(auth_request->real_remote_port); + tab[18].value = fields->session_id == NULL ? NULL : + escape_func(fields->session_id, auth_request); + if (fields->real_local_ip.family != 0) + tab[19].value = net_ip2addr(&fields->real_local_ip); + if (fields->real_remote_ip.family != 0) + tab[20].value = net_ip2addr(&fields->real_remote_ip); + tab[21].value = dec2str(fields->real_local_port); + tab[22].value = dec2str(fields->real_remote_port); tab[23].value = i_strchr_to_next(username, '@'); if (tab[23].value != NULL) { tab[23].value = escape_func(t_strcut(tab[23].value, '@'), @@ -153,21 +154,21 @@ auth_request_get_var_expand_table_full(const struct auth_request *auth_request, tab[24].value = strrchr(username, '@'); if (tab[24].value != NULL) tab[24].value = escape_func(tab[24].value+1, auth_request); - tab[25].value = auth_request->master_user == NULL ? NULL : - escape_func(auth_request->master_user, auth_request); + tab[25].value = fields->master_user == NULL ? NULL : + escape_func(fields->master_user, auth_request); tab[26].value = auth_request->session_pid == (pid_t)-1 ? NULL : dec2str(auth_request->session_pid); - orig_user = auth_request->original_username != NULL ? - auth_request->original_username : username; + orig_user = fields->original_username != NULL ? + fields->original_username : username; tab[27].value = escape_func(orig_user, auth_request); tab[28].value = escape_func(t_strcut(orig_user, '@'), auth_request); tab[29].value = i_strchr_to_next(orig_user, '@'); if (tab[29].value != NULL) tab[29].value = escape_func(tab[29].value, auth_request); - if (auth_request->master_user != NULL) - auth_user = auth_request->master_user; + if (fields->master_user != NULL) + auth_user = fields->master_user; else auth_user = orig_user; tab[30].value = escape_func(auth_user, auth_request); @@ -175,10 +176,10 @@ auth_request_get_var_expand_table_full(const struct auth_request *auth_request, tab[32].value = i_strchr_to_next(auth_user, '@'); if (tab[32].value != NULL) tab[32].value = escape_func(tab[32].value, auth_request); - if (auth_request->local_name != NULL) - tab[33].value = escape_func(auth_request->local_name, auth_request); - if (auth_request->client_id != NULL) - tab[34].value = escape_func(auth_request->client_id, auth_request); + if (fields->local_name != NULL) + tab[33].value = escape_func(fields->local_name, auth_request); + if (fields->client_id != NULL) + tab[34].value = escape_func(fields->client_id, auth_request); return ret_tab; } @@ -214,7 +215,7 @@ auth_request_var_expand_func_passdb(const char *data, void *context, const char *field_name = t_strcut(data, ':'); const char *value; - value = auth_fields_find(ctx->auth_request->extra_fields, field_name); + value = auth_fields_find(ctx->auth_request->fields.extra_fields, field_name); *value_r = ctx->escape_func(value != NULL ? value : field_get_default(data), ctx->auth_request); return 1; @@ -229,8 +230,8 @@ auth_request_var_expand_func_userdb(const char *data, void *context, const char *field_name = t_strcut(data, ':'); const char *value; - value = ctx->auth_request->userdb_reply == NULL ? NULL : - auth_fields_find(ctx->auth_request->userdb_reply, field_name); + value = ctx->auth_request->fields.userdb_reply == NULL ? NULL : + auth_fields_find(ctx->auth_request->fields.userdb_reply, field_name); *value_r = ctx->escape_func(value != NULL ? value : field_get_default(data), ctx->auth_request); return 1; diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index f2cd07a629..4211664982 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -107,7 +107,7 @@ static void auth_request_post_alloc_init(struct auth_request *request, struct ev request->last_access = ioloop_time; request->session_pid = (pid_t)-1; request->set = global_auth_settings; - request->extra_fields = auth_fields_init(request->pool); + request->fields.extra_fields = auth_fields_init(request->pool); request->event = event_create(parent_event); request->mech_event = event_create(request->event); @@ -130,7 +130,7 @@ auth_request_new(const struct mech_module *mech, struct event *parent_event) request = mech->auth_new(); auth_request_post_alloc_init(request, parent_event); request->mech = mech; - request->mech_name = mech->mech_name; + request->fields.mech_name = mech->mech_name; event_add_str(request->event, "mech", request->mech->mech_name); return request; @@ -177,7 +177,7 @@ void auth_request_init(struct auth_request *request) struct auth *auth_request_get_auth(struct auth_request *request) { - return auth_find_service(request->service); + return auth_find_service(request->fields.service); } void auth_request_success(struct auth_request *request, @@ -209,21 +209,21 @@ auth_request_finished_event(struct auth_request *request, struct event *event) { struct event_passthrough *e = event_create_passthrough(event); - e->add_str("user", request->user); - e->add_str("orig_user", request->original_username); - e->add_str("translated_user", request->translated_username); - e->add_str("login_user", request->requested_login_user); - e->add_str("master_user", request->master_user); + e->add_str("user", request->fields.user); + e->add_str("orig_user", request->fields.original_username); + e->add_str("translated_user", request->fields.translated_username); + e->add_str("login_user", request->fields.requested_login_user); + e->add_str("master_user", request->fields.master_user); if (request->failed) { if (request->internal_failure) { e->add_str("error", "internal failure"); } else { e->add_str("error", "authentication failed"); } - } else if (request->successful) { + } else if (request->fields.successful) { e->add_str("success", "yes"); } - switch(request->secured) { + switch (request->fields.secured) { case AUTH_REQUEST_SECURED_NONE: e->add_str("transport", "insecure"); break; @@ -240,7 +240,7 @@ auth_request_finished_event(struct auth_request *request, struct event *event) return e; } e->add_str("credentials_scheme", request->credentials_scheme); - e->add_str("realm", request->realm); + e->add_str("realm", request->fields.realm); if (request->policy_penalty > 0) e->add_int("policy_penalty", request->policy_penalty); if (request->policy_refusal) { @@ -281,7 +281,7 @@ void auth_request_success_continue(struct auth_policy_check_ctx *ctx) auth_request_fail(request); return; } - request->successful = TRUE; + request->fields.successful = TRUE; /* log before delay */ auth_request_log_finished(request); @@ -293,7 +293,7 @@ void auth_request_success_continue(struct auth_policy_check_ctx *ctx) return; } - if (ctx->success_data->used > 0 && !request->final_resp_ok) { + if (ctx->success_data->used > 0 && !request->fields.final_resp_ok) { /* we'll need one more SASL round, since client doesn't support the final SASL response */ auth_request_handler_reply_continue(request, @@ -304,7 +304,7 @@ void auth_request_success_continue(struct auth_policy_check_ctx *ctx) if (request->set->stats) { stats = auth_request_stats_get(request); stats->auth_success_count++; - if (request->master_user != NULL) + if (request->fields.master_user != NULL) stats->auth_master_success_count++; } @@ -404,128 +404,130 @@ auth_request_export_fields(string_t *dest, struct auth_fields *auth_fields, void auth_request_export(struct auth_request *request, string_t *dest) { + const struct auth_request_fields *fields = &request->fields; + str_append(dest, "user="); - str_append_tabescaped(dest, request->user); + str_append_tabescaped(dest, fields->user); - auth_str_add_keyvalue(dest, "service", request->service); + auth_str_add_keyvalue(dest, "service", fields->service); - if (request->master_user != NULL) { - auth_str_add_keyvalue(dest, "master-user", - request->master_user); - } + if (fields->master_user != NULL) + auth_str_add_keyvalue(dest, "master-user", fields->master_user); auth_str_add_keyvalue(dest, "original-username", - request->original_username); - if (request->requested_login_user != NULL) { + fields->original_username); + if (fields->requested_login_user != NULL) { auth_str_add_keyvalue(dest, "requested-login-user", - request->requested_login_user); + fields->requested_login_user); } - if (request->local_ip.family != 0) { + if (fields->local_ip.family != 0) { auth_str_add_keyvalue(dest, "lip", - net_ip2addr(&request->local_ip)); + net_ip2addr(&fields->local_ip)); } - if (request->remote_ip.family != 0) { + if (fields->remote_ip.family != 0) { auth_str_add_keyvalue(dest, "rip", - net_ip2addr(&request->remote_ip)); + net_ip2addr(&fields->remote_ip)); } - if (request->local_port != 0) - str_printfa(dest, "\tlport=%u", request->local_port); - if (request->remote_port != 0) - str_printfa(dest, "\trport=%u", request->remote_port); - if (request->real_local_ip.family != 0) { + if (fields->local_port != 0) + str_printfa(dest, "\tlport=%u", fields->local_port); + if (fields->remote_port != 0) + str_printfa(dest, "\trport=%u", fields->remote_port); + if (fields->real_local_ip.family != 0) { auth_str_add_keyvalue(dest, "real_lip", - net_ip2addr(&request->real_local_ip)); + net_ip2addr(&fields->real_local_ip)); } - if (request->real_remote_ip.family != 0) { + if (fields->real_remote_ip.family != 0) { auth_str_add_keyvalue(dest, "real_rip", - net_ip2addr(&request->real_remote_ip)); + net_ip2addr(&fields->real_remote_ip)); } - if (request->real_local_port != 0) - str_printfa(dest, "\treal_lport=%u", request->real_local_port); - if (request->real_remote_port != 0) - str_printfa(dest, "\treal_rport=%u", request->real_remote_port); - if (request->local_name != 0) { + if (fields->real_local_port != 0) + str_printfa(dest, "\treal_lport=%u", fields->real_local_port); + if (fields->real_remote_port != 0) + str_printfa(dest, "\treal_rport=%u", fields->real_remote_port); + if (fields->local_name != 0) { str_append(dest, "\tlocal_name="); - str_append_tabescaped(dest, request->local_name); + str_append_tabescaped(dest, fields->local_name); } - if (request->session_id != NULL) - str_printfa(dest, "\tsession=%s", request->session_id); + if (fields->session_id != NULL) + str_printfa(dest, "\tsession=%s", fields->session_id); if (event_want_debug(request->event)) str_append(dest, "\tdebug"); - switch(request->secured) { + switch (fields->secured) { case AUTH_REQUEST_SECURED_NONE: break; case AUTH_REQUEST_SECURED: str_append(dest, "\tsecured"); break; case AUTH_REQUEST_SECURED_TLS: str_append(dest, "\tsecured=tls"); break; default: break; } - if (request->skip_password_check) + if (fields->skip_password_check) str_append(dest, "\tskip-password-check"); - if (request->delayed_credentials != NULL) + if (fields->delayed_credentials != NULL) str_append(dest, "\tdelayed-credentials"); - if (request->valid_client_cert) + if (fields->valid_client_cert) str_append(dest, "\tvalid-client-cert"); - if (request->no_penalty) + if (fields->no_penalty) str_append(dest, "\tno-penalty"); - if (request->successful) + if (fields->successful) str_append(dest, "\tsuccessful"); - if (request->mech_name != NULL) - auth_str_add_keyvalue(dest, "mech", request->mech_name); - if (request->client_id != NULL) - auth_str_add_keyvalue(dest, "client_id", request->client_id); + if (fields->mech_name != NULL) + auth_str_add_keyvalue(dest, "mech", fields->mech_name); + if (fields->client_id != NULL) + auth_str_add_keyvalue(dest, "client_id", fields->client_id); /* export passdb extra fields */ - auth_request_export_fields(dest, request->extra_fields, "passdb_"); + auth_request_export_fields(dest, fields->extra_fields, "passdb_"); /* export any userdb fields */ - if (request->userdb_reply != NULL) - auth_request_export_fields(dest, request->userdb_reply, "userdb_"); + if (fields->userdb_reply != NULL) + auth_request_export_fields(dest, fields->userdb_reply, "userdb_"); } bool auth_request_import_info(struct auth_request *request, const char *key, const char *value) { + struct auth_request_fields *fields = &request->fields; + i_assert(value != NULL); /* authentication and user lookups may set these */ if (strcmp(key, "service") == 0) - request->service = p_strdup(request->pool, value); + fields->service = p_strdup(request->pool, value); else if (strcmp(key, "lip") == 0) { - (void)net_addr2ip(value, &request->local_ip); - if (request->real_local_ip.family == 0) - request->real_local_ip = request->local_ip; + (void)net_addr2ip(value, &fields->local_ip); + if (fields->real_local_ip.family == 0) + fields->real_local_ip = fields->local_ip; } else if (strcmp(key, "rip") == 0) { - (void)net_addr2ip(value, &request->remote_ip); - if (request->real_remote_ip.family == 0) - request->real_remote_ip = request->remote_ip; + (void)net_addr2ip(value, &fields->remote_ip); + if (fields->real_remote_ip.family == 0) + fields->real_remote_ip = fields->remote_ip; } else if (strcmp(key, "lport") == 0) { - (void)net_str2port(value, &request->local_port); - if (request->real_local_port == 0) - request->real_local_port = request->local_port; + (void)net_str2port(value, &fields->local_port); + if (fields->real_local_port == 0) + fields->real_local_port = fields->local_port; } else if (strcmp(key, "rport") == 0) { - (void)net_str2port(value, &request->remote_port); - if (request->real_remote_port == 0) - request->real_remote_port = request->remote_port; + (void)net_str2port(value, &fields->remote_port); + if (fields->real_remote_port == 0) + fields->real_remote_port = fields->remote_port; } else if (strcmp(key, "real_lip") == 0) - (void)net_addr2ip(value, &request->real_local_ip); + (void)net_addr2ip(value, &fields->real_local_ip); else if (strcmp(key, "real_rip") == 0) - (void)net_addr2ip(value, &request->real_remote_ip); + (void)net_addr2ip(value, &fields->real_remote_ip); else if (strcmp(key, "real_lport") == 0) - (void)net_str2port(value, &request->real_local_port); + (void)net_str2port(value, &fields->real_local_port); else if (strcmp(key, "real_rport") == 0) - (void)net_str2port(value, &request->real_remote_port); + (void)net_str2port(value, &fields->real_remote_port); else if (strcmp(key, "local_name") == 0) - request->local_name = p_strdup(request->pool, value); + fields->local_name = p_strdup(request->pool, value); else if (strcmp(key, "session") == 0) - request->session_id = p_strdup(request->pool, value); + fields->session_id = p_strdup(request->pool, value); else if (strcmp(key, "debug") == 0) event_set_forced_debug(request->event, TRUE); else if (strcmp(key, "client_id") == 0) - request->client_id = p_strdup(request->pool, value); + fields->client_id = p_strdup(request->pool, value); else if (strcmp(key, "forward_fields") == 0) { - auth_fields_import_prefixed(request->extra_fields, + auth_fields_import_prefixed(fields->extra_fields, "forward_", value, 0); /* make sure the forward_ fields aren't deleted by auth_fields_rollback() if the first passdb lookup fails. */ - auth_fields_snapshot(request->extra_fields); + auth_fields_snapshot(fields->extra_fields); } else return FALSE; /* NOTE: keep in sync with auth_request_export() */ @@ -535,6 +537,8 @@ bool auth_request_import_info(struct auth_request *request, bool auth_request_import_auth(struct auth_request *request, const char *key, const char *value) { + struct auth_request_fields *fields = &request->fields; + i_assert(value != NULL); if (auth_request_import_info(request, key, value)) @@ -543,22 +547,22 @@ bool auth_request_import_auth(struct auth_request *request, /* auth client may set these */ if (strcmp(key, "secured") == 0) { if (strcmp(value, "tls") == 0) - request->secured = AUTH_REQUEST_SECURED_TLS; + fields->secured = AUTH_REQUEST_SECURED_TLS; else - request->secured = AUTH_REQUEST_SECURED; + fields->secured = AUTH_REQUEST_SECURED; } else if (strcmp(key, "final-resp-ok") == 0) - request->final_resp_ok = TRUE; + fields->final_resp_ok = TRUE; else if (strcmp(key, "no-penalty") == 0) - request->no_penalty = TRUE; + fields->no_penalty = TRUE; else if (strcmp(key, "valid-client-cert") == 0) - request->valid_client_cert = TRUE; + fields->valid_client_cert = TRUE; else if (strcmp(key, "cert_username") == 0) { if (request->set->ssl_username_from_cert && *value != '\0') { /* get username from SSL certificate. it overrides the username given by the auth mechanism. */ - request->user = p_strdup(request->pool, value); - request->cert_username = TRUE; + fields->user = p_strdup(request->pool, value); + fields->cert_username = TRUE; } } else { return FALSE; @@ -587,6 +591,8 @@ bool auth_request_import_master(struct auth_request *request, bool auth_request_import(struct auth_request *request, const char *key, const char *value) { + struct auth_request_fields *fields = &request->fields; + i_assert(value != NULL); if (auth_request_import_auth(request, key, value)) @@ -594,31 +600,31 @@ bool auth_request_import(struct auth_request *request, /* for communication between auth master and worker processes */ if (strcmp(key, "user") == 0) - request->user = p_strdup(request->pool, value); + fields->user = p_strdup(request->pool, value); else if (strcmp(key, "master-user") == 0) - request->master_user = p_strdup(request->pool, value); + fields->master_user = p_strdup(request->pool, value); else if (strcmp(key, "original-username") == 0) - request->original_username = p_strdup(request->pool, value); + fields->original_username = p_strdup(request->pool, value); else if (strcmp(key, "requested-login-user") == 0) - request->requested_login_user = p_strdup(request->pool, value); + fields->requested_login_user = p_strdup(request->pool, value); else if (strcmp(key, "successful") == 0) - request->successful = TRUE; + fields->successful = TRUE; else if (strcmp(key, "skip-password-check") == 0) - request->skip_password_check = TRUE; + fields->skip_password_check = TRUE; else if (strcmp(key, "delayed-credentials") == 0) { /* just make passdb_handle_credentials() work identically in auth-worker as it does in auth-master. the worker shouldn't care about the actual contents of the credentials. */ - request->delayed_credentials = &uchar_nul; - request->delayed_credentials_size = 1; + fields->delayed_credentials = &uchar_nul; + fields->delayed_credentials_size = 1; } else if (strcmp(key, "mech") == 0) - request->mech_name = p_strdup(request->pool, value); + fields->mech_name = p_strdup(request->pool, value); else if (str_begins(key, "passdb_")) - auth_fields_add(request->extra_fields, key+7, value, 0); + auth_fields_add(fields->extra_fields, key+7, value, 0); else if (str_begins(key, "userdb_")) { - if (request->userdb_reply == NULL) - request->userdb_reply = auth_fields_init(request->pool); - auth_fields_add(request->userdb_reply, key+7, value, 0); + if (fields->userdb_reply == NULL) + fields->userdb_reply = auth_fields_init(request->pool); + auth_fields_add(fields->userdb_reply, key+7, value, 0); } else return FALSE; @@ -657,7 +663,7 @@ void auth_request_continue(struct auth_request *request, { i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE); - if (request->successful) { + if (request->fields.successful) { auth_request_success(request, "", 0); return; } @@ -675,8 +681,10 @@ static void auth_request_save_cache(struct auth_request *request, struct auth_passdb *passdb = request->passdb; const char *encoded_password; string_t *str; - struct password_generate_params gen_params = {.user = request->user, - .rounds = 0 }; + struct password_generate_params gen_params = { + .user = request->fields.user, + .rounds = 0 + }; switch (result) { case PASSDB_RESULT_USER_UNKNOWN: @@ -708,7 +716,7 @@ static void auth_request_save_cache(struct auth_request *request, } if (request->passdb_password == NULL && - !auth_fields_exists(request->extra_fields, "nopassword")) { + !auth_fields_exists(request->fields.extra_fields, "nopassword")) { /* passdb didn't provide the correct password */ if (result != PASSDB_RESULT_OK || request->mech_password == NULL) @@ -739,13 +747,13 @@ static void auth_request_save_cache(struct auth_request *request, str_append_tabescaped(str, request->passdb_password); } - if (!auth_fields_is_empty(request->extra_fields)) { + if (!auth_fields_is_empty(request->fields.extra_fields)) { str_append_c(str, '\t'); /* add only those extra fields to cache that were set by this passdb lookup. the CHANGED flag does this, because we snapshotted the extra_fields before the current passdb lookup. */ - auth_fields_append(request->extra_fields, str, + auth_fields_append(request->fields.extra_fields, str, AUTH_FIELD_FLAG_CHANGED, AUTH_FIELD_FLAG_CHANGED); } @@ -761,11 +769,11 @@ static void auth_request_master_lookup_finish(struct auth_request *request) /* master login successful. update user and master_user variables. */ e_info(authdb_event(request), "Master user logging in as %s", - request->requested_login_user); + request->fields.requested_login_user); - request->master_user = request->user; - request->user = request->requested_login_user; - request->requested_login_user = NULL; + request->fields.master_user = request->fields.user; + request->fields.user = request->fields.requested_login_user; + request->fields.requested_login_user = NULL; } static bool @@ -821,7 +829,7 @@ auth_request_want_skip_passdb(struct auth_request *request, const char *const *username_filter = passdb->passdb->username_filter; const char *username; - username = request->user; + username = request->fields.user; if (!auth_request_mechanism_accepted(mechs, request->mech)) { auth_request_log_debug(request, @@ -842,7 +850,7 @@ auth_request_want_skip_passdb(struct auth_request *request, /* skip_password_check basically specifies if authentication is finished */ - bool authenticated = request->skip_password_check; + bool authenticated = request->fields.skip_password_check; switch (passdb->skip) { case AUTH_PASSDB_SKIP_NEVER: @@ -907,13 +915,13 @@ auth_request_lookup_end_common(struct auth_request *request, { const char *p; struct event_passthrough *e = event_create_passthrough(event)-> - add_str("user", request->user); - if (request->master_user != NULL) - e->add_str("master_user", request->master_user); - if ((p = strchr(request->user, '@')) == NULL) - e->add_str("username", request->user); + add_str("user", request->fields.user); + if (request->fields.master_user != NULL) + e->add_str("master_user", request->fields.master_user); + if ((p = strchr(request->fields.user, '@')) == NULL) + e->add_str("username", request->fields.user); else - e->add_str("username", t_strdup_until(request->user, p))-> + e->add_str("username", t_strdup_until(request->fields.user, p))-> add_str("domain", p + 1); return e; } @@ -1057,7 +1065,7 @@ auth_request_handle_passdb_callback(enum passdb_result *result, if (*result == PASSDB_RESULT_OK) { /* password was successfully verified. don't bother checking it again. */ - request->skip_password_check = TRUE; + request->fields.skip_password_check = TRUE; } break; case AUTH_DB_RULE_CONTINUE_OK: @@ -1065,7 +1073,7 @@ auth_request_handle_passdb_callback(enum passdb_result *result, request->passdb_success = TRUE; /* password was successfully verified. don't bother checking it again. */ - request->skip_password_check = TRUE; + request->fields.skip_password_check = TRUE; break; case AUTH_DB_RULE_CONTINUE_FAIL: passdb_continue = TRUE; @@ -1074,10 +1082,10 @@ auth_request_handle_passdb_callback(enum passdb_result *result, } /* nopassword check is specific to a single passdb and shouldn't leak to the next one. we already added it to cache. */ - auth_fields_remove(request->extra_fields, "nopassword"); - auth_fields_remove(request->extra_fields, "noauthenticate"); + auth_fields_remove(request->fields.extra_fields, "nopassword"); + auth_fields_remove(request->fields.extra_fields, "noauthenticate"); - if (request->requested_login_user != NULL && + if (request->fields.requested_login_user != NULL && *result == PASSDB_RESULT_OK) { auth_request_master_lookup_finish(request); /* if the passdb lookup continues, it continues with non-master @@ -1093,16 +1101,16 @@ auth_request_handle_passdb_callback(enum passdb_result *result, if (*result == PASSDB_RESULT_OK || *result == PASSDB_RESULT_NEXT) { /* this passdb lookup succeeded, preserve its extra fields */ - auth_fields_snapshot(request->extra_fields); + auth_fields_snapshot(request->fields.extra_fields); request->snapshot_have_userdb_prefetch_set = request->userdb_prefetch_set; - if (request->userdb_reply != NULL) - auth_fields_snapshot(request->userdb_reply); + if (request->fields.userdb_reply != NULL) + auth_fields_snapshot(request->fields.userdb_reply); } else { /* this passdb lookup failed, remove any extra fields it set */ - auth_fields_rollback(request->extra_fields); - if (request->userdb_reply != NULL) { - auth_fields_rollback(request->userdb_reply); + auth_fields_rollback(request->fields.extra_fields); + if (request->fields.userdb_reply != NULL) { + auth_fields_rollback(request->fields.userdb_reply); request->userdb_prefetch_set = request->snapshot_have_userdb_prefetch_set; } @@ -1176,7 +1184,7 @@ void auth_request_verify_plain_callback(enum passdb_result result, auth_request_set_state(request, AUTH_REQUEST_STATE_MECH_CONTINUE); if (result == PASSDB_RESULT_OK && - auth_fields_exists(request->extra_fields, "noauthenticate")) + auth_fields_exists(request->fields.extra_fields, "noauthenticate")) result = PASSDB_RESULT_NEXT; if (result != PASSDB_RESULT_INTERNAL_FAILURE) @@ -1219,7 +1227,7 @@ static bool password_has_illegal_chars(const char *password) static bool auth_request_is_disabled_master_user(struct auth_request *request) { - if (request->requested_login_user == NULL || + if (request->fields.requested_login_user == NULL || request->passdb != NULL) return FALSE; @@ -1227,7 +1235,7 @@ static bool auth_request_is_disabled_master_user(struct auth_request *request) e_info(request->mech_event, "Attempted master login with no master passdbs " "(trying to log in as user: %s)", - request->requested_login_user); + request->fields.requested_login_user); return TRUE; } @@ -1272,7 +1280,8 @@ void auth_request_policy_check_callback(int result, void *context) if (result < 0) { /* fail it right here and now */ auth_request_fail(ctx->request); - } else if (ctx->type != AUTH_POLICY_CHECK_TYPE_SUCCESS && result > 0 && !ctx->request->no_penalty) { + } else if (ctx->type != AUTH_POLICY_CHECK_TYPE_SUCCESS && result > 0 && + !ctx->request->fields.no_penalty) { ctx->request->to_penalty = timeout_add(result * 1000, auth_request_policy_penalty_finish, context); @@ -1391,28 +1400,28 @@ auth_request_lookup_credentials_finish(enum passdb_result result, } if (!auth_request_handle_passdb_callback(&result, request)) { /* try next passdb */ - if (request->skip_password_check && - request->delayed_credentials == NULL && size > 0) { + if (request->fields.skip_password_check && + request->fields.delayed_credentials == NULL && size > 0) { /* passdb continue* rule after a successful lookup. remember these credentials and use them later on. */ unsigned char *dup; dup = p_malloc(request->pool, size); memcpy(dup, credentials, size); - request->delayed_credentials = dup; - request->delayed_credentials_size = size; + request->fields.delayed_credentials = dup; + request->fields.delayed_credentials_size = size; } auth_request_lookup_credentials(request, request->credentials_scheme, request->private_callback.lookup_credentials); } else { - if (request->delayed_credentials != NULL && size == 0) { + if (request->fields.delayed_credentials != NULL && size == 0) { /* we did multiple passdb lookups, but the last one didn't provide any credentials (e.g. just wanted to add some extra fields). so use the first passdb's credentials instead. */ - credentials = request->delayed_credentials; - size = request->delayed_credentials_size; + credentials = request->fields.delayed_credentials; + size = request->fields.delayed_credentials_size; } if (request->set->debug_passwords && result == PASSDB_RESULT_OK) { @@ -1445,7 +1454,7 @@ void auth_request_lookup_credentials_callback(enum passdb_result result, auth_request_set_state(request, AUTH_REQUEST_STATE_MECH_CONTINUE); if (result == PASSDB_RESULT_OK && - auth_fields_exists(request->extra_fields, "noauthenticate")) + auth_fields_exists(request->fields.extra_fields, "noauthenticate")) result = PASSDB_RESULT_NEXT; if (result != PASSDB_RESULT_INTERNAL_FAILURE) @@ -1602,7 +1611,7 @@ static void auth_request_userdb_save_cache(struct auth_request *request, cache_value = ""; else { str = t_str_new(128); - auth_fields_append(request->userdb_reply, str, + auth_fields_append(request->fields.userdb_reply, str, AUTH_FIELD_FLAG_CHANGED, AUTH_FIELD_FLAG_CHANGED); if (request->user_changed_by_lookup) { @@ -1610,7 +1619,7 @@ static void auth_request_userdb_save_cache(struct auth_request *request, if (str_len(str) > 0) str_append_c(str, '\t'); str_append(str, "user="); - str_append_tabescaped(str, request->user); + str_append_tabescaped(str, request->fields.user); } if (str_len(str) == 0) { /* no userdb fields. but we can't save an empty string, @@ -1652,7 +1661,7 @@ static bool auth_request_lookup_user_cache(struct auth_request *request, if (*value == '\0') { /* negative cache entry */ *result_r = USERDB_RESULT_USER_UNKNOWN; - request->userdb_reply = auth_fields_init(request->pool); + request->fields.userdb_reply = auth_fields_init(request->pool); return TRUE; } @@ -1661,8 +1670,8 @@ static bool auth_request_lookup_user_cache(struct auth_request *request, Don't use auth_request_init_userdb_reply(), because the entire userdb part of the result comes from the cache so we don't want to initialize it with default_fields. */ - if (request->userdb_reply == NULL) - request->userdb_reply = auth_fields_init(request->pool); + if (request->fields.userdb_reply == NULL) + request->fields.userdb_reply = auth_fields_init(request->pool); auth_request_userdb_import(request, value); *result_r = USERDB_RESULT_OK; return TRUE; @@ -1737,11 +1746,11 @@ void auth_request_userdb_callback(enum userdb_result result, USERDB_RESULT_INTERNAL_FAILURE, request); return; } - auth_fields_snapshot(request->userdb_reply); + auth_fields_snapshot(request->fields.userdb_reply); } else { /* this userdb lookup failed, remove any extra fields it set */ - auth_fields_rollback(request->userdb_reply); + auth_fields_rollback(request->fields.userdb_reply); } request->user_changed_by_lookup = FALSE; @@ -1814,7 +1823,7 @@ void auth_request_lookup_user(struct auth_request *request, request->user_changed_by_lookup = FALSE; request->userdb_lookup = TRUE; request->userdb_result_from_cache = FALSE; - if (request->userdb_reply == NULL) + if (request->fields.userdb_reply == NULL) auth_request_init_userdb_reply(request); else { /* we still want to set default_fields. these override any @@ -1891,8 +1900,8 @@ auth_request_fix_username(struct auth_request *request, const char *username, char *old_username; string_t *dest; - old_username = request->user; - request->user = user; + old_username = request->fields.user; + request->fields.user = user; dest = t_str_new(256); if (auth_request_var_expand(dest, set->username_format, @@ -1903,7 +1912,7 @@ auth_request_fix_username(struct auth_request *request, const char *username, } user = p_strdup(request->pool, str_c(dest)); - request->user = old_username; + request->fields.user = old_username; } if (user[0] == '\0') { @@ -1932,24 +1941,25 @@ bool auth_request_set_username(struct auth_request *request, } } - if (request->original_username == NULL) { + if (request->fields.original_username == NULL) { /* the username may change later, but we need to use this username when verifying at least DIGEST-MD5 password. */ - request->original_username = p_strdup(request->pool, username); + request->fields.original_username = + p_strdup(request->pool, username); } - if (request->cert_username) { + if (request->fields.cert_username) { /* cert_username overrides the username given by authentication mechanism. but still do checks and translations to it. */ - username = request->user; + username = request->fields.user; } - request->user = auth_request_fix_username(request, username, error_r); - if (request->user == NULL) + request->fields.user = auth_request_fix_username(request, username, error_r); + if (request->fields.user == NULL) return FALSE; - if (request->translated_username == NULL) { + if (request->fields.translated_username == NULL) { /* similar to original_username, but after translations */ - request->translated_username = request->user; + request->fields.translated_username = request->fields.user; } request->user_changed_by_lookup = TRUE; @@ -1973,7 +1983,7 @@ bool auth_request_set_login_username(struct auth_request *request, return FALSE; } - if (strcmp(username, request->user) == 0) { + if (strcmp(username, request->fields.user) == 0) { /* The usernames are the same, we don't really wish to log in as someone else */ return TRUE; @@ -1987,15 +1997,15 @@ bool auth_request_set_login_username(struct auth_request *request, } request->passdb = master_passdb; - request->requested_login_user = + request->fields.requested_login_user = auth_request_fix_username(request, username, error_r); - if (request->requested_login_user == NULL) + if (request->fields.requested_login_user == NULL) return FALSE; e_debug(request->event, "%sMaster user lookup for login: %s", get_log_prefix_db(request), - request->requested_login_user); + request->fields.requested_login_user); return TRUE; } @@ -2105,7 +2115,7 @@ auth_request_try_update_username(struct auth_request *request, { const char *new_value; - new_value = get_updated_username(request->user, name, value); + new_value = get_updated_username(request->fields.user, name, value); if (new_value == NULL) return FALSE; if (new_value[0] == '\0') { @@ -2115,11 +2125,11 @@ auth_request_try_update_username(struct auth_request *request, return TRUE; } - if (strcmp(request->user, new_value) != 0) { + if (strcmp(request->fields.user, new_value) != 0) { e_debug(authdb_event(request), "username changed %s -> %s", - request->user, new_value); - request->user = p_strdup(request->pool, new_value); + request->fields.user, new_value); + request->fields.user = p_strdup(request->pool, new_value); request->user_changed_by_lookup = TRUE; } return TRUE; @@ -2151,12 +2161,12 @@ void auth_request_set_field(struct auth_request *request, if (name_len > 10 && strcmp(name+name_len-10, ":protected") == 0) { /* set this field only if it hasn't been set before */ name = t_strndup(name, name_len-10); - if (auth_fields_exists(request->extra_fields, name)) + if (auth_fields_exists(request->fields.extra_fields, name)) return; } else if (name_len > 7 && strcmp(name+name_len-7, ":remove") == 0) { /* remove this field entirely */ name = t_strndup(name, name_len-7); - auth_fields_remove(request->extra_fields, name); + auth_fields_remove(request->fields.extra_fields, name); return; } @@ -2174,9 +2184,11 @@ void auth_request_set_field(struct auth_request *request, /* don't change the original value so it gets saved correctly to cache. */ } else if (strcmp(name, "login_user") == 0) { - request->requested_login_user = p_strdup(request->pool, value); + request->fields.requested_login_user = + p_strdup(request->pool, value); } else if (strcmp(name, "allow_nets") == 0) { - auth_request_validate_networks(request, name, value, &request->remote_ip); + auth_request_validate_networks(request, name, value, + &request->fields.remote_ip); } else if (strcmp(name, "fail") == 0) { request->failed = TRUE; } else if (strcmp(name, "delay_until") == 0) { @@ -2213,11 +2225,12 @@ void auth_request_set_field(struct auth_request *request, request->delay_until = timestamp; } } else if (strcmp(name, "allow_real_nets") == 0) { - auth_request_validate_networks(request, name, value, &request->real_remote_ip); + auth_request_validate_networks(request, name, value, + &request->fields.real_remote_ip); } else if (str_begins(name, "userdb_")) { /* for prefetch userdb */ request->userdb_prefetch_set = TRUE; - if (request->userdb_reply == NULL) + if (request->fields.userdb_reply == NULL) auth_request_init_userdb_reply(request); if (strcmp(name, "userdb_userdb_import") == 0) { /* we can't put the whole userdb_userdb_import @@ -2231,14 +2244,14 @@ void auth_request_set_field(struct auth_request *request, } else if (strcmp(name, "noauthenticate") == 0) { /* add "nopassword" also so that passdbs won't try to verify the password. */ - auth_fields_add(request->extra_fields, name, value, 0); - auth_fields_add(request->extra_fields, "nopassword", NULL, 0); + auth_fields_add(request->fields.extra_fields, name, value, 0); + auth_fields_add(request->fields.extra_fields, "nopassword", NULL, 0); } else if (strcmp(name, "nopassword") == 0) { /* NULL password - anything goes */ const char *password = request->passdb_password; if (password != NULL && - !auth_fields_exists(request->extra_fields, "noauthenticate")) { + !auth_fields_exists(request->fields.extra_fields, "noauthenticate")) { (void)password_get_scheme(&password); if (*password != '\0') { e_error(authdb_event(request), @@ -2248,14 +2261,14 @@ void auth_request_set_field(struct auth_request *request, } } request->passdb_password = NULL; - auth_fields_add(request->extra_fields, name, value, 0); + auth_fields_add(request->fields.extra_fields, name, value, 0); return; } else if (strcmp(name, "passdb_import") == 0) { auth_request_passdb_import(request, value, "", default_scheme); return; } else { /* these fields are returned to client */ - auth_fields_add(request->extra_fields, name, value, 0); + auth_fields_add(request->fields.extra_fields, name, value, 0); return; } @@ -2263,7 +2276,7 @@ void auth_request_set_field(struct auth_request *request, a) auth cache is used, b) if we're a worker and we'll need to send this to the main auth process that can store it in the cache, c) for easily checking :protected fields' existence. */ - auth_fields_add(request->extra_fields, name, value, + auth_fields_add(request->fields.extra_fields, name, value, AUTH_FIELD_FLAG_HIDDEN); } @@ -2308,7 +2321,7 @@ void auth_request_init_userdb_reply(struct auth_request *request) { const char *error; - request->userdb_reply = auth_fields_init(request->pool); + request->fields.userdb_reply = auth_fields_init(request->pool); if (userdb_template_export(request->userdb->default_fields_tmpl, request, &error) < 0) { e_error(authdb_event(request), @@ -2334,9 +2347,9 @@ static void auth_request_set_uidgid_file(struct auth_request *request, "stat(%s) failed: %m", str_c(path)); request->userdb_lookup_tempfailed = TRUE; } else { - auth_fields_add(request->userdb_reply, + auth_fields_add(request->fields.userdb_reply, "uid", dec2str(st.st_uid), 0); - auth_fields_add(request->userdb_reply, + auth_fields_add(request->fields.userdb_reply, "gid", dec2str(st.st_gid), 0); } } @@ -2371,12 +2384,12 @@ void auth_request_set_userdb_field(struct auth_request *request, if (name_len > 10 && strcmp(name+name_len-10, ":protected") == 0) { /* set this field only if it hasn't been set before */ name = t_strndup(name, name_len-10); - if (auth_fields_exists(request->userdb_reply, name)) + if (auth_fields_exists(request->fields.userdb_reply, name)) return; } else if (name_len > 7 && strcmp(name+name_len-7, ":remove") == 0) { /* remove this field entirely */ name = t_strndup(name, name_len-7); - auth_fields_remove(request->userdb_reply, name); + auth_fields_remove(request->fields.userdb_reply, name); return; } @@ -2417,7 +2430,7 @@ void auth_request_set_userdb_field(struct auth_request *request, return; } - auth_fields_add(request->userdb_reply, name, value, 0); + auth_fields_add(request->fields.userdb_reply, name, value, 0); } void auth_request_set_userdb_field_values(struct auth_request *request, @@ -2444,7 +2457,7 @@ void auth_request_set_userdb_field_values(struct auth_request *request, str_append_c(value, ','); str_append(value, dec2str(gid)); } - auth_fields_add(request->userdb_reply, name, str_c(value), 0); + auth_fields_add(request->fields.userdb_reply, name, str_c(value), 0); } else { /* add only one */ if (values[1] != NULL) { @@ -2461,8 +2474,8 @@ static bool auth_request_proxy_is_self(struct auth_request *request) const char *port = NULL; /* check if the port is the same */ - port = auth_fields_find(request->extra_fields, "port"); - if (port != NULL && !str_uint_equals(port, request->local_port)) + port = auth_fields_find(request->fields.extra_fields, "port"); + if (port != NULL && !str_uint_equals(port, request->fields.local_port)) return FALSE; /* don't check destuser. in some systems destuser is intentionally changed to proxied connections, but that shouldn't affect the @@ -2480,7 +2493,7 @@ auth_request_proxy_ip_is_self(struct auth_request *request, { unsigned int i; - if (net_ip_compare(ip, &request->real_local_ip)) + if (net_ip_compare(ip, &request->fields.real_local_ip)) return TRUE; for (i = 0; request->set->proxy_self_ips[i].family != 0; i++) { @@ -2494,17 +2507,19 @@ static void auth_request_proxy_finish_ip(struct auth_request *request, bool proxy_host_is_self) { - if (!auth_fields_exists(request->extra_fields, "proxy_maybe")) { + const struct auth_request_fields *fields = &request->fields; + + if (!auth_fields_exists(fields->extra_fields, "proxy_maybe")) { /* proxying */ } else if (!proxy_host_is_self || !auth_request_proxy_is_self(request)) { /* proxy destination isn't ourself - proxy */ - auth_fields_remove(request->extra_fields, "proxy_maybe"); - auth_fields_add(request->extra_fields, "proxy", NULL, 0); + auth_fields_remove(fields->extra_fields, "proxy_maybe"); + auth_fields_add(fields->extra_fields, "proxy", NULL, 0); } else { /* proxying to ourself - log in without proxying by dropping all the proxying fields. */ - bool proxy_always = auth_fields_exists(request->extra_fields, + bool proxy_always = auth_fields_exists(fields->extra_fields, "proxy_always"); auth_request_proxy_finish_failure(request); @@ -2514,7 +2529,7 @@ auth_request_proxy_finish_ip(struct auth_request *request, we've matched self here, so add proxy field and let director fill the host. */ - auth_fields_add(request->extra_fields, + auth_fields_add(request->fields.extra_fields, "proxy", NULL, 0); } } @@ -2532,7 +2547,7 @@ auth_request_proxy_dns_callback(const struct dns_lookup_result *result, request->dns_lookup_ctx = NULL; ctx->dns_lookup = NULL; - host = auth_fields_find(request->extra_fields, "host"); + host = auth_fields_find(request->fields.extra_fields, "host"); i_assert(host != NULL); if (result->ret != 0) { @@ -2546,7 +2561,7 @@ auth_request_proxy_dns_callback(const struct dns_lookup_result *result, "DNS lookup for %s took %u.%03u s", host, result->msecs/1000, result->msecs % 1000); } - auth_fields_add(request->extra_fields, "hostip", + auth_fields_add(request->fields.extra_fields, "hostip", net_ip2addr(&result->ips[0]), 0); proxy_host_is_self = FALSE; for (i = 0; i < result->ips_count; i++) { @@ -2576,7 +2591,7 @@ static int auth_request_proxy_host_lookup(struct auth_request *request, i_zero(&dns_set); dns_set.dns_client_socket_path = AUTH_DNS_SOCKET_PATH; dns_set.timeout_msecs = AUTH_DNS_DEFAULT_TIMEOUT_MSECS; - value = auth_fields_find(request->extra_fields, "proxy_timeout"); + value = auth_fields_find(request->fields.extra_fields, "proxy_timeout"); if (value != NULL) { if (str_to_uint(value, &secs) < 0) { auth_request_log_error(request, AUTH_SUBSYS_PROXY, @@ -2609,28 +2624,28 @@ int auth_request_proxy_finish(struct auth_request *request, if (request->auth_only) return 1; - if (!auth_fields_exists(request->extra_fields, "proxy") && - !auth_fields_exists(request->extra_fields, "proxy_maybe")) + if (!auth_fields_exists(request->fields.extra_fields, "proxy") && + !auth_fields_exists(request->fields.extra_fields, "proxy_maybe")) return 1; - host = auth_fields_find(request->extra_fields, "host"); + host = auth_fields_find(request->fields.extra_fields, "host"); if (host == NULL) { /* director can set the host. give it access to lip and lport so it can also perform proxy_maybe internally */ proxy_host_is_self = FALSE; - if (request->local_ip.family != 0) { - auth_fields_add(request->extra_fields, "lip", - net_ip2addr(&request->local_ip), 0); + if (request->fields.local_ip.family != 0) { + auth_fields_add(request->fields.extra_fields, "lip", + net_ip2addr(&request->fields.local_ip), 0); } - if (request->local_port != 0) { - auth_fields_add(request->extra_fields, "lport", - dec2str(request->local_port), 0); + if (request->fields.local_port != 0) { + auth_fields_add(request->fields.extra_fields, "lport", + dec2str(request->fields.local_port), 0); } } else if (net_addr2ip(host, &ip) == 0) { proxy_host_is_self = auth_request_proxy_ip_is_self(request, &ip); } else { - hostip = auth_fields_find(request->extra_fields, "hostip"); + hostip = auth_fields_find(request->fields.extra_fields, "hostip"); if (hostip != NULL && net_addr2ip(hostip, &ip) < 0) { auth_request_log_error(request, AUTH_SUBSYS_PROXY, "Invalid hostip in passdb: %s", hostip); @@ -2651,12 +2666,12 @@ int auth_request_proxy_finish(struct auth_request *request, void auth_request_proxy_finish_failure(struct auth_request *request) { /* drop all proxying fields */ - auth_fields_remove(request->extra_fields, "proxy"); - auth_fields_remove(request->extra_fields, "proxy_maybe"); - auth_fields_remove(request->extra_fields, "proxy_always"); - auth_fields_remove(request->extra_fields, "host"); - auth_fields_remove(request->extra_fields, "port"); - auth_fields_remove(request->extra_fields, "destuser"); + auth_fields_remove(request->fields.extra_fields, "proxy"); + auth_fields_remove(request->fields.extra_fields, "proxy_maybe"); + auth_fields_remove(request->fields.extra_fields, "proxy_always"); + auth_fields_remove(request->fields.extra_fields, "host"); + auth_fields_remove(request->fields.extra_fields, "port"); + auth_fields_remove(request->fields.extra_fields, "destuser"); } static void log_password_failure(struct auth_request *request, @@ -2784,10 +2799,12 @@ int auth_request_password_verify_log(struct auth_request *request, size_t raw_password_size; const char *error; int ret; - struct password_generate_params gen_params = {.user = request->original_username, - .rounds = 0}; + struct password_generate_params gen_params = { + .user = request->fields.original_username, + .rounds = 0 + }; - if (request->skip_password_check) { + if (request->fields.skip_password_check) { /* passdb continue* rule after a successful authentication */ return 1; } @@ -2797,7 +2814,7 @@ int auth_request_password_verify_log(struct auth_request *request, return 0; } - if (auth_fields_exists(request->extra_fields, "nopassword")) { + if (auth_fields_exists(request->fields.extra_fields, "nopassword")) { auth_request_log_debug(request, subsystem, "Allowing any password"); return 1; @@ -2843,7 +2860,7 @@ int auth_request_password_verify_log(struct auth_request *request, enum passdb_result auth_request_password_missing(struct auth_request *request) { - if (request->skip_password_check) { + if (request->fields.skip_password_check) { /* This passdb wasn't used for authentication */ return PASSDB_RESULT_OK; } @@ -2886,20 +2903,21 @@ static void get_log_identifier(string_t *str, struct auth_request *auth_request) { const char *ip; - if (auth_request->user == NULL) + if (auth_request->fields.user == NULL) str_append(str, "?"); else - str_sanitize_append(str, auth_request->user, MAX_LOG_USERNAME_LEN); + str_sanitize_append(str, auth_request->fields.user, + MAX_LOG_USERNAME_LEN); - ip = net_ip2addr(&auth_request->remote_ip); + ip = net_ip2addr(&auth_request->fields.remote_ip); if (ip[0] != '\0') { str_append_c(str, ','); str_append(str, ip); } - if (auth_request->requested_login_user != NULL) + if (auth_request->fields.requested_login_user != NULL) str_append(str, ",master"); - if (auth_request->session_id != NULL) - str_printfa(str, ",<%s>", auth_request->session_id); + if (auth_request->fields.session_id != NULL) + str_printfa(str, ",<%s>", auth_request->fields.session_id); } void auth_request_log_debug(struct auth_request *auth_request, diff --git a/src/auth/auth-request.h b/src/auth/auth-request.h index 8d85497382..f9a55a5ff8 100644 --- a/src/auth/auth-request.h +++ b/src/auth/auth-request.h @@ -30,16 +30,8 @@ enum auth_request_secured { AUTH_REQUEST_SECURED_TLS, }; -struct auth_request { - int refcount; - - pool_t pool; - - struct event *event; - struct event *mech_event; - ARRAY(struct event *) authdb_event; - - enum auth_request_state state; +/* All auth request fields are exported to auth-worker process. */ +struct auth_request_fields { /* user contains the user who is being authenticated. When master user is logging in as someone else, it gets more complicated. Initially user is set to master's username and the @@ -57,13 +49,44 @@ struct auth_request { const char *translated_username; /* realm for the request, may be specified by some auth mechanisms */ const char *realm; - char *mech_password; /* set if verify_plain() is called */ - char *passdb_password; /* set after password lookup if successful */ + + const char *service, *mech_name, *session_id, *local_name, *client_id; + struct ip_addr local_ip, remote_ip, real_local_ip, real_remote_ip; + in_port_t local_port, remote_port, real_local_port, real_remote_port; + /* extra_fields are returned in authentication reply. Fields prefixed with "userdb_" are automatically placed to userdb_reply instead. */ struct auth_fields *extra_fields; /* the whole userdb result reply */ struct auth_fields *userdb_reply; + + const unsigned char *delayed_credentials; + size_t delayed_credentials_size; + + enum auth_request_secured secured; + + bool successful:1; + bool skip_password_check:1; + + /* flags received from auth client: */ + bool final_resp_ok:1; + bool no_penalty:1; + bool valid_client_cert:1; + bool cert_username:1; +}; + +struct auth_request { + int refcount; + + pool_t pool; + + struct event *event; + struct event *mech_event; + ARRAY(struct event *) authdb_event; + + enum auth_request_state state; + char *mech_password; /* set if verify_plain() is called */ + char *passdb_password; /* set after password lookup if successful */ struct auth_request_proxy_dns_lookup_ctx *dns_lookup_ctx; /* The final result of passdb lookup (delayed due to asynchronous proxy DNS lookups) */ @@ -87,9 +110,7 @@ struct auth_request { time_t delay_until; pid_t session_pid; - const char *service, *mech_name, *session_id, *local_name, *client_id; - struct ip_addr local_ip, remote_ip, real_local_ip, real_remote_ip; - in_port_t local_port, remote_port, real_local_port, real_remote_port; + struct auth_request_fields fields; struct timeout *to_abort, *to_penalty; unsigned int policy_penalty; @@ -104,8 +125,6 @@ struct auth_request { userdb_callback_t *userdb; } private_callback; const char *credentials_scheme; - const unsigned char *delayed_credentials; - size_t delayed_credentials_size; void *context; @@ -118,17 +137,9 @@ struct auth_request { /* DIGEST-MD5 kludge */ bool domain_is_realm:1; - enum auth_request_secured secured; - - /* flags received from auth client: */ - bool final_resp_ok:1; - bool no_penalty:1; - bool valid_client_cert:1; - bool cert_username:1; bool request_auth_token:1; /* success/failure states: */ - bool successful:1; bool failed:1; /* overrides any other success */ bool internal_failure:1; bool passdbs_seen_user_unknown:1; @@ -137,7 +148,6 @@ struct auth_request { /* current state: */ bool accept_cont_input:1; - bool skip_password_check:1; bool prefer_plain_credentials:1; bool in_delayed_failure_queue:1; bool removed_from_handler:1; diff --git a/src/auth/auth-worker-client.c b/src/auth/auth-worker-client.c index db63d4a979..30e058793b 100644 --- a/src/auth/auth-worker-client.c +++ b/src/auth/auth-worker-client.c @@ -123,16 +123,17 @@ bool auth_worker_auth_request_new(struct auth_worker_command *cmd, unsigned int (void)auth_request_import(auth_request, key, value); } } - if (auth_request->user == NULL || auth_request->service == NULL) { + if (auth_request->fields.user == NULL || + auth_request->fields.service == NULL) { auth_request_unref(&auth_request); return FALSE; } /* reset changed-fields, so we'll export only the ones that were changed by this lookup. */ - auth_fields_snapshot(auth_request->extra_fields); - if (auth_request->userdb_reply != NULL) - auth_fields_snapshot(auth_request->userdb_reply); + auth_fields_snapshot(auth_request->fields.extra_fields); + if (auth_request->fields.userdb_reply != NULL) + auth_fields_snapshot(auth_request->fields.userdb_reply); auth_request_init(auth_request); *request_r = auth_request; @@ -157,24 +158,24 @@ static void auth_worker_send_reply(struct auth_worker_client *client, e_warning(client->conn.event, "Auth master disconnected us while handling " "request for %s for %ld secs (result=%s)", - request->user, (long)cmd_duration, p); + request->fields.user, (long)cmd_duration, p); } } static void reply_append_extra_fields(string_t *str, struct auth_request *request) { - if (!auth_fields_is_empty(request->extra_fields)) { + if (!auth_fields_is_empty(request->fields.extra_fields)) { str_append_c(str, '\t'); /* export only the fields changed by this lookup, so the changed-flag gets preserved correctly on the master side as well. */ - auth_fields_append(request->extra_fields, str, + auth_fields_append(request->fields.extra_fields, str, AUTH_FIELD_FLAG_CHANGED, AUTH_FIELD_FLAG_CHANGED); } - if (request->userdb_reply != NULL && - auth_fields_is_empty(request->userdb_reply)) { + if (request->fields.userdb_reply != NULL && + auth_fields_is_empty(request->fields.userdb_reply)) { /* all userdb_* fields had NULL values. we'll still need to tell this to the master */ str_append(str, "\tuserdb_"AUTH_REQUEST_USER_KEY_IGNORE); @@ -195,7 +196,7 @@ static void verify_plain_callback(enum passdb_result result, str_printfa(str, "%u\t", request->id); if (result == PASSDB_RESULT_OK) - if (auth_fields_exists(request->extra_fields, "noauthenticate")) + if (auth_fields_exists(request->fields.extra_fields, "noauthenticate")) str_append(str, "NEXT"); else str_append(str, "OK"); @@ -204,7 +205,7 @@ static void verify_plain_callback(enum passdb_result result, if (result != PASSDB_RESULT_INTERNAL_FAILURE) { str_append_c(str, '\t'); if (request->user_changed_by_lookup) - str_append_tabescaped(str, request->user); + str_append_tabescaped(str, request->fields.user); str_append_c(str, '\t'); if (request->passdb_password != NULL) str_append_tabescaped(str, request->passdb_password); @@ -347,7 +348,7 @@ lookup_credentials_callback(enum passdb_result result, else str_append(str, "OK\t"); if (request->user_changed_by_lookup) - str_append_tabescaped(str, request->user); + str_append_tabescaped(str, request->fields.user); str_append_c(str, '\t'); if (request->credentials_scheme[0] != '\0') { str_printfa(str, "{%s.b64}", request->credentials_scheme); @@ -485,10 +486,10 @@ lookup_user_callback(enum userdb_result result, case USERDB_RESULT_OK: str_append(str, "OK\t"); if (auth_request->user_changed_by_lookup) - str_append_tabescaped(str, auth_request->user); + str_append_tabescaped(str, auth_request->fields.user); str_append_c(str, '\t'); /* export only the fields changed by this lookup */ - auth_fields_append(auth_request->userdb_reply, str, + auth_fields_append(auth_request->fields.userdb_reply, str, AUTH_FIELD_FLAG_CHANGED, AUTH_FIELD_FLAG_CHANGED); if (auth_request->userdb_lookup_tempfailed) @@ -547,7 +548,7 @@ auth_worker_handle_user(struct auth_worker_command *cmd, return FALSE; } - if (auth_request->userdb_reply == NULL) + if (auth_request->fields.userdb_reply == NULL) auth_request_init_userdb_reply(auth_request); auth_request_userdb_lookup_begin(auth_request); auth_request->userdb->userdb->iface-> diff --git a/src/auth/db-checkpassword.c b/src/auth/db-checkpassword.c index 4e53641703..60b24df259 100644 --- a/src/auth/db-checkpassword.c +++ b/src/auth/db-checkpassword.c @@ -236,46 +236,48 @@ static void env_put_auth_vars(struct auth_request *request) static void checkpassword_setup_env(struct auth_request *request) { + const struct auth_request_fields *fields = &request->fields; + /* Besides passing the standard username and password in a pipe, also pass some other possibly interesting information via environment. Use UCSPI names for local/remote IPs. */ env_put("PROTO=TCP"); /* UCSPI */ env_put(t_strdup_printf("ORIG_UID=%s", dec2str(getuid()))); - env_put(t_strconcat("SERVICE=", request->service, NULL)); - if (request->local_ip.family != 0) { + env_put(t_strconcat("SERVICE=", fields->service, NULL)); + if (fields->local_ip.family != 0) { env_put(t_strconcat("TCPLOCALIP=", - net_ip2addr(&request->local_ip), NULL)); + net_ip2addr(&fields->local_ip), NULL)); /* FIXME: for backwards compatibility only, remove some day */ env_put(t_strconcat("LOCAL_IP=", - net_ip2addr(&request->local_ip), NULL)); + net_ip2addr(&fields->local_ip), NULL)); } - if (request->remote_ip.family != 0) { + if (fields->remote_ip.family != 0) { env_put(t_strconcat("TCPREMOTEIP=", - net_ip2addr(&request->remote_ip), NULL)); + net_ip2addr(&fields->remote_ip), NULL)); /* FIXME: for backwards compatibility only, remove some day */ env_put(t_strconcat("REMOTE_IP=", - net_ip2addr(&request->remote_ip), NULL)); + net_ip2addr(&fields->remote_ip), NULL)); } - if (request->local_port != 0) { + if (fields->local_port != 0) { env_put(t_strdup_printf("TCPLOCALPORT=%u", - request->local_port)); + fields->local_port)); } - if (request->remote_port != 0) { + if (fields->remote_port != 0) { env_put(t_strdup_printf("TCPREMOTEPORT=%u", - request->remote_port)); + fields->remote_port)); } - if (request->master_user != NULL) { + if (fields->master_user != NULL) { env_put(t_strconcat("MASTER_USER=", - request->master_user, NULL)); + fields->master_user, NULL)); } - if (!auth_fields_is_empty(request->extra_fields)) { - const ARRAY_TYPE(auth_field) *fields = - auth_fields_export(request->extra_fields); + if (!auth_fields_is_empty(fields->extra_fields)) { + const ARRAY_TYPE(auth_field) *extra_fields = + auth_fields_export(fields->extra_fields); /* extra fields could come from master db */ - env_put_extra_fields(fields); + env_put_extra_fields(extra_fields); } env_put_auth_vars(request); } @@ -341,7 +343,8 @@ static void checkpassword_child_output(struct chkpw_auth_request *request) ssize_t ret; buf = t_buffer_create(CHECKPASSWORD_MAX_REQUEST_LEN); - buffer_append(buf, auth_request->user, strlen(auth_request->user)+1); + buffer_append(buf, auth_request->fields.user, + strlen(auth_request->fields.user)+1); if (request->auth_password != NULL) { buffer_append(buf, request->auth_password, strlen(request->auth_password)+1); @@ -463,7 +466,7 @@ void db_checkpassword_call(struct db_checkpassword *db, pid_t pid; /* \0 \0 timestamp \0 */ - output_len = strlen(request->user) + 3; + output_len = strlen(request->fields.user) + 3; if (auth_password != NULL) output_len += strlen(auth_password); if (output_len > CHECKPASSWORD_MAX_REQUEST_LEN) { diff --git a/src/auth/db-lua.c b/src/auth/db-lua.c index 893c6804e7..987332867e 100644 --- a/src/auth/db-lua.c +++ b/src/auth/db-lua.c @@ -166,12 +166,12 @@ static int auth_request_lua_passdb(lua_State *L) const char *key = luaL_checkstring(L, 2); lua_pop(L, 1); - if (request->extra_fields == NULL) { + if (request->fields.extra_fields == NULL) { lua_pushnil(L); return 1; } - lua_pushstring(L, auth_fields_find(request->extra_fields, key)); + lua_pushstring(L, auth_fields_find(request->fields.extra_fields, key)); return 1; } @@ -182,12 +182,12 @@ static int auth_request_lua_userdb(lua_State *L) const char *key = luaL_checkstring(L, 2); lua_pop(L, 1); - if (request->userdb_reply == NULL) { + if (request->fields.userdb_reply == NULL) { lua_pushnil(L); return 1; } - lua_pushstring(L, auth_fields_find(request->userdb_reply, key)); + lua_pushstring(L, auth_fields_find(request->fields.userdb_reply, key)); return 1; } @@ -202,8 +202,10 @@ static int auth_request_lua_password_verify(lua_State *L) const unsigned char *raw_password = NULL; size_t raw_password_size; int ret; - struct password_generate_params gen_params = {.user = request->original_username, - .rounds = 0}; + struct password_generate_params gen_params = { + .user = request->fields.original_username, + .rounds = 0 + }; scheme = password_get_scheme(&crypted_password); if (scheme == NULL) scheme = "PLAIN"; @@ -310,12 +312,14 @@ static void auth_lua_push_auth_request(struct dlua_script *script, struct auth_r luaL_setmetatable(script->L, "userdb_"AUTH_LUA_AUTH_REQUEST); lua_setfield(script->L, -2, "userdb"); + lua_pushboolean(script->L, req->fields.skip_password_check); + lua_setfield(script->L, -2, "skip_password_check"); + #undef LUA_TABLE_SETBOOL #define LUA_TABLE_SETBOOL(field) \ lua_pushboolean(script->L, req->field); \ lua_setfield(script->L, -2, #field); - LUA_TABLE_SETBOOL(skip_password_check); LUA_TABLE_SETBOOL(passdbs_seen_user_unknown); LUA_TABLE_SETBOOL(passdbs_seen_internal_failure); LUA_TABLE_SETBOOL(userdbs_seen_internal_failure); diff --git a/src/auth/db-oauth2.c b/src/auth/db-oauth2.c index 1a4055dde2..f681eb73cd 100644 --- a/src/auth/db-oauth2.c +++ b/src/auth/db-oauth2.c @@ -631,15 +631,15 @@ static void db_oauth2_lookup_introspect(struct db_oauth2_request *req) "Making introspection request to %s", req->db->set.introspection_url); input.token = req->token; - input.local_ip = req->auth_request->local_ip; - input.local_port = req->auth_request->local_port; - input.remote_ip = req->auth_request->remote_ip; - input.remote_port = req->auth_request->remote_port; - input.real_local_ip = req->auth_request->real_local_ip; - input.real_local_port = req->auth_request->real_local_port; - input.real_remote_ip = req->auth_request->real_remote_ip; - input.real_remote_port = req->auth_request->real_remote_port; - input.service = req->auth_request->service; + input.local_ip = req->auth_request->fields.local_ip; + input.local_port = req->auth_request->fields.local_port; + input.remote_ip = req->auth_request->fields.remote_ip; + input.remote_port = req->auth_request->fields.remote_port; + input.real_local_ip = req->auth_request->fields.real_local_ip; + input.real_local_port = req->auth_request->fields.real_local_port; + input.real_remote_ip = req->auth_request->fields.real_remote_ip; + input.real_remote_port = req->auth_request->fields.real_remote_port; + input.service = req->auth_request->fields.service; req->req = oauth2_introspection_start(&req->db->oauth2_set, &input, db_oauth2_introspect_continue, req); @@ -753,15 +753,15 @@ void db_oauth2_lookup(struct db_oauth2 *db, struct db_oauth2_request *req, req->auth_request = request; input.token = token; - input.local_ip = req->auth_request->local_ip; - input.local_port = req->auth_request->local_port; - input.remote_ip = req->auth_request->remote_ip; - input.remote_port = req->auth_request->remote_port; - input.real_local_ip = req->auth_request->real_local_ip; - input.real_local_port = req->auth_request->real_local_port; - input.real_remote_ip = req->auth_request->real_remote_ip; - input.real_remote_port = req->auth_request->real_remote_port; - input.service = req->auth_request->service; + input.local_ip = req->auth_request->fields.local_ip; + input.local_port = req->auth_request->fields.local_port; + input.remote_ip = req->auth_request->fields.remote_ip; + input.remote_port = req->auth_request->fields.remote_port; + input.real_local_ip = req->auth_request->fields.real_local_ip; + input.real_local_port = req->auth_request->fields.real_local_port; + input.real_remote_ip = req->auth_request->fields.real_remote_ip; + input.real_remote_port = req->auth_request->fields.real_remote_port; + input.service = req->auth_request->fields.service; if (db->oauth2_set.introspection_mode == INTROSPECTION_MODE_LOCAL && !db_oauth2_uses_password_grant(db)) { @@ -777,7 +777,7 @@ void db_oauth2_lookup(struct db_oauth2 *db, struct db_oauth2_request *req, "Making grant url request to %s", db->set.grant_url); req->req = oauth2_passwd_grant_start(&db->oauth2_set, &input, - request->user, request->mech_password, + request->fields.user, request->mech_password, db_oauth2_lookup_passwd_grant, req); } else if (*db->oauth2_set.tokeninfo_url == '\0') { e_debug(authdb_event(req->auth_request), diff --git a/src/auth/mech-anonymous.c b/src/auth/mech-anonymous.c index 8c1ca21d2f..8b1da99e85 100644 --- a/src/auth/mech-anonymous.c +++ b/src/auth/mech-anonymous.c @@ -12,13 +12,13 @@ mech_anonymous_auth_continue(struct auth_request *request, if (request->set->verbose) { /* temporarily set the user to the one that was given, so that the log message goes right */ - request->user = + request->fields.user = p_strndup(pool_datastack_create(), data, data_size); e_info(request->mech_event, "login"); } - request->user = p_strdup(request->pool, - request->set->anonymous_username); + request->fields.user = p_strdup(request->pool, + request->set->anonymous_username); request->passdb_success = TRUE; auth_request_success(request, "", 0); diff --git a/src/auth/mech-digest-md5.c b/src/auth/mech-digest-md5.c index 5f39ea5bb9..b03ac771a2 100644 --- a/src/auth/mech-digest-md5.c +++ b/src/auth/mech-digest-md5.c @@ -257,8 +257,8 @@ static bool auth_handle_response(struct digest_auth_request *request, (void)str_lcase(key); if (strcmp(key, "realm") == 0) { - if (request->auth_request.realm == NULL && *value != '\0') - request->auth_request.realm = + if (request->auth_request.fields.realm == NULL && *value != '\0') + request->auth_request.fields.realm = p_strdup(request->pool, value); return TRUE; } @@ -523,10 +523,10 @@ mech_digest_md5_auth_continue(struct auth_request *auth_request, const char *username, *error; if (parse_digest_response(request, data, data_size, &error)) { - if (auth_request->realm != NULL && + if (auth_request->fields.realm != NULL && strchr(request->username, '@') == NULL) { username = t_strconcat(request->username, "@", - auth_request->realm, NULL); + auth_request->fields.realm, NULL); auth_request->domain_is_realm = TRUE; } else { username = request->username; diff --git a/src/auth/mech-dovecot-token.c b/src/auth/mech-dovecot-token.c index 9813a96724..408ef6e592 100644 --- a/src/auth/mech-dovecot-token.c +++ b/src/auth/mech-dovecot-token.c @@ -50,7 +50,8 @@ mech_dovecot_token_auth_continue(struct auth_request *request, auth_request_fail(request); } else { const char *valid_token = - auth_token_get(service, pid, request->user, session_id); + auth_token_get(service, pid, request->fields.user, + session_id); if (auth_token != NULL && str_equals_timing_almost_safe(auth_token, valid_token)) { diff --git a/src/auth/mech-external.c b/src/auth/mech-external.c index b9a287b2fc..39809b4e5f 100644 --- a/src/auth/mech-external.c +++ b/src/auth/mech-external.c @@ -12,7 +12,7 @@ mech_external_auth_continue(struct auth_request *request, const char *authzid, *error; authzid = t_strndup(data, data_size); - if (request->user == NULL) { + if (request->fields.user == NULL) { e_info(request->mech_event, "username not known"); auth_request_fail(request); diff --git a/src/auth/mech-login.c b/src/auth/mech-login.c index e4da330b93..6f27433a7f 100644 --- a/src/auth/mech-login.c +++ b/src/auth/mech-login.c @@ -20,7 +20,7 @@ mech_login_auth_continue(struct auth_request *request, static const char prompt2[] = "Password:"; const char *username, *error; - if (request->user == NULL) { + if (request->fields.user == NULL) { username = t_strndup(data, data_size); if (!auth_request_set_username(request, username, &error)) { diff --git a/src/auth/mech-ntlm.c b/src/auth/mech-ntlm.c index f782999c6b..5f496b9697 100644 --- a/src/auth/mech-ntlm.c +++ b/src/auth/mech-ntlm.c @@ -113,7 +113,7 @@ ntlm_verify_credentials(struct ntlm_auth_request *request, * Authentication target == NULL because we are acting * as a standalone server, not as NT domain member. */ - ntlmssp_v2_response(auth_request->user, NULL, + ntlmssp_v2_response(auth_request->fields.user, NULL, credentials, request->challenge, blob, response_length - NTLMSSP_V2_RESPONSE_SIZE, ntlm_v2_response); diff --git a/src/auth/mech-otp-skey-common.c b/src/auth/mech-otp-skey-common.c index b20951e197..ab00a411c0 100644 --- a/src/auth/mech-otp-skey-common.c +++ b/src/auth/mech-otp-skey-common.c @@ -26,10 +26,10 @@ void otp_lock_init(void) bool otp_try_lock(struct auth_request *auth_request) { - if (hash_table_lookup(otp_lock_table, auth_request->user) != NULL) + if (hash_table_lookup(otp_lock_table, auth_request->fields.user) != NULL) return FALSE; - hash_table_insert(otp_lock_table, auth_request->user, auth_request); + hash_table_insert(otp_lock_table, auth_request->fields.user, auth_request); return TRUE; } @@ -41,7 +41,7 @@ void otp_unlock(struct auth_request *auth_request) if (!request->lock) return; - hash_table_remove(otp_lock_table, auth_request->user); + hash_table_remove(otp_lock_table, auth_request->fields.user); request->lock = FALSE; } diff --git a/src/auth/mech-otp.c b/src/auth/mech-otp.c index 1b7ae8393a..2df2b94e76 100644 --- a/src/auth/mech-otp.c +++ b/src/auth/mech-otp.c @@ -223,7 +223,7 @@ static void mech_otp_auth_continue(struct auth_request *auth_request, const unsigned char *data, size_t data_size) { - if (auth_request->user == NULL) { + if (auth_request->fields.user == NULL) { mech_otp_auth_phase1(auth_request, data, data_size); } else { mech_otp_auth_phase2(auth_request, data, data_size); diff --git a/src/auth/mech-rpa.c b/src/auth/mech-rpa.c index 2de8705b4f..63afec0708 100644 --- a/src/auth/mech-rpa.c +++ b/src/auth/mech-rpa.c @@ -274,8 +274,9 @@ rpa_parse_token3(struct rpa_auth_request *request, const void *data, if (!auth_request_set_username(auth_request, user, error)) return FALSE; - request->username_ucs2be = ucs2be_str(request->pool, auth_request->user, - &request->username_len); + request->username_ucs2be = + ucs2be_str(request->pool, auth_request->fields.user, + &request->username_len); request->realm_ucs2be = ucs2be_str(request->pool, realm, &request->realm_len); @@ -338,13 +339,13 @@ mech_rpa_build_token2(struct rpa_auth_request *request, size_t *size) realms = t_str_new(64); for (tmp = set->realms_arr; *tmp != NULL; tmp++) { - rpa_add_realm(realms, *tmp, request->auth_request.service); + rpa_add_realm(realms, *tmp, request->auth_request.fields.service); } if (str_len(realms) == 0) { rpa_add_realm(realms, *set->default_realm != '\0' ? set->default_realm : my_hostname, - request->auth_request.service); + request->auth_request.fields.service); } realms_len = str_len(realms) - 1; @@ -482,7 +483,7 @@ mech_rpa_auth_phase1(struct auth_request *auth_request, return; } - service = t_str_lcase(auth_request->service); + service = t_str_lcase(auth_request->fields.service); token2 = mech_rpa_build_token2(request, &token2_size); diff --git a/src/auth/mech-skey.c b/src/auth/mech-skey.c index d6819a8590..6f26324f5a 100644 --- a/src/auth/mech-skey.c +++ b/src/auth/mech-skey.c @@ -162,7 +162,7 @@ static void mech_skey_auth_continue(struct auth_request *auth_request, const unsigned char *data, size_t data_size) { - if (auth_request->user == NULL) { + if (auth_request->fields.user == NULL) { mech_skey_auth_phase1(auth_request, data, data_size); } else { mech_skey_auth_phase2(auth_request, data, data_size); diff --git a/src/auth/passdb-blocking.c b/src/auth/passdb-blocking.c index f44258f050..2f2668d4af 100644 --- a/src/auth/passdb-blocking.c +++ b/src/auth/passdb-blocking.c @@ -96,7 +96,7 @@ void passdb_blocking_verify_plain(struct auth_request *request) auth_request_export(request, str); auth_request_ref(request); - auth_worker_call(request->pool, request->user, str_c(str), + auth_worker_call(request->pool, request->fields.user, str_c(str), verify_plain_callback, request); } @@ -136,7 +136,7 @@ void passdb_blocking_lookup_credentials(struct auth_request *request) auth_request_export(request, str); auth_request_ref(request); - auth_worker_call(request->pool, request->user, str_c(str), + auth_worker_call(request->pool, request->fields.user, str_c(str), lookup_credentials_callback, request); } @@ -164,6 +164,6 @@ void passdb_blocking_set_credentials(struct auth_request *request, auth_request_export(request, str); auth_request_ref(request); - auth_worker_call(request->pool, request->user, str_c(str), + auth_worker_call(request->pool, request->fields.user, str_c(str), set_credentials_callback, request); } diff --git a/src/auth/passdb-cache.c b/src/auth/passdb-cache.c index 3d9e918148..9daa0f97b5 100644 --- a/src/auth/passdb-cache.c +++ b/src/auth/passdb-cache.c @@ -110,7 +110,7 @@ bool passdb_cache_verify_plain(struct auth_request *request, const char *key, e_debug(authdb_event(request), "cache: " "validating password on worker"); auth_request_ref(request); - auth_worker_call(request->pool, request->user, str_c(str), + auth_worker_call(request->pool, request->fields.user, str_c(str), passdb_cache_verify_plain_callback, request); return TRUE; } else { diff --git a/src/auth/passdb-dict.c b/src/auth/passdb-dict.c index 9159380822..d2644e19e6 100644 --- a/src/auth/passdb-dict.c +++ b/src/auth/passdb-dict.c @@ -68,7 +68,8 @@ passdb_dict_lookup_key(struct auth_request *auth_request, return PASSDB_RESULT_INTERNAL_FAILURE; if (auth_request->passdb_password == NULL && - !auth_fields_exists(auth_request->extra_fields, "nopassword")) { + !auth_fields_exists(auth_request->fields.extra_fields, + "nopassword")) { return auth_request_password_missing(auth_request); } else { return PASSDB_RESULT_OK; diff --git a/src/auth/passdb-ldap.c b/src/auth/passdb-ldap.c index 428da3d5e5..dddc65ba23 100644 --- a/src/auth/passdb-ldap.c +++ b/src/auth/passdb-ldap.c @@ -83,7 +83,7 @@ ldap_lookup_finish(struct auth_request *auth_request, passdb_result = PASSDB_RESULT_INTERNAL_FAILURE; } else if (auth_request->passdb_password == NULL && ldap_request->require_password && - !auth_fields_exists(auth_request->extra_fields, "nopassword")) { + !auth_fields_exists(auth_request->fields.extra_fields, "nopassword")) { passdb_result = auth_request_password_missing(auth_request); } else { /* passdb_password may change on the way, @@ -258,7 +258,7 @@ static void ldap_bind_lookup_dn_callback(struct ldap_connection *conn, } else if (res == NULL || passdb_ldap_request->entries != 1) { /* failure */ ldap_bind_lookup_dn_fail(auth_request, passdb_ldap_request, res); - } else if (auth_request->skip_password_check) { + } else if (auth_request->fields.skip_password_check) { /* we've already verified that the password matched - we just wanted to get any extra fields */ passdb_ldap_request->callback. diff --git a/src/auth/passdb-lua.c b/src/auth/passdb-lua.c index 92c2e958f6..b49b98e960 100644 --- a/src/auth/passdb-lua.c +++ b/src/auth/passdb-lua.c @@ -50,7 +50,7 @@ passdb_lua_lookup(struct auth_request *request, e_error(authdb_event(request), "db-lua: %s", error); } else if (result != PASSDB_RESULT_OK) { /* skip next bit */ - } else if (!auth_fields_exists(request->extra_fields, "nopassword")) { + } else if (!auth_fields_exists(request->fields.extra_fields, "nopassword")) { if (*password_r == NULL || **password_r == '\0') { result = auth_request_password_missing(request); } else { diff --git a/src/auth/passdb-pam.c b/src/auth/passdb-pam.c index 647899a051..6a1032dfc5 100644 --- a/src/auth/passdb-pam.c +++ b/src/auth/passdb-pam.c @@ -80,7 +80,7 @@ pam_userpass_conv(int num_msg, pam_const struct pam_message **msg, case PAM_PROMPT_ECHO_ON: /* Assume we're asking for user. We might not ever get here because PAM already knows the user. */ - string = strdup(ctx->request->user); + string = strdup(ctx->request->fields.user); if (string == NULL) i_fatal_status(FATAL_OUTOFMEM, "Out of memory"); break; @@ -240,10 +240,10 @@ static void set_pam_items(struct auth_request *request, pam_handle_t *pamh) const char *host; /* These shouldn't fail, and we don't really care if they do. */ - host = net_ip2addr(&request->remote_ip); + host = net_ip2addr(&request->fields.remote_ip); if (host[0] != '\0') (void)pam_set_item(pamh, PAM_RHOST, host); - (void)pam_set_item(pamh, PAM_RUSER, request->user); + (void)pam_set_item(pamh, PAM_RUSER, request->fields.user); /* TTY is needed by eg. pam_access module */ (void)pam_set_item(pamh, PAM_TTY, "dovecot"); } @@ -265,7 +265,7 @@ pam_verify_plain_call(struct auth_request *request, const char *service, ctx.request = request; ctx.pass = password; - status = pam_start(service, request->user, &conv, &pamh); + status = pam_start(service, request->fields.user, &conv, &pamh); if (status != PAM_SUCCESS) { e_error(authdb_event(request), "pam_start() failed: %s", diff --git a/src/auth/passdb-passwd.c b/src/auth/passdb-passwd.c index 99ea8de66c..e09f9ede59 100644 --- a/src/auth/passdb-passwd.c +++ b/src/auth/passdb-passwd.c @@ -16,7 +16,7 @@ passwd_lookup(struct auth_request *request, struct passwd *pw_r) { e_debug(authdb_event(request), "lookup"); - switch (i_getpwnam(request->user, pw_r)) { + switch (i_getpwnam(request->fields.user, pw_r)) { case -1: e_error(authdb_event(request), "getpwnam() failed: %m"); diff --git a/src/auth/passdb-shadow.c b/src/auth/passdb-shadow.c index 2e7f67bc98..e312b45108 100644 --- a/src/auth/passdb-shadow.c +++ b/src/auth/passdb-shadow.c @@ -17,7 +17,7 @@ shadow_lookup(struct auth_request *request, struct spwd **spw_r) { e_debug(authdb_event(request), "lookup"); - *spw_r = getspnam(request->user); + *spw_r = getspnam(request->fields.user); if (*spw_r == NULL) { auth_request_log_unknown_user(request, AUTH_SUBSYS_DB); return PASSDB_RESULT_USER_UNKNOWN; diff --git a/src/auth/passdb-sql.c b/src/auth/passdb-sql.c index 666c7392cc..376e3cded2 100644 --- a/src/auth/passdb-sql.c +++ b/src/auth/passdb-sql.c @@ -99,7 +99,8 @@ static void sql_query_callback(struct sql_result *result, e_error(authdb_event(auth_request), "Password query returned multiple matches"); } else if (auth_request->passdb_password == NULL && - !auth_fields_exists(auth_request->extra_fields, "nopassword")) { + !auth_fields_exists(auth_request->fields.extra_fields, + "nopassword")) { passdb_result = auth_request_password_missing(auth_request); } else { /* passdb_password may change on the way, diff --git a/src/auth/passdb-static.c b/src/auth/passdb-static.c index c64d1e165c..f43123fbcd 100644 --- a/src/auth/passdb-static.c +++ b/src/auth/passdb-static.c @@ -37,7 +37,7 @@ static_save_fields(struct auth_request *request, const char **password_r, module->static_password_tmpl, error); return PASSDB_RESULT_INTERNAL_FAILURE; } - } else if (auth_fields_exists(request->extra_fields, "nopassword")) { + } else if (auth_fields_exists(request->fields.extra_fields, "nopassword")) { *password_r = ""; } else { return auth_request_password_missing(request); diff --git a/src/auth/passdb.c b/src/auth/passdb.c index 8b92a47b18..ad1e0f384e 100644 --- a/src/auth/passdb.c +++ b/src/auth/passdb.c @@ -111,12 +111,12 @@ bool passdb_get_credentials(struct auth_request *auth_request, /* we can generate anything out of plaintext passwords */ plaintext = t_strndup(*credentials_r, *size_r); i_zero(&pwd_gen_params); - pwd_gen_params.user = auth_request->original_username; + pwd_gen_params.user = auth_request->fields.original_username; if (!auth_request->domain_is_realm && strchr(pwd_gen_params.user, '@') != NULL) { /* domain must not be used as realm. add the @realm. */ pwd_gen_params.user = t_strconcat(pwd_gen_params.user, "@", - auth_request->realm, NULL); + auth_request->fields.realm, NULL); } if (auth_request->set->debug_passwords) { e_debug(authdb_event(auth_request), @@ -145,7 +145,8 @@ void passdb_handle_credentials(enum passdb_result result, if (result != PASSDB_RESULT_OK) { callback(result, NULL, 0, auth_request); return; - } else if (auth_fields_exists(auth_request->extra_fields, "noauthenticate")) { + } else if (auth_fields_exists(auth_request->fields.extra_fields, + "noauthenticate")) { callback(PASSDB_RESULT_NEXT, NULL, 0, auth_request); return; } @@ -157,7 +158,7 @@ void passdb_handle_credentials(enum passdb_result result, } else if (*auth_request->credentials_scheme == '\0') { /* We're doing a passdb lookup (not authenticating). Pass through a NULL password without an error. */ - } else if (auth_request->delayed_credentials != NULL) { + } else if (auth_request->fields.delayed_credentials != NULL) { /* We already have valid credentials from an earlier passdb lookup. auth_request_lookup_credentials_finish() will use them. */ diff --git a/src/auth/test-auth-request-var-expand.c b/src/auth/test-auth-request-var-expand.c index af55f1932e..557b0760cd 100644 --- a/src/auth/test-auth-request-var-expand.c +++ b/src/auth/test-auth-request-var-expand.c @@ -22,35 +22,36 @@ static struct auth_userdb test_auth_userdb = { }; static struct auth_request default_test_request = { - .user = "-user@+domain1@+domain2", - .service = "-service", - - .local_ip = { .family = AF_INET }, - .remote_ip = { .family = AF_INET }, + .fields = { + .user = "-user@+domain1@+domain2", + .service = "-service", + .local_ip = { .family = AF_INET }, + .remote_ip = { .family = AF_INET }, + .mech_name = "-mech", + .secured = AUTH_REQUEST_SECURED, + .local_port = 21, + .remote_port = 210, + .valid_client_cert = TRUE, + .requested_login_user = "-loginuser@+logindomain1@+logindomain2", + .session_id = "-session", + .real_local_ip = { .family = AF_INET }, + .real_remote_ip = { .family = AF_INET }, + .real_local_port = 200, + .real_remote_port = 201, + .master_user = "-masteruser@-masterdomain1@-masterdomain2", + .original_username = "-origuser@-origdomain1@-origdomain2", + }, .client_pid = 54321, .mech_password = "-password", - .mech_name = "-mech", - .secured = AUTH_REQUEST_SECURED, - .local_port = 21, - .remote_port = 210, - .valid_client_cert = TRUE, - - .requested_login_user = "-loginuser@+logindomain1@+logindomain2", - .session_id = "-session", - .real_local_ip = { .family = AF_INET }, - .real_remote_ip = { .family = AF_INET }, - .real_local_port = 200, - .real_remote_port = 201, - .master_user = "-masteruser@-masterdomain1@-masterdomain2", + .session_pid = 5000, - .original_username = "-origuser@-origdomain1@-origdomain2", .passdb = &test_auth_passdb, .userdb = &test_auth_userdb }; static struct auth_request test_request; -static struct auth_request empty_test_request = { .user = "" }; +static struct auth_request empty_test_request = { .fields = { .user = "" } }; static const char * test_escape(const char *string, const struct auth_request *request) @@ -122,16 +123,16 @@ static void test_auth_request_var_expand_flags(void) test_begin("auth request var expand flags"); test_request.userdb_lookup = FALSE; - test_request.secured = AUTH_REQUEST_SECURED_NONE; - test_request.valid_client_cert = FALSE; + test_request.fields.secured = AUTH_REQUEST_SECURED_NONE; + test_request.fields.valid_client_cert = FALSE; test_assert(var_expand(str, test_input, auth_request_get_var_expand_table(&test_request, test_escape), &error) == 1); test_assert(strcmp(str_c(str), "40\n\n\n") == 0); test_request.userdb_lookup = TRUE; - test_request.secured = AUTH_REQUEST_SECURED; - test_request.valid_client_cert = TRUE; + test_request.fields.secured = AUTH_REQUEST_SECURED; + test_request.fields.valid_client_cert = TRUE; str_truncate(str, 0); test_assert(var_expand(str, test_input, @@ -186,14 +187,14 @@ static void test_auth_request_var_expand_usernames(void) test_begin("auth request var expand usernames"); for (i = 0; i < N_ELEMENTS(tests); i++) { - test_request.user = t_strdup_noconst(tests[i].username); + test_request.fields.user = t_strdup_noconst(tests[i].username); str_truncate(str, 0); test_assert(var_expand(str, test_input, auth_request_get_var_expand_table(&test_request, test_escape), &error) == 1); test_assert_idx(strcmp(str_c(str), tests[i].output) == 0, i); } - test_request.user = default_test_request.user; + test_request.fields.user = default_test_request.fields.user; test_end(); } @@ -205,14 +206,14 @@ static void test_auth_request_var_expand_funcs(void) test_begin("auth request var expand funcs"); pool = pool_alloconly_create("test var expand funcs", 1024); - test_request.extra_fields = auth_fields_init(pool); - test_request.userdb_reply = auth_fields_init(pool); + test_request.fields.extra_fields = auth_fields_init(pool); + test_request.fields.userdb_reply = auth_fields_init(pool); - auth_fields_add(test_request.extra_fields, "pkey1", "-pval1", 0); - auth_fields_add(test_request.extra_fields, "pkey2", "", 0); + auth_fields_add(test_request.fields.extra_fields, "pkey1", "-pval1", 0); + auth_fields_add(test_request.fields.extra_fields, "pkey2", "", 0); - auth_fields_add(test_request.userdb_reply, "ukey1", "-uval1", 0); - auth_fields_add(test_request.userdb_reply, "ukey2", "", 0); + auth_fields_add(test_request.fields.userdb_reply, "ukey1", "-uval1", 0); + auth_fields_add(test_request.fields.userdb_reply, "ukey2", "", 0); test_assert(t_auth_request_var_expand( "%{passdb:pkey1}\n%{passdb:pkey1:default1}\n" @@ -236,10 +237,10 @@ static void test_auth_request_var_expand_funcs(void) void test_auth_request_var_expand(void) { - default_test_request.local_ip.u.ip4.s_addr = htonl(123456789); - default_test_request.remote_ip.u.ip4.s_addr = htonl(1234567890); - default_test_request.real_local_ip.u.ip4.s_addr = htonl(223456788); - default_test_request.real_remote_ip.u.ip4.s_addr = htonl(223456789); + default_test_request.fields.local_ip.u.ip4.s_addr = htonl(123456789); + default_test_request.fields.remote_ip.u.ip4.s_addr = htonl(1234567890); + default_test_request.fields.real_local_ip.u.ip4.s_addr = htonl(223456788); + default_test_request.fields.real_remote_ip.u.ip4.s_addr = htonl(223456789); test_request = default_test_request; diff --git a/src/auth/test-lua.c b/src/auth/test-lua.c index cabb2bb77c..6b708912ce 100644 --- a/src/auth/test-lua.c +++ b/src/auth/test-lua.c @@ -19,7 +19,7 @@ static void test_db_lua_auth_verify(void) struct event *event = event_create(req->event); array_push_back(&req->authdb_event, &event); req->passdb = passdb_mock(); - req->user = "testuser"; + req->fields.user = "testuser"; static const char *luascript = "function auth_password_verify(req, pass)\n" @@ -63,7 +63,7 @@ static void test_db_lua_auth_lookup_numberish_value(void) struct event *event = event_create(req->event); array_push_back(&req->authdb_event, &event); req->passdb = passdb_mock(); - req->user = "testuser"; + req->fields.user = "testuser"; static const char *luascript = "function auth_passdb_lookup(req)\n" @@ -80,7 +80,7 @@ static void test_db_lua_auth_lookup_numberish_value(void) if (script != NULL) { test_assert(auth_lua_script_init(script, &error) == 0); test_assert(auth_lua_call_passdb_lookup(script, req, &scheme, &pass, &error) == 1); - test_assert(strcmp(req->user, "01234") == 0); + test_assert(strcmp(req->fields.user, "01234") == 0); dlua_script_unref(&script); } if (error != NULL) { @@ -106,7 +106,7 @@ static void test_db_lua_auth_lookup(void) struct event *event = event_create(req->event); array_push_back(&req->authdb_event, &event); req->passdb = passdb_mock(); - req->user = "testuser"; + req->fields.user = "testuser"; static const char *luascript = "function auth_passdb_lookup(req)\n" diff --git a/src/auth/test-mech.c b/src/auth/test-mech.c index 0a22ff46d0..ea2275a246 100644 --- a/src/auth/test-mech.c +++ b/src/auth/test-mech.c @@ -70,7 +70,7 @@ request_handler_reply_mock_callback(struct auth_request *request, if (request->passdb_result == PASSDB_RESULT_OK) request->failed = FALSE; else if (request->mech == &mech_otp) { - if (null_strcmp(request->user, "otp_phase_2") == 0) + if (null_strcmp(request->fields.user, "otp_phase_2") == 0) request->failed = FALSE; } else if (request->mech == &mech_oauthbearer) { } @@ -152,14 +152,14 @@ static void test_mech_prepare_request(struct auth_request **request_r, request->userdb = auth->userdbs; handler->refcount = 1; - auth_fields_add(request->extra_fields, "nodelay", "", 0); + auth_fields_add(request->fields.extra_fields, "nodelay", "", 0); auth_request_ref(request); auth_request_state_count[AUTH_REQUEST_STATE_NEW] = 1; if (test_case->set_username_before_test || test_case->set_cert_username) - request->user = p_strdup(request->pool, test_case->username); + request->fields.user = p_strdup(request->pool, test_case->username); if (test_case->set_cert_username) - request->cert_username = TRUE; + request->fields.cert_username = TRUE; *request_r = request; } @@ -358,10 +358,10 @@ static void test_mechs(void) test_case->success); } - const char *username = request->user; + const char *username = request->fields.user; - if (request->master_user != NULL) - username = request->master_user; + if (request->fields.master_user != NULL) + username = request->fields.master_user; if (!test_case->set_username_before_test && test_case->success) { /* If the username was set by the test logic, do not @@ -415,7 +415,7 @@ static void test_rpa(void) struct auth_request *req = mech->auth_new(); global_auth_settings->realms_arr = t_strsplit("example.com", " "); req->set = global_auth_settings; - req->service = "login"; + req->fields.service = "login"; req->handler = &handler; req->mech_event = event_create(NULL); req->event = event_create(NULL); @@ -446,7 +446,7 @@ static void test_ntlm(void) struct auth_request *req = mech->auth_new(); global_auth_settings->realms_arr = t_strsplit("example.com", " "); req->set = global_auth_settings; - req->service = "login"; + req->fields.service = "login"; req->handler = &handler; req->mech_event = event_create(NULL); req->event = event_create(NULL); diff --git a/src/auth/userdb-blocking.c b/src/auth/userdb-blocking.c index af8477fab8..32e37a8ce3 100644 --- a/src/auth/userdb-blocking.c +++ b/src/auth/userdb-blocking.c @@ -34,8 +34,9 @@ static bool user_callback(const char *reply, void *context) args = ""; else username = t_strdup_until(username, args++); - if (username[0] != '\0' && strcmp(request->user, username) != 0) { - request->user = p_strdup(request->pool, username); + if (username[0] != '\0' && + strcmp(request->fields.user, username) != 0) { + request->fields.user = p_strdup(request->pool, username); request->user_changed_by_lookup = TRUE; } } else { @@ -45,8 +46,8 @@ static bool user_callback(const char *reply, void *context) } if (*args != '\0') { - auth_fields_import(request->userdb_reply, args, 0); - if (auth_fields_exists(request->userdb_reply, "tempfail")) + auth_fields_import(request->fields.userdb_reply, args, 0); + if (auth_fields_exists(request->fields.userdb_reply, "tempfail")) request->userdb_lookup_tempfailed = TRUE; } @@ -64,7 +65,7 @@ void userdb_blocking_lookup(struct auth_request *request) auth_request_export(request, str); auth_request_ref(request); - auth_worker_call(request->pool, request->user, + auth_worker_call(request->pool, request->fields.user, str_c(str), user_callback, request); } diff --git a/src/auth/userdb-passwd.c b/src/auth/userdb-passwd.c index 0ec7c49c80..70b9969f62 100644 --- a/src/auth/userdb-passwd.c +++ b/src/auth/userdb-passwd.c @@ -45,7 +45,7 @@ passwd_check_warnings(struct auth_request *auth_request, msecs = timeval_diff_msecs(&end_tv, start_tv); if (msecs >= PASSWD_SLOW_WARN_MSECS) { i_warning("passwd: Lookup for %s took %u secs", - auth_request->user, msecs/1000); + auth_request->fields.user, msecs/1000); return; } if (worker || module->slow_warned) @@ -89,7 +89,7 @@ static void passwd_lookup(struct auth_request *auth_request, e_debug(authdb_event(auth_request), "lookup"); i_gettimeofday(&start_tv); - ret = i_getpwnam(auth_request->user, &pw); + ret = i_getpwnam(auth_request->fields.user, &pw); if (start_tv.tv_sec != 0) passwd_check_warnings(auth_request, module, &start_tv); diff --git a/src/auth/userdb-static.c b/src/auth/userdb-static.c index 599d566f4d..bed0f58616 100644 --- a/src/auth/userdb-static.c +++ b/src/auth/userdb-static.c @@ -81,7 +81,7 @@ static void static_lookup(struct auth_request *auth_request, (struct static_userdb_module *)_module; struct static_context *ctx; - if (!auth_request->successful && !module->allow_all_users) { + if (!auth_request->fields.successful && !module->allow_all_users) { /* this is a userdb-only lookup. we need to know if this users exists or not. use a passdb lookup to do that. if the passdb doesn't support returning credentials, this