]>
Commit | Line | Data |
---|---|---|
57ba4cac HC |
1 | /* slapcommon.c - common routine for the slap tools */ |
2 | /* $OpenLDAP$ */ | |
3 | /* This work is part of OpenLDAP Software <http://www.openldap.org/>. | |
4 | * | |
dc0eacd4 | 5 | * Copyright 1998-2005 The OpenLDAP Foundation. |
57ba4cac HC |
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" | |
c225c4af | 39 | #include "ldif.h" |
57ba4cac HC |
40 | |
41 | tool_vars tool_globals; | |
42 | ||
43 | #ifdef CSRIMALLOC | |
44 | static char *leakfilename; | |
45 | static FILE *leakfile; | |
46 | #endif | |
47 | ||
c225c4af HC |
48 | static LDIFFP dummy; |
49 | ||
57ba4cac HC |
50 | static void |
51 | usage( int tool, const char *progname ) | |
52 | { | |
53 | char *options = NULL; | |
54 | fprintf( stderr, | |
2605dfa8 | 55 | "usage: %s [-v] [-d debuglevel] [-f configfile] [-F configdir]", |
764aa5d9 | 56 | progname ); |
57ba4cac HC |
57 | |
58 | switch( tool ) { | |
0ea4070e | 59 | case SLAPACL: |
e9ab146a PM |
60 | options = "\n\t[-U authcID | -D authcDN] [-X authzID | -o authzDN=<DN>]" |
61 | "\n\t-b DN -o <var>[=<val>] [-u] [attr[/access][:value]] [...]\n"; | |
0ea4070e PM |
62 | break; |
63 | ||
57ba4cac | 64 | case SLAPADD: |
37e58a73 | 65 | options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]\n" |
51c4161c | 66 | "\t[-l ldiffile] [-q] [-u] [-w]\n"; |
57ba4cac HC |
67 | break; |
68 | ||
0ea4070e PM |
69 | case SLAPAUTH: |
70 | options = "\n\t[-U authcID] [-X authzID] [-R realm] [-M mech] ID [...]\n"; | |
71 | break; | |
72 | ||
57ba4cac | 73 | case SLAPCAT: |
37e58a73 | 74 | options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]" |
8d0f39bb | 75 | " [-l ldiffile] [-a filter]\n"; |
764aa5d9 PM |
76 | break; |
77 | ||
78 | case SLAPDN: | |
8e19437d | 79 | options = "\n\t[-N | -P] DN [...]\n"; |
57ba4cac HC |
80 | break; |
81 | ||
82 | case SLAPINDEX: | |
37e58a73 | 83 | options = " [-c]\n\t[-g] [-n databasenumber | -b suffix] [-q]\n"; |
3ea43689 | 84 | break; |
7b65d46b | 85 | |
0ea4070e PM |
86 | case SLAPTEST: |
87 | options = " [-u]\n"; | |
7b65d46b | 88 | break; |
57ba4cac HC |
89 | } |
90 | ||
764aa5d9 | 91 | if ( options != NULL ) { |
57ba4cac HC |
92 | fputs( options, stderr ); |
93 | } | |
94 | exit( EXIT_FAILURE ); | |
95 | } | |
96 | ||
83bb1c93 PM |
97 | static int |
98 | parse_slapacl( void ) | |
99 | { | |
100 | size_t len; | |
101 | char *p; | |
102 | ||
103 | p = strchr( optarg, '=' ); | |
104 | if ( p == NULL ) { | |
105 | return -1; | |
106 | } | |
107 | ||
108 | len = p - optarg; | |
109 | p++; | |
110 | ||
111 | if ( strncasecmp( optarg, "sockurl", len ) == 0 ) { | |
112 | if ( !BER_BVISNULL( &listener_url ) ) { | |
113 | ber_memfree( listener_url.bv_val ); | |
114 | } | |
115 | ber_str2bv( p, 0, 1, &listener_url ); | |
116 | ||
117 | } else if ( strncasecmp( optarg, "domain", len ) == 0 ) { | |
118 | if ( !BER_BVISNULL( &peer_domain ) ) { | |
119 | ber_memfree( peer_domain.bv_val ); | |
120 | } | |
121 | ber_str2bv( p, 0, 1, &peer_domain ); | |
122 | ||
123 | } else if ( strncasecmp( optarg, "peername", len ) == 0 ) { | |
124 | if ( !BER_BVISNULL( &peer_name ) ) { | |
125 | ber_memfree( peer_name.bv_val ); | |
126 | } | |
127 | ber_str2bv( p, 0, 1, &peer_name ); | |
128 | ||
129 | } else if ( strncasecmp( optarg, "sockname", len ) == 0 ) { | |
130 | if ( !BER_BVISNULL( &sock_name ) ) { | |
131 | ber_memfree( sock_name.bv_val ); | |
132 | } | |
133 | ber_str2bv( p, 0, 1, &sock_name ); | |
134 | ||
135 | } else if ( strncasecmp( optarg, "ssf", len ) == 0 ) { | |
0fd295a3 PM |
136 | if ( lutil_atou( &ssf, p ) ) { |
137 | Debug( LDAP_DEBUG_ANY, "unable to parse ssf=\"%s\".\n", p, 0, 0 ); | |
138 | return -1; | |
139 | } | |
83bb1c93 PM |
140 | |
141 | } else if ( strncasecmp( optarg, "transport_ssf", len ) == 0 ) { | |
0fd295a3 PM |
142 | if ( lutil_atou( &transport_ssf, p ) ) { |
143 | Debug( LDAP_DEBUG_ANY, "unable to parse transport_ssf=\"%s\".\n", p, 0, 0 ); | |
144 | return -1; | |
145 | } | |
83bb1c93 PM |
146 | |
147 | } else if ( strncasecmp( optarg, "tls_ssf", len ) == 0 ) { | |
0fd295a3 PM |
148 | if ( lutil_atou( &tls_ssf, p ) ) { |
149 | Debug( LDAP_DEBUG_ANY, "unable to parse tls_ssf=\"%s\".\n", p, 0, 0 ); | |
150 | return -1; | |
151 | } | |
83bb1c93 PM |
152 | |
153 | } else if ( strncasecmp( optarg, "sasl_ssf", len ) == 0 ) { | |
0fd295a3 PM |
154 | if ( lutil_atou( &sasl_ssf, p ) ) { |
155 | Debug( LDAP_DEBUG_ANY, "unable to parse sasl_ssf=\"%s\".\n", p, 0, 0 ); | |
156 | return -1; | |
157 | } | |
83bb1c93 | 158 | |
e9ab146a PM |
159 | } else if ( strncasecmp( optarg, "authzDN", len ) == 0 ) { |
160 | ber_str2bv( p, 0, 1, &authzDN ); | |
161 | ||
83bb1c93 PM |
162 | } else { |
163 | return -1; | |
164 | } | |
165 | ||
166 | return 0; | |
167 | } | |
57ba4cac HC |
168 | |
169 | /* | |
170 | * slap_tool_init - initialize slap utility, handle program options. | |
171 | * arguments: | |
172 | * name program name | |
173 | * tool tool code | |
174 | * argc, argv command line arguments | |
175 | */ | |
176 | ||
177 | void | |
178 | slap_tool_init( | |
179 | const char* progname, | |
180 | int tool, | |
181 | int argc, char **argv ) | |
182 | { | |
183 | char *options; | |
cb686a5e HC |
184 | char *conffile = NULL; |
185 | char *confdir = NULL; | |
44725e73 | 186 | struct berval base = BER_BVNULL; |
cdd94c7a | 187 | char *filterstr = NULL; |
57ba4cac HC |
188 | char *subtree = NULL; |
189 | char *ldiffile = NULL; | |
190 | int rc, i, dbnum; | |
191 | int mode = SLAP_TOOL_MODE; | |
192 | int truncatemode = 0; | |
37e58a73 | 193 | int use_glue = 1; |
57ba4cac | 194 | |
6315ac9d PM |
195 | #ifdef LDAP_DEBUG |
196 | /* tools default to "none", so that at least LDAP_DEBUG_ANY | |
197 | * messages show up; use -d 0 to reset */ | |
198 | ldap_debug = LDAP_DEBUG_NONE; | |
199 | #endif | |
200 | ||
57ba4cac | 201 | #ifdef CSRIMALLOC |
42dadd57 | 202 | leakfilename = malloc( strlen( progname ) + STRLENOF( ".leak" ) + 1 ); |
57ba4cac HC |
203 | sprintf( leakfilename, "%s.leak", progname ); |
204 | if( ( leakfile = fopen( leakfilename, "w" )) == NULL ) { | |
205 | leakfile = stderr; | |
206 | } | |
207 | free( leakfilename ); | |
208 | #endif | |
209 | ||
210 | switch( tool ) { | |
211 | case SLAPADD: | |
37e58a73 | 212 | options = "b:cd:f:F:gl:n:qtuvw"; |
57ba4cac HC |
213 | break; |
214 | ||
57ba4cac | 215 | case SLAPCAT: |
37e58a73 | 216 | options = "a:b:cd:f:F:gl:n:s:v"; |
57ba4cac HC |
217 | mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; |
218 | break; | |
219 | ||
764aa5d9 | 220 | case SLAPDN: |
8e19437d | 221 | options = "d:f:F:NPv"; |
854863f0 | 222 | mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; |
764aa5d9 PM |
223 | break; |
224 | ||
0ea4070e | 225 | case SLAPTEST: |
bc4564ca | 226 | options = "d:f:F:uv"; |
0ea4070e PM |
227 | mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; |
228 | break; | |
229 | ||
a54900be | 230 | case SLAPAUTH: |
bc4564ca | 231 | options = "d:f:F:M:R:U:vX:"; |
854863f0 | 232 | mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; |
3ea43689 PM |
233 | break; |
234 | ||
764aa5d9 | 235 | case SLAPINDEX: |
37e58a73 | 236 | options = "b:cd:f:F:gn:qv"; |
764aa5d9 PM |
237 | mode |= SLAP_TOOL_READMAIN; |
238 | break; | |
239 | ||
7b65d46b | 240 | case SLAPACL: |
e9ab146a | 241 | options = "b:D:d:f:F:o:uU:vX:"; |
854863f0 | 242 | mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; |
7b65d46b PM |
243 | break; |
244 | ||
57ba4cac | 245 | default: |
cdd94c7a | 246 | fprintf( stderr, "%s: unknown tool mode (%d)\n", progname, tool ); |
57ba4cac HC |
247 | exit( EXIT_FAILURE ); |
248 | } | |
249 | ||
250 | dbnum = -1; | |
251 | while ( (i = getopt( argc, argv, options )) != EOF ) { | |
252 | switch ( i ) { | |
cdd94c7a KZ |
253 | case 'a': |
254 | filterstr = strdup( optarg ); | |
255 | break; | |
256 | ||
57ba4cac | 257 | case 'b': |
3ea43689 | 258 | ber_str2bv( optarg, 0, 1, &base ); |
57ba4cac HC |
259 | break; |
260 | ||
261 | case 'c': /* enable continue mode */ | |
262 | continuemode++; | |
263 | break; | |
264 | ||
265 | case 'd': /* turn on debugging */ | |
6315ac9d | 266 | { |
e725c848 | 267 | #ifdef LDAP_DEBUG |
6315ac9d PM |
268 | int level; |
269 | ||
e725c848 PM |
270 | if ( optarg != NULL && optarg[ 0 ] != '-' && !isdigit( optarg[ 0 ] ) ) |
271 | { | |
e725c848 PM |
272 | if ( str2loglevel( optarg, &level ) ) { |
273 | fprintf( stderr, | |
274 | "unrecognized log level " | |
275 | "\"%s\"\n", optarg ); | |
276 | exit( EXIT_FAILURE ); | |
277 | } | |
278 | ||
44a1f10d | 279 | } else if ( lutil_atoix( &level, optarg, 0 ) != 0 ) { |
d34fffca PM |
280 | fprintf( stderr, |
281 | "unrecognized log level " | |
282 | "\"%s\"\n", optarg ); | |
283 | exit( EXIT_FAILURE ); | |
6315ac9d PM |
284 | } |
285 | ||
286 | if ( level ) { | |
e725c848 | 287 | ldap_debug |= level; |
6315ac9d PM |
288 | } else { |
289 | /* allow to reset log level */ | |
290 | ldap_debug = 0; | |
e725c848 PM |
291 | } |
292 | #else | |
0fd295a3 | 293 | if ( lutil_atoi( &level, optarg ) != 0 || level != 0 ) |
e725c848 PM |
294 | fputs( "must compile with LDAP_DEBUG for debugging\n", |
295 | stderr ); | |
296 | #endif | |
6315ac9d | 297 | } break; |
57ba4cac | 298 | |
7b65d46b | 299 | case 'D': |
854863f0 | 300 | ber_str2bv( optarg, 0, 1, &authcDN ); |
7b65d46b PM |
301 | break; |
302 | ||
57ba4cac HC |
303 | case 'f': /* specify a conf file */ |
304 | conffile = strdup( optarg ); | |
305 | break; | |
306 | ||
bc4564ca HC |
307 | case 'F': /* specify a conf dir */ |
308 | confdir = strdup( optarg ); | |
309 | break; | |
310 | ||
37e58a73 HC |
311 | case 'g': /* disable subordinate glue */ |
312 | use_glue = 0; | |
313 | break; | |
314 | ||
57ba4cac HC |
315 | case 'l': /* LDIF file */ |
316 | ldiffile = strdup( optarg ); | |
317 | break; | |
318 | ||
cc78fb52 PM |
319 | case 'M': |
320 | ber_str2bv( optarg, 0, 0, &mech ); | |
321 | break; | |
322 | ||
8e19437d PM |
323 | case 'N': |
324 | if ( dn_mode && dn_mode != SLAP_TOOL_LDAPDN_NORMAL ) { | |
325 | usage( tool, progname ); | |
326 | } | |
327 | dn_mode = SLAP_TOOL_LDAPDN_NORMAL; | |
328 | break; | |
329 | ||
57ba4cac | 330 | case 'n': /* which config file db to index */ |
0fd295a3 PM |
331 | if ( lutil_atoi( &dbnum, optarg ) ) { |
332 | usage( tool, progname ); | |
333 | } | |
57ba4cac HC |
334 | break; |
335 | ||
83bb1c93 PM |
336 | case 'o': |
337 | if ( parse_slapacl() ) { | |
338 | usage( tool, progname ); | |
339 | } | |
340 | break; | |
341 | ||
8e19437d PM |
342 | case 'P': |
343 | if ( dn_mode && dn_mode != SLAP_TOOL_LDAPDN_PRETTY ) { | |
344 | usage( tool, progname ); | |
345 | } | |
346 | dn_mode = SLAP_TOOL_LDAPDN_PRETTY; | |
347 | break; | |
348 | ||
fe03b5a8 HC |
349 | case 'q': /* turn on quick */ |
350 | mode |= SLAP_TOOL_QUICK; | |
351 | break; | |
352 | ||
cc78fb52 PM |
353 | case 'R': |
354 | realm = optarg; | |
355 | break; | |
356 | ||
57ba4cac HC |
357 | case 's': /* dump subtree */ |
358 | subtree = strdup( optarg ); | |
359 | break; | |
360 | ||
361 | case 't': /* turn on truncate */ | |
362 | truncatemode++; | |
363 | mode |= SLAP_TRUNCATE_MODE; | |
364 | break; | |
365 | ||
3ea43689 PM |
366 | case 'U': |
367 | ber_str2bv( optarg, 0, 0, &authcID ); | |
368 | break; | |
369 | ||
57ba4cac HC |
370 | case 'u': /* dry run */ |
371 | dryrun++; | |
372 | break; | |
373 | ||
374 | case 'v': /* turn on verbose */ | |
375 | verbose++; | |
376 | break; | |
377 | ||
8d0f39bb | 378 | case 'w': /* write context csn at the end */ |
495c3156 | 379 | update_ctxcsn++; |
57ba4cac HC |
380 | break; |
381 | ||
3ea43689 PM |
382 | case 'X': |
383 | ber_str2bv( optarg, 0, 0, &authzID ); | |
384 | break; | |
385 | ||
57ba4cac HC |
386 | default: |
387 | usage( tool, progname ); | |
388 | break; | |
389 | } | |
390 | } | |
391 | ||
764aa5d9 PM |
392 | switch ( tool ) { |
393 | case SLAPADD: | |
394 | case SLAPCAT: | |
395 | case SLAPINDEX: | |
396 | if ( ( argc != optind ) || (dbnum >= 0 && base.bv_val != NULL ) ) { | |
397 | usage( tool, progname ); | |
398 | } | |
399 | ||
764aa5d9 | 400 | break; |
57ba4cac | 401 | |
764aa5d9 PM |
402 | case SLAPDN: |
403 | if ( argc == optind ) { | |
57ba4cac HC |
404 | usage( tool, progname ); |
405 | } | |
764aa5d9 PM |
406 | break; |
407 | ||
a54900be | 408 | case SLAPAUTH: |
3ea43689 PM |
409 | if ( argc == optind && BER_BVISNULL( &authcID ) ) { |
410 | usage( tool, progname ); | |
411 | } | |
412 | break; | |
413 | ||
764aa5d9 PM |
414 | case SLAPTEST: |
415 | if ( argc != optind ) { | |
416 | usage( tool, progname ); | |
417 | } | |
418 | break; | |
419 | ||
7b65d46b PM |
420 | case SLAPACL: |
421 | if ( !BER_BVISNULL( &authcDN ) && !BER_BVISNULL( &authcID ) ) { | |
422 | usage( tool, progname ); | |
423 | } | |
424 | if ( BER_BVISNULL( &base ) ) { | |
425 | usage( tool, progname ); | |
426 | } | |
427 | ber_dupbv( &baseDN, &base ); | |
428 | break; | |
429 | ||
764aa5d9 PM |
430 | default: |
431 | break; | |
57ba4cac HC |
432 | } |
433 | ||
c160e0d3 HC |
434 | ldap_syslog = 0; |
435 | ||
57ba4cac | 436 | if ( ldiffile == NULL ) { |
c225c4af HC |
437 | dummy.fp = tool == SLAPCAT ? stdout : stdin; |
438 | ldiffp = &dummy; | |
57ba4cac | 439 | |
c225c4af | 440 | } else if ((ldiffp = ldif_open( ldiffile, tool == SLAPCAT ? "w" : "r" )) |
57ba4cac HC |
441 | == NULL ) |
442 | { | |
443 | perror( ldiffile ); | |
444 | exit( EXIT_FAILURE ); | |
445 | } | |
446 | ||
447 | /* | |
448 | * initialize stuff and figure out which backend we're dealing with | |
449 | */ | |
450 | ||
8573640f | 451 | rc = slap_init( mode, progname ); |
57ba4cac | 452 | if ( rc != 0 ) { |
8573640f | 453 | fprintf( stderr, "%s: slap_init failed!\n", progname ); |
57ba4cac HC |
454 | exit( EXIT_FAILURE ); |
455 | } | |
456 | ||
bc4564ca | 457 | rc = read_config( conffile, confdir ); |
57ba4cac HC |
458 | |
459 | if ( rc != 0 ) { | |
53921b2c PM |
460 | fprintf( stderr, "%s: bad configuration %s!\n", |
461 | progname, confdir ? "directory" : "file" ); | |
57ba4cac HC |
462 | exit( EXIT_FAILURE ); |
463 | } | |
464 | ||
47e79480 | 465 | at_oc_cache = 1; |
75725a7a | 466 | |
764aa5d9 PM |
467 | switch ( tool ) { |
468 | case SLAPADD: | |
469 | case SLAPCAT: | |
470 | case SLAPINDEX: | |
471 | if ( !nbackends ) { | |
472 | fprintf( stderr, "No databases found " | |
473 | "in config file\n" ); | |
474 | exit( EXIT_FAILURE ); | |
475 | } | |
476 | break; | |
477 | ||
478 | default: | |
479 | break; | |
57ba4cac HC |
480 | } |
481 | ||
37e58a73 HC |
482 | if ( use_glue ) { |
483 | rc = glue_sub_attach(); | |
4a1eabf2 | 484 | |
37e58a73 HC |
485 | if ( rc != 0 ) { |
486 | fprintf( stderr, | |
487 | "%s: subordinate configuration error\n", progname ); | |
488 | exit( EXIT_FAILURE ); | |
489 | } | |
4a1eabf2 HC |
490 | } |
491 | ||
57ba4cac HC |
492 | rc = slap_schema_check(); |
493 | ||
494 | if ( rc != 0 ) { | |
495 | fprintf( stderr, "%s: slap_schema_prep failed!\n", progname ); | |
496 | exit( EXIT_FAILURE ); | |
497 | } | |
498 | ||
764aa5d9 PM |
499 | switch ( tool ) { |
500 | case SLAPDN: | |
501 | case SLAPTEST: | |
a54900be | 502 | case SLAPAUTH: |
3ea43689 PM |
503 | be = NULL; |
504 | goto startup; | |
505 | ||
764aa5d9 PM |
506 | default: |
507 | break; | |
508 | } | |
509 | ||
cdd94c7a KZ |
510 | if( filterstr ) { |
511 | filter = str2filter( filterstr ); | |
512 | ||
513 | if( filter == NULL ) { | |
514 | fprintf( stderr, "Invalid filter '%s'\n", filterstr ); | |
515 | exit( EXIT_FAILURE ); | |
516 | } | |
517 | } | |
518 | ||
57ba4cac HC |
519 | if( subtree ) { |
520 | struct berval val; | |
3ea43689 | 521 | ber_str2bv( subtree, 0, 0, &val ); |
57ba4cac HC |
522 | rc = dnNormalize( 0, NULL, NULL, &val, &sub_ndn, NULL ); |
523 | if( rc != LDAP_SUCCESS ) { | |
cdd94c7a | 524 | fprintf( stderr, "Invalid subtree DN '%s'\n", subtree ); |
57ba4cac HC |
525 | exit( EXIT_FAILURE ); |
526 | } | |
527 | ||
cdd94c7a | 528 | if ( BER_BVISNULL( &base ) && dbnum == -1 ) { |
57ba4cac | 529 | base = val; |
cdd94c7a | 530 | } else { |
57ba4cac | 531 | free( subtree ); |
cdd94c7a | 532 | } |
57ba4cac HC |
533 | } |
534 | ||
535 | if( base.bv_val != NULL ) { | |
536 | struct berval nbase; | |
537 | ||
538 | rc = dnNormalize( 0, NULL, NULL, &base, &nbase, NULL ); | |
539 | if( rc != LDAP_SUCCESS ) { | |
540 | fprintf( stderr, "%s: slap_init invalid suffix (\"%s\")\n", | |
541 | progname, base.bv_val ); | |
542 | exit( EXIT_FAILURE ); | |
543 | } | |
544 | ||
545 | be = select_backend( &nbase, 0, 0 ); | |
546 | ber_memfree( nbase.bv_val ); | |
547 | ||
854863f0 PM |
548 | switch ( tool ) { |
549 | case SLAPACL: | |
4d3a49b3 | 550 | goto startup; |
854863f0 PM |
551 | |
552 | default: | |
553 | break; | |
4d3a49b3 PM |
554 | } |
555 | ||
57ba4cac HC |
556 | if( be == NULL ) { |
557 | fprintf( stderr, "%s: slap_init no backend for \"%s\"\n", | |
558 | progname, base.bv_val ); | |
559 | exit( EXIT_FAILURE ); | |
560 | } | |
561 | /* If the named base is a glue master, operate on the | |
562 | * entire context | |
563 | */ | |
da69eca7 | 564 | if ( SLAP_GLUE_INSTANCE( be ) ) { |
57ba4cac HC |
565 | nosubordinates = 1; |
566 | } | |
567 | ||
568 | } else if ( dbnum == -1 ) { | |
6c214121 HC |
569 | /* no suffix and no dbnum specified, just default to |
570 | * the first available database | |
571 | */ | |
57ba4cac HC |
572 | if ( nbackends <= 0 ) { |
573 | fprintf( stderr, "No available databases\n" ); | |
574 | exit( EXIT_FAILURE ); | |
575 | } | |
0076b40c HC |
576 | LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { |
577 | dbnum++; | |
6c214121 HC |
578 | |
579 | /* db #0 is cn=config, don't select it as a default */ | |
0076b40c | 580 | if ( dbnum < 1 ) continue; |
57ba4cac | 581 | |
0076b40c HC |
582 | if ( SLAP_MONITOR(be)) |
583 | continue; | |
584 | ||
57ba4cac HC |
585 | /* If just doing the first by default and it is a |
586 | * glue subordinate, find the master. | |
587 | */ | |
0076b40c | 588 | if ( SLAP_GLUE_SUBORDINATE(be) ) { |
57ba4cac | 589 | nosubordinates = 1; |
0076b40c | 590 | continue; |
57ba4cac | 591 | } |
0076b40c | 592 | break; |
57ba4cac HC |
593 | } |
594 | ||
0076b40c | 595 | if ( !be ) { |
57ba4cac HC |
596 | fprintf( stderr, "Available database(s) " |
597 | "do not allow %s\n", progname ); | |
598 | exit( EXIT_FAILURE ); | |
599 | } | |
600 | ||
6c214121 | 601 | if ( nosubordinates == 0 && dbnum > 1 ) { |
57ba4cac | 602 | Debug( LDAP_DEBUG_ANY, |
cdd94c7a KZ |
603 | "The first database does not allow %s;" |
604 | " using the first available one (%d)\n", | |
6c214121 | 605 | progname, dbnum, 0 ); |
57ba4cac HC |
606 | } |
607 | ||
608 | } else if ( dbnum < 0 || dbnum > (nbackends-1) ) { | |
609 | fprintf( stderr, | |
610 | "Database number selected via -n is out of range\n" | |
6c214121 HC |
611 | "Must be in the range 0 to %d" |
612 | " (number of configured databases)\n", | |
613 | nbackends-1 ); | |
57ba4cac HC |
614 | exit( EXIT_FAILURE ); |
615 | ||
616 | } else { | |
0076b40c HC |
617 | LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { |
618 | if ( dbnum == 0 ) break; | |
619 | dbnum--; | |
620 | } | |
57ba4cac HC |
621 | } |
622 | ||
3ea43689 PM |
623 | startup:; |
624 | ||
57ba4cac HC |
625 | #ifdef CSRIMALLOC |
626 | mal_leaktrace(1); | |
627 | #endif | |
628 | ||
53a4d530 PM |
629 | if ( conffile != NULL ) { |
630 | ch_free( conffile ); | |
631 | } | |
632 | ||
633 | if ( ldiffile != NULL ) { | |
634 | ch_free( ldiffile ); | |
635 | } | |
636 | ||
884ebf91 HC |
637 | /* slapdn doesn't specify a backend to startup */ |
638 | if ( !dryrun && tool != SLAPDN && slap_startup( be ) ) { | |
d5238b91 PM |
639 | switch ( tool ) { |
640 | case SLAPTEST: | |
641 | fprintf( stderr, "slap_startup failed " | |
642 | "(test would succeed using " | |
643 | "the -u switch)\n" ); | |
644 | break; | |
645 | ||
646 | default: | |
647 | fprintf( stderr, "slap_startup failed\n" ); | |
648 | break; | |
649 | } | |
650 | ||
57ba4cac HC |
651 | exit( EXIT_FAILURE ); |
652 | } | |
653 | } | |
654 | ||
655 | void slap_tool_destroy( void ) | |
656 | { | |
4cba10c1 | 657 | if ( !dryrun ) { |
47415023 | 658 | slap_shutdown( be ); |
3958eb9e | 659 | slap_destroy(); |
47415023 | 660 | } |
57ba4cac HC |
661 | #ifdef SLAPD_MODULES |
662 | if ( slapMode == SLAP_SERVER_MODE ) { | |
663 | /* always false. just pulls in necessary symbol references. */ | |
664 | lutil_uuidstr(NULL, 0); | |
665 | } | |
666 | module_kill(); | |
667 | #endif | |
668 | schema_destroy(); | |
669 | #ifdef HAVE_TLS | |
670 | ldap_pvt_tls_destroy(); | |
671 | #endif | |
672 | config_destroy(); | |
673 | ||
674 | #ifdef CSRIMALLOC | |
675 | mal_dumpleaktrace( leakfile ); | |
676 | #endif | |
854863f0 PM |
677 | |
678 | if ( !BER_BVISNULL( &authcDN ) ) { | |
679 | ch_free( authcDN.bv_val ); | |
680 | } | |
57ba4cac | 681 | } |