close Warning: Failed to sync with repository "(default)": [Errno 12] Cannot allocate memory; repository information may be out of date. Look in the Trac log for more information including mitigation strategies.

source: storage_ldap.c @ aee8c19

Last change on this file since aee8c19 was a15c097, checked in by Jelmer Vernooij <jelmer@…>, at 2006-03-24T16:48:16Z

More work on LDAP backend; report errors

  • Property mode set to 100644
File size: 4.2 KB
Line 
1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* Storage backend that uses a LDAP database */
8
9/* Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org> */
10
11/*
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.
16
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.
21
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
26*/
27
28#define BITLBEE_CORE
29#include "bitlbee.h"
30#include <ldap.h>
31
32#define BB_LDAP_HOST "localhost"
33#define BB_LDAP_BASE ""
34
35static char *nick_dn(const char *nick)
36{
37        return g_strdup_printf("bitlBeeNick=%s%s%s", nick, BB_LDAP_BASE?",":"", BB_LDAP_BASE?BB_LDAP_BASE:"");
38}
39
40static storage_status_t nick_connect(const char *nick, const char *password, LDAP **ld)
41{
42        char *mydn;
43        int ret;
44        storage_status_t status;
45        *ld = ldap_init(BB_LDAP_HOST, LDAP_PORT);
46
47        if (!ld) {
48                log_message( LOGLVL_WARNING, "Unable to connect to LDAP server at %s", BB_LDAP_HOST );
49                return STORAGE_OTHER_ERROR;
50        }
51
52        mydn = nick_dn(nick);
53
54        ret = ldap_simple_bind_s(*ld, mydn, password);
55
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;
63        }
64
65        g_free(mydn);
66
67        return status;
68}
69
70static storage_status_t sldap_load ( const char *my_nick, const char* password, irc_t *irc )
71{
72        LDAPMessage *res, *msg;
73        LDAP *ld;
74        int ret, i;
75        storage_status_t status;
76        char *mydn; 
77
78        status = nick_connect(my_nick, password, &ld);
79        if (status != STORAGE_OK)
80                return status;
81
82        mydn = nick_dn(my_nick);
83
84        ret = ldap_search_s(ld, mydn, LDAP_SCOPE_BASE, "(objectClass=*)", NULL, 0, &res);
85
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;
90        }
91
92        g_free(mydn);
93
94        for (msg = ldap_first_entry(ld, res); msg; msg = ldap_next_entry(ld, msg)) {
95        }
96
97        /* FIXME: Store in irc_t */
98
99        ldap_unbind_s(ld);
100       
101        return STORAGE_OK;
102}
103
104static storage_status_t sldap_check_pass( const char *nick, const char *password )
105{
106        LDAP *ld;
107        storage_status_t status;
108
109        status = nick_connect(nick, password, &ld);
110
111        ldap_unbind_s(ld);
112
113        return status;
114}
115
116static storage_status_t sldap_remove( const char *nick, const char *password )
117{
118        storage_status_t status;
119        LDAP *ld;
120        char *mydn;
121        int ret;
122       
123        status = nick_connect(nick, password, &ld);
124
125        if (status != STORAGE_OK)
126                return status;
127
128        mydn = nick_dn(nick);
129       
130        ret = ldap_delete(ld, mydn);
131
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;
136        }
137
138        ldap_unbind_s(ld);
139
140        g_free(mydn);
141        return STORAGE_OK;
142}
143
144static storage_status_t sldap_save( irc_t *irc, int overwrite )
145{
146        LDAP *ld;
147        char *mydn;
148        storage_status_t status;
149        LDAPMessage *msg;
150
151        status = nick_connect(irc->nick, irc->password, &ld);
152        if (status != STORAGE_OK)
153                return status;
154
155        mydn = nick_dn(irc->nick);
156
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);
161
162        g_free(mydn);
163
164        ldap_unbind_s(ld);
165       
166        return STORAGE_OK;
167}
168
169
170
171storage_t storage_ldap = {
172        .name = "ldap",
173        .check_pass = sldap_check_pass,
174        .remove = sldap_remove,
175        .load = sldap_load,
176        .save = sldap_save
177};
Note: See TracBrowser for help on using the repository browser.