log IP address.
--HG--
branch : HEAD
}
struct passwd_user *
-db_passwd_file_lookup(struct passwd_file *pw, const char *user)
+db_passwd_file_lookup(struct passwd_file *pw, struct auth_request *request)
{
struct passwd_user *pu;
passwd_file_sync(pw);
- pu = hash_lookup(pw->users, user);
+ pu = hash_lookup(pw->users, request->user);
if (pu == NULL) {
- if (verbose)
- i_info("passwd-file(%s): unknown user", user);
+ if (verbose) {
+ i_info("passwd-file(%s): unknown user",
+ get_log_prefix(request));
+ }
}
return pu;
extern struct passwd_file *passdb_pwf;
struct passwd_user *
-db_passwd_file_lookup(struct passwd_file *pw, const char *user);
+db_passwd_file_lookup(struct passwd_file *pw, struct auth_request *request);
struct passwd_file *db_passwd_file_parse(const char *path, int userdb);
void db_passwd_file_unref(struct passwd_file *pw);
i_assert(anonymous_username != NULL);
if (verbose) {
- i_info("mech-anonymous: login by %s",
- t_strndup(data, data_size));
+ auth_request->user =
+ p_strndup(pool_datastack_create(), data, data_size);
+ i_info("anonymous(%s): login",
+ get_log_prefix(auth_request));
}
auth_request->callback = callback;
auth_request->user = p_strdup(auth_request->pool, anonymous_username);
+
mech_auth_finish(auth_request, NULL, 0, TRUE);
return TRUE;
}
if (memcmp(response_hex, auth->response, 32) != 0) {
if (verbose) {
i_info("cram-md5(%s): password mismatch",
- auth->username);
+ get_log_prefix(&auth->auth_request));
}
return FALSE;
}
if (verify_credentials(auth, result)) {
if (verbose) {
i_info("cram-md5(%s): authenticated",
- auth->username == NULL ? "" : auth->username);
+ get_log_prefix(&auth->auth_request));
}
mech_auth_finish(request, NULL, 0, TRUE);
} else {
if (verbose) {
i_info("cram-md5(%s): authentication failed",
- auth->username == NULL ? "" : auth->username);
+ get_log_prefix(&auth->auth_request));
}
mech_auth_finish(request, NULL, 0, FALSE);
}
if (verbose) {
i_info("cram-md5(%s): %s",
- auth->username == NULL ? "" : auth->username, error);
+ get_log_prefix(&auth->auth_request), error);
}
/* failed */
/* verify response */
if (memcmp(response_hex, auth->response, 32) != 0) {
if (verbose) {
+ struct auth_request *auth_request =
+ &auth->auth_request;
i_info("digest-md5(%s): "
"password mismatch",
- auth->username);
+ get_log_prefix(auth_request));
}
return FALSE;
}
error = "Authentication failed";
else if (verbose) {
i_info("digest-md5(%s): %s",
- auth->username == NULL ? "" : auth->username, error);
+ get_log_prefix(auth_request), error);
}
/* failed */
if (authenid == NULL) {
/* invalid input */
- if (verbose)
- i_info("mech-plain: no username given");
+ if (verbose) {
+ i_info("plain(%s): no username given",
+ get_log_prefix(auth_request));
+ }
mech_auth_finish(auth_request, NULL, 0, FALSE);
} else {
/* split and save user/realm */
if (!mech_is_valid_username(auth_request->user)) {
/* invalid username */
if (verbose) {
- i_info("mech-plain(%s): invalid username",
- auth_request->user);
+ i_info("plain(%s): invalid username",
+ get_log_prefix(auth_request));
}
mech_auth_finish(auth_request, NULL, 0, FALSE);
} else {
return;
}
- if (ssl_require_client_cert &&
- (request->flags & AUTH_CLIENT_FLAG_SSL_VALID_CLIENT_CERT) == 0) {
- /* we fail without valid certificate */
- if (verbose)
- i_info("Client didn't present valid SSL certificate");
- failure_reply.id = request->id;
- callback(&failure_reply, NULL, conn);
- return;
- }
-
#ifdef USE_CYRUS_SASL2
if (set_use_cyrus_sasl)
auth_request = mech_cyrus_sasl_new(conn, request, callback);
#endif
auth_request = mech->auth_new();
- if (auth_request != NULL) {
- auth_request->created = ioloop_time;
- auth_request->conn = conn;
- auth_request->id = request->id;
- auth_request->protocol =
- p_strdup(auth_request->pool,
- (const char *)data + request->protocol_idx);
-
- if (request->ip_family != 0) {
- auth_request->local_ip.family = request->ip_family;
- auth_request->remote_ip.family = request->ip_family;
-
-
- memcpy(&auth_request->local_ip, data, ip_size);
- memcpy(&auth_request->remote_ip, data + ip_size,
- ip_size);
- }
+ if (auth_request == NULL)
+ return;
- hash_insert(conn->auth_requests, POINTER_CAST(request->id),
- auth_request);
+ auth_request->created = ioloop_time;
+ auth_request->conn = conn;
+ auth_request->id = request->id;
+ auth_request->protocol =
+ p_strdup(auth_request->pool,
+ (const char *)data + request->protocol_idx);
- if (!auth_request->auth_initial(auth_request, request, data,
- callback))
- mech_request_free(auth_request, request->id);
+ if (request->ip_family != 0) {
+ auth_request->local_ip.family = request->ip_family;
+ auth_request->remote_ip.family = request->ip_family;
+
+ memcpy(&auth_request->local_ip.ip, data, ip_size);
+ memcpy(&auth_request->remote_ip.ip, data + ip_size, ip_size);
}
+
+ if (ssl_require_client_cert &&
+ (request->flags & AUTH_CLIENT_FLAG_SSL_VALID_CLIENT_CERT) == 0) {
+ /* we fail without valid certificate */
+ if (verbose) {
+ i_info("ssl-cert-check(%s): "
+ "Client didn't present valid SSL certificate",
+ get_log_prefix(auth_request));
+ }
+ auth_request_unref(auth_request);
+
+ failure_reply.id = request->id;
+ callback(&failure_reply, NULL, conn);
+ return;
+ }
+
+ hash_insert(conn->auth_requests, POINTER_CAST(request->id),
+ auth_request);
+
+ if (!auth_request->auth_initial(auth_request, request, data, callback))
+ mech_request_free(auth_request, request->id);
}
void mech_request_continue(struct auth_client_connection *conn,
return tab;
}
+const char *get_log_prefix(const struct auth_request *auth_request)
+{
+#define MAX_LOG_USERNAME_LEN 64
+ const char *p, *ip;
+ string_t *str;
+
+ str = t_str_new(64);
+
+ if (auth_request->user == NULL)
+ str_append(str, "?");
+ else {
+ /* any control characters in username will be replaced by '?' */
+ for (p = auth_request->user; *p != '\0'; p++) {
+ if ((unsigned char)*p < 32)
+ break;
+ }
+
+ str_append_n(str, auth_request->user,
+ (size_t)(p - auth_request->user));
+ for (; *p != '\0'; p++) {
+ if ((unsigned char)*p < 32)
+ str_append_c(str, '?');
+ else
+ str_append_c(str, *p);
+ }
+
+ if (str_len(str) > MAX_LOG_USERNAME_LEN) {
+ str_truncate(str, MAX_LOG_USERNAME_LEN);
+ str_append(str, "...");
+ }
+ }
+
+ ip = net_ip2addr(&auth_request->remote_ip);
+ if (ip != NULL) {
+ str_append_c(str, ',');
+ str_append(str, ip);
+ }
+ return str_c(str);
+}
+
extern struct mech_module mech_plain;
extern struct mech_module mech_cram_md5;
extern struct mech_module mech_digest_md5;
auth_request_get_var_expand_table(const struct auth_request *auth_request,
const char *(*escape_func)(const char *));
+const char *get_log_prefix(const struct auth_request *auth_request);
+
void mech_init(void);
void mech_deinit(void);
pw = getpwnam(request->user);
if (pw == NULL) {
- if (verbose)
- i_info("passwd(%s): unknown user", request->user);
+ if (verbose) {
+ i_info("passwd(%s): unknown user",
+ get_log_prefix(request));
+ }
callback(PASSDB_RESULT_USER_UNKNOWN, request);
return;
}
if (!IS_VALID_PASSWD(pw->pw_passwd)) {
if (verbose) {
i_info("passwd(%s): invalid password field '%s'",
- request->user, pw->pw_passwd);
+ get_log_prefix(request), pw->pw_passwd);
}
callback(PASSDB_RESULT_USER_DISABLED, request);
return;
safe_memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
if (!result) {
- if (verbose)
- i_info("passwd(%s): password mismatch", request->user);
+ if (verbose) {
+ i_info("passwd(%s): password mismatch",
+ get_log_prefix(request));
+ }
callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
return;
}
ret = ldap_result2error(conn->ld, res, 0);
if (ret != LDAP_SUCCESS) {
i_error("ldap(%s): ldap_search() failed: %s",
- user, ldap_err2string(ret));
+ get_log_prefix(auth_request),
+ ldap_err2string(ret));
res = NULL;
}
}
entry = res == NULL ? NULL : ldap_first_entry(conn->ld, res);
if (entry == NULL) {
- if (res != NULL)
- i_error("ldap(%s): unknown user", user);
+ if (res != NULL && verbose) {
+ i_info("ldap(%s): unknown user",
+ get_log_prefix(auth_request));
+ }
} else {
attr = ldap_first_attribute(conn->ld, entry, &ber);
while (attr != NULL) {
attr = ldap_next_attribute(conn->ld, entry, ber);
}
- if (password == NULL)
- i_error("ldap(%s): No password in reply", user);
- else if (ldap_next_entry(conn->ld, entry) != NULL) {
- i_error("ldap(%s): Multiple password replies", user);
+ if (password == NULL) {
+ i_error("ldap(%s): No password in reply",
+ get_log_prefix(auth_request));
+ } else if (ldap_next_entry(conn->ld, entry) != NULL) {
+ i_error("ldap(%s): Multiple password replies",
+ get_log_prefix(auth_request));
password = NULL;
}
}
}
ret = password_verify(ldap_request->password, password, scheme, user);
- if (ret < 0)
- i_error("ldap(%s): Unknown password scheme %s", user, scheme);
- else if (ret == 0) {
- if (verbose)
- i_info("ldap(%s): password mismatch", user);
+ if (ret < 0) {
+ i_error("ldap(%s): Unknown password scheme %s",
+ get_log_prefix(auth_request), scheme);
+ } else if (ret == 0) {
+ if (verbose) {
+ i_info("ldap(%s): password mismatch",
+ get_log_prefix(auth_request));
+ }
}
ldap_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
if (res != NULL) {
if (mysql_num_rows(res) == 0) {
- if (verbose)
- i_info("mysql(%s): Unknown user", user);
+ if (verbose) {
+ i_info("mysql(%s): Unknown user",
+ get_log_prefix(auth_request));
+ }
} else if (mysql_num_rows(res) > 1) {
- i_error("mysql(%s): Multiple matches for user", user);
+ i_error("mysql(%s): Multiple matches for user",
+ get_log_prefix(auth_request));
} else if (mysql_num_fields(res) != 1) {
i_error("mysql(%s): Password query returned "
- "more than one field", user);
+ "more than one field",
+ get_log_prefix(auth_request));
} else {
MYSQL_ROW row;
ret = password_verify(mysql_request->password, password,
scheme, user);
- if (ret < 0)
- i_error("mysql(%s): Unknown password scheme %s", user, scheme);
- else if (ret == 0) {
- if (verbose)
- i_info("mysql(%s): Password mismatch", user);
+ if (ret < 0) {
+ i_error("mysql(%s): Unknown password scheme %s",
+ get_log_prefix(auth_request), scheme);
+ } else if (ret == 0) {
+ if (verbose) {
+ i_info("mysql(%s): Password mismatch",
+ get_log_prefix(auth_request));
+ }
}
mysql_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
return PAM_SUCCESS;
}
-static int pam_auth(pam_handle_t *pamh, const char *user, const char **error)
+static int pam_auth(pam_handle_t *pamh, const char **error)
{
void *item;
int status;
*error = NULL;
if ((status = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
- *error = t_strdup_printf("pam_authenticate(%s) failed: %s",
- user, pam_strerror(pamh, status));
+ *error = t_strdup_printf("pam_authenticate() failed: %s",
+ pam_strerror(pamh, status));
return status;
}
#ifdef HAVE_PAM_SETCRED
if ((status = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) {
- *error = t_strdup_printf("pam_setcred(%s) failed: %s",
- user, pam_strerror(pamh, status));
+ *error = t_strdup_printf("pam_setcred() failed: %s",
+ pam_strerror(pamh, status));
return status;
}
#endif
if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS) {
- *error = t_strdup_printf("pam_acct_mgmt(%s) failed: %s",
- user, pam_strerror(pamh, status));
+ *error = t_strdup_printf("pam_acct_mgmt() failed: %s",
+ pam_strerror(pamh, status));
return status;
}
status = pam_get_item(pamh, PAM_USER, (linux_const void **)&item);
if (status != PAM_SUCCESS) {
- *error = t_strdup_printf("pam_get_item(%s) failed: %s",
- user, pam_strerror(pamh, status));
+ *error = t_strdup_printf("pam_get_item() failed: %s",
+ pam_strerror(pamh, status));
return status;
}
status = pam_start(service, user, &conv, &pamh);
if (status != PAM_SUCCESS) {
result = PASSDB_RESULT_INTERNAL_FAILURE;
- str = t_strdup_printf("pam_start(%s) failed: %s",
- user, pam_strerror(pamh, status));
+ str = t_strdup_printf("pam_start() failed: %s",
+ pam_strerror(pamh, status));
} else {
- status = pam_auth(pamh, user, &str);
+ status = pam_auth(pamh, &str);
if ((status2 = pam_end(pamh, status)) == PAM_SUCCESS) {
/* FIXME: check for PASSDB_RESULT_UNKNOWN_USER
somehow? */
PASSDB_RESULT_PASSWORD_MISMATCH;
} else {
result = PASSDB_RESULT_INTERNAL_FAILURE;
- str = t_strdup_printf("pam_end(%s) failed: %s", user,
+ str = t_strdup_printf("pam_end() failed: %s",
pam_strerror(pamh, status2));
}
}
static void pam_child_input(void *context)
{
struct pam_auth_request *request = context;
+ struct auth_request *auth_request = request->request;
enum passdb_result result;
char buf[513];
ssize_t ret;
We rely on that. */
ret = read(request->fd, buf, sizeof(buf)-1);
if (ret < 0) {
- i_error("PAM: read() from child process failed: %m");
+ i_error("pam(%s): read() from child process failed: %m",
+ get_log_prefix(auth_request));
result = PASSDB_RESULT_INTERNAL_FAILURE;
} else if (ret == 0) {
/* it died */
- i_error("PAM: Child process died");
+ i_error("pam(%s): Child process died",
+ get_log_prefix(auth_request));
result = PASSDB_RESULT_INTERNAL_FAILURE;
} else if ((size_t)ret < sizeof(result)) {
- i_error("PAM: Child process returned only %d bytes", ret);
+ i_error("pam(%s): Child process returned only %d bytes",
+ get_log_prefix(auth_request), ret);
result = PASSDB_RESULT_INTERNAL_FAILURE;
} else {
memcpy(&result, buf, sizeof(result));
/* error message included */
buf[ret] = '\0';
- if (result == PASSDB_RESULT_INTERNAL_FAILURE)
- i_error("PAM: %s", buf + sizeof(result));
- else
- i_info("PAM: %s", buf + sizeof(result));
+ if (result == PASSDB_RESULT_INTERNAL_FAILURE) {
+ i_error("pam(%s): %s",
+ get_log_prefix(auth_request),
+ buf + sizeof(result));
+ } else {
+ i_info("pam(%s): %s",
+ get_log_prefix(auth_request),
+ buf + sizeof(result));
+ }
}
}
- if (auth_request_unref(request->request))
- request->callback(result, request->request);
+ if (close(request->fd) < 0) {
+ i_error("pam(%s): close(child input) failed: %m",
+ get_log_prefix(auth_request));
+ }
+
+ if (auth_request_unref(auth_request))
+ request->callback(result, auth_request);
- if (close(request->fd) < 0)
- i_error("PAM: close(child input) failed: %m");
io_remove(request->io);
i_free(request);
}
service = service_name != NULL ? service_name : request->protocol;
if (pipe(fd) < 0) {
- i_error("PAM: pipe() failed: %m");
+ i_error("pam(%s): pipe() failed: %m", get_log_prefix(request));
callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
return;
}
pid = fork();
if (pid == -1) {
- i_error("PAM: fork() failed: %m");
+ i_error("pam(%s): fork() failed: %m", get_log_prefix(request));
callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
(void)close(fd[0]);
(void)close(fd[1]);
_exit(0);
}
- if (close(fd[1]) < 0)
- i_error("PAM: close(fd[1]) failed: %m");
+ if (close(fd[1]) < 0) {
+ i_error("pam(%s): close(fd[1]) failed: %m",
+ get_log_prefix(request));
+ }
auth_request_ref(request);
pam_auth_request = i_new(struct pam_auth_request, 1);
const char *scheme, *crypted_pass;
int ret;
- pu = db_passwd_file_lookup(passdb_pwf, request->user);
+ pu = db_passwd_file_lookup(passdb_pwf, request);
if (pu == NULL) {
callback(PASSDB_RESULT_USER_UNKNOWN, request);
return;
else {
if (ret < 0) {
i_error("passwd-file(%s): Unknown password scheme %s",
- pu->user_realm, scheme);
+ get_log_prefix(request), scheme);
} else if (verbose) {
i_info("passwd-file(%s): %s password mismatch",
- pu->user_realm, scheme);
+ get_log_prefix(request), scheme);
}
callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
}
struct passwd_user *pu;
const char *crypted_pass, *scheme;
- pu = db_passwd_file_lookup(passdb_pwf, request->user);
+ pu = db_passwd_file_lookup(passdb_pwf, request);
if (pu == NULL) {
callback(NULL, request);
return;
pw = getpwnam(request->user);
if (pw == NULL) {
- if (verbose)
- i_info("passwd(%s): unknown user", request->user);
+ if (verbose) {
+ i_info("passwd(%s): unknown user",
+ get_log_prefix(request));
+ }
callback(PASSDB_RESULT_USER_UNKNOWN, request);
return;
}
if (!IS_VALID_PASSWD(pw->pw_passwd)) {
if (verbose) {
i_info("passwd(%s): invalid password field '%s'",
- request->user, pw->pw_passwd);
+ get_log_prefix(request), pw->pw_passwd);
}
callback(PASSDB_RESULT_USER_DISABLED, request);
return;
safe_memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
if (!result) {
- if (verbose)
- i_info("passwd(%s): password mismatch", request->user);
+ if (verbose) {
+ i_info("passwd(%s): password mismatch",
+ get_log_prefix(request));
+ }
callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
return;
}
if (res != NULL) {
if (PQntuples(res) == 0) {
- if (verbose)
- i_info("pgsql(%s): Unknown user", user);
+ if (verbose) {
+ i_info("pgsql(%s): Unknown user",
+ get_log_prefix(auth_request));
+ }
} else if (PQntuples(res) > 1) {
- i_error("pgsql(%s): Multiple matches for user", user);
+ i_error("pgsql(%s): Multiple matches for user",
+ get_log_prefix(auth_request));
} else if (PQnfields(res) != 1) {
i_error("pgsql(%s): Password query returned "
- "more than one field", user);
+ "more than one field",
+ get_log_prefix(auth_request));
} else {
password = t_strdup(PQgetvalue(res, 0, 0));
}
ret = password_verify(pgsql_request->password, password,
scheme, user);
- if (ret < 0)
- i_error("pgsql(%s): Unknown password scheme %s", user, scheme);
- else if (ret == 0) {
- if (verbose)
- i_info("pgsql(%s): Password mismatch", user);
+ if (ret < 0) {
+ i_error("pgsql(%s): Unknown password scheme %s",
+ get_log_prefix(auth_request), scheme);
+ } else if (ret == 0) {
+ if (verbose) {
+ i_info("pgsql(%s): Password mismatch",
+ get_log_prefix(auth_request));
+ }
}
pgsql_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
spw = getspnam(request->user);
if (spw == NULL) {
- if (verbose)
- i_info("shadow(%s): unknown user", request->user);
+ if (verbose) {
+ i_info("shadow(%s): unknown user",
+ get_log_prefix(request));
+ }
callback(PASSDB_RESULT_USER_UNKNOWN, request);
return;
}
if (!IS_VALID_PASSWD(spw->sp_pwdp)) {
if (verbose) {
i_info("shadow(%s): invalid password field '%s'",
- request->user, spw->sp_pwdp);
+ get_log_prefix(request), spw->sp_pwdp);
}
callback(PASSDB_RESULT_USER_DISABLED, request);
return;
safe_memset(spw->sp_pwdp, 0, strlen(spw->sp_pwdp));
if (!result) {
- if (verbose)
- i_info("shadow(%s): password mismatch", request->user);
+ if (verbose) {
+ i_info("shadow(%s): password mismatch",
+ get_log_prefix(request));
+ }
callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
return;
}
((vpw->pw_gid & NO_POP) != 0 &&
strcmp(request->protocol, "POP3") == 0)) {
if (verbose) {
- i_info("vpopmail(%s@%s): %s disabled",
- vpop_user, vpop_domain, request->protocol);
+ i_info("vpopmail(%s): %s disabled",
+ get_log_prefix(request), request->protocol);
}
callback(PASSDB_RESULT_USER_DISABLED, request);
return;
if (!result) {
if (verbose) {
- i_info("vpopmail(%s@%s): password mismatch",
- vpop_user, vpop_domain);
+ i_info("vpopmail(%s): password mismatch",
+ get_log_prefix(request));
}
callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
struct user_data data;
struct passwd_user *pu;
- pu = db_passwd_file_lookup(userdb_pwf, auth_request->user);
+ pu = db_passwd_file_lookup(userdb_pwf, auth_request);
if (pu == NULL) {
callback(NULL, context);
return;
pw = getpwnam(auth_request->user);
if (pw == NULL) {
- if (verbose)
- i_info("passwd(%s): unknown user", auth_request->user);
+ if (verbose) {
+ i_info("passwd(%s): unknown user",
+ get_log_prefix(auth_request));
+ }
callback(NULL, context);
return;
}