1 #define BITLBEE_CORE
2 #define LDAP_DEPRECATED 1
3 #include "bitlbee.h"
4 #include <ldap.h>
5
ldap_check_pass(const char * nick,const char * password)6 static storage_status_t ldap_check_pass(const char *nick, const char *password)
7 {
8 LDAP *ldap;
9 LDAPMessage *msg, *entry;
10 char *dn = NULL;
11 char *filter;
12 char *attrs[1] = { NULL };
13 int ret, count;
14
15 if((ret = ldap_initialize(&ldap, NULL)) != LDAP_SUCCESS) {
16 log_message(LOGLVL_WARNING, "ldap_initialize failed: %s", ldap_err2string(ret));
17 return STORAGE_OTHER_ERROR;
18 }
19
20 /* First we do an anonymous bind to map uid=$nick to a DN*/
21 if((ret = ldap_simple_bind_s(ldap, NULL, NULL)) != LDAP_SUCCESS) {
22 ldap_unbind_s(ldap);
23 log_message(LOGLVL_WARNING, "Anonymous bind failed: %s", ldap_err2string(ret));
24 return STORAGE_OTHER_ERROR;
25 }
26
27
28 /* We search and process the result */
29 filter = g_strdup_printf("(uid=%s)", nick);
30 ret = ldap_search_ext_s(ldap, NULL, LDAP_SCOPE_SUBTREE, filter, attrs, 0, NULL, NULL, NULL, 1, &msg);
31 g_free(filter);
32
33 if(ret != LDAP_SUCCESS) {
34 ldap_unbind_s(ldap);
35 log_message(LOGLVL_WARNING, "uid search failed: %s", ldap_err2string(ret));
36 return STORAGE_OTHER_ERROR;
37 }
38
39 count = ldap_count_entries(ldap, msg);
40 if (count == -1) {
41 ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ret);
42 ldap_msgfree(msg);
43 ldap_unbind_s(ldap);
44 log_message(LOGLVL_WARNING, "uid search failed: %s", ldap_err2string(ret));
45 return STORAGE_OTHER_ERROR;
46 }
47
48 if (!count) {
49 ldap_msgfree(msg);
50 ldap_unbind_s(ldap);
51 return STORAGE_NO_SUCH_USER;
52 }
53
54 entry = ldap_first_entry(ldap, msg);
55 dn = ldap_get_dn(ldap, entry);
56 ldap_msgfree(msg);
57
58 /* And now we bind as the user to authenticate */
59 ret = ldap_simple_bind_s(ldap, dn, password);
60 g_free(dn);
61 ldap_unbind_s(ldap);
62
63 switch (ret) {
64 case LDAP_SUCCESS:
65 return STORAGE_OK;
66 case LDAP_INVALID_CREDENTIALS:
67 return STORAGE_INVALID_PASSWORD;
68 default:
69 log_message(LOGLVL_WARNING, "Authenticated bind failed: %s", ldap_err2string(ret));
70 return STORAGE_OTHER_ERROR;
71 }
72 }
73
74 auth_backend_t auth_ldap = {
75 .name = "ldap",
76 .check_pass = ldap_check_pass,
77 };
78