]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldap/bind.c
921bbe0cdce751de0d66a2ebfae3c6eff33ee000
[openldap] / servers / slapd / back-ldap / bind.c
1 /* bind.c - ldap backend bind function */
2 /* $OpenLDAP$ */
3
4 /*
5  * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
6  * 
7  * Permission is granted to anyone to use this software for any purpose
8  * on any computer system, and to alter it and redistribute it, subject
9  * to the following restrictions:
10  * 
11  * 1. The author is not responsible for the consequences of use of this
12  *    software, no matter how awful, even if they arise from flaws in it.
13  * 
14  * 2. The origin of this software must not be misrepresented, either by
15  *    explicit claim or by omission.  Since few users ever read sources,
16  *    credits should appear in the documentation.
17  * 
18  * 3. Altered versions must be plainly marked as such, and must not be
19  *    misrepresented as being the original software.  Since few users
20  *    ever read sources, credits should appear in the documentation.
21  * 
22  * 4. This notice may not be removed or altered.
23  */
24
25 #include "portable.h"
26
27 #include <stdio.h>
28
29 #include <ac/socket.h>
30 #include <ac/string.h>
31
32 #include "slap.h"
33 #include "back-ldap.h"
34
35 int
36 ldap_back_bind(
37     Backend             *be,
38     Connection          *conn,
39     Operation           *op,
40     const char          *dn,
41     const char          *ndn,
42     int                 method,
43     struct berval       *cred,
44         char            **edn
45 )
46 {
47         struct ldapinfo *li = (struct ldapinfo *) be->be_private;
48         struct ldapconn *lc;
49
50         *edn = NULL;
51
52         lc = ldap_back_getconn(li, conn, op);
53         if (!lc)
54                 return( -1 );
55
56         if (ldap_bind_s(lc->ld, dn, cred->bv_val, method) != LDAP_SUCCESS)
57                 return( ldap_back_op_result(lc, op) );
58
59         lc->bound = 1;
60         return( 0 );
61 }
62
63 struct ldapconn *
64 ldap_back_getconn(struct ldapinfo *li, Connection *conn, Operation *op)
65 {
66         struct ldapconn *lc;
67         LDAP *ld;
68
69         ldap_pvt_thread_mutex_lock( &li->conn_mutex );
70         for (lc = li->lcs; lc; lc=lc->next)
71                 if (lc->conn == conn)
72                         break;
73         ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
74
75         /* Looks like we didn't get a bind. Open a new session... */
76         if (!lc) {
77                 int err = ldap_initialize(&ld, li->url);
78                 if (err != LDAP_SUCCESS) {
79                         err = ldap_back_map_result(err);
80                         send_ldap_result( conn, op, err,
81                                 NULL, "ldap_init failed", NULL, NULL );
82                         return( NULL );
83                 }
84                 lc = (struct ldapconn *)ch_malloc(sizeof(struct ldapconn));
85                 lc->conn = conn;
86                 lc->ld = ld;
87                 lc->bound = 0;
88                 ldap_pvt_thread_mutex_lock( &li->conn_mutex );
89                 lc->next = li->lcs;
90                 li->lcs = lc;
91                 ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
92         }
93         return( lc );
94 }
95
96 void
97 ldap_back_dobind(struct ldapconn *lc, Operation *op)
98 {
99         if (lc->bound)
100                 return;
101
102         if (ldap_bind_s(lc->ld, lc->conn->c_cdn, NULL, LDAP_AUTH_SIMPLE) !=
103                 LDAP_SUCCESS)
104                 ldap_back_op_result(lc, op);
105         else
106                 lc->bound = 1;
107 }
108
109 /* Map API errors to protocol errors... */
110
111 int
112 ldap_back_map_result(int err)
113 {
114         switch(err)
115         {
116         case LDAP_SERVER_DOWN:
117                 return LDAP_UNAVAILABLE;
118         case LDAP_LOCAL_ERROR:
119                 return LDAP_OPERATIONS_ERROR;
120         case LDAP_ENCODING_ERROR:
121         case LDAP_DECODING_ERROR:
122                 return LDAP_PROTOCOL_ERROR;
123         case LDAP_TIMEOUT:
124                 return LDAP_UNAVAILABLE;
125         case LDAP_AUTH_UNKNOWN:
126                 return LDAP_AUTH_METHOD_NOT_SUPPORTED;
127         case LDAP_FILTER_ERROR:
128                 return LDAP_OPERATIONS_ERROR;
129         case LDAP_USER_CANCELLED:
130                 return LDAP_OPERATIONS_ERROR;
131         case LDAP_PARAM_ERROR:
132                 return LDAP_PROTOCOL_ERROR;
133         case LDAP_NO_MEMORY:
134                 return LDAP_OPERATIONS_ERROR;
135         case LDAP_CONNECT_ERROR:
136                 return LDAP_UNAVAILABLE;
137         case LDAP_NOT_SUPPORTED:
138                 return LDAP_UNWILLING_TO_PERFORM;
139         case LDAP_CONTROL_NOT_FOUND:
140                 return LDAP_PROTOCOL_ERROR;
141         case LDAP_NO_RESULTS_RETURNED:
142                 return LDAP_NO_SUCH_OBJECT;
143         case LDAP_MORE_RESULTS_TO_RETURN:
144                 return LDAP_OTHER;
145         case LDAP_CLIENT_LOOP:
146         case LDAP_REFERRAL_LIMIT_EXCEEDED:
147                 return LDAP_LOOP_DETECT;
148         default:
149                 if LDAP_API_ERROR(err)
150                         return LDAP_OTHER;
151                 else
152                         return err;
153         }
154 }
155
156 int
157 ldap_back_op_result(struct ldapconn *lc, Operation *op)
158 {
159         int err;
160         char *msg;
161         char *match;
162
163         ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &err);
164         ldap_get_option(lc->ld, LDAP_OPT_ERROR_STRING, &msg);
165         ldap_get_option(lc->ld, LDAP_OPT_MATCHED_DN, &match);
166         err = ldap_back_map_result(err);
167         send_ldap_result( lc->conn, op, err, match, msg, NULL, NULL );
168         free(match);
169         free(msg);
170         return( (err==LDAP_SUCCESS) ? 0 : -1 );
171 }