db-ldap.c revision 473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen/* Copyright (C) 2003 Timo Sirainen */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen#if defined(PASSDB_LDAP) || defined(USERDB_LDAP)
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen/* Older versions may require calling ldap_result() twice */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen { type, #name, offsetof(struct ldap_settings, name) }
c4457e497e01b57565d24da624968699b166e02aTimo Sirainenstatic struct ldap_connection *ldap_connections = NULL;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic int ldap_conn_open(struct ldap_connection *conn);
985375eafa124c948eee326eb6bfbe2b268514b5Timo Sirainenstatic void ldap_conn_close(struct ldap_connection *conn);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen i_fatal("LDAP: Unknown deref option '%s'", str);
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen i_fatal("LDAP: Unknown scope option '%s'", str);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic const char *get_ldap_error(struct ldap_connection *conn)
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen ret = ldap_get_option(conn->ld, LDAP_OPT_ERROR_NUMBER, (void *) &err);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenvoid db_ldap_search(struct ldap_connection *conn, const char *base, int scope,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen msgid = ldap_search(conn->ld, base, scope, filter, attributes, 0);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen i_error("LDAP: ldap_search() failed (filter %s): %s",
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen hash_insert(conn->requests, POINTER_CAST(msgid), request);
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen ret = ldap_result(conn->ld, LDAP_RES_ANY, 1, &timeout, &res);
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen /* try again, there may be another in buffer */
985375eafa124c948eee326eb6bfbe2b268514b5Timo Sirainen /* reconnect */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic int ldap_conn_open(struct ldap_connection *conn)
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen conn->ld = ldap_init(conn->set.hosts, LDAP_PORT);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen i_fatal("LDAP: ldap_init() failed with hosts: %s",
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen ret = ldap_set_option(conn->ld, LDAP_OPT_DEREF,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* NOTE: we use blocking connect, we couldn't do anything anyway
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen until it's done. */
7d6389e4053c2dac1fb37180b5756b00785983dcTimo Sirainen ret = ldap_simple_bind_s(conn->ld, conn->set.dn, conn->set.dnpass);
985375eafa124c948eee326eb6bfbe2b268514b5Timo Sirainen i_error("LDAP: ldap_simple_bind_s() failed: %s",
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* register LDAP input to ioloop */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen ret = ldap_get_option(conn->ld, LDAP_OPT_DESC, (void *) &fd);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen conn->io = io_add(fd, IO_READ, ldap_input, conn);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic void ldap_conn_close(struct ldap_connection *conn)
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenvoid db_ldap_set_attrs(struct ldap_connection *conn, const char *value,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen const char *const *attr;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* +1 for terminating NULL */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen *attrs = p_new(conn->pool, unsigned int, size);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen *attr_names = p_new(conn->pool, char *, size + 1);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen for (i = 0, dest = 0; *attr != NULL; i++, attr++) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen (*attr_names)[dest] = p_strdup(conn->pool, *attr);
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen const char *p;
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen if (*p == '\0')
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen for (; *p != '\0'; p++) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic const char *parse_setting(const char *key, const char *value,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen return parse_setting_from_defs(conn->pool, setting_defs,
c4457e497e01b57565d24da624968699b166e02aTimo Sirainenstatic struct ldap_connection *ldap_conn_find(const char *config_path)
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen for (conn = ldap_connections; conn != NULL; conn = conn->next) {
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen if (strcmp(conn->config_path, config_path) == 0)
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstruct ldap_connection *db_ldap_init(const char *config_path)
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen /* see if it already exists */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen pool = pool_alloconly_create("ldap_connection", 1024);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen conn = p_new(pool, struct ldap_connection, 1);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen conn->requests = hash_create(default_pool, pool, 0, NULL, NULL);
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen conn->config_path = p_strdup(pool, config_path);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen settings_read(config_path, parse_setting, conn);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen conn->set.ldap_deref = deref2str(conn->set.deref);
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen conn->set.ldap_scope = scope2str(conn->set.scope);