From: Marco Bettini Date: Tue, 11 Oct 2022 11:03:41 +0000 (+0000) Subject: lib-auth: auth_user_fields_parse() - Fail on parse errors rather than just log it X-Git-Tag: 2.4.0~3527 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2424a0779015a2b5c1c75a10a34b102e8a5ed331;p=thirdparty%2Fdovecot%2Fcore.git lib-auth: auth_user_fields_parse() - Fail on parse errors rather than just log it --- diff --git a/src/imap-urlauth/imap-urlauth.c b/src/imap-urlauth/imap-urlauth.c index 65edbd42a7..d48ec0d46d 100644 --- a/src/imap-urlauth/imap-urlauth.c +++ b/src/imap-urlauth/imap-urlauth.c @@ -138,8 +138,18 @@ login_request_finished(const struct login_server_request *request, const char *const *fields; const char *service = NULL; unsigned int count, i; + const char *error; - auth_user_fields_parse(extra_fields, pool_datastack_create(), &reply); + if (auth_user_fields_parse(extra_fields, pool_datastack_create(), + &reply, &error) < 0) { + e_error(request->conn->event, + "Invalid settings in userdb: %s", error); + if (write(request->fd, msg, strlen(msg)) < 0) { + /* ignored */ + } + net_disconnect(request->fd); + return; + } /* check peer credentials if possible */ if (reply.uid != (uid_t)-1 && net_getunixcred(request->fd, &cred) == 0 && diff --git a/src/lib-auth/auth-master.c b/src/lib-auth/auth-master.c index 169478aebc..d8f8d61b2b 100644 --- a/src/lib-auth/auth-master.c +++ b/src/lib-auth/auth-master.c @@ -719,8 +719,8 @@ int auth_master_user_lookup(struct auth_master_connection *conn, return ctx.return_value; } -void auth_user_fields_parse(const char *const *fields, pool_t pool, - struct auth_user_reply *reply_r) +int auth_user_fields_parse(const char *const *fields, pool_t pool, + struct auth_user_reply *reply_r, const char **error_r) { const char *value; @@ -731,11 +731,15 @@ void auth_user_fields_parse(const char *const *fields, pool_t pool, for (; *fields != NULL; fields++) { if (str_begins(*fields, "uid=", &value)) { - if (str_to_uid(value, &reply_r->uid) < 0) - i_error("Invalid uid in reply"); + if (str_to_uid(value, &reply_r->uid) < 0) { + *error_r = "Invalid uid in reply"; + return -1; + } } else if (str_begins(*fields, "gid=", &value)) { - if (str_to_gid(value, &reply_r->gid) < 0) - i_error("Invalid gid in reply"); + if (str_to_gid(value, &reply_r->gid) < 0) { + *error_r = "Invalid gid in reply"; + return -1; + } } else if (str_begins(*fields, "home=", &value)) reply_r->home = p_strdup(pool, value); else if (str_begins(*fields, "chroot=", &value)) @@ -747,6 +751,7 @@ void auth_user_fields_parse(const char *const *fields, pool_t pool, array_push_back(&reply_r->extra_fields, &field); } } + return 0; } int auth_master_pass_lookup(struct auth_master_connection *conn, diff --git a/src/lib-auth/auth-master.h b/src/lib-auth/auth-master.h index b4bcd59a67..7fa79059b7 100644 --- a/src/lib-auth/auth-master.h +++ b/src/lib-auth/auth-master.h @@ -57,8 +57,8 @@ int auth_master_cache_flush(struct auth_master_connection *conn, const char *const *users, unsigned int *count_r); /* Parse userdb extra fields into auth_user_reply structure. */ -void auth_user_fields_parse(const char *const *fields, pool_t pool, - struct auth_user_reply *reply_r); +int auth_user_fields_parse(const char *const *fields, pool_t pool, + struct auth_user_reply *reply_r, const char **error_r); /* Iterate through all users. If user_mask is non-NULL, it contains a string with wildcards ('*', '?') that the auth server MAY use to limit what users diff --git a/src/lib-storage/mail-storage-service.c b/src/lib-storage/mail-storage-service.c index cd8df9720e..ca77abaec1 100644 --- a/src/lib-storage/mail-storage-service.c +++ b/src/lib-storage/mail-storage-service.c @@ -1359,9 +1359,14 @@ mail_storage_service_lookup_real(struct mail_storage_service_ctx *ctx, } if (userdb_fields != NULL) { - auth_user_fields_parse(userdb_fields, temp_pool, &reply); - array_sort(&reply.extra_fields, extra_field_key_cmp_p); - if (user_reply_handle(ctx, user, &reply, &error) < 0) { + int ret2 = auth_user_fields_parse(userdb_fields, temp_pool, + &reply, &error); + if (ret2 == 0) { + array_sort(&reply.extra_fields, extra_field_key_cmp_p); + ret2 = user_reply_handle(ctx, user, &reply, &error); + } + + if (ret2 < 0) { *error_r = t_strdup_printf( "Invalid settings in userdb: %s", error); ret = -2; diff --git a/src/lib-storage/mail-user.c b/src/lib-storage/mail-user.c index 57a562333d..bcd397bfe7 100644 --- a/src/lib-storage/mail-user.c +++ b/src/lib-storage/mail-user.c @@ -433,8 +433,14 @@ static int mail_user_userdb_lookup_home(struct mail_user *user) user->username, &info, userdb_pool, &username, &fields); if (ret > 0) { - auth_user_fields_parse(fields, userdb_pool, &reply); - user->_home = p_strdup(user->pool, reply.home); + const char *error; + if (auth_user_fields_parse(fields, userdb_pool, + &reply, &error) < 0) { + e_error(user->event, + "Failed to parse credentials due to %s", error); + ret = -1; + } else + user->_home = p_strdup(user->pool, reply.home); } pool_unref(&userdb_pool); return ret;