File: auth_ldap.c

package info (click to toggle)
bitlbee 3.5.1-1.3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 3,228 kB
  • sloc: ansic: 41,803; xml: 2,348; sh: 888; python: 778; makefile: 522; perl: 41
file content (77 lines) | stat: -rw-r--r-- 2,035 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#define BITLBEE_CORE
#define LDAP_DEPRECATED 1
#include "bitlbee.h"
#include <ldap.h>

static storage_status_t ldap_check_pass(const char *nick, const char *password)
{
	LDAP *ldap;
	LDAPMessage *msg, *entry;
	char *dn = NULL;
	char *filter;
	char *attrs[1] = { NULL };
	int ret, count;

	if((ret = ldap_initialize(&ldap, NULL)) != LDAP_SUCCESS) {
		log_message(LOGLVL_WARNING, "ldap_initialize failed: %s", ldap_err2string(ret));
		return STORAGE_OTHER_ERROR;
	}

	/* First we do an anonymous bind to map uid=$nick to a DN*/
	if((ret = ldap_simple_bind_s(ldap, NULL, NULL)) != LDAP_SUCCESS) {
		ldap_unbind_s(ldap);
		log_message(LOGLVL_WARNING, "Anonymous bind failed: %s", ldap_err2string(ret));
		return STORAGE_OTHER_ERROR;
	}


	/* We search and process the result */
	filter = g_strdup_printf("(uid=%s)", nick);
	ret = ldap_search_ext_s(ldap, NULL, LDAP_SCOPE_SUBTREE, filter, attrs, 0, NULL, NULL, NULL, 1, &msg);
	g_free(filter);

	if(ret != LDAP_SUCCESS) {
		ldap_unbind_s(ldap);
		log_message(LOGLVL_WARNING, "uid search failed: %s", ldap_err2string(ret));
		return STORAGE_OTHER_ERROR;
	}

	count = ldap_count_entries(ldap, msg);
	if (count == -1) {
		ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ret);
		ldap_msgfree(msg);
		ldap_unbind_s(ldap);
		log_message(LOGLVL_WARNING, "uid search failed: %s", ldap_err2string(ret));
		return STORAGE_OTHER_ERROR;
	}

	if (!count) {
		ldap_msgfree(msg);
		ldap_unbind_s(ldap);
		return STORAGE_NO_SUCH_USER;
	}

	entry = ldap_first_entry(ldap, msg);
	dn = ldap_get_dn(ldap, entry);
	ldap_msgfree(msg);

	/* And now we bind as the user to authenticate */
	ret = ldap_simple_bind_s(ldap, dn, password);
	g_free(dn);
	ldap_unbind_s(ldap);

	switch (ret) {
		case LDAP_SUCCESS:
			return STORAGE_OK;
		case LDAP_INVALID_CREDENTIALS:
			return STORAGE_INVALID_PASSWORD;
		default:
			log_message(LOGLVL_WARNING, "Authenticated bind failed: %s", ldap_err2string(ret));
			return STORAGE_OTHER_ERROR;
	}
}

auth_backend_t auth_ldap = {
	.name = "ldap",
	.check_pass = ldap_check_pass,
};