/* 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
/* 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) -
(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);
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;
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);
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;
}
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;
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;
{
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) -
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;
}
{
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,
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) {
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 */
}
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
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");
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);
}
}
}
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);
/* 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);
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;
}
}
- 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");
}
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,
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);
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");
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;
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 */
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);
}
}
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);
}
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;
}
}
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);
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);
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;
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,
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, '@'),
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, '@'),
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);
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;
}
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;
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;
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);
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;
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,
{
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;
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) {
auth_request_fail(request);
return;
}
- request->successful = TRUE;
+ request->fields.successful = TRUE;
/* log before delay */
auth_request_log_finished(request);
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,
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++;
}
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() */
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))
/* 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;
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))
/* 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;
{
i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
- if (request->successful) {
+ if (request->fields.successful) {
auth_request_success(request, "", 0);
return;
}
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:
}
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)
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);
}
/* 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
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,
/* 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:
{
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;
}
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:
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;
}
/* 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
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;
}
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)
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;
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;
}
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);
}
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) {
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)
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) {
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,
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;
}
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;
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;
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
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,
}
user = p_strdup(request->pool, str_c(dest));
- request->user = old_username;
+ request->fields.user = old_username;
}
if (user[0] == '\0') {
}
}
- 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;
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;
}
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;
}
{
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') {
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;
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;
}
/* 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) {
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
} 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),
}
}
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;
}
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);
}
{
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),
"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);
}
}
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;
}
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,
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) {
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
{
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++) {
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);
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);
}
}
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) {
"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++) {
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,
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);
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,
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;
}
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;
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;
}
{
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,
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
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) */
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;
userdb_callback_t *userdb;
} private_callback;
const char *credentials_scheme;
- const unsigned char *delayed_credentials;
- size_t delayed_credentials_size;
void *context;
/* 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;
/* 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;
(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;
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);
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");
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);
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);
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)
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->
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);
}
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);
pid_t pid;
/* <username> \0 <password> \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) {
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;
}
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;
}
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";
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);
"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);
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)) {
"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),
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);
(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;
}
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;
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)) {
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);
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)) {
* 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);
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;
}
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;
}
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);
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);
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;
return;
}
- service = t_str_lcase(auth_request->service);
+ service = t_str_lcase(auth_request->fields.service);
token2 = mech_rpa_build_token2(request, &token2_size);
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);
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);
}
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);
}
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);
}
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 {
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;
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,
} 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.
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 {
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;
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");
}
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",
{
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");
{
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;
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,
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);
/* 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),
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;
}
} 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. */
};
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)
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,
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();
}
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"
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;
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"
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"
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) {
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"
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) {
}
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;
}
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
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);
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);
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 {
}
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;
}
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);
}
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)
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);
(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