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 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 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 == '\0' || 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 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 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 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 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 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 * 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 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 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 * 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 * 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 */ 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