ldapsearch.c revision 1.3 1 1.3 christos /* $NetBSD: ldapsearch.c,v 1.3 2021/08/14 16:14:49 christos Exp $ */
2 1.2 christos
3 1.1 lukem /* ldapsearch -- a tool for searching LDAP directories */
4 1.2 christos /* $OpenLDAP$ */
5 1.1 lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 1.1 lukem *
7 1.3 christos * Copyright 1998-2021 The OpenLDAP Foundation.
8 1.1 lukem * Portions Copyright 1998-2003 Kurt D. Zeilenga.
9 1.1 lukem * Portions Copyright 1998-2001 Net Boolean Incorporated.
10 1.1 lukem * Portions Copyright 2001-2003 IBM Corporation.
11 1.1 lukem * All rights reserved.
12 1.1 lukem *
13 1.1 lukem * Redistribution and use in source and binary forms, with or without
14 1.1 lukem * modification, are permitted only as authorized by the OpenLDAP
15 1.1 lukem * Public License.
16 1.1 lukem *
17 1.1 lukem * A copy of this license is available in the file LICENSE in the
18 1.1 lukem * top-level directory of the distribution or, alternatively, at
19 1.1 lukem * <http://www.OpenLDAP.org/license.html>.
20 1.1 lukem */
21 1.1 lukem /* Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
22 1.1 lukem * All rights reserved.
23 1.1 lukem *
24 1.1 lukem * Redistribution and use in source and binary forms are permitted
25 1.1 lukem * provided that this notice is preserved and that due credit is given
26 1.1 lukem * to the University of Michigan at Ann Arbor. The name of the
27 1.1 lukem * University may not be used to endorse or promote products derived
28 1.1 lukem * from this software without specific prior written permission. This
29 1.1 lukem * software is provided ``as is'' without express or implied warranty.
30 1.1 lukem */
31 1.1 lukem /* ACKNOWLEDGEMENTS:
32 1.1 lukem * This work was originally developed by the University of Michigan
33 1.1 lukem * (as part of U-MICH LDAP). Additional significant contributors
34 1.1 lukem * include:
35 1.1 lukem * Jong Hyuk Choi
36 1.1 lukem * Lynn Moss
37 1.1 lukem * Mikhail Sahalaev
38 1.1 lukem * Kurt D. Zeilenga
39 1.1 lukem */
40 1.1 lukem
41 1.2 christos #include <sys/cdefs.h>
42 1.3 christos __RCSID("$NetBSD: ldapsearch.c,v 1.3 2021/08/14 16:14:49 christos Exp $");
43 1.2 christos
44 1.1 lukem #include "portable.h"
45 1.1 lukem
46 1.1 lukem #include <stdio.h>
47 1.1 lukem
48 1.1 lukem #include <ac/stdlib.h>
49 1.1 lukem #include <ac/ctype.h>
50 1.1 lukem #include <ac/string.h>
51 1.1 lukem #include <ac/unistd.h>
52 1.1 lukem #include <ac/errno.h>
53 1.2 christos #include <ac/time.h>
54 1.2 christos
55 1.1 lukem #include <sys/stat.h>
56 1.1 lukem
57 1.1 lukem #include <ac/signal.h>
58 1.1 lukem
59 1.1 lukem #ifdef HAVE_FCNTL_H
60 1.1 lukem #include <fcntl.h>
61 1.1 lukem #endif
62 1.1 lukem #ifdef HAVE_SYS_TYPES_H
63 1.1 lukem #include <sys/types.h>
64 1.1 lukem #endif
65 1.1 lukem #ifdef HAVE_IO_H
66 1.1 lukem #include <io.h>
67 1.1 lukem #endif
68 1.1 lukem
69 1.1 lukem #include <ldap.h>
70 1.1 lukem
71 1.1 lukem #include "ldif.h"
72 1.1 lukem #include "lutil.h"
73 1.1 lukem #include "lutil_ldap.h"
74 1.1 lukem #include "ldap_defaults.h"
75 1.1 lukem #include "ldap_pvt.h"
76 1.1 lukem
77 1.1 lukem #include "common.h"
78 1.1 lukem
79 1.1 lukem #if !LDAP_DEPRECATED
80 1.1 lukem /*
81 1.1 lukem * NOTE: we use this deprecated function only because
82 1.1 lukem * we want ldapsearch to provide some client-side sorting
83 1.1 lukem * capability.
84 1.1 lukem */
85 1.1 lukem /* from ldap.h */
86 1.1 lukem typedef int (LDAP_SORT_AD_CMP_PROC) LDAP_P(( /* deprecated */
87 1.1 lukem LDAP_CONST char *left,
88 1.1 lukem LDAP_CONST char *right ));
89 1.1 lukem
90 1.1 lukem LDAP_F( int ) /* deprecated */
91 1.1 lukem ldap_sort_entries LDAP_P(( LDAP *ld,
92 1.1 lukem LDAPMessage **chain,
93 1.1 lukem LDAP_CONST char *attr,
94 1.1 lukem LDAP_SORT_AD_CMP_PROC *cmp ));
95 1.1 lukem #endif
96 1.1 lukem
97 1.1 lukem static int scope = LDAP_SCOPE_SUBTREE;
98 1.1 lukem static int deref = -1;
99 1.1 lukem static int attrsonly;
100 1.1 lukem static int timelimit = -1;
101 1.1 lukem static int sizelimit = -1;
102 1.1 lukem
103 1.1 lukem static char *control;
104 1.1 lukem
105 1.1 lukem static char *def_tmpdir;
106 1.1 lukem static char *def_urlpre;
107 1.1 lukem
108 1.1 lukem #if defined(__CYGWIN__) || defined(__MINGW32__)
109 1.1 lukem /* Turn off commandline globbing, otherwise you cannot search for
110 1.1 lukem * attribute '*'
111 1.1 lukem */
112 1.1 lukem int _CRT_glob = 0;
113 1.1 lukem #endif
114 1.1 lukem
115 1.1 lukem void
116 1.1 lukem usage( void )
117 1.1 lukem {
118 1.1 lukem fprintf( stderr, _("usage: %s [options] [filter [attributes...]]\nwhere:\n"), prog);
119 1.1 lukem fprintf( stderr, _(" filter\tRFC 4515 compliant LDAP search filter\n"));
120 1.1 lukem fprintf( stderr, _(" attributes\twhitespace-separated list of attribute descriptions\n"));
121 1.1 lukem fprintf( stderr, _(" which may include:\n"));
122 1.1 lukem fprintf( stderr, _(" 1.1 no attributes\n"));
123 1.1 lukem fprintf( stderr, _(" * all user attributes\n"));
124 1.1 lukem fprintf( stderr, _(" + all operational attributes\n"));
125 1.1 lukem
126 1.1 lukem
127 1.1 lukem fprintf( stderr, _("Search options:\n"));
128 1.1 lukem fprintf( stderr, _(" -a deref one of never (default), always, search, or find\n"));
129 1.1 lukem fprintf( stderr, _(" -A retrieve attribute names only (no values)\n"));
130 1.1 lukem fprintf( stderr, _(" -b basedn base dn for search\n"));
131 1.2 christos fprintf( stderr, _(" -c continuous operation mode (do not stop on errors)\n"));
132 1.1 lukem fprintf( stderr, _(" -E [!]<ext>[=<extparam>] search extensions (! indicates criticality)\n"));
133 1.3 christos #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY
134 1.3 christos fprintf( stderr, _(" [!]accountUsability (NetScape Account usability)\n"));
135 1.3 christos #endif
136 1.1 lukem fprintf( stderr, _(" [!]domainScope (domain scope)\n"));
137 1.1 lukem fprintf( stderr, _(" !dontUseCopy (Don't Use Copy)\n"));
138 1.2 christos fprintf( stderr, _(" [!]mv=<filter> (RFC 3876 matched values filter)\n"));
139 1.2 christos fprintf( stderr, _(" [!]pr=<size>[/prompt|noprompt] (RFC 2696 paged results/prompt)\n"));
140 1.3 christos fprintf( stderr, _(" [!]ps=<changetypes>/<changesonly>/<echg> (draft persistent search)\n"));
141 1.2 christos fprintf( stderr, _(" [!]sss=[-]<attr[:OID]>[/[-]<attr[:OID]>...]\n"));
142 1.2 christos fprintf( stderr, _(" (RFC 2891 server side sorting)\n"));
143 1.2 christos fprintf( stderr, _(" [!]subentries[=true|false] (RFC 3672 subentries)\n"));
144 1.2 christos fprintf( stderr, _(" [!]sync=ro[/<cookie>] (RFC 4533 LDAP Sync refreshOnly)\n"));
145 1.2 christos fprintf( stderr, _(" rp[/<cookie>][/<slimit>] (refreshAndPersist)\n"));
146 1.2 christos fprintf( stderr, _(" [!]vlv=<before>/<after>(/<offset>/<count>|:<value>)\n"));
147 1.2 christos fprintf( stderr, _(" (ldapv3-vlv-09 virtual list views)\n"));
148 1.2 christos #ifdef LDAP_CONTROL_X_DEREF
149 1.2 christos fprintf( stderr, _(" [!]deref=derefAttr:attr[,...][;derefAttr:attr[,...][;...]]\n"));
150 1.2 christos #endif
151 1.3 christos #ifdef LDAP_CONTROL_X_DIRSYNC
152 1.3 christos fprintf( stderr, _(" !dirSync=<flags>/<maxAttrCount>[/<cookie>]\n"));
153 1.3 christos fprintf( stderr, _(" (MS AD DirSync)\n"));
154 1.3 christos #endif
155 1.3 christos #ifdef LDAP_CONTROL_X_EXTENDED_DN
156 1.3 christos fprintf( stderr, _(" [!]extendedDn=<flag> (MS AD Extended DN\n"));
157 1.3 christos #endif
158 1.3 christos #ifdef LDAP_CONTROL_X_SHOW_DELETED
159 1.3 christos fprintf( stderr, _(" [!]showDeleted (MS AD Show Deleted)\n"));
160 1.3 christos #endif
161 1.3 christos #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION
162 1.3 christos fprintf( stderr, _(" [!]serverNotif (MS AD Server Notification)\n"));
163 1.3 christos #endif
164 1.3 christos fprintf( stderr, _(" [!]<oid>[=:<value>|::<b64value>] (generic control; no response handling)\n"));
165 1.2 christos fprintf( stderr, _(" -f file read operations from `file'\n"));
166 1.1 lukem fprintf( stderr, _(" -F prefix URL prefix for files (default: %s)\n"), def_urlpre);
167 1.1 lukem fprintf( stderr, _(" -l limit time limit (in seconds, or \"none\" or \"max\") for search\n"));
168 1.1 lukem fprintf( stderr, _(" -L print responses in LDIFv1 format\n"));
169 1.1 lukem fprintf( stderr, _(" -LL print responses in LDIF format without comments\n"));
170 1.1 lukem fprintf( stderr, _(" -LLL print responses in LDIF format without comments\n"));
171 1.1 lukem fprintf( stderr, _(" and version\n"));
172 1.2 christos fprintf( stderr, _(" -M enable Manage DSA IT control (-MM to make critical)\n"));
173 1.2 christos fprintf( stderr, _(" -P version protocol version (default: 3)\n"));
174 1.1 lukem fprintf( stderr, _(" -s scope one of base, one, sub or children (search scope)\n"));
175 1.1 lukem fprintf( stderr, _(" -S attr sort the results by attribute `attr'\n"));
176 1.1 lukem fprintf( stderr, _(" -t write binary values to files in temporary directory\n"));
177 1.1 lukem fprintf( stderr, _(" -tt write all values to files in temporary directory\n"));
178 1.1 lukem fprintf( stderr, _(" -T path write files to directory specified by path (default: %s)\n"), def_tmpdir);
179 1.1 lukem fprintf( stderr, _(" -u include User Friendly entry names in the output\n"));
180 1.1 lukem fprintf( stderr, _(" -z limit size limit (in entries, or \"none\" or \"max\") for search\n"));
181 1.1 lukem tool_common_usage();
182 1.1 lukem exit( EXIT_FAILURE );
183 1.1 lukem }
184 1.1 lukem
185 1.1 lukem static void print_entry LDAP_P((
186 1.1 lukem LDAP *ld,
187 1.1 lukem LDAPMessage *entry,
188 1.1 lukem int attrsonly));
189 1.1 lukem
190 1.1 lukem static void print_reference(
191 1.1 lukem LDAP *ld,
192 1.1 lukem LDAPMessage *reference );
193 1.1 lukem
194 1.1 lukem static void print_extended(
195 1.1 lukem LDAP *ld,
196 1.1 lukem LDAPMessage *extended );
197 1.1 lukem
198 1.3 christos static void print_syncinfo(
199 1.3 christos BerValue *info );
200 1.3 christos
201 1.1 lukem static void print_partial(
202 1.1 lukem LDAP *ld,
203 1.1 lukem LDAPMessage *partial );
204 1.1 lukem
205 1.1 lukem static int print_result(
206 1.1 lukem LDAP *ld,
207 1.1 lukem LDAPMessage *result,
208 1.1 lukem int search );
209 1.1 lukem
210 1.1 lukem static int dosearch LDAP_P((
211 1.1 lukem LDAP *ld,
212 1.1 lukem char *base,
213 1.1 lukem int scope,
214 1.1 lukem char *filtpatt,
215 1.1 lukem char *value,
216 1.1 lukem char **attrs,
217 1.1 lukem int attrsonly,
218 1.1 lukem LDAPControl **sctrls,
219 1.1 lukem LDAPControl **cctrls,
220 1.1 lukem struct timeval *timeout,
221 1.1 lukem int sizelimit ));
222 1.1 lukem
223 1.1 lukem static char *tmpdir = NULL;
224 1.1 lukem static char *urlpre = NULL;
225 1.1 lukem static char *base = NULL;
226 1.1 lukem static char *sortattr = NULL;
227 1.1 lukem static int includeufn, vals2tmp = 0;
228 1.1 lukem
229 1.1 lukem static int subentries = 0, valuesReturnFilter = 0;
230 1.1 lukem static char *vrFilter = NULL;
231 1.1 lukem
232 1.3 christos #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY
233 1.3 christos static int accountUsability = 0;
234 1.3 christos #endif
235 1.3 christos
236 1.1 lukem #ifdef LDAP_CONTROL_DONTUSECOPY
237 1.1 lukem static int dontUseCopy = 0;
238 1.1 lukem #endif
239 1.1 lukem
240 1.1 lukem static int domainScope = 0;
241 1.1 lukem
242 1.2 christos static int sss = 0;
243 1.2 christos static LDAPSortKey **sss_keys = NULL;
244 1.2 christos
245 1.2 christos static int vlv = 0;
246 1.2 christos static LDAPVLVInfo vlvInfo;
247 1.2 christos static struct berval vlvValue;
248 1.2 christos
249 1.1 lukem static int ldapsync = 0;
250 1.1 lukem static struct berval sync_cookie = { 0, NULL };
251 1.1 lukem static int sync_slimit = -1;
252 1.1 lukem
253 1.3 christos static int psearch = 0;
254 1.3 christos static int ps_chgtypes, ps_chgsonly, ps_echg_ctrls;
255 1.3 christos
256 1.1 lukem /* cookie and morePagedResults moved to common.c */
257 1.1 lukem static int pagedResults = 0;
258 1.1 lukem static int pagePrompt = 1;
259 1.1 lukem static ber_int_t pageSize = 0;
260 1.1 lukem static ber_int_t entriesLeft = 0;
261 1.1 lukem static int npagedresponses;
262 1.1 lukem static int npagedentries;
263 1.1 lukem static int npagedreferences;
264 1.1 lukem static int npagedextended;
265 1.1 lukem static int npagedpartial;
266 1.1 lukem
267 1.1 lukem static LDAPControl *c = NULL;
268 1.1 lukem static int nctrls = 0;
269 1.1 lukem static int save_nctrls = 0;
270 1.1 lukem
271 1.2 christos #ifdef LDAP_CONTROL_X_DEREF
272 1.2 christos static int derefcrit;
273 1.2 christos static LDAPDerefSpec *ds;
274 1.2 christos static struct berval derefval;
275 1.2 christos #endif
276 1.2 christos
277 1.3 christos #ifdef LDAP_CONTROL_X_DIRSYNC
278 1.3 christos static int dirSync;
279 1.3 christos static int dirSyncFlags;
280 1.3 christos static int dirSyncMaxAttrCount;
281 1.3 christos static struct berval dirSyncCookie;
282 1.3 christos #endif
283 1.3 christos
284 1.3 christos #ifdef LDAP_CONTROL_X_EXTENDED_DN
285 1.3 christos static int extendedDn;
286 1.3 christos static int extendedDnFlag;
287 1.3 christos #endif
288 1.3 christos
289 1.3 christos #ifdef LDAP_CONTROL_X_SHOW_DELETED
290 1.3 christos static int showDeleted;
291 1.3 christos #endif
292 1.3 christos
293 1.3 christos #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION
294 1.3 christos static int serverNotif;
295 1.3 christos #endif
296 1.3 christos
297 1.1 lukem static int
298 1.1 lukem ctrl_add( void )
299 1.1 lukem {
300 1.1 lukem LDAPControl *tmpc;
301 1.1 lukem
302 1.1 lukem nctrls++;
303 1.1 lukem tmpc = realloc( c, sizeof( LDAPControl ) * nctrls );
304 1.1 lukem if ( tmpc == NULL ) {
305 1.1 lukem nctrls--;
306 1.1 lukem fprintf( stderr,
307 1.1 lukem _("unable to make room for control; out of memory?\n"));
308 1.1 lukem return -1;
309 1.1 lukem }
310 1.1 lukem c = tmpc;
311 1.1 lukem
312 1.1 lukem return 0;
313 1.1 lukem }
314 1.1 lukem
315 1.1 lukem static void
316 1.1 lukem urlize(char *url)
317 1.1 lukem {
318 1.1 lukem char *p;
319 1.1 lukem
320 1.1 lukem if (*LDAP_DIRSEP != '/') {
321 1.1 lukem for (p = url; *p; p++) {
322 1.1 lukem if (*p == *LDAP_DIRSEP)
323 1.1 lukem *p = '/';
324 1.1 lukem }
325 1.1 lukem }
326 1.1 lukem }
327 1.1 lukem
328 1.2 christos static int
329 1.2 christos parse_vlv(char *cvalue)
330 1.2 christos {
331 1.2 christos char *keyp, *key2;
332 1.2 christos int num1, num2;
333 1.2 christos
334 1.2 christos keyp = cvalue;
335 1.2 christos if ( sscanf( keyp, "%d/%d", &num1, &num2 ) != 2 ) {
336 1.2 christos fprintf( stderr,
337 1.2 christos _("VLV control value \"%s\" invalid\n"),
338 1.2 christos cvalue );
339 1.2 christos return -1;
340 1.2 christos }
341 1.2 christos vlvInfo.ldvlv_before_count = num1;
342 1.2 christos vlvInfo.ldvlv_after_count = num2;
343 1.2 christos keyp = strchr( keyp, '/' ) + 1;
344 1.2 christos key2 = strchr( keyp, '/' );
345 1.2 christos if ( key2 ) {
346 1.2 christos keyp = key2 + 1;
347 1.2 christos if ( sscanf( keyp, "%d/%d", &num1, &num2 ) != 2 ) {
348 1.2 christos fprintf( stderr,
349 1.2 christos _("VLV control value \"%s\" invalid\n"),
350 1.2 christos cvalue );
351 1.2 christos return -1;
352 1.2 christos }
353 1.2 christos vlvInfo.ldvlv_offset = num1;
354 1.2 christos vlvInfo.ldvlv_count = num2;
355 1.2 christos vlvInfo.ldvlv_attrvalue = NULL;
356 1.2 christos } else {
357 1.2 christos key2 = strchr( keyp, ':' );
358 1.2 christos if ( !key2 ) {
359 1.2 christos fprintf( stderr,
360 1.2 christos _("VLV control value \"%s\" invalid\n"),
361 1.2 christos cvalue );
362 1.2 christos return -1;
363 1.2 christos }
364 1.2 christos ber_str2bv( key2+1, 0, 0, &vlvValue );
365 1.2 christos vlvInfo.ldvlv_attrvalue = &vlvValue;
366 1.2 christos }
367 1.2 christos return 0;
368 1.2 christos }
369 1.1 lukem
370 1.1 lukem const char options[] = "a:Ab:cE:F:l:Ls:S:tT:uz:"
371 1.2 christos "Cd:D:e:f:h:H:IMnNO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
372 1.1 lukem
373 1.1 lukem int
374 1.1 lukem handle_private_option( int i )
375 1.1 lukem {
376 1.1 lukem int crit, ival;
377 1.1 lukem char *cvalue, *next;
378 1.1 lukem switch ( i ) {
379 1.1 lukem case 'a': /* set alias deref option */
380 1.1 lukem if ( strcasecmp( optarg, "never" ) == 0 ) {
381 1.1 lukem deref = LDAP_DEREF_NEVER;
382 1.1 lukem } else if ( strncasecmp( optarg, "search", sizeof("search")-1 ) == 0 ) {
383 1.1 lukem deref = LDAP_DEREF_SEARCHING;
384 1.1 lukem } else if ( strncasecmp( optarg, "find", sizeof("find")-1 ) == 0 ) {
385 1.1 lukem deref = LDAP_DEREF_FINDING;
386 1.1 lukem } else if ( strcasecmp( optarg, "always" ) == 0 ) {
387 1.1 lukem deref = LDAP_DEREF_ALWAYS;
388 1.1 lukem } else {
389 1.1 lukem fprintf( stderr,
390 1.1 lukem _("alias deref should be never, search, find, or always\n") );
391 1.1 lukem usage();
392 1.1 lukem }
393 1.1 lukem break;
394 1.1 lukem case 'A': /* retrieve attribute names only -- no values */
395 1.1 lukem ++attrsonly;
396 1.1 lukem break;
397 1.1 lukem case 'b': /* search base */
398 1.3 christos base = optarg;
399 1.1 lukem break;
400 1.1 lukem case 'E': /* search extensions */
401 1.1 lukem if( protocol == LDAP_VERSION2 ) {
402 1.1 lukem fprintf( stderr, _("%s: -E incompatible with LDAPv%d\n"),
403 1.1 lukem prog, protocol );
404 1.1 lukem exit( EXIT_FAILURE );
405 1.1 lukem }
406 1.1 lukem
407 1.1 lukem /* should be extended to support comma separated list of
408 1.1 lukem * [!]key[=value] parameters, e.g. -E !foo,bar=567
409 1.1 lukem */
410 1.1 lukem
411 1.1 lukem crit = 0;
412 1.1 lukem cvalue = NULL;
413 1.3 christos while ( optarg[0] == '!' ) {
414 1.3 christos crit++;
415 1.1 lukem optarg++;
416 1.1 lukem }
417 1.1 lukem
418 1.3 christos control = optarg;
419 1.1 lukem if ( (cvalue = strchr( control, '=' )) != NULL ) {
420 1.1 lukem *cvalue++ = '\0';
421 1.1 lukem }
422 1.1 lukem
423 1.1 lukem if ( strcasecmp( control, "mv" ) == 0 ) {
424 1.1 lukem /* ValuesReturnFilter control */
425 1.1 lukem if( valuesReturnFilter ) {
426 1.1 lukem fprintf( stderr,
427 1.1 lukem _("ValuesReturnFilter previously specified\n"));
428 1.1 lukem exit( EXIT_FAILURE );
429 1.1 lukem }
430 1.1 lukem valuesReturnFilter= 1 + crit;
431 1.1 lukem
432 1.1 lukem if ( cvalue == NULL ) {
433 1.1 lukem fprintf( stderr,
434 1.1 lukem _("missing filter in ValuesReturnFilter control\n"));
435 1.1 lukem exit( EXIT_FAILURE );
436 1.1 lukem }
437 1.1 lukem
438 1.1 lukem vrFilter = cvalue;
439 1.1 lukem protocol = LDAP_VERSION3;
440 1.1 lukem
441 1.1 lukem } else if ( strcasecmp( control, "pr" ) == 0 ) {
442 1.1 lukem int num, tmp;
443 1.1 lukem /* PagedResults control */
444 1.1 lukem if ( pagedResults != 0 ) {
445 1.1 lukem fprintf( stderr,
446 1.1 lukem _("PagedResultsControl previously specified\n") );
447 1.1 lukem exit( EXIT_FAILURE );
448 1.1 lukem }
449 1.2 christos if ( vlv != 0 ) {
450 1.2 christos fprintf( stderr,
451 1.2 christos _("PagedResultsControl incompatible with VLV\n") );
452 1.2 christos exit( EXIT_FAILURE );
453 1.2 christos }
454 1.1 lukem
455 1.1 lukem if( cvalue != NULL ) {
456 1.1 lukem char *promptp;
457 1.1 lukem
458 1.1 lukem promptp = strchr( cvalue, '/' );
459 1.1 lukem if ( promptp != NULL ) {
460 1.1 lukem *promptp++ = '\0';
461 1.1 lukem if ( strcasecmp( promptp, "prompt" ) == 0 ) {
462 1.1 lukem pagePrompt = 1;
463 1.1 lukem } else if ( strcasecmp( promptp, "noprompt" ) == 0) {
464 1.1 lukem pagePrompt = 0;
465 1.1 lukem } else {
466 1.1 lukem fprintf( stderr,
467 1.1 lukem _("Invalid value for PagedResultsControl,"
468 1.1 lukem " %s/%s.\n"), cvalue, promptp );
469 1.1 lukem exit( EXIT_FAILURE );
470 1.1 lukem }
471 1.1 lukem }
472 1.1 lukem num = sscanf( cvalue, "%d", &tmp );
473 1.1 lukem if ( num != 1 ) {
474 1.1 lukem fprintf( stderr,
475 1.1 lukem _("Invalid value for PagedResultsControl, %s.\n"),
476 1.1 lukem cvalue );
477 1.1 lukem exit( EXIT_FAILURE );
478 1.1 lukem }
479 1.1 lukem } else {
480 1.1 lukem fprintf(stderr, _("Invalid value for PagedResultsControl.\n"));
481 1.1 lukem exit( EXIT_FAILURE );
482 1.1 lukem }
483 1.1 lukem pageSize = (ber_int_t) tmp;
484 1.1 lukem pagedResults = 1 + crit;
485 1.1 lukem
486 1.3 christos } else if ( strcasecmp( control, "ps" ) == 0 ) {
487 1.3 christos int num;
488 1.3 christos /* PersistentSearch control */
489 1.3 christos if ( psearch != 0 ) {
490 1.3 christos fprintf( stderr,
491 1.3 christos _("PersistentSearch previously specified\n") );
492 1.3 christos exit( EXIT_FAILURE );
493 1.3 christos }
494 1.3 christos if( cvalue != NULL ) {
495 1.3 christos num = sscanf( cvalue, "%i/%d/%d", &ps_chgtypes, &ps_chgsonly, &ps_echg_ctrls );
496 1.3 christos if ( num != 3 ) {
497 1.3 christos fprintf( stderr,
498 1.3 christos _("Invalid value for PersistentSearch, %s.\n"),
499 1.3 christos cvalue );
500 1.3 christos exit( EXIT_FAILURE );
501 1.3 christos }
502 1.3 christos } else {
503 1.3 christos fprintf(stderr, _("Invalid value for PersistentSearch.\n"));
504 1.3 christos exit( EXIT_FAILURE );
505 1.3 christos }
506 1.3 christos psearch = 1 + crit;
507 1.3 christos
508 1.1 lukem #ifdef LDAP_CONTROL_DONTUSECOPY
509 1.1 lukem } else if ( strcasecmp( control, "dontUseCopy" ) == 0 ) {
510 1.1 lukem if( dontUseCopy ) {
511 1.1 lukem fprintf( stderr,
512 1.1 lukem _("dontUseCopy control previously specified\n"));
513 1.1 lukem exit( EXIT_FAILURE );
514 1.1 lukem }
515 1.1 lukem if( cvalue != NULL ) {
516 1.1 lukem fprintf( stderr,
517 1.1 lukem _("dontUseCopy: no control value expected\n") );
518 1.1 lukem usage();
519 1.1 lukem }
520 1.1 lukem if( !crit ) {
521 1.1 lukem fprintf( stderr,
522 1.1 lukem _("dontUseCopy: critical flag required\n") );
523 1.1 lukem usage();
524 1.1 lukem }
525 1.1 lukem
526 1.1 lukem dontUseCopy = 1 + crit;
527 1.1 lukem #endif
528 1.1 lukem } else if ( strcasecmp( control, "domainScope" ) == 0 ) {
529 1.1 lukem if( domainScope ) {
530 1.1 lukem fprintf( stderr,
531 1.1 lukem _("domainScope control previously specified\n"));
532 1.1 lukem exit( EXIT_FAILURE );
533 1.1 lukem }
534 1.1 lukem if( cvalue != NULL ) {
535 1.1 lukem fprintf( stderr,
536 1.1 lukem _("domainScope: no control value expected\n") );
537 1.1 lukem usage();
538 1.1 lukem }
539 1.1 lukem
540 1.1 lukem domainScope = 1 + crit;
541 1.1 lukem
542 1.2 christos } else if ( strcasecmp( control, "sss" ) == 0 ) {
543 1.2 christos char *keyp;
544 1.2 christos if( sss ) {
545 1.2 christos fprintf( stderr,
546 1.2 christos _("server side sorting control previously specified\n"));
547 1.2 christos exit( EXIT_FAILURE );
548 1.2 christos }
549 1.2 christos if( cvalue == NULL ) {
550 1.2 christos fprintf( stderr,
551 1.2 christos _("missing specification of sss control\n") );
552 1.2 christos exit( EXIT_FAILURE );
553 1.2 christos }
554 1.2 christos keyp = cvalue;
555 1.2 christos while ( ( keyp = strchr(keyp, '/') ) != NULL ) {
556 1.2 christos *keyp++ = ' ';
557 1.2 christos }
558 1.2 christos if ( ldap_create_sort_keylist( &sss_keys, cvalue )) {
559 1.2 christos fprintf( stderr,
560 1.2 christos _("server side sorting control value \"%s\" invalid\n"),
561 1.2 christos cvalue );
562 1.2 christos exit( EXIT_FAILURE );
563 1.2 christos }
564 1.2 christos
565 1.2 christos sss = 1 + crit;
566 1.2 christos
567 1.1 lukem } else if ( strcasecmp( control, "subentries" ) == 0 ) {
568 1.1 lukem if( subentries ) {
569 1.1 lukem fprintf( stderr,
570 1.1 lukem _("subentries control previously specified\n"));
571 1.1 lukem exit( EXIT_FAILURE );
572 1.1 lukem }
573 1.1 lukem if( cvalue == NULL || strcasecmp( cvalue, "true") == 0 ) {
574 1.1 lukem subentries = 2;
575 1.1 lukem } else if ( strcasecmp( cvalue, "false") == 0 ) {
576 1.1 lukem subentries = 1;
577 1.1 lukem } else {
578 1.1 lukem fprintf( stderr,
579 1.1 lukem _("subentries control value \"%s\" invalid\n"),
580 1.1 lukem cvalue );
581 1.1 lukem exit( EXIT_FAILURE );
582 1.1 lukem }
583 1.1 lukem if( crit ) subentries *= -1;
584 1.1 lukem
585 1.1 lukem } else if ( strcasecmp( control, "sync" ) == 0 ) {
586 1.1 lukem char *cookiep;
587 1.1 lukem char *slimitp;
588 1.1 lukem if ( ldapsync ) {
589 1.1 lukem fprintf( stderr, _("sync control previously specified\n") );
590 1.1 lukem exit( EXIT_FAILURE );
591 1.1 lukem }
592 1.1 lukem if ( cvalue == NULL ) {
593 1.1 lukem fprintf( stderr, _("missing specification of sync control\n"));
594 1.1 lukem exit( EXIT_FAILURE );
595 1.1 lukem }
596 1.1 lukem if ( strncasecmp( cvalue, "ro", 2 ) == 0 ) {
597 1.1 lukem ldapsync = LDAP_SYNC_REFRESH_ONLY;
598 1.1 lukem cookiep = strchr( cvalue, '/' );
599 1.1 lukem if ( cookiep != NULL ) {
600 1.1 lukem cookiep++;
601 1.1 lukem if ( *cookiep != '\0' ) {
602 1.1 lukem ber_str2bv( cookiep, 0, 0, &sync_cookie );
603 1.1 lukem }
604 1.1 lukem }
605 1.1 lukem } else if ( strncasecmp( cvalue, "rp", 2 ) == 0 ) {
606 1.1 lukem ldapsync = LDAP_SYNC_REFRESH_AND_PERSIST;
607 1.1 lukem cookiep = strchr( cvalue, '/' );
608 1.1 lukem if ( cookiep != NULL ) {
609 1.1 lukem *cookiep++ = '\0';
610 1.1 lukem cvalue = cookiep;
611 1.1 lukem }
612 1.1 lukem slimitp = strchr( cvalue, '/' );
613 1.1 lukem if ( slimitp != NULL ) {
614 1.1 lukem *slimitp++ = '\0';
615 1.1 lukem }
616 1.1 lukem if ( cookiep != NULL && *cookiep != '\0' )
617 1.1 lukem ber_str2bv( cookiep, 0, 0, &sync_cookie );
618 1.1 lukem if ( slimitp != NULL && *slimitp != '\0' ) {
619 1.1 lukem ival = strtol( slimitp, &next, 10 );
620 1.1 lukem if ( next == NULL || next[0] != '\0' ) {
621 1.1 lukem fprintf( stderr, _("Unable to parse sync control value \"%s\"\n"), slimitp );
622 1.1 lukem exit( EXIT_FAILURE );
623 1.1 lukem }
624 1.1 lukem sync_slimit = ival;
625 1.1 lukem }
626 1.1 lukem } else {
627 1.1 lukem fprintf( stderr, _("sync control value \"%s\" invalid\n"),
628 1.1 lukem cvalue );
629 1.1 lukem exit( EXIT_FAILURE );
630 1.1 lukem }
631 1.1 lukem if ( crit ) ldapsync *= -1;
632 1.1 lukem
633 1.2 christos } else if ( strcasecmp( control, "vlv" ) == 0 ) {
634 1.2 christos if( vlv ) {
635 1.2 christos fprintf( stderr,
636 1.2 christos _("virtual list view control previously specified\n"));
637 1.2 christos exit( EXIT_FAILURE );
638 1.2 christos }
639 1.2 christos if ( pagedResults != 0 ) {
640 1.2 christos fprintf( stderr,
641 1.2 christos _("PagedResultsControl incompatible with VLV\n") );
642 1.2 christos exit( EXIT_FAILURE );
643 1.2 christos }
644 1.2 christos if( cvalue == NULL ) {
645 1.2 christos fprintf( stderr,
646 1.2 christos _("missing specification of vlv control\n") );
647 1.2 christos exit( EXIT_FAILURE );
648 1.2 christos }
649 1.2 christos if ( parse_vlv( cvalue ))
650 1.2 christos exit( EXIT_FAILURE );
651 1.2 christos
652 1.2 christos vlv = 1 + crit;
653 1.2 christos
654 1.2 christos #ifdef LDAP_CONTROL_X_DEREF
655 1.2 christos } else if ( strcasecmp( control, "deref" ) == 0 ) {
656 1.2 christos int ispecs;
657 1.2 christos char **specs;
658 1.2 christos
659 1.2 christos /* cvalue is something like
660 1.2 christos *
661 1.2 christos * derefAttr:attr[,attr[...]][;derefAttr:attr[,attr[...]]]"
662 1.2 christos */
663 1.2 christos
664 1.2 christos specs = ldap_str2charray( cvalue, ";" );
665 1.2 christos if ( specs == NULL ) {
666 1.2 christos fprintf( stderr, _("deref specs \"%s\" invalid\n"),
667 1.2 christos cvalue );
668 1.2 christos exit( EXIT_FAILURE );
669 1.2 christos }
670 1.2 christos for ( ispecs = 0; specs[ ispecs ] != NULL; ispecs++ )
671 1.2 christos /* count'em */ ;
672 1.2 christos
673 1.2 christos ds = ldap_memcalloc( ispecs + 1, sizeof( LDAPDerefSpec ) );
674 1.2 christos if ( ds == NULL ) {
675 1.2 christos perror( "malloc" );
676 1.2 christos exit( EXIT_FAILURE );
677 1.2 christos }
678 1.2 christos
679 1.2 christos for ( ispecs = 0; specs[ ispecs ] != NULL; ispecs++ ) {
680 1.2 christos char *ptr;
681 1.2 christos
682 1.2 christos ptr = strchr( specs[ ispecs ], ':' );
683 1.2 christos if ( ptr == NULL ) {
684 1.2 christos fprintf( stderr, _("deref specs \"%s\" invalid\n"),
685 1.2 christos cvalue );
686 1.2 christos exit( EXIT_FAILURE );
687 1.2 christos }
688 1.2 christos
689 1.2 christos ds[ ispecs ].derefAttr = specs[ ispecs ];
690 1.2 christos *ptr++ = '\0';
691 1.2 christos ds[ ispecs ].attributes = ldap_str2charray( ptr, "," );
692 1.2 christos }
693 1.2 christos
694 1.2 christos derefcrit = 1 + crit;
695 1.2 christos
696 1.2 christos ldap_memfree( specs );
697 1.2 christos #endif /* LDAP_CONTROL_X_DEREF */
698 1.2 christos
699 1.3 christos #ifdef LDAP_CONTROL_X_DIRSYNC
700 1.3 christos } else if ( strcasecmp( control, "dirSync" ) == 0 ) {
701 1.3 christos char *maxattrp;
702 1.3 christos char *cookiep;
703 1.3 christos int num, tmp;
704 1.3 christos if( dirSync ) {
705 1.3 christos fprintf( stderr,
706 1.3 christos _("dirSync control previously specified\n"));
707 1.3 christos exit( EXIT_FAILURE );
708 1.3 christos }
709 1.3 christos if ( cvalue == NULL ) {
710 1.3 christos fprintf( stderr, _("missing specification of dirSync control\n"));
711 1.3 christos exit( EXIT_FAILURE );
712 1.3 christos }
713 1.3 christos if( !crit ) {
714 1.3 christos fprintf( stderr,
715 1.3 christos _("dirSync: critical flag required\n") );
716 1.3 christos usage();
717 1.3 christos }
718 1.3 christos maxattrp = strchr( cvalue, '/' );
719 1.3 christos if ( maxattrp == NULL ) {
720 1.3 christos fprintf( stderr, _("dirSync control value \"%s\" invalid\n"),
721 1.3 christos cvalue );
722 1.3 christos exit( EXIT_FAILURE );
723 1.3 christos }
724 1.3 christos *maxattrp++ = '\0';
725 1.3 christos cookiep = strchr( maxattrp, '/' );
726 1.3 christos if ( cookiep != NULL ) {
727 1.3 christos if ( cookiep[1] != '\0' ) {
728 1.3 christos struct berval type;
729 1.3 christos int freeval;
730 1.3 christos char save1, save2;
731 1.3 christos
732 1.3 christos /* dummy type "x"
733 1.3 christos * to use ldif_parse_line2() */
734 1.3 christos save1 = cookiep[ -1 ];
735 1.3 christos save2 = cookiep[ -2 ];
736 1.3 christos cookiep[ -2 ] = 'x';
737 1.3 christos cookiep[ -1 ] = ':';
738 1.3 christos cookiep[ 0 ] = ':';
739 1.3 christos ldif_parse_line2( &cookiep[ -2 ], &type,
740 1.3 christos &dirSyncCookie, &freeval );
741 1.3 christos cookiep[ -1 ] = save1;
742 1.3 christos cookiep[ -2 ] = save2;
743 1.3 christos }
744 1.3 christos *cookiep = '\0';
745 1.3 christos }
746 1.3 christos num = sscanf( cvalue, "%i", &tmp );
747 1.3 christos if ( num != 1 ) {
748 1.3 christos fprintf( stderr,
749 1.3 christos _("Invalid value for dirSync, %s.\n"),
750 1.3 christos cvalue );
751 1.3 christos exit( EXIT_FAILURE );
752 1.3 christos }
753 1.3 christos dirSyncFlags = tmp;
754 1.3 christos
755 1.3 christos num = sscanf( maxattrp, "%d", &tmp );
756 1.3 christos if ( num != 1 ) {
757 1.3 christos fprintf( stderr,
758 1.3 christos _("Invalid value for dirSync, %s.\n"),
759 1.3 christos maxattrp );
760 1.3 christos exit( EXIT_FAILURE );
761 1.3 christos }
762 1.3 christos dirSyncMaxAttrCount = tmp;
763 1.3 christos
764 1.3 christos dirSync = 1 + crit;
765 1.3 christos #endif /* LDAP_CONTROL_X_DIRSYNC */
766 1.3 christos
767 1.3 christos #ifdef LDAP_CONTROL_X_EXTENDED_DN
768 1.3 christos } else if ( strcasecmp( control, "extendedDn" ) == 0 ) {
769 1.3 christos int num, tmp;
770 1.3 christos if( extendedDn ) {
771 1.3 christos fprintf( stderr,
772 1.3 christos _("extendedDn control previously specified\n"));
773 1.3 christos exit( EXIT_FAILURE );
774 1.3 christos }
775 1.3 christos if ( cvalue == NULL ) {
776 1.3 christos fprintf( stderr, _("missing specification of extendedDn control\n"));
777 1.3 christos exit( EXIT_FAILURE );
778 1.3 christos }
779 1.3 christos num = sscanf( cvalue, "%d", &tmp );
780 1.3 christos if ( num != 1 ) {
781 1.3 christos fprintf( stderr,
782 1.3 christos _("Invalid value for extendedDn, %s.\n"),
783 1.3 christos cvalue );
784 1.3 christos exit( EXIT_FAILURE );
785 1.3 christos }
786 1.3 christos
787 1.3 christos extendedDnFlag = tmp;
788 1.3 christos extendedDn = 1 + crit;
789 1.3 christos #endif /* LDAP_CONTROL_X_EXTENDED_DN */
790 1.3 christos
791 1.3 christos #ifdef LDAP_CONTROL_X_SHOW_DELETED
792 1.3 christos } else if ( strcasecmp( control, "showDeleted" ) == 0 ) {
793 1.3 christos if( showDeleted ) {
794 1.3 christos fprintf( stderr,
795 1.3 christos _("showDeleted control previously specified\n"));
796 1.3 christos exit( EXIT_FAILURE );
797 1.3 christos }
798 1.3 christos if ( cvalue != NULL ) {
799 1.3 christos fprintf( stderr,
800 1.3 christos _("showDeleted: no control value expected\n") );
801 1.3 christos usage();
802 1.3 christos }
803 1.3 christos
804 1.3 christos showDeleted = 1 + crit;
805 1.3 christos #endif /* LDAP_CONTROL_X_SHOW_DELETED */
806 1.3 christos
807 1.3 christos #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION
808 1.3 christos } else if ( strcasecmp( control, "serverNotif" ) == 0 ) {
809 1.3 christos if( serverNotif ) {
810 1.3 christos fprintf( stderr,
811 1.3 christos _("serverNotif control previously specified\n"));
812 1.3 christos exit( EXIT_FAILURE );
813 1.3 christos }
814 1.3 christos if ( cvalue != NULL ) {
815 1.3 christos fprintf( stderr,
816 1.3 christos _("serverNotif: no control value expected\n") );
817 1.3 christos usage();
818 1.3 christos }
819 1.3 christos
820 1.3 christos serverNotif = 1 + crit;
821 1.3 christos #endif /* LDAP_CONTROL_X_SERVER_NOTIFICATION */
822 1.3 christos
823 1.3 christos #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY
824 1.3 christos } else if ( strcasecmp( control, "accountUsability" ) == 0 ) {
825 1.3 christos if( accountUsability ) {
826 1.3 christos fprintf( stderr,
827 1.3 christos _("accountUsability control previously specified\n"));
828 1.3 christos exit( EXIT_FAILURE );
829 1.3 christos }
830 1.3 christos if( cvalue != NULL ) {
831 1.3 christos fprintf( stderr,
832 1.3 christos _("accountUsability: no control value expected\n") );
833 1.3 christos usage();
834 1.3 christos }
835 1.3 christos
836 1.3 christos accountUsability = 1 + crit;
837 1.3 christos #endif /* LDAP_CONTROL_X_ACCOUNT_USABILITY */
838 1.3 christos
839 1.1 lukem } else if ( tool_is_oid( control ) ) {
840 1.3 christos if ( c != NULL ) {
841 1.3 christos int i;
842 1.3 christos for ( i = 0; i < nctrls; i++ ) {
843 1.3 christos if ( strcmp( control, c[ i ].ldctl_oid ) == 0 ) {
844 1.3 christos fprintf( stderr, "%s control previously specified\n", control );
845 1.3 christos exit( EXIT_FAILURE );
846 1.3 christos }
847 1.3 christos }
848 1.3 christos }
849 1.3 christos
850 1.1 lukem if ( ctrl_add() ) {
851 1.1 lukem exit( EXIT_FAILURE );
852 1.1 lukem }
853 1.1 lukem
854 1.1 lukem /* OID */
855 1.1 lukem c[ nctrls - 1 ].ldctl_oid = control;
856 1.1 lukem
857 1.1 lukem /* value */
858 1.1 lukem if ( cvalue == NULL ) {
859 1.1 lukem c[ nctrls - 1 ].ldctl_value.bv_val = NULL;
860 1.1 lukem c[ nctrls - 1 ].ldctl_value.bv_len = 0;
861 1.1 lukem
862 1.1 lukem } else if ( cvalue[ 0 ] == ':' ) {
863 1.2 christos struct berval type;
864 1.2 christos struct berval value;
865 1.2 christos int freeval;
866 1.2 christos char save_c;
867 1.1 lukem
868 1.1 lukem cvalue++;
869 1.1 lukem
870 1.1 lukem /* dummy type "x"
871 1.1 lukem * to use ldif_parse_line2() */
872 1.2 christos save_c = cvalue[ -2 ];
873 1.1 lukem cvalue[ -2 ] = 'x';
874 1.1 lukem ldif_parse_line2( &cvalue[ -2 ], &type,
875 1.1 lukem &value, &freeval );
876 1.2 christos cvalue[ -2 ] = save_c;
877 1.1 lukem
878 1.1 lukem if ( freeval ) {
879 1.1 lukem c[ nctrls - 1 ].ldctl_value = value;
880 1.1 lukem
881 1.1 lukem } else {
882 1.1 lukem ber_dupbv( &c[ nctrls - 1 ].ldctl_value, &value );
883 1.1 lukem }
884 1.2 christos
885 1.2 christos } else {
886 1.2 christos fprintf( stderr, "unable to parse %s control value\n", control );
887 1.2 christos exit( EXIT_FAILURE );
888 1.2 christos
889 1.1 lukem }
890 1.1 lukem
891 1.1 lukem /* criticality */
892 1.1 lukem c[ nctrls - 1 ].ldctl_iscritical = crit;
893 1.1 lukem
894 1.1 lukem } else {
895 1.1 lukem fprintf( stderr, _("Invalid search extension name: %s\n"),
896 1.1 lukem control );
897 1.1 lukem usage();
898 1.1 lukem }
899 1.1 lukem break;
900 1.1 lukem case 'F': /* uri prefix */
901 1.1 lukem if( urlpre ) free( urlpre );
902 1.3 christos urlpre = optarg;
903 1.1 lukem break;
904 1.1 lukem case 'l': /* time limit */
905 1.1 lukem if ( strcasecmp( optarg, "none" ) == 0 ) {
906 1.1 lukem timelimit = 0;
907 1.1 lukem
908 1.1 lukem } else if ( strcasecmp( optarg, "max" ) == 0 ) {
909 1.1 lukem timelimit = LDAP_MAXINT;
910 1.1 lukem
911 1.1 lukem } else {
912 1.1 lukem ival = strtol( optarg, &next, 10 );
913 1.1 lukem if ( next == NULL || next[0] != '\0' ) {
914 1.1 lukem fprintf( stderr,
915 1.1 lukem _("Unable to parse time limit \"%s\"\n"), optarg );
916 1.1 lukem exit( EXIT_FAILURE );
917 1.1 lukem }
918 1.1 lukem timelimit = ival;
919 1.1 lukem }
920 1.1 lukem if( timelimit < 0 || timelimit > LDAP_MAXINT ) {
921 1.1 lukem fprintf( stderr, _("%s: invalid timelimit (%d) specified\n"),
922 1.1 lukem prog, timelimit );
923 1.1 lukem exit( EXIT_FAILURE );
924 1.1 lukem }
925 1.1 lukem break;
926 1.1 lukem case 'L': /* print entries in LDIF format */
927 1.1 lukem ++ldif;
928 1.1 lukem break;
929 1.1 lukem case 's': /* search scope */
930 1.1 lukem if ( strncasecmp( optarg, "base", sizeof("base")-1 ) == 0 ) {
931 1.1 lukem scope = LDAP_SCOPE_BASE;
932 1.1 lukem } else if ( strncasecmp( optarg, "one", sizeof("one")-1 ) == 0 ) {
933 1.1 lukem scope = LDAP_SCOPE_ONELEVEL;
934 1.1 lukem } else if (( strcasecmp( optarg, "subordinate" ) == 0 )
935 1.1 lukem || ( strcasecmp( optarg, "children" ) == 0 ))
936 1.1 lukem {
937 1.1 lukem scope = LDAP_SCOPE_SUBORDINATE;
938 1.1 lukem } else if ( strncasecmp( optarg, "sub", sizeof("sub")-1 ) == 0 ) {
939 1.1 lukem scope = LDAP_SCOPE_SUBTREE;
940 1.1 lukem } else {
941 1.1 lukem fprintf( stderr, _("scope should be base, one, or sub\n") );
942 1.1 lukem usage();
943 1.1 lukem }
944 1.1 lukem break;
945 1.1 lukem case 'S': /* sort attribute */
946 1.3 christos sortattr = optarg;
947 1.1 lukem break;
948 1.1 lukem case 't': /* write attribute values to TMPDIR files */
949 1.1 lukem ++vals2tmp;
950 1.1 lukem break;
951 1.1 lukem case 'T': /* tmpdir */
952 1.1 lukem if( tmpdir ) free( tmpdir );
953 1.3 christos tmpdir = optarg;
954 1.1 lukem break;
955 1.1 lukem case 'u': /* include UFN */
956 1.1 lukem ++includeufn;
957 1.1 lukem break;
958 1.1 lukem case 'z': /* size limit */
959 1.1 lukem if ( strcasecmp( optarg, "none" ) == 0 ) {
960 1.1 lukem sizelimit = 0;
961 1.1 lukem
962 1.1 lukem } else if ( strcasecmp( optarg, "max" ) == 0 ) {
963 1.1 lukem sizelimit = LDAP_MAXINT;
964 1.1 lukem
965 1.1 lukem } else {
966 1.1 lukem ival = strtol( optarg, &next, 10 );
967 1.1 lukem if ( next == NULL || next[0] != '\0' ) {
968 1.1 lukem fprintf( stderr,
969 1.1 lukem _("Unable to parse size limit \"%s\"\n"), optarg );
970 1.1 lukem exit( EXIT_FAILURE );
971 1.1 lukem }
972 1.1 lukem sizelimit = ival;
973 1.1 lukem }
974 1.1 lukem if( sizelimit < 0 || sizelimit > LDAP_MAXINT ) {
975 1.1 lukem fprintf( stderr, _("%s: invalid sizelimit (%d) specified\n"),
976 1.1 lukem prog, sizelimit );
977 1.1 lukem exit( EXIT_FAILURE );
978 1.1 lukem }
979 1.1 lukem break;
980 1.1 lukem default:
981 1.1 lukem return 0;
982 1.1 lukem }
983 1.1 lukem return 1;
984 1.1 lukem }
985 1.1 lukem
986 1.1 lukem
987 1.1 lukem static void
988 1.1 lukem private_conn_setup( LDAP *ld )
989 1.1 lukem {
990 1.1 lukem if (deref != -1 &&
991 1.1 lukem ldap_set_option( ld, LDAP_OPT_DEREF, (void *) &deref )
992 1.1 lukem != LDAP_OPT_SUCCESS )
993 1.1 lukem {
994 1.1 lukem fprintf( stderr, _("Could not set LDAP_OPT_DEREF %d\n"), deref );
995 1.2 christos tool_exit( ld, EXIT_FAILURE );
996 1.1 lukem }
997 1.1 lukem }
998 1.1 lukem
999 1.1 lukem int
1000 1.1 lukem main( int argc, char **argv )
1001 1.1 lukem {
1002 1.1 lukem char *filtpattern, **attrs = NULL, line[BUFSIZ];
1003 1.1 lukem FILE *fp = NULL;
1004 1.1 lukem int rc, rc1, i, first;
1005 1.1 lukem LDAP *ld = NULL;
1006 1.1 lukem BerElement *seber = NULL, *vrber = NULL;
1007 1.1 lukem
1008 1.1 lukem BerElement *syncber = NULL;
1009 1.1 lukem struct berval *syncbvalp = NULL;
1010 1.1 lukem int err;
1011 1.1 lukem
1012 1.1 lukem tool_init( TOOL_SEARCH );
1013 1.1 lukem
1014 1.1 lukem npagedresponses = npagedentries = npagedreferences =
1015 1.1 lukem npagedextended = npagedpartial = 0;
1016 1.1 lukem
1017 1.1 lukem prog = lutil_progname( "ldapsearch", argc, argv );
1018 1.1 lukem
1019 1.1 lukem if((def_tmpdir = getenv("TMPDIR")) == NULL &&
1020 1.1 lukem (def_tmpdir = getenv("TMP")) == NULL &&
1021 1.1 lukem (def_tmpdir = getenv("TEMP")) == NULL )
1022 1.1 lukem {
1023 1.1 lukem def_tmpdir = LDAP_TMPDIR;
1024 1.1 lukem }
1025 1.1 lukem
1026 1.1 lukem if ( !*def_tmpdir )
1027 1.1 lukem def_tmpdir = LDAP_TMPDIR;
1028 1.1 lukem
1029 1.1 lukem def_urlpre = malloc( sizeof("file:////") + strlen(def_tmpdir) );
1030 1.1 lukem
1031 1.1 lukem if( def_urlpre == NULL ) {
1032 1.1 lukem perror( "malloc" );
1033 1.1 lukem return EXIT_FAILURE;
1034 1.1 lukem }
1035 1.1 lukem
1036 1.1 lukem sprintf( def_urlpre, "file:///%s/",
1037 1.1 lukem def_tmpdir[0] == *LDAP_DIRSEP ? &def_tmpdir[1] : def_tmpdir );
1038 1.1 lukem
1039 1.1 lukem urlize( def_urlpre );
1040 1.1 lukem
1041 1.1 lukem tool_args( argc, argv );
1042 1.1 lukem
1043 1.2 christos if ( vlv && !sss ) {
1044 1.2 christos fprintf( stderr,
1045 1.2 christos _("VLV control requires server side sort control\n" ));
1046 1.2 christos return EXIT_FAILURE;
1047 1.2 christos }
1048 1.2 christos
1049 1.1 lukem if (( argc - optind < 1 ) ||
1050 1.1 lukem ( *argv[optind] != '(' /*')'*/ &&
1051 1.1 lukem ( strchr( argv[optind], '=' ) == NULL ) ) )
1052 1.1 lukem {
1053 1.1 lukem filtpattern = "(objectclass=*)";
1054 1.1 lukem } else {
1055 1.1 lukem filtpattern = argv[optind++];
1056 1.1 lukem }
1057 1.1 lukem
1058 1.1 lukem if ( argv[optind] != NULL ) {
1059 1.1 lukem attrs = &argv[optind];
1060 1.1 lukem }
1061 1.1 lukem
1062 1.1 lukem if ( infile != NULL ) {
1063 1.1 lukem int percent = 0;
1064 1.1 lukem
1065 1.1 lukem if ( infile[0] == '-' && infile[1] == '\0' ) {
1066 1.1 lukem fp = stdin;
1067 1.1 lukem } else if (( fp = fopen( infile, "r" )) == NULL ) {
1068 1.1 lukem perror( infile );
1069 1.1 lukem return EXIT_FAILURE;
1070 1.1 lukem }
1071 1.1 lukem
1072 1.1 lukem for( i=0 ; filtpattern[i] ; i++ ) {
1073 1.1 lukem if( filtpattern[i] == '%' ) {
1074 1.1 lukem if( percent ) {
1075 1.1 lukem fprintf( stderr, _("Bad filter pattern \"%s\"\n"),
1076 1.1 lukem filtpattern );
1077 1.1 lukem return EXIT_FAILURE;
1078 1.1 lukem }
1079 1.1 lukem
1080 1.1 lukem percent++;
1081 1.1 lukem
1082 1.1 lukem if( filtpattern[i+1] != 's' ) {
1083 1.1 lukem fprintf( stderr, _("Bad filter pattern \"%s\"\n"),
1084 1.1 lukem filtpattern );
1085 1.1 lukem return EXIT_FAILURE;
1086 1.1 lukem }
1087 1.1 lukem }
1088 1.1 lukem }
1089 1.1 lukem }
1090 1.1 lukem
1091 1.1 lukem if ( tmpdir == NULL ) {
1092 1.1 lukem tmpdir = def_tmpdir;
1093 1.1 lukem
1094 1.1 lukem if ( urlpre == NULL )
1095 1.1 lukem urlpre = def_urlpre;
1096 1.1 lukem }
1097 1.1 lukem
1098 1.1 lukem if( urlpre == NULL ) {
1099 1.1 lukem urlpre = malloc( sizeof("file:////") + strlen(tmpdir) );
1100 1.1 lukem
1101 1.1 lukem if( urlpre == NULL ) {
1102 1.1 lukem perror( "malloc" );
1103 1.1 lukem return EXIT_FAILURE;
1104 1.1 lukem }
1105 1.1 lukem
1106 1.1 lukem sprintf( urlpre, "file:///%s/",
1107 1.1 lukem tmpdir[0] == *LDAP_DIRSEP ? &tmpdir[1] : tmpdir );
1108 1.1 lukem
1109 1.1 lukem urlize( urlpre );
1110 1.1 lukem }
1111 1.1 lukem
1112 1.1 lukem if ( debug )
1113 1.1 lukem ldif_debug = debug;
1114 1.1 lukem
1115 1.1 lukem ld = tool_conn_setup( 0, &private_conn_setup );
1116 1.1 lukem
1117 1.1 lukem tool_bind( ld );
1118 1.1 lukem
1119 1.1 lukem getNextPage:
1120 1.2 christos /* fp may have been closed, need to reopen if code jumps
1121 1.2 christos * back here to getNextPage.
1122 1.2 christos */
1123 1.2 christos if ( !fp && infile ) {
1124 1.2 christos if (( fp = fopen( infile, "r" )) == NULL ) {
1125 1.2 christos perror( infile );
1126 1.2 christos tool_exit( ld, EXIT_FAILURE );
1127 1.2 christos }
1128 1.2 christos }
1129 1.1 lukem save_nctrls = nctrls;
1130 1.1 lukem i = nctrls;
1131 1.1 lukem if ( nctrls > 0
1132 1.3 christos #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY
1133 1.3 christos || accountUsability
1134 1.3 christos #endif
1135 1.1 lukem #ifdef LDAP_CONTROL_DONTUSECOPY
1136 1.1 lukem || dontUseCopy
1137 1.1 lukem #endif
1138 1.2 christos #ifdef LDAP_CONTROL_X_DEREF
1139 1.2 christos || derefcrit
1140 1.2 christos #endif
1141 1.3 christos #ifdef LDAP_CONTROL_X_DIRSYNC
1142 1.3 christos || dirSync
1143 1.3 christos #endif
1144 1.3 christos #ifdef LDAP_CONTROL_X_EXTENDED_DN
1145 1.3 christos || extendedDn
1146 1.3 christos #endif
1147 1.3 christos #ifdef LDAP_CONTROL_X_SHOW_DELETED
1148 1.3 christos || showDeleted
1149 1.3 christos #endif
1150 1.3 christos #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION
1151 1.3 christos || serverNotif
1152 1.3 christos #endif
1153 1.1 lukem || domainScope
1154 1.1 lukem || pagedResults
1155 1.3 christos || psearch
1156 1.1 lukem || ldapsync
1157 1.2 christos || sss
1158 1.1 lukem || subentries
1159 1.2 christos || valuesReturnFilter
1160 1.2 christos || vlv )
1161 1.1 lukem {
1162 1.1 lukem
1163 1.3 christos #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY
1164 1.3 christos if ( accountUsability ) {
1165 1.3 christos if ( ctrl_add() ) {
1166 1.3 christos tool_exit( ld, EXIT_FAILURE );
1167 1.3 christos }
1168 1.3 christos
1169 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_X_ACCOUNT_USABILITY;
1170 1.3 christos c[i].ldctl_value.bv_val = NULL;
1171 1.3 christos c[i].ldctl_value.bv_len = 0;
1172 1.3 christos c[i].ldctl_iscritical = accountUsability == 2;
1173 1.3 christos i++;
1174 1.3 christos }
1175 1.3 christos #endif
1176 1.3 christos
1177 1.1 lukem #ifdef LDAP_CONTROL_DONTUSECOPY
1178 1.1 lukem if ( dontUseCopy ) {
1179 1.1 lukem if ( ctrl_add() ) {
1180 1.2 christos tool_exit( ld, EXIT_FAILURE );
1181 1.1 lukem }
1182 1.1 lukem
1183 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_DONTUSECOPY;
1184 1.1 lukem c[i].ldctl_value.bv_val = NULL;
1185 1.1 lukem c[i].ldctl_value.bv_len = 0;
1186 1.3 christos c[i].ldctl_iscritical = dontUseCopy == 2;
1187 1.1 lukem i++;
1188 1.1 lukem }
1189 1.1 lukem #endif
1190 1.1 lukem
1191 1.1 lukem if ( domainScope ) {
1192 1.1 lukem if ( ctrl_add() ) {
1193 1.2 christos tool_exit( ld, EXIT_FAILURE );
1194 1.1 lukem }
1195 1.1 lukem
1196 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_X_DOMAIN_SCOPE;
1197 1.1 lukem c[i].ldctl_value.bv_val = NULL;
1198 1.1 lukem c[i].ldctl_value.bv_len = 0;
1199 1.1 lukem c[i].ldctl_iscritical = domainScope > 1;
1200 1.1 lukem i++;
1201 1.1 lukem }
1202 1.1 lukem
1203 1.1 lukem if ( subentries ) {
1204 1.1 lukem if ( ctrl_add() ) {
1205 1.2 christos tool_exit( ld, EXIT_FAILURE );
1206 1.1 lukem }
1207 1.1 lukem
1208 1.1 lukem if (( seber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
1209 1.2 christos tool_exit( ld, EXIT_FAILURE );
1210 1.1 lukem }
1211 1.1 lukem
1212 1.1 lukem err = ber_printf( seber, "b", abs(subentries) == 1 ? 0 : 1 );
1213 1.1 lukem if ( err == -1 ) {
1214 1.1 lukem ber_free( seber, 1 );
1215 1.1 lukem fprintf( stderr, _("Subentries control encoding error!\n") );
1216 1.2 christos tool_exit( ld, EXIT_FAILURE );
1217 1.1 lukem }
1218 1.1 lukem
1219 1.1 lukem if ( ber_flatten2( seber, &c[i].ldctl_value, 0 ) == -1 ) {
1220 1.2 christos tool_exit( ld, EXIT_FAILURE );
1221 1.1 lukem }
1222 1.1 lukem
1223 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_SUBENTRIES;
1224 1.1 lukem c[i].ldctl_iscritical = subentries < 1;
1225 1.1 lukem i++;
1226 1.1 lukem }
1227 1.1 lukem
1228 1.1 lukem if ( ldapsync ) {
1229 1.1 lukem if ( ctrl_add() ) {
1230 1.2 christos tool_exit( ld, EXIT_FAILURE );
1231 1.1 lukem }
1232 1.1 lukem
1233 1.1 lukem if (( syncber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
1234 1.2 christos tool_exit( ld, EXIT_FAILURE );
1235 1.1 lukem }
1236 1.1 lukem
1237 1.1 lukem if ( sync_cookie.bv_len == 0 ) {
1238 1.1 lukem err = ber_printf( syncber, "{e}", abs(ldapsync) );
1239 1.1 lukem } else {
1240 1.1 lukem err = ber_printf( syncber, "{eO}", abs(ldapsync),
1241 1.1 lukem &sync_cookie );
1242 1.1 lukem }
1243 1.1 lukem
1244 1.2 christos if ( err == -1 ) {
1245 1.1 lukem ber_free( syncber, 1 );
1246 1.1 lukem fprintf( stderr, _("ldap sync control encoding error!\n") );
1247 1.2 christos tool_exit( ld, EXIT_FAILURE );
1248 1.1 lukem }
1249 1.1 lukem
1250 1.2 christos if ( ber_flatten( syncber, &syncbvalp ) == -1 ) {
1251 1.2 christos tool_exit( ld, EXIT_FAILURE );
1252 1.1 lukem }
1253 1.1 lukem
1254 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_SYNC;
1255 1.1 lukem c[i].ldctl_value = (*syncbvalp);
1256 1.1 lukem c[i].ldctl_iscritical = ldapsync < 0;
1257 1.1 lukem i++;
1258 1.1 lukem }
1259 1.1 lukem
1260 1.1 lukem if ( valuesReturnFilter ) {
1261 1.1 lukem if ( ctrl_add() ) {
1262 1.2 christos tool_exit( ld, EXIT_FAILURE );
1263 1.1 lukem }
1264 1.1 lukem
1265 1.1 lukem if (( vrber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
1266 1.2 christos tool_exit( ld, EXIT_FAILURE );
1267 1.1 lukem }
1268 1.1 lukem
1269 1.1 lukem if ( ( err = ldap_put_vrFilter( vrber, vrFilter ) ) == -1 ) {
1270 1.1 lukem ber_free( vrber, 1 );
1271 1.1 lukem fprintf( stderr, _("Bad ValuesReturnFilter: %s\n"), vrFilter );
1272 1.2 christos tool_exit( ld, EXIT_FAILURE );
1273 1.1 lukem }
1274 1.1 lukem
1275 1.1 lukem if ( ber_flatten2( vrber, &c[i].ldctl_value, 0 ) == -1 ) {
1276 1.2 christos tool_exit( ld, EXIT_FAILURE );
1277 1.1 lukem }
1278 1.1 lukem
1279 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_VALUESRETURNFILTER;
1280 1.1 lukem c[i].ldctl_iscritical = valuesReturnFilter > 1;
1281 1.1 lukem i++;
1282 1.1 lukem }
1283 1.1 lukem
1284 1.1 lukem if ( pagedResults ) {
1285 1.1 lukem if ( ctrl_add() ) {
1286 1.2 christos tool_exit( ld, EXIT_FAILURE );
1287 1.1 lukem }
1288 1.1 lukem
1289 1.1 lukem if ( ldap_create_page_control_value( ld,
1290 1.1 lukem pageSize, &pr_cookie, &c[i].ldctl_value ) )
1291 1.1 lukem {
1292 1.2 christos tool_exit( ld, EXIT_FAILURE );
1293 1.1 lukem }
1294 1.1 lukem
1295 1.1 lukem if ( pr_cookie.bv_val != NULL ) {
1296 1.1 lukem ber_memfree( pr_cookie.bv_val );
1297 1.1 lukem pr_cookie.bv_val = NULL;
1298 1.1 lukem pr_cookie.bv_len = 0;
1299 1.1 lukem }
1300 1.1 lukem
1301 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
1302 1.1 lukem c[i].ldctl_iscritical = pagedResults > 1;
1303 1.1 lukem i++;
1304 1.1 lukem }
1305 1.2 christos
1306 1.3 christos if ( psearch ) {
1307 1.3 christos if ( ctrl_add() ) {
1308 1.3 christos tool_exit( ld, EXIT_FAILURE );
1309 1.3 christos }
1310 1.3 christos
1311 1.3 christos if ( ldap_create_persistentsearch_control_value( ld,
1312 1.3 christos ps_chgtypes, ps_chgsonly, ps_echg_ctrls, &c[i].ldctl_value ) )
1313 1.3 christos {
1314 1.3 christos tool_exit( ld, EXIT_FAILURE );
1315 1.3 christos }
1316 1.3 christos
1317 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_PERSIST_REQUEST;
1318 1.3 christos c[i].ldctl_iscritical = psearch > 1;
1319 1.3 christos i++;
1320 1.3 christos }
1321 1.3 christos
1322 1.2 christos if ( sss ) {
1323 1.2 christos if ( ctrl_add() ) {
1324 1.2 christos tool_exit( ld, EXIT_FAILURE );
1325 1.2 christos }
1326 1.2 christos
1327 1.2 christos if ( ldap_create_sort_control_value( ld,
1328 1.2 christos sss_keys, &c[i].ldctl_value ) )
1329 1.2 christos {
1330 1.2 christos tool_exit( ld, EXIT_FAILURE );
1331 1.2 christos }
1332 1.2 christos
1333 1.2 christos c[i].ldctl_oid = LDAP_CONTROL_SORTREQUEST;
1334 1.2 christos c[i].ldctl_iscritical = sss > 1;
1335 1.2 christos i++;
1336 1.2 christos }
1337 1.2 christos
1338 1.2 christos if ( vlv ) {
1339 1.2 christos if ( ctrl_add() ) {
1340 1.2 christos tool_exit( ld, EXIT_FAILURE );
1341 1.2 christos }
1342 1.2 christos
1343 1.2 christos if ( ldap_create_vlv_control_value( ld,
1344 1.2 christos &vlvInfo, &c[i].ldctl_value ) )
1345 1.2 christos {
1346 1.2 christos tool_exit( ld, EXIT_FAILURE );
1347 1.2 christos }
1348 1.2 christos
1349 1.2 christos c[i].ldctl_oid = LDAP_CONTROL_VLVREQUEST;
1350 1.3 christos c[i].ldctl_iscritical = vlv > 1;
1351 1.2 christos i++;
1352 1.2 christos }
1353 1.2 christos #ifdef LDAP_CONTROL_X_DEREF
1354 1.2 christos if ( derefcrit ) {
1355 1.2 christos if ( derefval.bv_val == NULL ) {
1356 1.2 christos int i;
1357 1.2 christos
1358 1.2 christos assert( ds != NULL );
1359 1.2 christos
1360 1.2 christos if ( ldap_create_deref_control_value( ld, ds, &derefval ) != LDAP_SUCCESS ) {
1361 1.2 christos tool_exit( ld, EXIT_FAILURE );
1362 1.2 christos }
1363 1.2 christos
1364 1.2 christos for ( i = 0; ds[ i ].derefAttr != NULL; i++ ) {
1365 1.2 christos ldap_memfree( ds[ i ].derefAttr );
1366 1.2 christos ldap_charray_free( ds[ i ].attributes );
1367 1.2 christos }
1368 1.2 christos ldap_memfree( ds );
1369 1.2 christos ds = NULL;
1370 1.2 christos }
1371 1.2 christos
1372 1.2 christos if ( ctrl_add() ) {
1373 1.2 christos tool_exit( ld, EXIT_FAILURE );
1374 1.2 christos }
1375 1.2 christos
1376 1.2 christos c[ i ].ldctl_iscritical = derefcrit > 1;
1377 1.2 christos c[ i ].ldctl_oid = LDAP_CONTROL_X_DEREF;
1378 1.2 christos c[ i ].ldctl_value = derefval;
1379 1.2 christos i++;
1380 1.2 christos }
1381 1.2 christos #endif /* LDAP_CONTROL_X_DEREF */
1382 1.3 christos #ifdef LDAP_CONTROL_X_DIRSYNC
1383 1.3 christos if ( dirSync ) {
1384 1.3 christos if ( ctrl_add() ) {
1385 1.3 christos tool_exit( ld, EXIT_FAILURE );
1386 1.3 christos }
1387 1.3 christos
1388 1.3 christos if ( ldap_create_dirsync_value( ld,
1389 1.3 christos dirSyncFlags, dirSyncMaxAttrCount, &dirSyncCookie,
1390 1.3 christos &c[i].ldctl_value ) )
1391 1.3 christos {
1392 1.3 christos tool_exit( ld, EXIT_FAILURE );
1393 1.3 christos }
1394 1.3 christos
1395 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_X_DIRSYNC;
1396 1.3 christos c[i].ldctl_iscritical = dirSync > 1;
1397 1.3 christos i++;
1398 1.3 christos }
1399 1.3 christos #endif
1400 1.3 christos #ifdef LDAP_CONTROL_X_EXTENDED_DN
1401 1.3 christos if ( extendedDn ) {
1402 1.3 christos if ( ctrl_add() ) {
1403 1.3 christos tool_exit( ld, EXIT_FAILURE );
1404 1.3 christos }
1405 1.3 christos
1406 1.3 christos if ( ldap_create_extended_dn_value( ld,
1407 1.3 christos extendedDnFlag, &c[i].ldctl_value ) )
1408 1.3 christos {
1409 1.3 christos tool_exit( ld, EXIT_FAILURE );
1410 1.3 christos }
1411 1.3 christos
1412 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_X_EXTENDED_DN;
1413 1.3 christos c[i].ldctl_iscritical = extendedDn > 1;
1414 1.3 christos i++;
1415 1.3 christos }
1416 1.3 christos #endif
1417 1.3 christos #ifdef LDAP_CONTROL_X_SHOW_DELETED
1418 1.3 christos if ( showDeleted ) {
1419 1.3 christos if ( ctrl_add() ) {
1420 1.3 christos tool_exit( ld, EXIT_FAILURE );
1421 1.3 christos }
1422 1.3 christos
1423 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_X_SHOW_DELETED;
1424 1.3 christos c[i].ldctl_value.bv_val = NULL;
1425 1.3 christos c[i].ldctl_value.bv_len = 0;
1426 1.3 christos c[i].ldctl_iscritical = showDeleted > 1;
1427 1.3 christos i++;
1428 1.3 christos }
1429 1.3 christos #endif
1430 1.3 christos #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION
1431 1.3 christos if ( serverNotif ) {
1432 1.3 christos if ( ctrl_add() ) {
1433 1.3 christos tool_exit( ld, EXIT_FAILURE );
1434 1.3 christos }
1435 1.3 christos
1436 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_X_SERVER_NOTIFICATION;
1437 1.3 christos c[i].ldctl_value.bv_val = NULL;
1438 1.3 christos c[i].ldctl_value.bv_len = 0;
1439 1.3 christos c[i].ldctl_iscritical = serverNotif > 1;
1440 1.3 christos i++;
1441 1.3 christos }
1442 1.3 christos #endif
1443 1.1 lukem }
1444 1.1 lukem
1445 1.1 lukem tool_server_controls( ld, c, i );
1446 1.1 lukem
1447 1.2 christos if ( seber ) ber_free( seber, 1 );
1448 1.2 christos if ( vrber ) ber_free( vrber, 1 );
1449 1.1 lukem
1450 1.1 lukem /* step back to the original number of controls, so that
1451 1.1 lukem * those set while parsing args are preserved */
1452 1.1 lukem nctrls = save_nctrls;
1453 1.1 lukem
1454 1.1 lukem if ( verbose ) {
1455 1.1 lukem fprintf( stderr, _("filter%s: %s\nrequesting: "),
1456 1.1 lukem infile != NULL ? _(" pattern") : "",
1457 1.1 lukem filtpattern );
1458 1.1 lukem
1459 1.1 lukem if ( attrs == NULL ) {
1460 1.1 lukem fprintf( stderr, _("All userApplication attributes") );
1461 1.1 lukem } else {
1462 1.1 lukem for ( i = 0; attrs[ i ] != NULL; ++i ) {
1463 1.1 lukem fprintf( stderr, "%s ", attrs[ i ] );
1464 1.1 lukem }
1465 1.1 lukem }
1466 1.1 lukem fprintf( stderr, "\n" );
1467 1.1 lukem }
1468 1.1 lukem
1469 1.1 lukem if ( ldif == 0 ) {
1470 1.1 lukem printf( _("# extended LDIF\n") );
1471 1.1 lukem } else if ( ldif < 3 ) {
1472 1.1 lukem printf( _("version: %d\n\n"), 1 );
1473 1.1 lukem }
1474 1.1 lukem
1475 1.1 lukem if (ldif < 2 ) {
1476 1.1 lukem char *realbase = base;
1477 1.1 lukem
1478 1.1 lukem if ( realbase == NULL ) {
1479 1.1 lukem ldap_get_option( ld, LDAP_OPT_DEFBASE, (void **)(char *)&realbase );
1480 1.1 lukem }
1481 1.1 lukem
1482 1.1 lukem printf( "#\n" );
1483 1.1 lukem printf(_("# LDAPv%d\n"), protocol);
1484 1.1 lukem printf(_("# base <%s>%s with scope %s\n"),
1485 1.1 lukem realbase ? realbase : "",
1486 1.1 lukem ( realbase == NULL || realbase != base ) ? " (default)" : "",
1487 1.1 lukem ((scope == LDAP_SCOPE_BASE) ? "baseObject"
1488 1.1 lukem : ((scope == LDAP_SCOPE_ONELEVEL) ? "oneLevel"
1489 1.1 lukem : ((scope == LDAP_SCOPE_SUBORDINATE) ? "children"
1490 1.1 lukem : "subtree" ))));
1491 1.1 lukem printf(_("# filter%s: %s\n"), infile != NULL ? _(" pattern") : "",
1492 1.1 lukem filtpattern);
1493 1.1 lukem printf(_("# requesting: "));
1494 1.1 lukem
1495 1.1 lukem if ( attrs == NULL ) {
1496 1.1 lukem printf( _("ALL") );
1497 1.1 lukem } else {
1498 1.1 lukem for ( i = 0; attrs[ i ] != NULL; ++i ) {
1499 1.1 lukem printf( "%s ", attrs[ i ] );
1500 1.1 lukem }
1501 1.1 lukem }
1502 1.1 lukem
1503 1.1 lukem if ( manageDSAit ) {
1504 1.1 lukem printf(_("\n# with manageDSAit %scontrol"),
1505 1.1 lukem manageDSAit > 1 ? _("critical ") : "" );
1506 1.1 lukem }
1507 1.1 lukem if ( noop ) {
1508 1.1 lukem printf(_("\n# with noop %scontrol"),
1509 1.1 lukem noop > 1 ? _("critical ") : "" );
1510 1.1 lukem }
1511 1.1 lukem if ( subentries ) {
1512 1.1 lukem printf(_("\n# with subentries %scontrol: %s"),
1513 1.1 lukem subentries < 0 ? _("critical ") : "",
1514 1.1 lukem abs(subentries) == 1 ? "false" : "true" );
1515 1.1 lukem }
1516 1.1 lukem if ( valuesReturnFilter ) {
1517 1.1 lukem printf(_("\n# with valuesReturnFilter %scontrol: %s"),
1518 1.1 lukem valuesReturnFilter > 1 ? _("critical ") : "", vrFilter );
1519 1.1 lukem }
1520 1.1 lukem if ( pagedResults ) {
1521 1.1 lukem printf(_("\n# with pagedResults %scontrol: size=%d"),
1522 1.1 lukem (pagedResults > 1) ? _("critical ") : "",
1523 1.1 lukem pageSize );
1524 1.1 lukem }
1525 1.2 christos if ( sss ) {
1526 1.2 christos printf(_("\n# with server side sorting %scontrol"),
1527 1.2 christos sss > 1 ? _("critical ") : "" );
1528 1.2 christos }
1529 1.2 christos if ( vlv ) {
1530 1.2 christos printf(_("\n# with virtual list view %scontrol: %d/%d"),
1531 1.2 christos vlv > 1 ? _("critical ") : "",
1532 1.2 christos vlvInfo.ldvlv_before_count, vlvInfo.ldvlv_after_count);
1533 1.2 christos if ( vlvInfo.ldvlv_attrvalue )
1534 1.2 christos printf(":%s", vlvInfo.ldvlv_attrvalue->bv_val );
1535 1.2 christos else
1536 1.2 christos printf("/%d/%d", vlvInfo.ldvlv_offset, vlvInfo.ldvlv_count );
1537 1.2 christos }
1538 1.2 christos #ifdef LDAP_CONTROL_X_DEREF
1539 1.2 christos if ( derefcrit ) {
1540 1.2 christos printf(_("\n# with dereference %scontrol"),
1541 1.2 christos derefcrit > 1 ? _("critical ") : "" );
1542 1.2 christos }
1543 1.2 christos #endif
1544 1.1 lukem
1545 1.1 lukem printf( _("\n#\n\n") );
1546 1.1 lukem
1547 1.1 lukem if ( realbase && realbase != base ) {
1548 1.1 lukem ldap_memfree( realbase );
1549 1.1 lukem }
1550 1.1 lukem }
1551 1.1 lukem
1552 1.1 lukem if ( infile == NULL ) {
1553 1.1 lukem rc = dosearch( ld, base, scope, NULL, filtpattern,
1554 1.2 christos attrs, attrsonly, NULL, NULL, NULL, sizelimit );
1555 1.1 lukem
1556 1.1 lukem } else {
1557 1.1 lukem rc = 0;
1558 1.1 lukem first = 1;
1559 1.1 lukem while ( fgets( line, sizeof( line ), fp ) != NULL ) {
1560 1.1 lukem line[ strlen( line ) - 1 ] = '\0';
1561 1.1 lukem if ( !first ) {
1562 1.1 lukem putchar( '\n' );
1563 1.1 lukem } else {
1564 1.1 lukem first = 0;
1565 1.1 lukem }
1566 1.1 lukem rc1 = dosearch( ld, base, scope, filtpattern, line,
1567 1.2 christos attrs, attrsonly, NULL, NULL, NULL, sizelimit );
1568 1.1 lukem
1569 1.1 lukem if ( rc1 != 0 ) {
1570 1.1 lukem rc = rc1;
1571 1.1 lukem if ( !contoper )
1572 1.1 lukem break;
1573 1.1 lukem }
1574 1.1 lukem }
1575 1.1 lukem if ( fp != stdin ) {
1576 1.1 lukem fclose( fp );
1577 1.2 christos fp = NULL;
1578 1.1 lukem }
1579 1.1 lukem }
1580 1.1 lukem
1581 1.1 lukem if (( rc == LDAP_SUCCESS ) && pageSize && pr_morePagedResults ) {
1582 1.2 christos char buf[12];
1583 1.1 lukem int i, moreEntries, tmpSize;
1584 1.1 lukem
1585 1.1 lukem /* Loop to get the next pages when
1586 1.1 lukem * enter is pressed on the terminal.
1587 1.1 lukem */
1588 1.1 lukem if ( pagePrompt != 0 ) {
1589 1.1 lukem if ( entriesLeft > 0 ) {
1590 1.1 lukem printf( _("Estimate entries: %d\n"), entriesLeft );
1591 1.1 lukem }
1592 1.1 lukem printf( _("Press [size] Enter for the next {%d|size} entries.\n"),
1593 1.1 lukem (int)pageSize );
1594 1.1 lukem i = 0;
1595 1.1 lukem moreEntries = getchar();
1596 1.1 lukem while ( moreEntries != EOF && moreEntries != '\n' ) {
1597 1.1 lukem if ( i < (int)sizeof(buf) - 1 ) {
1598 1.1 lukem buf[i] = moreEntries;
1599 1.1 lukem i++;
1600 1.1 lukem }
1601 1.1 lukem moreEntries = getchar();
1602 1.1 lukem }
1603 1.1 lukem buf[i] = '\0';
1604 1.1 lukem
1605 1.1 lukem if ( i > 0 && isdigit( (unsigned char)buf[0] ) ) {
1606 1.1 lukem int num = sscanf( buf, "%d", &tmpSize );
1607 1.1 lukem if ( num != 1 ) {
1608 1.1 lukem fprintf( stderr,
1609 1.1 lukem _("Invalid value for PagedResultsControl, %s.\n"), buf);
1610 1.2 christos tool_exit( ld, EXIT_FAILURE );
1611 1.1 lukem
1612 1.1 lukem }
1613 1.1 lukem pageSize = (ber_int_t)tmpSize;
1614 1.1 lukem }
1615 1.1 lukem }
1616 1.1 lukem
1617 1.1 lukem goto getNextPage;
1618 1.1 lukem }
1619 1.1 lukem
1620 1.2 christos if (( rc == LDAP_SUCCESS ) && vlv ) {
1621 1.2 christos char buf[BUFSIZ];
1622 1.2 christos int i, moreEntries;
1623 1.2 christos
1624 1.2 christos /* Loop to get the next window when
1625 1.2 christos * enter is pressed on the terminal.
1626 1.2 christos */
1627 1.2 christos printf( _("Press [before/after(/offset/count|:value)] Enter for the next window.\n"));
1628 1.2 christos i = 0;
1629 1.2 christos moreEntries = getchar();
1630 1.2 christos while ( moreEntries != EOF && moreEntries != '\n' ) {
1631 1.2 christos if ( i < (int)sizeof(buf) - 1 ) {
1632 1.2 christos buf[i] = moreEntries;
1633 1.2 christos i++;
1634 1.2 christos }
1635 1.2 christos moreEntries = getchar();
1636 1.2 christos }
1637 1.2 christos buf[i] = '\0';
1638 1.2 christos if ( buf[0] ) {
1639 1.2 christos i = parse_vlv( strdup( buf ));
1640 1.2 christos if ( i )
1641 1.2 christos tool_exit( ld, EXIT_FAILURE );
1642 1.2 christos } else {
1643 1.2 christos vlvInfo.ldvlv_attrvalue = NULL;
1644 1.2 christos vlvInfo.ldvlv_count = vlvCount;
1645 1.2 christos vlvInfo.ldvlv_offset += vlvInfo.ldvlv_after_count;
1646 1.2 christos }
1647 1.2 christos
1648 1.2 christos if ( vlvInfo.ldvlv_context )
1649 1.2 christos ber_bvfree( vlvInfo.ldvlv_context );
1650 1.2 christos vlvInfo.ldvlv_context = vlvContext;
1651 1.2 christos
1652 1.2 christos goto getNextPage;
1653 1.2 christos }
1654 1.2 christos
1655 1.2 christos if ( sss_keys != NULL ) {
1656 1.2 christos ldap_free_sort_keylist( sss_keys );
1657 1.2 christos }
1658 1.2 christos if ( derefval.bv_val != NULL ) {
1659 1.2 christos ldap_memfree( derefval.bv_val );
1660 1.2 christos }
1661 1.2 christos if ( urlpre != NULL ) {
1662 1.2 christos if ( def_urlpre != urlpre )
1663 1.2 christos free( def_urlpre );
1664 1.2 christos free( urlpre );
1665 1.2 christos }
1666 1.1 lukem
1667 1.1 lukem if ( c ) {
1668 1.1 lukem for ( ; save_nctrls-- > 0; ) {
1669 1.1 lukem ber_memfree( c[ save_nctrls ].ldctl_value.bv_val );
1670 1.1 lukem }
1671 1.1 lukem free( c );
1672 1.1 lukem c = NULL;
1673 1.1 lukem }
1674 1.1 lukem
1675 1.2 christos tool_exit( ld, rc );
1676 1.1 lukem }
1677 1.1 lukem
1678 1.1 lukem
1679 1.1 lukem static int dosearch(
1680 1.1 lukem LDAP *ld,
1681 1.1 lukem char *base,
1682 1.1 lukem int scope,
1683 1.1 lukem char *filtpatt,
1684 1.1 lukem char *value,
1685 1.1 lukem char **attrs,
1686 1.1 lukem int attrsonly,
1687 1.1 lukem LDAPControl **sctrls,
1688 1.1 lukem LDAPControl **cctrls,
1689 1.1 lukem struct timeval *timeout,
1690 1.1 lukem int sizelimit )
1691 1.1 lukem {
1692 1.1 lukem char *filter;
1693 1.2 christos int rc, rc2 = LDAP_OTHER;
1694 1.1 lukem int nresponses;
1695 1.1 lukem int nentries;
1696 1.1 lukem int nreferences;
1697 1.1 lukem int nextended;
1698 1.1 lukem int npartial;
1699 1.1 lukem LDAPMessage *res, *msg;
1700 1.1 lukem ber_int_t msgid;
1701 1.1 lukem char *retoid = NULL;
1702 1.1 lukem struct berval *retdata = NULL;
1703 1.1 lukem int nresponses_psearch = -1;
1704 1.1 lukem int cancel_msgid = -1;
1705 1.2 christos struct timeval tv, *tvp = NULL;
1706 1.2 christos struct timeval tv_timelimit, *tv_timelimitp = NULL;
1707 1.1 lukem
1708 1.1 lukem if( filtpatt != NULL ) {
1709 1.2 christos size_t max_fsize = strlen( filtpatt ) + strlen( value ) + 1, outlen;
1710 1.1 lukem filter = malloc( max_fsize );
1711 1.1 lukem if( filter == NULL ) {
1712 1.1 lukem perror( "malloc" );
1713 1.1 lukem return EXIT_FAILURE;
1714 1.1 lukem }
1715 1.1 lukem
1716 1.2 christos outlen = snprintf( filter, max_fsize, filtpatt, value );
1717 1.2 christos if( outlen >= max_fsize ) {
1718 1.1 lukem fprintf( stderr, "Bad filter pattern: \"%s\"\n", filtpatt );
1719 1.1 lukem free( filter );
1720 1.1 lukem return EXIT_FAILURE;
1721 1.1 lukem }
1722 1.1 lukem
1723 1.1 lukem if ( verbose ) {
1724 1.1 lukem fprintf( stderr, _("filter: %s\n"), filter );
1725 1.1 lukem }
1726 1.1 lukem
1727 1.1 lukem if( ldif < 2 ) {
1728 1.1 lukem printf( _("#\n# filter: %s\n#\n"), filter );
1729 1.1 lukem }
1730 1.1 lukem
1731 1.1 lukem } else {
1732 1.1 lukem filter = value;
1733 1.1 lukem }
1734 1.1 lukem
1735 1.1 lukem if ( dont ) {
1736 1.1 lukem if ( filtpatt != NULL ) {
1737 1.1 lukem free( filter );
1738 1.1 lukem }
1739 1.1 lukem return LDAP_SUCCESS;
1740 1.1 lukem }
1741 1.1 lukem
1742 1.2 christos if ( timelimit > 0 ) {
1743 1.2 christos tv_timelimit.tv_sec = timelimit;
1744 1.2 christos tv_timelimit.tv_usec = 0;
1745 1.2 christos tv_timelimitp = &tv_timelimit;
1746 1.2 christos }
1747 1.2 christos
1748 1.3 christos again:
1749 1.1 lukem rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
1750 1.2 christos sctrls, cctrls, tv_timelimitp, sizelimit, &msgid );
1751 1.1 lukem
1752 1.1 lukem if ( filtpatt != NULL ) {
1753 1.1 lukem free( filter );
1754 1.1 lukem }
1755 1.1 lukem
1756 1.1 lukem if( rc != LDAP_SUCCESS ) {
1757 1.2 christos tool_perror( "ldap_search_ext", rc, NULL, NULL, NULL, NULL );
1758 1.1 lukem return( rc );
1759 1.1 lukem }
1760 1.1 lukem
1761 1.1 lukem nresponses = nentries = nreferences = nextended = npartial = 0;
1762 1.1 lukem
1763 1.1 lukem res = NULL;
1764 1.1 lukem
1765 1.2 christos if ( timelimit > 0 ) {
1766 1.2 christos /* disable timeout */
1767 1.2 christos tv.tv_sec = -1;
1768 1.2 christos tv.tv_usec = 0;
1769 1.2 christos tvp = &tv;
1770 1.2 christos }
1771 1.2 christos
1772 1.3 christos if ( backlog == 1 ) {
1773 1.3 christos printf( _("\nWaiting for responses to accumulate, press Enter to continue: "));
1774 1.3 christos fflush( stdout );
1775 1.3 christos getchar();
1776 1.3 christos printf( _("Abandoning msgid %d\n"), msgid );
1777 1.3 christos ldap_abandon_ext( ld, msgid, NULL, NULL );
1778 1.3 christos /* turn off syncrepl control */
1779 1.3 christos ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, NULL );
1780 1.3 christos backlog = 2;
1781 1.3 christos scope = LDAP_SCOPE_BASE;
1782 1.3 christos goto again;
1783 1.3 christos } else if ( backlog == 2 ) {
1784 1.3 christos tv.tv_sec = timelimit;
1785 1.3 christos }
1786 1.3 christos
1787 1.1 lukem while ((rc = ldap_result( ld, LDAP_RES_ANY,
1788 1.1 lukem sortattr ? LDAP_MSG_ALL : LDAP_MSG_ONE,
1789 1.2 christos tvp, &res )) > 0 )
1790 1.1 lukem {
1791 1.2 christos if ( tool_check_abandon( ld, msgid ) ) {
1792 1.2 christos return -1;
1793 1.1 lukem }
1794 1.1 lukem
1795 1.1 lukem if( sortattr ) {
1796 1.1 lukem (void) ldap_sort_entries( ld, &res,
1797 1.1 lukem ( *sortattr == '\0' ) ? NULL : sortattr, strcasecmp );
1798 1.1 lukem }
1799 1.1 lukem
1800 1.1 lukem for ( msg = ldap_first_message( ld, res );
1801 1.1 lukem msg != NULL;
1802 1.1 lukem msg = ldap_next_message( ld, msg ) )
1803 1.1 lukem {
1804 1.1 lukem if ( nresponses++ ) putchar('\n');
1805 1.1 lukem if ( nresponses_psearch >= 0 )
1806 1.1 lukem nresponses_psearch++;
1807 1.1 lukem
1808 1.1 lukem switch( ldap_msgtype( msg ) ) {
1809 1.1 lukem case LDAP_RES_SEARCH_ENTRY:
1810 1.1 lukem nentries++;
1811 1.1 lukem print_entry( ld, msg, attrsonly );
1812 1.1 lukem break;
1813 1.1 lukem
1814 1.1 lukem case LDAP_RES_SEARCH_REFERENCE:
1815 1.1 lukem nreferences++;
1816 1.1 lukem print_reference( ld, msg );
1817 1.1 lukem break;
1818 1.1 lukem
1819 1.1 lukem case LDAP_RES_EXTENDED:
1820 1.1 lukem nextended++;
1821 1.1 lukem print_extended( ld, msg );
1822 1.1 lukem
1823 1.1 lukem if ( ldap_msgid( msg ) == 0 ) {
1824 1.1 lukem /* unsolicited extended operation */
1825 1.1 lukem goto done;
1826 1.1 lukem }
1827 1.1 lukem
1828 1.1 lukem if ( cancel_msgid != -1 &&
1829 1.1 lukem cancel_msgid == ldap_msgid( msg ) ) {
1830 1.1 lukem printf(_("Cancelled \n"));
1831 1.1 lukem printf(_("cancel_msgid = %d\n"), cancel_msgid);
1832 1.1 lukem goto done;
1833 1.1 lukem }
1834 1.1 lukem break;
1835 1.1 lukem
1836 1.1 lukem case LDAP_RES_SEARCH_RESULT:
1837 1.1 lukem /* pagedResults stuff is dealt with
1838 1.1 lukem * in tool_print_ctrls(), called by
1839 1.1 lukem * print_results(). */
1840 1.2 christos rc2 = print_result( ld, msg, 1 );
1841 1.1 lukem if ( ldapsync == LDAP_SYNC_REFRESH_AND_PERSIST ) {
1842 1.1 lukem break;
1843 1.1 lukem }
1844 1.1 lukem
1845 1.1 lukem goto done;
1846 1.1 lukem
1847 1.1 lukem case LDAP_RES_INTERMEDIATE:
1848 1.1 lukem npartial++;
1849 1.1 lukem ldap_parse_intermediate( ld, msg,
1850 1.1 lukem &retoid, &retdata, NULL, 0 );
1851 1.1 lukem
1852 1.1 lukem nresponses_psearch = 0;
1853 1.1 lukem
1854 1.1 lukem if ( strcmp( retoid, LDAP_SYNC_INFO ) == 0 ) {
1855 1.3 christos if ( ldif < 1 ) {
1856 1.3 christos print_syncinfo( retdata );
1857 1.3 christos } else if ( ldif < 2 ) {
1858 1.3 christos printf(_("# SyncInfo Received\n"));
1859 1.3 christos }
1860 1.1 lukem ldap_memfree( retoid );
1861 1.1 lukem ber_bvfree( retdata );
1862 1.1 lukem break;
1863 1.1 lukem }
1864 1.1 lukem
1865 1.1 lukem print_partial( ld, msg );
1866 1.1 lukem ldap_memfree( retoid );
1867 1.1 lukem ber_bvfree( retdata );
1868 1.1 lukem goto done;
1869 1.1 lukem }
1870 1.1 lukem
1871 1.1 lukem if ( ldapsync && sync_slimit != -1 &&
1872 1.1 lukem nresponses_psearch >= sync_slimit ) {
1873 1.1 lukem BerElement *msgidber = NULL;
1874 1.1 lukem struct berval *msgidvalp = NULL;
1875 1.1 lukem msgidber = ber_alloc_t(LBER_USE_DER);
1876 1.1 lukem ber_printf(msgidber, "{i}", msgid);
1877 1.1 lukem ber_flatten(msgidber, &msgidvalp);
1878 1.1 lukem ldap_extended_operation(ld, LDAP_EXOP_CANCEL,
1879 1.1 lukem msgidvalp, NULL, NULL, &cancel_msgid);
1880 1.1 lukem nresponses_psearch = -1;
1881 1.1 lukem }
1882 1.1 lukem }
1883 1.1 lukem
1884 1.1 lukem ldap_msgfree( res );
1885 1.2 christos fflush( stdout );
1886 1.1 lukem }
1887 1.1 lukem
1888 1.1 lukem done:
1889 1.2 christos if ( tvp == NULL && rc != LDAP_RES_SEARCH_RESULT ) {
1890 1.2 christos ldap_get_option( ld, LDAP_OPT_RESULT_CODE, (void *)&rc2 );
1891 1.1 lukem }
1892 1.1 lukem
1893 1.1 lukem ldap_msgfree( res );
1894 1.1 lukem
1895 1.1 lukem if ( pagedResults ) {
1896 1.1 lukem npagedresponses += nresponses;
1897 1.1 lukem npagedentries += nentries;
1898 1.1 lukem npagedextended += nextended;
1899 1.1 lukem npagedpartial += npartial;
1900 1.1 lukem npagedreferences += nreferences;
1901 1.1 lukem if ( ( pr_morePagedResults == 0 ) && ( ldif < 2 ) ) {
1902 1.1 lukem printf( _("\n# numResponses: %d\n"), npagedresponses );
1903 1.1 lukem if( npagedentries ) {
1904 1.1 lukem printf( _("# numEntries: %d\n"), npagedentries );
1905 1.1 lukem }
1906 1.1 lukem if( npagedextended ) {
1907 1.1 lukem printf( _("# numExtended: %d\n"), npagedextended );
1908 1.1 lukem }
1909 1.1 lukem if( npagedpartial ) {
1910 1.1 lukem printf( _("# numPartial: %d\n"), npagedpartial );
1911 1.1 lukem }
1912 1.1 lukem if( npagedreferences ) {
1913 1.1 lukem printf( _("# numReferences: %d\n"), npagedreferences );
1914 1.1 lukem }
1915 1.1 lukem }
1916 1.1 lukem } else if ( ldif < 2 ) {
1917 1.1 lukem printf( _("\n# numResponses: %d\n"), nresponses );
1918 1.1 lukem if( nentries ) printf( _("# numEntries: %d\n"), nentries );
1919 1.1 lukem if( nextended ) printf( _("# numExtended: %d\n"), nextended );
1920 1.1 lukem if( npartial ) printf( _("# numPartial: %d\n"), npartial );
1921 1.1 lukem if( nreferences ) printf( _("# numReferences: %d\n"), nreferences );
1922 1.1 lukem }
1923 1.1 lukem
1924 1.2 christos if ( rc != LDAP_RES_SEARCH_RESULT ) {
1925 1.2 christos tool_perror( "ldap_result", rc2, NULL, NULL, NULL, NULL );
1926 1.2 christos }
1927 1.2 christos
1928 1.2 christos return( rc2 );
1929 1.1 lukem }
1930 1.1 lukem
1931 1.1 lukem /* This is the proposed new way of doing things.
1932 1.1 lukem * It is more efficient, but the API is non-standard.
1933 1.1 lukem */
1934 1.1 lukem static void
1935 1.1 lukem print_entry(
1936 1.1 lukem LDAP *ld,
1937 1.1 lukem LDAPMessage *entry,
1938 1.1 lukem int attrsonly)
1939 1.1 lukem {
1940 1.1 lukem char *ufn = NULL;
1941 1.1 lukem char tmpfname[ 256 ];
1942 1.1 lukem char url[ 256 ];
1943 1.1 lukem int i, rc;
1944 1.1 lukem BerElement *ber = NULL;
1945 1.1 lukem struct berval bv, *bvals, **bvp = &bvals;
1946 1.1 lukem LDAPControl **ctrls = NULL;
1947 1.1 lukem FILE *tmpfp;
1948 1.1 lukem
1949 1.1 lukem rc = ldap_get_dn_ber( ld, entry, &ber, &bv );
1950 1.1 lukem
1951 1.1 lukem if ( ldif < 2 ) {
1952 1.1 lukem ufn = ldap_dn2ufn( bv.bv_val );
1953 1.1 lukem tool_write_ldif( LDIF_PUT_COMMENT, NULL, ufn, ufn ? strlen( ufn ) : 0 );
1954 1.1 lukem }
1955 1.1 lukem tool_write_ldif( LDIF_PUT_VALUE, "dn", bv.bv_val, bv.bv_len );
1956 1.1 lukem
1957 1.1 lukem rc = ldap_get_entry_controls( ld, entry, &ctrls );
1958 1.1 lukem if( rc != LDAP_SUCCESS ) {
1959 1.1 lukem fprintf(stderr, _("print_entry: %d\n"), rc );
1960 1.1 lukem tool_perror( "ldap_get_entry_controls", rc, NULL, NULL, NULL, NULL );
1961 1.2 christos tool_exit( ld, EXIT_FAILURE );
1962 1.1 lukem }
1963 1.1 lukem
1964 1.1 lukem if( ctrls ) {
1965 1.1 lukem tool_print_ctrls( ld, ctrls );
1966 1.1 lukem ldap_controls_free( ctrls );
1967 1.1 lukem }
1968 1.1 lukem
1969 1.1 lukem if ( includeufn ) {
1970 1.1 lukem if( ufn == NULL ) {
1971 1.1 lukem ufn = ldap_dn2ufn( bv.bv_val );
1972 1.1 lukem }
1973 1.1 lukem tool_write_ldif( LDIF_PUT_VALUE, "ufn", ufn, ufn ? strlen( ufn ) : 0 );
1974 1.1 lukem }
1975 1.1 lukem
1976 1.1 lukem if( ufn != NULL ) ldap_memfree( ufn );
1977 1.1 lukem
1978 1.1 lukem if ( attrsonly ) bvp = NULL;
1979 1.1 lukem
1980 1.1 lukem for ( rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp );
1981 1.1 lukem rc == LDAP_SUCCESS;
1982 1.1 lukem rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp ) )
1983 1.1 lukem {
1984 1.1 lukem if (bv.bv_val == NULL) break;
1985 1.1 lukem
1986 1.1 lukem if ( attrsonly ) {
1987 1.1 lukem tool_write_ldif( LDIF_PUT_NOVALUE, bv.bv_val, NULL, 0 );
1988 1.1 lukem
1989 1.1 lukem } else if ( bvals ) {
1990 1.1 lukem for ( i = 0; bvals[i].bv_val != NULL; i++ ) {
1991 1.1 lukem if ( vals2tmp > 1 || ( vals2tmp &&
1992 1.1 lukem ldif_is_not_printable( bvals[i].bv_val, bvals[i].bv_len )))
1993 1.1 lukem {
1994 1.1 lukem int tmpfd;
1995 1.1 lukem /* write value to file */
1996 1.1 lukem snprintf( tmpfname, sizeof tmpfname,
1997 1.1 lukem "%s" LDAP_DIRSEP "ldapsearch-%s-XXXXXX",
1998 1.1 lukem tmpdir, bv.bv_val );
1999 1.1 lukem tmpfp = NULL;
2000 1.1 lukem
2001 1.1 lukem tmpfd = mkstemp( tmpfname );
2002 1.1 lukem
2003 1.1 lukem if ( tmpfd < 0 ) {
2004 1.1 lukem perror( tmpfname );
2005 1.1 lukem continue;
2006 1.1 lukem }
2007 1.1 lukem
2008 1.1 lukem if (( tmpfp = fdopen( tmpfd, "w")) == NULL ) {
2009 1.1 lukem perror( tmpfname );
2010 1.1 lukem continue;
2011 1.1 lukem }
2012 1.1 lukem
2013 1.1 lukem if ( fwrite( bvals[ i ].bv_val,
2014 1.1 lukem bvals[ i ].bv_len, 1, tmpfp ) == 0 )
2015 1.1 lukem {
2016 1.1 lukem perror( tmpfname );
2017 1.1 lukem fclose( tmpfp );
2018 1.1 lukem continue;
2019 1.1 lukem }
2020 1.1 lukem
2021 1.1 lukem fclose( tmpfp );
2022 1.1 lukem
2023 1.1 lukem snprintf( url, sizeof url, "%s%s", urlpre,
2024 1.1 lukem &tmpfname[strlen(tmpdir) + sizeof(LDAP_DIRSEP) - 1] );
2025 1.1 lukem
2026 1.1 lukem urlize( url );
2027 1.1 lukem tool_write_ldif( LDIF_PUT_URL, bv.bv_val, url, strlen( url ));
2028 1.1 lukem
2029 1.1 lukem } else {
2030 1.1 lukem tool_write_ldif( LDIF_PUT_VALUE, bv.bv_val,
2031 1.1 lukem bvals[ i ].bv_val, bvals[ i ].bv_len );
2032 1.1 lukem }
2033 1.1 lukem }
2034 1.1 lukem ber_memfree( bvals );
2035 1.1 lukem }
2036 1.1 lukem }
2037 1.1 lukem
2038 1.1 lukem if( ber != NULL ) {
2039 1.1 lukem ber_free( ber, 0 );
2040 1.1 lukem }
2041 1.1 lukem }
2042 1.1 lukem
2043 1.1 lukem static void print_reference(
2044 1.1 lukem LDAP *ld,
2045 1.1 lukem LDAPMessage *reference )
2046 1.1 lukem {
2047 1.1 lukem int rc;
2048 1.1 lukem char **refs = NULL;
2049 1.1 lukem LDAPControl **ctrls;
2050 1.1 lukem
2051 1.1 lukem if( ldif < 2 ) {
2052 1.1 lukem printf(_("# search reference\n"));
2053 1.1 lukem }
2054 1.1 lukem
2055 1.1 lukem rc = ldap_parse_reference( ld, reference, &refs, &ctrls, 0 );
2056 1.1 lukem
2057 1.1 lukem if( rc != LDAP_SUCCESS ) {
2058 1.1 lukem tool_perror( "ldap_parse_reference", rc, NULL, NULL, NULL, NULL );
2059 1.2 christos tool_exit( ld, EXIT_FAILURE );
2060 1.1 lukem }
2061 1.1 lukem
2062 1.1 lukem if( refs ) {
2063 1.1 lukem int i;
2064 1.1 lukem for( i=0; refs[i] != NULL; i++ ) {
2065 1.1 lukem tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
2066 1.1 lukem "ref", refs[i], strlen(refs[i]) );
2067 1.1 lukem }
2068 1.1 lukem ber_memvfree( (void **) refs );
2069 1.1 lukem }
2070 1.1 lukem
2071 1.1 lukem if( ctrls ) {
2072 1.1 lukem tool_print_ctrls( ld, ctrls );
2073 1.1 lukem ldap_controls_free( ctrls );
2074 1.1 lukem }
2075 1.1 lukem }
2076 1.1 lukem
2077 1.1 lukem static void print_extended(
2078 1.1 lukem LDAP *ld,
2079 1.1 lukem LDAPMessage *extended )
2080 1.1 lukem {
2081 1.1 lukem int rc;
2082 1.1 lukem char *retoid = NULL;
2083 1.1 lukem struct berval *retdata = NULL;
2084 1.1 lukem
2085 1.1 lukem if( ldif < 2 ) {
2086 1.1 lukem printf(_("# extended result response\n"));
2087 1.1 lukem }
2088 1.1 lukem
2089 1.1 lukem rc = ldap_parse_extended_result( ld, extended,
2090 1.1 lukem &retoid, &retdata, 0 );
2091 1.1 lukem
2092 1.1 lukem if( rc != LDAP_SUCCESS ) {
2093 1.1 lukem tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
2094 1.2 christos tool_exit( ld, EXIT_FAILURE );
2095 1.1 lukem }
2096 1.1 lukem
2097 1.1 lukem if ( ldif < 2 ) {
2098 1.1 lukem tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
2099 1.1 lukem "extended", retoid, retoid ? strlen(retoid) : 0 );
2100 1.1 lukem }
2101 1.1 lukem ber_memfree( retoid );
2102 1.1 lukem
2103 1.1 lukem if(retdata) {
2104 1.1 lukem if ( ldif < 2 ) {
2105 1.1 lukem tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
2106 1.1 lukem "data", retdata->bv_val, retdata->bv_len );
2107 1.1 lukem }
2108 1.1 lukem ber_bvfree( retdata );
2109 1.1 lukem }
2110 1.1 lukem
2111 1.1 lukem print_result( ld, extended, 0 );
2112 1.1 lukem }
2113 1.1 lukem
2114 1.3 christos static void print_syncinfo(
2115 1.3 christos BerValue *data )
2116 1.3 christos {
2117 1.3 christos BerElement *syncinfo;
2118 1.3 christos struct berval bv, cookie;
2119 1.3 christos ber_tag_t tag;
2120 1.3 christos ber_len_t len;
2121 1.3 christos
2122 1.3 christos if ( (syncinfo = ber_alloc()) == NULL ) {
2123 1.3 christos return;
2124 1.3 christos }
2125 1.3 christos ber_init2( syncinfo, data, 0 );
2126 1.3 christos
2127 1.3 christos printf(_("# SyncInfo Received: "));
2128 1.3 christos tag = ber_peek_tag( syncinfo, &len );
2129 1.3 christos switch (tag) {
2130 1.3 christos case LDAP_TAG_SYNC_NEW_COOKIE: {
2131 1.3 christos printf(_("new cookie\n"));
2132 1.3 christos ber_scanf( syncinfo, "m", &cookie );
2133 1.3 christos
2134 1.3 christos if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) {
2135 1.3 christos bv.bv_len = LUTIL_BASE64_ENCODE_LEN(
2136 1.3 christos cookie.bv_len ) + 1;
2137 1.3 christos bv.bv_val = ber_memalloc( bv.bv_len + 1 );
2138 1.3 christos
2139 1.3 christos bv.bv_len = lutil_b64_ntop(
2140 1.3 christos (unsigned char *) cookie.bv_val,
2141 1.3 christos cookie.bv_len,
2142 1.3 christos bv.bv_val, bv.bv_len );
2143 1.3 christos
2144 1.3 christos printf(_("# cookie:: %s\n"), bv.bv_val );
2145 1.3 christos ber_memfree( bv.bv_val );
2146 1.3 christos } else {
2147 1.3 christos printf(_("# cookie: %s\n"), cookie.bv_val );
2148 1.3 christos }
2149 1.3 christos } break;
2150 1.3 christos case LDAP_TAG_SYNC_REFRESH_DELETE: {
2151 1.3 christos ber_int_t done = 1;
2152 1.3 christos
2153 1.3 christos printf(_("refresh delete\n"));
2154 1.3 christos /* Skip sequence tag first */
2155 1.3 christos ber_skip_tag( syncinfo, &len );
2156 1.3 christos
2157 1.3 christos tag = ber_peek_tag( syncinfo, &len );
2158 1.3 christos if ( tag == LDAP_TAG_SYNC_COOKIE ) {
2159 1.3 christos ber_scanf( syncinfo, "m", &cookie );
2160 1.3 christos
2161 1.3 christos if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) {
2162 1.3 christos bv.bv_len = LUTIL_BASE64_ENCODE_LEN(
2163 1.3 christos cookie.bv_len ) + 1;
2164 1.3 christos bv.bv_val = ber_memalloc( bv.bv_len + 1 );
2165 1.3 christos
2166 1.3 christos bv.bv_len = lutil_b64_ntop(
2167 1.3 christos (unsigned char *) cookie.bv_val,
2168 1.3 christos cookie.bv_len,
2169 1.3 christos bv.bv_val, bv.bv_len );
2170 1.3 christos
2171 1.3 christos printf(_("# cookie:: %s\n"), bv.bv_val );
2172 1.3 christos ber_memfree( bv.bv_val );
2173 1.3 christos } else {
2174 1.3 christos printf(_("# cookie: %s\n"), cookie.bv_val );
2175 1.3 christos }
2176 1.3 christos
2177 1.3 christos tag = ber_peek_tag( syncinfo, &len );
2178 1.3 christos }
2179 1.3 christos if ( tag == LDAP_TAG_REFRESHDONE ) {
2180 1.3 christos ber_get_boolean( syncinfo, &done );
2181 1.3 christos }
2182 1.3 christos if ( done )
2183 1.3 christos printf(_("# refresh done, switching to persist stage\n"));
2184 1.3 christos } break;
2185 1.3 christos case LDAP_TAG_SYNC_REFRESH_PRESENT: {
2186 1.3 christos ber_int_t done = 1;
2187 1.3 christos
2188 1.3 christos printf(_("refresh present\n"));
2189 1.3 christos /* Skip sequence tag first */
2190 1.3 christos ber_skip_tag( syncinfo, &len );
2191 1.3 christos
2192 1.3 christos tag = ber_peek_tag( syncinfo, &len );
2193 1.3 christos if ( tag == LDAP_TAG_SYNC_COOKIE ) {
2194 1.3 christos ber_scanf( syncinfo, "m", &cookie );
2195 1.3 christos
2196 1.3 christos if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) {
2197 1.3 christos bv.bv_len = LUTIL_BASE64_ENCODE_LEN(
2198 1.3 christos cookie.bv_len ) + 1;
2199 1.3 christos bv.bv_val = ber_memalloc( bv.bv_len + 1 );
2200 1.3 christos
2201 1.3 christos bv.bv_len = lutil_b64_ntop(
2202 1.3 christos (unsigned char *) cookie.bv_val,
2203 1.3 christos cookie.bv_len,
2204 1.3 christos bv.bv_val, bv.bv_len );
2205 1.3 christos
2206 1.3 christos printf(_("# cookie:: %s\n"), bv.bv_val );
2207 1.3 christos ber_memfree( bv.bv_val );
2208 1.3 christos } else {
2209 1.3 christos printf(_("# cookie: %s\n"), cookie.bv_val );
2210 1.3 christos }
2211 1.3 christos
2212 1.3 christos tag = ber_peek_tag( syncinfo, &len );
2213 1.3 christos }
2214 1.3 christos if ( tag == LDAP_TAG_REFRESHDONE ) {
2215 1.3 christos ber_get_boolean( syncinfo, &done );
2216 1.3 christos }
2217 1.3 christos if ( done )
2218 1.3 christos printf(_("# refresh done, switching to persist stage\n"));
2219 1.3 christos } break;
2220 1.3 christos case LDAP_TAG_SYNC_ID_SET: {
2221 1.3 christos ber_int_t refreshDeletes = 0;
2222 1.3 christos BerVarray uuids;
2223 1.3 christos
2224 1.3 christos printf(_("ID Set\n"));
2225 1.3 christos /* Skip sequence tag first */
2226 1.3 christos ber_skip_tag( syncinfo, &len );
2227 1.3 christos
2228 1.3 christos tag = ber_peek_tag( syncinfo, &len );
2229 1.3 christos if ( tag == LDAP_TAG_SYNC_COOKIE ) {
2230 1.3 christos ber_scanf( syncinfo, "m", &cookie );
2231 1.3 christos
2232 1.3 christos if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) {
2233 1.3 christos bv.bv_len = LUTIL_BASE64_ENCODE_LEN(
2234 1.3 christos cookie.bv_len ) + 1;
2235 1.3 christos bv.bv_val = ber_memalloc( bv.bv_len + 1 );
2236 1.3 christos
2237 1.3 christos bv.bv_len = lutil_b64_ntop(
2238 1.3 christos (unsigned char *) cookie.bv_val,
2239 1.3 christos cookie.bv_len,
2240 1.3 christos bv.bv_val, bv.bv_len );
2241 1.3 christos
2242 1.3 christos printf(_("# cookie:: %s\n"), bv.bv_val );
2243 1.3 christos ber_memfree( bv.bv_val );
2244 1.3 christos } else {
2245 1.3 christos printf(_("# cookie: %s\n"), cookie.bv_val );
2246 1.3 christos }
2247 1.3 christos
2248 1.3 christos tag = ber_peek_tag( syncinfo, &len );
2249 1.3 christos }
2250 1.3 christos if ( tag == LDAP_TAG_REFRESHDELETES ) {
2251 1.3 christos ber_get_boolean( syncinfo, &refreshDeletes );
2252 1.3 christos tag = ber_peek_tag( syncinfo, &len );
2253 1.3 christos }
2254 1.3 christos if ( refreshDeletes ) {
2255 1.3 christos printf(_("# following UUIDs no longer match the search\n"));
2256 1.3 christos }
2257 1.3 christos
2258 1.3 christos printf(_("# syncUUIDs:\n"));
2259 1.3 christos ber_scanf( syncinfo, "[W]", &uuids );
2260 1.3 christos if ( uuids ) {
2261 1.3 christos char buf[LDAP_LUTIL_UUIDSTR_BUFSIZE];
2262 1.3 christos int i;
2263 1.3 christos
2264 1.3 christos for ( i=0; !BER_BVISNULL( &uuids[i] ); i++ ) {
2265 1.3 christos int rc = lutil_uuidstr_from_normalized(
2266 1.3 christos uuids[i].bv_val, uuids[i].bv_len,
2267 1.3 christos buf, LDAP_LUTIL_UUIDSTR_BUFSIZE );
2268 1.3 christos if ( rc <= 0 || rc >= LDAP_LUTIL_UUIDSTR_BUFSIZE ) {
2269 1.3 christos printf(_("#\t(UUID malformed)\n"));
2270 1.3 christos } else {
2271 1.3 christos printf(_("#\t%s\n"), buf);
2272 1.3 christos }
2273 1.3 christos }
2274 1.3 christos ber_bvarray_free( uuids );
2275 1.3 christos }
2276 1.3 christos } break;
2277 1.3 christos case LBER_DEFAULT:
2278 1.3 christos printf(_("empty SyncInfoValue\n"));
2279 1.3 christos default:
2280 1.3 christos printf(_("SyncInfoValue unknown\n"));
2281 1.3 christos break;
2282 1.3 christos }
2283 1.3 christos ber_free( syncinfo, 0 );
2284 1.3 christos }
2285 1.3 christos
2286 1.1 lukem static void print_partial(
2287 1.1 lukem LDAP *ld,
2288 1.1 lukem LDAPMessage *partial )
2289 1.1 lukem {
2290 1.1 lukem int rc;
2291 1.1 lukem char *retoid = NULL;
2292 1.1 lukem struct berval *retdata = NULL;
2293 1.1 lukem LDAPControl **ctrls = NULL;
2294 1.1 lukem
2295 1.1 lukem if( ldif < 2 ) {
2296 1.1 lukem printf(_("# extended partial response\n"));
2297 1.1 lukem }
2298 1.1 lukem
2299 1.1 lukem rc = ldap_parse_intermediate( ld, partial,
2300 1.1 lukem &retoid, &retdata, &ctrls, 0 );
2301 1.1 lukem
2302 1.1 lukem if( rc != LDAP_SUCCESS ) {
2303 1.1 lukem tool_perror( "ldap_parse_intermediate", rc, NULL, NULL, NULL, NULL );
2304 1.2 christos tool_exit( ld, EXIT_FAILURE );
2305 1.1 lukem }
2306 1.1 lukem
2307 1.1 lukem if ( ldif < 2 ) {
2308 1.1 lukem tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
2309 1.1 lukem "partial", retoid, retoid ? strlen(retoid) : 0 );
2310 1.1 lukem }
2311 1.1 lukem
2312 1.1 lukem ber_memfree( retoid );
2313 1.1 lukem
2314 1.1 lukem if( retdata ) {
2315 1.1 lukem if ( ldif < 2 ) {
2316 1.1 lukem tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
2317 1.1 lukem "data", retdata->bv_val, retdata->bv_len );
2318 1.1 lukem }
2319 1.1 lukem
2320 1.1 lukem ber_bvfree( retdata );
2321 1.1 lukem }
2322 1.1 lukem
2323 1.1 lukem if( ctrls ) {
2324 1.1 lukem tool_print_ctrls( ld, ctrls );
2325 1.1 lukem ldap_controls_free( ctrls );
2326 1.1 lukem }
2327 1.1 lukem }
2328 1.1 lukem
2329 1.1 lukem static int print_result(
2330 1.1 lukem LDAP *ld,
2331 1.1 lukem LDAPMessage *result, int search )
2332 1.1 lukem {
2333 1.1 lukem int rc;
2334 1.1 lukem int err;
2335 1.1 lukem char *matcheddn = NULL;
2336 1.1 lukem char *text = NULL;
2337 1.1 lukem char **refs = NULL;
2338 1.1 lukem LDAPControl **ctrls = NULL;
2339 1.1 lukem
2340 1.1 lukem if( search ) {
2341 1.1 lukem if ( ldif < 2 ) {
2342 1.1 lukem printf(_("# search result\n"));
2343 1.1 lukem }
2344 1.1 lukem if ( ldif < 1 ) {
2345 1.1 lukem printf("%s: %d\n", _("search"), ldap_msgid(result) );
2346 1.1 lukem }
2347 1.1 lukem }
2348 1.1 lukem
2349 1.1 lukem rc = ldap_parse_result( ld, result,
2350 1.1 lukem &err, &matcheddn, &text, &refs, &ctrls, 0 );
2351 1.1 lukem
2352 1.1 lukem if( rc != LDAP_SUCCESS ) {
2353 1.1 lukem tool_perror( "ldap_parse_result", rc, NULL, NULL, NULL, NULL );
2354 1.2 christos tool_exit( ld, EXIT_FAILURE );
2355 1.1 lukem }
2356 1.1 lukem
2357 1.1 lukem
2358 1.1 lukem if( !ldif ) {
2359 1.1 lukem printf( _("result: %d %s\n"), err, ldap_err2string(err) );
2360 1.1 lukem
2361 1.1 lukem } else if ( err != LDAP_SUCCESS ) {
2362 1.1 lukem fprintf( stderr, "%s (%d)\n", ldap_err2string(err), err );
2363 1.1 lukem }
2364 1.1 lukem
2365 1.1 lukem if( matcheddn ) {
2366 1.1 lukem if( *matcheddn ) {
2367 1.1 lukem if( !ldif ) {
2368 1.1 lukem tool_write_ldif( LDIF_PUT_VALUE,
2369 1.1 lukem "matchedDN", matcheddn, strlen(matcheddn) );
2370 1.1 lukem } else {
2371 1.1 lukem fprintf( stderr, _("Matched DN: %s\n"), matcheddn );
2372 1.1 lukem }
2373 1.1 lukem }
2374 1.1 lukem
2375 1.1 lukem ber_memfree( matcheddn );
2376 1.1 lukem }
2377 1.1 lukem
2378 1.1 lukem if( text ) {
2379 1.1 lukem if( *text ) {
2380 1.1 lukem if( !ldif ) {
2381 1.1 lukem if ( err == LDAP_PARTIAL_RESULTS ) {
2382 1.1 lukem char *line;
2383 1.1 lukem
2384 1.1 lukem for ( line = text; line != NULL; ) {
2385 1.1 lukem char *next = strchr( line, '\n' );
2386 1.1 lukem
2387 1.1 lukem tool_write_ldif( LDIF_PUT_TEXT,
2388 1.1 lukem "text", line,
2389 1.2 christos next ? (size_t) (next - line) : strlen( line ));
2390 1.1 lukem
2391 1.1 lukem line = next ? next + 1 : NULL;
2392 1.1 lukem }
2393 1.1 lukem
2394 1.1 lukem } else {
2395 1.1 lukem tool_write_ldif( LDIF_PUT_TEXT, "text",
2396 1.1 lukem text, strlen(text) );
2397 1.1 lukem }
2398 1.1 lukem } else {
2399 1.1 lukem fprintf( stderr, _("Additional information: %s\n"), text );
2400 1.1 lukem }
2401 1.1 lukem }
2402 1.1 lukem
2403 1.1 lukem ber_memfree( text );
2404 1.1 lukem }
2405 1.1 lukem
2406 1.1 lukem if( refs ) {
2407 1.1 lukem int i;
2408 1.1 lukem for( i=0; refs[i] != NULL; i++ ) {
2409 1.1 lukem if( !ldif ) {
2410 1.1 lukem tool_write_ldif( LDIF_PUT_VALUE, "ref", refs[i], strlen(refs[i]) );
2411 1.1 lukem } else {
2412 1.1 lukem fprintf( stderr, _("Referral: %s\n"), refs[i] );
2413 1.1 lukem }
2414 1.1 lukem }
2415 1.1 lukem
2416 1.1 lukem ber_memvfree( (void **) refs );
2417 1.1 lukem }
2418 1.1 lukem
2419 1.1 lukem pr_morePagedResults = 0;
2420 1.1 lukem
2421 1.1 lukem if( ctrls ) {
2422 1.1 lukem tool_print_ctrls( ld, ctrls );
2423 1.1 lukem ldap_controls_free( ctrls );
2424 1.1 lukem }
2425 1.1 lukem
2426 1.1 lukem return err;
2427 1.1 lukem }
2428