search.c revision 1.1.1.1.6.2 1 1.1.1.1.6.2 wrstuden /* $OpenLDAP: pkg/ldap/libraries/libldap/search.c,v 1.76.2.5 2008/02/11 23:26:41 kurt Exp $ */
2 1.1.1.1.6.2 wrstuden /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 1.1.1.1.6.2 wrstuden *
4 1.1.1.1.6.2 wrstuden * Copyright 1998-2008 The OpenLDAP Foundation.
5 1.1.1.1.6.2 wrstuden * All rights reserved.
6 1.1.1.1.6.2 wrstuden *
7 1.1.1.1.6.2 wrstuden * Redistribution and use in source and binary forms, with or without
8 1.1.1.1.6.2 wrstuden * modification, are permitted only as authorized by the OpenLDAP
9 1.1.1.1.6.2 wrstuden * Public License.
10 1.1.1.1.6.2 wrstuden *
11 1.1.1.1.6.2 wrstuden * A copy of this license is available in the file LICENSE in the
12 1.1.1.1.6.2 wrstuden * top-level directory of the distribution or, alternatively, at
13 1.1.1.1.6.2 wrstuden * <http://www.OpenLDAP.org/license.html>.
14 1.1.1.1.6.2 wrstuden */
15 1.1.1.1.6.2 wrstuden /* Portions Copyright (c) 1990 Regents of the University of Michigan.
16 1.1.1.1.6.2 wrstuden * All rights reserved.
17 1.1.1.1.6.2 wrstuden */
18 1.1.1.1.6.2 wrstuden
19 1.1.1.1.6.2 wrstuden #include "portable.h"
20 1.1.1.1.6.2 wrstuden
21 1.1.1.1.6.2 wrstuden #include <stdio.h>
22 1.1.1.1.6.2 wrstuden
23 1.1.1.1.6.2 wrstuden #include <ac/stdlib.h>
24 1.1.1.1.6.2 wrstuden
25 1.1.1.1.6.2 wrstuden #include <ac/socket.h>
26 1.1.1.1.6.2 wrstuden #include <ac/string.h>
27 1.1.1.1.6.2 wrstuden #include <ac/time.h>
28 1.1.1.1.6.2 wrstuden
29 1.1.1.1.6.2 wrstuden #include "ldap-int.h"
30 1.1.1.1.6.2 wrstuden #include "ldap_log.h"
31 1.1.1.1.6.2 wrstuden
32 1.1.1.1.6.2 wrstuden /*
33 1.1.1.1.6.2 wrstuden * ldap_search_ext - initiate an ldap search operation.
34 1.1.1.1.6.2 wrstuden *
35 1.1.1.1.6.2 wrstuden * Parameters:
36 1.1.1.1.6.2 wrstuden *
37 1.1.1.1.6.2 wrstuden * ld LDAP descriptor
38 1.1.1.1.6.2 wrstuden * base DN of the base object
39 1.1.1.1.6.2 wrstuden * scope the search scope - one of
40 1.1.1.1.6.2 wrstuden * LDAP_SCOPE_BASE (baseObject),
41 1.1.1.1.6.2 wrstuden * LDAP_SCOPE_ONELEVEL (oneLevel),
42 1.1.1.1.6.2 wrstuden * LDAP_SCOPE_SUBTREE (subtree), or
43 1.1.1.1.6.2 wrstuden * LDAP_SCOPE_SUBORDINATE (children) -- OpenLDAP extension
44 1.1.1.1.6.2 wrstuden * filter a string containing the search filter
45 1.1.1.1.6.2 wrstuden * (e.g., "(|(cn=bob)(sn=bob))")
46 1.1.1.1.6.2 wrstuden * attrs list of attribute types to return for matches
47 1.1.1.1.6.2 wrstuden * attrsonly 1 => attributes only 0 => attributes and values
48 1.1.1.1.6.2 wrstuden *
49 1.1.1.1.6.2 wrstuden * Example:
50 1.1.1.1.6.2 wrstuden * char *attrs[] = { "mail", "title", 0 };
51 1.1.1.1.6.2 wrstuden * ldap_search_ext( ld, "dc=example,dc=com", LDAP_SCOPE_SUBTREE, "cn~=bob",
52 1.1.1.1.6.2 wrstuden * attrs, attrsonly, sctrls, ctrls, timeout, sizelimit,
53 1.1.1.1.6.2 wrstuden * &msgid );
54 1.1.1.1.6.2 wrstuden */
55 1.1.1.1.6.2 wrstuden int
56 1.1.1.1.6.2 wrstuden ldap_search_ext(
57 1.1.1.1.6.2 wrstuden LDAP *ld,
58 1.1.1.1.6.2 wrstuden LDAP_CONST char *base,
59 1.1.1.1.6.2 wrstuden int scope,
60 1.1.1.1.6.2 wrstuden LDAP_CONST char *filter,
61 1.1.1.1.6.2 wrstuden char **attrs,
62 1.1.1.1.6.2 wrstuden int attrsonly,
63 1.1.1.1.6.2 wrstuden LDAPControl **sctrls,
64 1.1.1.1.6.2 wrstuden LDAPControl **cctrls,
65 1.1.1.1.6.2 wrstuden struct timeval *timeout,
66 1.1.1.1.6.2 wrstuden int sizelimit,
67 1.1.1.1.6.2 wrstuden int *msgidp )
68 1.1.1.1.6.2 wrstuden {
69 1.1.1.1.6.2 wrstuden int rc;
70 1.1.1.1.6.2 wrstuden BerElement *ber;
71 1.1.1.1.6.2 wrstuden int timelimit;
72 1.1.1.1.6.2 wrstuden ber_int_t id;
73 1.1.1.1.6.2 wrstuden
74 1.1.1.1.6.2 wrstuden Debug( LDAP_DEBUG_TRACE, "ldap_search_ext\n", 0, 0, 0 );
75 1.1.1.1.6.2 wrstuden
76 1.1.1.1.6.2 wrstuden assert( ld != NULL );
77 1.1.1.1.6.2 wrstuden assert( LDAP_VALID( ld ) );
78 1.1.1.1.6.2 wrstuden
79 1.1.1.1.6.2 wrstuden /* check client controls */
80 1.1.1.1.6.2 wrstuden rc = ldap_int_client_controls( ld, cctrls );
81 1.1.1.1.6.2 wrstuden if( rc != LDAP_SUCCESS ) return rc;
82 1.1.1.1.6.2 wrstuden
83 1.1.1.1.6.2 wrstuden /*
84 1.1.1.1.6.2 wrstuden * if timeout is provided, both tv_sec and tv_usec must
85 1.1.1.1.6.2 wrstuden * not be zero
86 1.1.1.1.6.2 wrstuden */
87 1.1.1.1.6.2 wrstuden if( timeout != NULL ) {
88 1.1.1.1.6.2 wrstuden if( timeout->tv_sec == 0 && timeout->tv_usec == 0 ) {
89 1.1.1.1.6.2 wrstuden return LDAP_PARAM_ERROR;
90 1.1.1.1.6.2 wrstuden }
91 1.1.1.1.6.2 wrstuden
92 1.1.1.1.6.2 wrstuden /* timelimit must be non-zero if timeout is provided */
93 1.1.1.1.6.2 wrstuden timelimit = timeout->tv_sec != 0 ? timeout->tv_sec : 1;
94 1.1.1.1.6.2 wrstuden
95 1.1.1.1.6.2 wrstuden } else {
96 1.1.1.1.6.2 wrstuden /* no timeout, no timelimit */
97 1.1.1.1.6.2 wrstuden timelimit = -1;
98 1.1.1.1.6.2 wrstuden }
99 1.1.1.1.6.2 wrstuden
100 1.1.1.1.6.2 wrstuden ber = ldap_build_search_req( ld, base, scope, filter, attrs,
101 1.1.1.1.6.2 wrstuden attrsonly, sctrls, cctrls, timelimit, sizelimit, &id );
102 1.1.1.1.6.2 wrstuden
103 1.1.1.1.6.2 wrstuden if ( ber == NULL ) {
104 1.1.1.1.6.2 wrstuden return ld->ld_errno;
105 1.1.1.1.6.2 wrstuden }
106 1.1.1.1.6.2 wrstuden
107 1.1.1.1.6.2 wrstuden
108 1.1.1.1.6.2 wrstuden /* send the message */
109 1.1.1.1.6.2 wrstuden *msgidp = ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber, id );
110 1.1.1.1.6.2 wrstuden
111 1.1.1.1.6.2 wrstuden if( *msgidp < 0 )
112 1.1.1.1.6.2 wrstuden return ld->ld_errno;
113 1.1.1.1.6.2 wrstuden
114 1.1.1.1.6.2 wrstuden return LDAP_SUCCESS;
115 1.1.1.1.6.2 wrstuden }
116 1.1.1.1.6.2 wrstuden
117 1.1.1.1.6.2 wrstuden int
118 1.1.1.1.6.2 wrstuden ldap_search_ext_s(
119 1.1.1.1.6.2 wrstuden LDAP *ld,
120 1.1.1.1.6.2 wrstuden LDAP_CONST char *base,
121 1.1.1.1.6.2 wrstuden int scope,
122 1.1.1.1.6.2 wrstuden LDAP_CONST char *filter,
123 1.1.1.1.6.2 wrstuden char **attrs,
124 1.1.1.1.6.2 wrstuden int attrsonly,
125 1.1.1.1.6.2 wrstuden LDAPControl **sctrls,
126 1.1.1.1.6.2 wrstuden LDAPControl **cctrls,
127 1.1.1.1.6.2 wrstuden struct timeval *timeout,
128 1.1.1.1.6.2 wrstuden int sizelimit,
129 1.1.1.1.6.2 wrstuden LDAPMessage **res )
130 1.1.1.1.6.2 wrstuden {
131 1.1.1.1.6.2 wrstuden int rc;
132 1.1.1.1.6.2 wrstuden int msgid;
133 1.1.1.1.6.2 wrstuden
134 1.1.1.1.6.2 wrstuden rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
135 1.1.1.1.6.2 wrstuden sctrls, cctrls, timeout, sizelimit, &msgid );
136 1.1.1.1.6.2 wrstuden
137 1.1.1.1.6.2 wrstuden if ( rc != LDAP_SUCCESS ) {
138 1.1.1.1.6.2 wrstuden return( rc );
139 1.1.1.1.6.2 wrstuden }
140 1.1.1.1.6.2 wrstuden
141 1.1.1.1.6.2 wrstuden rc = ldap_result( ld, msgid, LDAP_MSG_ALL, timeout, res );
142 1.1.1.1.6.2 wrstuden
143 1.1.1.1.6.2 wrstuden if( rc <= 0 ) {
144 1.1.1.1.6.2 wrstuden /* error(-1) or timeout(0) */
145 1.1.1.1.6.2 wrstuden return( ld->ld_errno );
146 1.1.1.1.6.2 wrstuden }
147 1.1.1.1.6.2 wrstuden
148 1.1.1.1.6.2 wrstuden if( rc == LDAP_RES_SEARCH_REFERENCE || rc == LDAP_RES_INTERMEDIATE ) {
149 1.1.1.1.6.2 wrstuden return( ld->ld_errno );
150 1.1.1.1.6.2 wrstuden }
151 1.1.1.1.6.2 wrstuden
152 1.1.1.1.6.2 wrstuden return( ldap_result2error( ld, *res, 0 ) );
153 1.1.1.1.6.2 wrstuden }
154 1.1.1.1.6.2 wrstuden
155 1.1.1.1.6.2 wrstuden /*
156 1.1.1.1.6.2 wrstuden * ldap_search - initiate an ldap search operation.
157 1.1.1.1.6.2 wrstuden *
158 1.1.1.1.6.2 wrstuden * Parameters:
159 1.1.1.1.6.2 wrstuden *
160 1.1.1.1.6.2 wrstuden * ld LDAP descriptor
161 1.1.1.1.6.2 wrstuden * base DN of the base object
162 1.1.1.1.6.2 wrstuden * scope the search scope - one of
163 1.1.1.1.6.2 wrstuden * LDAP_SCOPE_BASE (baseObject),
164 1.1.1.1.6.2 wrstuden * LDAP_SCOPE_ONELEVEL (oneLevel),
165 1.1.1.1.6.2 wrstuden * LDAP_SCOPE_SUBTREE (subtree), or
166 1.1.1.1.6.2 wrstuden * LDAP_SCOPE_SUBORDINATE (children) -- OpenLDAP extension
167 1.1.1.1.6.2 wrstuden * filter a string containing the search filter
168 1.1.1.1.6.2 wrstuden * (e.g., "(|(cn=bob)(sn=bob))")
169 1.1.1.1.6.2 wrstuden * attrs list of attribute types to return for matches
170 1.1.1.1.6.2 wrstuden * attrsonly 1 => attributes only 0 => attributes and values
171 1.1.1.1.6.2 wrstuden *
172 1.1.1.1.6.2 wrstuden * Example:
173 1.1.1.1.6.2 wrstuden * char *attrs[] = { "mail", "title", 0 };
174 1.1.1.1.6.2 wrstuden * msgid = ldap_search( ld, "dc=example,dc=com", LDAP_SCOPE_SUBTREE, "cn~=bob",
175 1.1.1.1.6.2 wrstuden * attrs, attrsonly );
176 1.1.1.1.6.2 wrstuden */
177 1.1.1.1.6.2 wrstuden int
178 1.1.1.1.6.2 wrstuden ldap_search(
179 1.1.1.1.6.2 wrstuden LDAP *ld, LDAP_CONST char *base, int scope, LDAP_CONST char *filter,
180 1.1.1.1.6.2 wrstuden char **attrs, int attrsonly )
181 1.1.1.1.6.2 wrstuden {
182 1.1.1.1.6.2 wrstuden BerElement *ber;
183 1.1.1.1.6.2 wrstuden ber_int_t id;
184 1.1.1.1.6.2 wrstuden
185 1.1.1.1.6.2 wrstuden Debug( LDAP_DEBUG_TRACE, "ldap_search\n", 0, 0, 0 );
186 1.1.1.1.6.2 wrstuden
187 1.1.1.1.6.2 wrstuden assert( ld != NULL );
188 1.1.1.1.6.2 wrstuden assert( LDAP_VALID( ld ) );
189 1.1.1.1.6.2 wrstuden
190 1.1.1.1.6.2 wrstuden ber = ldap_build_search_req( ld, base, scope, filter, attrs,
191 1.1.1.1.6.2 wrstuden attrsonly, NULL, NULL, -1, -1, &id );
192 1.1.1.1.6.2 wrstuden
193 1.1.1.1.6.2 wrstuden if ( ber == NULL ) {
194 1.1.1.1.6.2 wrstuden return( -1 );
195 1.1.1.1.6.2 wrstuden }
196 1.1.1.1.6.2 wrstuden
197 1.1.1.1.6.2 wrstuden
198 1.1.1.1.6.2 wrstuden /* send the message */
199 1.1.1.1.6.2 wrstuden return ( ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber, id ));
200 1.1.1.1.6.2 wrstuden }
201 1.1.1.1.6.2 wrstuden
202 1.1.1.1.6.2 wrstuden
203 1.1.1.1.6.2 wrstuden BerElement *
204 1.1.1.1.6.2 wrstuden ldap_build_search_req(
205 1.1.1.1.6.2 wrstuden LDAP *ld,
206 1.1.1.1.6.2 wrstuden LDAP_CONST char *base,
207 1.1.1.1.6.2 wrstuden ber_int_t scope,
208 1.1.1.1.6.2 wrstuden LDAP_CONST char *filter,
209 1.1.1.1.6.2 wrstuden char **attrs,
210 1.1.1.1.6.2 wrstuden ber_int_t attrsonly,
211 1.1.1.1.6.2 wrstuden LDAPControl **sctrls,
212 1.1.1.1.6.2 wrstuden LDAPControl **cctrls,
213 1.1.1.1.6.2 wrstuden ber_int_t timelimit,
214 1.1.1.1.6.2 wrstuden ber_int_t sizelimit,
215 1.1.1.1.6.2 wrstuden ber_int_t *idp)
216 1.1.1.1.6.2 wrstuden {
217 1.1.1.1.6.2 wrstuden BerElement *ber;
218 1.1.1.1.6.2 wrstuden int err;
219 1.1.1.1.6.2 wrstuden
220 1.1.1.1.6.2 wrstuden /*
221 1.1.1.1.6.2 wrstuden * Create the search request. It looks like this:
222 1.1.1.1.6.2 wrstuden * SearchRequest := [APPLICATION 3] SEQUENCE {
223 1.1.1.1.6.2 wrstuden * baseObject DistinguishedName,
224 1.1.1.1.6.2 wrstuden * scope ENUMERATED {
225 1.1.1.1.6.2 wrstuden * baseObject (0),
226 1.1.1.1.6.2 wrstuden * singleLevel (1),
227 1.1.1.1.6.2 wrstuden * wholeSubtree (2)
228 1.1.1.1.6.2 wrstuden * },
229 1.1.1.1.6.2 wrstuden * derefAliases ENUMERATED {
230 1.1.1.1.6.2 wrstuden * neverDerefaliases (0),
231 1.1.1.1.6.2 wrstuden * derefInSearching (1),
232 1.1.1.1.6.2 wrstuden * derefFindingBaseObj (2),
233 1.1.1.1.6.2 wrstuden * alwaysDerefAliases (3)
234 1.1.1.1.6.2 wrstuden * },
235 1.1.1.1.6.2 wrstuden * sizelimit INTEGER (0 .. 65535),
236 1.1.1.1.6.2 wrstuden * timelimit INTEGER (0 .. 65535),
237 1.1.1.1.6.2 wrstuden * attrsOnly BOOLEAN,
238 1.1.1.1.6.2 wrstuden * filter Filter,
239 1.1.1.1.6.2 wrstuden * attributes SEQUENCE OF AttributeType
240 1.1.1.1.6.2 wrstuden * }
241 1.1.1.1.6.2 wrstuden * wrapped in an ldap message.
242 1.1.1.1.6.2 wrstuden */
243 1.1.1.1.6.2 wrstuden
244 1.1.1.1.6.2 wrstuden /* create a message to send */
245 1.1.1.1.6.2 wrstuden if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
246 1.1.1.1.6.2 wrstuden return( NULL );
247 1.1.1.1.6.2 wrstuden }
248 1.1.1.1.6.2 wrstuden
249 1.1.1.1.6.2 wrstuden if ( base == NULL ) {
250 1.1.1.1.6.2 wrstuden /* no base provided, use session default base */
251 1.1.1.1.6.2 wrstuden base = ld->ld_options.ldo_defbase;
252 1.1.1.1.6.2 wrstuden
253 1.1.1.1.6.2 wrstuden if ( base == NULL ) {
254 1.1.1.1.6.2 wrstuden /* no session default base, use top */
255 1.1.1.1.6.2 wrstuden base = "";
256 1.1.1.1.6.2 wrstuden }
257 1.1.1.1.6.2 wrstuden }
258 1.1.1.1.6.2 wrstuden
259 1.1.1.1.6.2 wrstuden LDAP_NEXT_MSGID( ld, *idp );
260 1.1.1.1.6.2 wrstuden #ifdef LDAP_CONNECTIONLESS
261 1.1.1.1.6.2 wrstuden if ( LDAP_IS_UDP(ld) ) {
262 1.1.1.1.6.2 wrstuden struct sockaddr sa = {0};
263 1.1.1.1.6.2 wrstuden /* dummy, filled with ldo_peer in request.c */
264 1.1.1.1.6.2 wrstuden err = ber_write( ber, &sa, sizeof( sa ), 0 );
265 1.1.1.1.6.2 wrstuden }
266 1.1.1.1.6.2 wrstuden if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version == LDAP_VERSION2) {
267 1.1.1.1.6.2 wrstuden char *dn = ld->ld_options.ldo_cldapdn;
268 1.1.1.1.6.2 wrstuden if (!dn) dn = "";
269 1.1.1.1.6.2 wrstuden err = ber_printf( ber, "{ist{seeiib", *idp, dn,
270 1.1.1.1.6.2 wrstuden LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref,
271 1.1.1.1.6.2 wrstuden (sizelimit < 0) ? ld->ld_sizelimit : sizelimit,
272 1.1.1.1.6.2 wrstuden (timelimit < 0) ? ld->ld_timelimit : timelimit,
273 1.1.1.1.6.2 wrstuden attrsonly );
274 1.1.1.1.6.2 wrstuden } else
275 1.1.1.1.6.2 wrstuden #endif
276 1.1.1.1.6.2 wrstuden {
277 1.1.1.1.6.2 wrstuden err = ber_printf( ber, "{it{seeiib", *idp,
278 1.1.1.1.6.2 wrstuden LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref,
279 1.1.1.1.6.2 wrstuden (sizelimit < 0) ? ld->ld_sizelimit : sizelimit,
280 1.1.1.1.6.2 wrstuden (timelimit < 0) ? ld->ld_timelimit : timelimit,
281 1.1.1.1.6.2 wrstuden attrsonly );
282 1.1.1.1.6.2 wrstuden }
283 1.1.1.1.6.2 wrstuden
284 1.1.1.1.6.2 wrstuden if ( err == -1 ) {
285 1.1.1.1.6.2 wrstuden ld->ld_errno = LDAP_ENCODING_ERROR;
286 1.1.1.1.6.2 wrstuden ber_free( ber, 1 );
287 1.1.1.1.6.2 wrstuden return( NULL );
288 1.1.1.1.6.2 wrstuden }
289 1.1.1.1.6.2 wrstuden
290 1.1.1.1.6.2 wrstuden if( filter == NULL ) {
291 1.1.1.1.6.2 wrstuden filter = "(objectclass=*)";
292 1.1.1.1.6.2 wrstuden }
293 1.1.1.1.6.2 wrstuden
294 1.1.1.1.6.2 wrstuden err = ldap_pvt_put_filter( ber, filter );
295 1.1.1.1.6.2 wrstuden
296 1.1.1.1.6.2 wrstuden if ( err == -1 ) {
297 1.1.1.1.6.2 wrstuden ld->ld_errno = LDAP_FILTER_ERROR;
298 1.1.1.1.6.2 wrstuden ber_free( ber, 1 );
299 1.1.1.1.6.2 wrstuden return( NULL );
300 1.1.1.1.6.2 wrstuden }
301 1.1.1.1.6.2 wrstuden
302 1.1.1.1.6.2 wrstuden #ifdef LDAP_DEBUG
303 1.1.1.1.6.2 wrstuden if ( ldap_debug & LDAP_DEBUG_ARGS ) {
304 1.1.1.1.6.2 wrstuden char buf[ BUFSIZ ] = { ' ', '*', '\0' };
305 1.1.1.1.6.2 wrstuden
306 1.1.1.1.6.2 wrstuden if ( attrs != NULL ) {
307 1.1.1.1.6.2 wrstuden char *ptr;
308 1.1.1.1.6.2 wrstuden int i;
309 1.1.1.1.6.2 wrstuden
310 1.1.1.1.6.2 wrstuden for ( ptr = buf, i = 0;
311 1.1.1.1.6.2 wrstuden attrs[ i ] != NULL && ptr < &buf[ sizeof( buf ) ];
312 1.1.1.1.6.2 wrstuden i++ )
313 1.1.1.1.6.2 wrstuden {
314 1.1.1.1.6.2 wrstuden ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ),
315 1.1.1.1.6.2 wrstuden " %s", attrs[ i ] );
316 1.1.1.1.6.2 wrstuden }
317 1.1.1.1.6.2 wrstuden
318 1.1.1.1.6.2 wrstuden if ( ptr >= &buf[ sizeof( buf ) ] ) {
319 1.1.1.1.6.2 wrstuden AC_MEMCPY( &buf[ sizeof( buf ) - STRLENOF( "...(truncated)" ) - 1 ],
320 1.1.1.1.6.2 wrstuden "...(truncated)", STRLENOF( "...(truncated)" ) + 1 );
321 1.1.1.1.6.2 wrstuden }
322 1.1.1.1.6.2 wrstuden }
323 1.1.1.1.6.2 wrstuden
324 1.1.1.1.6.2 wrstuden Debug( LDAP_DEBUG_ARGS, "ldap_build_search_req ATTRS:%s\n", buf, 0, 0 );
325 1.1.1.1.6.2 wrstuden }
326 1.1.1.1.6.2 wrstuden #endif /* LDAP_DEBUG */
327 1.1.1.1.6.2 wrstuden
328 1.1.1.1.6.2 wrstuden if ( ber_printf( ber, /*{*/ "{v}N}", attrs ) == -1 ) {
329 1.1.1.1.6.2 wrstuden ld->ld_errno = LDAP_ENCODING_ERROR;
330 1.1.1.1.6.2 wrstuden ber_free( ber, 1 );
331 1.1.1.1.6.2 wrstuden return( NULL );
332 1.1.1.1.6.2 wrstuden }
333 1.1.1.1.6.2 wrstuden
334 1.1.1.1.6.2 wrstuden /* Put Server Controls */
335 1.1.1.1.6.2 wrstuden if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
336 1.1.1.1.6.2 wrstuden ber_free( ber, 1 );
337 1.1.1.1.6.2 wrstuden return( NULL );
338 1.1.1.1.6.2 wrstuden }
339 1.1.1.1.6.2 wrstuden
340 1.1.1.1.6.2 wrstuden if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
341 1.1.1.1.6.2 wrstuden ld->ld_errno = LDAP_ENCODING_ERROR;
342 1.1.1.1.6.2 wrstuden ber_free( ber, 1 );
343 1.1.1.1.6.2 wrstuden return( NULL );
344 1.1.1.1.6.2 wrstuden }
345 1.1.1.1.6.2 wrstuden
346 1.1.1.1.6.2 wrstuden return( ber );
347 1.1.1.1.6.2 wrstuden }
348 1.1.1.1.6.2 wrstuden
349 1.1.1.1.6.2 wrstuden int
350 1.1.1.1.6.2 wrstuden ldap_search_st(
351 1.1.1.1.6.2 wrstuden LDAP *ld, LDAP_CONST char *base, int scope,
352 1.1.1.1.6.2 wrstuden LDAP_CONST char *filter, char **attrs,
353 1.1.1.1.6.2 wrstuden int attrsonly, struct timeval *timeout, LDAPMessage **res )
354 1.1.1.1.6.2 wrstuden {
355 1.1.1.1.6.2 wrstuden int msgid;
356 1.1.1.1.6.2 wrstuden
357 1.1.1.1.6.2 wrstuden if ( (msgid = ldap_search( ld, base, scope, filter, attrs, attrsonly ))
358 1.1.1.1.6.2 wrstuden == -1 )
359 1.1.1.1.6.2 wrstuden return( ld->ld_errno );
360 1.1.1.1.6.2 wrstuden
361 1.1.1.1.6.2 wrstuden if ( ldap_result( ld, msgid, LDAP_MSG_ALL, timeout, res ) == -1 || !*res )
362 1.1.1.1.6.2 wrstuden return( ld->ld_errno );
363 1.1.1.1.6.2 wrstuden
364 1.1.1.1.6.2 wrstuden if ( ld->ld_errno == LDAP_TIMEOUT ) {
365 1.1.1.1.6.2 wrstuden (void) ldap_abandon( ld, msgid );
366 1.1.1.1.6.2 wrstuden ld->ld_errno = LDAP_TIMEOUT;
367 1.1.1.1.6.2 wrstuden return( ld->ld_errno );
368 1.1.1.1.6.2 wrstuden }
369 1.1.1.1.6.2 wrstuden
370 1.1.1.1.6.2 wrstuden return( ldap_result2error( ld, *res, 0 ) );
371 1.1.1.1.6.2 wrstuden }
372 1.1.1.1.6.2 wrstuden
373 1.1.1.1.6.2 wrstuden int
374 1.1.1.1.6.2 wrstuden ldap_search_s(
375 1.1.1.1.6.2 wrstuden LDAP *ld,
376 1.1.1.1.6.2 wrstuden LDAP_CONST char *base,
377 1.1.1.1.6.2 wrstuden int scope,
378 1.1.1.1.6.2 wrstuden LDAP_CONST char *filter,
379 1.1.1.1.6.2 wrstuden char **attrs,
380 1.1.1.1.6.2 wrstuden int attrsonly,
381 1.1.1.1.6.2 wrstuden LDAPMessage **res )
382 1.1.1.1.6.2 wrstuden {
383 1.1.1.1.6.2 wrstuden int msgid;
384 1.1.1.1.6.2 wrstuden
385 1.1.1.1.6.2 wrstuden if ( (msgid = ldap_search( ld, base, scope, filter, attrs, attrsonly ))
386 1.1.1.1.6.2 wrstuden == -1 )
387 1.1.1.1.6.2 wrstuden return( ld->ld_errno );
388 1.1.1.1.6.2 wrstuden
389 1.1.1.1.6.2 wrstuden if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, res ) == -1 || !*res )
390 1.1.1.1.6.2 wrstuden return( ld->ld_errno );
391 1.1.1.1.6.2 wrstuden
392 1.1.1.1.6.2 wrstuden return( ldap_result2error( ld, *res, 0 ) );
393 1.1.1.1.6.2 wrstuden }
394 1.1.1.1.6.2 wrstuden
395 1.1.1.1.6.2 wrstuden static char escape[128] = {
396 1.1.1.1.6.2 wrstuden 1, 1, 1, 1, 1, 1, 1, 1,
397 1.1.1.1.6.2 wrstuden 1, 1, 1, 1, 1, 1, 1, 1,
398 1.1.1.1.6.2 wrstuden 1, 1, 1, 1, 1, 1, 1, 1,
399 1.1.1.1.6.2 wrstuden 1, 1, 1, 1, 1, 1, 1, 1,
400 1.1.1.1.6.2 wrstuden
401 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 0, 0, 0, 0,
402 1.1.1.1.6.2 wrstuden 1, 1, 1, 0, 0, 0, 0, 0,
403 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 0, 0, 0, 0,
404 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 0, 0, 0, 0,
405 1.1.1.1.6.2 wrstuden
406 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 0, 0, 0, 0,
407 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 0, 0, 0, 0,
408 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 0, 0, 0, 0,
409 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 1, 0, 0, 0,
410 1.1.1.1.6.2 wrstuden
411 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 0, 0, 0, 0,
412 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 0, 0, 0, 0,
413 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 0, 0, 0, 0,
414 1.1.1.1.6.2 wrstuden 0, 0, 0, 0, 0, 0, 0, 1
415 1.1.1.1.6.2 wrstuden };
416 1.1.1.1.6.2 wrstuden #define NEEDFLTESCAPE(c) ((c) & 0x80 || escape[ (unsigned)(c) ])
417 1.1.1.1.6.2 wrstuden
418 1.1.1.1.6.2 wrstuden /*
419 1.1.1.1.6.2 wrstuden * compute the length of the escaped value
420 1.1.1.1.6.2 wrstuden */
421 1.1.1.1.6.2 wrstuden ber_len_t
422 1.1.1.1.6.2 wrstuden ldap_bv2escaped_filter_value_len( struct berval *in )
423 1.1.1.1.6.2 wrstuden {
424 1.1.1.1.6.2 wrstuden ber_len_t i, l;
425 1.1.1.1.6.2 wrstuden
426 1.1.1.1.6.2 wrstuden assert( in != NULL );
427 1.1.1.1.6.2 wrstuden
428 1.1.1.1.6.2 wrstuden if ( in->bv_len == 0 ) {
429 1.1.1.1.6.2 wrstuden return 0;
430 1.1.1.1.6.2 wrstuden }
431 1.1.1.1.6.2 wrstuden
432 1.1.1.1.6.2 wrstuden for( l = 0, i = 0; i < in->bv_len; l++, i++ ) {
433 1.1.1.1.6.2 wrstuden char c = in->bv_val[ i ];
434 1.1.1.1.6.2 wrstuden if ( NEEDFLTESCAPE( c ) ) {
435 1.1.1.1.6.2 wrstuden l += 2;
436 1.1.1.1.6.2 wrstuden }
437 1.1.1.1.6.2 wrstuden }
438 1.1.1.1.6.2 wrstuden
439 1.1.1.1.6.2 wrstuden return l;
440 1.1.1.1.6.2 wrstuden }
441 1.1.1.1.6.2 wrstuden
442 1.1.1.1.6.2 wrstuden int
443 1.1.1.1.6.2 wrstuden ldap_bv2escaped_filter_value( struct berval *in, struct berval *out )
444 1.1.1.1.6.2 wrstuden {
445 1.1.1.1.6.2 wrstuden return ldap_bv2escaped_filter_value_x( in, out, 0, NULL );
446 1.1.1.1.6.2 wrstuden }
447 1.1.1.1.6.2 wrstuden
448 1.1.1.1.6.2 wrstuden int
449 1.1.1.1.6.2 wrstuden ldap_bv2escaped_filter_value_x( struct berval *in, struct berval *out, int inplace, void *ctx )
450 1.1.1.1.6.2 wrstuden {
451 1.1.1.1.6.2 wrstuden ber_len_t i, l;
452 1.1.1.1.6.2 wrstuden
453 1.1.1.1.6.2 wrstuden assert( in != NULL );
454 1.1.1.1.6.2 wrstuden assert( out != NULL );
455 1.1.1.1.6.2 wrstuden
456 1.1.1.1.6.2 wrstuden BER_BVZERO( out );
457 1.1.1.1.6.2 wrstuden
458 1.1.1.1.6.2 wrstuden if ( in->bv_len == 0 ) {
459 1.1.1.1.6.2 wrstuden return 0;
460 1.1.1.1.6.2 wrstuden }
461 1.1.1.1.6.2 wrstuden
462 1.1.1.1.6.2 wrstuden /* assume we'll escape everything */
463 1.1.1.1.6.2 wrstuden l = ldap_bv2escaped_filter_value_len( in );
464 1.1.1.1.6.2 wrstuden if ( l == in->bv_len ) {
465 1.1.1.1.6.2 wrstuden if ( inplace ) {
466 1.1.1.1.6.2 wrstuden *out = *in;
467 1.1.1.1.6.2 wrstuden } else {
468 1.1.1.1.6.2 wrstuden ber_dupbv( out, in );
469 1.1.1.1.6.2 wrstuden }
470 1.1.1.1.6.2 wrstuden return 0;
471 1.1.1.1.6.2 wrstuden }
472 1.1.1.1.6.2 wrstuden out->bv_val = LDAP_MALLOCX( l + 1, ctx );
473 1.1.1.1.6.2 wrstuden if ( out->bv_val == NULL ) {
474 1.1.1.1.6.2 wrstuden return -1;
475 1.1.1.1.6.2 wrstuden }
476 1.1.1.1.6.2 wrstuden
477 1.1.1.1.6.2 wrstuden for ( i = 0; i < in->bv_len; i++ ) {
478 1.1.1.1.6.2 wrstuden char c = in->bv_val[ i ];
479 1.1.1.1.6.2 wrstuden if ( NEEDFLTESCAPE( c ) ) {
480 1.1.1.1.6.2 wrstuden assert( out->bv_len < l - 2 );
481 1.1.1.1.6.2 wrstuden out->bv_val[out->bv_len++] = '\\';
482 1.1.1.1.6.2 wrstuden out->bv_val[out->bv_len++] = "0123456789ABCDEF"[0x0f & (c>>4)];
483 1.1.1.1.6.2 wrstuden out->bv_val[out->bv_len++] = "0123456789ABCDEF"[0x0f & c];
484 1.1.1.1.6.2 wrstuden
485 1.1.1.1.6.2 wrstuden } else {
486 1.1.1.1.6.2 wrstuden assert( out->bv_len < l );
487 1.1.1.1.6.2 wrstuden out->bv_val[out->bv_len++] = c;
488 1.1.1.1.6.2 wrstuden }
489 1.1.1.1.6.2 wrstuden }
490 1.1.1.1.6.2 wrstuden
491 1.1.1.1.6.2 wrstuden out->bv_val[out->bv_len] = '\0';
492 1.1.1.1.6.2 wrstuden
493 1.1.1.1.6.2 wrstuden return 0;
494 1.1.1.1.6.2 wrstuden }
495 1.1.1.1.6.2 wrstuden
496