~ttx/openldap/lucid-gssapi-495418

« back to all changes in this revision

Viewing changes to servers/slapd/slapcommon.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2008-07-10 14:45:49 UTC
  • Revision ID: james.westby@ubuntu.com-20080710144549-wck73med0e72gfyo
Tags: upstream-2.4.10
ImportĀ upstreamĀ versionĀ 2.4.10

Show diffs side-by-side

added added

removed removed

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