# HG changeset patch # User Timo Sirainen # Date 1123414879 -10800 # Node ID e2fe8222449d93687d3888e4351d55016cbcb06c # Parent 7addee16b0269bd11d76670323b58082edcba135 s/occured/occurred/ diff -r 7addee16b026 -r e2fe8222449d doc/auth-protocol.txt --- a/doc/auth-protocol.txt Sun Aug 07 14:28:13 2005 +0300 +++ b/doc/auth-protocol.txt Sun Aug 07 14:41:19 2005 +0300 @@ -169,7 +169,7 @@ it happens it means either a timeout caused by very high load, or client lying to master about the request. -FAIL reply means an internal error occured. Usually either a configuration +FAIL reply means an internal error occurred. Usually either a configuration mistake or temporary error caused by lost resource (eg. database down). USER reply is sent if request succeeded. It can return parameters: diff -r 7addee16b026 -r e2fe8222449d doc/index.txt --- a/doc/index.txt Sun Aug 07 14:28:13 2005 +0300 +++ b/doc/index.txt Sun Aug 07 14:41:19 2005 +0300 @@ -87,7 +87,7 @@ Dovecot uses modify log file to log changes made to index files; currently message flag changes and expunges. This way only one of the Dovecot processes has to scan the mailbox, other processes simply check from the -log file what changes occured. +log file what changes occurred. All external changes that Dovecot notices (eg. another MUA expunging mails) are also saved into log file. They can quickly be found from there when diff -r 7addee16b026 -r e2fe8222449d src/auth/Makefile.am --- a/src/auth/Makefile.am Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/Makefile.am Sun Aug 07 14:41:19 2005 +0300 @@ -40,6 +40,7 @@ auth-module.c \ auth-request.c \ auth-request-handler.c \ + auth-stream.c \ auth-worker-client.c \ auth-worker-server.c \ db-ldap.c \ @@ -88,6 +89,7 @@ auth-module.h \ auth-request.h \ auth-request-handler.h \ + auth-stream.h \ auth-worker-client.h \ auth-worker-server.h \ db-ldap.h \ diff -r 7addee16b026 -r e2fe8222449d src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/auth-master-connection.c Sun Aug 07 14:41:19 2005 +0300 @@ -78,17 +78,18 @@ } static void -user_callback(const char *result, struct auth_request *auth_request) +user_callback(struct auth_stream_reply *reply, + struct auth_request *auth_request) { struct auth_master_connection *conn = auth_request->context; string_t *str; str = t_str_new(128); - if (result == NULL) + if (reply == NULL) str_printfa(str, "NOTFOUND\t%u\n", auth_request->id); else { str_printfa(str, "USER\t%u\t", auth_request->id); - str_append(str, result); + str_append(str, auth_stream_reply_export(reply)); str_append_c(str, '\n'); } (void)o_stream_send(conn->output, str_data(str), str_len(str)); diff -r 7addee16b026 -r e2fe8222449d src/auth/auth-request-handler.c --- a/src/auth/auth-request-handler.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/auth-request-handler.c Sun Aug 07 14:41:19 2005 +0300 @@ -104,16 +104,19 @@ static const char *get_client_extra_fields(struct auth_request *request) { string_t *str; - const char **fields; + const char **fields, *extra_fields; unsigned int src, dest; + extra_fields = request->extra_fields == NULL ? NULL : + auth_stream_reply_export(request->extra_fields); + if (!request->proxy) { - if (request->extra_fields == NULL) + if (extra_fields == NULL) return NULL; /* we only wish to remove all fields prefixed with "userdb_" */ - if (strstr(str_c(request->extra_fields), "userdb_") == NULL) - return str_c(request->extra_fields); + if (strstr(extra_fields, "userdb_") == NULL) + return extra_fields; } str = t_str_new(128); @@ -123,7 +126,7 @@ str_printfa(str, "pass=%s", request->mech_password); } - fields = t_strsplit(str_c(request->extra_fields), "\t"); + fields = t_strsplit(extra_fields, "\t"); for (src = dest = 0; fields[src] != NULL; src++) { if (strncmp(fields[src], "userdb_", 7) != 0) { if (str_len(str) > 0) @@ -374,23 +377,24 @@ return TRUE; } -static void userdb_callback(const char *result, struct auth_request *request) +static void userdb_callback(struct auth_stream_reply *reply, + struct auth_request *request) { struct auth_request_handler *handler = request->context; - string_t *reply; + string_t *str; i_assert(request->state == AUTH_REQUEST_STATE_USERDB); request->state = AUTH_REQUEST_STATE_FINISHED; - reply = t_str_new(256); - if (result == NULL) - str_printfa(reply, "NOTFOUND\t%u", request->id); + str = t_str_new(256); + if (reply == NULL) + str_printfa(str, "NOTFOUND\t%u", request->id); else { - str_printfa(reply, "USER\t%u\t", request->id); - str_append(reply, result); + str_printfa(str, "USER\t%u\t", request->id); + str_append(str, auth_stream_reply_export(reply)); } - handler->master_callback(str_c(reply), request->master); + handler->master_callback(str_c(str), request->master); auth_request_unref(request); auth_request_handler_unref(handler); diff -r 7addee16b026 -r e2fe8222449d src/auth/auth-request.c --- a/src/auth/auth-request.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/auth-request.c Sun Aug 07 14:41:19 2005 +0300 @@ -153,11 +153,14 @@ enum passdb_result result) { struct passdb_module *passdb = request->passdb->passdb; + const char *extra_fields; string_t *str; - i_assert(request->extra_fields == NULL || - (strstr(str_c(request->extra_fields), "\tpass=") == NULL && - strncmp(str_c(request->extra_fields), "pass=", 5) != 0)); + extra_fields = request->extra_fields == NULL ? NULL : + auth_stream_reply_export(request->extra_fields); + i_assert(extra_fields == NULL || + (strstr(extra_fields, "\tpass=") == NULL && + strncmp(extra_fields, "pass=", 5) != 0)); if (passdb_cache == NULL) return; @@ -175,8 +178,7 @@ } /* save all except the currently given password in cache */ - str = t_str_new(32 + (request->extra_fields != NULL ? - str_len(request->extra_fields) : 0)); + str = t_str_new(256); if (request->passdb_password != NULL) { if (*request->passdb_password != '{') { /* cached passwords must have a known scheme */ @@ -184,12 +186,16 @@ str_append(str, passdb->default_pass_scheme); str_append_c(str, '}'); } + if (strchr(request->passdb_password, '\t') != NULL) + i_panic("%s: Password contains TAB", request->user); + if (strchr(request->passdb_password, '\n') != NULL) + i_panic("%s: Password contains LF", request->user); str_append(str, request->passdb_password); } - if (request->extra_fields != NULL) { + if (extra_fields != NULL) { str_append_c(str, '\t'); - str_append_str(str, request->extra_fields); + str_append(str, extra_fields); } if (request->no_failure_delay) { str_append_c(str, '\t'); @@ -235,7 +241,7 @@ request->passdb->next != NULL) { /* try next passdb. */ if (request->extra_fields != NULL) - str_truncate(request->extra_fields, 0); + auth_stream_reply_reset(request->extra_fields); request->state = AUTH_REQUEST_STATE_MECH_CONTINUE; request->passdb = request->passdb->next; @@ -355,13 +361,13 @@ } } -void auth_request_userdb_callback(const char *result, +void auth_request_userdb_callback(struct auth_stream_reply *reply, struct auth_request *request) { - if (result == NULL && request->userdb->next != NULL) { + if (reply == NULL && request->userdb->next != NULL) { /* try next userdb. */ if (request->extra_fields != NULL) - str_truncate(request->extra_fields, 0); + auth_stream_reply_reset(request->extra_fields); request->userdb = request->userdb->next; auth_request_lookup_user(request, @@ -369,13 +375,13 @@ return; } - if (result == NULL && request->client_pid != 0) { + if (reply == NULL && request->client_pid != 0) { /* this was actual login attempt */ auth_request_log_error(request, "userdb", "user not found from userdb"); } - request->private_callback.userdb(result, request); + request->private_callback.userdb(reply, request); } void auth_request_lookup_user(struct auth_request *request, @@ -426,8 +432,6 @@ const char *name, const char *value, const char *default_scheme) { - string_t *str; - i_assert(value != NULL); if (strcmp(name, "password") == 0) { @@ -466,29 +470,19 @@ return; } - str = request->extra_fields; - if (str == NULL) - request->extra_fields = str = str_new(request->pool, 64); - if (strcmp(name, "nologin") == 0) { /* user can't actually login - don't keep this reply for master */ request->no_login = TRUE; - if (str_len(str) > 0) - str_append_c(str, '\t'); - str_append(str, name); } else if (strcmp(name, "proxy") == 0) { /* we're proxying authentication for this user. send password back if using plaintext authentication. */ request->proxy = TRUE; - if (str_len(str) > 0) - str_append_c(str, '\t'); - str_append(str, name); - } else { - if (str_len(str) > 0) - str_append_c(str, '\t'); - str_printfa(str, "%s=%s", name, value); } + + if (request->extra_fields == NULL) + request->extra_fields = auth_stream_reply_init(request); + auth_stream_reply_add(request->extra_fields, name, value); } static const char *escape_none(const char *str) diff -r 7addee16b026 -r e2fe8222449d src/auth/auth-request.h --- a/src/auth/auth-request.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/auth-request.h Sun Aug 07 14:41:19 2005 +0300 @@ -24,7 +24,7 @@ char *user; char *mech_password; /* set if verify_plain() is called */ char *passdb_password; /* set after password lookup if successful */ - string_t *extra_fields; + struct auth_stream_reply *extra_fields; struct mech_module *mech; struct auth *auth; @@ -116,7 +116,7 @@ void auth_request_lookup_credentials_callback(enum passdb_result result, const char *credentials, struct auth_request *request); -void auth_request_userdb_callback(const char *result, +void auth_request_userdb_callback(struct auth_stream_reply *reply, struct auth_request *request); #endif diff -r 7addee16b026 -r e2fe8222449d src/auth/auth-worker-client.c --- a/src/auth/auth-worker-client.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/auth-worker-client.c Sun Aug 07 14:41:19 2005 +0300 @@ -90,8 +90,11 @@ if (request->passdb_password != NULL) str_append(str, request->passdb_password); str_append_c(str, '\t'); - if (request->extra_fields != NULL) - str_append_str(str, request->extra_fields); + if (request->extra_fields != NULL) { + const char *field = + auth_stream_reply_export(request->extra_fields); + str_append(str, field); + } } str_append_c(str, '\n'); o_stream_send(client->output, str_data(str), str_len(str)); @@ -161,8 +164,11 @@ str_printfa(str, "OK\t%s\t{%s}%s\t", request->user, passdb_credentials_to_str(request->credentials), credentials); - if (request->extra_fields != NULL) - str_append_str(str, request->extra_fields); + if (request->extra_fields != NULL) { + const char *field = + auth_stream_reply_export(request->extra_fields); + str_append(str, field); + } } str_append_c(str, '\n'); o_stream_send(client->output, str_data(str), str_len(str)); @@ -220,15 +226,16 @@ } static void -lookup_user_callback(const char *result, struct auth_request *auth_request) +lookup_user_callback(struct auth_stream_reply *reply, + struct auth_request *auth_request) { struct auth_worker_client *client = auth_request->context; string_t *str; str = t_str_new(64); str_printfa(str, "%u\t", auth_request->id); - if (result != NULL) - str_append(str, result); + if (reply != NULL) + str_append(str, auth_stream_reply_export(reply)); str_append_c(str, '\n'); o_stream_send(client->output, str_data(str), str_len(str)); diff -r 7addee16b026 -r e2fe8222449d src/auth/passdb-blocking.c --- a/src/auth/passdb-blocking.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/passdb-blocking.c Sun Aug 07 14:41:19 2005 +0300 @@ -87,8 +87,8 @@ if (p != NULL && (p[6] == '\0' || p[6] == '\t')) request->proxy = TRUE; - request->extra_fields = str_new(request->pool, 128); - str_append(request->extra_fields, reply); + request->extra_fields = auth_stream_reply_init(request); + auth_stream_reply_import(request->extra_fields, reply); } return 0; } diff -r 7addee16b026 -r e2fe8222449d src/auth/passdb-checkpassword.c --- a/src/auth/passdb-checkpassword.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/passdb-checkpassword.c Sun Aug 07 14:41:19 2005 +0300 @@ -62,10 +62,9 @@ if (result == PASSDB_RESULT_OK) { request->request->extra_fields = - str_new(request->request->pool, - str_len(request->input_buf)); - str_append_str(request->request->extra_fields, - request->input_buf); + auth_stream_reply_init(request->request); + auth_stream_reply_import(request->request->extra_fields, + str_c(request->input_buf)); } if (auth_request_unref(request->request)) { diff -r 7addee16b026 -r e2fe8222449d src/auth/passdb.h --- a/src/auth/passdb.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/passdb.h Sun Aug 07 14:41:19 2005 +0300 @@ -67,7 +67,7 @@ lookup_credentials_callback_t *callback, struct auth_request *auth_request); -const char * passdb_credentials_to_str(enum passdb_credentials credentials); +const char *passdb_credentials_to_str(enum passdb_credentials credentials); void passdb_preinit(struct auth *auth, const char *driver, const char *args); void passdb_init(struct auth_passdb *passdb); diff -r 7addee16b026 -r e2fe8222449d src/auth/userdb-blocking.c --- a/src/auth/userdb-blocking.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/userdb-blocking.c Sun Aug 07 14:41:19 2005 +0300 @@ -10,10 +10,15 @@ static void user_callback(struct auth_request *request, const char *reply) { + struct auth_stream_reply *stream_reply; + if (*reply == '\0') reply = NULL; - request->private_callback.userdb(reply, request); + stream_reply = auth_stream_reply_init(request); + auth_stream_reply_import(stream_reply, reply); + + request->private_callback.userdb(stream_reply, request); } void userdb_blocking_lookup(struct auth_request *request) diff -r 7addee16b026 -r e2fe8222449d src/auth/userdb-ldap.c --- a/src/auth/userdb-ldap.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/userdb-ldap.c Sun Aug 07 14:41:19 2005 +0300 @@ -25,57 +25,53 @@ static struct ldap_connection *userdb_ldap_conn; -static int append_uid_list(struct auth_request *auth_request, string_t *str, +static int append_uid_list(struct auth_request *auth_request, + struct auth_stream_reply *reply, const char *name, char **vals) { uid_t uid; for (; *vals != NULL; vals++) { - str_append_c(str, '\t'); - str_append(str, name); - str_append_c(str, '='); - uid = userdb_parse_uid(auth_request, *vals); if (uid == (uid_t)-1) return FALSE; - str_append(str, dec2str(uid)); + + auth_stream_reply_add(reply, name, dec2str(uid)); } return TRUE; } -static int append_gid_list(struct auth_request *auth_request, string_t *str, +static int append_gid_list(struct auth_request *auth_request, + struct auth_stream_reply *reply, const char *name, char **vals) { gid_t gid; for (; *vals != NULL; vals++) { - str_append_c(str, '\t'); - str_append(str, name); - str_append_c(str, '='); - gid = userdb_parse_gid(auth_request, *vals); if (gid == (gid_t)-1) return FALSE; - str_append(str, dec2str(gid)); + + auth_stream_reply_add(reply, name, dec2str(gid)); } return TRUE; } -static const char * +static struct auth_stream_reply * ldap_query_get_result(struct ldap_connection *conn, LDAPMessage *entry, struct auth_request *auth_request) { - string_t *str; + struct auth_stream_reply *reply; BerElement *ber; const char *name; char *attr, **vals; unsigned int i; int seen_uid = FALSE, seen_gid = FALSE; - str = t_str_new(256); - str_append(str, auth_request->user); + reply = auth_stream_reply_init(auth_request); + auth_stream_reply_add(reply, NULL, auth_request->user); attr = ldap_first_attribute(conn->ld, entry, &ber); while (attr != NULL) { @@ -84,21 +80,19 @@ if (name != NULL && vals != NULL && vals[0] != NULL) { if (strcmp(name, "uid") == 0) { - if (!append_uid_list(auth_request, str, + if (!append_uid_list(auth_request, reply, name, vals)) return NULL; seen_uid = TRUE; } else if (strcmp(name, "gid") == 0) { - if (!append_gid_list(auth_request, str, - name, vals)) + if (!append_gid_list(auth_request, reply, + name, vals)) return NULL; seen_gid = TRUE; } else { for (i = 0; vals[i] != NULL; i++) { - str_append_c(str, '\t'); - str_append(str, name); - str_append_c(str, '='); - str_append(str, vals[i]); + auth_stream_reply_add(reply, name, + vals[i]); } } } @@ -109,30 +103,27 @@ } if (!seen_uid) { - } - - if (!seen_uid) { if (conn->set.uid == (uid_t)-1) { auth_request_log_error(auth_request, "ldap", "uid not in user_attrs and no default given in " "user_global_uid"); + return NULL; } - str_append(str, "\tuid="); - str_append(str, dec2str(conn->set.uid)); + auth_stream_reply_add(reply, "uid", dec2str(conn->set.uid)); } if (!seen_gid) { if (conn->set.gid == (gid_t)-1) { auth_request_log_error(auth_request, "ldap", "gid not in user_attrs and no default given in " "user_global_gid"); + return NULL; } - str_append(str, "\tgid="); - str_append(str, dec2str(conn->set.gid)); + auth_stream_reply_add(reply, "gid", dec2str(conn->set.gid)); } - return str_c(str); + return reply; } static void handle_request(struct ldap_connection *conn, @@ -142,7 +133,7 @@ (struct userdb_ldap_request *) request; struct auth_request *auth_request = urequest->auth_request; LDAPMessage *entry; - const char *result; + struct auth_stream_reply *reply = NULL; int ret; ret = ldap_result2error(conn->ld, res, 0); @@ -159,17 +150,16 @@ auth_request_log_error(auth_request, "ldap", "Authenticated user not found"); } - result = NULL; } else { - result = ldap_query_get_result(conn, entry, auth_request); + reply = ldap_query_get_result(conn, entry, auth_request); if (ldap_next_entry(conn->ld, entry) != NULL) { auth_request_log_error(auth_request, "ldap", "Multiple replies found for user"); - result = NULL; + reply = NULL; } } - urequest->userdb_callback(result, auth_request); + urequest->userdb_callback(reply, auth_request); } static void userdb_ldap_lookup(struct auth_request *auth_request, diff -r 7addee16b026 -r e2fe8222449d src/auth/userdb-passdb.c --- a/src/auth/userdb-passdb.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/userdb-passdb.c Sun Aug 07 14:41:19 2005 +0300 @@ -2,7 +2,8 @@ #include "common.h" -#ifdef USERDB_PASSDB +//#ifdef USERDB_PASSDB +#if 1 #include "str.h" #include "var-expand.h" @@ -34,7 +35,10 @@ str = t_str_new(256); str_append(str, auth_request->user); - args = t_strsplit(str_c(auth_request->extra_fields), "\t"); + /* export the request. keep all keys starting with userdb_ but strip + the userdb_ away. */ + args = t_strsplit(auth_stream_reply_export(auth_request->extra_fields), + "\t"); for (; *args != NULL; args++) { const char *arg = *args; @@ -75,8 +79,15 @@ if (uid == (uid_t)-1 || gid == (gid_t)-1) callback(NULL, auth_request); - else - callback(str_c(str), auth_request); + else { + struct auth_stream_reply *reply; + + /* import the string into request. since the values were + exported they are already in escaped form in the string. */ + reply = auth_stream_reply_init(auth_request); + auth_stream_reply_import(reply, str_c(str)); + callback(reply, auth_request); + } t_pop(); } diff -r 7addee16b026 -r e2fe8222449d src/auth/userdb-passwd-file.c --- a/src/auth/userdb-passwd-file.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/userdb-passwd-file.c Sun Aug 07 14:41:19 2005 +0300 @@ -13,8 +13,8 @@ static void passwd_file_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { + struct auth_stream_reply *reply; struct passwd_user *pu; - string_t *str; pu = db_passwd_file_lookup(userdb_pwf, auth_request); if (pu == NULL) { @@ -22,16 +22,17 @@ return; } - str = t_str_new(128); - str_printfa(str, "%s\tuid=%s\tgid=%s", - auth_request->user, dec2str(pu->uid), dec2str(pu->gid)); + reply = auth_stream_reply_init(auth_request); + auth_stream_reply_add(reply, NULL, auth_request->user); + auth_stream_reply_add(reply, "uid", dec2str(pu->uid)); + auth_stream_reply_add(reply, "gid", dec2str(pu->gid)); if (pu->home != NULL) - str_printfa(str, "\thome=%s", pu->home); + auth_stream_reply_add(reply, "home", pu->home); if (pu->mail != NULL) - str_printfa(str, "\tmail=%s", pu->mail); + auth_stream_reply_add(reply, "mail", pu->mail); - callback(str_c(str), auth_request); + callback(reply, auth_request); } static void passwd_file_init(const char *args) diff -r 7addee16b026 -r e2fe8222449d src/auth/userdb-passwd.c --- a/src/auth/userdb-passwd.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/userdb-passwd.c Sun Aug 07 14:41:19 2005 +0300 @@ -12,7 +12,7 @@ userdb_callback_t *callback) { struct passwd *pw; - const char *result; + struct auth_stream_reply *reply; pw = getpwnam(auth_request->user); if (pw == NULL) { @@ -29,11 +29,14 @@ pw->pw_name, auth_request->user); } - result = t_strdup_printf("%s\tsystem_user=%s\tuid=%s\tgid=%s\t" - "home=%s", pw->pw_name, pw->pw_name, - dec2str(pw->pw_uid), dec2str(pw->pw_gid), - pw->pw_dir); - callback(result, auth_request); + reply = auth_stream_reply_init(auth_request); + auth_stream_reply_add(reply, NULL, pw->pw_name); + auth_stream_reply_add(reply, "system_user", pw->pw_name); + auth_stream_reply_add(reply, "uid", dec2str(pw->pw_uid)); + auth_stream_reply_add(reply, "gid", dec2str(pw->pw_gid)); + auth_stream_reply_add(reply, "home", pw->pw_dir); + + callback(reply, auth_request); } struct userdb_module userdb_passwd = { diff -r 7addee16b026 -r e2fe8222449d src/auth/userdb-sql.c --- a/src/auth/userdb-sql.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/userdb-sql.c Sun Aug 07 14:41:19 2005 +0300 @@ -22,10 +22,11 @@ static struct sql_connection *userdb_sql_conn; -static const char *sql_query_get_result(struct sql_result *result, - struct auth_request *auth_request) +static struct auth_stream_reply * +sql_query_get_result(struct sql_result *result, + struct auth_request *auth_request) { - string_t *str; + struct auth_stream_reply *reply; uid_t uid, gid; const char *name, *value; unsigned int i, fields_count; @@ -33,8 +34,8 @@ uid = (uid_t)-1; gid = (gid_t)-1; - str = t_str_new(256); - str_append(str, auth_request->user); + reply = auth_stream_reply_init(auth_request); + auth_stream_reply_add(reply, NULL, auth_request->user); fields_count = sql_result_get_fields_count(result); for (i = 0; i < fields_count; i++) { @@ -44,10 +45,6 @@ if (value == NULL) continue; - str_append_c(str, '\t'); - str_append(str, name); - str_append_c(str, '='); - /* some special handling for UID and GID. */ if (strcmp(name, "uid") == 0) { uid = userdb_parse_uid(auth_request, value); @@ -61,26 +58,28 @@ value = dec2str(gid); } - str_append(str, value); + auth_stream_reply_add(reply, name, value); } if (uid == (uid_t)-1) { auth_request_log_error(auth_request, "sql", "Password query didn't return uid, or it was NULL"); + return NULL; } if (gid == (gid_t)-1) { auth_request_log_error(auth_request, "sql", "Password query didn't return gid, or it was NULL"); + return NULL; } - return str_c(str); + return reply; } static void sql_query_callback(struct sql_result *result, void *context) { struct userdb_sql_request *sql_request = context; struct auth_request *auth_request = sql_request->auth_request; - const char *user_result = NULL; + struct auth_stream_reply *reply = NULL; int ret; ret = sql_result_next_row(result); @@ -90,10 +89,10 @@ } else if (ret == 0) { auth_request_log_info(auth_request, "sql", "User not found"); } else { - user_result = sql_query_get_result(result, auth_request); + reply = sql_query_get_result(result, auth_request); } - sql_request->callback(user_result, auth_request); + sql_request->callback(reply, auth_request); i_free(sql_request); } diff -r 7addee16b026 -r e2fe8222449d src/auth/userdb-static.c --- a/src/auth/userdb-static.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/userdb-static.c Sun Aug 07 14:41:19 2005 +0300 @@ -4,74 +4,97 @@ #ifdef USERDB_STATIC +#include "array.h" #include "str.h" #include "var-expand.h" #include "userdb.h" #include -static char *static_template; +static pool_t static_pool; +static array_t ARRAY_DEFINE(static_template, const char *); static void static_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { + const struct var_expand_table *table; + struct auth_stream_reply *reply; string_t *str; + const char *const *args; + unsigned int i, count; + + t_push(); + str = t_str_new(256); + table = auth_request_get_var_expand_table(auth_request, NULL); - str = t_str_new(128); - str_append(str, auth_request->user); - var_expand(str, static_template, - auth_request_get_var_expand_table(auth_request, NULL)); - callback(str_c(str), auth_request); + reply = auth_stream_reply_init(auth_request); + auth_stream_reply_add(reply, NULL, auth_request->user); + + args = array_get(&static_template, &count); + i_assert((count % 2) == 0); + for (i = 0; i < count; i += 2) { + str_truncate(str, 0); + var_expand(str, args[i+1], table); + auth_stream_reply_add(reply, args[i], str_c(str)); + } + + callback(reply, auth_request); } static void static_init(const char *args) { - const char *const *tmp; + const char *const *tmp, *key, *value; uid_t uid; gid_t gid; - string_t *str; + static_pool = pool_alloconly_create("static userdb", 256); uid = (uid_t)-1; gid = (gid_t)-1; + ARRAY_CREATE(&static_template, static_pool, const char *, 16); + t_push(); - str = t_str_new(128); - for (tmp = t_strsplit_spaces(args, " "); *tmp != NULL; tmp++) { - str_append_c(str, '\t'); - if (strncasecmp(*tmp, "uid=", 4) == 0) { - uid = userdb_parse_uid(NULL, *tmp + 4); + value = strchr(*tmp, '='); + if (value == NULL) + key = *tmp; + else { + key = t_strdup_until(*tmp, value); + value++; + } + + if (strcasecmp(key, "uid") == 0) { + uid = userdb_parse_uid(NULL, value); if (uid == (uid_t)-1) { i_fatal("static userdb: Invalid uid: %s", - *tmp + 4); + value); } - str_append(str, "uid="); - str_append(str, dec2str(uid)); - } else if (strncasecmp(*tmp, "gid=", 4) == 0) { - gid = userdb_parse_gid(NULL, *tmp + 4); + value = dec2str(uid); + } else if (strcasecmp(key, "gid") == 0) { + gid = userdb_parse_gid(NULL, value); if (gid == (gid_t)-1) { i_fatal("static userdb: Invalid gid: %s", - *tmp + 4); + value); } - str_append(str, "gid="); - str_append(str, dec2str(gid)); - } else { - str_append(str, *tmp); + value = dec2str(gid); } + key = p_strdup(static_pool, key); + value = p_strdup(static_pool, value); + + array_append(&static_template, &key, 1); + array_append(&static_template, &value, 1); } + t_pop(); if (uid == (uid_t)-1) i_fatal("static userdb: uid missing"); if (gid == (gid_t)-1) i_fatal("static userdb: gid missing"); - - static_template = i_strdup(str_c(str)); - t_pop(); } static void static_deinit(void) { - i_free(static_template); + pool_unref(static_pool); } struct userdb_module userdb_static = { diff -r 7addee16b026 -r e2fe8222449d src/auth/userdb-vpopmail.c --- a/src/auth/userdb-vpopmail.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/userdb-vpopmail.c Sun Aug 07 14:41:19 2005 +0300 @@ -44,7 +44,7 @@ { char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT]; struct vqpasswd *vpw; - const char *result; + struct auth_stream_reply *reply; uid_t uid; gid_t gid; @@ -84,11 +84,13 @@ } } - result = t_strdup_printf("%s\tuid=%s\tgid=%s\thome=%s", - vpw->pw_name, dec2str(uid), dec2str(gid), - vpw->pw_dir); + reply = auth_stream_reply_init(); + auth_stream_reply_add(reply, NULL, vpw->pw_name); + auth_stream_reply_add(reply, "uid", dec2str(uid)); + auth_stream_reply_add(reply, "gid", dec2str(gid)); + auth_stream_reply_add(reply, "home", vpw->pw_dir); - callback(result, auth_request); + callback(reply, auth_request); } struct userdb_module userdb_vpopmail = { diff -r 7addee16b026 -r e2fe8222449d src/auth/userdb.c --- a/src/auth/userdb.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/userdb.c Sun Aug 07 14:41:19 2005 +0300 @@ -45,6 +45,9 @@ { struct passwd *pw; + if (str == NULL) + return (uid_t)-1; + if (*str >= '0' && *str <= '9') return (uid_t)strtoul(str, NULL, 10); @@ -63,6 +66,9 @@ { struct group *gr; + if (str == NULL) + return (uid_t)-1; + if (*str >= '0' && *str <= '9') return (gid_t)strtoul(str, NULL, 10); diff -r 7addee16b026 -r e2fe8222449d src/auth/userdb.h --- a/src/auth/userdb.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/auth/userdb.h Sun Aug 07 14:41:19 2005 +0300 @@ -1,9 +1,11 @@ #ifndef __USERDB_H #define __USERDB_H +#include "auth-stream.h" + struct auth_request; -typedef void userdb_callback_t(const char *result, +typedef void userdb_callback_t(struct auth_stream_reply *reply, struct auth_request *request); struct userdb_module { diff -r 7addee16b026 -r e2fe8222449d src/imap/client.h --- a/src/imap/client.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/imap/client.h Sun Aug 07 14:41:19 2005 +0300 @@ -74,7 +74,7 @@ const char *msg); /* Read a number of arguments. Returns TRUE if everything was read or - FALSE if either needs more data or error occured. */ + FALSE if either needs more data or error occurred. */ int client_read_args(struct client_command_context *cmd, unsigned int count, unsigned int flags, struct imap_arg **args); /* Reads a number of string arguments. ... is a list of pointers where to diff -r 7addee16b026 -r e2fe8222449d src/imap/cmd-idle.c --- a/src/imap/cmd-idle.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/imap/cmd-idle.c Sun Aug 07 14:41:19 2005 +0300 @@ -159,7 +159,7 @@ /* outlook workaround */ idle_send_expunge(ctx); } else if (ctx->sync_pending) { - /* more changes occured while we were sending changes to + /* more changes occurred while we were sending changes to client */ idle_callback(client->mailbox, client); } diff -r 7addee16b026 -r e2fe8222449d src/lib-imap/imap-parser.h --- a/src/lib-imap/imap-parser.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib-imap/imap-parser.h Sun Aug 07 14:41:19 2005 +0300 @@ -93,7 +93,7 @@ /* Read a number of arguments. This function doesn't call i_stream_read(), you need to do that. Returns number of arguments read (may be less than count - in case of EOL), -2 if more data is needed or -1 if error occured. + in case of EOL), -2 if more data is needed or -1 if error occurred. count-sized array of arguments are stored into args when return value is 0 or larger. If all arguments weren't read, they're set to NIL. count diff -r 7addee16b026 -r e2fe8222449d src/lib-mail/message-parser.h --- a/src/lib-mail/message-parser.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib-mail/message-parser.h Sun Aug 07 14:41:19 2005 +0300 @@ -110,7 +110,7 @@ /* Read and return next header line. Returns 1 if header is returned, 0 if input stream is non-blocking and more data needs to be read, -1 when all is - done or error occured (see stream's error status). */ + done or error occurred (see stream's error status). */ int message_parse_header_next(struct message_header_parser_ctx *ctx, struct message_header_line **hdr_r); diff -r 7addee16b026 -r e2fe8222449d src/lib-sql/sql-api.h --- a/src/lib-sql/sql-api.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib-sql/sql-api.h Sun Aug 07 14:41:19 2005 +0300 @@ -34,7 +34,7 @@ sql_query_callback_t *callback, void *context); /* Go to next row, returns 1 if ok, 0 if this was the last row or -1 if error - occured. This needs to be the first call for result. */ + occurred. This needs to be the first call for result. */ int sql_result_next_row(struct sql_result *result); /* Return number of fields in result. */ diff -r 7addee16b026 -r e2fe8222449d src/lib-storage/index/maildir/maildir-sync.c --- a/src/lib-storage/index/maildir/maildir-sync.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync.c Sun Aug 07 14:41:19 2005 +0300 @@ -5,14 +5,14 @@ it's problems: We want to be as efficient as we can. The most efficient way to - check if changes have occured is to stat() the new/ and cur/ + check if changes have occurred is to stat() the new/ and cur/ directories and uidlist file - if their mtimes haven't changed, there's no changes and we don't need to do anything. Problem 1: Multiple changes can happen within a single second - nothing guarantees that once we synced it, someone else didn't just then make a modification. Such modifications wouldn't get noticed - until a new modification occured later. + until a new modification occurred later. Problem 2: Syncing cur/ directory is much more costly than syncing new/. Moving mails from new/ to cur/ will always change mtime of diff -r 7addee16b026 -r e2fe8222449d src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib-storage/mail-storage.c Sun Aug 07 14:41:19 2005 +0300 @@ -11,7 +11,7 @@ /* Message to show to users when critical error occurs */ #define CRITICAL_MSG \ - "Internal error occured. Refer to server log for more information." + "Internal error occurred. Refer to server log for more information." #define CRITICAL_MSG_STAMP CRITICAL_MSG " [%Y-%m-%d %H:%M:%S]" unsigned int mail_storage_module_id = 0; diff -r 7addee16b026 -r e2fe8222449d src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib-storage/mail-storage.h Sun Aug 07 14:41:19 2005 +0300 @@ -268,7 +268,7 @@ struct mailbox_list * mail_storage_mailbox_list_next(struct mailbox_list_context *ctx); /* Deinitialize mailbox list request. Returns FALSE if some error - occured while listing. */ + occurred while listing. */ int mail_storage_mailbox_list_deinit(struct mailbox_list_context *ctx); /* Subscribe/unsubscribe mailbox. There should be no error when @@ -282,7 +282,7 @@ const char *name, enum mailbox_name_status *status); -/* Returns the error message of last occured error. */ +/* Returns the error message of last occurred error. */ const char *mail_storage_get_last_error(struct mail_storage *storage, int *syntax_error_r, int *temporary_error_r); @@ -296,7 +296,7 @@ struct mailbox *mailbox_open(struct mail_storage *storage, const char *name, struct istream *input, enum mailbox_open_flags flags); -/* Close the box. Returns FALSE if some cleanup errors occured, but +/* Close the box. Returns FALSE if some cleanup errors occurred, but the mailbox was closed anyway. */ int mailbox_close(struct mailbox *box); @@ -416,18 +416,18 @@ int mail_set_seq(struct mail *mail, uint32_t seq); /* Get the time message was received (IMAP INTERNALDATE). - Returns (time_t)-1 if error occured. */ + Returns (time_t)-1 if error occurred. */ time_t mail_get_received_date(struct mail *mail); /* Get the Date-header in mail. Timezone is in minutes. - Returns (time_t)-1 if error occured, 0 if field wasn't found or + Returns (time_t)-1 if error occurred, 0 if field wasn't found or couldn't be parsed. */ time_t mail_get_date(struct mail *mail, int *timezone); /* Get the full virtual size of mail (IMAP RFC822.SIZE). - Returns (uoff_t)-1 if error occured */ + Returns (uoff_t)-1 if error occurred */ uoff_t mail_get_virtual_size(struct mail *mail); /* Get the full physical size of mail. - Returns (uoff_t)-1 if error occured */ + Returns (uoff_t)-1 if error occurred */ uoff_t mail_get_physical_size(struct mail *mail); /* Get value for single header field */ diff -r 7addee16b026 -r e2fe8222449d src/lib-storage/subscription-file/subscription-file.h --- a/src/lib-storage/subscription-file/subscription-file.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib-storage/subscription-file/subscription-file.h Sun Aug 07 14:41:19 2005 +0300 @@ -7,7 +7,7 @@ struct subsfile_list_context * subsfile_list_init(struct mail_storage *storage, const char *path); -/* Deinitialize subscription file listing. Returns FALSE if some error occured +/* Deinitialize subscription file listing. Returns FALSE if some error occurred while listing. */ int subsfile_list_deinit(struct subsfile_list_context *ctx); /* Returns the next subscribed mailbox, or NULL. */ diff -r 7addee16b026 -r e2fe8222449d src/lib/file-cache.h --- a/src/lib/file-cache.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib/file-cache.h Sun Aug 07 14:41:19 2005 +0300 @@ -10,7 +10,7 @@ void file_cache_set_fd(struct file_cache *cache, int fd); /* Read data from file, returns how many bytes was actually read or -1 if - error occured. */ + error occurred. */ ssize_t file_cache_read(struct file_cache *cache, uoff_t offset, size_t size); /* Returns pointer to beginning of cached file. Only parts of the returned diff -r 7addee16b026 -r e2fe8222449d src/lib/istream.h --- a/src/lib/istream.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib/istream.h Sun Aug 07 14:41:19 2005 +0300 @@ -63,7 +63,7 @@ needed to make a full line. */ char *i_stream_next_line(struct istream *stream); /* Like i_stream_next_line(), but reads for more data if needed. Returns NULL - if more data is needed or error occured. */ + if more data is needed or error occurred. */ char *i_stream_read_next_line(struct istream *stream); /* Returns pointer to beginning of read data, or NULL if there's no data diff -r 7addee16b026 -r e2fe8222449d src/lib/read-full.h --- a/src/lib/read-full.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib/read-full.h Sun Aug 07 14:41:19 2005 +0300 @@ -1,7 +1,7 @@ #ifndef __READ_FULL_H #define __READ_FULL_H -/* Read data from file. Returns -1 if error occured, or 0 if EOF came before +/* Read data from file. Returns -1 if error occurred, or 0 if EOF came before everything was read, or 1 if all was ok. */ int read_full(int fd, void *data, size_t size); int pread_full(int fd, void *data, size_t size, off_t offset); diff -r 7addee16b026 -r e2fe8222449d src/lib/strfuncs.c --- a/src/lib/strfuncs.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib/strfuncs.c Sun Aug 07 14:41:19 2005 +0300 @@ -98,7 +98,7 @@ va_end(args); if (len < 0) { - /* some error occured */ + /* some error occurred */ len = 0; ret = -1; } else if ((size_t)len >= max_chars) { diff -r 7addee16b026 -r e2fe8222449d src/lib/write-full.h --- a/src/lib/write-full.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/lib/write-full.h Sun Aug 07 14:41:19 2005 +0300 @@ -1,7 +1,7 @@ #ifndef __WRITE_FULL_H #define __WRITE_FULL_H -/* Write data into file. Returns -1 if error occured, or 0 if all was ok. +/* Write data into file. Returns -1 if error occurred, or 0 if all was ok. If there's not enough space in device, -1 with ENOSPC is returned, and it's unspecified how much data was actually written. */ int write_full(int fd, const void *data, size_t size); diff -r 7addee16b026 -r e2fe8222449d src/login-common/ssl-proxy-gnutls.c --- a/src/login-common/ssl-proxy-gnutls.c Sun Aug 07 14:28:13 2005 +0300 +++ b/src/login-common/ssl-proxy-gnutls.c Sun Aug 07 14:41:19 2005 +0300 @@ -80,7 +80,7 @@ } if (verbose_ssl) { - /* fatal error occured */ + /* fatal error occurred */ if (error == GNUTLS_E_FATAL_ALERT_RECEIVED) { i_warning("Received SSL fatal alert: %s [%s]", get_alert_text(proxy), diff -r 7addee16b026 -r e2fe8222449d src/login-common/ssl-proxy.h --- a/src/login-common/ssl-proxy.h Sun Aug 07 14:28:13 2005 +0300 +++ b/src/login-common/ssl-proxy.h Sun Aug 07 14:41:19 2005 +0300 @@ -7,7 +7,7 @@ extern int ssl_initialized; /* establish SSL connection with the given fd, returns a new fd which you - must use from now on, or -1 if error occured. Unless -1 is returned, + must use from now on, or -1 if error occurred. Unless -1 is returned, the given fd must be simply forgotten. */ int ssl_proxy_new(int fd, struct ip_addr *ip, struct ssl_proxy **proxy_r); int ssl_proxy_has_valid_client_cert(struct ssl_proxy *proxy);