Update .bzrignore.
[bitlbee.git] / storage_ldap.c
blob4bc99de5b90cdc084b1c883e406cf4e36dec59e2
1 /********************************************************************\
2 * BitlBee -- An IRC to other IM-networks gateway *
3 * *
4 * Copyright 2002-2004 Wilmer van der Gaast and others *
5 \********************************************************************/
7 /* Storage backend that uses a LDAP database */
9 /* Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org> */
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License with
23 the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
24 if not, write to the Free Software Foundation, Inc., 59 Temple Place,
25 Suite 330, Boston, MA 02111-1307 USA
28 #define BITLBEE_CORE
29 #include "bitlbee.h"
30 #include <ldap.h>
32 #define BB_LDAP_HOST "localhost"
33 #define BB_LDAP_BASE ""
35 static char *nick_dn(const char *nick)
37 return g_strdup_printf("bitlBeeNick=%s%s%s", nick, BB_LDAP_BASE?",":"", BB_LDAP_BASE?BB_LDAP_BASE:"");
40 static storage_status_t nick_connect(const char *nick, const char *password, LDAP **ld)
42 char *mydn;
43 int ret;
44 storage_status_t status;
45 *ld = ldap_init(BB_LDAP_HOST, LDAP_PORT);
47 if (!ld) {
48 log_message( LOGLVL_WARNING, "Unable to connect to LDAP server at %s", BB_LDAP_HOST );
49 return STORAGE_OTHER_ERROR;
52 mydn = nick_dn(nick);
54 ret = ldap_simple_bind_s(*ld, mydn, password);
56 switch (ret) {
57 case LDAP_SUCCESS: status = STORAGE_OK; break;
58 case LDAP_INVALID_CREDENTIALS: status = STORAGE_INVALID_PASSWORD; break;
59 default:
60 log_message( LOGLVL_WARNING, "Unable to authenticate %s: %s", mydn, ldap_err2string(ret) );
61 status = STORAGE_OTHER_ERROR;
62 break;
65 g_free(mydn);
67 return status;
70 static storage_status_t sldap_load ( const char *my_nick, const char* password, irc_t *irc )
72 LDAPMessage *res, *msg;
73 LDAP *ld;
74 int ret, i;
75 storage_status_t status;
76 char *mydn;
78 status = nick_connect(my_nick, password, &ld);
79 if (status != STORAGE_OK)
80 return status;
82 mydn = nick_dn(my_nick);
84 ret = ldap_search_s(ld, mydn, LDAP_SCOPE_BASE, "(objectClass=*)", NULL, 0, &res);
86 if (ret != LDAP_SUCCESS) {
87 log_message( LOGLVL_WARNING, "Unable to search for %s: %s", mydn, ldap_err2string(ret) );
88 ldap_unbind_s(ld);
89 return STORAGE_OTHER_ERROR;
92 g_free(mydn);
94 for (msg = ldap_first_entry(ld, res); msg; msg = ldap_next_entry(ld, msg)) {
97 /* FIXME: Store in irc_t */
99 ldap_unbind_s(ld);
101 return STORAGE_OK;
104 static storage_status_t sldap_check_pass( const char *nick, const char *password )
106 LDAP *ld;
107 storage_status_t status;
109 status = nick_connect(nick, password, &ld);
111 ldap_unbind_s(ld);
113 return status;
116 static storage_status_t sldap_remove( const char *nick, const char *password )
118 storage_status_t status;
119 LDAP *ld;
120 char *mydn;
121 int ret;
123 status = nick_connect(nick, password, &ld);
125 if (status != STORAGE_OK)
126 return status;
128 mydn = nick_dn(nick);
130 ret = ldap_delete(ld, mydn);
132 if (ret != LDAP_SUCCESS) {
133 log_message( LOGLVL_WARNING, "Error removing %s: %s", mydn, ldap_err2string(ret) );
134 ldap_unbind_s(ld);
135 return STORAGE_OTHER_ERROR;
138 ldap_unbind_s(ld);
140 g_free(mydn);
141 return STORAGE_OK;
144 static storage_status_t sldap_save( irc_t *irc, int overwrite )
146 LDAP *ld;
147 char *mydn;
148 storage_status_t status;
149 LDAPMessage *msg;
151 status = nick_connect(irc->nick, irc->password, &ld);
152 if (status != STORAGE_OK)
153 return status;
155 mydn = nick_dn(irc->nick);
157 /* FIXME: Make this a bit more atomic? What if we crash after
158 * removing the old account but before adding the new one ? */
159 if (overwrite)
160 sldap_remove(irc->nick, irc->password);
162 g_free(mydn);
164 ldap_unbind_s(ld);
166 return STORAGE_OK;
171 storage_t storage_ldap = {
172 .name = "ldap",
173 .check_pass = sldap_check_pass,
174 .remove = sldap_remove,
175 .load = sldap_load,
176 .save = sldap_save