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