From: Timo Sirainen Date: Sun, 27 Apr 2003 00:12:42 +0000 (+0300) Subject: Fixes and support for system_user, mail and chroot settings X-Git-Tag: 1.1.alpha1~4714 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c55692dcf1ee7be08c9bc857a82d27a2de07ce9;p=thirdparty%2Fdovecot%2Fcore.git Fixes and support for system_user, mail and chroot settings --HG-- branch : HEAD --- diff --git a/doc/dovecot-pgsql.conf b/doc/dovecot-pgsql.conf index 07f840613e..b43cfdb0a6 100644 --- a/doc/dovecot-pgsql.conf +++ b/doc/dovecot-pgsql.conf @@ -55,11 +55,16 @@ # Query to retrieve the user information. # -# The query must reutrn only one row. The columns to return are home directory, -# uid, and gid. They do not have to be in any given order, but if they are not -# named "home", "uid", and "gid", then they must be cast to those names. If -# more than one row is returned or there's missing fields, login will -# automatically fail. +# The query must return only one row. The columns to return are: +# home - Home directory +# mail - MAIL environment +# system_user - System user name (for initgroups()) +# uid - System UID +# gid - System GID +# chroot - Chroot to home directory? (Y / N) +# +# Either home or mail is required. uid and gid are required. If more than one +# row is returned or there's missing fields, login will automatically fail. # # Examples # user_query = SELECT home, uid, gid FROM users WHERE userid = '%n' AND domain = '%d' diff --git a/src/auth/db-pgsql.c b/src/auth/db-pgsql.c index 16de206879..5efe6fee03 100644 --- a/src/auth/db-pgsql.c +++ b/src/auth/db-pgsql.c @@ -56,17 +56,13 @@ void db_pgsql_query(struct pgsql_connection *conn, const char *query, i_error("PGSQL: Query \"%s\" failed: %s", query, PQresultErrorMessage(res)); failed = TRUE; - } else if (PQntuples(res) != 1) { - i_error("PGSQL: Query \"%s\" returned %d rows", - query, PQntuples(res)); - failed = TRUE; } else { failed = FALSE; } request->callback(conn, request, failed ? NULL : res); PQclear(res); - + i_free(request); } static int pgsql_conn_open(struct pgsql_connection *conn) diff --git a/src/auth/userdb-pgsql.c b/src/auth/userdb-pgsql.c index c6ab9eeaee..716fd70027 100644 --- a/src/auth/userdb-pgsql.c +++ b/src/auth/userdb-pgsql.c @@ -23,6 +23,8 @@ struct userdb_pgsql_connection { struct userdb_pgsql_request { struct pgsql_request request; userdb_callback_t *userdb_callback; + + char username[1]; /* variable width */ }; static struct userdb_pgsql_connection *userdb_pgsql_conn; @@ -40,11 +42,6 @@ static int is_result_valid(PGresult *res) return FALSE; } - if (PQfnumber(res, "home") == -1) { - i_error("PGSQL: User query did not return 'home' field"); - return FALSE; - } - if (PQfnumber(res, "uid") == -1) { i_error("PGSQL: User query did not return 'uid' field"); return FALSE; @@ -58,18 +55,32 @@ static int is_result_valid(PGresult *res) return TRUE; } +static const char *pg_get_str(PGresult *res, const char *field) +{ + int fieldnum; + + fieldnum = PQfnumber(res, field); + return fieldnum == -1 ? NULL : PQgetvalue(res, 0, fieldnum); +} + static void pgsql_handle_request(struct pgsql_connection *conn __attr_unused__, struct pgsql_request *request, PGresult *res) { struct userdb_pgsql_request *urequest = (struct userdb_pgsql_request *) request; struct user_data user; + const char *str; if (res != NULL && is_result_valid(res)) { memset(&user, 0, sizeof(user)); - user.home = PQgetvalue(res, 0, PQfnumber(res, "home")); + user.virtual_user = urequest->username; + user.system_user = pg_get_str(res, "system_user"); + user.home = pg_get_str(res, "home"); + user.mail = pg_get_str(res, "mail"); user.uid = atoi(PQgetvalue(res, 0, PQfnumber(res, "uid"))); user.gid = atoi(PQgetvalue(res, 0, PQfnumber(res, "gid"))); + str = pg_get_str(res, "chroot"); + user.chroot = str != NULL && (*str == 'Y' || *str == 'y'); urequest->userdb_callback(&user, request->context); } else { urequest->userdb_callback(NULL, request->context); @@ -88,10 +99,11 @@ static void userdb_pgsql_lookup(const char *user, userdb_callback_t *callback, var_expand(str, conn->set.user_query, str_escape(user), NULL); query = str_c(str); - request = i_new(struct userdb_pgsql_request, 1); + request = i_malloc(sizeof(struct userdb_pgsql_request) + strlen(user)); request->request.callback = pgsql_handle_request; request->request.context = context; request->userdb_callback = callback; + strcpy(request->username, user); db_pgsql_query(conn, query, &request->request); }