]>
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 | * | |
da6d9eb0 | 5 | * Copyright 1998-2007 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 | ||
cff53d48 PM |
50 | #ifdef LDAP_SYSLOG |
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_SYSLOG */ | |
57 | ||
57ba4cac HC |
58 | static void |
59 | usage( int tool, const char *progname ) | |
60 | { | |
61 | char *options = NULL; | |
62 | fprintf( stderr, | |
cff53d48 | 63 | "usage: %s [-v] [-d debuglevel] [-f configfile] [-F configdir] [-o <name>[=<value>]]", |
764aa5d9 | 64 | progname ); |
57ba4cac HC |
65 | |
66 | switch( tool ) { | |
0ea4070e | 67 | case SLAPACL: |
e9ab146a | 68 | options = "\n\t[-U authcID | -D authcDN] [-X authzID | -o authzDN=<DN>]" |
cff53d48 | 69 | "\n\t-b DN [-u] [attr[/access][:value]] [...]\n"; |
0ea4070e PM |
70 | break; |
71 | ||
57ba4cac | 72 | case SLAPADD: |
37e58a73 | 73 | options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]\n" |
59ca2d19 | 74 | "\t[-l ldiffile] [-j linenumber] [-q] [-u] [-s] [-w]\n"; |
57ba4cac HC |
75 | break; |
76 | ||
0ea4070e PM |
77 | case SLAPAUTH: |
78 | options = "\n\t[-U authcID] [-X authzID] [-R realm] [-M mech] ID [...]\n"; | |
79 | break; | |
80 | ||
57ba4cac | 81 | case SLAPCAT: |
37e58a73 | 82 | options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]" |
8d0f39bb | 83 | " [-l ldiffile] [-a filter]\n"; |
764aa5d9 PM |
84 | break; |
85 | ||
86 | case SLAPDN: | |
8e19437d | 87 | options = "\n\t[-N | -P] DN [...]\n"; |
57ba4cac HC |
88 | break; |
89 | ||
90 | case SLAPINDEX: | |
5d3f3c24 | 91 | options = " [-c]\n\t[-g] [-n databasenumber | -b suffix] [attr ...] [-q]\n"; |
3ea43689 | 92 | break; |
7b65d46b | 93 | |
0ea4070e PM |
94 | case SLAPTEST: |
95 | options = " [-u]\n"; | |
7b65d46b | 96 | break; |
57ba4cac HC |
97 | } |
98 | ||
764aa5d9 | 99 | if ( options != NULL ) { |
57ba4cac HC |
100 | fputs( options, stderr ); |
101 | } | |
102 | exit( EXIT_FAILURE ); | |
103 | } | |
104 | ||
83bb1c93 | 105 | static int |
cff53d48 | 106 | parse_slapopt( void ) |
83bb1c93 | 107 | { |
cff53d48 | 108 | size_t len = 0; |
83bb1c93 PM |
109 | char *p; |
110 | ||
111 | p = strchr( optarg, '=' ); | |
cff53d48 PM |
112 | if ( p != NULL ) { |
113 | len = p - optarg; | |
114 | p++; | |
83bb1c93 PM |
115 | } |
116 | ||
83bb1c93 PM |
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 ) { | |
0fd295a3 PM |
142 | if ( lutil_atou( &ssf, p ) ) { |
143 | Debug( LDAP_DEBUG_ANY, "unable to parse ssf=\"%s\".\n", p, 0, 0 ); | |
144 | return -1; | |
145 | } | |
83bb1c93 PM |
146 | |
147 | } else if ( strncasecmp( optarg, "transport_ssf", len ) == 0 ) { | |
0fd295a3 PM |
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 | } | |
83bb1c93 PM |
152 | |
153 | } else if ( strncasecmp( optarg, "tls_ssf", len ) == 0 ) { | |
0fd295a3 PM |
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 | } | |
83bb1c93 PM |
158 | |
159 | } else if ( strncasecmp( optarg, "sasl_ssf", len ) == 0 ) { | |
0fd295a3 PM |
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 | } | |
83bb1c93 | 164 | |
e9ab146a PM |
165 | } else if ( strncasecmp( optarg, "authzDN", len ) == 0 ) { |
166 | ber_str2bv( p, 0, 1, &authzDN ); | |
167 | ||
cff53d48 PM |
168 | #ifdef LDAP_SYSLOG |
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_SYSLOG */ | |
189 | ||
83bb1c93 PM |
190 | } else { |
191 | return -1; | |
192 | } | |
193 | ||
194 | return 0; | |
195 | } | |
57ba4cac HC |
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 | ||
ce3c0245 PM |
205 | static int need_shutdown; |
206 | ||
57ba4cac HC |
207 | void |
208 | slap_tool_init( | |
209 | const char* progname, | |
210 | int tool, | |
211 | int argc, char **argv ) | |
212 | { | |
213 | char *options; | |
cb686a5e HC |
214 | char *conffile = NULL; |
215 | char *confdir = NULL; | |
44725e73 | 216 | struct berval base = BER_BVNULL; |
cdd94c7a | 217 | char *filterstr = NULL; |
57ba4cac HC |
218 | char *subtree = NULL; |
219 | char *ldiffile = NULL; | |
0ef77423 | 220 | char **debug_unknowns = NULL; |
57ba4cac HC |
221 | int rc, i, dbnum; |
222 | int mode = SLAP_TOOL_MODE; | |
223 | int truncatemode = 0; | |
37e58a73 | 224 | int use_glue = 1; |
57ba4cac | 225 | |
6315ac9d PM |
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 */ | |
6459cbb7 | 229 | slap_debug = LDAP_DEBUG_NONE; |
6315ac9d | 230 | #endif |
cff53d48 | 231 | ldap_syslog = 0; |
6315ac9d | 232 | |
57ba4cac | 233 | #ifdef CSRIMALLOC |
42dadd57 | 234 | leakfilename = malloc( strlen( progname ) + STRLENOF( ".leak" ) + 1 ); |
57ba4cac HC |
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: | |
59ca2d19 | 244 | options = "b:cd:f:F:gj:l:n:o:qstuvw"; |
57ba4cac HC |
245 | break; |
246 | ||
57ba4cac | 247 | case SLAPCAT: |
cff53d48 | 248 | options = "a:b:cd:f:F:gl:n:o:s:v"; |
57ba4cac HC |
249 | mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; |
250 | break; | |
251 | ||
764aa5d9 | 252 | case SLAPDN: |
cff53d48 | 253 | options = "d:f:F:No:Pv"; |
854863f0 | 254 | mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; |
764aa5d9 PM |
255 | break; |
256 | ||
0ea4070e | 257 | case SLAPTEST: |
cff53d48 | 258 | options = "d:f:F:o:uv"; |
0ea4070e PM |
259 | mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; |
260 | break; | |
261 | ||
a54900be | 262 | case SLAPAUTH: |
cff53d48 | 263 | options = "d:f:F:M:o:R:U:vX:"; |
854863f0 | 264 | mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; |
3ea43689 PM |
265 | break; |
266 | ||
764aa5d9 | 267 | case SLAPINDEX: |
cff53d48 | 268 | options = "b:cd:f:F:gn:o:qv"; |
764aa5d9 PM |
269 | mode |= SLAP_TOOL_READMAIN; |
270 | break; | |
271 | ||
7b65d46b | 272 | case SLAPACL: |
e9ab146a | 273 | options = "b:D:d:f:F:o:uU:vX:"; |
854863f0 | 274 | mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; |
7b65d46b PM |
275 | break; |
276 | ||
57ba4cac | 277 | default: |
cdd94c7a | 278 | fprintf( stderr, "%s: unknown tool mode (%d)\n", progname, tool ); |
57ba4cac HC |
279 | exit( EXIT_FAILURE ); |
280 | } | |
281 | ||
282 | dbnum = -1; | |
283 | while ( (i = getopt( argc, argv, options )) != EOF ) { | |
284 | switch ( i ) { | |
cdd94c7a | 285 | case 'a': |
8ae4cbe6 | 286 | filterstr = ch_strdup( optarg ); |
cdd94c7a KZ |
287 | break; |
288 | ||
57ba4cac | 289 | case 'b': |
3ea43689 | 290 | ber_str2bv( optarg, 0, 1, &base ); |
57ba4cac HC |
291 | break; |
292 | ||
293 | case 'c': /* enable continue mode */ | |
294 | continuemode++; | |
295 | break; | |
296 | ||
2422e6aa PM |
297 | case 'd': { /* turn on debugging */ |
298 | int level = 0; | |
299 | ||
0ef77423 | 300 | if ( parse_debug_level( optarg, &level, &debug_unknowns ) ) { |
3517bdf2 PM |
301 | usage( tool, progname ); |
302 | } | |
e725c848 | 303 | #ifdef LDAP_DEBUG |
3517bdf2 PM |
304 | if ( level == 0 ) { |
305 | /* allow to reset log level */ | |
306 | slap_debug = 0; | |
6459cbb7 PM |
307 | |
308 | } else { | |
3517bdf2 | 309 | slap_debug |= level; |
e725c848 PM |
310 | } |
311 | #else | |
3517bdf2 | 312 | if ( level != 0 ) |
e725c848 PM |
313 | fputs( "must compile with LDAP_DEBUG for debugging\n", |
314 | stderr ); | |
315 | #endif | |
2422e6aa | 316 | } break; |
57ba4cac | 317 | |
7b65d46b | 318 | case 'D': |
854863f0 | 319 | ber_str2bv( optarg, 0, 1, &authcDN ); |
7b65d46b PM |
320 | break; |
321 | ||
57ba4cac | 322 | case 'f': /* specify a conf file */ |
8ae4cbe6 | 323 | conffile = ch_strdup( optarg ); |
57ba4cac HC |
324 | break; |
325 | ||
bc4564ca | 326 | case 'F': /* specify a conf dir */ |
8ae4cbe6 | 327 | confdir = ch_strdup( optarg ); |
bc4564ca HC |
328 | break; |
329 | ||
37e58a73 HC |
330 | case 'g': /* disable subordinate glue */ |
331 | use_glue = 0; | |
332 | break; | |
333 | ||
59ca2d19 HC |
334 | case 'j': /* jump to linenumber */ |
335 | if ( lutil_atoi( &jumpline, optarg ) ) { | |
336 | usage( tool, progname ); | |
337 | } | |
338 | break; | |
339 | ||
57ba4cac | 340 | case 'l': /* LDIF file */ |
8ae4cbe6 | 341 | ldiffile = ch_strdup( optarg ); |
57ba4cac HC |
342 | break; |
343 | ||
cc78fb52 PM |
344 | case 'M': |
345 | ber_str2bv( optarg, 0, 0, &mech ); | |
346 | break; | |
347 | ||
8e19437d PM |
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 | ||
57ba4cac | 355 | case 'n': /* which config file db to index */ |
0fd295a3 PM |
356 | if ( lutil_atoi( &dbnum, optarg ) ) { |
357 | usage( tool, progname ); | |
358 | } | |
57ba4cac HC |
359 | break; |
360 | ||
83bb1c93 | 361 | case 'o': |
cff53d48 | 362 | if ( parse_slapopt() ) { |
83bb1c93 PM |
363 | usage( tool, progname ); |
364 | } | |
365 | break; | |
366 | ||
8e19437d PM |
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 | ||
fe03b5a8 HC |
374 | case 'q': /* turn on quick */ |
375 | mode |= SLAP_TOOL_QUICK; | |
376 | break; | |
377 | ||
cc78fb52 PM |
378 | case 'R': |
379 | realm = optarg; | |
380 | break; | |
381 | ||
57ba4cac | 382 | case 's': /* dump subtree */ |
c51a71e5 LH |
383 | if ( tool == SLAPADD ) |
384 | mode |= SLAP_TOOL_NO_SCHEMA_CHECK; | |
385 | else if ( tool == SLAPCAT ) | |
8ae4cbe6 | 386 | subtree = ch_strdup( optarg ); |
57ba4cac HC |
387 | break; |
388 | ||
389 | case 't': /* turn on truncate */ | |
390 | truncatemode++; | |
391 | mode |= SLAP_TRUNCATE_MODE; | |
392 | break; | |
393 | ||
3ea43689 PM |
394 | case 'U': |
395 | ber_str2bv( optarg, 0, 0, &authcID ); | |
396 | break; | |
397 | ||
57ba4cac HC |
398 | case 'u': /* dry run */ |
399 | dryrun++; | |
400 | break; | |
401 | ||
402 | case 'v': /* turn on verbose */ | |
403 | verbose++; | |
404 | break; | |
405 | ||
8d0f39bb | 406 | case 'w': /* write context csn at the end */ |
495c3156 | 407 | update_ctxcsn++; |
57ba4cac HC |
408 | break; |
409 | ||
3ea43689 PM |
410 | case 'X': |
411 | ber_str2bv( optarg, 0, 0, &authzID ); | |
412 | break; | |
413 | ||
57ba4cac HC |
414 | default: |
415 | usage( tool, progname ); | |
416 | break; | |
417 | } | |
418 | } | |
419 | ||
cff53d48 PM |
420 | #ifdef LDAP_SYSLOG |
421 | if ( start_syslog ) { | |
422 | char *logName; | |
423 | #ifdef HAVE_EBCDIC | |
424 | logName = ch_strdup( progname ); | |
425 | __atoe( logName ); | |
426 | #else | |
427 | logName = (char *)progname; | |
428 | #endif | |
429 | ||
430 | #ifdef LOG_LOCAL4 | |
431 | openlog( logName, OPENLOG_OPTIONS, syslogUser ); | |
bbc719ca | 432 | #elif defined LOG_DEBUG |
cff53d48 PM |
433 | openlog( logName, OPENLOG_OPTIONS ); |
434 | #endif | |
435 | #ifdef HAVE_EBCDIC | |
436 | free( logName ); | |
437 | #endif | |
438 | } | |
439 | #endif /* LDAP_SYSLOG */ | |
440 | ||
764aa5d9 PM |
441 | switch ( tool ) { |
442 | case SLAPADD: | |
443 | case SLAPCAT: | |
764aa5d9 PM |
444 | if ( ( argc != optind ) || (dbnum >= 0 && base.bv_val != NULL ) ) { |
445 | usage( tool, progname ); | |
446 | } | |
447 | ||
764aa5d9 | 448 | break; |
57ba4cac | 449 | |
5d3f3c24 HC |
450 | case SLAPINDEX: |
451 | if ( dbnum >= 0 && base.bv_val != NULL ) { | |
452 | usage( tool, progname ); | |
453 | } | |
454 | ||
455 | break; | |
456 | ||
764aa5d9 PM |
457 | case SLAPDN: |
458 | if ( argc == optind ) { | |
57ba4cac HC |
459 | usage( tool, progname ); |
460 | } | |
764aa5d9 PM |
461 | break; |
462 | ||
a54900be | 463 | case SLAPAUTH: |
3ea43689 PM |
464 | if ( argc == optind && BER_BVISNULL( &authcID ) ) { |
465 | usage( tool, progname ); | |
466 | } | |
467 | break; | |
468 | ||
764aa5d9 PM |
469 | case SLAPTEST: |
470 | if ( argc != optind ) { | |
471 | usage( tool, progname ); | |
472 | } | |
473 | break; | |
474 | ||
7b65d46b PM |
475 | case SLAPACL: |
476 | if ( !BER_BVISNULL( &authcDN ) && !BER_BVISNULL( &authcID ) ) { | |
477 | usage( tool, progname ); | |
478 | } | |
479 | if ( BER_BVISNULL( &base ) ) { | |
480 | usage( tool, progname ); | |
481 | } | |
482 | ber_dupbv( &baseDN, &base ); | |
483 | break; | |
484 | ||
764aa5d9 PM |
485 | default: |
486 | break; | |
57ba4cac HC |
487 | } |
488 | ||
489 | if ( ldiffile == NULL ) { | |
c225c4af HC |
490 | dummy.fp = tool == SLAPCAT ? stdout : stdin; |
491 | ldiffp = &dummy; | |
57ba4cac | 492 | |
c225c4af | 493 | } else if ((ldiffp = ldif_open( ldiffile, tool == SLAPCAT ? "w" : "r" )) |
57ba4cac HC |
494 | == NULL ) |
495 | { | |
496 | perror( ldiffile ); | |
497 | exit( EXIT_FAILURE ); | |
498 | } | |
499 | ||
500 | /* | |
501 | * initialize stuff and figure out which backend we're dealing with | |
502 | */ | |
503 | ||
8573640f | 504 | rc = slap_init( mode, progname ); |
57ba4cac | 505 | if ( rc != 0 ) { |
8573640f | 506 | fprintf( stderr, "%s: slap_init failed!\n", progname ); |
57ba4cac HC |
507 | exit( EXIT_FAILURE ); |
508 | } | |
509 | ||
bc4564ca | 510 | rc = read_config( conffile, confdir ); |
57ba4cac HC |
511 | |
512 | if ( rc != 0 ) { | |
53921b2c PM |
513 | fprintf( stderr, "%s: bad configuration %s!\n", |
514 | progname, confdir ? "directory" : "file" ); | |
57ba4cac HC |
515 | exit( EXIT_FAILURE ); |
516 | } | |
517 | ||
0ef77423 HC |
518 | if ( debug_unknowns ) { |
519 | rc = parse_debug_unknowns( debug_unknowns, &slap_debug ); | |
520 | ldap_charray_free( debug_unknowns ); | |
521 | debug_unknowns = NULL; | |
522 | if ( rc ) | |
523 | exit( EXIT_FAILURE ); | |
524 | } | |
525 | ||
3f4e196b | 526 | #ifdef LDAP_SYSLOG |
cff53d48 PM |
527 | if ( syslog_unknowns ) { |
528 | rc = parse_debug_unknowns( syslog_unknowns, &ldap_syslog ); | |
529 | ldap_charray_free( syslog_unknowns ); | |
530 | syslog_unknowns = NULL; | |
531 | if ( rc ) | |
532 | exit( EXIT_FAILURE ); | |
533 | } | |
3f4e196b | 534 | #endif |
cff53d48 | 535 | |
47e79480 | 536 | at_oc_cache = 1; |
75725a7a | 537 | |
764aa5d9 PM |
538 | switch ( tool ) { |
539 | case SLAPADD: | |
540 | case SLAPCAT: | |
541 | case SLAPINDEX: | |
542 | if ( !nbackends ) { | |
543 | fprintf( stderr, "No databases found " | |
544 | "in config file\n" ); | |
545 | exit( EXIT_FAILURE ); | |
546 | } | |
547 | break; | |
548 | ||
549 | default: | |
550 | break; | |
57ba4cac HC |
551 | } |
552 | ||
37e58a73 HC |
553 | if ( use_glue ) { |
554 | rc = glue_sub_attach(); | |
4a1eabf2 | 555 | |
37e58a73 HC |
556 | if ( rc != 0 ) { |
557 | fprintf( stderr, | |
558 | "%s: subordinate configuration error\n", progname ); | |
559 | exit( EXIT_FAILURE ); | |
560 | } | |
4a1eabf2 HC |
561 | } |
562 | ||
57ba4cac HC |
563 | rc = slap_schema_check(); |
564 | ||
565 | if ( rc != 0 ) { | |
566 | fprintf( stderr, "%s: slap_schema_prep failed!\n", progname ); | |
567 | exit( EXIT_FAILURE ); | |
568 | } | |
569 | ||
764aa5d9 PM |
570 | switch ( tool ) { |
571 | case SLAPDN: | |
572 | case SLAPTEST: | |
a54900be | 573 | case SLAPAUTH: |
3ea43689 PM |
574 | be = NULL; |
575 | goto startup; | |
576 | ||
764aa5d9 PM |
577 | default: |
578 | break; | |
579 | } | |
580 | ||
cdd94c7a KZ |
581 | if( filterstr ) { |
582 | filter = str2filter( filterstr ); | |
583 | ||
584 | if( filter == NULL ) { | |
585 | fprintf( stderr, "Invalid filter '%s'\n", filterstr ); | |
586 | exit( EXIT_FAILURE ); | |
587 | } | |
588 | } | |
589 | ||
57ba4cac HC |
590 | if( subtree ) { |
591 | struct berval val; | |
3ea43689 | 592 | ber_str2bv( subtree, 0, 0, &val ); |
57ba4cac HC |
593 | rc = dnNormalize( 0, NULL, NULL, &val, &sub_ndn, NULL ); |
594 | if( rc != LDAP_SUCCESS ) { | |
cdd94c7a | 595 | fprintf( stderr, "Invalid subtree DN '%s'\n", subtree ); |
57ba4cac HC |
596 | exit( EXIT_FAILURE ); |
597 | } | |
598 | ||
cdd94c7a | 599 | if ( BER_BVISNULL( &base ) && dbnum == -1 ) { |
57ba4cac | 600 | base = val; |
cdd94c7a | 601 | } else { |
57ba4cac | 602 | free( subtree ); |
cdd94c7a | 603 | } |
57ba4cac HC |
604 | } |
605 | ||
606 | if( base.bv_val != NULL ) { | |
607 | struct berval nbase; | |
608 | ||
609 | rc = dnNormalize( 0, NULL, NULL, &base, &nbase, NULL ); | |
610 | if( rc != LDAP_SUCCESS ) { | |
611 | fprintf( stderr, "%s: slap_init invalid suffix (\"%s\")\n", | |
612 | progname, base.bv_val ); | |
613 | exit( EXIT_FAILURE ); | |
614 | } | |
615 | ||
616 | be = select_backend( &nbase, 0, 0 ); | |
617 | ber_memfree( nbase.bv_val ); | |
618 | ||
854863f0 PM |
619 | switch ( tool ) { |
620 | case SLAPACL: | |
4d3a49b3 | 621 | goto startup; |
854863f0 PM |
622 | |
623 | default: | |
624 | break; | |
4d3a49b3 PM |
625 | } |
626 | ||
57ba4cac HC |
627 | if( be == NULL ) { |
628 | fprintf( stderr, "%s: slap_init no backend for \"%s\"\n", | |
629 | progname, base.bv_val ); | |
630 | exit( EXIT_FAILURE ); | |
631 | } | |
632 | /* If the named base is a glue master, operate on the | |
633 | * entire context | |
634 | */ | |
da69eca7 | 635 | if ( SLAP_GLUE_INSTANCE( be ) ) { |
57ba4cac HC |
636 | nosubordinates = 1; |
637 | } | |
638 | ||
639 | } else if ( dbnum == -1 ) { | |
6c214121 HC |
640 | /* no suffix and no dbnum specified, just default to |
641 | * the first available database | |
642 | */ | |
57ba4cac HC |
643 | if ( nbackends <= 0 ) { |
644 | fprintf( stderr, "No available databases\n" ); | |
645 | exit( EXIT_FAILURE ); | |
646 | } | |
0076b40c HC |
647 | LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { |
648 | dbnum++; | |
6c214121 HC |
649 | |
650 | /* db #0 is cn=config, don't select it as a default */ | |
0076b40c | 651 | if ( dbnum < 1 ) continue; |
57ba4cac | 652 | |
0076b40c HC |
653 | if ( SLAP_MONITOR(be)) |
654 | continue; | |
655 | ||
57ba4cac HC |
656 | /* If just doing the first by default and it is a |
657 | * glue subordinate, find the master. | |
658 | */ | |
0076b40c | 659 | if ( SLAP_GLUE_SUBORDINATE(be) ) { |
57ba4cac | 660 | nosubordinates = 1; |
0076b40c | 661 | continue; |
57ba4cac | 662 | } |
0076b40c | 663 | break; |
57ba4cac HC |
664 | } |
665 | ||
0076b40c | 666 | if ( !be ) { |
57ba4cac HC |
667 | fprintf( stderr, "Available database(s) " |
668 | "do not allow %s\n", progname ); | |
669 | exit( EXIT_FAILURE ); | |
670 | } | |
671 | ||
6c214121 | 672 | if ( nosubordinates == 0 && dbnum > 1 ) { |
57ba4cac | 673 | Debug( LDAP_DEBUG_ANY, |
cdd94c7a KZ |
674 | "The first database does not allow %s;" |
675 | " using the first available one (%d)\n", | |
6c214121 | 676 | progname, dbnum, 0 ); |
57ba4cac HC |
677 | } |
678 | ||
679 | } else if ( dbnum < 0 || dbnum > (nbackends-1) ) { | |
680 | fprintf( stderr, | |
681 | "Database number selected via -n is out of range\n" | |
6c214121 HC |
682 | "Must be in the range 0 to %d" |
683 | " (number of configured databases)\n", | |
684 | nbackends-1 ); | |
57ba4cac HC |
685 | exit( EXIT_FAILURE ); |
686 | ||
687 | } else { | |
0076b40c HC |
688 | LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { |
689 | if ( dbnum == 0 ) break; | |
690 | dbnum--; | |
691 | } | |
57ba4cac HC |
692 | } |
693 | ||
3ea43689 PM |
694 | startup:; |
695 | ||
57ba4cac HC |
696 | #ifdef CSRIMALLOC |
697 | mal_leaktrace(1); | |
698 | #endif | |
699 | ||
53a4d530 PM |
700 | if ( conffile != NULL ) { |
701 | ch_free( conffile ); | |
702 | } | |
703 | ||
704 | if ( ldiffile != NULL ) { | |
705 | ch_free( ldiffile ); | |
706 | } | |
707 | ||
884ebf91 | 708 | /* slapdn doesn't specify a backend to startup */ |
a9844efa | 709 | if ( !dryrun && tool != SLAPDN ) { |
ce3c0245 PM |
710 | need_shutdown = 1; |
711 | ||
a9844efa HC |
712 | if ( slap_startup( be ) ) { |
713 | switch ( tool ) { | |
714 | case SLAPTEST: | |
715 | fprintf( stderr, "slap_startup failed " | |
716 | "(test would succeed using " | |
717 | "the -u switch)\n" ); | |
718 | break; | |
719 | ||
720 | default: | |
721 | fprintf( stderr, "slap_startup failed\n" ); | |
722 | break; | |
723 | } | |
d5238b91 | 724 | |
a9844efa | 725 | exit( EXIT_FAILURE ); |
d5238b91 | 726 | } |
57ba4cac HC |
727 | } |
728 | } | |
729 | ||
730 | void slap_tool_destroy( void ) | |
731 | { | |
4cba10c1 | 732 | if ( !dryrun ) { |
ce3c0245 PM |
733 | if ( need_shutdown ) { |
734 | slap_shutdown( be ); | |
735 | } | |
3958eb9e | 736 | slap_destroy(); |
47415023 | 737 | } |
57ba4cac HC |
738 | #ifdef SLAPD_MODULES |
739 | if ( slapMode == SLAP_SERVER_MODE ) { | |
740 | /* always false. just pulls in necessary symbol references. */ | |
741 | lutil_uuidstr(NULL, 0); | |
742 | } | |
743 | module_kill(); | |
744 | #endif | |
745 | schema_destroy(); | |
746 | #ifdef HAVE_TLS | |
747 | ldap_pvt_tls_destroy(); | |
748 | #endif | |
749 | config_destroy(); | |
750 | ||
751 | #ifdef CSRIMALLOC | |
752 | mal_dumpleaktrace( leakfile ); | |
753 | #endif | |
854863f0 PM |
754 | |
755 | if ( !BER_BVISNULL( &authcDN ) ) { | |
756 | ch_free( authcDN.bv_val ); | |
757 | } | |
57ba4cac | 758 | } |