db-ldap.h revision b6df44e31bf9d54669b5903dfb5dd3fbbe896acc
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen#ifndef DB_LDAP_H
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen#define DB_LDAP_H
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen
0536ccb51d41e3078c3a9fa33e509fb4b2420f95Timo Sirainen/* Functions like ldap_bind() have been deprecated in OpenLDAP 2.3
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen This define enables them until the code here can be refactored */
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen#define LDAP_DEPRECATED 1
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen/* Maximum number of pending requests before delaying new requests. */
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen#define DB_LDAP_MAX_PENDING_REQUESTS 8
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen/* If LDAP connection is down, fail requests after waiting for this long. */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen#define DB_LDAP_REQUEST_DISCONNECT_TIMEOUT_SECS 4
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen/* If request is still in queue after this many seconds and other requests
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen have been replied, assume the request was lost and abort it. */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen#define DB_LDAP_REQUEST_LOST_TIMEOUT_SECS 60
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen/* If server disconnects us, don't reconnect if no requests have been sent
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen for this many seconds. */
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen#define DB_LDAP_IDLE_RECONNECT_SECS 60
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen#include <ldap.h>
3785910c303507db5f629684e6dde2cc7f83668eTimo Sirainen
42dbeeb3462895b03e7633dbc59e8e191199734bTimo Sirainenstruct auth_request;
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainenstruct ldap_connection;
e815af0640b38444b31eadfaa1673bcb422e1573Timo Sirainenstruct ldap_request;
e815af0640b38444b31eadfaa1673bcb422e1573Timo Sirainen
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainentypedef void db_search_callback_t(struct ldap_connection *conn,
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen struct ldap_request *request,
e815af0640b38444b31eadfaa1673bcb422e1573Timo Sirainen LDAPMessage *res);
e815af0640b38444b31eadfaa1673bcb422e1573Timo Sirainen
3785910c303507db5f629684e6dde2cc7f83668eTimo Sirainenstruct ldap_settings {
1a266561b099269bef75eee1a3742e61130ef780Timo Sirainen const char *hosts;
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen const char *uris;
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen const char *dn;
dd2df6a67f10792ce31a3666197c0b6885893a3aTimo Sirainen const char *dnpass;
14175321ddb88619015866978c05a27786ca4814Timo Sirainen bool auth_bind;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen const char *auth_bind_userdn;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen bool tls;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen bool sasl_bind;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen const char *sasl_mech;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen const char *sasl_realm;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *sasl_authz_id;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *tls_ca_cert_file;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen const char *tls_ca_cert_dir;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen const char *tls_cert_file;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen const char *tls_key_file;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen const char *tls_cipher_suite;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen const char *tls_require_cert;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *deref;
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen const char *scope;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen const char *base;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen unsigned int ldap_version;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *ldaprc_path;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *debug_level;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen const char *user_attrs;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *user_filter;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *pass_attrs;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *pass_filter;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *iterate_attrs;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *iterate_filter;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *default_pass_scheme;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen bool userdb_warning_disable; /* deprecated for now at least */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* ... */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen int ldap_deref, ldap_scope;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen uid_t uid;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen gid_t gid;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen};
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainenenum ldap_request_type {
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen LDAP_REQUEST_TYPE_SEARCH,
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen LDAP_REQUEST_TYPE_BIND
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen};
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainenstruct ldap_field {
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* Dovecot field name. */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *name;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* Field value template with %vars. NULL = same as LDAP value. */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *value;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* LDAP attribute name, or "" if this is a static field. */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *ldap_attr_name;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* LDAP value contains a DN, which is looked up and used for @name
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen attributes. */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen bool value_is_dn;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* This attribute is used internally only via %{ldap_ptr},
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen it shouldn't be returned in iteration. */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen bool skip;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen};
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo SirainenARRAY_DEFINE_TYPE(ldap_field, struct ldap_field);
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
d4fe93a9c242d745e0cf2e6cc58d5caf265de2a0Timo Sirainenstruct ldap_request {
d4fe93a9c242d745e0cf2e6cc58d5caf265de2a0Timo Sirainen enum ldap_request_type type;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
d4fe93a9c242d745e0cf2e6cc58d5caf265de2a0Timo Sirainen /* msgid for sent requests, -1 if not sent */
d4fe93a9c242d745e0cf2e6cc58d5caf265de2a0Timo Sirainen int msgid;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* timestamp when request was created */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen time_t create_time;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen db_search_callback_t *callback;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen struct auth_request *auth_request;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen};
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainenstruct ldap_request_named_result {
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen const struct ldap_field *field;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *dn;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen LDAPMessage *result;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen};
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainenstruct ldap_request_search {
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen struct ldap_request request;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen const char *base;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen const char *filter;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen char **attributes; /* points to pass_attr_names / user_attr_names */
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen const ARRAY_TYPE(ldap_field) *attr_map;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen LDAPMessage *result;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen ARRAY(struct ldap_request_named_result) named_results;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen unsigned int name_idx;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen bool multi_entry;
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen};
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainenstruct ldap_request_bind {
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen struct ldap_request request;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen const char *dn;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen};
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen
4d6c99647852146fec4f2663767b17593ef73a47Timo Sirainenenum ldap_connection_state {
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen /* Not connected */
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen LDAP_CONN_STATE_DISCONNECTED,
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen /* Binding - either to default dn or doing auth bind */
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen LDAP_CONN_STATE_BINDING,
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen /* Bound to auth dn */
4d6c99647852146fec4f2663767b17593ef73a47Timo Sirainen LDAP_CONN_STATE_BOUND_AUTH,
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen /* Bound to default dn */
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen LDAP_CONN_STATE_BOUND_DEFAULT
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen};
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainenstruct ldap_connection {
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen struct ldap_connection *next;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen pool_t pool;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen int refcount;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen char *config_path;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen struct ldap_settings set;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen LDAP *ld;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen enum ldap_connection_state conn_state;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen int default_bind_msgid;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen int fd;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen struct io *io;
4d6c99647852146fec4f2663767b17593ef73a47Timo Sirainen struct timeout *to;
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen /* Request queue contains sent requests at tail (msgid != -1) and
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen queued requests at head (msgid == -1). */
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen struct aqueue *request_queue;
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen ARRAY(struct ldap_request *) request_array;
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen /* Number of messages in queue with msgid != -1 */
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen unsigned int pending_count;
5478609e31a7665ee108ded988a309673f221aa1Timo Sirainen
553667c748977991590854426255e1c34a615f24Timo Sirainen /* Timestamp when we last received a reply */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen time_t last_reply_stamp;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen
553667c748977991590854426255e1c34a615f24Timo Sirainen char **pass_attr_names, **user_attr_names, **iterate_attr_names;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen ARRAY_TYPE(ldap_field) pass_attr_map, user_attr_map, iterate_attr_map;
5478609e31a7665ee108ded988a309673f221aa1Timo Sirainen bool userdb_used;
5478609e31a7665ee108ded988a309673f221aa1Timo Sirainen};
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen/* Send/queue request */
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenvoid db_ldap_request(struct ldap_connection *conn,
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen struct ldap_request *request);
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenvoid db_ldap_set_attrs(struct ldap_connection *conn, const char *attrlist,
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen char ***attr_names_r, ARRAY_TYPE(ldap_field) *attr_map,
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen const char *skip_attr) ATTR_NULL(5);
597dba3488c648ffb375ee4a552bd52ac4346979Timo Sirainen
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainenstruct ldap_connection *db_ldap_init(const char *config_path, bool userdb);
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainenvoid db_ldap_unref(struct ldap_connection **conn);
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen
da2aa032ccfa8e7e4a4380ef738014549f4d2c2dTimo Sirainenint db_ldap_connect(struct ldap_connection *conn);
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen
bf3fb941cc1deb06786449b89c77d9a56a07c251Timo Sirainenvoid db_ldap_enable_input(struct ldap_connection *conn, bool enable);
9511a40d933181045343110c8101b75887062aaeTimo Sirainen
9511a40d933181045343110c8101b75887062aaeTimo Sirainenconst char *ldap_escape(const char *str,
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen const struct auth_request *auth_request);
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenconst char *ldap_get_error(struct ldap_connection *conn);
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenstruct db_ldap_result_iterate_context *
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainendb_ldap_result_iterate_init(struct ldap_connection *conn,
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen struct ldap_request_search *ldap_request,
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen LDAPMessage *res);
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenbool db_ldap_result_iterate_next(struct db_ldap_result_iterate_context *ctx,
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen const char **name_r,
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen const char *const **values_r);
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenvoid db_ldap_result_iterate_deinit(struct db_ldap_result_iterate_context **ctx);
#endif