]>
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 | * | |
4af9eb97 | 5 | * Copyright 1998-2009 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 | ||
dfc10014 | 50 | #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) |
cff53d48 PM |
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 */ | |
dfc10014 | 56 | #endif /* LDAP_DEBUG && LDAP_SYSLOG */ |
cff53d48 | 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]" |
c9f514d1 | 83 | " [-l ldiffile] [-a filter] [-s subtree]\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: | |
1ed9b5c3 | 91 | options = " [-c]\n\t[-g] [-n databasenumber | -b suffix] [attr ...] [-q] [-t]\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 | ||
dfc10014 | 168 | #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) |
cff53d48 PM |
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 */ | |
dfc10014 | 188 | #endif /* LDAP_DEBUG && LDAP_SYSLOG */ |
cff53d48 | 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; |
f3014a23 | 221 | int rc, i; |
57ba4cac HC |
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: | |
1ed9b5c3 | 244 | options = "b:cd:f:F:gj:l:n:o:qsS:uvw"; |
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: |
9a55fe70 | 258 | options = "d:f:F:o:Quv"; |
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: |
1ed9b5c3 | 268 | options = "b:cd:f:F:gn:o:qtv"; |
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 */ |
f3014a23 | 356 | if ( lutil_atoi( &dbnum, optarg ) || dbnum < 0 ) { |
0fd295a3 PM |
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 | ||
9a55fe70 PM |
374 | case 'Q': |
375 | quiet++; | |
376 | slap_debug = 0; | |
377 | break; | |
378 | ||
fe03b5a8 HC |
379 | case 'q': /* turn on quick */ |
380 | mode |= SLAP_TOOL_QUICK; | |
381 | break; | |
382 | ||
cc78fb52 PM |
383 | case 'R': |
384 | realm = optarg; | |
385 | break; | |
386 | ||
a6fd7fa9 | 387 | case 'S': |
aad65553 | 388 | if ( lutil_atou( &csnsid, optarg ) |
a6fd7fa9 PM |
389 | || csnsid > SLAP_SYNC_SID_MAX ) |
390 | { | |
391 | usage( tool, progname ); | |
392 | } | |
393 | break; | |
394 | ||
57ba4cac | 395 | case 's': /* dump subtree */ |
c51a71e5 LH |
396 | if ( tool == SLAPADD ) |
397 | mode |= SLAP_TOOL_NO_SCHEMA_CHECK; | |
398 | else if ( tool == SLAPCAT ) | |
8ae4cbe6 | 399 | subtree = ch_strdup( optarg ); |
57ba4cac HC |
400 | break; |
401 | ||
402 | case 't': /* turn on truncate */ | |
403 | truncatemode++; | |
404 | mode |= SLAP_TRUNCATE_MODE; | |
405 | break; | |
406 | ||
3ea43689 PM |
407 | case 'U': |
408 | ber_str2bv( optarg, 0, 0, &authcID ); | |
409 | break; | |
410 | ||
57ba4cac HC |
411 | case 'u': /* dry run */ |
412 | dryrun++; | |
413 | break; | |
414 | ||
415 | case 'v': /* turn on verbose */ | |
416 | verbose++; | |
417 | break; | |
418 | ||
8d0f39bb | 419 | case 'w': /* write context csn at the end */ |
495c3156 | 420 | update_ctxcsn++; |
57ba4cac HC |
421 | break; |
422 | ||
3ea43689 PM |
423 | case 'X': |
424 | ber_str2bv( optarg, 0, 0, &authzID ); | |
425 | break; | |
426 | ||
57ba4cac HC |
427 | default: |
428 | usage( tool, progname ); | |
429 | break; | |
430 | } | |
431 | } | |
432 | ||
dfc10014 | 433 | #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) |
cff53d48 PM |
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 ); | |
bbc719ca | 445 | #elif defined LOG_DEBUG |
cff53d48 PM |
446 | openlog( logName, OPENLOG_OPTIONS ); |
447 | #endif | |
448 | #ifdef HAVE_EBCDIC | |
449 | free( logName ); | |
450 | #endif | |
451 | } | |
dfc10014 | 452 | #endif /* LDAP_DEBUG && LDAP_SYSLOG */ |
cff53d48 | 453 | |
764aa5d9 PM |
454 | switch ( tool ) { |
455 | case SLAPADD: | |
456 | case SLAPCAT: | |
764aa5d9 PM |
457 | if ( ( argc != optind ) || (dbnum >= 0 && base.bv_val != NULL ) ) { |
458 | usage( tool, progname ); | |
459 | } | |
460 | ||
764aa5d9 | 461 | break; |
57ba4cac | 462 | |
5d3f3c24 HC |
463 | case SLAPINDEX: |
464 | if ( dbnum >= 0 && base.bv_val != NULL ) { | |
465 | usage( tool, progname ); | |
466 | } | |
467 | ||
468 | break; | |
469 | ||
764aa5d9 PM |
470 | case SLAPDN: |
471 | if ( argc == optind ) { | |
57ba4cac HC |
472 | usage( tool, progname ); |
473 | } | |
764aa5d9 PM |
474 | break; |
475 | ||
a54900be | 476 | case SLAPAUTH: |
3ea43689 PM |
477 | if ( argc == optind && BER_BVISNULL( &authcID ) ) { |
478 | usage( tool, progname ); | |
479 | } | |
480 | break; | |
481 | ||
764aa5d9 PM |
482 | case SLAPTEST: |
483 | if ( argc != optind ) { | |
484 | usage( tool, progname ); | |
485 | } | |
486 | break; | |
487 | ||
7b65d46b PM |
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 | ||
764aa5d9 PM |
498 | default: |
499 | break; | |
57ba4cac HC |
500 | } |
501 | ||
502 | if ( ldiffile == NULL ) { | |
c225c4af HC |
503 | dummy.fp = tool == SLAPCAT ? stdout : stdin; |
504 | ldiffp = &dummy; | |
57ba4cac | 505 | |
c225c4af | 506 | } else if ((ldiffp = ldif_open( ldiffile, tool == SLAPCAT ? "w" : "r" )) |
57ba4cac HC |
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 | ||
8573640f | 517 | rc = slap_init( mode, progname ); |
57ba4cac | 518 | if ( rc != 0 ) { |
8573640f | 519 | fprintf( stderr, "%s: slap_init failed!\n", progname ); |
57ba4cac HC |
520 | exit( EXIT_FAILURE ); |
521 | } | |
522 | ||
bc4564ca | 523 | rc = read_config( conffile, confdir ); |
57ba4cac HC |
524 | |
525 | if ( rc != 0 ) { | |
53921b2c PM |
526 | fprintf( stderr, "%s: bad configuration %s!\n", |
527 | progname, confdir ? "directory" : "file" ); | |
57ba4cac HC |
528 | exit( EXIT_FAILURE ); |
529 | } | |
530 | ||
0ef77423 HC |
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 | ||
dfc10014 | 539 | #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) |
cff53d48 PM |
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 | } | |
3f4e196b | 547 | #endif |
cff53d48 | 548 | |
47e79480 | 549 | at_oc_cache = 1; |
75725a7a | 550 | |
764aa5d9 PM |
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; | |
57ba4cac HC |
564 | } |
565 | ||
37e58a73 | 566 | if ( use_glue ) { |
1861632d | 567 | rc = glue_sub_attach( 0 ); |
4a1eabf2 | 568 | |
37e58a73 HC |
569 | if ( rc != 0 ) { |
570 | fprintf( stderr, | |
571 | "%s: subordinate configuration error\n", progname ); | |
572 | exit( EXIT_FAILURE ); | |
573 | } | |
4a1eabf2 HC |
574 | } |
575 | ||
57ba4cac HC |
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 | ||
764aa5d9 PM |
583 | switch ( tool ) { |
584 | case SLAPDN: | |
585 | case SLAPTEST: | |
a54900be | 586 | case SLAPAUTH: |
3ea43689 PM |
587 | be = NULL; |
588 | goto startup; | |
589 | ||
764aa5d9 PM |
590 | default: |
591 | break; | |
592 | } | |
593 | ||
cdd94c7a KZ |
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 | ||
57ba4cac HC |
603 | if( subtree ) { |
604 | struct berval val; | |
3ea43689 | 605 | ber_str2bv( subtree, 0, 0, &val ); |
57ba4cac HC |
606 | rc = dnNormalize( 0, NULL, NULL, &val, &sub_ndn, NULL ); |
607 | if( rc != LDAP_SUCCESS ) { | |
cdd94c7a | 608 | fprintf( stderr, "Invalid subtree DN '%s'\n", subtree ); |
57ba4cac HC |
609 | exit( EXIT_FAILURE ); |
610 | } | |
611 | ||
cdd94c7a | 612 | if ( BER_BVISNULL( &base ) && dbnum == -1 ) { |
57ba4cac | 613 | base = val; |
cdd94c7a | 614 | } else { |
57ba4cac | 615 | free( subtree ); |
cdd94c7a | 616 | } |
57ba4cac HC |
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 | ||
88cbe052 | 629 | be = select_backend( &nbase, 0 ); |
57ba4cac HC |
630 | ber_memfree( nbase.bv_val ); |
631 | ||
854863f0 PM |
632 | switch ( tool ) { |
633 | case SLAPACL: | |
4d3a49b3 | 634 | goto startup; |
854863f0 PM |
635 | |
636 | default: | |
637 | break; | |
4d3a49b3 PM |
638 | } |
639 | ||
57ba4cac HC |
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 | */ | |
da69eca7 | 648 | if ( SLAP_GLUE_INSTANCE( be ) ) { |
57ba4cac HC |
649 | nosubordinates = 1; |
650 | } | |
651 | ||
652 | } else if ( dbnum == -1 ) { | |
6c214121 HC |
653 | /* no suffix and no dbnum specified, just default to |
654 | * the first available database | |
655 | */ | |
57ba4cac HC |
656 | if ( nbackends <= 0 ) { |
657 | fprintf( stderr, "No available databases\n" ); | |
658 | exit( EXIT_FAILURE ); | |
659 | } | |
0076b40c HC |
660 | LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { |
661 | dbnum++; | |
6c214121 HC |
662 | |
663 | /* db #0 is cn=config, don't select it as a default */ | |
0076b40c | 664 | if ( dbnum < 1 ) continue; |
57ba4cac | 665 | |
0076b40c HC |
666 | if ( SLAP_MONITOR(be)) |
667 | continue; | |
668 | ||
57ba4cac HC |
669 | /* If just doing the first by default and it is a |
670 | * glue subordinate, find the master. | |
671 | */ | |
0076b40c | 672 | if ( SLAP_GLUE_SUBORDINATE(be) ) { |
57ba4cac | 673 | nosubordinates = 1; |
0076b40c | 674 | continue; |
57ba4cac | 675 | } |
0076b40c | 676 | break; |
57ba4cac HC |
677 | } |
678 | ||
0076b40c | 679 | if ( !be ) { |
57ba4cac HC |
680 | fprintf( stderr, "Available database(s) " |
681 | "do not allow %s\n", progname ); | |
682 | exit( EXIT_FAILURE ); | |
683 | } | |
684 | ||
6c214121 | 685 | if ( nosubordinates == 0 && dbnum > 1 ) { |
57ba4cac | 686 | Debug( LDAP_DEBUG_ANY, |
cdd94c7a KZ |
687 | "The first database does not allow %s;" |
688 | " using the first available one (%d)\n", | |
6c214121 | 689 | progname, dbnum, 0 ); |
57ba4cac HC |
690 | } |
691 | ||
f3014a23 | 692 | } else if ( dbnum >= nbackends ) { |
57ba4cac HC |
693 | fprintf( stderr, |
694 | "Database number selected via -n is out of range\n" | |
6c214121 | 695 | "Must be in the range 0 to %d" |
30066c81 PM |
696 | " (the number of configured databases)\n", |
697 | nbackends - 1 ); | |
57ba4cac HC |
698 | exit( EXIT_FAILURE ); |
699 | ||
700 | } else { | |
0076b40c HC |
701 | LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { |
702 | if ( dbnum == 0 ) break; | |
703 | dbnum--; | |
704 | } | |
57ba4cac HC |
705 | } |
706 | ||
3ea43689 | 707 | startup:; |
f3014a23 PM |
708 | if ( be ) { |
709 | BackendDB *bdtmp; | |
710 | ||
711 | dbnum = 0; | |
712 | LDAP_STAILQ_FOREACH( bdtmp, &backendDB, be_next ) { | |
713 | if ( bdtmp == be ) break; | |
714 | dbnum++; | |
715 | } | |
716 | } | |
3ea43689 | 717 | |
57ba4cac HC |
718 | #ifdef CSRIMALLOC |
719 | mal_leaktrace(1); | |
720 | #endif | |
721 | ||
53a4d530 PM |
722 | if ( conffile != NULL ) { |
723 | ch_free( conffile ); | |
724 | } | |
725 | ||
726 | if ( ldiffile != NULL ) { | |
727 | ch_free( ldiffile ); | |
728 | } | |
729 | ||
884ebf91 | 730 | /* slapdn doesn't specify a backend to startup */ |
a9844efa | 731 | if ( !dryrun && tool != SLAPDN ) { |
ce3c0245 PM |
732 | need_shutdown = 1; |
733 | ||
a9844efa HC |
734 | if ( slap_startup( be ) ) { |
735 | switch ( tool ) { | |
736 | case SLAPTEST: | |
737 | fprintf( stderr, "slap_startup failed " | |
738 | "(test would succeed using " | |
739 | "the -u switch)\n" ); | |
740 | break; | |
741 | ||
742 | default: | |
743 | fprintf( stderr, "slap_startup failed\n" ); | |
744 | break; | |
745 | } | |
d5238b91 | 746 | |
a9844efa | 747 | exit( EXIT_FAILURE ); |
d5238b91 | 748 | } |
57ba4cac HC |
749 | } |
750 | } | |
751 | ||
4e22081e | 752 | int slap_tool_destroy( void ) |
57ba4cac | 753 | { |
4e22081e | 754 | int rc = 0; |
4cba10c1 | 755 | if ( !dryrun ) { |
ce3c0245 | 756 | if ( need_shutdown ) { |
4e22081e HC |
757 | if ( slap_shutdown( be )) |
758 | rc = EXIT_FAILURE; | |
ce3c0245 | 759 | } |
4e22081e HC |
760 | if ( slap_destroy()) |
761 | rc = EXIT_FAILURE; | |
47415023 | 762 | } |
57ba4cac HC |
763 | #ifdef SLAPD_MODULES |
764 | if ( slapMode == SLAP_SERVER_MODE ) { | |
765 | /* always false. just pulls in necessary symbol references. */ | |
766 | lutil_uuidstr(NULL, 0); | |
767 | } | |
768 | module_kill(); | |
769 | #endif | |
770 | schema_destroy(); | |
771 | #ifdef HAVE_TLS | |
772 | ldap_pvt_tls_destroy(); | |
773 | #endif | |
774 | config_destroy(); | |
775 | ||
776 | #ifdef CSRIMALLOC | |
777 | mal_dumpleaktrace( leakfile ); | |
778 | #endif | |
854863f0 PM |
779 | |
780 | if ( !BER_BVISNULL( &authcDN ) ) { | |
781 | ch_free( authcDN.bv_val ); | |
782 | } | |
8931d68e PM |
783 | |
784 | if ( ldiffp && ldiffp != &dummy ) { | |
785 | ldif_close( ldiffp ); | |
786 | } | |
4e22081e | 787 | return rc; |
57ba4cac | 788 | } |