]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldap/bind.c
ITS#919: fix str2ad initialization bug
[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 vers = conn->c_protocol;
78                 int err = ldap_initialize(&ld, li->url);
79                 if (err != LDAP_SUCCESS) {
80                         err = ldap_back_map_result(err);
81                         send_ldap_result( conn, op, err,
82                                 NULL, "ldap_init failed", NULL, NULL );
83                         return( NULL );
84                 }
85                 /* Set LDAP version. This will always succeed: If the client
86                  * bound with a particular version, then so can we.
87                  */
88                 ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &vers);
89
90                 lc = (struct ldapconn *)ch_malloc(sizeof(struct ldapconn));
91                 lc->conn = conn;
92                 lc->ld = ld;
93                 lc->bound = 0;
94                 ldap_pvt_thread_mutex_lock( &li->conn_mutex );
95                 lc->next = li->lcs;
96                 li->lcs = lc;
97                 ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
98         }
99         return( lc );
100 }
101
102 void
103 ldap_back_dobind(struct ldapconn *lc, Operation *op)
104 {
105         if (lc->bound)
106                 return;
107
108         if (ldap_bind_s(lc->ld, lc->conn->c_cdn, NULL, LDAP_AUTH_SIMPLE) !=
109                 LDAP_SUCCESS)
110                 ldap_back_op_result(lc, op);
111         else
112                 lc->bound = 1;
113 }
114
115 /* Map API errors to protocol errors... */
116
117 int
118 ldap_back_map_result(int err)
119 {
120         switch(err)
121         {
122         case LDAP_SERVER_DOWN:
123                 return LDAP_UNAVAILABLE;
124         case LDAP_LOCAL_ERROR:
125                 return LDAP_OPERATIONS_ERROR;
126         case LDAP_ENCODING_ERROR:
127         case LDAP_DECODING_ERROR:
128                 return LDAP_PROTOCOL_ERROR;
129         case LDAP_TIMEOUT:
130                 return LDAP_UNAVAILABLE;
131         case LDAP_AUTH_UNKNOWN:
132                 return LDAP_AUTH_METHOD_NOT_SUPPORTED;
133         case LDAP_FILTER_ERROR:
134                 return LDAP_OPERATIONS_ERROR;
135         case LDAP_USER_CANCELLED:
136                 return LDAP_OPERATIONS_ERROR;
137         case LDAP_PARAM_ERROR:
138                 return LDAP_PROTOCOL_ERROR;
139         case LDAP_NO_MEMORY:
140                 return LDAP_OPERATIONS_ERROR;
141         case LDAP_CONNECT_ERROR:
142                 return LDAP_UNAVAILABLE;
143         case LDAP_NOT_SUPPORTED:
144                 return LDAP_UNWILLING_TO_PERFORM;
145         case LDAP_CONTROL_NOT_FOUND:
146                 return LDAP_PROTOCOL_ERROR;
147         case LDAP_NO_RESULTS_RETURNED:
148                 return LDAP_NO_SUCH_OBJECT;
149         case LDAP_MORE_RESULTS_TO_RETURN:
150                 return LDAP_OTHER;
151         case LDAP_CLIENT_LOOP:
152         case LDAP_REFERRAL_LIMIT_EXCEEDED:
153                 return LDAP_LOOP_DETECT;
154         default:
155                 if LDAP_API_ERROR(err)
156                         return LDAP_OTHER;
157                 else
158                         return err;
159         }
160 }
161
162 int
163 ldap_back_op_result(struct ldapconn *lc, Operation *op)
164 {
165         int err;
166         char *msg;
167         char *match;
168
169         ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &err);
170         ldap_get_option(lc->ld, LDAP_OPT_ERROR_STRING, &msg);
171         ldap_get_option(lc->ld, LDAP_OPT_MATCHED_DN, &match);
172         err = ldap_back_map_result(err);
173         send_ldap_result( lc->conn, op, err, match, msg, NULL, NULL );
174         free(match);
175         free(msg);
176         return( (err==LDAP_SUCCESS) ? 0 : -1 );
177 }