1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * The contents of this file are subject to the Netscape Public
8 * License Version 1.1 (the "License"); you may not use this file
9 * except in compliance with the License. You may obtain a copy of
10 * the License at http://www.mozilla.org/NPL/
11 *
12 * Software distributed under the License is distributed on an "AS
13 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * rights and limitations under the License.
16 *
17 * The Original Code is Mozilla Communicator client code, released
18 * March 31, 1998.
19 *
20 * The Initial Developer of the Original Code is Netscape
21 * Communications Corporation. Portions created by Netscape are
22 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
23 * Rights Reserved.
24 *
25 * Contributor(s):
26 */
27
28 /* ldapsearch.c - generic program to search LDAP */
29
30 #include "ldaptool.h"
31 #include "fileurl.h"
32 #ifdef SOLARIS_LDAP_CMD
33 #include <locale.h>
34 #include "solaris-int.h"
35 #endif /* SOLARIS_LDAP_CMD */
36
37 #define VLV_PARAM_SEP ':'
38
39 #ifndef SOLARIS_LDAP_CMD
40 #define gettext(s) s
41 #endif
42
43 static void usage( void );
44 static int dosearch( LDAP *ld, char *base, int scope, char **attrs,
45 int attrsonly, char *filtpatt, char *value);
46 static void write_string_attr_value( char *attrname, char *strval,
47 unsigned long opts );
48 #define LDAPTOOL_WRITEVALOPT_SUPPRESS_NAME 0x01
49 static int write_ldif_value( char *type, char *value, unsigned long vallen,
50 unsigned long ldifoptions );
51 static void print_entry( LDAP *ld, LDAPMessage *entry, int attrsonly );
52 static void options_callback( int option, char *optarg );
53 static void parse_and_display_reference( LDAP *ld, LDAPMessage *ref );
54 static char *sortresult2string(unsigned long result);
55 static char *changetype_num2string( int chgtype );
56 static char *msgtype2str( int msgtype );
57 static char **get_effectiverights_attrlist(char * optarg);
58
59 #ifdef SOLARIS_LDAP_CMD
60 static void fill_ldapsearch_msgtypes( void );
61 #endif /* SOLARIS_LDAP_CMD */
62
63 /*
64 * Prefix used in names of pseudo attributes added to the entry LDIF
65 * output if we receive an entryChangeNotification control with an entry
66 * (requested using persistent search).
67 */
68 #define LDAPTOOL_PSEARCH_ATTR_PREFIX "persistentSearch-"
69
70
71 static void
usage(void)72 usage( void )
73 {
74 fprintf( stderr, gettext("usage: %s -b basedn [options] filter [attributes...]\n"), ldaptool_progname );
75 fprintf( stderr, gettext(" %s -b basedn [options] -f file [attributes...]\nwhere:\n"), ldaptool_progname );
76 fprintf( stderr, gettext(" basedn\tbase dn for search\n") );
77 fprintf( stderr, gettext("\t\t(if the environment variable LDAP_BASEDN is set,\n") );
78 fprintf( stderr, gettext("\t\tthen the -b flag is not required)\n") );
79 fprintf( stderr, gettext(" filter\tRFC-2254 compliant LDAP search filter\n") );
80 fprintf( stderr, gettext(" file\tfile containing a sequence of LDAP search filters to use\n") );
81 fprintf( stderr, gettext(" attributes\twhitespace-separated list of attributes to retrieve\n") );
82 fprintf( stderr, gettext("\t\t(if no attribute list is given, all are retrieved)\n") );
83 fprintf( stderr, gettext("options:\n") );
84 ldaptool_common_usage( 0 );
85 #if defined( XP_WIN32 )
86 fprintf( stderr, gettext(" -t\t\twrite values to files in temp directory.\n") );
87 #else
88 fprintf( stderr, gettext(" -t\t\twrite values to files in /tmp\n") );
89 #endif
90 fprintf( stderr, gettext(" -U\t\tproduce file URLs in conjunction with -t\n") );
91 fprintf( stderr, gettext(" -e\t\tminimize base-64 encoding of values\n") );
92 fprintf( stderr, gettext(" -u\t\tinclude User Friendly entry names in the output\n") );
93 #ifndef HAVE_SASL_OPTIONS
94 fprintf( stderr, gettext(" -o\t\tprint entries using old format (default is LDIF)\n") );
95 #endif
96 fprintf( stderr, gettext(" -T\t\tdon't fold (wrap) long lines (default is to fold)\n") );
97 fprintf( stderr, gettext(" -1\t\tomit leading \"version: %d\" line in LDIF output\n"), LDIF_VERSION_ONE );
98 fprintf( stderr, gettext(" -A\t\tretrieve attribute names only (no values)\n") );
99 fprintf( stderr, gettext(" -B\t\tprint non-ASCII values and use old output format (attr=value)\n") );
100 fprintf( stderr, gettext(" -x\t\tperforming sorting on server\n") );
101 #ifdef SOLARIS_LDAP_CMD
102 fprintf( stderr, gettext(" -r\t\tprint entries using old format (default is LDIF)\n") );
103 #endif /* SOLARIS_LDAP_CMD */
104 fprintf( stderr, gettext(" -F sep\tprint `sep' instead of `%s' between attribute names\n"), LDAPTOOL_DEFSEP );
105 fprintf( stderr, gettext(" \tand values\n") );
106 fprintf( stderr, gettext(" -S attr\tsort the results by attribute `attr'\n") );
107 fprintf( stderr, gettext(" -s scope\tone of base, one, or sub (default is sub)\n") );
108 fprintf( stderr, gettext(" -a deref\tone of never, always, search, or find (default: never)\n") );
109 fprintf( stderr, gettext(" \t(alias dereferencing)\n") );
110 fprintf( stderr, gettext(" -l timelim\ttime limit (in seconds) for search (default is no limit)\n") );
111 fprintf( stderr, gettext(" -z sizelim\tsize limit (in entries) for search (default is no limit)\n") );
112 fprintf( stderr, gettext(" -C ps:changetype[:changesonly[:entrychgcontrols]]\n") );
113 fprintf( stderr, gettext("\t\tchangetypes are add,delete,modify,moddn,any\n") );
114 fprintf( stderr, gettext("\t\tchangesonly and entrychgcontrols are boolean values\n") );
115 fprintf( stderr, gettext("\t\t(default is 1)\n") );
116 fprintf( stderr, gettext(" -G before%cafter%cindex%ccount | before%cafter%cvalue where 'before' and\n"), VLV_PARAM_SEP, VLV_PARAM_SEP, VLV_PARAM_SEP, VLV_PARAM_SEP, VLV_PARAM_SEP );
117 fprintf( stderr, gettext("\t\t'after' are the number of entries surrounding 'index.'\n"));
118 fprintf( stderr, gettext("\t\t'count' is the content count, 'value' is the search value.\n"));
119 #ifndef SOLARIS_LDAP_CMD
120 fprintf( stderr, gettext(" -c authzid\tspecifies the getEffectiveRights control authzid\n"));
121 fprintf( stderr, gettext("\t\t eg. dn:uid=bjensen,dc=example,dc=com\n"));
122 fprintf( stderr, gettext("\t\t A value of \"\" means \"the authorization id for the operation\".\n"));
123 fprintf( stderr, gettext("\t\t A value of \"dn:\" means \"anonymous\"\n"));
124 fprintf( stderr, gettext("\t\t (The aclRights operational attribute must be requested)\n"));
125 fprintf( stderr, gettext(" -X attrlist\tspecifies the getEffectiveRights control specific attribute list.\n"));
126 fprintf( stderr, gettext("\t\t eg. \"nsroledn userPassword\"\n"));
127 #endif /* SOLARIS_LDAP_CMD */
128
129 exit( LDAP_PARAM_ERROR );
130 }
131
132 static char *base = NULL;
133 static char *sep = LDAPTOOL_DEFSEP;
134 static char **sortattr = NULL;
135 static char *vlv_value = NULL;
136 static int sortsize = 0;
137 static int *skipsortattr = NULL;
138 static int includeufn, allow_binary, vals2tmp, ldif, scope, deref;
139 static int attrsonly, timelimit, sizelimit, server_sort, fold;
140 static int minimize_base64, produce_file_urls;
141 static int use_vlv = 0, vlv_before, vlv_after, vlv_index, vlv_count;
142 static int use_psearch=0;
143 static int write_ldif_version = 1;
144 #ifndef SOLARIS_LDAP_CMD
145 static char *get_effectiverights_control_target_dn = NULL; /* -c */
146 static char **get_effectiverights_control_attrlist = NULL; /* -X */
147 static int do_effective_rights_control = 0;
148 #endif /* SOLARIS_LDAP_CMD */
149
150 /* Persistent search variables */
151 static int chgtype=0, changesonly=1, return_echg_ctls=1;
152
153
154 int
main(int argc,char ** argv)155 main( int argc, char **argv )
156 {
157 char *filtpattern, **attrs;
158 int rc, optind, i, first, free_filtpattern;
159 LDAP *ld;
160
161 #ifdef SOLARIS_LDAP_CMD
162 char *locale = setlocale(LC_ALL, "");
163 textdomain(TEXT_DOMAIN);
164 ldaptool_require_binddn = 0;
165 #endif /* SOLARIS_LDAP_CMD */
166
167 free_filtpattern = 0;
168 deref = LDAP_DEREF_NEVER;
169 allow_binary = vals2tmp = attrsonly = 0;
170 minimize_base64 = produce_file_urls = 0;
171 ldif = 1;
172 fold = 1;
173 sizelimit = timelimit = 0;
174 scope = LDAP_SCOPE_SUBTREE;
175 server_sort = 0;
176
177
178 #ifdef notdef
179 #ifdef HPUX11
180 #ifndef __LP64__
181 _main( argc, argv);
182 #endif /* __LP64_ */
183 #endif /* HPUX11 */
184 #endif
185
186
187 ldaptool_reset_control_array( ldaptool_request_ctrls );
188 #ifdef HAVE_SASL_OPTIONS
189 #ifdef SOLARIS_LDAP_CMD
190 optind = ldaptool_process_args( argc, argv, "ABLTU1etuxra:b:F:G:l:S:s:z:C:",
191 0, options_callback );
192 #else
193 optind = ldaptool_process_args( argc, argv, "ABLTU1etuxa:b:F:G:l:S:s:z:C:c:",
194 0, options_callback );
195 #endif /* SOLARIS_LDAP_CMD */
196 #else
197 optind = ldaptool_process_args( argc, argv, "ABLTU1eotuxa:b:F:G:l:S:s:z:C:c:",
198 0, options_callback );
199 #endif /* HAVE_SASL_OPTIONS */
200
201 if ( optind == -1 ) {
202 usage();
203 }
204
205 if ( base == NULL ) {
206 if (( base = getenv( "LDAP_BASEDN" )) == NULL ) {
207 usage();
208 }
209 }
210 if ( sortattr ) {
211 for ( sortsize = 0; sortattr[sortsize] != NULL; sortsize++ ) {
212 ; /* NULL */
213 }
214 sortsize++; /* add in the final NULL field */
215 skipsortattr = (int *) malloc( sortsize * sizeof(int *) );
216 if ( skipsortattr == NULL ) {
217 fprintf( stderr, gettext("Out of memory\n") );
218 exit( LDAP_NO_MEMORY );
219 }
220 memset( (char *) skipsortattr, 0, sortsize * sizeof(int *) );
221 } else if ( server_sort ) {
222 server_sort = 0; /* ignore this option if no sortattrs were given */
223 }
224
225 if ( argc - optind < 1 ) {
226 if ( ldaptool_fp == NULL ) {
227 usage();
228 }
229 attrs = NULL;
230 filtpattern = "%s";
231 } else { /* there are additional args (filter + attrs) */
232 if ( ldaptool_fp == NULL || strstr( argv[ optind ], "%s" ) != NULL ) {
233 filtpattern = ldaptool_local2UTF8( argv[ optind ] );
234 /* since local2UTF8 always allocates something, we should free it */
235 free_filtpattern = 1;
236 ++optind;
237 } else {
238 filtpattern = "%s";
239 }
240
241 if ( argv[ optind ] == NULL ) {
242 attrs = NULL;
243 } else if ( sortattr == NULL || *sortattr == NULL || server_sort) {
244 attrs = &argv[ optind ];
245 } else {
246 attrs = ldap_charray_dup( &argv[ optind ] );
247 if ( attrs == NULL ) {
248 fprintf( stderr, gettext("Out of memory\n") );
249 exit( LDAP_NO_MEMORY );
250 }
251 for ( i = 0; i < (sortsize - 1); i++ ) {
252 if ( !ldap_charray_inlist( attrs, sortattr[i] ) ) {
253 if ( ldap_charray_add( &attrs, sortattr[i] ) != 0 ) {
254 fprintf( stderr, gettext("Out of memory\n") );
255 exit( LDAP_NO_MEMORY );
256 }
257 /*
258 * attribute in the search list only for the purpose of
259 * sorting
260 */
261 skipsortattr[i] = 1;
262 }
263 }
264 }
265 }
266
267 ld = ldaptool_ldap_init( 0 );
268
269 if ( !ldaptool_not ) {
270 ldap_set_option( ld, LDAP_OPT_DEREF, &deref );
271 ldap_set_option( ld, LDAP_OPT_TIMELIMIT, &timelimit );
272 ldap_set_option( ld, LDAP_OPT_SIZELIMIT, &sizelimit );
273 }
274
275 ldaptool_bind( ld );
276
277 if ( ldaptool_verbose ) {
278 printf( gettext("filter pattern: %s\nreturning: "), filtpattern );
279 if ( attrs == NULL ) {
280 printf( gettext("ALL") );
281 } else {
282 for ( i = 0; attrs[ i ] != NULL; ++i ) {
283 printf( "%s ", attrs[ i ] );
284 }
285 }
286 putchar( '\n' );
287 }
288
289 if ( ldaptool_fp == NULL ) {
290 char *conv;
291
292 conv = ldaptool_local2UTF8( base );
293 rc = dosearch( ld, conv, scope, attrs, attrsonly, filtpattern, "" );
294 if( conv != NULL )
295 free( conv );
296 } else {
297 int done = 0;
298
299 rc = LDAP_SUCCESS;
300 first = 1;
301 while ( rc == LDAP_SUCCESS && !done ) {
302 char *linep = NULL;
303 int increment = 0;
304 int c, index;
305
306 /* allocate initial block of memory */
307 if ((linep = (char *)malloc(BUFSIZ)) == NULL) {
308 fprintf( stderr, gettext("Out of memory\n") );
309 exit( LDAP_NO_MEMORY );
310 }
311 increment++;
312 index = 0;
313 while ((c = fgetc( ldaptool_fp )) != '\n' && c != EOF) {
314
315 /* check if we will overflow the buffer */
316 if ((c != EOF) && (index == ((increment * BUFSIZ) -1))) {
317
318 /* if we did, add another BUFSIZ worth of bytes */
319 if ((linep = (char *)
320 realloc(linep, (increment + 1) * BUFSIZ)) == NULL) {
321 fprintf( stderr, gettext("Out of memory\n") );
322 exit( LDAP_NO_MEMORY );
323 }
324 increment++;
325 }
326 linep[index++] = c;
327 }
328
329 if (c == EOF) {
330 done = 1;
331 break;
332 }
333
334 linep[index] = '\0';
335
336 if ( !first ) {
337 putchar( '\n' );
338 } else {
339 first = 0;
340 }
341 rc = dosearch( ld, base, scope, attrs, attrsonly, filtpattern,
342 linep );
343 free (linep);
344 }
345 }
346
347 ldaptool_cleanup( ld );
348 if (free_filtpattern != 0 && filtpattern != NULL) {
349 free (filtpattern);
350 }
351
352 /* check for and report output error */
353 fflush( stdout );
354 rc = ldaptool_check_ferror( stdout, rc,
355 gettext("output error (output might be incomplete)") );
356 return( rc );
357 }
358
359
360 static void
options_callback(int option,char * optarg)361 options_callback( int option, char *optarg )
362 {
363 char *s, *temp_arg, *ps_ptr, *ps_arg;
364
365 switch( option ) {
366 case 'u': /* include UFN */
367 ++includeufn;
368 break;
369 case 't': /* write attribute values to /tmp files */
370 ++vals2tmp;
371 break;
372 case 'U': /* produce file URLs in conjunction with -t */
373 ++produce_file_urls;
374 break;
375 case 'e': /* minimize base-64 encoding of values */
376 ++minimize_base64;
377 break;
378 case 'A': /* retrieve attribute names only -- no values */
379 ++attrsonly;
380 break;
381 case 'L': /* print entries in LDIF format -- now the default */
382 break;
383 #ifdef SOLARIS_LDAP_CMD
384 case 'r': /* print entries in the old format */
385 ldif = 0;
386 break;
387 #endif /* SOLARIS_LDAP_CMD */
388 #ifdef HAVE_SASL_OPTIONS
389 #ifdef HAVE_SASL_OPTIONS_2
390 case 'o': /* print entries using old ldapsearch format */
391 ldif = 0;
392 break;
393 #endif
394 #else
395 case 'o': /* print entries using old ldapsearch format */
396 ldif = 0;
397 break;
398 #endif
399 case 'B': /* allow binary values to be printed, use old format */
400 ++allow_binary;
401 ldif = 0;
402 break;
403 case '1': /* omit leading "version: #" line from LDIF output */
404 write_ldif_version = 0;
405 break;
406 case 's': /* search scope */
407 if ( strncasecmp( optarg, "base", 4 ) == 0 ) {
408 scope = LDAP_SCOPE_BASE;
409 } else if ( strncasecmp( optarg, "one", 3 ) == 0 ) {
410 scope = LDAP_SCOPE_ONELEVEL;
411 } else if ( strncasecmp( optarg, "sub", 3 ) == 0 ) {
412 scope = LDAP_SCOPE_SUBTREE;
413 } else {
414 fprintf( stderr, gettext("scope should be base, one, or sub\n") );
415 usage();
416 }
417 break;
418
419 case 'a': /* set alias deref option */
420 if ( strncasecmp( optarg, "never", 5 ) == 0 ) {
421 deref = LDAP_DEREF_NEVER;
422 } else if ( strncasecmp( optarg, "search", 5 ) == 0 ) {
423 deref = LDAP_DEREF_SEARCHING;
424 } else if ( strncasecmp( optarg, "find", 4 ) == 0 ) {
425 deref = LDAP_DEREF_FINDING;
426 } else if ( strncasecmp( optarg, "always", 6 ) == 0 ) {
427 deref = LDAP_DEREF_ALWAYS;
428 } else {
429 fprintf( stderr, gettext("alias deref should be never, search, find, or always\n") );
430 usage();
431 }
432 break;
433
434 case 'F': /* field separator */
435 sep = strdup( optarg );
436 ldif = 0;
437 break;
438 #ifndef SOLARIS_LDAP_CMD
439 case 'c':
440 if ( optarg && optarg[0] == '\0' ) {
441 /* -c ""
442 means "This user"
443 */
444 get_effectiverights_control_target_dn = NULL;
445 do_effective_rights_control = 1;
446 }else if ( strlen(optarg) < 3 || (strncasecmp(optarg, "dn:", 3) != 0) ) {
447 fprintf(stderr, gettext("-c wrong format--should be \"\" or \"dn:...\".\n"
448 "\"dn:\" means anonymous user."));
449 usage();
450 } else {
451 get_effectiverights_control_target_dn = strdup(optarg);
452 do_effective_rights_control = 1;
453 }
454 break;
455 case 'X':
456 get_effectiverights_control_attrlist = get_effectiverights_attrlist(optarg);
457 do_effective_rights_control = 1;
458 break;
459 #endif /* SOLARIS_LDAP_CMD */
460 case 'b': /* searchbase */
461 base = strdup( optarg );
462 break;
463 case 'l': /* time limit */
464 timelimit = atoi( optarg );
465 break;
466 case 'x': /* server sorting requested */
467 server_sort = 1;
468 break;
469 case 'z': /* size limit */
470 sizelimit = atoi( optarg );
471 break;
472 case 'S': /* sort attribute */
473 ldap_charray_add( &sortattr, strdup( optarg ) );
474 break;
475 case 'T': /* don't fold lines */
476 fold = 0;
477 break;
478 case 'G': /* do the virtual list setup */
479 use_vlv++;
480 s = strchr(optarg, VLV_PARAM_SEP );
481
482 if (s != NULL)
483 {
484 vlv_before = atoi(optarg);
485 s++;
486 vlv_after = atoi( s );
487 s = strchr(s, VLV_PARAM_SEP );
488 if (s != NULL)
489 {
490 s++;
491 /* below is a small set of logic to implement the following cases
492 * -G23:23:wilber
493 * -G23:23:"wilber:wright"
494 * -G23:23:'wilber'
495 * -G23:23:wilber wright
496 * all of the above are before, after, value - NOTE: a colon not in a quoted
497 * string will break the parser!!!!
498 * -G23:23:45:600
499 * above is index, count encoding
500 */
501
502 if (*s == '\'' || *s == '"')
503 {
504 vlv_value = strdup( s );
505 }
506 else
507 {
508 if (strchr( s, VLV_PARAM_SEP ))
509 {
510 /* we have an index + count option */
511 vlv_index = atoi( s );
512 vlv_count = atoi( strchr( s, VLV_PARAM_SEP) + 1);
513 }
514 else
515 {
516 /* we don't have a quote surrounding the assertion value
517 * do we need to???
518 */
519 vlv_value = strdup( s );
520 }
521 }
522 }
523 else
524 {
525 fprintf( stderr,gettext("Illegal 'after' paramater for virtual list\n") );
526 exit( LDAP_PARAM_ERROR );
527 }
528
529 }
530 else
531 {
532 fprintf( stderr,gettext("Illegal 'before' paramater for virtual list\n") );
533 exit( LDAP_PARAM_ERROR );
534 }
535 break;
536 case 'C':
537 use_psearch++;
538 if ( (ps_arg = strdup( optarg)) == NULL ) {
539 perror ("strdup");
540 exit (LDAP_NO_MEMORY);
541 }
542
543 ps_ptr=strtok(ps_arg, ":");
544 if (ps_ptr == NULL || (strcasecmp(ps_ptr, "ps")) ) {
545 fprintf (stderr, gettext("Invalid argument for -C\n"));
546 usage();
547 }
548 if (NULL != (ps_ptr=strtok(NULL, ":"))) {
549 if ( (temp_arg = strdup( ps_ptr )) == NULL ) {
550 perror ("strdup");
551 exit (LDAP_NO_MEMORY);
552 }
553 } else {
554 fprintf (stderr, gettext("Invalid argument for -C\n"));
555 usage();
556 }
557 if (NULL != (ps_ptr=strtok(NULL, ":"))) {
558 if ( (changesonly = ldaptool_boolean_str2value(ps_ptr, 0)) == -1) {
559 fprintf(stderr, gettext("Invalid option value: %s\n"), ps_ptr);
560 usage();
561 }
562 }
563 if (NULL != (ps_ptr=strtok(NULL, ":"))) {
564 if ( (return_echg_ctls = ldaptool_boolean_str2value(ps_ptr, 0)) == -1) {
565 fprintf(stderr, gettext("Invalid option value: %s\n"), ps_ptr);
566 usage();
567 }
568 }
569
570 /* Now parse the temp_arg and build chgtype as
571 * the changetypes are encountered */
572
573 if ((ps_ptr = strtok( temp_arg, "," )) == NULL) {
574 usage();
575 } else {
576 while ( ps_ptr ) {
577 if ((strcasecmp(ps_ptr, "add"))==0)
578 chgtype |= LDAP_CHANGETYPE_ADD;
579 else if ((strcasecmp(ps_ptr, "delete"))==0)
580 chgtype |= LDAP_CHANGETYPE_DELETE;
581 else if ((strcasecmp(ps_ptr, "modify"))==0)
582 chgtype |= LDAP_CHANGETYPE_MODIFY;
583 else if ((strcasecmp(ps_ptr, "moddn"))==0)
584 chgtype |= LDAP_CHANGETYPE_MODDN;
585 else if ((strcasecmp(ps_ptr, "any"))==0)
586 chgtype = LDAP_CHANGETYPE_ANY;
587 else {
588 fprintf(stderr, gettext("Unknown changetype: %s\n"), ps_ptr);
589 usage();
590 }
591 ps_ptr = strtok( NULL, "," );
592 }
593 }
594 break;
595 default:
596 usage();
597 break;
598 }
599 }
600
601
602 static int
dosearch(ld,base,scope,attrs,attrsonly,filtpatt,value)603 dosearch( ld, base, scope, attrs, attrsonly, filtpatt, value )
604 LDAP *ld;
605 char *base;
606 int scope;
607 char **attrs;
608 int attrsonly;
609 char *filtpatt;
610 char *value;
611 {
612 char **refs = NULL, filter[ BUFSIZ ], *filterp = NULL;
613 int rc, first, matches;
614 LDAPMessage *res, *e;
615 LDAPControl *ldctrl;
616 LDAPControl **ctrl_response_array = NULL;
617 LDAPVirtualList vlv_data;
618 int msgid = 0;
619 int length = 0;
620 int mallocd_filter = 0;
621
622 if ( strstr( filtpatt, "%s" ) == NULL ) { /* no need to sprintf() */
623 filterp = filtpatt;
624 } else {
625 length = strlen( filtpatt ) + strlen ( value ) +1;
626 if ( length > BUFSIZ ) {
627 if ((filterp = (char *)
628 malloc ( length )) == NULL) {
629 perror( gettext("filter and/or pattern too long?") );
630 exit (LDAP_PARAM_ERROR);
631 }
632 mallocd_filter = 1;
633 } else {
634 filterp = filter;
635 }
636
637 #ifdef HAVE_SNPRINTF
638 if ( snprintf( filterp, length, filtpatt, value ) < 0 ) {
639 perror( gettext("snprintf filter (filter and/or pattern too long?)") );
640 exit( LDAP_PARAM_ERROR );
641 }
642 #else
643 sprintf( filterp, filtpatt, value );
644 #endif
645 }
646
647 if ( *filterp == '\0' ) { /* treat empty filter is a shortcut for oc=* */
648 if (mallocd_filter) {
649 free(filterp);
650 mallocd_filter = 0;
651 }
652 filterp = "(objectclass=*)";
653 }
654
655 if ( ldaptool_verbose ) {
656 /*
657 * Display the filter that will be used. Add surrounding parens.
658 * if they are missing.
659 */
660 if ( '(' == *filterp ) {
661 printf( "filter is: %s\n", filterp );
662 } else {
663 printf( "filter is: (%s)\n", filterp );
664 }
665 }
666
667 if ( ldaptool_not ) {
668 if (mallocd_filter) free(filterp);
669 return( LDAP_SUCCESS );
670 }
671
672 if (( ldctrl = ldaptool_create_manage_dsait_control()) != NULL ) {
673 ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls);
674 }
675
676 if ((ldctrl = ldaptool_create_proxyauth_control(ld)) !=NULL) {
677 ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls);
678 }
679
680 #ifndef SOLARIS_LDAP_CMD
681 if ( do_effective_rights_control ) {
682 if ((ldctrl = ldaptool_create_geteffectiveRights_control(ld,
683 get_effectiverights_control_target_dn,
684 (const char**) get_effectiverights_control_attrlist)) !=NULL) {
685 ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls);
686 }
687 }
688 #endif /* SOLARIS_LDAP_CMD */
689
690 if (use_psearch) {
691 if ( ldap_create_persistentsearch_control( ld, chgtype,
692 changesonly, return_echg_ctls,
693 1, &ldctrl ) != LDAP_SUCCESS )
694 {
695 ldap_perror( ld, "ldap_create_persistentsearch_control" );
696 return (1);
697 }
698 ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls);
699 }
700
701
702 if (server_sort) {
703 /* First make a sort key list from the attribute list we have */
704 LDAPsortkey **keylist = NULL;
705 int i = 0;
706 char *sortattrs = NULL;
707 char *s = NULL;
708 int string_length = 0;
709
710 /* Count the sort strings */
711 for (i = 0; i < sortsize - 1 ; i++) {
712 string_length += strlen(sortattr[i]) + 1;
713 }
714
715 sortattrs = (char *) malloc(string_length + 1);
716 if (NULL == sortattrs) {
717 fprintf( stderr, gettext("Out of memory\n") );
718 exit( LDAP_NO_MEMORY );
719 }
720
721 s = sortattrs;
722 for (i = 0; i < sortsize - 1 ; i++) {
723 memcpy(s, sortattr[i], strlen(sortattr[i]));
724 s += strlen(sortattr[i]);
725 *s++ = ' ';
726 }
727
728 sortattrs[string_length] = '\0';
729
730 ldap_create_sort_keylist(&keylist,sortattrs);
731 free(sortattrs);
732 sortattrs = NULL;
733
734 /* Then make a control for the sort attributes we have */
735 rc = ldap_create_sort_control(ld,keylist,0,&ldctrl);
736 ldap_free_sort_keylist(keylist);
737 if ( rc != LDAP_SUCCESS ) {
738 if (mallocd_filter) free(filterp);
739 return( ldaptool_print_lderror( ld, "ldap_create_sort_control",
740 LDAPTOOL_CHECK4SSL_IF_APPROP ));
741 }
742
743 ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls);
744
745 }
746 /* remember server side sorting must be available for vlv!!!! */
747
748 if (use_vlv)
749 {
750 vlv_data.ldvlist_before_count = vlv_before;
751 vlv_data.ldvlist_after_count = vlv_after;
752 if ( ldaptool_verbose ) {
753 printf( gettext("vlv data %lu, %lu, "),
754 vlv_data.ldvlist_before_count,
755 vlv_data.ldvlist_after_count
756 );
757 }
758 if (vlv_value)
759 {
760 vlv_data.ldvlist_attrvalue = vlv_value;
761 vlv_data.ldvlist_size = 0;
762 vlv_data.ldvlist_index = 0;
763 if ( ldaptool_verbose ) {
764 printf( "%s, 0, 0\n", vlv_data.ldvlist_attrvalue);
765 }
766 }
767 else
768 {
769 vlv_data.ldvlist_attrvalue = NULL;
770 vlv_data.ldvlist_size = vlv_count;
771 vlv_data.ldvlist_index = vlv_index;
772 if ( ldaptool_verbose ) {
773 printf( "(null), %lu, %lu\n", vlv_data.ldvlist_size, vlv_data.ldvlist_index );
774 }
775 }
776
777 if ( rc != LDAP_SUCCESS ) {
778 if (mallocd_filter) free(filterp);
779 return( ldaptool_print_lderror( ld, "ldap_create_sort_control",
780 LDAPTOOL_CHECK4SSL_IF_APPROP ));
781 }
782 if (LDAP_SUCCESS != (rc = ldap_create_virtuallist_control(ld,
783 &vlv_data, &ldctrl)))
784 {
785 if (mallocd_filter) free(filterp);
786 return( ldaptool_print_lderror( ld,
787 "ldap_create_virtuallist_control",
788 LDAPTOOL_CHECK4SSL_IF_APPROP ));
789 }
790
791 ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls);
792
793 }
794
795 if ( ldap_search_ext( ld, base, scope, filterp, attrs, attrsonly,
796 ldaptool_request_ctrls, NULL, NULL, -1, &msgid )
797 != LDAP_SUCCESS ) {
798 if (mallocd_filter) free(filterp);
799 return( ldaptool_print_lderror( ld, "ldap_search",
800 LDAPTOOL_CHECK4SSL_IF_APPROP ));
801 }
802
803
804 matches = 0;
805 first = 1;
806 if ( sortattr && !server_sort ) {
807 rc = ldap_result( ld, LDAP_RES_ANY, 1, NULL, &res );
808 } else {
809 while ( (rc = ldap_result( ld, LDAP_RES_ANY, 0, NULL, &res )) !=
810 LDAP_RES_SEARCH_RESULT && rc != -1 ) {
811 if ( rc != LDAP_RES_SEARCH_ENTRY ) {
812 if ( rc == LDAP_RES_SEARCH_REFERENCE ) {
813 parse_and_display_reference( ld, res );
814 } else if ( rc == LDAP_RES_EXTENDED
815 && ldap_msgid( res ) == LDAP_RES_UNSOLICITED ) {
816 ldaptool_print_extended_response( ld, res,
817 gettext("Unsolicited response") );
818 } else {
819 fprintf( stderr, gettext("%s: ignoring LDAP response message"
820 " type 0x%x (%s)\n"),
821 ldaptool_progname, rc, msgtype2str( rc ));
822 }
823 ldap_msgfree( res );
824 continue;
825 }
826 matches++;
827 e = ldap_first_entry( ld, res );
828 if ( !first ) {
829 putchar( '\n' );
830 } else {
831 first = 0;
832 }
833 print_entry( ld, e, attrsonly );
834 ldap_msgfree( res );
835 }
836 }
837 if ( rc == -1 ) {
838 if (mallocd_filter) free(filterp);
839 return( ldaptool_print_lderror( ld, "ldap_result",
840 LDAPTOOL_CHECK4SSL_IF_APPROP ));
841 }
842
843 if ( ldap_parse_result( ld, res, &rc, NULL, NULL, &refs,
844 &ctrl_response_array, 0 ) != LDAP_SUCCESS ) {
845 ldaptool_print_lderror( ld, "ldap_parse_result",
846 LDAPTOOL_CHECK4SSL_IF_APPROP );
847 } else if ( rc != LDAP_SUCCESS ) {
848 ldaptool_print_lderror( ld, "ldap_search",
849 LDAPTOOL_CHECK4SSL_IF_APPROP );
850 }
851 /* Parse the returned sort control */
852 if (server_sort) {
853 unsigned long result = 0;
854 char *attribute;
855
856 if ( LDAP_SUCCESS != ldap_parse_sort_control(ld,ctrl_response_array,&result,&attribute) ) {
857 ldaptool_print_lderror(ld, "ldap_parse_sort_control",
858 LDAPTOOL_CHECK4SSL_IF_APPROP );
859 ldap_controls_free(ctrl_response_array);
860 ldap_msgfree(res);
861 if (mallocd_filter) free(filterp);
862 return ( ldap_get_lderrno( ld, NULL, NULL ) );
863 }
864
865 if (0 == result) {
866 if ( ldaptool_verbose ) {
867 printf( gettext("Server indicated results sorted OK\n"));
868 }
869 } else {
870 if (NULL != attribute) {
871 printf(gettext("Server reported sorting error %ld: %s, attribute in error\"%s\"\n"),result,sortresult2string(result),attribute);
872 } else {
873 printf(gettext("Server reported sorting error %ld: %s\n"),result,sortresult2string(result));
874 }
875 }
876
877 }
878
879 if (use_vlv)
880 {
881 unsigned long vpos, vcount;
882 int vresult;
883 if ( LDAP_SUCCESS != ldap_parse_virtuallist_control(ld,ctrl_response_array,&vpos, &vcount,&vresult) ) {
884 ldaptool_print_lderror( ld, "ldap_parse_virtuallist_control",
885 LDAPTOOL_CHECK4SSL_IF_APPROP );
886 ldap_controls_free(ctrl_response_array);
887 ldap_msgfree(res);
888 if (mallocd_filter) free(filterp);
889 return ( ldap_get_lderrno( ld, NULL, NULL ) );
890 }
891
892 if (0 == vresult) {
893 if ( ldaptool_verbose ) {
894 printf( gettext("Server indicated virtual list positioning OK\n"));
895 }
896 printf(gettext("index %lu content count %lu\n"), vpos, vcount);
897
898 } else {
899 printf(gettext("Server reported sorting error %d: %s\n"),vresult,sortresult2string(vresult));
900
901 }
902
903 }
904
905 ldap_controls_free(ctrl_response_array);
906
907 if ( sortattr != NULL && !server_sort) {
908
909 (void) ldap_multisort_entries( ld, &res,
910 ( *sortattr == NULL ) ? NULL : sortattr,
911 (LDAP_CMP_CALLBACK *)strcasecmp );
912 matches = 0;
913 first = 1;
914 for ( e = ldap_first_entry( ld, res ); e != NULLMSG;
915 e = ldap_next_entry( ld, e ) ) {
916 matches++;
917 if ( !first ) {
918 putchar( '\n' );
919 } else {
920 first = 0;
921 }
922 print_entry( ld, e, attrsonly );
923 }
924 }
925
926 if ( ldaptool_verbose ) {
927 printf( gettext("%d matches\n"), matches );
928 }
929
930 if ( refs != NULL ) {
931 ldaptool_print_referrals( refs );
932 ldap_value_free( refs );
933 }
934
935 if (mallocd_filter) free(filterp);
936
937 ldap_msgfree( res );
938 return( rc );
939 }
940
941
942 static void
print_entry(ld,entry,attrsonly)943 print_entry( ld, entry, attrsonly )
944 LDAP *ld;
945 LDAPMessage *entry;
946 int attrsonly;
947 {
948 char *a, *dn, *ufn, tmpfname[ BUFSIZ ];
949 int i, notascii;
950 BerElement *ber;
951 struct berval **bvals;
952 FILE *tmpfp;
953 #if defined( XP_WIN32 )
954 char mode[20] = "w+b";
955 #else
956 char mode[20] = "w";
957 #endif
958
959 dn = ldap_get_dn( ld, entry );
960 write_string_attr_value( "dn", dn, LDAPTOOL_WRITEVALOPT_SUPPRESS_NAME );
961 if ( includeufn ) {
962 ufn = ldap_dn2ufn( dn );
963 write_string_attr_value( "ufn", ufn,
964 LDAPTOOL_WRITEVALOPT_SUPPRESS_NAME );
965 free( ufn );
966 }
967 ldap_memfree( dn );
968
969 if ( use_psearch ) {
970 LDAPControl **ectrls;
971 int chgtype, chgnumpresent;
972 #ifdef SOLARIS_LDAP_CMD
973 ber_int_t chgnum;
974 #else
975 long chgnum;
976 #endif /* SOLARIS_LDAP_CMD */
977 char *prevdn, longbuf[ 128 ];
978
979 if ( ldap_get_entry_controls( ld, entry, &ectrls ) == LDAP_SUCCESS ) {
980 if ( ldap_parse_entrychange_control( ld, ectrls, &chgtype,
981 &prevdn, &chgnumpresent, &chgnum ) == LDAP_SUCCESS ) {
982 write_string_attr_value(
983 LDAPTOOL_PSEARCH_ATTR_PREFIX "changeType",
984 changetype_num2string( chgtype ), 0 );
985 if ( chgnumpresent ) {
986 sprintf( longbuf, "%d", chgnum );
987 write_string_attr_value(
988 LDAPTOOL_PSEARCH_ATTR_PREFIX "changeNumber",
989 longbuf, 0 );
990 }
991 if ( NULL != prevdn ) {
992 write_string_attr_value(
993 LDAPTOOL_PSEARCH_ATTR_PREFIX "previousDN",
994 prevdn, 0 );
995 ldap_memfree( prevdn );
996 }
997 }
998 ldap_controls_free (ectrls);
999 }
1000 }
1001
1002 for ( a = ldap_first_attribute( ld, entry, &ber ); a != NULL;
1003 a = ldap_next_attribute( ld, entry, ber ) ) {
1004 if ( ldap_charray_inlist(sortattr, a) && /* in the list*/
1005 skipsortattr[ldap_charray_position(sortattr, a)] ) {/* and skip it*/
1006 continue; /* so skip it! */
1007 }
1008 if ( attrsonly ) {
1009 if ( ldif ) {
1010 write_ldif_value( a, "", 0, 0 );
1011 } else {
1012 printf( "%s\n", a );
1013 }
1014 } else if (( bvals = ldap_get_values_len( ld, entry, a )) != NULL ) {
1015 for ( i = 0; bvals[i] != NULL; i++ ) {
1016 if ( vals2tmp ) {
1017 #ifdef HAVE_SNPRINTF
1018 if ( snprintf( tmpfname, sizeof(tmpfname),
1019 "%s/ldapsearch-%s-XXXXXX",
1020 ldaptool_get_tmp_dir(), a ) < 0 ) {
1021 perror( gettext("snprintf tmpfname (attribute name too long?)") );
1022 exit( LDAP_PARAM_ERROR );
1023 }
1024 #else
1025 sprintf( tmpfname, "%s/ldapsearch-%s-XXXXXX",
1026 ldaptool_get_tmp_dir(), a );
1027 #endif
1028 tmpfp = NULL;
1029
1030 if ( LDAPTOOL_MKTEMP( tmpfname ) == NULL ) {
1031 perror( tmpfname );
1032 } else if (( tmpfp = ldaptool_open_file( tmpfname, mode)) == NULL ) {
1033 perror( tmpfname );
1034 } else if ( bvals[ i ]->bv_len > 0 &&
1035 fwrite( bvals[ i ]->bv_val,
1036 bvals[ i ]->bv_len, 1, tmpfp ) == 0 ) {
1037 perror( tmpfname );
1038 } else if ( ldif ) {
1039 if ( produce_file_urls ) {
1040 char *url;
1041
1042 if ( ldaptool_path2fileurl( tmpfname, &url ) !=
1043 LDAPTOOL_FILEURL_SUCCESS ) {
1044 perror( "ldaptool_path2fileurl" );
1045 } else {
1046 write_ldif_value( a, url, strlen( url ),
1047 LDIF_OPT_VALUE_IS_URL );
1048 free( url );
1049 }
1050 } else {
1051 write_ldif_value( a, tmpfname, strlen( tmpfname ),
1052 0 );
1053 }
1054 } else {
1055 printf( "%s%s%s\n", a, sep, tmpfname );
1056 }
1057
1058 if ( tmpfp != NULL ) {
1059 fclose( tmpfp );
1060 }
1061 } else {
1062 notascii = 0;
1063 if ( !ldif && !allow_binary ) {
1064 notascii = !ldaptool_berval_is_ascii( bvals[i] );
1065 }
1066
1067 if ( ldif ) {
1068 write_ldif_value( a, bvals[ i ]->bv_val,
1069 bvals[ i ]->bv_len, 0 );
1070 } else {
1071 printf( "%s%s%s\n", a, sep,
1072 notascii ? gettext("NOT ASCII") : bvals[ i ]->bv_val );
1073 }
1074 }
1075 }
1076 ber_bvecfree( bvals );
1077 }
1078 ldap_memfree( a );
1079 }
1080
1081 if ( ldap_get_lderrno( ld, NULL, NULL ) != LDAP_SUCCESS ) {
1082 ldaptool_print_lderror( ld, "ldap_first_attribute/ldap_next_attribute",
1083 LDAPTOOL_CHECK4SSL_IF_APPROP );
1084 }
1085
1086 if ( ber != NULL ) {
1087 ber_free( ber, 0 );
1088 }
1089 }
1090
1091
1092 static void
write_string_attr_value(char * attrname,char * strval,unsigned long opts)1093 write_string_attr_value( char *attrname, char *strval, unsigned long opts )
1094 {
1095 if ( strval == NULL ) {
1096 strval = "";
1097 }
1098 if ( ldif ) {
1099 write_ldif_value( attrname, strval, strlen( strval ), 0 );
1100 } else if ( 0 != ( opts & LDAPTOOL_WRITEVALOPT_SUPPRESS_NAME )) {
1101 printf( "%s\n", strval );
1102 } else {
1103 printf( "%s%s%s\n", attrname, sep, strval );
1104 }
1105 }
1106
1107
1108 static int
write_ldif_value(char * type,char * value,unsigned long vallen,unsigned long ldifoptions)1109 write_ldif_value( char *type, char *value, unsigned long vallen,
1110 unsigned long ldifoptions )
1111 {
1112 char *ldif;
1113 static int wrote_version = 0;
1114
1115 if ( write_ldif_version && !wrote_version ) {
1116 char versionbuf[ 64 ];
1117
1118 wrote_version = 1;
1119 sprintf( versionbuf, "%d", LDIF_VERSION_ONE );
1120 write_ldif_value( "version", versionbuf, strlen( versionbuf ), 0 );
1121 }
1122
1123 if ( !fold ) {
1124 ldifoptions |= LDIF_OPT_NOWRAP;
1125 }
1126 if ( minimize_base64 ) {
1127 ldifoptions |= LDIF_OPT_MINIMAL_ENCODING;
1128 }
1129
1130 if (( ldif = ldif_type_and_value_with_options( type, value, (int)vallen,
1131 ldifoptions )) == NULL ) {
1132 return( -1 );
1133 }
1134
1135 fputs( ldif, stdout );
1136 free( ldif );
1137
1138 return( 0 );
1139 }
1140
1141
1142 static char *
sortresult2string(unsigned long result)1143 sortresult2string(unsigned long result)
1144 {
1145 /*
1146 success (0), -- results are sorted
1147 operationsError (1), -- server internal failure
1148 timeLimitExceeded (3), -- timelimit reached before
1149 -- sorting was completed
1150 strongAuthRequired (8), -- refused to return sorted
1151 -- results via insecure
1152 -- protocol
1153 adminLimitExceeded (11), -- too many matching entries
1154 -- for the server to sort
1155 noSuchAttribute (16), -- unrecognized attribute
1156 -- type in sort key
1157 inappropriateMatching (18), -- unrecognized or inappro-
1158 -- priate matching rule in
1159 -- sort key
1160 insufficientAccessRights (50), -- refused to return sorted
1161 -- results to this client
1162 busy (51), -- too busy to process
1163 unwillingToPerform (53), -- unable to sort
1164 other (80)
1165 */
1166
1167 switch (result) {
1168 case 0: return (gettext("success"));
1169 case 1: return (gettext("operations error"));
1170 case 3: return (gettext("time limit exceeded"));
1171 case 8: return (gettext("strong auth required"));
1172 case 11: return (gettext("admin limit exceeded"));
1173 case 16: return (gettext("no such attribute"));
1174 case 18: return (gettext("unrecognized or inappropriate matching rule"));
1175 case 50: return (gettext("insufficient access rights"));
1176 case 51: return (gettext("too busy"));
1177 case 53: return (gettext("unable to sort"));
1178 case 80:
1179 default: return (gettext("Er...Other ?"));
1180 }
1181 }
1182
1183
1184 static void
parse_and_display_reference(LDAP * ld,LDAPMessage * ref)1185 parse_and_display_reference( LDAP *ld, LDAPMessage *ref )
1186 {
1187 int i;
1188 char **refs;
1189
1190 if ( ldap_parse_reference( ld, ref, &refs, NULL, 0 ) != LDAP_SUCCESS ) {
1191 ldaptool_print_lderror( ld, "ldap_parse_reference",
1192 LDAPTOOL_CHECK4SSL_IF_APPROP );
1193 } else if ( refs != NULL && refs[ 0 ] != NULL ) {
1194 fputs( gettext("Unfollowed continuation reference(s):\n"), stderr );
1195 for ( i = 0; refs[ i ] != NULL; ++i ) {
1196 fprintf( stderr, " %s\n", refs[ i ] );
1197 }
1198 ldap_value_free( refs );
1199 }
1200 }
1201
1202
1203 /*possible operations a client can invoke -- copied from ldaprot.h */
1204
1205 #ifndef LDAP_REQ_BIND
1206 #define LDAP_REQ_BIND 0x60L /* application + constructed */
1207 #define LDAP_REQ_UNBIND 0x42L /* application + primitive */
1208 #define LDAP_REQ_SEARCH 0x63L /* application + constructed */
1209 #define LDAP_REQ_MODIFY 0x66L /* application + constructed */
1210 #define LDAP_REQ_ADD 0x68L /* application + constructed */
1211 #define LDAP_REQ_DELETE 0x4aL /* application + primitive */
1212 #define LDAP_REQ_RENAME 0x6cL /* application + constructed */
1213 #define LDAP_REQ_COMPARE 0x6eL /* application + constructed */
1214 #define LDAP_REQ_ABANDON 0x50L /* application + primitive */
1215 #define LDAP_REQ_EXTENDED 0x77L /* application + constructed */
1216 #endif /* LDAP_REQ_BIND */
1217
1218
1219
1220 struct ldapsearch_type2str {
1221
1222 int ldst2s_type; /* message type */
1223 char *ldst2s_string; /* descriptive string */
1224 };
1225
1226 #ifdef SOLARIS_LDAP_CMD
1227 static struct ldapsearch_type2str ldapsearch_msgtypes[] = {
1228
1229 /* results: */
1230 { LDAP_RES_BIND, NULL },
1231 { LDAP_RES_SEARCH_REFERENCE, NULL },
1232 { LDAP_RES_SEARCH_ENTRY, NULL },
1233 { LDAP_RES_SEARCH_RESULT, NULL },
1234 { LDAP_RES_MODIFY, NULL },
1235 { LDAP_RES_ADD, NULL },
1236 { LDAP_RES_DELETE, NULL },
1237 { LDAP_RES_MODDN, NULL },
1238 { LDAP_RES_COMPARE, NULL },
1239 { LDAP_RES_EXTENDED, NULL },
1240 /* requests: */
1241 { LDAP_REQ_BIND, NULL },
1242 { LDAP_REQ_UNBIND, NULL },
1243 { LDAP_REQ_SEARCH, NULL },
1244 { LDAP_REQ_MODIFY, NULL },
1245 { LDAP_REQ_ADD, NULL },
1246 { LDAP_REQ_DELETE, NULL },
1247 { LDAP_REQ_RENAME, NULL },
1248 { LDAP_REQ_COMPARE, NULL },
1249 { LDAP_REQ_ABANDON, NULL },
1250 { LDAP_REQ_EXTENDED, NULL },
1251
1252 };
1253 #else
1254 static struct ldapsearch_type2str ldapsearch_msgtypes[] = {
1255
1256 /* results: */
1257 { LDAP_RES_BIND, "bind result" },
1258 { LDAP_RES_SEARCH_REFERENCE, "continuation reference" },
1259 { LDAP_RES_SEARCH_ENTRY, "entry" },
1260 { LDAP_RES_SEARCH_RESULT, "search result" },
1261 { LDAP_RES_MODIFY, "modify result" },
1262 { LDAP_RES_ADD, "add result" },
1263 { LDAP_RES_DELETE, "delete result" },
1264 { LDAP_RES_MODDN, "rename result" },
1265 { LDAP_RES_COMPARE, "compare result" },
1266 { LDAP_RES_EXTENDED, "extended operation result" },
1267 /* requests: */
1268 { LDAP_REQ_BIND, "bind request" },
1269 { LDAP_REQ_UNBIND, "unbind request" },
1270 { LDAP_REQ_SEARCH, "search request" },
1271 { LDAP_REQ_MODIFY, "modify request" },
1272 { LDAP_REQ_ADD, "add request" },
1273 { LDAP_REQ_DELETE, "delete request" },
1274 { LDAP_REQ_RENAME, "rename request" },
1275 { LDAP_REQ_COMPARE, "compare request" },
1276 { LDAP_REQ_ABANDON, "abandon request" },
1277 { LDAP_REQ_EXTENDED, "extended request" },
1278
1279 };
1280 #endif /* SOLARIS_LDAP_CMD */
1281
1282
1283 #define LDAPSEARCHTOOL_NUMTYPES (sizeof(ldapsearch_msgtypes) \
1284 / sizeof(struct ldapsearch_type2str))
1285
1286 #ifdef SOLARIS_LDAP_CMD
1287 static void
fill_ldapsearch_msgtypes(void)1288 fill_ldapsearch_msgtypes( void )
1289 {
1290 int i = 0;
1291 if (ldapsearch_msgtypes[LDAPSEARCHTOOL_NUMTYPES - 1].ldst2s_string
1292 != NULL)
1293 return;
1294
1295 /* results: */
1296 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1297 "bind result");
1298 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1299 "continuation reference");
1300 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1301 "entry");
1302 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1303 "search result");
1304 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1305 "modify result");
1306 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1307 "add result");
1308 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1309 "delete result");
1310 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1311 "rename result");
1312 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1313 "compare result");
1314 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1315 "extended operation result");
1316 /* requests: */
1317 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1318 "bind request");
1319 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1320 "unbind request");
1321 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1322 "search request");
1323 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1324 "modify request");
1325 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1326 "add request");
1327 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1328 "delete request");
1329 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1330 "rename request");
1331 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1332 "compare request");
1333 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1334 "abandon request");
1335 ldapsearch_msgtypes[i++].ldst2s_string = gettext(
1336 "extended request");
1337 }
1338 #endif /* SOLARIS_LDAP_CMD */
1339
1340 /*
1341 * Return a descriptive string given an LDAP result message type (tag).
1342 */
1343 static char *
msgtype2str(int msgtype)1344 msgtype2str( int msgtype )
1345 {
1346 char *s = gettext("unknown");
1347 int i;
1348
1349 #ifdef SOLARIS_LDAP_CMD
1350 /* Make sure ldapsearch_msgtypes is initialized */
1351 if (ldapsearch_msgtypes[LDAPSEARCHTOOL_NUMTYPES - 1].ldst2s_string
1352 == NULL)
1353 (void) fill_ldapsearch_msgtypes();
1354 #endif /* SOLARIS_LDAP_CMD */
1355
1356 for ( i = 0; i < LDAPSEARCHTOOL_NUMTYPES; ++i ) {
1357 if ( msgtype == ldapsearch_msgtypes[ i ].ldst2s_type ) {
1358 s = ldapsearch_msgtypes[ i ].ldst2s_string;
1359 }
1360 }
1361 return( s );
1362 }
1363
1364
1365 /*
1366 * Return a descriptive string given a Persistent Search change type
1367 */
1368 static char *
changetype_num2string(int chgtype)1369 changetype_num2string( int chgtype )
1370 {
1371 char *s = gettext("unknown");
1372
1373 switch( chgtype ) {
1374 case LDAP_CHANGETYPE_ADD:
1375 s = gettext("add");
1376 break;
1377 case LDAP_CHANGETYPE_DELETE:
1378 s = gettext("delete");
1379 break;
1380 case LDAP_CHANGETYPE_MODIFY:
1381 s = gettext("modify");
1382 break;
1383 case LDAP_CHANGETYPE_MODDN:
1384 s = gettext("moddn");
1385 break;
1386 }
1387
1388 return( s );
1389 }
1390
1391 /* returns a null teminated charrary */
get_effectiverights_attrlist(char * optarg)1392 static char **get_effectiverights_attrlist(char * optarg) {
1393
1394 char * tmp_str = strdup(optarg);
1395 char ** retArray = NULL;
1396 int i = 0;
1397
1398 retArray = ldap_str2charray( tmp_str, " "); /* takes copies */
1399
1400 free(tmp_str);
1401
1402 /* Oops - somebody left this debug message in for the
1403 getEffectiveRights control
1404 fprintf(stderr, "attrlist: "); */
1405 i = 0;
1406 while( retArray[i] != NULL ) {
1407
1408 fprintf(stderr,"%s ", retArray[i]);
1409 i++;
1410 }
1411 fprintf(stderr, "\n");
1412
1413 return(retArray);
1414
1415 }
1416