backend.c 22.5 KB
Newer Older
1
/* $OpenLDAP$ */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
2
/*
Kurt Zeilenga's avatar
Kurt Zeilenga committed
3
 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
4
5
 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
6
7
8
/* backend.c - routines for dealing with back-end databases */


Kurt Zeilenga's avatar
Kurt Zeilenga committed
9
10
#include "portable.h"

Kurt Zeilenga's avatar
Kurt Zeilenga committed
11
#include <stdio.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
12
13
14
15

#include <ac/string.h>
#include <ac/socket.h>

Kurt Zeilenga's avatar
Kurt Zeilenga committed
16
#include <sys/stat.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
17

Kurt Zeilenga's avatar
Kurt Zeilenga committed
18
#include "slap.h"
19
#include "lutil.h"
Kurt Zeilenga's avatar
Kurt Zeilenga committed
20

Howard Chu's avatar
Howard Chu committed
21
22
23
24
25
26
27
28
29
/*
 * If a module is configured as dynamic, its header should not
 * get included into slapd. While this is a general rule and does
 * not have much of an effect in UNIX, this rule should be adhered
 * to for Windows, where dynamic object code should not be implicitly
 * imported into slapd without appropriate __declspec(dllimport) directives.
 */

#if defined(SLAPD_BDB) && !defined(SLAPD_BDB_DYNAMIC)
Kurt Zeilenga's avatar
Kurt Zeilenga committed
30
31
#include "back-bdb/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
32
#if defined(SLAPD_DNSSRV) && !defined(SLAPD_DNSSRV_DYNAMIC)
33
34
#include "back-dnssrv/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
35
#if defined(SLAPD_LDAP) && !defined(SLAPD_LDAP_DYNAMIC)
36
37
#include "back-ldap/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
38
#if defined(SLAPD_LDBM) && !defined(SLAPD_LDBM_DYNAMIC)
39
40
#include "back-ldbm/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
41
#if defined(SLAPD_META) && !defined(SLAPD_META_DYNAMIC)
Pierangelo Masarati's avatar
Pierangelo Masarati committed
42
43
#include "back-meta/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
44
#if defined(SLAPD_MONITOR) && !defined(SLAPD_MONITOR_DYNAMIC)
45
46
#include "back-monitor/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
47
#if defined(SLAPD_PASSWD) && !defined(SLAPD_PASSWD_DYNAMIC)
48
49
#include "back-passwd/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
50
#if defined(SLAPD_PERL) && !defined(SLAPD_PERL_DYNAMIC)
51
52
#include "back-perl/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
53
#if defined(SLAPD_SHELL) && !defined(SLAPD_SHELL_DYNAMIC)
54
55
#include "back-shell/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
56
#if defined(SLAPD_TCL) && !defined(SLAPD_TCL_DYNAMIC)
57
58
#include "back-tcl/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
59
#if defined(SLAPD_SQL) && !defined(SLAPD_SQL_DYNAMIC)
60
61
#include "back-sql/external.h"
#endif
Howard Chu's avatar
Howard Chu committed
62
#if defined(SLAPD_PRIVATE) && !defined(SLAPD_PRIVATE_DYNAMIC)
63
64
#include "private/external.h"
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
65

66
static BackendInfo binfo[] = {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
67
#if defined(SLAPD_BDB) && !defined(SLAPD_BDB_DYNAMIC)
Kurt Zeilenga's avatar
Kurt Zeilenga committed
68
	{"bdb",	bdb_initialize},
Kurt Zeilenga's avatar
Kurt Zeilenga committed
69
#endif
70
71
72
#if defined(SLAPD_DNSSRV) && !defined(SLAPD_DNSSRV_DYNAMIC)
	{"dnssrv",	dnssrv_back_initialize},
#endif
73
#if defined(SLAPD_LDAP) && !defined(SLAPD_LDAP_DYNAMIC)
74
75
	{"ldap",	ldap_back_initialize},
#endif
76
#if defined(SLAPD_LDBM) && !defined(SLAPD_LDBM_DYNAMIC)
77
78
	{"ldbm",	ldbm_back_initialize},
#endif
Pierangelo Masarati's avatar
Pierangelo Masarati committed
79
80
81
#if defined(SLAPD_META) && !defined(SLAPD_META_DYNAMIC)
	{"meta",	meta_back_initialize},
#endif
82
83
84
#if defined(SLAPD_MONITOR) && !defined(SLAPD_MONITOR_DYNAMIC)
	{"monitor",	monitor_back_initialize},
#endif
85
#if defined(SLAPD_PASSWD) && !defined(SLAPD_PASSWD_DYNAMIC)
86
87
	{"passwd",	passwd_back_initialize},
#endif
88
#if defined(SLAPD_PERL) && !defined(SLAPD_PERL_DYNAMIC)
89
90
	{"perl",	perl_back_initialize},
#endif
91
#if defined(SLAPD_SHELL) && !defined(SLAPD_SHELL_DYNAMIC)
92
	{"shell",	shell_back_initialize},
93
#endif
94
#if defined(SLAPD_TCL) && !defined(SLAPD_TCL_DYNAMIC)
95
	{"tcl",		tcl_back_initialize},
Mark Valence's avatar
Mark Valence committed
96
#endif
97
98
#if defined(SLAPD_SQL) && !defined(SLAPD_SQL_DYNAMIC)
	{"sql",		sql_back_initialize},
99
100
101
102
#endif
	/* for any private backend */
#if defined(SLAPD_PRIVATE) && !defined(SLAPD_PRIVATE_DYNAMIC)
	{"private",	private_back_initialize},
103
104
105
#endif
	{NULL}
};
Kurt Zeilenga's avatar
Kurt Zeilenga committed
106

107
108
int			nBackendInfo = 0;
BackendInfo	*backendInfo = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
109

110
111
112
113
int			nBackendDB = 0; 
BackendDB	*backendDB = NULL;

int backend_init(void)
Kurt Zeilenga's avatar
Kurt Zeilenga committed
114
{
115
	int rc = -1;
116
117
118

	if((nBackendInfo != 0) || (backendInfo != NULL)) {
		/* already initialized */
119
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
120
121
		LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
			   "backend_init:  backend already initialized\n" ));
122
#else
123
124
		Debug( LDAP_DEBUG_ANY,
			"backend_init: already initialized.\n", 0, 0, 0 );
125
#endif
126
		return -1;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
127
128
	}

129
	for( ;
130
		binfo[nBackendInfo].bi_type != NULL;
131
132
		nBackendInfo++ )
	{
133
		rc = binfo[nBackendInfo].bi_init( &binfo[nBackendInfo] );
134
135

		if(rc != 0) {
136
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
137
			LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
138
139
				"backend_init:  initialized for type \"%s\"\n",
				binfo[nBackendInfo].bi_type ));
140
#else
141
142
			Debug( LDAP_DEBUG_ANY,
				"backend_init: initialized for type \"%s\"\n",
143
				binfo[nBackendInfo].bi_type, 0, 0 );
144
#endif
145
146
147
148
149
150
151
152
153
154
155
156
157
			/* destroy those we've already inited */
			for( nBackendInfo--;
				nBackendInfo >= 0 ;
				nBackendInfo-- )
			{ 
				if ( binfo[nBackendInfo].bi_destroy ) {
					binfo[nBackendInfo].bi_destroy(
						&binfo[nBackendInfo] );
				}
			}
			return rc;
		}
	}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
158

159
160
161
	if ( nBackendInfo > 0) {
		backendInfo = binfo;
		return 0;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
162
163
	}

164
165
166
#ifdef SLAPD_MODULES	
	return 0;
#else
167
168

#ifdef NEW_LOGGING
169
170
	LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
		"backend_init: failed\n" ));
171
#else
172
	Debug( LDAP_DEBUG_ANY,
173
174
		"backend_init: failed\n",
		0, 0, 0 );
175
#endif
176

177
	return rc;
178
179
180
181
182
183
184
185
#endif /* SLAPD_MODULES */
}

int backend_add(BackendInfo *aBackendInfo)
{
   int rc = 0;

   if ((rc = aBackendInfo->bi_init(aBackendInfo)) != 0) {
186
187
188
189
190
#ifdef NEW_LOGGING
       LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
                  "backend_add:  initialization for type \"%s\" failed\n",
                  aBackendInfo->bi_type ));
#else
191
192
193
      Debug( LDAP_DEBUG_ANY,
	     "backend_add: initialization for type \"%s\" failed\n",
	     aBackendInfo->bi_type, 0, 0 );
194
#endif
195
196
197
198
199
200
201
202
203
204
      return rc;
   }

   /* now add the backend type to the Backend Info List */
   {
      BackendInfo *newBackendInfo = 0;

      /* if backendInfo == binfo no deallocation of old backendInfo */
      if (backendInfo == binfo) {
	 newBackendInfo = ch_calloc(nBackendInfo + 1, sizeof(BackendInfo));
Kurt Zeilenga's avatar
Kurt Zeilenga committed
205
	 AC_MEMCPY(newBackendInfo, backendInfo, sizeof(BackendInfo) * 
206
207
208
209
210
		nBackendInfo);
      } else {
	 newBackendInfo = ch_realloc(backendInfo, sizeof(BackendInfo) * 
				     (nBackendInfo + 1));
      }
Kurt Zeilenga's avatar
Kurt Zeilenga committed
211
      AC_MEMCPY(&newBackendInfo[nBackendInfo], aBackendInfo, 
212
213
214
215
216
217
	     sizeof(BackendInfo));
      backendInfo = newBackendInfo;
      nBackendInfo++;

      return 0;
   }	    
218
219
}

220
int backend_startup(Backend *be)
221
222
223
224
225
226
{
	int i;
	int rc = 0;

	if( ! ( nBackendDB > 0 ) ) {
		/* no databases */
227
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
228
229
230
		LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
			   "backend_startup: %d databases to startup. \n",
			   nBackendDB ));
231
#else
232
233
234
		Debug( LDAP_DEBUG_ANY,
			"backend_startup: %d databases to startup.\n",
			nBackendDB, 0, 0 );
235
#endif
236
		return 1;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
237
238
	}

239
	if(be != NULL) {
240
		/* startup a specific backend database */
241
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
242
243
		LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
			   "backend_startup:  starting \"%s\"\n",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
244
			   be->be_suffix[0]->bv_val ));
245
#else
246
		Debug( LDAP_DEBUG_TRACE,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
247
			"backend_startup: starting \"%s\"\n",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
248
			be->be_suffix[0]->bv_val, 0, 0 );
249
#endif
250

251
252
		if ( be->bd_info->bi_open ) {
			rc = be->bd_info->bi_open( be->bd_info );
253
254
255
		}

		if(rc != 0) {
256
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
257
258
			LDAP_LOG(( "backend", LDAP_LEVEL_CRIT,
				   "backend_startup: bi_open failed!\n" ));
259
#else
260
			Debug( LDAP_DEBUG_ANY,
261
262
				"backend_startup: bi_open failed!\n",
				0, 0, 0 );
263
264
#endif

265
266
267
			return rc;
		}

268
269
		if ( be->bd_info->bi_db_open ) {
			rc = be->bd_info->bi_db_open( be );
270
271
272
		}

		if(rc != 0) {
273
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
274
			LDAP_LOG(( "backend", LDAP_LEVEL_CRIT,
275
				"backend_startup: bi_db_open failed! (%d)\n", rc ));
276
#else
277
			Debug( LDAP_DEBUG_ANY,
278
279
				"backend_startup: bi_db_open failed! (%d)\n",
				rc, 0, 0 );
280
#endif
281
282
283
284
			return rc;
		}

		return rc;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
285
286
	}

287
288
	/* open each backend type */
	for( i = 0; i < nBackendInfo; i++ ) {
289
290
291
292
293
		if( backendInfo[i].bi_nDB == 0) {
			/* no database of this type, don't open */
			continue;
		}

294
295
296
297
		if( backendInfo[i].bi_open ) {
			rc = backendInfo[i].bi_open(
				&backendInfo[i] );
		}
298

299
		if(rc != 0) {
300
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
301
302
			LDAP_LOG(( "backend", LDAP_LEVEL_CRIT,
				   "backend_startup: bi_open %d failed!\n", i ));
303
#else
304
			Debug( LDAP_DEBUG_ANY,
305
306
				"backend_startup: bi_open %d failed!\n",
				i, 0, 0 );
307
#endif
308
309
			return rc;
		}
310
311
	}

312
313
	/* open each backend database */
	for( i = 0; i < nBackendDB; i++ ) {
314
315
316
		/* append global access controls */
		acl_append( &backendDB[i].be_acl, global_acl );

317
318
319
320
321
322
		if ( backendDB[i].bd_info->bi_db_open ) {
			rc = backendDB[i].bd_info->bi_db_open(
				&backendDB[i] );
		}

		if(rc != 0) {
323
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
324
			LDAP_LOG(( "backend", LDAP_LEVEL_CRIT,
325
326
				"backend_startup: bi_db_open(%d) failed! (%d)\n",
				i, rc ));
327
#else
328
			Debug( LDAP_DEBUG_ANY,
329
330
				"backend_startup: bi_db_open(%d) failed! (%d)\n",
				i, rc, 0 );
331
#endif
332
333
334
335
336
337
338
			return rc;
		}
	}

	return rc;
}

339
int backend_num( Backend *be )
340
341
342
{
	int i;

343
344
345
346
347
348
349
	if( be == NULL ) return -1;

	for( i = 0; i < nBackendDB; i++ ) {
		if( be == &backendDB[i] ) return i;
	}
	return -1;
}
350

351
352
353
354
int backend_shutdown( Backend *be )
{
	int i;
	int rc = 0;
355

356
357
	if( be != NULL ) {
		/* shutdown a specific backend database */
358

359
		if ( be->bd_info->bi_nDB == 0 ) {
360
361
362
363
			/* no database of this type, we never opened it */
			return 0;
		}

364
365
		if ( be->bd_info->bi_db_close ) {
			be->bd_info->bi_db_close( be );
366
367
		}

368
369
		if( be->bd_info->bi_close ) {
			be->bd_info->bi_close( be->bd_info );
370
371
372
373
374
375
376
377
378
379
380
		}

		return 0;
	}

	/* close each backend database */
	for( i = 0; i < nBackendDB; i++ ) {
		if ( backendDB[i].bd_info->bi_db_close ) {
			backendDB[i].bd_info->bi_db_close(
				&backendDB[i] );
		}
381
382

		if(rc != 0) {
383
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
384
385
386
			LDAP_LOG(( "backend", LDAP_LEVEL_NOTICE,
				   "backend_shutdown: bi_close %s failed!\n",
				   backendDB[i].be_type ));
387
#else
388
389
			Debug( LDAP_DEBUG_ANY,
				"backend_close: bi_close %s failed!\n",
390
				backendDB[i].be_type, 0, 0 );
391
#endif
392
		}
393
394
395
396
	}

	/* close each backend type */
	for( i = 0; i < nBackendInfo; i++ ) {
397
398
399
400
401
		if( backendInfo[i].bi_nDB == 0 ) {
			/* no database of this type */
			continue;
		}

402
403
404
405
406
407
408
409
410
411
412
413
		if( backendInfo[i].bi_close ) {
			backendInfo[i].bi_close(
				&backendInfo[i] );
		}
	}

	return 0;
}

int backend_destroy(void)
{
	int i;
Howard Chu's avatar
Howard Chu committed
414
	BackendDB *bd;
415
416

	/* destroy each backend database */
Howard Chu's avatar
Howard Chu committed
417
418
419
	for( i = 0, bd = backendDB; i < nBackendDB; i++, bd++ ) {
		if ( bd->bd_info->bi_db_destroy ) {
			bd->bd_info->bi_db_destroy( bd );
420
		}
Howard Chu's avatar
Howard Chu committed
421
422
423
424
425
426
		ber_bvecfree( bd->be_suffix );
		ber_bvecfree( bd->be_nsuffix );
		if ( bd->be_rootdn.bv_val ) free( bd->be_rootdn.bv_val );
		if ( bd->be_rootndn.bv_val ) free( bd->be_rootndn.bv_val );
		if ( bd->be_rootpw.bv_val ) free( bd->be_rootpw.bv_val );
		acl_destroy( bd->be_acl, global_acl );
427
	}
428
	free( backendDB );
429

430
431
	/* destroy each backend type */
	for( i = 0; i < nBackendInfo; i++ ) {
432
433
		if( backendInfo[i].bi_destroy ) {
			backendInfo[i].bi_destroy(
434
435
436
437
				&backendInfo[i] );
		}
	}

438
439
440
441
442
443
444
445
446
#ifdef SLAPD_MODULES
	if (backendInfo != binfo) {
	   free(backendInfo);
	}
#endif /* SLAPD_MODULES */

	nBackendInfo = 0;
	backendInfo = NULL;

447
448
449
	return 0;
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
450
BackendInfo* backend_info(const char *type)
451
452
{
	int i;
453

454
455
456
457
458
	/* search for the backend type */
	for( i = 0; i < nBackendInfo; i++ ) {
		if( strcasecmp(backendInfo[i].bi_type, type) == 0 ) {
			return &backendInfo[i];
		}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
459
460
	}

461
462
463
464
465
466
	return NULL;
}


BackendDB *
backend_db_init(
Kurt Zeilenga's avatar
Kurt Zeilenga committed
467
    const char	*type
468
469
470
471
472
473
474
)
{
	Backend	*be;
	BackendInfo *bi = backend_info(type);
	int	rc = 0;

	if( bi == NULL ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
475
		fprintf( stderr, "Unrecognized database type (%s)\n", type );
476
477
478
479
480
481
482
483
484
485
486
487
		return NULL;
	}

	backendDB = (BackendDB *) ch_realloc(
			(char *) backendDB,
		    (nBackendDB + 1) * sizeof(Backend) );

	memset( &backendDB[nbackends], '\0', sizeof(Backend) );

	be = &backends[nbackends++];

	be->bd_info = bi;
488
	be->be_def_limit = deflimit;
489
	be->be_dfltaccess = global_default_access;
490

491
492
493
	be->be_restrictops = global_restrictops;
	be->be_requires = global_requires;

Kurt Zeilenga's avatar
Kurt Zeilenga committed
494
495
496
 	/* assign a default depth limit for alias deref */
	be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; 

497
498
499
500
501
502
503
504
	if(bi->bi_db_init) {
		rc = bi->bi_db_init( be );
	}

	if(rc != 0) {
		fprintf( stderr, "database init failed (%s)\n", type );
		nbackends--;
		return NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
505
506
	}

507
	bi->bi_nDB++;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
508
509
510
	return( be );
}

511
512
513
514
515
516
void
be_db_close( void )
{
	int	i;

	for ( i = 0; i < nbackends; i++ ) {
517
		if ( backends[i].bd_info->bi_db_close ) {
518
519
520
521
522
			(*backends[i].bd_info->bi_db_close)( &backends[i] );
		}
	}
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
523
Backend *
524
select_backend(
525
	struct berval * dn,
526
527
	int manageDSAit,
	int noSubs )
Kurt Zeilenga's avatar
Kurt Zeilenga committed
528
{
529
530
	int	i, j;
	ber_len_t len, dnlen = dn->bv_len;
531
	Backend *be = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
532
533

	for ( i = 0; i < nbackends; i++ ) {
534
535
		for ( j = 0; backends[i].be_nsuffix != NULL &&
		    backends[i].be_nsuffix[j] != NULL; j++ )
536
		{
537
538
539
			if (( backends[i].be_flags & SLAP_BFLAG_GLUE_SUBORDINATE )
				&& noSubs )
			{
540
			  	continue;
541
			}
542

543
			len = backends[i].be_nsuffix[j]->bv_len;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
544
545

			if ( len > dnlen ) {
546
				/* suffix is longer than DN */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
547
548
				continue;
			}
549
			
550
551
552
553
			if ( len && len < dnlen &&
				( !DN_SEPARATOR( dn->bv_val[(dnlen-len)-1] ) ||
					DN_ESCAPE( dn->bv_val[(dnlen-len)-2] ) ) )
			{
554
555
556
557
				/* make sure we have a separator */
				continue;
			}

558
559
560
			if ( strcmp( backends[i].be_nsuffix[j]->bv_val,
				&dn->bv_val[dnlen-len] ) == 0 )
			{
561
562
563
564
565
566
567
568
569
570
				if( be == NULL ) {
					be = &backends[i];

					if( manageDSAit && len == dnlen ) {
						continue;
					}
				} else {
					be = &backends[i];
				}
				return be;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
571
572
573
574
			}
		}
	}

575
	return be;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
576
577
578
579
580
}

int
be_issuffix(
    Backend	*be,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
581
    const char	*suffix
Kurt Zeilenga's avatar
Kurt Zeilenga committed
582
583
584
)
{
	int	i;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
585
	struct berval	bvsuffix = { strlen( suffix ), (char *)suffix };
Kurt Zeilenga's avatar
Kurt Zeilenga committed
586

587
	for ( i = 0; be->be_nsuffix != NULL && be->be_nsuffix[i] != NULL; i++ ) {
588
		if ( ber_bvcmp( be->be_nsuffix[i], &bvsuffix ) == 0 ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
589
590
591
592
593
594
595
596
			return( 1 );
		}
	}

	return( 0 );
}

int
Kurt Zeilenga's avatar
Kurt Zeilenga committed
597
be_isroot( Backend *be, struct berval *ndn )
Kurt Zeilenga's avatar
Kurt Zeilenga committed
598
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
599
	if ( !ndn->bv_len ) {
600
601
602
		return( 0 );
	}

603
	if ( !be->be_rootndn.bv_len ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
604
605
606
		return( 0 );
	}

607
	return dn_match( &be->be_rootndn, ndn );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
608
609
}

Pierangelo Masarati's avatar
Pierangelo Masarati committed
610
int
611
be_isupdate( Backend *be, struct berval *ndn )
Pierangelo Masarati's avatar
Pierangelo Masarati committed
612
{
613
	if ( !ndn->bv_len ) {
Pierangelo Masarati's avatar
Pierangelo Masarati committed
614
615
616
		return( 0 );
	}

617
	if ( !be->be_update_ndn.bv_len ) {
Pierangelo Masarati's avatar
Pierangelo Masarati committed
618
619
620
		return( 0 );
	}

621
	return dn_match( &be->be_update_ndn, ndn );
Pierangelo Masarati's avatar
Pierangelo Masarati committed
622
623
}

624
struct berval *
625
626
be_root_dn( Backend *be )
{
627
	return &be->be_rootdn;
628
629
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
630
int
Kurt Zeilenga's avatar
Kurt Zeilenga committed
631
632
be_isroot_pw( Backend *be,
	Connection *conn,
633
	struct berval *ndn,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
634
	struct berval *cred )
Kurt Zeilenga's avatar
Kurt Zeilenga committed
635
{
636
637
	int result;

638
	if ( ! be_isroot( be, ndn ) ) {
639
		return 0;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
640
641
	}

642
	if( be->be_rootpw.bv_len == 0 ) {
643
644
645
		return 0;
	}

646
#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
647
648
649
650
	ldap_pvt_thread_mutex_lock( &passwd_mutex );
#ifdef SLAPD_SPASSWD
	lutil_passwd_sasl_conn = conn->c_sasl_context;
#endif
651
652
#endif

653
	result = lutil_passwd( &be->be_rootpw, cred, NULL );
654

655
#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
Kurt Zeilenga's avatar
Kurt Zeilenga committed
656
657
658
#ifdef SLAPD_SPASSWD
	lutil_passwd_sasl_conn = NULL;
#endif
659
	ldap_pvt_thread_mutex_unlock( &passwd_mutex );
660
661
662
#endif

	return result == 0;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
663
664
}

665
int
666
667
668
669
670
671
be_entry_release_rw(
	BackendDB *be,
	Connection *conn,
	Operation *op,
	Entry *e,
	int rw )
672
673
674
{
	if ( be->be_release ) {
		/* free and release entry from backend */
675
		return be->be_release( be, conn, op, e, rw );
676
677
678
679
680
681
682
	} else {
		/* free entry */
		entry_free( e );
		return 0;
	}
}

683
684
int
backend_unbind(
Kurt Zeilenga's avatar
Kurt Zeilenga committed
685
686
687
688
689
690
691
	Connection   *conn,
	Operation    *op
)
{
	int	i;

	for ( i = 0; i < nbackends; i++ ) {
692
		if ( backends[i].be_unbind ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
693
694
695
			(*backends[i].be_unbind)( &backends[i], conn, op );
		}
	}
696
697

	return 0;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
698
}
699

700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
int
backend_connection_init(
	Connection   *conn
)
{
	int	i;

	for ( i = 0; i < nbackends; i++ ) {
		if ( backends[i].be_connection_init ) {
			(*backends[i].be_connection_init)( &backends[i], conn);
		}
	}

	return 0;
}

int
backend_connection_destroy(
	Connection   *conn
)
{
	int	i;

	for ( i = 0; i < nbackends; i++ ) {
		if ( backends[i].be_connection_destroy ) {
			(*backends[i].be_connection_destroy)( &backends[i], conn);
		}
	}

	return 0;
}

732
static int
733
734
735
backend_check_controls(
	Backend *be,
	Connection *conn,
736
	Operation *op,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
737
	const char **text )
738
739
740
741
742
743
744
745
746
747
748
{
	LDAPControl **ctrls;
	ctrls = op->o_ctrls;
	if( ctrls == NULL ) {
		return LDAP_SUCCESS;
	}

	for( ; *ctrls != NULL ; ctrls++ ) {
		if( (*ctrls)->ldctl_iscritical &&
			!charray_inlist( be->be_controls, (*ctrls)->ldctl_oid ) )
		{
749
			*text = "control unavailable in context";
750
751
752
753
754
755
756
			return LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
		}
	}

	return LDAP_SUCCESS;
}

757
758
759
760
761
int
backend_check_restrictions(
	Backend *be,
	Connection *conn,
	Operation *op,
762
	const void *opdata,
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
	const char **text )
{
	int rc;
	slap_mask_t restrictops;
	slap_mask_t requires;
	slap_mask_t opflag;
	slap_ssf_set_t *ssf;
	int updateop = 0;

	if( be ) {
		rc = backend_check_controls( be, conn, op, text );

		if( rc != LDAP_SUCCESS ) {
			return rc;
		}

		restrictops = be->be_restrictops;
		requires = be->be_requires;
		ssf = &be->be_ssf_set;

	} else {
		restrictops = global_restrictops;
		requires = global_requires;
		ssf = &global_ssf_set;
	}

	switch( op->o_tag ) {
	case LDAP_REQ_ADD:
		opflag = SLAP_RESTRICT_OP_ADD;
		updateop++;
		break;
	case LDAP_REQ_BIND:
		opflag = SLAP_RESTRICT_OP_BIND;
		break;
	case LDAP_REQ_COMPARE:
		opflag = SLAP_RESTRICT_OP_COMPARE;
		break;
	case LDAP_REQ_DELETE:
		updateop++;
		opflag = SLAP_RESTRICT_OP_DELETE;
		break;
	case LDAP_REQ_EXTENDED:
		opflag = SLAP_RESTRICT_OP_EXTENDED;
		break;
	case LDAP_REQ_MODIFY:
		updateop++;
		opflag = SLAP_RESTRICT_OP_MODIFY;
		break;
	case LDAP_REQ_RENAME:
		updateop++;
		opflag = SLAP_RESTRICT_OP_RENAME;
		break;
	case LDAP_REQ_SEARCH:
		opflag = SLAP_RESTRICT_OP_SEARCH;
		break;
	case LDAP_REQ_UNBIND:
		opflag = 0;
		break;
	default:
		*text = "restrict operations internal error";
		return LDAP_OTHER;
	}

826
827
828
	if ( op->o_tag != LDAP_REQ_EXTENDED
		|| strcmp( (const char *) opdata, LDAP_EXOP_START_TLS ) )
	{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
829
		/* these checks don't apply to StartTLS */
830
831
832
833
834
835
836
837
838
839

		if( op->o_tag == LDAP_REQ_EXTENDED ) {
			/* threat other extended operations as update ops */
			updateop++;
		}

		if( op->o_transport_ssf < ssf->sss_transport ) {
			*text = "transport confidentiality required";
			return LDAP_CONFIDENTIALITY_REQUIRED;
		}
840

841
842
843
844
845
		if( op->o_tls_ssf < ssf->sss_tls ) {
			*text = "TLS confidentiality required";
			return LDAP_CONFIDENTIALITY_REQUIRED;
		}

846
847
848
849
850
851
852
853
854
855
		if( op->o_tag != LDAP_REQ_BIND || opdata == NULL ) {
			/* these checks don't apply to SASL bind */

			if( op->o_sasl_ssf < ssf->sss_sasl ) {
				*text = "SASL confidentiality required";
				return LDAP_CONFIDENTIALITY_REQUIRED;
			}

			if( op->o_ssf < ssf->sss_ssf ) {
				*text = "confidentiality required";
856
857
				return LDAP_CONFIDENTIALITY_REQUIRED;
			}
858
859
860
		}

		if( updateop ) {
861
862
863
864
			if( op->o_transport_ssf < ssf->sss_update_transport ) {
				*text = "transport update confidentiality required";
				return LDAP_CONFIDENTIALITY_REQUIRED;
			}
865

866
867
868
869
			if( op->o_tls_ssf < ssf->sss_update_tls ) {
				*text = "TLS update confidentiality required";
				return LDAP_CONFIDENTIALITY_REQUIRED;
			}
870

871
872
873
874
			if( op->o_sasl_ssf < ssf->sss_update_sasl ) {
				*text = "SASL update confidentiality required";
				return LDAP_CONFIDENTIALITY_REQUIRED;
			}
875
876
877
878
879

			if( op->o_ssf < ssf->sss_update_ssf ) {
				*text = "update confidentiality required";
				return LDAP_CONFIDENTIALITY_REQUIRED;
			}
880

881
			if( op->o_ndn.bv_len == 0 ) {
882
883
884
				*text = "modifications require authentication";
				return LDAP_OPERATIONS_ERROR;
			}
885
		}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
886
887
	}

888
889
	if ( op->o_tag != LDAP_REQ_BIND && ( op->o_tag != LDAP_REQ_EXTENDED ||
		strcmp( (const char *) opdata, LDAP_EXOP_START_TLS ) ) )
Kurt Zeilenga's avatar
Kurt Zeilenga committed
890
	{
891
		/* these checks don't apply to Bind or StartTLS */
892
893
894

		if( requires & SLAP_REQUIRE_STRONG ) {
			/* should check mechanism */
895
			if( op->o_authmech == NULL || op->o_dn.bv_len == 0 )
896
			{
897
				*text = "strong authentication required";
898
899
900
901
902
				return LDAP_STRONG_AUTH_REQUIRED;
			}
		}

		if( requires & SLAP_REQUIRE_SASL ) {
903
			if( op->o_authmech == NULL || op->o_dn.bv_len == 0 )
904
905
906
907
908
909
910
			{
				*text = "SASL authentication required";
				return LDAP_STRONG_AUTH_REQUIRED;
			}
		}
			
		if( requires & SLAP_REQUIRE_AUTHC ) {
911
			if( op->o_dn.bv_len == 0 ) {
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
				*text = "authentication required";
				return LDAP_UNWILLING_TO_PERFORM;
			}
		}

		if( requires & SLAP_REQUIRE_BIND ) {
			int version;
			ldap_pvt_thread_mutex_lock( &conn->c_mutex );
			version = conn->c_protocol;
			ldap_pvt_thread_mutex_unlock( &conn->c_mutex );

			if( !version ) {
				/* no bind has occurred */
				*text = "BIND required";
				return LDAP_OPERATIONS_ERROR;
			}
		}

		if( requires & SLAP_REQUIRE_LDAP_V3 ) {
			if( op->o_protocol < LDAP_VERSION3 ) {
				/* no bind has occurred */
				*text = "operation restricted to LDAPv3 clients";
				return LDAP_OPERATIONS_ERROR;
			}
		}
	}

	if( restrictops & opflag ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
940
		if( restrictops == SLAP_RESTRICT_OP_READS ) {
941
942
943
944
945
946
947
948
949
950
			*text = "read operations restricted";
		} else {
			*text = "operation restricted";
		}
		return LDAP_UNWILLING_TO_PERFORM;
 	}

	return LDAP_SUCCESS;
}

951
952
953
954
int backend_check_referrals(
	Backend *be,
	Connection *conn,
	Operation *op,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
955
956
	struct berval *dn,
	struct berval *ndn )
957
{
958
	int rc = LDAP_SUCCESS;
959
960

	if( be->be_chk_referrals ) {
961
962
		const char *text;

963
		rc = be->be_chk_referrals( be,
964
			conn, op, dn, ndn, &text );
965
966
967
968
969

		if( rc != LDAP_SUCCESS && rc != LDAP_REFERRAL ) {
			send_ldap_result( conn, op, rc,
				NULL, text, NULL, NULL );
		}
970
971
	}

972
	return rc;
973
974
}

975
int 
976
backend_group(
977
	Backend	*be,
978
979
	Connection *conn,
	Operation *op,
980
	Entry	*target,
981
	struct berval *gr_ndn,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
982
	struct berval *op_ndn,
983
	ObjectClass *group_oc,
984
	AttributeDescription *group_at
985
)
986
{
987
988
989
990
991
992
	GroupAssertion *g;
	int i;

	ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
	i = op->o_abandon;
	ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
993
	if (i) return SLAPD_ABANDON;
994

995
	if ( !dn_match( &target->e_nname, gr_ndn ) ) {
996
997
		/* we won't attempt to send it to a different backend */
		
998
		be = select_backend( gr_ndn, 0,
999
			(be->be_flags & SLAP_BFLAG_GLUE_INSTANCE));
1000

For faster browsing, not all history is shown. View entire blame