1 /********************************************************************\
2 * BitlBee -- An IRC to other IM-networks gateway *
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
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
)
44 storage_status_t status
;
45 *ld
= ldap_init(BB_LDAP_HOST
, LDAP_PORT
);
48 log_message( LOGLVL_WARNING
, "Unable to connect to LDAP server at %s", BB_LDAP_HOST
);
49 return STORAGE_OTHER_ERROR
;
54 ret
= ldap_simple_bind_s(*ld
, mydn
, password
);
57 case LDAP_SUCCESS
: status
= STORAGE_OK
; break;
58 case LDAP_INVALID_CREDENTIALS
: status
= STORAGE_INVALID_PASSWORD
; break;
60 log_message( LOGLVL_WARNING
, "Unable to authenticate %s: %s", mydn
, ldap_err2string(ret
) );
61 status
= STORAGE_OTHER_ERROR
;
70 static storage_status_t
sldap_load ( const char *my_nick
, const char* password
, irc_t
*irc
)
72 LDAPMessage
*res
, *msg
;
75 storage_status_t status
;
78 status
= nick_connect(my_nick
, password
, &ld
);
79 if (status
!= STORAGE_OK
)
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
) );
89 return STORAGE_OTHER_ERROR
;
94 for (msg
= ldap_first_entry(ld
, res
); msg
; msg
= ldap_next_entry(ld
, msg
)) {
97 /* FIXME: Store in irc_t */
104 static storage_status_t
sldap_check_pass( const char *nick
, const char *password
)
107 storage_status_t status
;
109 status
= nick_connect(nick
, password
, &ld
);
116 static storage_status_t
sldap_remove( const char *nick
, const char *password
)
118 storage_status_t status
;
123 status
= nick_connect(nick
, password
, &ld
);
125 if (status
!= STORAGE_OK
)
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
) );
135 return STORAGE_OTHER_ERROR
;
144 static storage_status_t
sldap_save( irc_t
*irc
, int overwrite
)
148 storage_status_t status
;
151 status
= nick_connect(irc
->nick
, irc
->password
, &ld
);
152 if (status
!= STORAGE_OK
)
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 ? */
160 sldap_remove(irc
->nick
, irc
->password
);
171 storage_t storage_ldap
= {
173 .check_pass
= sldap_check_pass
,
174 .remove
= sldap_remove
,