static void passwd_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) { struct passwd pw; int ret; auth_request_log_debug(request, "passwd", "lookup"); switch (i_getpwnam(request->user, &pw)) { case -1: auth_request_log_error(request, "passwd", "getpwnam() failed: %m"); callback(PASSDB_RESULT_INTERNAL_FAILURE, request); return; case 0: auth_request_log_unknown_user(request, "passwd"); callback(PASSDB_RESULT_USER_UNKNOWN, request); return; } if (!IS_VALID_PASSWD(pw.pw_passwd)) { auth_request_log_info(request, "passwd", "invalid password field '%s'", pw.pw_passwd); callback(PASSDB_RESULT_USER_DISABLED, request); return; } /* save the password so cache can use it */ auth_request_set_field(request, "password", pw.pw_passwd, PASSWD_PASS_SCHEME); /* check if the password is valid */ ret = auth_request_password_verify(request, password, pw.pw_passwd, PASSWD_PASS_SCHEME, "passwd"); /* clear the passwords from memory */ safe_memset(pw.pw_passwd, 0, strlen(pw.pw_passwd)); if (ret <= 0) { callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; } /* make sure we're using the username exactly as it's in the database */ auth_request_set_field(request, "user", pw.pw_name, NULL); callback(PASSDB_RESULT_OK, request); }
static enum passdb_result auth_worker_reply_parse(struct auth_request *request, const char *reply) { enum passdb_result ret; const char *const *args; args = t_strsplit_tabescaped(reply); if (strcmp(*args, "OK") == 0 && args[1] != NULL && args[2] != NULL) { /* OK \t user \t password [\t extra] */ auth_request_set_field(request, "user", args[1], NULL); auth_worker_reply_parse_args(request, args + 2); return PASSDB_RESULT_OK; } if (strcmp(*args, "NEXT") == 0 && args[1] != NULL) { /* NEXT \t user [\t extra] */ auth_request_set_field(request, "user", args[1], NULL); auth_worker_reply_parse_args(request, args + 1); return PASSDB_RESULT_NEXT; } if (strcmp(*args, "FAIL") == 0 && args[1] != NULL) { int result; /* FAIL \t result [\t user \t password [\t extra]] */ if (str_to_int(args[1], &result) < 0) { /* shouldn't happen */ } else { ret = (enum passdb_result)result; if (ret == PASSDB_RESULT_OK) { /* shouldn't happen */ } else if (args[2] == NULL) { /* internal failure most likely */ return ret; } else if (args[3] != NULL) { if (*args[2] != '\0') { auth_request_set_field(request, "user", args[2], NULL); } auth_worker_reply_parse_args(request, args + 3); return ret; } } } auth_request_log_error(request, AUTH_SUBSYS_DB, "Received invalid reply from worker: %s", reply); return PASSDB_RESULT_INTERNAL_FAILURE; }
static enum passdb_result passwd_lookup(struct auth_request *request, struct passwd *pw_r) { auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup"); switch (i_getpwnam(request->user, pw_r)) { case -1: auth_request_log_error(request, AUTH_SUBSYS_DB, "getpwnam() failed: %m"); return PASSDB_RESULT_INTERNAL_FAILURE; case 0: auth_request_log_unknown_user(request, AUTH_SUBSYS_DB); return PASSDB_RESULT_USER_UNKNOWN; } if (!IS_VALID_PASSWD(pw_r->pw_passwd)) { auth_request_log_info(request, AUTH_SUBSYS_DB, "invalid password field '%s'", pw_r->pw_passwd); return PASSDB_RESULT_USER_DISABLED; } /* save the password so cache can use it */ auth_request_set_field(request, "password", pw_r->pw_passwd, PASSWD_PASS_SCHEME); return PASSDB_RESULT_OK; }
static void passwd_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) { struct passwd pw; enum passdb_result res; int ret; res = passwd_lookup(request, &pw); if (res != PASSDB_RESULT_OK) { callback(res, request); return; } /* check if the password is valid */ ret = auth_request_password_verify(request, password, pw.pw_passwd, PASSWD_PASS_SCHEME, AUTH_SUBSYS_DB); /* clear the passwords from memory */ safe_memset(pw.pw_passwd, 0, strlen(pw.pw_passwd)); if (ret <= 0) { callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; } /* make sure we're using the username exactly as it's in the database */ auth_request_set_field(request, "user", pw.pw_name, NULL); callback(PASSDB_RESULT_OK, request); }
static void ldap_query_save_result(struct ldap_connection *conn, struct auth_request *auth_request, struct ldap_request_search *ldap_request, LDAPMessage *res) { struct db_ldap_result_iterate_context *ldap_iter; const char *name, *const *values; ldap_iter = db_ldap_result_iterate_init(conn, ldap_request, res, FALSE); while (db_ldap_result_iterate_next(ldap_iter, &name, &values)) { if (values[0] == NULL) { auth_request_set_null_field(auth_request, name); continue; } if (values[1] != NULL) { auth_request_log_warning(auth_request, AUTH_SUBSYS_DB, "Multiple values found for '%s', " "using value '%s'", name, values[0]); } auth_request_set_field(auth_request, name, values[0], conn->set.default_pass_scheme); } db_ldap_result_iterate_deinit(&ldap_iter); }
void passdb_template_export(struct passdb_template *tmpl, struct auth_request *auth_request) { const struct var_expand_table *table; string_t *str; const char *const *args, *value; unsigned int i, count; str = t_str_new(256); table = auth_request_get_var_expand_table(auth_request, NULL); args = array_get(&tmpl->args, &count); i_assert((count % 2) == 0); for (i = 0; i < count; i += 2) { if (args[i+1] == NULL) value = ""; else { str_truncate(str, 0); var_expand(str, args[i+1], table); value = str_c(str); } auth_request_set_field(auth_request, args[i], value, STATIC_PASS_SCHEME); } }
static void userdb_nss_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { struct userdb_module *_module = auth_request->userdb->userdb; struct nss_userdb_module *module = (struct nss_userdb_module *)_module; struct passwd pw; enum nss_status status; enum userdb_result result = USERDB_RESULT_INTERNAL_FAILURE; int err; auth_request_log_debug(auth_request, "nss", "lookup"); status = module->getpwnam_r(auth_request->user, &pw, module->buf, module->bufsize, &err); switch (status) { case NSS_STATUS_TRYAGAIN: auth_request_log_error(auth_request, "nss", "returned tryagain (err=%d)", err); break; case NSS_STATUS_UNAVAIL: auth_request_log_error(auth_request, "nss", "unavailable (err=%d)", err); break; case NSS_STATUS_NOTFOUND: auth_request_log_info(auth_request, "nss", "unknown user"); result = USERDB_RESULT_USER_UNKNOWN; break; case NSS_STATUS_SUCCESS: result = USERDB_RESULT_OK; break; default: auth_request_log_info(auth_request, "nss", "returned %d (err=%d)", status, err); break; } if (result != USERDB_RESULT_OK) { callback(result, auth_request); return; } auth_request_set_field(auth_request, "user", pw.pw_name, NULL); auth_request_init_userdb_reply(auth_request); auth_request_set_userdb_field(auth_request, "system_groups_user", pw.pw_name); auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid)); auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid)); auth_request_set_userdb_field(auth_request, "home", pw.pw_dir); callback(USERDB_RESULT_OK, auth_request); }
static void passwd_file_save_results(struct auth_request *request, const struct passwd_user *pu, const char **crypted_pass_r, const char **scheme_r) { const struct var_expand_table *table; const char *key, *value; string_t *str; char **p; *crypted_pass_r = pu->password != NULL ? pu->password : ""; *scheme_r = password_get_scheme(crypted_pass_r); if (*scheme_r == NULL) *scheme_r = request->passdb->passdb->default_pass_scheme; /* save the password so cache can use it */ auth_request_set_field(request, "password", *crypted_pass_r, *scheme_r); if (pu->extra_fields != NULL) { str = t_str_new(512); table = auth_request_get_var_expand_table(request, NULL); for (p = pu->extra_fields; *p != NULL; p++) { value = strchr(*p, '='); if (value != NULL) { key = t_strdup_until(*p, value); str_truncate(str, 0); auth_request_var_expand_with_table(str, value + 1, request, table, NULL); value = str_c(str); } else { key = *p; value = ""; } auth_request_set_field(request, key, value, NULL); } } }
static void ldap_query_save_result(struct ldap_connection *conn, LDAPMessage *entry, struct auth_request *auth_request) { struct db_ldap_result_iterate_context *ldap_iter; const char *name, *value; ldap_iter = db_ldap_result_iterate_init(conn, entry, auth_request, conn->pass_attr_map); while (db_ldap_result_iterate_next(ldap_iter, &name, &value)) { auth_request_set_field(auth_request, name, value, conn->set.default_pass_scheme); } }
static void passwd_lookup_credentials(struct auth_request *request, lookup_credentials_callback_t *callback) { struct passwd pw; enum passdb_result res; res = passwd_lookup(request, &pw); if (res != PASSDB_RESULT_OK) { callback(res, NULL, 0, request); return; } /* make sure we're using the username exactly as it's in the database */ auth_request_set_field(request, "user", pw.pw_name, NULL); passdb_handle_credentials(PASSDB_RESULT_OK, pw.pw_passwd, PASSWD_PASS_SCHEME, callback, request); }
static enum passdb_result static_save_fields(struct auth_request *request, const char **password_r, const char **scheme_r) { struct static_passdb_module *module = (struct static_passdb_module *)request->passdb->passdb; const char *error; *password_r = NULL; *scheme_r = NULL; auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup"); if (passdb_template_export(module->tmpl, request, &error) < 0) { auth_request_log_error(request, AUTH_SUBSYS_DB, "Failed to expand template: %s", error); return PASSDB_RESULT_INTERNAL_FAILURE; } if (module->static_password_tmpl != NULL) { if (t_auth_request_var_expand(module->static_password_tmpl, request, NULL, password_r, &error) <= 0) { auth_request_log_error(request, AUTH_SUBSYS_DB, "Failed to expand password=%s: %s", module->static_password_tmpl, error); return PASSDB_RESULT_INTERNAL_FAILURE; } } else if (auth_fields_exists(request->extra_fields, "nopassword")) { *password_r = ""; } else { auth_request_log_info(request, AUTH_SUBSYS_DB, "No password returned (and no nopassword)"); return PASSDB_RESULT_PASSWORD_MISMATCH; } *scheme_r = password_get_scheme(password_r); if (*scheme_r == NULL) *scheme_r = STATIC_PASS_SCHEME; auth_request_set_field(request, "password", *password_r, *scheme_r); return PASSDB_RESULT_OK; }
static int dict_query_save_results(struct auth_request *auth_request, struct dict_connection *conn, struct db_dict_value_iter *iter) { const char *key, *value, *error; while (db_dict_value_iter_next(iter, &key, &value)) { if (value != NULL) { auth_request_set_field(auth_request, key, value, conn->set.default_pass_scheme); } } if (db_dict_value_iter_deinit(&iter, &error) < 0) { auth_request_log_error(auth_request, AUTH_SUBSYS_DB, "%s", error); return -1; } return 0; }
static void passwd_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { struct userdb_module *_module = auth_request->userdb->userdb; struct passwd_userdb_module *module = (struct passwd_userdb_module *)_module; struct passwd pw; struct timeval start_tv; int ret; auth_request_log_debug(auth_request, "passwd", "lookup"); if (gettimeofday(&start_tv, NULL) < 0) start_tv.tv_sec = 0; ret = i_getpwnam(auth_request->user, &pw); if (start_tv.tv_sec != 0) passwd_check_warnings(auth_request, module, &start_tv); switch (ret) { case -1: auth_request_log_error(auth_request, "passwd", "getpwnam() failed: %m"); callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request); return; case 0: auth_request_log_info(auth_request, "passwd", "unknown user"); callback(USERDB_RESULT_USER_UNKNOWN, auth_request); return; } auth_request_set_field(auth_request, "user", pw.pw_name, NULL); auth_request_init_userdb_reply(auth_request); auth_request_set_userdb_field(auth_request, "system_groups_user", pw.pw_name); auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid)); auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid)); auth_request_set_userdb_field(auth_request, "home", pw.pw_dir); userdb_template_export(module->tmpl, auth_request); callback(USERDB_RESULT_OK, auth_request); }
static void bsdauth_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) { struct passwd pw; const char *type; int result; auth_request_log_debug(request, "bsdauth", "lookup"); switch (i_getpwnam(request->user, &pw)) { case -1: auth_request_log_error(request, "bsdauth", "getpwnam() failed: %m"); callback(PASSDB_RESULT_INTERNAL_FAILURE, request); return; case 0: auth_request_log_unknown_user(request, "bsdauth"); callback(PASSDB_RESULT_USER_UNKNOWN, request); return; } /* check if the password is valid */ type = t_strdup_printf("auth-%s", request->service); result = auth_userokay(request->user, NULL, t_strdup_noconst(type), t_strdup_noconst(password)); /* clear the passwords from memory */ safe_memset(pw.pw_passwd, 0, strlen(pw.pw_passwd)); if (result == 0) { auth_request_log_password_mismatch(request, "bsdauth"); callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; } /* make sure we're using the username exactly as it's in the database */ auth_request_set_field(request, "user", pw.pw_name, NULL); callback(PASSDB_RESULT_OK, request); }
static void auth_checkpassword_callback(struct auth_request *request, enum db_checkpassword_status status, const char *const *extra_fields, verify_plain_callback_t *callback) { const char *scheme, *crypted_pass = NULL; unsigned int i; switch (status) { case DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE: callback(PASSDB_RESULT_INTERNAL_FAILURE, request); return; case DB_CHECKPASSWORD_STATUS_FAILURE: callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; case DB_CHECKPASSWORD_STATUS_OK: break; } for (i = 0; extra_fields[i] != NULL; i++) { if (strncmp(extra_fields[i], "password="******"password", crypted_pass, scheme); } else { auth_request_log_error(request, AUTH_SUBSYS_DB, "password field returned without {scheme} prefix"); } } callback(PASSDB_RESULT_OK, request); }
static int dict_query_save_results(struct auth_request *auth_request, struct dict_connection *conn, const char *result) { struct db_dict_value_iter *iter; const char *key, *value, *error; iter = db_dict_value_iter_init(conn, result); while (db_dict_value_iter_next(iter, &key, &value)) { if (value != NULL) { auth_request_set_field(auth_request, key, value, conn->set.default_pass_scheme); } } if (db_dict_value_iter_deinit(&iter, &error) < 0) { auth_request_log_error(auth_request, "dict", "Value '%s' not in valid %s format: %s", result, conn->set.value_format, error); return -1; } return 0; }
static void sql_query_save_results(struct sql_result *result, struct passdb_sql_request *sql_request) { struct auth_request *auth_request = sql_request->auth_request; struct passdb_module *_module = auth_request->passdb->passdb; struct sql_passdb_module *module = (struct sql_passdb_module *)_module; unsigned int i, fields_count; const char *name, *value; fields_count = sql_result_get_fields_count(result); for (i = 0; i < fields_count; i++) { name = sql_result_get_field_name(result, i); value = sql_result_get_field_value(result, i); if (*name == '\0') ; else if (value == NULL) auth_request_set_null_field(auth_request, name); else { auth_request_set_field(auth_request, name, value, module->conn->set.default_pass_scheme); } } }