Mercurial > dovecot > original-hg > dovecot-1.2
view src/auth/userdb-ldap.c @ 3502:5e78500f1aee HEAD
user_global_uid and user_global_gid settings weren't working. Also changed
them to now allow named user/group.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 22 Jul 2005 14:32:57 +0300 |
parents | 9096b7957413 |
children | e2fe8222449d |
line wrap: on
line source
/* Copyright (C) 2003 Timo Sirainen */ #include "common.h" #ifdef USERDB_LDAP #include "hash.h" #include "str.h" #include "var-expand.h" #include "db-ldap.h" #include "userdb.h" #include <ldap.h> #include <stdlib.h> static const char *default_attr_map[] = { "", "home", "mail", "system_user", "uid", "gid", NULL }; struct userdb_ldap_request { struct ldap_request request; struct auth_request *auth_request; userdb_callback_t *userdb_callback; }; static struct ldap_connection *userdb_ldap_conn; static int append_uid_list(struct auth_request *auth_request, string_t *str, 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)); } return TRUE; } static int append_gid_list(struct auth_request *auth_request, string_t *str, 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)); } return TRUE; } static const char * ldap_query_get_result(struct ldap_connection *conn, LDAPMessage *entry, struct auth_request *auth_request) { string_t *str; 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); attr = ldap_first_attribute(conn->ld, entry, &ber); while (attr != NULL) { name = hash_lookup(userdb_ldap_conn->user_attr_map, attr); vals = ldap_get_values(conn->ld, entry, attr); if (name != NULL && vals != NULL && vals[0] != NULL) { if (strcmp(name, "uid") == 0) { if (!append_uid_list(auth_request, str, name, vals)) return NULL; seen_uid = TRUE; } else if (strcmp(name, "gid") == 0) { if (!append_gid_list(auth_request, str, 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]); } } } ldap_value_free(vals); ldap_memfree(attr); attr = ldap_next_attribute(conn->ld, entry, ber); } 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"); } str_append(str, "\tuid="); str_append(str, 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"); } str_append(str, "\tgid="); str_append(str, dec2str(conn->set.gid)); } return str_c(str); } static void handle_request(struct ldap_connection *conn, struct ldap_request *request, LDAPMessage *res) { struct userdb_ldap_request *urequest = (struct userdb_ldap_request *) request; struct auth_request *auth_request = urequest->auth_request; LDAPMessage *entry; const char *result; int ret; ret = ldap_result2error(conn->ld, res, 0); if (ret != LDAP_SUCCESS) { auth_request_log_error(auth_request, "ldap", "ldap_search() failed: %s", ldap_err2string(ret)); urequest->userdb_callback(NULL, auth_request); return; } entry = res == NULL ? NULL : ldap_first_entry(conn->ld, res); if (entry == NULL) { if (res != NULL) { auth_request_log_error(auth_request, "ldap", "Authenticated user not found"); } result = NULL; } else { result = 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; } } urequest->userdb_callback(result, auth_request); } static void userdb_ldap_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { struct ldap_connection *conn = userdb_ldap_conn; const struct var_expand_table *vars; const char **attr_names = (const char **)userdb_ldap_conn->user_attr_names; struct userdb_ldap_request *request; const char *filter, *base; string_t *str; vars = auth_request_get_var_expand_table(auth_request, ldap_escape); str = t_str_new(512); var_expand(str, conn->set.base, vars); base = t_strdup(str_c(str)); str_truncate(str, 0); var_expand(str, conn->set.user_filter, vars); filter = str_c(str); request = p_new(auth_request->pool, struct userdb_ldap_request, 1); request->request.callback = handle_request; request->auth_request = auth_request; request->userdb_callback = callback; auth_request_log_debug(auth_request, "ldap", "base=%s scope=%s filter=%s fields=%s", base, conn->set.scope, filter, t_strarray_join(attr_names, ",")); db_ldap_search(conn, base, conn->set.ldap_scope, filter, userdb_ldap_conn->user_attr_names, &request->request); } static void userdb_ldap_preinit(const char *args) { userdb_ldap_conn = db_ldap_init(args); userdb_ldap_conn->user_attr_map = hash_create(default_pool, userdb_ldap_conn->pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); db_ldap_set_attrs(userdb_ldap_conn, userdb_ldap_conn->set.user_attrs, &userdb_ldap_conn->user_attr_names, userdb_ldap_conn->user_attr_map, default_attr_map); } static void userdb_ldap_init(const char *args __attr_unused__) { (void)db_ldap_connect(userdb_ldap_conn); } static void userdb_ldap_deinit(void) { db_ldap_unref(userdb_ldap_conn); } struct userdb_module userdb_ldap = { "ldap", FALSE, userdb_ldap_preinit, userdb_ldap_init, userdb_ldap_deinit, userdb_ldap_lookup }; #endif