1 /* $NetBSD: slapcommon.c,v 1.1.1.2 2010/03/08 02:14:20 lukem Exp $ */ 2 3 /* slapcommon.c - common routine for the slap tools */ 4 /* OpenLDAP: pkg/ldap/servers/slapd/slapcommon.c,v 1.73.2.18 2009/11/24 00:51:40 quanah Exp */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2009 The OpenLDAP Foundation. 8 * Portions Copyright 1998-2003 Kurt D. Zeilenga. 9 * Portions Copyright 2003 IBM Corporation. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted only as authorized by the OpenLDAP 14 * Public License. 15 * 16 * A copy of this license is available in file LICENSE in the 17 * top-level directory of the distribution or, alternatively, at 18 * <http://www.OpenLDAP.org/license.html>. 19 */ 20 /* ACKNOWLEDGEMENTS: 21 * This work was initially developed by Kurt Zeilenga for inclusion 22 * in OpenLDAP Software. Additional signficant contributors include 23 * Jong Hyuk Choi 24 * Hallvard B. Furuseth 25 * Howard Chu 26 * Pierangelo Masarati 27 */ 28 29 #include "portable.h" 30 31 #include <stdio.h> 32 33 #include <ac/stdlib.h> 34 #include <ac/ctype.h> 35 #include <ac/string.h> 36 #include <ac/socket.h> 37 #include <ac/unistd.h> 38 39 #include "slapcommon.h" 40 #include "lutil.h" 41 #include "ldif.h" 42 43 tool_vars tool_globals; 44 45 #ifdef CSRIMALLOC 46 static char *leakfilename; 47 static FILE *leakfile; 48 #endif 49 50 static LDIFFP dummy; 51 52 #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) 53 int start_syslog; 54 static char **syslog_unknowns; 55 #ifdef LOG_LOCAL4 56 static int syslogUser = SLAP_DEFAULT_SYSLOG_USER; 57 #endif /* LOG_LOCAL4 */ 58 #endif /* LDAP_DEBUG && LDAP_SYSLOG */ 59 60 static void 61 usage( int tool, const char *progname ) 62 { 63 char *options = NULL; 64 fprintf( stderr, 65 "usage: %s [-v] [-d debuglevel] [-f configfile] [-F configdir] [-o <name>[=<value>]]", 66 progname ); 67 68 switch( tool ) { 69 case SLAPACL: 70 options = "\n\t[-U authcID | -D authcDN] [-X authzID | -o authzDN=<DN>]" 71 "\n\t-b DN [-u] [attr[/access][:value]] [...]\n"; 72 break; 73 74 case SLAPADD: 75 options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]\n" 76 "\t[-l ldiffile] [-j linenumber] [-q] [-u] [-s] [-w]\n"; 77 break; 78 79 case SLAPAUTH: 80 options = "\n\t[-U authcID] [-X authzID] [-R realm] [-M mech] ID [...]\n"; 81 break; 82 83 case SLAPCAT: 84 options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]" 85 " [-l ldiffile] [-a filter] [-s subtree]\n"; 86 break; 87 88 case SLAPDN: 89 options = "\n\t[-N | -P] DN [...]\n"; 90 break; 91 92 case SLAPINDEX: 93 options = " [-c]\n\t[-g] [-n databasenumber | -b suffix] [attr ...] [-q] [-t]\n"; 94 break; 95 96 case SLAPTEST: 97 options = " [-n databasenumber] [-u]\n"; 98 break; 99 100 case SLAPSCHEMA: 101 options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]" 102 " [-l errorfile] [-a filter] [-s subtree]\n"; 103 break; 104 } 105 106 if ( options != NULL ) { 107 fputs( options, stderr ); 108 } 109 exit( EXIT_FAILURE ); 110 } 111 112 static int 113 parse_slapopt( void ) 114 { 115 size_t len = 0; 116 char *p; 117 118 p = strchr( optarg, '=' ); 119 if ( p != NULL ) { 120 len = p - optarg; 121 p++; 122 } 123 124 if ( strncasecmp( optarg, "sockurl", len ) == 0 ) { 125 if ( !BER_BVISNULL( &listener_url ) ) { 126 ber_memfree( listener_url.bv_val ); 127 } 128 ber_str2bv( p, 0, 1, &listener_url ); 129 130 } else if ( strncasecmp( optarg, "domain", len ) == 0 ) { 131 if ( !BER_BVISNULL( &peer_domain ) ) { 132 ber_memfree( peer_domain.bv_val ); 133 } 134 ber_str2bv( p, 0, 1, &peer_domain ); 135 136 } else if ( strncasecmp( optarg, "peername", len ) == 0 ) { 137 if ( !BER_BVISNULL( &peer_name ) ) { 138 ber_memfree( peer_name.bv_val ); 139 } 140 ber_str2bv( p, 0, 1, &peer_name ); 141 142 } else if ( strncasecmp( optarg, "sockname", len ) == 0 ) { 143 if ( !BER_BVISNULL( &sock_name ) ) { 144 ber_memfree( sock_name.bv_val ); 145 } 146 ber_str2bv( p, 0, 1, &sock_name ); 147 148 } else if ( strncasecmp( optarg, "ssf", len ) == 0 ) { 149 if ( lutil_atou( &ssf, p ) ) { 150 Debug( LDAP_DEBUG_ANY, "unable to parse ssf=\"%s\".\n", p, 0, 0 ); 151 return -1; 152 } 153 154 } else if ( strncasecmp( optarg, "transport_ssf", len ) == 0 ) { 155 if ( lutil_atou( &transport_ssf, p ) ) { 156 Debug( LDAP_DEBUG_ANY, "unable to parse transport_ssf=\"%s\".\n", p, 0, 0 ); 157 return -1; 158 } 159 160 } else if ( strncasecmp( optarg, "tls_ssf", len ) == 0 ) { 161 if ( lutil_atou( &tls_ssf, p ) ) { 162 Debug( LDAP_DEBUG_ANY, "unable to parse tls_ssf=\"%s\".\n", p, 0, 0 ); 163 return -1; 164 } 165 166 } else if ( strncasecmp( optarg, "sasl_ssf", len ) == 0 ) { 167 if ( lutil_atou( &sasl_ssf, p ) ) { 168 Debug( LDAP_DEBUG_ANY, "unable to parse sasl_ssf=\"%s\".\n", p, 0, 0 ); 169 return -1; 170 } 171 172 } else if ( strncasecmp( optarg, "authzDN", len ) == 0 ) { 173 ber_str2bv( p, 0, 1, &authzDN ); 174 175 #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) 176 } else if ( strncasecmp( optarg, "syslog", len ) == 0 ) { 177 if ( parse_debug_level( p, &ldap_syslog, &syslog_unknowns ) ) { 178 return -1; 179 } 180 start_syslog = 1; 181 182 } else if ( strncasecmp( optarg, "syslog-level", len ) == 0 ) { 183 if ( parse_syslog_level( p, &ldap_syslog_level ) ) { 184 return -1; 185 } 186 start_syslog = 1; 187 188 #ifdef LOG_LOCAL4 189 } else if ( strncasecmp( optarg, "syslog-user", len ) == 0 ) { 190 if ( parse_syslog_user( p, &syslogUser ) ) { 191 return -1; 192 } 193 start_syslog = 1; 194 #endif /* LOG_LOCAL4 */ 195 #endif /* LDAP_DEBUG && LDAP_SYSLOG */ 196 197 } else { 198 return -1; 199 } 200 201 return 0; 202 } 203 204 /* 205 * slap_tool_init - initialize slap utility, handle program options. 206 * arguments: 207 * name program name 208 * tool tool code 209 * argc, argv command line arguments 210 */ 211 212 static int need_shutdown; 213 214 void 215 slap_tool_init( 216 const char* progname, 217 int tool, 218 int argc, char **argv ) 219 { 220 char *options; 221 char *conffile = NULL; 222 char *confdir = NULL; 223 struct berval base = BER_BVNULL; 224 char *filterstr = NULL; 225 char *subtree = NULL; 226 char *ldiffile = NULL; 227 char **debug_unknowns = NULL; 228 int rc, i; 229 int mode = SLAP_TOOL_MODE; 230 int truncatemode = 0; 231 int use_glue = 1; 232 int writer; 233 234 #ifdef LDAP_DEBUG 235 /* tools default to "none", so that at least LDAP_DEBUG_ANY 236 * messages show up; use -d 0 to reset */ 237 slap_debug = LDAP_DEBUG_NONE; 238 ldif_debug = slap_debug; 239 #endif 240 ldap_syslog = 0; 241 242 #ifdef CSRIMALLOC 243 leakfilename = malloc( strlen( progname ) + STRLENOF( ".leak" ) + 1 ); 244 sprintf( leakfilename, "%s.leak", progname ); 245 if( ( leakfile = fopen( leakfilename, "w" )) == NULL ) { 246 leakfile = stderr; 247 } 248 free( leakfilename ); 249 leakfilename = NULL; 250 #endif 251 252 switch( tool ) { 253 case SLAPADD: 254 options = "b:cd:f:F:gj:l:n:o:qsS:uvw"; 255 break; 256 257 case SLAPCAT: 258 options = "a:b:cd:f:F:gl:n:o:s:v"; 259 mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; 260 break; 261 262 case SLAPDN: 263 options = "d:f:F:No:Pv"; 264 mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; 265 break; 266 267 case SLAPSCHEMA: 268 options = "a:b:cd:f:F:gl:n:o:s:v"; 269 mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; 270 break; 271 272 case SLAPTEST: 273 options = "d:f:F:n:o:Quv"; 274 mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; 275 break; 276 277 case SLAPAUTH: 278 options = "d:f:F:M:o:R:U:vX:"; 279 mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; 280 break; 281 282 case SLAPINDEX: 283 options = "b:cd:f:F:gn:o:qtv"; 284 mode |= SLAP_TOOL_READMAIN; 285 break; 286 287 case SLAPACL: 288 options = "b:D:d:f:F:o:uU:vX:"; 289 mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; 290 break; 291 292 default: 293 fprintf( stderr, "%s: unknown tool mode (%d)\n", progname, tool ); 294 exit( EXIT_FAILURE ); 295 } 296 297 dbnum = -1; 298 while ( (i = getopt( argc, argv, options )) != EOF ) { 299 switch ( i ) { 300 case 'a': 301 filterstr = ch_strdup( optarg ); 302 break; 303 304 case 'b': 305 ber_str2bv( optarg, 0, 1, &base ); 306 break; 307 308 case 'c': /* enable continue mode */ 309 continuemode++; 310 break; 311 312 case 'd': { /* turn on debugging */ 313 int level = 0; 314 315 if ( parse_debug_level( optarg, &level, &debug_unknowns ) ) { 316 usage( tool, progname ); 317 } 318 #ifdef LDAP_DEBUG 319 if ( level == 0 ) { 320 /* allow to reset log level */ 321 slap_debug = 0; 322 323 } else { 324 slap_debug |= level; 325 } 326 #else 327 if ( level != 0 ) 328 fputs( "must compile with LDAP_DEBUG for debugging\n", 329 stderr ); 330 #endif 331 } break; 332 333 case 'D': 334 ber_str2bv( optarg, 0, 1, &authcDN ); 335 break; 336 337 case 'f': /* specify a conf file */ 338 conffile = ch_strdup( optarg ); 339 break; 340 341 case 'F': /* specify a conf dir */ 342 confdir = ch_strdup( optarg ); 343 break; 344 345 case 'g': /* disable subordinate glue */ 346 use_glue = 0; 347 break; 348 349 case 'j': /* jump to linenumber */ 350 if ( lutil_atoi( &jumpline, optarg ) ) { 351 usage( tool, progname ); 352 } 353 break; 354 355 case 'l': /* LDIF file */ 356 ldiffile = ch_strdup( optarg ); 357 break; 358 359 case 'M': 360 ber_str2bv( optarg, 0, 0, &mech ); 361 break; 362 363 case 'N': 364 if ( dn_mode && dn_mode != SLAP_TOOL_LDAPDN_NORMAL ) { 365 usage( tool, progname ); 366 } 367 dn_mode = SLAP_TOOL_LDAPDN_NORMAL; 368 break; 369 370 case 'n': /* which config file db to index */ 371 if ( lutil_atoi( &dbnum, optarg ) || dbnum < 0 ) { 372 usage( tool, progname ); 373 } 374 break; 375 376 case 'o': 377 if ( parse_slapopt() ) { 378 usage( tool, progname ); 379 } 380 break; 381 382 case 'P': 383 if ( dn_mode && dn_mode != SLAP_TOOL_LDAPDN_PRETTY ) { 384 usage( tool, progname ); 385 } 386 dn_mode = SLAP_TOOL_LDAPDN_PRETTY; 387 break; 388 389 case 'Q': 390 quiet++; 391 slap_debug = 0; 392 break; 393 394 case 'q': /* turn on quick */ 395 mode |= SLAP_TOOL_QUICK; 396 break; 397 398 case 'R': 399 realm = optarg; 400 break; 401 402 case 'S': 403 if ( lutil_atou( &csnsid, optarg ) 404 || csnsid > SLAP_SYNC_SID_MAX ) 405 { 406 usage( tool, progname ); 407 } 408 break; 409 410 case 's': /* dump subtree */ 411 if ( tool == SLAPADD ) 412 mode |= SLAP_TOOL_NO_SCHEMA_CHECK; 413 else if ( tool == SLAPCAT || tool == SLAPSCHEMA ) 414 subtree = ch_strdup( optarg ); 415 break; 416 417 case 't': /* turn on truncate */ 418 truncatemode++; 419 mode |= SLAP_TRUNCATE_MODE; 420 break; 421 422 case 'U': 423 ber_str2bv( optarg, 0, 0, &authcID ); 424 break; 425 426 case 'u': /* dry run */ 427 dryrun++; 428 break; 429 430 case 'v': /* turn on verbose */ 431 verbose++; 432 break; 433 434 case 'w': /* write context csn at the end */ 435 update_ctxcsn++; 436 break; 437 438 case 'X': 439 ber_str2bv( optarg, 0, 0, &authzID ); 440 break; 441 442 default: 443 usage( tool, progname ); 444 break; 445 } 446 } 447 448 #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) 449 if ( start_syslog ) { 450 char *logName; 451 #ifdef HAVE_EBCDIC 452 logName = ch_strdup( progname ); 453 __atoe( logName ); 454 #else 455 logName = (char *)progname; 456 #endif 457 458 #ifdef LOG_LOCAL4 459 openlog( logName, OPENLOG_OPTIONS, syslogUser ); 460 #elif defined LOG_DEBUG 461 openlog( logName, OPENLOG_OPTIONS ); 462 #endif 463 #ifdef HAVE_EBCDIC 464 free( logName ); 465 logName = NULL; 466 #endif 467 } 468 #endif /* LDAP_DEBUG && LDAP_SYSLOG */ 469 470 switch ( tool ) { 471 case SLAPCAT: 472 case SLAPSCHEMA: 473 writer = 1; 474 break; 475 476 default: 477 writer = 0; 478 break; 479 } 480 481 switch ( tool ) { 482 case SLAPADD: 483 case SLAPCAT: 484 case SLAPSCHEMA: 485 if ( ( argc != optind ) || (dbnum >= 0 && base.bv_val != NULL ) ) { 486 usage( tool, progname ); 487 } 488 489 break; 490 491 case SLAPINDEX: 492 if ( dbnum >= 0 && base.bv_val != NULL ) { 493 usage( tool, progname ); 494 } 495 496 break; 497 498 case SLAPDN: 499 if ( argc == optind ) { 500 usage( tool, progname ); 501 } 502 break; 503 504 case SLAPAUTH: 505 if ( argc == optind && BER_BVISNULL( &authcID ) ) { 506 usage( tool, progname ); 507 } 508 break; 509 510 case SLAPTEST: 511 if ( argc != optind ) { 512 usage( tool, progname ); 513 } 514 break; 515 516 case SLAPACL: 517 if ( !BER_BVISNULL( &authcDN ) && !BER_BVISNULL( &authcID ) ) { 518 usage( tool, progname ); 519 } 520 if ( BER_BVISNULL( &base ) ) { 521 usage( tool, progname ); 522 } 523 ber_dupbv( &baseDN, &base ); 524 break; 525 526 default: 527 break; 528 } 529 530 if ( ldiffile == NULL ) { 531 dummy.fp = writer ? stdout : stdin; 532 ldiffp = &dummy; 533 534 } else if ((ldiffp = ldif_open( ldiffile, writer ? "w" : "r" )) 535 == NULL ) 536 { 537 perror( ldiffile ); 538 exit( EXIT_FAILURE ); 539 } 540 541 /* 542 * initialize stuff and figure out which backend we're dealing with 543 */ 544 545 rc = slap_init( mode, progname ); 546 if ( rc != 0 ) { 547 fprintf( stderr, "%s: slap_init failed!\n", progname ); 548 exit( EXIT_FAILURE ); 549 } 550 551 rc = read_config( conffile, confdir ); 552 553 if ( rc != 0 ) { 554 fprintf( stderr, "%s: bad configuration %s!\n", 555 progname, confdir ? "directory" : "file" ); 556 exit( EXIT_FAILURE ); 557 } 558 559 if ( debug_unknowns ) { 560 rc = parse_debug_unknowns( debug_unknowns, &slap_debug ); 561 ldap_charray_free( debug_unknowns ); 562 debug_unknowns = NULL; 563 if ( rc ) 564 exit( EXIT_FAILURE ); 565 } 566 567 #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) 568 if ( syslog_unknowns ) { 569 rc = parse_debug_unknowns( syslog_unknowns, &ldap_syslog ); 570 ldap_charray_free( syslog_unknowns ); 571 syslog_unknowns = NULL; 572 if ( rc ) 573 exit( EXIT_FAILURE ); 574 } 575 #endif 576 577 at_oc_cache = 1; 578 579 switch ( tool ) { 580 case SLAPADD: 581 case SLAPCAT: 582 case SLAPINDEX: 583 case SLAPSCHEMA: 584 if ( !nbackends ) { 585 fprintf( stderr, "No databases found " 586 "in config file\n" ); 587 exit( EXIT_FAILURE ); 588 } 589 break; 590 591 default: 592 break; 593 } 594 595 if ( use_glue ) { 596 rc = glue_sub_attach( 0 ); 597 598 if ( rc != 0 ) { 599 fprintf( stderr, 600 "%s: subordinate configuration error\n", progname ); 601 exit( EXIT_FAILURE ); 602 } 603 } 604 605 rc = slap_schema_check(); 606 607 if ( rc != 0 ) { 608 fprintf( stderr, "%s: slap_schema_prep failed!\n", progname ); 609 exit( EXIT_FAILURE ); 610 } 611 612 switch ( tool ) { 613 case SLAPTEST: 614 if ( dbnum >= 0 ) 615 goto get_db; 616 /* FALLTHRU */ 617 case SLAPDN: 618 case SLAPAUTH: 619 be = NULL; 620 goto startup; 621 622 default: 623 break; 624 } 625 626 if( filterstr ) { 627 filter = str2filter( filterstr ); 628 629 if( filter == NULL ) { 630 fprintf( stderr, "Invalid filter '%s'\n", filterstr ); 631 exit( EXIT_FAILURE ); 632 } 633 634 ch_free( filterstr ); 635 filterstr = NULL; 636 } 637 638 if( subtree ) { 639 struct berval val; 640 ber_str2bv( subtree, 0, 0, &val ); 641 rc = dnNormalize( 0, NULL, NULL, &val, &sub_ndn, NULL ); 642 if( rc != LDAP_SUCCESS ) { 643 fprintf( stderr, "Invalid subtree DN '%s'\n", subtree ); 644 exit( EXIT_FAILURE ); 645 } 646 647 if ( BER_BVISNULL( &base ) && dbnum == -1 ) { 648 base = val; 649 } else { 650 free( subtree ); 651 subtree = NULL; 652 } 653 } 654 655 if( base.bv_val != NULL ) { 656 struct berval nbase; 657 658 rc = dnNormalize( 0, NULL, NULL, &base, &nbase, NULL ); 659 if( rc != LDAP_SUCCESS ) { 660 fprintf( stderr, "%s: slap_init invalid suffix (\"%s\")\n", 661 progname, base.bv_val ); 662 exit( EXIT_FAILURE ); 663 } 664 665 be = select_backend( &nbase, 0 ); 666 ber_memfree( nbase.bv_val ); 667 BER_BVZERO( &nbase ); 668 669 switch ( tool ) { 670 case SLAPACL: 671 goto startup; 672 673 default: 674 break; 675 } 676 677 if( be == NULL ) { 678 fprintf( stderr, "%s: slap_init no backend for \"%s\"\n", 679 progname, base.bv_val ); 680 exit( EXIT_FAILURE ); 681 } 682 /* If the named base is a glue master, operate on the 683 * entire context 684 */ 685 if ( SLAP_GLUE_INSTANCE( be ) ) { 686 nosubordinates = 1; 687 } 688 689 ch_free( base.bv_val ); 690 BER_BVZERO( &base ); 691 692 } else if ( dbnum == -1 ) { 693 /* no suffix and no dbnum specified, just default to 694 * the first available database 695 */ 696 if ( nbackends <= 0 ) { 697 fprintf( stderr, "No available databases\n" ); 698 exit( EXIT_FAILURE ); 699 } 700 LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { 701 dbnum++; 702 703 /* db #0 is cn=config, don't select it as a default */ 704 if ( dbnum < 1 ) continue; 705 706 if ( SLAP_MONITOR(be)) 707 continue; 708 709 /* If just doing the first by default and it is a 710 * glue subordinate, find the master. 711 */ 712 if ( SLAP_GLUE_SUBORDINATE(be) ) { 713 nosubordinates = 1; 714 continue; 715 } 716 break; 717 } 718 719 if ( !be ) { 720 fprintf( stderr, "Available database(s) " 721 "do not allow %s\n", progname ); 722 exit( EXIT_FAILURE ); 723 } 724 725 if ( nosubordinates == 0 && dbnum > 1 ) { 726 Debug( LDAP_DEBUG_ANY, 727 "The first database does not allow %s;" 728 " using the first available one (%d)\n", 729 progname, dbnum, 0 ); 730 } 731 732 } else if ( dbnum >= nbackends ) { 733 fprintf( stderr, 734 "Database number selected via -n is out of range\n" 735 "Must be in the range 0 to %d" 736 " (the number of configured databases)\n", 737 nbackends - 1 ); 738 exit( EXIT_FAILURE ); 739 740 } else { 741 get_db: 742 LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { 743 if ( dbnum == 0 ) break; 744 dbnum--; 745 } 746 } 747 748 startup:; 749 if ( be ) { 750 BackendDB *bdtmp; 751 752 dbnum = 0; 753 LDAP_STAILQ_FOREACH( bdtmp, &backendDB, be_next ) { 754 if ( bdtmp == be ) break; 755 dbnum++; 756 } 757 } 758 759 #ifdef CSRIMALLOC 760 mal_leaktrace(1); 761 #endif 762 763 if ( conffile != NULL ) { 764 ch_free( conffile ); 765 conffile = NULL; 766 } 767 768 if ( confdir != NULL ) { 769 ch_free( confdir ); 770 confdir = NULL; 771 } 772 773 if ( ldiffile != NULL ) { 774 ch_free( ldiffile ); 775 ldiffile = NULL; 776 } 777 778 /* slapdn doesn't specify a backend to startup */ 779 if ( !dryrun && tool != SLAPDN ) { 780 need_shutdown = 1; 781 782 if ( slap_startup( be ) ) { 783 switch ( tool ) { 784 case SLAPTEST: 785 fprintf( stderr, "slap_startup failed " 786 "(test would succeed using " 787 "the -u switch)\n" ); 788 break; 789 790 default: 791 fprintf( stderr, "slap_startup failed\n" ); 792 break; 793 } 794 795 exit( EXIT_FAILURE ); 796 } 797 } 798 } 799 800 int slap_tool_destroy( void ) 801 { 802 int rc = 0; 803 if ( !dryrun ) { 804 if ( need_shutdown ) { 805 if ( slap_shutdown( be )) 806 rc = EXIT_FAILURE; 807 } 808 if ( slap_destroy()) 809 rc = EXIT_FAILURE; 810 } 811 #ifdef SLAPD_MODULES 812 if ( slapMode == SLAP_SERVER_MODE ) { 813 /* always false. just pulls in necessary symbol references. */ 814 lutil_uuidstr(NULL, 0); 815 } 816 module_kill(); 817 #endif 818 schema_destroy(); 819 #ifdef HAVE_TLS 820 ldap_pvt_tls_destroy(); 821 #endif 822 config_destroy(); 823 824 #ifdef CSRIMALLOC 825 mal_dumpleaktrace( leakfile ); 826 #endif 827 828 if ( !BER_BVISNULL( &authcDN ) ) { 829 ch_free( authcDN.bv_val ); 830 BER_BVZERO( &authcDN ); 831 } 832 833 if ( ldiffp && ldiffp != &dummy ) { 834 ldif_close( ldiffp ); 835 } 836 return rc; 837 } 838