]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-auth: auth_user_fields_parse() - Fail on parse errors rather than just log it
authorMarco Bettini <marco.bettini@open-xchange.com>
Tue, 11 Oct 2022 11:03:41 +0000 (11:03 +0000)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Wed, 26 Oct 2022 16:35:08 +0000 (16:35 +0000)
src/imap-urlauth/imap-urlauth.c
src/lib-auth/auth-master.c
src/lib-auth/auth-master.h
src/lib-storage/mail-storage-service.c
src/lib-storage/mail-user.c

index 65edbd42a7d9c30a1d5dc69ea4ae4a6d73edf557..d48ec0d46d47c4e15ab66cbc0b5f3117d505eba7 100644 (file)
@@ -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 &&
index 169478aebc42846712712672e80be91eb929053b..d8f8d61b2bffa2fea530cc545895592afd094821 100644 (file)
@@ -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,
index b4bcd59a67b65aa2e58014d24457f3fa07c6e629..7fa79059b7de3445826d30c99ebadb953bb0eb1f 100644 (file)
@@ -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
index cd8df9720e1955444b367fe17ffc1116ec36d361..ca77abaec1ff29baa105a69b47a4586324a46022 100644 (file)
@@ -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;
index 57a562333dc3f5060b759848bd77478d9ec4ec22..bcd397bfe7b8f5bc2e83abdbcc71fdad8167ec50 100644 (file)
@@ -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;