1 /* 2 * Copyright 2004 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 /* 31 * code that is shared by two or more of the LDAP command line tools 32 */ 33 34 #include "ldaptool.h" 35 #include "fileurl.h" 36 #ifdef SOLARIS_LDAP_CMD 37 #include "solaris-int.h" 38 #include <ldap.h> 39 #include <locale.h> 40 #include <libgen.h> 41 #include <sys/types.h> 42 #include <sys/stat.h> 43 #include <limits.h> 44 #endif /* SOLARIS_LDAP_CMD */ 45 46 #ifdef LDAP_TOOL_ARGPIN 47 #include "argpin.h" 48 #include "ntuserpin.h" 49 #endif /* LDAP_TOOL_ARGPIN */ 50 51 #ifndef SOLARIS_LDAP_CMD 52 #include <nspr.h> /* for PR_Cleanup() */ 53 #endif /* SOLARIS_LDAP_CMD */ 54 #include <stdlib.h> 55 #include <time.h> /* for time() and ctime() */ 56 #ifdef HAVE_SASL_OPTIONS 57 #ifdef SOLARIS_LDAP_CMD 58 #include <sasl/sasl.h> 59 #else 60 #include <sasl.h> 61 #endif /* SOLARIS_LDAP_CMD */ 62 #include "ldaptool-sasl.h" 63 #endif /* HAVE_SASL_OPTIONS */ 64 65 #ifndef SOLARIS_LDAP_CMD 66 #define gettext(s) s 67 #endif 68 69 #ifdef SOLARIS_LDAP_CMD 70 #define PATH_BUF_SIZE (PATH_MAX + 1) 71 #endif 72 73 static LDAP_REBINDPROC_CALLBACK get_rebind_credentials; 74 static void print_library_info( const LDAPAPIInfo *aip, FILE *fp ); 75 static int wait4result( LDAP *ld, int msgid, struct berval **servercredp, 76 char *msg ); 77 static int parse_result( LDAP *ld, LDAPMessage *res, 78 struct berval **servercredp, char *msg, int freeit ); 79 80 #ifdef LDAPTOOL_DEBUG_MEMORY 81 static void *ldaptool_debug_malloc( size_t size ); 82 static void *ldaptool_debug_calloc( size_t nelem, size_t elsize ); 83 static void *ldaptool_debug_realloc( void *ptr, size_t size ); 84 static void ldaptool_debug_free( void *ptr ); 85 #endif /* LDAPTOOL_DEBUG_MEMORY */ 86 87 #if defined(NET_SSL) 88 static char *certpath2keypath( char *certdbpath ); 89 static int ldaptool_setcallbacks( struct ldapssl_pkcs_fns *pfns); 90 static char * buildTokenCertName( const char *tokenName, const char *certName); 91 #ifdef FORTEZZA 92 static int ldaptool_fortezza_init( int exit_on_error ); 93 static int ldaptool_fortezza_alert( void *arg, PRBool onOpen, 94 char *string, int value1, void *value2 ); 95 static void * ldaptool_fortezza_getpin( char **passwordp ); 96 static char * ldaptool_fortezza_err2string( int err ); 97 #endif /* FORTEZZA */ 98 #endif 99 #ifdef HAVE_SASL_OPTIONS 100 static int saslSetParam(char *saslarg); 101 #endif /* HAVE_SASL_OPTIONS */ 102 103 /* 104 * display usage for common options with one exception: -f is not included 105 * since the description tends to be tool-specific. 106 * 107 * As of 1-Jul-1998, of the characters in the set [A-Za-z] the following are 108 * not currently used by any of the tools: EJgjqr 109 */ 110 void 111 ldaptool_common_usage( int two_hosts ) 112 { 113 fprintf( stderr, gettext(" -n\t\tshow what would be done but don't actually do it\n") ); 114 fprintf( stderr, gettext(" -v\t\trun in verbose mode (diagnostics to standard output)\n") ); 115 if ( two_hosts ) { 116 fprintf( stderr, gettext(" -h host\tLDAP server1 name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST ); 117 fprintf( stderr, gettext(" -p port\tLDAP server1 TCP port number (default: %d)\n"), LDAP_PORT ); 118 fprintf( stderr, gettext(" -h host\tLDAP server2 name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST ); 119 fprintf( stderr, gettext(" -p port\tLDAP server2 TCP port number (default: %d)\n"), LDAP_PORT ); 120 } else { 121 fprintf( stderr, gettext(" -h host\tLDAP server name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST ); 122 fprintf( stderr, gettext(" -p port\tLDAP server TCP port number (default: %d)\n"), LDAP_PORT ); 123 } 124 fprintf( stderr, 125 gettext(" -V n\tLDAP protocol version number (%d or %d; default: %d)\n"), 126 LDAP_VERSION2, LDAP_VERSION3, LDAP_VERSION3 ); 127 #if defined(NET_SSL) 128 fprintf( stderr, gettext(" -Z\t\tmake an SSL-encrypted connection\n") ); 129 fprintf( stderr, gettext(" -P pathname\tpath to SSL certificate database (default: current directory)\n") ); 130 fprintf( stderr, gettext(" -N\t\tname of certificate to use for SSL client authentication\n") ); 131 #ifndef SOLARIS_LDAP_CMD 132 fprintf( stderr, gettext(" -K pathname\tpath to key database to use for SSL client authentication\n") ); 133 fprintf( stderr, gettext(" \t\t(default: path to certificate database provided with -P option)\n") ); 134 #endif /* SOLARIS_LDAP_CMD */ 135 #ifdef LDAP_TOOL_PKCS11 136 fprintf( stderr, gettext(" -m pathname\tpath to security module database\n")); 137 #endif /* LDAP_TOOL_PKCS11 */ 138 fprintf( stderr, gettext(" -W\t\tSSL key password\n") ); 139 #ifndef SOLARIS_LDAP_CMD 140 fprintf( stderr, gettext(" -3\t\tcheck hostnames in SSL certificates\n") ); 141 #endif /SOLARIS_LDAP_CMD */ 142 143 #ifdef LDAP_TOOL_PKCS11 144 fprintf( stderr, gettext(" -Q [token][:certificate name]\tPKCS 11\n") ); 145 /* fprintf( stderr, " -X pathname\tFORTEZZA compromised key list (CKL)\n" ); */ 146 fprintf( stderr, gettext(" -I pin\tcard password file\n") ); 147 #endif /* LDAP_TOOL_PKCS11 */ 148 149 #endif /* NET_SSL */ 150 fprintf( stderr, gettext(" -D binddn\tbind dn\n") ); 151 fprintf( stderr, gettext(" -w passwd\tbind passwd (for simple authentication)\n") ); 152 fprintf( stderr, gettext(" -w - \tprompt for bind passwd (for simple authentication)\n") ); 153 fprintf( stderr, gettext(" -j file\tread bind passwd (for simple authentication)\n") ); 154 fprintf( stderr, gettext(" \t\tor SSL key password from 'file'\n") ); 155 fprintf( stderr, gettext(" -E\t\task server to expose (report) bind identity\n") ); 156 #ifdef LDAP_DEBUG 157 fprintf( stderr, gettext(" -d level\tset LDAP debugging level to `level'\n") ); 158 #endif 159 fprintf( stderr, gettext(" -R\t\tdo not automatically follow referrals\n") ); 160 fprintf( stderr, gettext(" -O limit\tmaximum number of referral hops to traverse (default: %d)\n"), LDAPTOOL_DEFREFHOPLIMIT ); 161 fprintf( stderr, gettext(" -M\t\tmanage references (treat them as regular entries)\n") ); 162 #ifndef SOLARIS_LDAP_CMD 163 fprintf( stderr, gettext(" -0\t\tignore LDAP library version mismatches\n") ); 164 #endif /* SOLARIS_LDAP_CMD */ 165 166 #ifndef NO_LIBLCACHE 167 fprintf( stderr, gettext(" -C cfgfile\tuse local database described by cfgfile\n") ); 168 #endif 169 fprintf( stderr, gettext(" -i charset\tcharacter set for command line input (default taken from locale)\n") ); 170 fprintf( stderr, gettext(" -k dir\tconversion routine directory (default: current directory)\n") ); 171 #if 0 172 /* 173 * Suppress usage for -y (old proxied authorization control) even though 174 * we still support it. We want to encourage people to use -Y instead (the 175 * new proxied authorization control). 176 */ 177 fprintf( stderr, gettext(" -y proxydn\tDN used for proxy authorization\n") ); 178 #endif 179 fprintf( stderr, gettext(" -Y proxyid\tproxied authorization id,\n") ); 180 fprintf( stderr, gettext(" \te.g, dn:uid=bjensen,dc=example,dc=com\n") ); 181 fprintf( stderr, gettext(" -H\t\tdisplay usage information\n") ); 182 #ifdef SOLARIS_LDAP_CMD 183 fprintf( stderr, gettext(" -?\t\tdisplay usage information\n") ); 184 #endif /* SOLARIS_LDAP_CMD */ 185 fprintf( stderr, gettext(" -J controloid[:criticality[:value|::b64value|:<fileurl]]\n") ); 186 fprintf( stderr, gettext("\t\tcriticality is a boolean value (default is false)\n") ); 187 #ifdef HAVE_SASL_OPTIONS 188 fprintf( stderr, gettext(" -o attrName=attrVal\tSASL options which are described in the man page\n")); 189 #endif /* HAVE_SASL_OPTIONS */ 190 } 191 192 /* globals */ 193 char *ldaptool_charset = ""; 194 char *ldaptool_host = LDAPTOOL_DEFHOST; 195 char *ldaptool_host2 = LDAPTOOL_DEFHOST; 196 int ldaptool_port = LDAP_PORT; 197 int ldaptool_port2 = LDAP_PORT; 198 int ldaptool_verbose = 0; 199 int ldaptool_not = 0; 200 #ifdef SOLARIS_LDAP_CMD 201 int ldaptool_require_binddn = 1; 202 #endif /* SOLARIS_LDAP_CMD */ 203 FILE *ldaptool_fp = NULL; 204 FILE *password_fp = NULL; 205 char *ldaptool_progname = ""; 206 char *ldaptool_nls_lang = NULL; 207 char *proxyauth_id = NULL; 208 int proxyauth_version = 2; /* use newer proxy control */ 209 LDAPControl *ldaptool_request_ctrls[CONTROL_REQUESTS] = {0}; 210 #ifdef LDAP_DEBUG 211 int ldaptool_dbg_lvl = 0; 212 #endif /* LDAP_DEBUG */ 213 214 /* statics */ 215 static char *binddn = NULL; 216 static char *passwd = NULL; 217 static int send_auth_response_ctrl = 0; 218 static int user_specified_port = 0; 219 static int user_specified_port2 = 0; 220 static int chase_referrals = 1; 221 static int lib_version_mismatch_is_fatal = 1; 222 static int ldversion = -1; /* use default */ 223 static int refhoplim = LDAPTOOL_DEFREFHOPLIMIT; 224 static int send_manage_dsait_ctrl = 0; 225 static int prompt_password = 0; 226 #ifdef HAVE_SASL_OPTIONS 227 static unsigned sasl_flags = LDAP_SASL_INTERACTIVE; 228 static char *sasl_mech = NULL; 229 static char *sasl_authid = NULL; 230 static char *sasl_mode = NULL; 231 static char *sasl_realm = NULL; 232 static char *sasl_username = NULL; 233 static char *sasl_secprops = NULL; 234 static int ldapauth = -1; 235 #endif /* HAVE_SASL_OPTIONS */ 236 237 #ifndef NO_LIBLCACHE 238 static char *cache_config_file = NULL; 239 #endif /* !NO_LIBLCACHE */ 240 #if defined(NET_SSL) 241 static int secure = 0; 242 static int isZ = 0; 243 static int isN = 0; 244 static int isW = 0; 245 static int isw = 0; 246 static int isD = 0; 247 static int isj = 0; 248 static int ssl_strength = LDAPTOOL_DEFSSLSTRENGTH; 249 #ifdef SOLARIS_LDAP_CMD 250 static char pathname[PATH_BUF_SIZE]; 251 #endif 252 static char *ssl_certdbpath = NULL; 253 static char *ssl_keydbpath = NULL; 254 static char *ssl_keyname = NULL; 255 static char *ssl_certname = NULL; 256 static char *ssl_passwd = NULL; 257 258 #ifdef LDAP_TOOL_PKCS11 259 static char *ssl_secmodpath = NULL; 260 261 static char *pkcs_token = NULL; 262 263 static char *ssl_donglefile = NULL; 264 265 #if 0 266 static char *pkcs_pin = NULL; 267 #endif 268 static struct ldapssl_pkcs_fns local_pkcs_fns = 269 {0,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL }; 270 271 #ifdef FORTEZZA 272 static uint32 fortezza_cardmask = 0; 273 static char *fortezza_personality = NULL; 274 static char *fortezza_krlfile = NULL; 275 static char *fortezza_pin = NULL; 276 #endif /* FORTEZZA */ 277 #endif /* LDAP_TOOL_PKCS11 */ 278 #endif /* NET_SSL */ 279 280 /* 281 * Handle general initialization and options that are common to all of 282 * the LDAP tools. 283 * Handle options that are common to all of the LDAP tools. 284 * Note the the H option is included here but handled via the 285 * extra_opt_callback function (along with any "extra_opts" ). 286 * 287 * Return: final value for optind or -1 if usage should be displayed (for 288 * some fatal errors, we call exit here). 289 */ 290 int 291 ldaptool_process_args( int argc, char **argv, char *extra_opts, 292 int two_hosts, void (*extra_opt_callback)( int option, char *optarg )) 293 { 294 int rc, i, hostnum; 295 char *optstring, *common_opts; 296 extern char *optarg; 297 extern int optind; 298 LDAPAPIInfo ldai; 299 char *ctrl_arg, *ctrl_oid=NULL, *ctrl_value=NULL; 300 int ctrl_criticality=0, vlen; 301 LDAPControl *ldctrl; 302 #ifdef SOLARIS_LDAP_CMD 303 struct stat st; 304 #endif 305 306 307 /* 308 * Set program name global based on argv[0]. 309 */ 310 if (( ldaptool_progname = strrchr( argv[ 0 ], '/' )) == NULL ) { 311 ldaptool_progname = argv[ 0 ]; 312 } else { 313 ++ldaptool_progname; 314 } 315 316 #ifdef LDAPTOOL_DEBUG_MEMORY 317 { 318 struct ldap_memalloc_fns mafns = { 319 ldaptool_debug_malloc, 320 ldaptool_debug_calloc, 321 ldaptool_debug_realloc, 322 ldaptool_debug_free 323 }; 324 325 ldap_set_option( NULL, LDAP_OPT_MEMALLOC_FN_PTRS, &mafns ); 326 } 327 #endif /* LDAPTOOL_DEBUG_MEMORY */ 328 329 #ifdef LDAP_DEBUG 330 i = LDAP_DEBUG_ANY; 331 ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, (void *) &i); 332 #endif 333 334 /* 335 * Perform a sanity check on the revision of the LDAP API library to 336 * make sure it is at least as new as the one we were compiled against. 337 * If the API implementation is from the same vendor as we were compiled 338 * against, we also check to make sure the vendor version is at least 339 * as new as the library we were compiled against. 340 * 341 * Version differences are fatal unless the -0 option is passed on the 342 * tool command line (that's a zero, not an oh). We check for the 343 * presence of -0 in a crude way to it must appear by itself in argv. 344 */ 345 for ( i = 1; i < argc; ++i ) { 346 if ( strcmp( argv[i], "-0" ) == 0 ) { 347 lib_version_mismatch_is_fatal = 0; 348 break; 349 } 350 } 351 352 memset( &ldai, 0, sizeof(ldai)); 353 ldai.ldapai_info_version = LDAP_API_INFO_VERSION; 354 if (( rc = ldap_get_option( NULL, LDAP_OPT_API_INFO, &ldai )) != 0 ) { 355 fprintf( stderr, gettext("%s: unable to retrieve LDAP library version" 356 " information;\n\tthis program requires an LDAP library that" 357 " implements revision\n\t%d or greater of the LDAP API.\n"), 358 ldaptool_progname, LDAP_API_VERSION ); 359 if ( lib_version_mismatch_is_fatal ) { 360 exit( LDAP_LOCAL_ERROR ); 361 } 362 } else if ( ldai.ldapai_api_version < LDAP_API_VERSION ) { 363 fprintf( stderr, gettext("%s: this program requires an LDAP library that" 364 " implements revision\n\t%d or greater of the LDAP API;" 365 " running with revision %d.\n"), 366 ldaptool_progname, LDAP_API_VERSION, ldai.ldapai_api_version ); 367 if ( lib_version_mismatch_is_fatal ) { 368 exit( LDAP_LOCAL_ERROR ); 369 } 370 } else if ( strcmp( ldai.ldapai_vendor_name, LDAP_VENDOR_NAME ) != 0) { 371 fprintf( stderr, gettext("%s: this program requires %s's LDAP\n" 372 "\tlibrary version %2.2f or greater; running with\n" 373 "\t%s's version %2.2f.\n"), 374 ldaptool_progname, LDAP_VENDOR_NAME, 375 (float)LDAP_VENDOR_VERSION / 100, 376 ldai.ldapai_vendor_name, 377 (float)ldai.ldapai_vendor_version / 100 ); 378 if ( lib_version_mismatch_is_fatal ) { 379 exit( LDAP_LOCAL_ERROR ); 380 } 381 } else if (ldai.ldapai_vendor_version < LDAP_VENDOR_VERSION ) { 382 fprintf( stderr, gettext("%s: this program requires %s's LDAP\n" 383 "\tlibrary version %2.2f or greater; running with" 384 " version %2.2f.\n"), 385 ldaptool_progname, LDAP_VENDOR_NAME, 386 (float)LDAP_VENDOR_VERSION / 100, 387 (float)ldai.ldapai_vendor_version / 100 ); 388 if ( lib_version_mismatch_is_fatal ) { 389 exit( LDAP_LOCAL_ERROR ); 390 } 391 } 392 393 /* 394 * Process command line options. 395 */ 396 if ( extra_opts == NULL ) { 397 extra_opts = ""; 398 } 399 400 #ifdef HAVE_SASL_OPTIONS 401 #ifdef SOLARIS_LDAP_CMD 402 common_opts = "nvEMRH?Zd:D:f:h:j:N:O:o:P:p:W:w:V:i:k:y:Y:J:"; 403 #else 404 common_opts = "nvEMRHZ03d:D:f:h:j:I:K:N:O:o:P:p:Q:W:w:V:X:m:i:k:y:Y:J:"; 405 #endif /* SOLARIS_LDAP_CMD */ 406 #else 407 common_opts = "nvEMRHZ03d:D:f:h:j:I:K:N:O:P:p:Q:W:w:V:X:m:i:k:y:Y:J:"; 408 #endif /* HAVE_SASL_OPTIONS */ 409 410 /* note: optstring must include room for liblcache "C:" option */ 411 if (( optstring = (char *) malloc( strlen( extra_opts ) + strlen( common_opts ) 412 + 3 )) == NULL ) { 413 perror( "malloc" ); 414 exit( LDAP_NO_MEMORY ); 415 } 416 417 #ifdef NO_LIBLCACHE 418 sprintf( optstring, "%s%s", common_opts, extra_opts ); 419 #else 420 sprintf( optstring, "%s%sC:", common_opts, extra_opts ); 421 #endif 422 423 hostnum = 0; 424 while ( (i = getopt( argc, argv, optstring )) != EOF ) { 425 switch( i ) { 426 case 'n': /* do Not do any LDAP operations */ 427 ++ldaptool_not; 428 break; 429 case 'v': /* verbose mode */ 430 ++ldaptool_verbose; 431 break; 432 case 'd': 433 #ifdef LDAP_DEBUG 434 ldaptool_dbg_lvl = atoi( optarg ); /* */ 435 #ifdef SOLARIS_LDAP_CMD 436 ldap_set_option(NULL, LBER_OPT_DEBUG_LEVEL, 437 (void *)&ldaptool_dbg_lvl); 438 #else 439 ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, 440 (void *)&ldaptool_dbg_lvl); 441 #endif /* SOLARIS_LDAP_CMD */ 442 ldaptool_dbg_lvl |= LDAP_DEBUG_ANY; 443 ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, 444 (void *)&ldaptool_dbg_lvl); 445 #else /* LDAP_DEBUG */ 446 fprintf( stderr, gettext("compile with -DLDAP_DEBUG for debugging\n") ); 447 #endif /* LDAP_DEBUG */ 448 break; 449 case 'R': /* don't automatically chase referrals */ 450 chase_referrals = 0; 451 break; 452 #ifndef NO_LIBLCACHE 453 case 'C': /* search local database */ 454 cache_config_file = strdup( optarg ); 455 break; 456 #endif 457 case 'f': /* input file */ 458 if ( optarg[0] == '-' && optarg[1] == '\0' ) { 459 ldaptool_fp = stdin; 460 } else if (( ldaptool_fp = ldaptool_open_file( optarg, "r" )) == NULL ) { 461 perror( optarg ); 462 exit( LDAP_PARAM_ERROR ); 463 } 464 break; 465 case 'h': /* ldap host */ 466 if ( hostnum == 0 ) { 467 ldaptool_host = strdup( optarg ); 468 } else { 469 ldaptool_host2 = strdup( optarg ); 470 } 471 ++hostnum; 472 break; 473 case 'D': /* bind DN */ 474 isD = 1; 475 binddn = strdup( optarg ); 476 break; 477 case 'E': /* expose bind identity via auth. response control */ 478 ++send_auth_response_ctrl; 479 break; 480 481 case 'p': /* ldap port */ 482 if ( !user_specified_port ) { 483 ++user_specified_port; 484 ldaptool_port = atoi( optarg ); 485 } else { 486 ++user_specified_port2; 487 ldaptool_port2 = atoi( optarg ); 488 } 489 break; 490 #if defined(NET_SSL) 491 case 'P': /* path to security database */ 492 secure = 1; /* do SSL encryption */ 493 #ifndef SOLARIS_LDAP_CMD 494 ssl_certdbpath = strdup(optarg); 495 if (NULL == ssl_certdbpath) { 496 perror("malloc"); 497 exit( LDAP_NO_MEMORY ); 498 } 499 #else 500 /* 501 * Verify whether it's a base directory or a cert db file. 502 * If it is not a directory, truncate the file name as 503 * the revised NSS_Init() doesn't take file name any longer. 504 */ 505 if (strlcpy(pathname, optarg, PATH_BUF_SIZE) >= PATH_BUF_SIZE) { 506 fprintf(stderr, gettext("\"-P\": Path name is too " 507 "long\n")); 508 exit(LDAP_PARAM_ERROR); 509 } 510 511 if (stat(pathname, &st) != 0) { 512 perror("stat"); 513 fprintf(stderr, gettext("\"-P\": Path name is " 514 "invalid\n")); 515 exit(LDAP_PARAM_ERROR); 516 } else { 517 if (S_ISREG(st.st_mode)) { 518 /* redir to a regular file's dir name */ 519 ssl_certdbpath = dirname(pathname); 520 } else 521 ssl_certdbpath = pathname; 522 } 523 #endif /* SOLARIS_LDAP_CMD */ 524 break; 525 case 'Z': /* do SSL encryption */ 526 secure = 1; 527 isZ = 1; 528 break; 529 case 'N': /* nickname of cert. to use for client auth. */ 530 ssl_certname = strdup( optarg ); 531 if (NULL == ssl_certname) 532 { 533 perror("malloc"); 534 exit( LDAP_NO_MEMORY ); 535 } 536 isN = 1; 537 break; 538 #ifndef SOLARIS_LDAP_CMD 539 case 'K': /* location of key database */ 540 ssl_keydbpath = strdup( optarg ); 541 if (NULL == ssl_keydbpath) 542 { 543 perror("malloc"); 544 exit( LDAP_NO_MEMORY ); 545 } 546 break; 547 #endif /* SOLARIS_LDAP_CMD */ 548 549 case 'W': /* SSL key password */ 550 ssl_passwd = strdup( optarg ); 551 if (NULL == ssl_passwd) 552 { 553 perror("malloc"); 554 exit( LDAP_NO_MEMORY ); 555 } 556 isW = 1; 557 break; 558 559 #ifndef SOLARIS_LDAP_CMD 560 case '3': /* check hostnames in SSL certificates ("no third") */ 561 ssl_strength = LDAPSSL_AUTH_CNCHECK; 562 break; 563 #endif /* SOLARIS_LDAP_CMD */ 564 565 #ifdef LDAP_TOOL_PKCS11 566 case 'm': /* SSL secmod path */ 567 ssl_secmodpath = strdup( optarg); 568 if (NULL == ssl_secmodpath) 569 { 570 perror("malloc"); 571 exit( LDAP_NO_MEMORY ); 572 } 573 break; 574 575 case 'Q': /* FORTEZZA [card][:personality] */ 576 pkcs_token = strdup(optarg); 577 if (NULL == pkcs_token) 578 { 579 perror("malloc"); 580 exit( LDAP_NO_MEMORY ); 581 } 582 583 break; 584 /* This option removed to prevent interference 585 with the getEffectiveRights option, also -X 586 case 'X': * path to FORTEZZA CKL file * 587 588 fortezza_krlfile = strdup( optarg ); 589 590 591 break; 592 */ 593 case 'I': /* FORTEZZA PIN (password file) */ 594 ssl_donglefile = strdup( optarg ); 595 596 break; 597 #endif /* LDAP_TOOL_PKCS11 */ 598 599 #endif /* NET_SSL */ 600 case 'w': /* bind password */ 601 isw = 1; 602 if ( optarg[0] == '-' && optarg[1] == '\0' ) 603 prompt_password = 1; 604 else 605 passwd = strdup( optarg ); 606 break; 607 case 'j': /* bind password or SSL key password from file */ 608 isj = 1; 609 if ((password_fp = fopen( optarg, "r" )) == NULL ) { 610 fprintf(stderr, gettext("%s: Unable to open '%s' file\n"), 611 ldaptool_progname, optarg); 612 exit( LDAP_PARAM_ERROR ); 613 } 614 break; 615 case 'O': /* referral hop limit */ 616 refhoplim = atoi( optarg ); 617 break; 618 case 'V': /* protocol version */ 619 ldversion = atoi (optarg); 620 if ( ldversion != LDAP_VERSION2 && ldversion != LDAP_VERSION3 ) { 621 fprintf( stderr, gettext("%s: LDAP protocol version %d is not " 622 "supported (use -V%d or -V%d)\n"), 623 ldaptool_progname, ldversion, LDAP_VERSION2, 624 LDAP_VERSION3 ); 625 exit( LDAP_PARAM_ERROR ); 626 } 627 break; 628 case 'M': /* send a manageDsaIT control */ 629 send_manage_dsait_ctrl = 1; 630 break; 631 632 case 'i': /* character set specified */ 633 ldaptool_charset = strdup( optarg ); 634 if (NULL == ldaptool_charset) 635 { 636 perror( "malloc" ); 637 exit( LDAP_NO_MEMORY ); 638 } 639 640 break; 641 case 'k': /* conversion directory */ 642 ldaptool_convdir = strdup( optarg ); 643 if (NULL == ldaptool_convdir) 644 { 645 perror( "malloc" ); 646 exit( LDAP_NO_MEMORY ); 647 } 648 break; 649 case 'y': /* old (version 1) proxied authorization control */ 650 proxyauth_version = 1; 651 case 'Y': /* new (version 2 ) proxied authorization control */ 652 /*FALLTHRU*/ 653 proxyauth_id = strdup(optarg); 654 if (NULL == proxyauth_id) 655 { 656 perror( "malloc" ); 657 exit( LDAP_NO_MEMORY ); 658 } 659 660 break; 661 662 #ifndef SOLARIS_LDAP_CMD 663 case '0': /* zero -- override LDAP library version check */ 664 break; /* already handled above */ 665 #endif /* SOLARIS_LDAP_CMD */ 666 case 'J': /* send an arbitrary control */ 667 if ( (ctrl_arg = strdup( optarg)) == NULL ) { 668 perror ("strdup"); 669 exit (LDAP_NO_MEMORY); 670 } 671 if (ldaptool_parse_ctrl_arg(ctrl_arg, ':', &ctrl_oid, 672 &ctrl_criticality, &ctrl_value, &vlen)) { 673 return (-1); 674 } 675 ldctrl = calloc(1,sizeof(LDAPControl)); 676 if (ctrl_value) { 677 rc = ldaptool_berval_from_ldif_value( ctrl_value, 678 vlen, &(ldctrl->ldctl_value), 679 1 /* recognize file URLs */, 680 0 /* always try file */, 681 1 /* report errors */ ); 682 if ((rc = ldaptool_fileurlerr2ldaperr( rc )) != LDAP_SUCCESS) { 683 fprintf( stderr, gettext("Unable to parse %s\n"), ctrl_value); 684 return (-1); 685 } 686 } 687 ldctrl->ldctl_oid = ctrl_oid; 688 ldctrl->ldctl_iscritical = ctrl_criticality; 689 ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls); 690 break; 691 #ifdef HAVE_SASL_OPTIONS 692 case 'o': /* attribute assignment */ 693 if ((rc = saslSetParam(optarg)) == -1) { 694 return (-1); 695 } 696 ldapauth = LDAP_AUTH_SASL; 697 ldversion = LDAP_VERSION3; 698 break; 699 #endif /* HAVE_SASL_OPTIONS */ 700 default: 701 (*extra_opt_callback)( i, optarg ); 702 } 703 } 704 705 706 /* If '-Z' is specified, check if '-P' is specified too. */ 707 if ( isN || isW ) { 708 if ( !isZ ) { 709 fprintf( stderr, gettext("%s: with -N, -W options, please specify -Z\n\n"), ldaptool_progname ); 710 return (-1); 711 } 712 } 713 714 /* if '-N' is specified, -W is needed too */ 715 if ( isN && NULL == ssl_passwd ) { 716 fprintf( stderr, gettext("%s: with the -N option, please specify -W also\n\n"), 717 ldaptool_progname ); 718 return (-1); 719 } 720 721 #ifdef SOLARIS_LDAP_CMD 722 if ( isj && ( isw || isW )) { 723 fprintf(stderr, gettext("%s: -j and -w or -W options cannot be specified simultaneously\n\n"), ldaptool_progname ); 724 #else 725 if ( isj && isw ) { 726 fprintf(stderr, gettext("%s: -j and -w options cannot be specified simultaneously\n\n"), ldaptool_progname ); 727 #endif /* SOLARIS_LDAP_CMD */ 728 return (-1); 729 } 730 731 /* complain if -j or -w does not also have -D, unless using SASL */ 732 #ifdef HAVE_SASL_OPTIONS 733 if ( (isj || isw) && !isD && ( ldapauth != LDAP_AUTH_SASL ) ) { 734 #else 735 if ( (isj || isw) && !isD ) { 736 #endif 737 fprintf(stderr, gettext("%s: with -j, -w options, please specify -D\n\n"), ldaptool_progname ); 738 return (-1); 739 } 740 741 /* use default key and cert DB paths if not set on the command line */ 742 if ( NULL == ssl_keydbpath ) { 743 if ( NULL == ssl_certdbpath ) { 744 ssl_keydbpath = LDAPTOOL_DEFKEYDBPATH; 745 } else { 746 ssl_keydbpath = certpath2keypath( ssl_certdbpath ); 747 } 748 } 749 if ( NULL == ssl_certdbpath ) { 750 ssl_certdbpath = LDAPTOOL_DEFCERTDBPATH; 751 } 752 753 if (prompt_password != 0) { 754 char *password_string = "Enter bind password: "; 755 756 #if defined(_WIN32) 757 char pbuf[257]; 758 fputs(password_string,stdout); 759 fflush(stdout); 760 if (fgets(pbuf,256,stdin) == NULL) { 761 passwd = NULL; 762 } else { 763 char *tmp; 764 765 tmp = strchr(pbuf,'\n'); 766 if (tmp) *tmp = '\0'; 767 tmp = strchr(pbuf,'\r'); 768 if (tmp) *tmp = '\0'; 769 passwd = strdup(pbuf); 770 } 771 #else 772 #if defined(SOLARIS) 773 /* 256 characters on Solaris */ 774 passwd = getpassphrase(password_string); 775 #else 776 /* limited to 16 chars on Tru64, 32 on AIX */ 777 passwd = getpass(password_string); 778 #endif 779 #endif 780 781 } else if (password_fp != NULL) { 782 char *linep = NULL; 783 int increment = 0; 784 int c, index; 785 786 /* allocate initial block of memory */ 787 if ((linep = (char *)malloc(BUFSIZ)) == NULL) { 788 fprintf( stderr, gettext("%s: not enough memory to read password from file\n"), ldaptool_progname ); 789 exit( LDAP_NO_MEMORY ); 790 } 791 increment++; 792 index = 0; 793 while ((c = fgetc( password_fp )) != '\n' && c != EOF) { 794 795 /* check if we will overflow the buffer */ 796 if ((c != EOF) && (index == ((increment * BUFSIZ) -1))) { 797 798 /* if we did, add another BUFSIZ worth of bytes */ 799 if ((linep = (char *) 800 realloc(linep, (increment + 1) * BUFSIZ)) == NULL) { 801 fprintf( stderr, gettext("%s: not enough memory to read password from file\n"), ldaptool_progname ); 802 exit( LDAP_NO_MEMORY ); 803 } 804 increment++; 805 } 806 linep[index++] = c; 807 } 808 linep[index] = '\0'; 809 passwd = linep; 810 } 811 812 #ifdef SOLARIS_LDAP_CMD 813 if (binddn != NULL && passwd == NULL) { 814 char *password_string = gettext("Enter bind password: "); 815 passwd = getpassphrase(password_string); 816 } 817 818 #ifdef HAVE_SASL_OPTIONS 819 if (ldapauth == LDAP_AUTH_SASL) { 820 /* BindDN not required for SASL */ 821 ldaptool_require_binddn = 0; 822 } 823 #endif /* HAVE_SASL_OPTIONS */ 824 825 #ifdef NET_SSL 826 if (secure == 1) { 827 /* BindDN not required for SSL */ 828 ldaptool_require_binddn = 0; 829 } 830 #endif /* NET_SSL */ 831 832 if (ldaptool_require_binddn && binddn == NULL && passwd == NULL) { 833 fprintf(stderr, 834 gettext("%s: DN and Bind Password are required.\n"), 835 ldaptool_progname ); 836 exit(1); 837 } 838 #endif /* SOLARIS_LDAP_CMD */ 839 840 /* 841 * If verbose (-v) flag was passed in, display program name and start time. 842 * If the verbose flag was passed at least twice (-vv), also display 843 * information about the API library we are running with. 844 */ 845 if ( ldaptool_verbose ) { 846 time_t curtime; 847 848 curtime = time( NULL ); 849 printf( gettext("%s: started %s\n"), ldaptool_progname, ctime( &curtime )); 850 if ( ldaptool_verbose > 1 ) { 851 print_library_info( &ldai, stdout ); 852 } 853 } 854 855 #ifdef LDAP_TOOL_PKCS11 856 if ((NULL != pkcs_token) && (NULL != ssl_certname)) { 857 char *result; 858 859 if ( (result = buildTokenCertName( pkcs_token, ssl_certname)) != NULL){ 860 free( ssl_certname ); 861 ssl_certname = result; 862 } 863 } 864 #endif /* LDAP_TOOL_PKCS11 */ 865 866 free( optstring ); 867 868 /* 869 * Clean up and return index of first non-option argument. 870 */ 871 if ( ldai.ldapai_extensions != NULL ) { 872 ldap_value_free( ldai.ldapai_extensions ); 873 } 874 if ( ldai.ldapai_vendor_name != NULL ) { 875 ldap_memfree( ldai.ldapai_vendor_name ); 876 } 877 878 #ifdef HAVE_SASL_OPTIONS 879 if (ldversion == LDAP_VERSION2 && ldapauth == LDAP_AUTH_SASL) { 880 fprintf( stderr, gettext("Incompatible with version %d\n"), ldversion); 881 return (-1); 882 } 883 #endif /* HAVE_SASL_OPTIONS */ 884 return( optind ); 885 } 886 887 888 /* 889 * Write detailed information about the API library we are running with to fp. 890 */ 891 static void 892 print_library_info( const LDAPAPIInfo *aip, FILE *fp ) 893 { 894 int i; 895 LDAPAPIFeatureInfo fi; 896 897 fprintf( fp, gettext("LDAP Library Information -\n" 898 " Highest supported protocol version: %d\n" 899 " LDAP API revision: %d\n" 900 " API vendor name: %s\n" 901 " Vendor-specific version: %.2f\n"), 902 aip->ldapai_protocol_version, aip->ldapai_api_version, 903 aip->ldapai_vendor_name, 904 (float)aip->ldapai_vendor_version / 100.0 ); 905 906 if ( aip->ldapai_extensions != NULL ) { 907 fputs( gettext(" LDAP API Extensions:\n"), fp ); 908 909 for ( i = 0; aip->ldapai_extensions[i] != NULL; i++ ) { 910 fprintf( fp, gettext(" %s"), aip->ldapai_extensions[i] ); 911 fi.ldapaif_info_version = LDAP_FEATURE_INFO_VERSION; 912 fi.ldapaif_name = aip->ldapai_extensions[i]; 913 fi.ldapaif_version = 0; 914 915 if ( ldap_get_option( NULL, LDAP_OPT_API_FEATURE_INFO, &fi ) 916 != 0 ) { 917 fprintf( fp, gettext(" %s: ldap_get_option( NULL," 918 " LDAP_OPT_API_FEATURE_INFO, ... ) for %s failed" 919 " (Feature Info version: %d)\n"), ldaptool_progname, 920 fi.ldapaif_name, fi.ldapaif_info_version ); 921 } else { 922 fprintf( fp, gettext(" (revision %d)\n"), fi.ldapaif_version); 923 } 924 } 925 } 926 fputc( '\n', fp ); 927 } 928 929 930 931 #ifdef LDAP_TOOL_ARGPIN 932 static int PinArgRegistration( void ) 933 { 934 935 /* pkcs_init was successful register the pin args */ 936 937 SVRCOREArgPinObj *ArgPinObj; 938 char *tokenName; 939 #ifndef _WIN32 940 SVRCOREStdPinObj *StdPinObj; 941 #else 942 SVRCOREFilePinObj *FilePinObj; 943 SVRCOREAltPinObj *AltPinObj; 944 SVRCORENTUserPinObj *NTUserPinObj; 945 int err; 946 #endif 947 char *pin; 948 char *filename; 949 /* Create and register the pin object for PKCS 11 */ 950 local_pkcs_fns.pkcs_getdonglefilename(NULL, &filename); 951 local_pkcs_fns.pkcs_getpin(NULL, "", &pin); 952 #ifndef _WIN32 953 if ( SVRCORE_CreateStdPinObj(&StdPinObj, filename, PR_TRUE) != 954 SVRCORE_Success) { 955 fprintf(stderr, gettext("Security Initialization: Unable to create PinObj " 956 "(%d)"), PR_GetError()); 957 return -1; 958 } 959 if (pin != NULL) 960 { 961 local_pkcs_fns.pkcs_gettokenname(NULL, &tokenName); 962 SVRCORE_CreateArgPinObj(&ArgPinObj, tokenName, pin, (SVRCOREPinObj *)StdPinObj); 963 SVRCORE_RegisterPinObj((SVRCOREPinObj *)ArgPinObj); 964 } 965 else 966 { 967 SVRCORE_RegisterPinObj((SVRCOREPinObj *)StdPinObj); 968 } 969 #else 970 if (NULL != pin) 971 { 972 local_pkcs_fns.pkcs_gettokenname(NULL, &tokenName); 973 if ((err = SVRCORE_CreateNTUserPinObj(&NTUserPinObj)) != SVRCORE_Success){ 974 fprintf(stderr, gettext("Security Initialization: Unable to create NTUserPinObj " 975 "(%d)"), PR_GetError()); 976 exit( LDAP_LOCAL_ERROR ); 977 } 978 if ((err = SVRCORE_CreateArgPinObj(&ArgPinObj, tokenName, pin, 979 (SVRCOREPinObj *)NTUserPinObj)) != SVRCORE_Success) 980 { 981 fprintf(stderr, gettext("Security Initialization: Unable to create ArgPinObj " 982 "(%d)"), PR_GetError()); 983 return -1; 984 985 } 986 SVRCORE_RegisterPinObj((SVRCOREPinObj *)ArgPinObj); 987 988 } 989 else 990 { 991 if ((err = SVRCORE_CreateNTUserPinObj(&NTUserPinObj)) != SVRCORE_Success){ 992 fprintf(stderr, gettext("Security Initialization: Unable to create NTUserPinObj " 993 "(%d)"), PR_GetError()); 994 return -1; 995 } 996 if (filename && *filename) 997 { 998 if ((err = SVRCORE_CreateFilePinObj(&FilePinObj, filename)) != 999 SVRCORE_Success) { 1000 fprintf(stderr, gettext("Security Initialization: Unable to create FilePinObj " 1001 "(%d)"), PR_GetError()); 1002 return -1; 1003 1004 } 1005 if ((err = SVRCORE_CreateAltPinObj(&AltPinObj, (SVRCOREPinObj *)FilePinObj, 1006 (SVRCOREPinObj *)NTUserPinObj)) != SVRCORE_Success) { 1007 fprintf(stderr, gettext("Security Initialization: Unable to create AltPinObj " 1008 "(%d)"), PR_GetError()); 1009 return -1; 1010 } 1011 SVRCORE_RegisterPinObj((SVRCOREPinObj *)AltPinObj); 1012 } 1013 else 1014 { 1015 SVRCORE_RegisterPinObj((SVRCOREPinObj *)NTUserPinObj); 1016 } 1017 } 1018 #endif 1019 return LDAP_SUCCESS; 1020 1021 } 1022 #endif /* LDAP_TOOL_ARGPIN */ 1023 1024 1025 /* 1026 * initialize and return an LDAP session handle. 1027 * if errors occur, we exit here. 1028 */ 1029 LDAP * 1030 ldaptool_ldap_init( int second_host ) 1031 { 1032 LDAP *ld = NULL; 1033 char *host; 1034 int port, rc, user_port; 1035 1036 if ( ldaptool_not ) { 1037 return( NULL ); 1038 } 1039 1040 if ( second_host ) { 1041 host = ldaptool_host2; 1042 port = ldaptool_port2; 1043 user_port = user_specified_port2; 1044 } else { 1045 host = ldaptool_host; 1046 port = ldaptool_port; 1047 user_port = user_specified_port; 1048 } 1049 1050 1051 if ( ldaptool_verbose ) { 1052 printf( gettext("ldap_init( %s, %d )\n"), host, port ); 1053 } 1054 1055 #if defined(NET_SSL) 1056 /* 1057 * Initialize security libraries and databases and LDAP session. If 1058 * ssl_certname is not NULL, then we will attempt to use client auth. 1059 * if the server supports it. 1060 */ 1061 #ifdef LDAP_TOOL_PKCS11 1062 ldaptool_setcallbacks( &local_pkcs_fns ); 1063 1064 if ( !second_host && secure 1065 &&(rc = ldapssl_pkcs_init( &local_pkcs_fns)) < 0) { 1066 /* secure connection requested -- fail if no SSL */ 1067 #ifndef SOLARIS_LDAP_CMD 1068 rc = PORT_GetError(); 1069 #endif /* SOLARIS_LDAP_CMD */ 1070 fprintf( stderr, gettext("SSL initialization failed: error %d (%s)\n"), 1071 rc, ldapssl_err2string( rc )); 1072 exit( LDAP_LOCAL_ERROR ); 1073 } 1074 1075 #ifdef LDAP_TOOL_ARGPIN 1076 if (secure) { 1077 if (PinArgRegistration( )) { 1078 exit( LDAP_LOCAL_ERROR); 1079 } 1080 } 1081 #endif /* LDAP_TOOL_ARGPIN */ 1082 1083 #else /* LDAP_TOOL_PKCS11 */ 1084 if ( !second_host && secure 1085 &&(rc = ldapssl_client_init( ssl_certdbpath, NULL )) < 0) { 1086 /* secure connection requested -- fail if no SSL */ 1087 #ifndef SOLARIS_LDAP_CMD 1088 rc = PORT_GetError(); 1089 #endif /* SOLARIS_LDAP_CMD */ 1090 fprintf( stderr, gettext("SSL initialization failed: error %d (%s)\n"), 1091 rc, ldapssl_err2string( rc )); 1092 exit( LDAP_LOCAL_ERROR ); 1093 } 1094 #endif /* LDAP_TOOL_PKCS11 */ 1095 1096 /* set the default SSL strength (used for all future ld's we create) */ 1097 if ( ldapssl_set_strength( NULL, ssl_strength ) < 0 ) { 1098 perror( "ldapssl_set_strength" ); 1099 exit( LDAP_LOCAL_ERROR ); 1100 } 1101 1102 1103 if (secure) { 1104 if ( !user_port ) { 1105 port = LDAPS_PORT; 1106 } 1107 1108 if (( ld = ldapssl_init( host, port, 1109 secure )) != NULL && ssl_certname != NULL ) 1110 if (ldapssl_enable_clientauth( ld, ssl_keydbpath, ssl_passwd, 1111 ssl_certname ) != 0 ) { 1112 exit ( ldaptool_print_lderror( ld, "ldapssl_enable_clientauth", 1113 LDAPTOOL_CHECK4SSL_ALWAYS )); 1114 } 1115 } else { 1116 /* In order to support IPv6, we use NSPR I/O */ 1117 #ifdef SOLARIS_LDAP_CMD 1118 ld = ldap_init( host, port ); 1119 #else 1120 ld = prldap_init( host, port, 0 /* not shared across threads */ ); 1121 #endif /* SOLARIS_LDAP_CMD */ 1122 } 1123 1124 #else /* NET_SSL */ 1125 /* In order to support IPv6, we use NSPR I/O */ 1126 #ifdef SOLARIS_LDAP_CMD 1127 ld = ldap_init( host, port ); 1128 #else 1129 ld = prldap_init( host, port, 0 /* not shared across threads */ ); 1130 #endif /* SOLARIS_LDAP_CMD */ 1131 #endif /* NET_SSL */ 1132 1133 if ( ld == NULL ) { 1134 perror( "ldap_init" ); 1135 exit( LDAP_LOCAL_ERROR ); 1136 } 1137 1138 #ifndef NO_LIBLCACHE 1139 if ( cache_config_file != NULL ) { 1140 int opt; 1141 1142 if ( lcache_init( ld, cache_config_file ) != 0 ) { 1143 exit( ldaptool_print_lderror( ld, cache_config_file, 1144 LDAPTOOL_CHECK4SSL_NEVER )); 1145 } 1146 opt = 1; 1147 (void) ldap_set_option( ld, LDAP_OPT_CACHE_ENABLE, &opt ); 1148 opt = LDAP_CACHE_LOCALDB; 1149 (void) ldap_set_option( ld, LDAP_OPT_CACHE_STRATEGY, &opt ); 1150 if ( ldversion == -1 ) { /* not set with -V */ 1151 ldversion = LDAP_VERSION2; /* local db only supports v2 */ 1152 } 1153 } 1154 #endif 1155 1156 1157 ldap_set_option( ld, LDAP_OPT_REFERRALS, chase_referrals ? LDAP_OPT_ON: 1158 LDAP_OPT_OFF ); 1159 if ( chase_referrals ) { 1160 ldap_set_rebind_proc( ld, get_rebind_credentials, NULL ); 1161 ldap_set_option( ld, LDAP_OPT_REFERRAL_HOP_LIMIT, &refhoplim ); 1162 } 1163 1164 if ( ldversion == -1 ) { /* not set with -V and not using local db */ 1165 ldversion = LDAP_VERSION3; 1166 } 1167 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldversion ); 1168 1169 return( ld ); 1170 } 1171 1172 1173 /* 1174 * perform a bind to the LDAP server if needed. 1175 * if an error occurs, we exit here. 1176 */ 1177 void 1178 ldaptool_bind( LDAP *ld ) 1179 { 1180 int rc; 1181 char *conv; 1182 LDAPControl auth_resp_ctrl, *ctrl_array[ 2 ], **bindctrls; 1183 #ifdef HAVE_SASL_OPTIONS 1184 void *defaults; 1185 #endif 1186 1187 if ( ldaptool_not ) { 1188 return; 1189 } 1190 1191 if ( send_auth_response_ctrl ) { 1192 auth_resp_ctrl.ldctl_oid = LDAP_CONTROL_AUTH_REQUEST; 1193 auth_resp_ctrl.ldctl_value.bv_val = NULL; 1194 auth_resp_ctrl.ldctl_value.bv_len = 0; 1195 auth_resp_ctrl.ldctl_iscritical = 0; 1196 1197 ctrl_array[0] = &auth_resp_ctrl; 1198 ctrl_array[1] = NULL; 1199 bindctrls = ctrl_array; 1200 } else { 1201 bindctrls = NULL; 1202 } 1203 1204 /* 1205 * if using LDAPv3 and not using client auth., omit NULL bind for 1206 * efficiency. 1207 */ 1208 if ( ldversion > LDAP_VERSION2 && binddn == NULL && passwd == NULL 1209 && ssl_certname == NULL ) { 1210 #ifdef HAVE_SASL_OPTIONS 1211 if ( ldapauth != LDAP_AUTH_SASL ) { 1212 return; 1213 } 1214 #else 1215 return; 1216 #endif 1217 } 1218 1219 /* 1220 * do the bind, backing off one LDAP version if necessary 1221 */ 1222 conv = ldaptool_local2UTF8( binddn ); 1223 1224 #ifdef HAVE_SASL_OPTIONS 1225 if ( ldapauth == LDAP_AUTH_SASL) { 1226 if ( sasl_mech == NULL) { 1227 fprintf( stderr, gettext("Please specify the SASL mechanism name when " 1228 "using SASL options\n")); 1229 return; 1230 } 1231 1232 if ( sasl_secprops != NULL) { 1233 rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS, 1234 (void *) sasl_secprops ); 1235 1236 if ( rc != LDAP_SUCCESS ) { 1237 fprintf( stderr, gettext("Unable to set LDAP_OPT_X_SASL_SECPROPS: %s\n"), 1238 sasl_secprops ); 1239 return; 1240 } 1241 } 1242 1243 defaults = ldaptool_set_sasl_defaults( ld, sasl_mech, sasl_authid, sasl_username, passwd, sasl_realm ); 1244 if (defaults == NULL) { 1245 perror ("malloc"); 1246 exit (LDAP_NO_MEMORY); 1247 } 1248 1249 rc = ldap_sasl_interactive_bind_s( ld, binddn, sasl_mech, NULL, NULL, 1250 sasl_flags, ldaptool_sasl_interact, defaults ); 1251 1252 if (rc != LDAP_SUCCESS ) { 1253 ldap_perror( ld, "ldap_sasl_interactive_bind_s" ); 1254 } 1255 } else 1256 #endif /* HAVE_SASL_OPTIONS */ 1257 /* 1258 * if using LDAPv3 and client auth., try a SASL EXTERNAL bind 1259 */ 1260 if ( ldversion > LDAP_VERSION2 && binddn == NULL && passwd == NULL 1261 && ssl_certname != NULL ) { 1262 rc = ldaptool_sasl_bind_s( ld, NULL, LDAP_SASL_EXTERNAL, NULL, 1263 bindctrls, NULL, NULL, "ldap_sasl_bind" ); 1264 } 1265 else { 1266 rc = ldaptool_simple_bind_s( ld, conv, passwd, bindctrls, NULL, 1267 "ldap_simple_bind" ); 1268 } 1269 1270 if ( rc == LDAP_SUCCESS ) { 1271 if ( conv != NULL ) { 1272 free( conv ); 1273 } 1274 return; /* success */ 1275 } 1276 1277 #ifdef HAVE_SASL_OPTIONS 1278 if (ldapauth != LDAP_AUTH_SASL) { 1279 #endif /* HAVE_SASL_OPTIONS */ 1280 if ( rc == LDAP_PROTOCOL_ERROR && ldversion > LDAP_VERSION2 ) { 1281 /* 1282 * try again, backing off one LDAP version 1283 * this is okay even for client auth. because the way to achieve 1284 * client auth. with LDAPv2 is to perform a NULL simple bind. 1285 */ 1286 --ldversion; 1287 fprintf( stderr, gettext("%s: the server doesn't understand LDAPv%d;" 1288 " trying LDAPv%d instead...\n"), ldaptool_progname, 1289 ldversion + 1, ldversion ); 1290 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldversion ); 1291 if (( rc = ldaptool_simple_bind_s( ld, conv, passwd, 1292 bindctrls, NULL, "ldap_simple_bind" )) == LDAP_SUCCESS ) { 1293 if( conv != NULL ) 1294 free( conv ); 1295 return; /* a qualified success */ 1296 } 1297 } 1298 #ifdef HAVE_SASL_OPTIONS 1299 } 1300 #endif /* HAVE_SASL_OPTIONS */ 1301 1302 if ( conv != NULL ) { 1303 free( conv ); 1304 } 1305 1306 /* 1307 * bind(s) failed -- fatal error 1308 */ 1309 ldap_unbind( ld ); 1310 exit( rc ); 1311 } 1312 1313 1314 /* 1315 * close open files, unbind, etc. 1316 */ 1317 void 1318 ldaptool_cleanup( LDAP *ld ) 1319 { 1320 if ( ld != NULL ) { 1321 ldap_unbind( ld ); 1322 } 1323 1324 if ( ldaptool_fp != NULL && ldaptool_fp != stdin ) { 1325 fclose( ldaptool_fp ); 1326 ldaptool_fp = NULL; 1327 } 1328 } 1329 1330 1331 /* 1332 * Retrieve and print an LDAP error message. Returns the LDAP error code. 1333 */ 1334 int 1335 ldaptool_print_lderror( LDAP *ld, char *msg, int check4ssl ) 1336 { 1337 int lderr = ldap_get_lderrno( ld, NULL, NULL ); 1338 1339 ldap_perror( ld, msg ); 1340 #ifndef SOLARIS_LDAP_CMD 1341 if ( secure && check4ssl != LDAPTOOL_CHECK4SSL_NEVER ) { 1342 if ( check4ssl == LDAPTOOL_CHECK4SSL_ALWAYS 1343 || ( lderr == LDAP_SERVER_DOWN )) { 1344 int sslerr = PORT_GetError(); 1345 1346 fprintf( stderr, gettext("\tSSL error %d (%s)\n"), sslerr, 1347 ldapssl_err2string( sslerr )); 1348 } 1349 } 1350 #endif /* SOLARIS_LDAP_CMD */ 1351 1352 return( lderr ); 1353 } 1354 1355 1356 /* 1357 * print referrals to stderr 1358 */ 1359 void 1360 ldaptool_print_referrals( char **refs ) 1361 { 1362 int i; 1363 1364 if ( refs != NULL ) { 1365 for ( i = 0; refs[ i ] != NULL; ++i ) { 1366 fprintf( stderr, gettext("Referral: %s\n"), refs[ i ] ); 1367 } 1368 } 1369 } 1370 1371 1372 /* 1373 * print contents of an extended response to stderr 1374 * this is mainly to support unsolicited notifications 1375 * Returns an LDAP error code (from the extended result). 1376 */ 1377 int 1378 ldaptool_print_extended_response( LDAP *ld, LDAPMessage *res, char *msg ) 1379 { 1380 char *oid; 1381 struct berval *data; 1382 1383 if ( ldap_parse_extended_result( ld, res, &oid, &data, 0 ) 1384 != LDAP_SUCCESS ) { 1385 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1386 } else { 1387 if ( oid != NULL ) { 1388 if ( strcmp ( oid, LDAP_NOTICE_OF_DISCONNECTION ) == 0 ) { 1389 fprintf( stderr, gettext("%s: Notice of Disconnection\n"), msg ); 1390 } else { 1391 fprintf( stderr, gettext("%s: OID %s\n"), msg, oid ); 1392 } 1393 ldap_memfree( oid ); 1394 } else { 1395 fprintf( stderr, gettext("%s: missing OID\n"), msg ); 1396 } 1397 1398 if ( data != NULL ) { 1399 fprintf( stderr, gettext("%s: Data (length %ld):\n"), msg, data->bv_len ); 1400 #if 0 1401 /* XXXmcs: maybe we should display the actual data? */ 1402 lber_bprint( data->bv_val, data->bv_len ); 1403 #endif 1404 ber_bvfree( data ); 1405 } 1406 } 1407 1408 return parse_result( ld, res, NULL, msg, 1 ); 1409 } 1410 1411 1412 /* 1413 * Like ldap_sasl_bind_s() but calls wait4result() to display 1414 * any referrals returned and report errors in a consistent way. 1415 */ 1416 int 1417 ldaptool_sasl_bind_s( LDAP *ld, const char *dn, const char *mechanism, 1418 const struct berval *cred, LDAPControl **serverctrls, 1419 LDAPControl **clientctrls, struct berval **servercredp, char *msg ) 1420 { 1421 int rc, msgid; 1422 1423 if ( servercredp != NULL ) { 1424 *servercredp = NULL; 1425 } 1426 1427 if (( rc = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls, 1428 clientctrls, &msgid )) != LDAP_SUCCESS ) { 1429 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1430 } else { 1431 rc = wait4result( ld, msgid, servercredp, msg ); 1432 } 1433 1434 return( rc ); 1435 } 1436 1437 1438 /* 1439 * Like ldap_simple_bind_s() but calls wait4result() to display 1440 * any referrals returned and report errors in a consistent way. 1441 */ 1442 int 1443 ldaptool_simple_bind_s( LDAP *ld, const char *dn, const char *passwd, 1444 LDAPControl **serverctrls, LDAPControl **clientctrls, char *msg ) 1445 { 1446 struct berval bv; 1447 1448 bv.bv_val = (char *)passwd; /* XXXmcs: had to cast away const */ 1449 bv.bv_len = ( passwd == NULL ? 0 : strlen( passwd )); 1450 return( ldaptool_sasl_bind_s( ld, dn, LDAP_SASL_SIMPLE, &bv, serverctrls, 1451 clientctrls, NULL, msg )); 1452 } 1453 1454 1455 /* 1456 * Like ldap_add_ext_s() but calls wait4result() to display 1457 * any referrals returned and report errors in a consistent way. 1458 */ 1459 int 1460 ldaptool_add_ext_s( LDAP *ld, const char *dn, LDAPMod **attrs, 1461 LDAPControl **serverctrls, LDAPControl **clientctrls, char *msg ) 1462 { 1463 int rc, msgid; 1464 1465 if (( rc = ldap_add_ext( ld, dn, attrs, serverctrls, clientctrls, &msgid )) 1466 != LDAP_SUCCESS ) { 1467 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1468 } else { 1469 /* 1470 * 25-April-2000 Note: the next line used to read: 1471 * rc = wait4result( ld, msgid, NULL, msg ); 1472 * 'msgid' it was changed to 'LDAP_RES_ANY' in order to receive 1473 * unsolicited notifications. 1474 */ 1475 rc = wait4result( ld, LDAP_RES_ANY, NULL, msg ); 1476 } 1477 1478 return( rc ); 1479 } 1480 1481 1482 /* 1483 * Like ldap_modify_ext_s() but calls wait4result() to display 1484 * any referrals returned and report errors in a consistent way. 1485 */ 1486 int 1487 ldaptool_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods, 1488 LDAPControl **serverctrls, LDAPControl **clientctrls, char *msg ) 1489 { 1490 int rc, msgid; 1491 1492 if (( rc = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls, 1493 &msgid )) != LDAP_SUCCESS ) { 1494 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1495 } else { 1496 rc = wait4result( ld, msgid, NULL, msg ); 1497 } 1498 1499 return( rc ); 1500 } 1501 1502 1503 /* 1504 * Like ldap_delete_ext_s() but calls wait4result() to display 1505 * any referrals returned and report errors in a consistent way. 1506 */ 1507 int 1508 ldaptool_delete_ext_s( LDAP *ld, const char *dn, LDAPControl **serverctrls, 1509 LDAPControl **clientctrls, char *msg ) 1510 { 1511 int rc, msgid; 1512 1513 if (( rc = ldap_delete_ext( ld, dn, serverctrls, clientctrls, &msgid )) 1514 != LDAP_SUCCESS ) { 1515 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1516 } else { 1517 rc = wait4result( ld, msgid, NULL, msg ); 1518 } 1519 1520 return( rc ); 1521 } 1522 1523 1524 /* 1525 * Like ldap_compare_ext_s() but calls wait4result() to display 1526 * any referrals returned and report errors in a consistent way. 1527 */ 1528 int ldaptool_compare_ext_s( LDAP *ld, const char *dn, const char *attrtype, 1529 const struct berval *bvalue, LDAPControl **serverctrls, 1530 LDAPControl **clientctrls, char *msg ) 1531 { 1532 int rc, msgid; 1533 1534 if (( rc = ldap_compare_ext( ld, dn, attrtype, bvalue, serverctrls, 1535 clientctrls, &msgid )) != LDAP_SUCCESS ) { 1536 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1537 } else { 1538 rc = wait4result( ld, msgid, NULL, msg ); 1539 } 1540 1541 return( rc ); 1542 } 1543 1544 1545 /* 1546 * Like ldap_rename_s() but calls wait4result() to display 1547 * any referrals returned and report errors in a consistent way. 1548 */ 1549 int 1550 ldaptool_rename_s( LDAP *ld, const char *dn, const char *newrdn, 1551 const char *newparent, int deleteoldrdn, LDAPControl **serverctrls, 1552 LDAPControl **clientctrls, char *msg ) 1553 { 1554 int rc, msgid; 1555 1556 if (( rc = ldap_rename( ld, dn, newrdn, newparent, deleteoldrdn, 1557 serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS ) { 1558 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1559 } else { 1560 rc = wait4result( ld, msgid, NULL, msg ); 1561 } 1562 1563 return( rc ); 1564 } 1565 1566 1567 /* 1568 * Wait for a result, check for and display errors and referrals. 1569 * Also recognize and display "Unsolicited notification" messages. 1570 * Returns an LDAP error code. 1571 */ 1572 static int 1573 wait4result( LDAP *ld, int msgid, struct berval **servercredp, char *msg ) 1574 { 1575 LDAPMessage *res; 1576 int rc, received_only_unsolicited = 1; 1577 1578 while ( received_only_unsolicited ) { 1579 res = NULL; 1580 if (( rc = ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res )) 1581 == -1 ) { 1582 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1583 return( ldap_get_lderrno( ld, NULL, NULL )); 1584 } 1585 1586 /* 1587 * Special handling for unsolicited notifications: 1588 * 1. Parse and display contents. 1589 * 2. go back and wait for another (real) result. 1590 */ 1591 if ( rc == LDAP_RES_EXTENDED 1592 && ldap_msgid( res ) == LDAP_RES_UNSOLICITED ) { 1593 rc = ldaptool_print_extended_response( ld, res, 1594 "Unsolicited response" ); 1595 } else { 1596 rc = parse_result( ld, res, servercredp, msg, 1 ); 1597 received_only_unsolicited = 0; /* we're done */ 1598 } 1599 } 1600 1601 return( rc ); 1602 } 1603 1604 1605 static int 1606 parse_result( LDAP *ld, LDAPMessage *res, struct berval **servercredp, 1607 char *msg, int freeit ) 1608 { 1609 int rc, lderr, errno; 1610 int pw_days=0, pw_hrs=0, pw_mins=0, pw_secs=0; /* for pwpolicy */ 1611 char **refs = NULL; 1612 LDAPControl **ctrls; 1613 1614 if (( rc = ldap_parse_result( ld, res, &lderr, NULL, NULL, &refs, 1615 &ctrls, 0 )) != LDAP_SUCCESS ) { 1616 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1617 ldap_msgfree( res ); 1618 return( rc ); 1619 } 1620 1621 /* check for authentication response control & PWPOLICY control*/ 1622 if ( NULL != ctrls ) { 1623 int i; 1624 char *s; 1625 1626 for ( i = 0; NULL != ctrls[i]; ++i ) { 1627 if ( 0 == strcmp( ctrls[i]->ldctl_oid, 1628 LDAP_CONTROL_AUTH_RESPONSE )) { 1629 s = ctrls[i]->ldctl_value.bv_val; 1630 if ( NULL == s ) { 1631 s = "Null"; 1632 } else if ( *s == '\0' ) { 1633 s = "Anonymous"; 1634 } 1635 fprintf( stderr, gettext("%s: bound as %s\n"), ldaptool_progname, s ); 1636 } 1637 1638 if ( 0 == strcmp( ctrls[i]->ldctl_oid, 1639 LDAP_CONTROL_PWEXPIRING )) { 1640 1641 /* Warn the user his passwd is to expire */ 1642 errno = 0; 1643 pw_secs = atoi(ctrls[i]->ldctl_value.bv_val); 1644 if ( pw_secs > 0 && errno != ERANGE ) { 1645 if ( pw_secs > 86400 ) { 1646 pw_days = ( pw_secs / 86400 ); 1647 pw_secs = ( pw_secs % 86400 ); 1648 } 1649 if ( pw_secs > 3600 ) { 1650 pw_hrs = ( pw_secs / 3600 ); 1651 pw_secs = ( pw_secs % 3600 ); 1652 } 1653 if ( pw_secs > 60 ) { 1654 pw_mins = ( pw_secs / 60 ); 1655 pw_secs = ( pw_secs % 60 ); 1656 } 1657 1658 printf(gettext("%s: Warning ! Your password will expire after "), ldaptool_progname); 1659 if ( pw_days ) { 1660 printf (gettext("%d days, "), pw_days); 1661 } 1662 if ( pw_hrs ) { 1663 printf (gettext("%d hrs, "), pw_hrs); 1664 } 1665 if ( pw_mins ) { 1666 printf (gettext("%d mins, "), pw_mins); 1667 } 1668 printf(gettext("%d seconds.\n"), pw_secs); 1669 1670 } 1671 } 1672 } 1673 ldap_controls_free( ctrls ); 1674 } 1675 1676 if ( servercredp != NULL && ( rc = ldap_parse_sasl_bind_result( ld, res, 1677 servercredp, 0 )) != LDAP_SUCCESS ) { 1678 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1679 ldap_msgfree( res ); 1680 return( rc ); 1681 } 1682 1683 if ( freeit ) { 1684 ldap_msgfree( res ); 1685 } 1686 1687 if ( LDAPTOOL_RESULT_IS_AN_ERROR( lderr )) { 1688 ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP ); 1689 } 1690 1691 if ( refs != NULL ) { 1692 ldaptool_print_referrals( refs ); 1693 ldap_value_free( refs ); 1694 } 1695 1696 return( lderr ); 1697 } 1698 1699 1700 /* 1701 * if -M was passed on the command line, create and return a "Manage DSA IT" 1702 * LDAPv3 control. If not, return NULL. 1703 */ 1704 LDAPControl * 1705 ldaptool_create_manage_dsait_control( void ) 1706 { 1707 LDAPControl *ctl; 1708 1709 if ( !send_manage_dsait_ctrl ) { 1710 return( NULL ); 1711 } 1712 1713 if (( ctl = (LDAPControl *)calloc( 1, sizeof( LDAPControl ))) == NULL || 1714 ( ctl->ldctl_oid = strdup( LDAP_CONTROL_MANAGEDSAIT )) == NULL ) { 1715 perror( "calloc" ); 1716 exit( LDAP_NO_MEMORY ); 1717 } 1718 1719 ctl->ldctl_iscritical = 1; 1720 1721 return( ctl ); 1722 } 1723 1724 /* 1725 * if -y "dn" was supplied on the command line, create the control 1726 */ 1727 LDAPControl * 1728 ldaptool_create_proxyauth_control( LDAP *ld ) 1729 { 1730 LDAPControl *ctl = NULL; 1731 int rc; 1732 1733 1734 if ( !proxyauth_id) 1735 return( NULL ); 1736 1737 if ( 2 == proxyauth_version ) { 1738 rc = ldap_create_proxiedauth_control( ld, proxyauth_id, &ctl); 1739 } else { 1740 rc = ldap_create_proxyauth_control( ld, proxyauth_id, 1, &ctl); 1741 } 1742 if ( rc != LDAP_SUCCESS) 1743 { 1744 if (ctl) 1745 ldap_control_free( ctl); 1746 return NULL; 1747 } 1748 return( ctl ); 1749 } 1750 1751 #ifndef SOLARIS_LDAP_CMD 1752 LDAPControl * 1753 ldaptool_create_geteffectiveRights_control ( LDAP *ld, const char *authzid, 1754 const char **attrlist) 1755 { 1756 LDAPControl *ctl = NULL; 1757 int rc; 1758 1759 rc = ldap_create_geteffectiveRights_control( ld, authzid, attrlist, 1, 1760 &ctl); 1761 1762 if ( rc != LDAP_SUCCESS) 1763 { 1764 if (ctl) 1765 ldap_control_free( ctl); 1766 return NULL; 1767 } 1768 return( ctl ); 1769 } 1770 #endif /* SOLARIS_LDAP_CMD */ 1771 1772 1773 void 1774 ldaptool_add_control_to_array( LDAPControl *ctrl, LDAPControl **array) 1775 { 1776 1777 int i; 1778 for (i=0; i< CONTROL_REQUESTS; i++) 1779 { 1780 if (*(array + i) == NULL) 1781 { 1782 *(array + i +1) = NULL; 1783 *(array + i) = ctrl; 1784 return ; 1785 } 1786 } 1787 fprintf(stderr, gettext("%s: failed to store request control!!!!!!\n"), 1788 ldaptool_progname); 1789 } 1790 1791 /* 1792 * Dispose of all controls in array and prepare array for reuse. 1793 */ 1794 void 1795 ldaptool_reset_control_array( LDAPControl **array ) 1796 { 1797 int i; 1798 1799 for ( i = 0; i < CONTROL_REQUESTS; i++ ) { 1800 if ( array[i] != NULL ) { 1801 ldap_control_free( array[i] ); 1802 array[i] = NULL; 1803 } 1804 } 1805 } 1806 1807 /* 1808 * This function calculates control value and its length. *value can 1809 * be pointing to plain value, ":b64encoded value" or "<fileurl". 1810 */ 1811 static int 1812 calculate_ctrl_value( const char *value, 1813 char **ctrl_value, int *vlen) 1814 { 1815 int b64; 1816 if (*value == ':') { 1817 value++; 1818 b64 = 1; 1819 } else { 1820 b64 = 0; 1821 } 1822 *ctrl_value = (char *)value; 1823 1824 if ( b64 ) { 1825 if (( *vlen = ldif_base64_decode( (char *)value, 1826 (unsigned char *)value )) < 0 ) { 1827 fprintf( stderr, 1828 gettext("Unable to decode base64 control value \"%s\"\n"), value); 1829 return( -1 ); 1830 } 1831 } else { 1832 *vlen = (int)strlen(*ctrl_value); 1833 } 1834 return( 0 ); 1835 } 1836 1837 /* 1838 * Parse the optarg from -J option of ldapsearch 1839 * and within LDIFfile for ldapmodify. Take ctrl_arg 1840 * (the whole string) and divide it into oid, criticality 1841 * and value. This function breaks down original ctrl_arg 1842 * with '\0' in places. Also, calculate length of valuestring. 1843 */ 1844 int 1845 ldaptool_parse_ctrl_arg(char *ctrl_arg, char sep, 1846 char **ctrl_oid, int *ctrl_criticality, 1847 char **ctrl_value, int *vlen) 1848 { 1849 char *s, *p; 1850 int strict; 1851 1852 /* Initialize passed variables with default values */ 1853 *ctrl_oid = *ctrl_value = NULL; 1854 *ctrl_criticality = 0; 1855 *vlen = 0; 1856 1857 strict = (sep == ' ' ? 1 : 0); 1858 if(!(s=strchr(ctrl_arg, sep))) { 1859 /* Possible values of ctrl_arg are 1860 * oid[:value|::b64value|:<fileurl] within LDIF, i.e. sep=' ' 1861 * oid from command line option, i.e. sep=':' 1862 */ 1863 if (sep == ' ') { 1864 if (!(s=strchr(ctrl_arg, ':'))) { 1865 *ctrl_oid = ctrl_arg; 1866 } 1867 else { 1868 /* ctrl_arg is of oid:[value|:b64value|<fileurl] 1869 * form in the LDIF record. So, grab the oid and then 1870 * jump to continue the parsing of ctrl_arg. 1871 * 's' is pointing just after oid ends. 1872 */ 1873 *s++ = '\0'; 1874 *ctrl_oid = ctrl_arg; 1875 return (calculate_ctrl_value( s, ctrl_value, vlen )); 1876 } 1877 } else { 1878 /* oid - from command line option, i.e. sep=':' */ 1879 *ctrl_oid = ctrl_arg; 1880 } 1881 } 1882 else { 1883 /* Possible values of ctrl_arg are 1884 * oid:criticality[:value|::b64value|:<fileurl] - command line 1885 * oid criticality[:value|::b64value|:<fileurl] - LDIF 1886 * And 's' is pointing just after oid ends. 1887 */ 1888 1889 if (*(s+1) == '\0') { 1890 fprintf( stderr, gettext("missing value\n") ); 1891 return( -1 ); 1892 } 1893 *s = '\0'; 1894 *ctrl_oid = ctrl_arg; 1895 p = ++s; 1896 if(!(s=strchr(p, ':'))) { 1897 if ( (*ctrl_criticality = ldaptool_boolean_str2value(p, strict)) 1898 == -1 ) { 1899 fprintf( stderr, gettext("Invalid criticality value\n") ); 1900 return( -1 ); 1901 } 1902 } 1903 else { 1904 if (*(s+1) == '\0') { 1905 fprintf( stderr, gettext("missing value\n") ); 1906 return ( -1 ); 1907 } 1908 *s++ = '\0'; 1909 if ( (*ctrl_criticality = ldaptool_boolean_str2value(p, strict)) 1910 == -1 ) { 1911 fprintf( stderr, gettext("Invalid criticality value\n") ); 1912 return ( -1 ); 1913 } 1914 return (calculate_ctrl_value( s, ctrl_value, vlen )); 1915 } 1916 } 1917 1918 return( 0 ); 1919 } 1920 1921 1922 /* 1923 * callback function for LDAP bind credentials 1924 */ 1925 static int 1926 LDAP_CALL 1927 LDAP_CALLBACK 1928 get_rebind_credentials( LDAP *ld, char **whop, char **credp, 1929 int *methodp, int freeit, void* arg ) 1930 { 1931 if ( !freeit ) { 1932 *whop = binddn; 1933 *credp = passwd; 1934 *methodp = LDAP_AUTH_SIMPLE; 1935 } 1936 1937 return( LDAP_SUCCESS ); 1938 } 1939 1940 1941 /* 1942 * return pointer to pathname to temporary directory. 1943 * First we see if the environment variable "TEMP" is set and use it. 1944 * Then we see if the environment variable "TMP" is set and use it. 1945 * If this fails, we use "/tmp" on UNIX and fail on Windows. 1946 */ 1947 char * 1948 ldaptool_get_tmp_dir( void ) 1949 { 1950 char *p; 1951 int offset; 1952 1953 if (( p = getenv( "TEMP" )) == NULL && ( p = getenv( "TMP" )) == NULL ) { 1954 #ifdef _WINDOWS 1955 fprintf( stderr, gettext("%s: please set the TEMP environment variable.\n"), 1956 ldaptool_progname ); 1957 exit( LDAP_LOCAL_ERROR ); 1958 #else 1959 return( "/tmp" ); /* last resort on UNIX */ 1960 #endif 1961 } 1962 1963 /* 1964 * remove trailing slash if present 1965 */ 1966 offset = strlen( p ) - 1; 1967 if ( p[offset] == '/' 1968 #ifdef _WINDOWS 1969 || p[offset] == '\\' 1970 #endif 1971 ) { 1972 if (( p = strdup( p )) == NULL ) { 1973 perror( "strdup" ); 1974 exit( LDAP_NO_MEMORY ); 1975 } 1976 1977 p[offset] = '\0'; 1978 } 1979 1980 return( p ); 1981 } 1982 1983 1984 int 1985 ldaptool_berval_is_ascii( const struct berval *bvp ) 1986 { 1987 unsigned long j; 1988 int is_ascii = 1; /* optimistic */ 1989 1990 for ( j = 0; j < bvp->bv_len; ++j ) { 1991 if ( !isascii( bvp->bv_val[ j ] )) { 1992 is_ascii = 0; 1993 break; 1994 } 1995 } 1996 1997 return( is_ascii ); 1998 } 1999 2000 2001 #ifdef LDAP_DEBUG_MEMORY 2002 #define LDAPTOOL_ALLOC_FREED 0xF001 2003 #define LDAPTOOL_ALLOC_INUSE 0xF002 2004 2005 static void * 2006 ldaptool_debug_alloc( void *ptr, size_t size ) 2007 { 2008 int *statusp; 2009 void *systemptr; 2010 2011 if ( ptr == NULL ) { 2012 systemptr = NULL; 2013 } else { 2014 systemptr = (void *)((char *)ptr - sizeof(int)); 2015 } 2016 2017 if (( statusp = (int *)realloc( systemptr, size + sizeof(int))) == NULL ) { 2018 fprintf( stderr, gettext("%s: realloc( 0x%x, %d) failed\n"), 2019 ldaptool_progname, systemptr, size ); 2020 return( NULL ); 2021 } 2022 2023 *statusp = LDAPTOOL_ALLOC_INUSE; 2024 2025 return( (char *)statusp + sizeof(int)); 2026 } 2027 2028 2029 static void * 2030 ldaptool_debug_realloc( void *ptr, size_t size ) 2031 { 2032 void *p; 2033 2034 if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) { 2035 fprintf( stderr, gettext("%s: => realloc( 0x%x, %d )\n"), 2036 ldaptool_progname, ptr, size ); 2037 } 2038 2039 p = ldaptool_debug_alloc( ptr, size ); 2040 2041 if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) { 2042 fprintf( stderr, gettext("%s: 0x%x <= realloc()\n"), ldaptool_progname, p ); 2043 } 2044 2045 return( p ); 2046 } 2047 2048 2049 static void * 2050 ldaptool_debug_malloc( size_t size ) 2051 { 2052 void *p; 2053 2054 if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) { 2055 fprintf( stderr, gettext("%s: => malloc( %d)\n"), ldaptool_progname, size ); 2056 } 2057 2058 p = ldaptool_debug_alloc( NULL, size ); 2059 2060 if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) { 2061 fprintf( stderr, gettext("%s: 0x%x <= malloc()\n"), ldaptool_progname, p ); 2062 } 2063 2064 return( p ); 2065 } 2066 2067 2068 static void * 2069 ldaptool_debug_calloc( size_t nelem, size_t elsize ) 2070 { 2071 void *p; 2072 2073 if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) { 2074 fprintf( stderr, gettext("%s: => calloc( %d, %d )\n"), 2075 ldaptool_progname, nelem, elsize ); 2076 } 2077 2078 if (( p = ldaptool_debug_alloc( NULL, nelem * elsize )) != NULL ) { 2079 memset( p, 0, nelem * elsize ); 2080 } 2081 2082 if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) { 2083 fprintf( stderr, gettext("%s: 0x%x <= calloc()\n"), ldaptool_progname, p ); 2084 } 2085 2086 return( p ); 2087 } 2088 2089 2090 static void 2091 ldaptool_debug_free( void *ptr ) 2092 { 2093 int *statusp = (int *)((char *)ptr - sizeof(int)); 2094 2095 if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) { 2096 fprintf( stderr, gettext("%s: => free( 0x%x )\n"), ldaptool_progname, ptr ); 2097 } 2098 2099 if ( ptr == NULL ) { 2100 fprintf( stderr, gettext("%s: bad free( 0x0 ) attempted (NULL pointer)\n"), 2101 ldaptool_progname ); 2102 } else if ( *statusp != LDAPTOOL_ALLOC_INUSE ) { 2103 fprintf( stderr, gettext("%s: bad free( 0x%x ) attempted" 2104 " (block not in use; status is %d)\n"), 2105 ldaptool_progname, ptr, *statusp ); 2106 } else { 2107 *statusp = LDAPTOOL_ALLOC_FREED; 2108 free( statusp ); 2109 } 2110 } 2111 #endif /* LDAP_DEBUG_MEMORY */ 2112 2113 2114 #if defined(NET_SSL) 2115 /* 2116 * Derive key database path from certificate database path and return a 2117 * malloc'd string. 2118 * 2119 * We just return an exact copy of "certdbpath" unless it ends in "cert.db", 2120 * "cert5.db", or "cert7.db". In those cases we strip off everything from 2121 * "cert" on and append "key.db", "key5.db", or "key3.db" as appropriate. 2122 * Strangely enough cert7.db and key3.db go together. 2123 */ 2124 static char * 2125 certpath2keypath( char *certdbpath ) 2126 { 2127 char *keydbpath, *appendstr; 2128 int len, striplen; 2129 2130 if ( certdbpath == NULL ) { 2131 return( NULL ); 2132 } 2133 2134 if (( keydbpath = strdup( certdbpath )) == NULL ) { 2135 perror( "strdup" ); 2136 exit( LDAP_NO_MEMORY ); 2137 } 2138 2139 len = strlen( keydbpath ); 2140 if ( len > 7 && 2141 strcasecmp( "cert.db", keydbpath + len - 7 ) == 0 ) { 2142 striplen = 7; 2143 appendstr = "key.db"; 2144 2145 } else if ( len > 8 && 2146 strcasecmp( "cert5.db", keydbpath + len - 8 ) == 0 ) { 2147 striplen = 8; 2148 appendstr = "key5.db"; 2149 } else if ( len > 8 && 2150 strcasecmp( "cert7.db", keydbpath + len - 8 ) == 0 ) { 2151 striplen = 8; 2152 appendstr = "key3.db"; 2153 } else { 2154 striplen = 0; 2155 } 2156 2157 if ( striplen > 0 ) { 2158 /* 2159 * The following code assumes that strlen( appendstr ) < striplen! 2160 */ 2161 strcpy( keydbpath + len - striplen, appendstr ); 2162 } 2163 2164 return( keydbpath ); 2165 } 2166 2167 #ifdef LDAP_TOOL_PKCS11 2168 static 2169 char * 2170 buildTokenCertName( const char *tokenName, const char *certName) 2171 { 2172 2173 int tokenlen = strlen(tokenName); 2174 int len = tokenlen + strlen(certName) +2; 2175 char *result; 2176 2177 if (( result = malloc( len )) != NULL) { 2178 strcpy(result, tokenName); 2179 *(result+tokenlen) = ':'; 2180 ++tokenlen; 2181 strcpy(result+tokenlen, certName); 2182 } else { 2183 perror("malloc"); 2184 exit( LDAP_NO_MEMORY ); 2185 } 2186 return result; 2187 } 2188 2189 2190 2191 static 2192 int 2193 ldaptool_getcertpath( void *context, char **certlocp ) 2194 { 2195 2196 *certlocp = ssl_certdbpath; 2197 if ( ldaptool_verbose ) { 2198 if (ssl_certdbpath) 2199 { 2200 printf(gettext("ldaptool_getcertpath -- %s\n"), ssl_certdbpath ); 2201 } 2202 else 2203 { 2204 printf(gettext("ldaptool_getcertpath -- (null)\n")); 2205 } 2206 2207 } 2208 return LDAP_SUCCESS; 2209 } 2210 2211 int 2212 ldaptool_getcertname( void *context, char **certnamep ) 2213 { 2214 2215 *certnamep = ssl_certname; 2216 if ( ldaptool_verbose ) { 2217 if (ssl_certname) 2218 { 2219 printf(gettext("ldaptool_getcertname -- %s\n"), *certnamep); 2220 } 2221 else 2222 { 2223 printf(gettext("ldaptool_getcertname -- (null)\n")); 2224 } 2225 } 2226 return LDAP_SUCCESS; 2227 } 2228 2229 int 2230 ldaptool_getkeypath(void *context, char **keylocp ) 2231 { 2232 *keylocp = ssl_keydbpath; 2233 if ( ldaptool_verbose ) { 2234 if (ssl_keydbpath) 2235 { 2236 printf(gettext("ldaptool_getkeypath -- %s\n"),*keylocp); 2237 } 2238 else 2239 { 2240 printf(gettext("ldaptool_getkeypath -- (null)\n")); 2241 } 2242 } 2243 2244 return LDAP_SUCCESS; 2245 } 2246 2247 int 2248 ldaptool_gettokenname( void *context, char **tokennamep ) 2249 { 2250 2251 *tokennamep = pkcs_token; 2252 if ( ldaptool_verbose ) { 2253 if (pkcs_token) 2254 { 2255 printf(gettext("ldaptool_gettokenname -- %s\n"),*tokennamep); 2256 } 2257 else 2258 { 2259 printf(gettext("ldaptool_gettokenname -- (null)\n")); 2260 } 2261 } 2262 2263 return LDAP_SUCCESS; 2264 } 2265 int 2266 ldaptool_gettokenpin( void *context, const char *tokennamep, char **tokenpinp) 2267 { 2268 2269 #if 0 2270 char *localtoken; 2271 #endif 2272 2273 /* XXXceb this stuff is removed for the time being. 2274 * This function should return the pin from ssl_password 2275 */ 2276 2277 2278 *tokenpinp = ssl_passwd; 2279 return LDAP_SUCCESS; 2280 2281 #if 0 2282 2283 ldaptool_gettokenname( NULL, &localtoken); 2284 2285 if (strcmp( localtoken, tokennamep)) 2286 2287 *tokenpinp = pkcs_pin; 2288 else 2289 *tokenpinp = NULL; 2290 2291 if ( ldaptool_verbose ) { 2292 if (pkcs_pin) 2293 { 2294 printf(gettext("ldaptool_getokenpin --%s\n"), tokenpinp); 2295 } 2296 else 2297 { 2298 printf(gettext("ldaptool_getokenpin -- (null)\n")); 2299 } 2300 } 2301 return LDAP_SUCCESS; 2302 #endif 2303 } 2304 2305 int 2306 ldaptool_getmodpath( void *context, char **modulep ) 2307 { 2308 *modulep = ssl_secmodpath; 2309 if ( ldaptool_verbose ) { 2310 if (ssl_secmodpath) 2311 { 2312 printf(gettext("ldaptool_getmodpath -- %s\n"), *modulep); 2313 } 2314 else 2315 { 2316 printf(gettext("ldaptool_getmodpath -- (null)\n")); 2317 } 2318 } 2319 2320 return LDAP_SUCCESS; 2321 } 2322 2323 int 2324 ldaptool_getdonglefilename( void *context, char **filename ) 2325 { 2326 *filename = ssl_donglefile; 2327 if ( ldaptool_verbose ) { 2328 if (ssl_donglefile) 2329 { 2330 printf(gettext("ldaptool_getdonglefilename -- %s\n"), *filename); 2331 } 2332 else 2333 { 2334 printf(gettext("ldaptool_getdonglefilename -- (null)\n")); 2335 } 2336 2337 } 2338 2339 return LDAP_SUCCESS; 2340 } 2341 2342 static int 2343 ldaptool_setcallbacks( struct ldapssl_pkcs_fns *pfns) 2344 { 2345 pfns->pkcs_getcertpath = (int (*)(void *, char **))ldaptool_getcertpath; 2346 pfns->pkcs_getcertname = (int (*)(void *, char **))ldaptool_getcertname; 2347 pfns->pkcs_getkeypath = (int (*)(void *, char **)) ldaptool_getkeypath; 2348 pfns->pkcs_getmodpath = (int (*)(void *, char **)) ldaptool_getmodpath; 2349 pfns->pkcs_getpin = (int (*)(void *, const char*, char **)) ldaptool_gettokenpin; 2350 pfns->pkcs_gettokenname = (int (*)(void *, char **)) ldaptool_gettokenname; 2351 pfns->pkcs_getdonglefilename = (int (*)(void *, char **)) ldaptool_getdonglefilename; 2352 pfns->local_structure_id=PKCS_STRUCTURE_ID; 2353 return LDAP_SUCCESS; 2354 } 2355 2356 2357 2358 #ifdef FORTEZZA 2359 static int 2360 ldaptool_fortezza_init( int exit_on_error ) 2361 { 2362 int rc, errcode; 2363 2364 if ( fortezza_personality == NULL && fortezza_cardmask == 0 ) { /* no FORTEZZA desired */ 2365 SSL_EnableGroup( SSL_GroupFortezza, DSFalse ); /* disable FORTEZZA */ 2366 return( 0 ); 2367 } 2368 2369 if (( rc = FortezzaConfigureServer( ldaptool_fortezza_getpin, fortezza_cardmask, 2370 fortezza_personality, ldaptool_fortezza_alert, NULL, &errcode, 2371 fortezza_krlfile )) < 0 ) { 2372 fprintf( stderr, 2373 "%s: FORTEZZA initialization failed (error %d - %s)\n", 2374 ldaptool_progname, errcode, 2375 ldaptool_fortezza_err2string( errcode )); 2376 if ( exit_on_error ) { 2377 exit( LDAP_LOCAL_ERROR ); 2378 } 2379 2380 SSL_EnableGroup( SSL_GroupFortezza, DSFalse ); /* disable FORTEZZA */ 2381 return( -1 ); 2382 } 2383 2384 SSL_EnableGroup( SSL_GroupFortezza, DSTrue ); /* enable FORTEZZA */ 2385 return( 0 ); 2386 } 2387 2388 2389 static int 2390 ldaptool_fortezza_alert( void *arg, PRBool onOpen, char *string, 2391 int value1, void *value2 ) 2392 { 2393 fprintf( stderr, "%s: FORTEZZA alert: ", ldaptool_progname ); 2394 fprintf( stderr, string, value1, value2 ); 2395 fprintf( stderr, "\n" ); 2396 return( 1 ); 2397 } 2398 2399 2400 static void * 2401 ldaptool_fortezza_getpin( char **passwordp ) 2402 { 2403 *passwordp = fortezza_pin; 2404 return( *passwordp ); 2405 } 2406 2407 2408 /* 2409 * convert a Fortezza error code (as returned by FortezzaConfigureServer() 2410 * into a human-readable string. 2411 * 2412 * Error strings are intentionally similar to those found in 2413 * ns/netsite/lib/libadmin/httpcon.c 2414 */ 2415 static char * 2416 ldaptool_fortezza_err2string( int err ) 2417 { 2418 char *s; 2419 2420 switch( err ) { 2421 case FORTEZZA_BADPASSWD: 2422 s = "invalid pin number"; 2423 break; 2424 case FORTEZZA_BADCARD: 2425 s = "bad or missing card"; 2426 break; 2427 case FORTEZZA_MISSING_KRL: 2428 s = "bad or missing compromised key list"; 2429 break; 2430 case FORTEZZA_CERT_INIT_ERROR: 2431 s = "unable to initialize certificate cache. either a cert on " 2432 "the card is bad, or an old FORTEZZA certificate is in a" 2433 "readonly database"; 2434 break; 2435 case FORTEZZA_EXPIRED_CERT: 2436 s = "unable to verify certificate"; 2437 break; 2438 default: 2439 s = "unknown error"; 2440 } 2441 2442 return( s ); 2443 } 2444 2445 #endif /* FORTEZZA */ 2446 #endif /* LDAP_TOOL_PKCS11 */ 2447 #endif /* NET_SSL */ 2448 2449 int 2450 ldaptool_boolean_str2value ( const char *ptr, int strict ) 2451 { 2452 if (strict) { 2453 if ( !(strcasecmp(ptr, "true"))) { 2454 return 1; 2455 } 2456 else if ( !(strcasecmp(ptr, "false"))) { 2457 return 0; 2458 } 2459 else { 2460 return (-1); 2461 } 2462 } 2463 else { 2464 if ( !(strcasecmp(ptr, "true")) || 2465 !(strcasecmp(ptr, "t")) || 2466 !(strcmp(ptr, "1")) ) { 2467 return (1); 2468 } 2469 else if ( !(strcasecmp(ptr, "false")) || 2470 !(strcasecmp(ptr, "f")) || 2471 !(strcmp(ptr, "0")) ) { 2472 return (0); 2473 } 2474 else { 2475 return (-1); 2476 } 2477 } 2478 } 2479 2480 FILE * 2481 ldaptool_open_file(const char *filename, const char *mode) 2482 { 2483 #ifdef _LARGEFILE64_SOURCE 2484 return fopen64(filename, mode); 2485 #else 2486 return fopen(filename, mode); 2487 #endif 2488 } 2489 2490 #ifdef later 2491 /* Functions for list in ldapdelete.c */ 2492 2493 void L_Init(Head *list) 2494 { 2495 if(list) 2496 { 2497 list->first = NULL; 2498 list->last = NULL; 2499 list->count = 0; 2500 } 2501 } 2502 2503 void L_Insert(Element *Node, Head *HeadNode) 2504 { 2505 if (!Node || !HeadNode) 2506 return; 2507 2508 Node->right = NULL; 2509 2510 if (HeadNode->first == NULL) 2511 { 2512 Node->left= NULL; 2513 HeadNode->last = HeadNode->first = Node; 2514 } 2515 else 2516 { 2517 Node->left = HeadNode->last; 2518 HeadNode->last = Node->left->right = Node; 2519 } 2520 HeadNode->count++; 2521 } 2522 2523 void L_Remove(Element *Node, Head *HeadNode) 2524 { 2525 Element *traverse = NULL; 2526 Element *prevnode = NULL; 2527 2528 if(!Node || !HeadNode) 2529 return; 2530 2531 for(traverse = HeadNode->first; traverse; traverse = traverse->right) 2532 { 2533 if(traverse == Node) 2534 { 2535 if(HeadNode->first == traverse) 2536 { 2537 HeadNode->first = traverse->right; 2538 } 2539 if(HeadNode->last == traverse) 2540 { 2541 HeadNode->last = prevnode; 2542 } 2543 traverse = traverse->right; 2544 if(prevnode != NULL) 2545 { 2546 prevnode->right = traverse; 2547 } 2548 if(traverse != NULL) 2549 { 2550 traverse->left = prevnode; 2551 } 2552 HeadNode->count--; 2553 return; 2554 } 2555 else /* traverse != node */ 2556 { 2557 prevnode = traverse; 2558 } 2559 } 2560 } 2561 #endif 2562 2563 #ifdef HAVE_SASL_OPTIONS 2564 /* 2565 * Function checks for valid args, returns an error if not found 2566 * and sets SASL params from command line 2567 */ 2568 2569 static int 2570 saslSetParam(char *saslarg) 2571 { 2572 char *attr = NULL; 2573 2574 attr = strchr(saslarg, '='); 2575 if (attr == NULL) { 2576 fprintf( stderr, gettext("Didn't find \"=\" character in %s\n"), saslarg); 2577 return (-1); 2578 } 2579 *attr = '\0'; 2580 attr++; 2581 2582 if (!strcasecmp(saslarg, "secProp")) { 2583 if ( sasl_secprops != NULL ) { 2584 fprintf( stderr, gettext("secProp previously specified\n")); 2585 return (-1); 2586 } 2587 if (( sasl_secprops = strdup(attr)) == NULL ) { 2588 perror ("malloc"); 2589 exit (LDAP_NO_MEMORY); 2590 } 2591 } else if (!strcasecmp(saslarg, "realm")) { 2592 if ( sasl_realm != NULL ) { 2593 fprintf( stderr, gettext("Realm previously specified\n")); 2594 return (-1); 2595 } 2596 if (( sasl_realm = strdup(attr)) == NULL ) { 2597 perror ("malloc"); 2598 exit (LDAP_NO_MEMORY); 2599 } 2600 } else if (!strcasecmp(saslarg, "authzid")) { 2601 if (sasl_username != NULL) { 2602 fprintf( stderr, gettext("Authorization name previously specified\n")); 2603 return (-1); 2604 } 2605 if (( sasl_username = strdup(attr)) == NULL ) { 2606 perror ("malloc"); 2607 exit (LDAP_NO_MEMORY); 2608 } 2609 } else if (!strcasecmp(saslarg, "authid")) { 2610 if ( sasl_authid != NULL ) { 2611 fprintf( stderr, gettext("Authentication name previously specified\n")); 2612 return (-1); 2613 } 2614 if (( sasl_authid = strdup(attr)) == NULL) { 2615 perror ("malloc"); 2616 exit (LDAP_NO_MEMORY); 2617 } 2618 } else if (!strcasecmp(saslarg, "mech")) { 2619 if ( sasl_mech != NULL ) { 2620 fprintf( stderr, gettext("Mech previously specified\n")); 2621 return (-1); 2622 } 2623 if (( sasl_mech = strdup(attr)) == NULL) { 2624 perror ("malloc"); 2625 exit (LDAP_NO_MEMORY); 2626 } 2627 } else { 2628 fprintf (stderr, gettext("Invalid attribute name %s\n"), saslarg); 2629 return (-1); 2630 } 2631 return 0; 2632 } 2633 #endif /* HAVE_SASL_OPTIONS */ 2634