1 /* $NetBSD: backend.c,v 1.1.1.4 2014/05/28 09:58:45 tron Exp $ */ 2 3 /* backend.c - routines for dealing with back-end databases */ 4 /* $OpenLDAP$ */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2014 The OpenLDAP Foundation. 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 the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18 /* Portions Copyright (c) 1995 Regents of the University of Michigan. 19 * All rights reserved. 20 * 21 * Redistribution and use in source and binary forms are permitted 22 * provided that this notice is preserved and that due credit is given 23 * to the University of Michigan at Ann Arbor. The name of the University 24 * may not be used to endorse or promote products derived from this 25 * software without specific prior written permission. This software 26 * is provided ``as is'' without express or implied warranty. 27 */ 28 29 30 #include "portable.h" 31 32 #include <stdio.h> 33 34 #include <ac/string.h> 35 #include <ac/socket.h> 36 #include <sys/stat.h> 37 38 #include "slap.h" 39 #include "config.h" 40 #include "lutil.h" 41 #include "lber_pvt.h" 42 43 /* 44 * If a module is configured as dynamic, its header should not 45 * get included into slapd. While this is a general rule and does 46 * not have much of an effect in UNIX, this rule should be adhered 47 * to for Windows, where dynamic object code should not be implicitly 48 * imported into slapd without appropriate __declspec(dllimport) directives. 49 */ 50 51 int nBackendInfo = 0; 52 slap_bi_head backendInfo = LDAP_STAILQ_HEAD_INITIALIZER(backendInfo); 53 54 int nBackendDB = 0; 55 slap_be_head backendDB = LDAP_STAILQ_HEAD_INITIALIZER(backendDB); 56 57 static int 58 backend_init_controls( BackendInfo *bi ) 59 { 60 if ( bi->bi_controls ) { 61 int i; 62 63 for ( i = 0; bi->bi_controls[ i ]; i++ ) { 64 int cid; 65 66 if ( slap_find_control_id( bi->bi_controls[ i ], &cid ) 67 == LDAP_CONTROL_NOT_FOUND ) 68 { 69 if ( !( slapMode & SLAP_TOOL_MODE ) ) { 70 assert( 0 ); 71 } 72 73 return -1; 74 } 75 76 bi->bi_ctrls[ cid ] = 1; 77 } 78 } 79 80 return 0; 81 } 82 83 int backend_init(void) 84 { 85 int rc = -1; 86 BackendInfo *bi; 87 88 if((nBackendInfo != 0) || !LDAP_STAILQ_EMPTY(&backendInfo)) { 89 /* already initialized */ 90 Debug( LDAP_DEBUG_ANY, 91 "backend_init: already initialized\n", 0, 0, 0 ); 92 return -1; 93 } 94 95 for( bi=slap_binfo; bi->bi_type != NULL; bi++,nBackendInfo++ ) { 96 assert( bi->bi_init != 0 ); 97 98 rc = bi->bi_init( bi ); 99 100 if(rc != 0) { 101 Debug( LDAP_DEBUG_ANY, 102 "backend_init: initialized for type \"%s\"\n", 103 bi->bi_type, 0, 0 ); 104 /* destroy those we've already inited */ 105 for( nBackendInfo--; 106 nBackendInfo >= 0 ; 107 nBackendInfo-- ) 108 { 109 if ( slap_binfo[nBackendInfo].bi_destroy ) { 110 slap_binfo[nBackendInfo].bi_destroy( 111 &slap_binfo[nBackendInfo] ); 112 } 113 } 114 return rc; 115 } 116 117 LDAP_STAILQ_INSERT_TAIL(&backendInfo, bi, bi_next); 118 } 119 120 if ( nBackendInfo > 0) { 121 return 0; 122 } 123 124 #ifdef SLAPD_MODULES 125 return 0; 126 #else 127 128 Debug( LDAP_DEBUG_ANY, 129 "backend_init: failed\n", 130 0, 0, 0 ); 131 132 return rc; 133 #endif /* SLAPD_MODULES */ 134 } 135 136 int backend_add(BackendInfo *aBackendInfo) 137 { 138 int rc = 0; 139 140 if ( aBackendInfo->bi_init == NULL ) { 141 Debug( LDAP_DEBUG_ANY, "backend_add: " 142 "backend type \"%s\" does not have the (mandatory)init function\n", 143 aBackendInfo->bi_type, 0, 0 ); 144 return -1; 145 } 146 147 rc = aBackendInfo->bi_init(aBackendInfo); 148 if ( rc != 0) { 149 Debug( LDAP_DEBUG_ANY, 150 "backend_add: initialization for type \"%s\" failed\n", 151 aBackendInfo->bi_type, 0, 0 ); 152 return rc; 153 } 154 155 (void)backend_init_controls( aBackendInfo ); 156 157 /* now add the backend type to the Backend Info List */ 158 LDAP_STAILQ_INSERT_TAIL( &backendInfo, aBackendInfo, bi_next ); 159 nBackendInfo++; 160 return 0; 161 } 162 163 static int 164 backend_set_controls( BackendDB *be ) 165 { 166 BackendInfo *bi = be->bd_info; 167 168 /* back-relay takes care of itself; so may do other */ 169 if ( overlay_is_over( be ) ) { 170 bi = ((slap_overinfo *)be->bd_info->bi_private)->oi_orig; 171 } 172 173 if ( bi->bi_controls ) { 174 if ( be->be_ctrls[ SLAP_MAX_CIDS ] == 0 ) { 175 AC_MEMCPY( be->be_ctrls, bi->bi_ctrls, 176 sizeof( be->be_ctrls ) ); 177 be->be_ctrls[ SLAP_MAX_CIDS ] = 1; 178 179 } else { 180 int i; 181 182 for ( i = 0; i < SLAP_MAX_CIDS; i++ ) { 183 if ( bi->bi_ctrls[ i ] ) { 184 be->be_ctrls[ i ] = bi->bi_ctrls[ i ]; 185 } 186 } 187 } 188 189 } 190 191 return 0; 192 } 193 194 /* startup a specific backend database */ 195 int backend_startup_one(Backend *be, ConfigReply *cr) 196 { 197 int rc = 0; 198 199 assert( be != NULL ); 200 201 be->be_pending_csn_list = (struct be_pcl *) 202 ch_calloc( 1, sizeof( struct be_pcl ) ); 203 204 LDAP_TAILQ_INIT( be->be_pending_csn_list ); 205 206 Debug( LDAP_DEBUG_TRACE, 207 "backend_startup_one: starting \"%s\"\n", 208 be->be_suffix ? be->be_suffix[0].bv_val : "(unknown)", 209 0, 0 ); 210 211 /* set database controls */ 212 (void)backend_set_controls( be ); 213 214 #if 0 215 if ( !BER_BVISEMPTY( &be->be_rootndn ) 216 && select_backend( &be->be_rootndn, 0 ) == be 217 && BER_BVISNULL( &be->be_rootpw ) ) 218 { 219 /* warning: if rootdn entry is created, 220 * it can take rootdn privileges; 221 * set empty rootpw to prevent */ 222 } 223 #endif 224 225 if ( be->bd_info->bi_db_open ) { 226 rc = be->bd_info->bi_db_open( be, cr ); 227 if ( rc == 0 ) { 228 (void)backend_set_controls( be ); 229 230 } else { 231 char *type = be->bd_info->bi_type; 232 char *suffix = "(null)"; 233 234 if ( overlay_is_over( be ) ) { 235 slap_overinfo *oi = (slap_overinfo *)be->bd_info->bi_private; 236 type = oi->oi_orig->bi_type; 237 } 238 239 if ( be->be_suffix != NULL && !BER_BVISNULL( &be->be_suffix[0] ) ) { 240 suffix = be->be_suffix[0].bv_val; 241 } 242 243 Debug( LDAP_DEBUG_ANY, 244 "backend_startup_one (type=%s, suffix=\"%s\"): " 245 "bi_db_open failed! (%d)\n", 246 type, suffix, rc ); 247 } 248 } 249 250 return rc; 251 } 252 253 int backend_startup(Backend *be) 254 { 255 int i; 256 int rc = 0; 257 BackendInfo *bi; 258 ConfigReply cr={0, ""}; 259 260 if( ! ( nBackendDB > 0 ) ) { 261 /* no databases */ 262 Debug( LDAP_DEBUG_ANY, 263 "backend_startup: %d databases to startup.\n", 264 nBackendDB, 0, 0 ); 265 return 1; 266 } 267 268 if(be != NULL) { 269 if ( be->bd_info->bi_open ) { 270 rc = be->bd_info->bi_open( be->bd_info ); 271 if ( rc != 0 ) { 272 Debug( LDAP_DEBUG_ANY, 273 "backend_startup: bi_open failed!\n", 274 0, 0, 0 ); 275 276 return rc; 277 } 278 } 279 280 return backend_startup_one( be, &cr ); 281 } 282 283 /* open frontend, if required */ 284 if ( frontendDB->bd_info->bi_db_open ) { 285 rc = frontendDB->bd_info->bi_db_open( frontendDB, &cr ); 286 if ( rc != 0 ) { 287 Debug( LDAP_DEBUG_ANY, 288 "backend_startup: bi_db_open(frontend) failed! (%d)\n", 289 rc, 0, 0 ); 290 return rc; 291 } 292 } 293 294 /* open each backend type */ 295 i = -1; 296 LDAP_STAILQ_FOREACH(bi, &backendInfo, bi_next) { 297 i++; 298 if( bi->bi_nDB == 0) { 299 /* no database of this type, don't open */ 300 continue; 301 } 302 303 if( bi->bi_open ) { 304 rc = bi->bi_open( bi ); 305 if ( rc != 0 ) { 306 Debug( LDAP_DEBUG_ANY, 307 "backend_startup: bi_open %d (%s) failed!\n", 308 i, bi->bi_type, 0 ); 309 return rc; 310 } 311 } 312 313 (void)backend_init_controls( bi ); 314 } 315 316 /* open each backend database */ 317 i = -1; 318 LDAP_STAILQ_FOREACH(be, &backendDB, be_next) { 319 i++; 320 if ( be->be_suffix == NULL ) { 321 Debug( LDAP_DEBUG_ANY, 322 "backend_startup: warning, database %d (%s) " 323 "has no suffix\n", 324 i, be->bd_info->bi_type, 0 ); 325 } 326 327 rc = backend_startup_one( be, &cr ); 328 329 if ( rc ) return rc; 330 } 331 332 return rc; 333 } 334 335 int backend_num( Backend *be ) 336 { 337 int i = 0; 338 BackendDB *b2; 339 340 if( be == NULL ) return -1; 341 342 LDAP_STAILQ_FOREACH( b2, &backendDB, be_next ) { 343 if( be == b2 ) return i; 344 i++; 345 } 346 return -1; 347 } 348 349 int backend_shutdown( Backend *be ) 350 { 351 int rc = 0; 352 BackendInfo *bi; 353 354 if( be != NULL ) { 355 /* shutdown a specific backend database */ 356 357 if ( be->bd_info->bi_nDB == 0 ) { 358 /* no database of this type, we never opened it */ 359 return 0; 360 } 361 362 if ( be->bd_info->bi_db_close ) { 363 rc = be->bd_info->bi_db_close( be, NULL ); 364 if ( rc ) return rc; 365 } 366 367 if( be->bd_info->bi_close ) { 368 rc = be->bd_info->bi_close( be->bd_info ); 369 if ( rc ) return rc; 370 } 371 372 return 0; 373 } 374 375 /* close each backend database */ 376 LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { 377 if ( be->bd_info->bi_db_close ) { 378 be->bd_info->bi_db_close( be, NULL ); 379 } 380 381 if(rc != 0) { 382 Debug( LDAP_DEBUG_ANY, 383 "backend_close: bi_db_close %s failed!\n", 384 be->be_type, 0, 0 ); 385 } 386 } 387 388 /* close each backend type */ 389 LDAP_STAILQ_FOREACH( bi, &backendInfo, bi_next ) { 390 if( bi->bi_nDB == 0 ) { 391 /* no database of this type */ 392 continue; 393 } 394 395 if( bi->bi_close ) { 396 bi->bi_close( bi ); 397 } 398 } 399 400 /* close frontend, if required */ 401 if ( frontendDB->bd_info->bi_db_close ) { 402 rc = frontendDB->bd_info->bi_db_close ( frontendDB, NULL ); 403 if ( rc != 0 ) { 404 Debug( LDAP_DEBUG_ANY, 405 "backend_startup: bi_db_close(frontend) failed! (%d)\n", 406 rc, 0, 0 ); 407 } 408 } 409 410 return 0; 411 } 412 413 /* 414 * This function is supposed to be the exact counterpart 415 * of backend_startup_one(), although this one calls bi_db_destroy() 416 * while backend_startup_one() calls bi_db_open(). 417 * 418 * Make sure backend_stopdown_one() destroys resources allocated 419 * by backend_startup_one(); only call backend_destroy_one() when 420 * all stuff in a BackendDB needs to be destroyed 421 */ 422 void 423 backend_stopdown_one( BackendDB *bd ) 424 { 425 if ( bd->be_pending_csn_list ) { 426 struct slap_csn_entry *csne; 427 csne = LDAP_TAILQ_FIRST( bd->be_pending_csn_list ); 428 while ( csne ) { 429 struct slap_csn_entry *tmp_csne = csne; 430 431 LDAP_TAILQ_REMOVE( bd->be_pending_csn_list, csne, ce_csn_link ); 432 ch_free( csne->ce_csn.bv_val ); 433 csne = LDAP_TAILQ_NEXT( csne, ce_csn_link ); 434 ch_free( tmp_csne ); 435 } 436 ch_free( bd->be_pending_csn_list ); 437 } 438 439 if ( bd->bd_info->bi_db_destroy ) { 440 bd->bd_info->bi_db_destroy( bd, NULL ); 441 } 442 } 443 444 void backend_destroy_one( BackendDB *bd, int dynamic ) 445 { 446 if ( dynamic ) { 447 LDAP_STAILQ_REMOVE(&backendDB, bd, BackendDB, be_next ); 448 } 449 450 if ( bd->be_syncinfo ) { 451 syncinfo_free( bd->be_syncinfo, 1 ); 452 } 453 454 backend_stopdown_one( bd ); 455 456 ber_bvarray_free( bd->be_suffix ); 457 ber_bvarray_free( bd->be_nsuffix ); 458 if ( !BER_BVISNULL( &bd->be_rootdn ) ) { 459 free( bd->be_rootdn.bv_val ); 460 } 461 if ( !BER_BVISNULL( &bd->be_rootndn ) ) { 462 free( bd->be_rootndn.bv_val ); 463 } 464 if ( !BER_BVISNULL( &bd->be_rootpw ) ) { 465 free( bd->be_rootpw.bv_val ); 466 } 467 acl_destroy( bd->be_acl ); 468 limits_destroy( bd->be_limits ); 469 if ( bd->be_extra_anlist ) { 470 anlist_free( bd->be_extra_anlist, 1, NULL ); 471 } 472 if ( !BER_BVISNULL( &bd->be_update_ndn ) ) { 473 ch_free( bd->be_update_ndn.bv_val ); 474 } 475 if ( bd->be_update_refs ) { 476 ber_bvarray_free( bd->be_update_refs ); 477 } 478 479 ldap_pvt_thread_mutex_destroy( &bd->be_pcl_mutex ); 480 481 if ( dynamic ) { 482 free( bd ); 483 } 484 } 485 486 int backend_destroy(void) 487 { 488 BackendDB *bd; 489 BackendInfo *bi; 490 491 /* destroy each backend database */ 492 while (( bd = LDAP_STAILQ_FIRST(&backendDB))) { 493 backend_destroy_one( bd, 1 ); 494 } 495 496 /* destroy each backend type */ 497 LDAP_STAILQ_FOREACH( bi, &backendInfo, bi_next ) { 498 if( bi->bi_destroy ) { 499 bi->bi_destroy( bi ); 500 } 501 } 502 503 nBackendInfo = 0; 504 LDAP_STAILQ_INIT(&backendInfo); 505 506 /* destroy frontend database */ 507 bd = frontendDB; 508 if ( bd ) { 509 if ( bd->bd_info->bi_db_destroy ) { 510 bd->bd_info->bi_db_destroy( bd, NULL ); 511 } 512 ber_bvarray_free( bd->be_suffix ); 513 ber_bvarray_free( bd->be_nsuffix ); 514 if ( !BER_BVISNULL( &bd->be_rootdn ) ) { 515 free( bd->be_rootdn.bv_val ); 516 } 517 if ( !BER_BVISNULL( &bd->be_rootndn ) ) { 518 free( bd->be_rootndn.bv_val ); 519 } 520 if ( !BER_BVISNULL( &bd->be_rootpw ) ) { 521 free( bd->be_rootpw.bv_val ); 522 } 523 acl_destroy( bd->be_acl ); 524 frontendDB = NULL; 525 } 526 527 return 0; 528 } 529 530 BackendInfo* backend_info(const char *type) 531 { 532 BackendInfo *bi; 533 534 /* search for the backend type */ 535 LDAP_STAILQ_FOREACH(bi,&backendInfo,bi_next) { 536 if( strcasecmp(bi->bi_type, type) == 0 ) { 537 return bi; 538 } 539 } 540 541 return NULL; 542 } 543 544 void 545 backend_db_insert( 546 BackendDB *be, 547 int idx 548 ) 549 { 550 /* If idx < 0, just add to end of list */ 551 if ( idx < 0 ) { 552 LDAP_STAILQ_INSERT_TAIL(&backendDB, be, be_next); 553 } else if ( idx == 0 ) { 554 LDAP_STAILQ_INSERT_HEAD(&backendDB, be, be_next); 555 } else { 556 int i; 557 BackendDB *b2; 558 559 b2 = LDAP_STAILQ_FIRST(&backendDB); 560 idx--; 561 for (i=0; i<idx; i++) { 562 b2 = LDAP_STAILQ_NEXT(b2, be_next); 563 } 564 LDAP_STAILQ_INSERT_AFTER(&backendDB, b2, be, be_next); 565 } 566 } 567 568 void 569 backend_db_move( 570 BackendDB *be, 571 int idx 572 ) 573 { 574 LDAP_STAILQ_REMOVE(&backendDB, be, BackendDB, be_next); 575 backend_db_insert(be, idx); 576 } 577 578 BackendDB * 579 backend_db_init( 580 const char *type, 581 BackendDB *b0, 582 int idx, 583 ConfigReply *cr) 584 { 585 BackendInfo *bi = backend_info(type); 586 BackendDB *be = b0; 587 int rc = 0; 588 589 if( bi == NULL ) { 590 fprintf( stderr, "Unrecognized database type (%s)\n", type ); 591 return NULL; 592 } 593 594 /* If be is provided, treat it as private. Otherwise allocate 595 * one and add it to the global list. 596 */ 597 if ( !be ) { 598 be = ch_calloc( 1, sizeof(Backend) ); 599 /* Just append */ 600 if ( idx >= nbackends ) 601 idx = -1; 602 nbackends++; 603 backend_db_insert( be, idx ); 604 } 605 606 be->bd_info = bi; 607 be->bd_self = be; 608 609 be->be_def_limit = frontendDB->be_def_limit; 610 be->be_dfltaccess = frontendDB->be_dfltaccess; 611 612 be->be_restrictops = frontendDB->be_restrictops; 613 be->be_requires = frontendDB->be_requires; 614 be->be_ssf_set = frontendDB->be_ssf_set; 615 616 ldap_pvt_thread_mutex_init( &be->be_pcl_mutex ); 617 618 /* assign a default depth limit for alias deref */ 619 be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; 620 621 if ( bi->bi_db_init ) { 622 rc = bi->bi_db_init( be, cr ); 623 } 624 625 if ( rc != 0 ) { 626 fprintf( stderr, "database init failed (%s)\n", type ); 627 /* If we created and linked this be, remove it and free it */ 628 if ( !b0 ) { 629 LDAP_STAILQ_REMOVE(&backendDB, be, BackendDB, be_next); 630 ldap_pvt_thread_mutex_destroy( &be->be_pcl_mutex ); 631 ch_free( be ); 632 be = NULL; 633 nbackends--; 634 } 635 } else { 636 if ( !bi->bi_nDB ) { 637 backend_init_controls( bi ); 638 } 639 bi->bi_nDB++; 640 } 641 return( be ); 642 } 643 644 void 645 be_db_close( void ) 646 { 647 BackendDB *be; 648 649 LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { 650 if ( be->bd_info->bi_db_close ) { 651 be->bd_info->bi_db_close( be, NULL ); 652 } 653 } 654 655 if ( frontendDB->bd_info->bi_db_close ) { 656 frontendDB->bd_info->bi_db_close( frontendDB, NULL ); 657 } 658 659 } 660 661 Backend * 662 select_backend( 663 struct berval * dn, 664 int noSubs ) 665 { 666 int j; 667 ber_len_t len, dnlen = dn->bv_len; 668 Backend *be; 669 670 LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { 671 if ( be->be_nsuffix == NULL || SLAP_DBHIDDEN( be )) { 672 continue; 673 } 674 675 for ( j = 0; !BER_BVISNULL( &be->be_nsuffix[j] ); j++ ) 676 { 677 if ( ( SLAP_GLUE_SUBORDINATE( be ) ) && noSubs ) 678 { 679 continue; 680 } 681 682 len = be->be_nsuffix[j].bv_len; 683 684 if ( len > dnlen ) { 685 /* suffix is longer than DN */ 686 continue; 687 } 688 689 /* 690 * input DN is normalized, so the separator check 691 * need not look at escaping 692 */ 693 if ( len && len < dnlen && 694 !DN_SEPARATOR( dn->bv_val[(dnlen-len)-1] )) 695 { 696 continue; 697 } 698 699 if ( strcmp( be->be_nsuffix[j].bv_val, 700 &dn->bv_val[dnlen-len] ) == 0 ) 701 { 702 return be; 703 } 704 } 705 } 706 707 return be; 708 } 709 710 int 711 be_issuffix( 712 Backend *be, 713 struct berval *bvsuffix ) 714 { 715 int i; 716 717 if ( be->be_nsuffix == NULL ) { 718 return 0; 719 } 720 721 for ( i = 0; !BER_BVISNULL( &be->be_nsuffix[i] ); i++ ) { 722 if ( bvmatch( &be->be_nsuffix[i], bvsuffix ) ) { 723 return 1; 724 } 725 } 726 727 return 0; 728 } 729 730 int 731 be_issubordinate( 732 Backend *be, 733 struct berval *bvsubordinate ) 734 { 735 int i; 736 737 if ( be->be_nsuffix == NULL ) { 738 return 0; 739 } 740 741 for ( i = 0; !BER_BVISNULL( &be->be_nsuffix[i] ); i++ ) { 742 if ( dnIsSuffix( bvsubordinate, &be->be_nsuffix[i] ) ) { 743 return 1; 744 } 745 } 746 747 return 0; 748 } 749 750 int 751 be_isroot_dn( Backend *be, struct berval *ndn ) 752 { 753 if ( BER_BVISEMPTY( ndn ) || BER_BVISEMPTY( &be->be_rootndn ) ) { 754 return 0; 755 } 756 757 return dn_match( &be->be_rootndn, ndn ); 758 } 759 760 int 761 be_slurp_update( Operation *op ) 762 { 763 return ( SLAP_SLURP_SHADOW( op->o_bd ) && 764 be_isupdate_dn( op->o_bd, &op->o_ndn ) ); 765 } 766 767 int 768 be_shadow_update( Operation *op ) 769 { 770 /* This assumes that all internal ops (connid <= -1000) on a syncrepl 771 * database are syncrepl operations. 772 */ 773 return ( ( SLAP_SYNC_SHADOW( op->o_bd ) && SLAPD_SYNC_IS_SYNCCONN( op->o_connid ) ) || 774 ( SLAP_SHADOW( op->o_bd ) && be_isupdate_dn( op->o_bd, &op->o_ndn ) ) ); 775 } 776 777 int 778 be_isupdate_dn( Backend *be, struct berval *ndn ) 779 { 780 if ( BER_BVISEMPTY( ndn ) || BER_BVISEMPTY( &be->be_update_ndn ) ) { 781 return 0; 782 } 783 784 return dn_match( &be->be_update_ndn, ndn ); 785 } 786 787 struct berval * 788 be_root_dn( Backend *be ) 789 { 790 return &be->be_rootdn; 791 } 792 793 int 794 be_isroot( Operation *op ) 795 { 796 return be_isroot_dn( op->o_bd, &op->o_ndn ); 797 } 798 799 int 800 be_isroot_pw( Operation *op ) 801 { 802 return be_rootdn_bind( op, NULL ) == LDAP_SUCCESS; 803 } 804 805 /* 806 * checks if binding as rootdn 807 * 808 * return value: 809 * SLAP_CB_CONTINUE if not the rootdn, or if rootpw is null 810 * LDAP_SUCCESS if rootdn & rootpw 811 * LDAP_INVALID_CREDENTIALS if rootdn & !rootpw 812 * 813 * if rs != NULL 814 * if LDAP_SUCCESS, op->orb_edn is set 815 * if LDAP_INVALID_CREDENTIALS, response is sent to client 816 */ 817 int 818 be_rootdn_bind( Operation *op, SlapReply *rs ) 819 { 820 int rc; 821 #ifdef SLAPD_SPASSWD 822 void *old_authctx = NULL; 823 #endif 824 825 assert( op->o_tag == LDAP_REQ_BIND ); 826 assert( op->orb_method == LDAP_AUTH_SIMPLE ); 827 828 if ( !be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) { 829 return SLAP_CB_CONTINUE; 830 } 831 832 if ( BER_BVISNULL( &op->o_bd->be_rootpw ) ) { 833 /* give the database a chance */ 834 return SLAP_CB_CONTINUE; 835 } 836 837 if ( BER_BVISEMPTY( &op->o_bd->be_rootpw ) ) { 838 /* rootdn bind explicitly disallowed */ 839 rc = LDAP_INVALID_CREDENTIALS; 840 if ( rs ) { 841 goto send_result; 842 } 843 844 return rc; 845 } 846 847 #ifdef SLAPD_SPASSWD 848 ldap_pvt_thread_pool_setkey( op->o_threadctx, (void *)slap_sasl_bind, 849 op->o_conn->c_sasl_authctx, 0, &old_authctx, NULL ); 850 #endif 851 852 rc = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL, NULL ); 853 854 #ifdef SLAPD_SPASSWD 855 ldap_pvt_thread_pool_setkey( op->o_threadctx, (void *)slap_sasl_bind, 856 old_authctx, 0, NULL, NULL ); 857 #endif 858 859 rc = ( rc == 0 ? LDAP_SUCCESS : LDAP_INVALID_CREDENTIALS ); 860 if ( rs ) { 861 send_result:; 862 rs->sr_err = rc; 863 864 Debug( LDAP_DEBUG_TRACE, "%s: rootdn=\"%s\" bind%s\n", 865 op->o_log_prefix, op->o_bd->be_rootdn.bv_val, 866 rc == LDAP_SUCCESS ? " succeeded" : " failed" ); 867 868 if ( rc == LDAP_SUCCESS ) { 869 /* Set to the pretty rootdn */ 870 ber_dupbv( &op->orb_edn, &op->o_bd->be_rootdn ); 871 872 } else { 873 send_ldap_result( op, rs ); 874 } 875 } 876 877 return rc; 878 } 879 880 int 881 be_entry_release_rw( 882 Operation *op, 883 Entry *e, 884 int rw ) 885 { 886 if ( op->o_bd->be_release ) { 887 /* free and release entry from backend */ 888 return op->o_bd->be_release( op, e, rw ); 889 } else { 890 /* free entry */ 891 entry_free( e ); 892 return 0; 893 } 894 } 895 896 int 897 backend_unbind( Operation *op, SlapReply *rs ) 898 { 899 BackendDB *be; 900 901 LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { 902 if ( be->be_unbind ) { 903 op->o_bd = be; 904 be->be_unbind( op, rs ); 905 } 906 } 907 908 return 0; 909 } 910 911 int 912 backend_connection_init( 913 Connection *conn ) 914 { 915 BackendDB *be; 916 917 LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { 918 if ( be->be_connection_init ) { 919 be->be_connection_init( be, conn ); 920 } 921 } 922 923 return 0; 924 } 925 926 int 927 backend_connection_destroy( 928 Connection *conn ) 929 { 930 BackendDB *be; 931 932 LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { 933 if ( be->be_connection_destroy ) { 934 be->be_connection_destroy( be, conn); 935 } 936 } 937 938 return 0; 939 } 940 941 int 942 backend_check_controls( 943 Operation *op, 944 SlapReply *rs ) 945 { 946 LDAPControl **ctrls = op->o_ctrls; 947 rs->sr_err = LDAP_SUCCESS; 948 949 if( ctrls ) { 950 for( ; *ctrls != NULL ; ctrls++ ) { 951 int cid; 952 953 switch ( slap_global_control( op, (*ctrls)->ldctl_oid, &cid ) ) { 954 case LDAP_CONTROL_NOT_FOUND: 955 /* unrecognized control */ 956 if ( (*ctrls)->ldctl_iscritical ) { 957 /* should not be reachable */ 958 Debug( LDAP_DEBUG_ANY, "backend_check_controls: " 959 "unrecognized critical control: %s\n", 960 (*ctrls)->ldctl_oid, 0, 0 ); 961 assert( 0 ); 962 } else { 963 Debug( LDAP_DEBUG_TRACE, "backend_check_controls: " 964 "unrecognized non-critical control: %s\n", 965 (*ctrls)->ldctl_oid, 0, 0 ); 966 } 967 break; 968 969 case LDAP_COMPARE_FALSE: 970 if ( !op->o_bd->be_ctrls[cid] && (*ctrls)->ldctl_iscritical ) { 971 #ifdef SLAP_CONTROL_X_WHATFAILED 972 if ( get_whatFailed( op ) ) { 973 char *oids[ 2 ]; 974 oids[ 0 ] = (*ctrls)->ldctl_oid; 975 oids[ 1 ] = NULL; 976 slap_ctrl_whatFailed_add( op, rs, oids ); 977 } 978 #endif 979 /* RFC 4511 allows unavailableCriticalExtension to be 980 * returned when the server is unwilling to perform 981 * an operation extended by a recognized critical 982 * control. 983 */ 984 rs->sr_text = "critical control unavailable in context"; 985 rs->sr_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; 986 goto done; 987 } 988 break; 989 990 case LDAP_COMPARE_TRUE: 991 break; 992 993 default: 994 /* unreachable */ 995 Debug( LDAP_DEBUG_ANY, 996 "backend_check_controls: unable to check control: %s\n", 997 (*ctrls)->ldctl_oid, 0, 0 ); 998 assert( 0 ); 999 1000 rs->sr_text = "unable to check control"; 1001 rs->sr_err = LDAP_OTHER; 1002 goto done; 1003 } 1004 } 1005 } 1006 1007 #if 0 /* temporarily removed */ 1008 /* check should be generalized */ 1009 if( get_relax(op) && !be_isroot(op)) { 1010 rs->sr_text = "requires manager authorization"; 1011 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 1012 } 1013 #endif 1014 1015 done:; 1016 return rs->sr_err; 1017 } 1018 1019 int 1020 backend_check_restrictions( 1021 Operation *op, 1022 SlapReply *rs, 1023 struct berval *opdata ) 1024 { 1025 slap_mask_t restrictops; 1026 slap_mask_t requires; 1027 slap_mask_t opflag; 1028 slap_mask_t exopflag = 0; 1029 slap_ssf_set_t ssfs, *ssf; 1030 int updateop = 0; 1031 int starttls = 0; 1032 int session = 0; 1033 1034 restrictops = frontendDB->be_restrictops; 1035 requires = frontendDB->be_requires; 1036 ssfs = frontendDB->be_ssf_set; 1037 ssf = &ssfs; 1038 1039 if ( op->o_bd ) { 1040 slap_ssf_t *fssf, *bssf; 1041 int rc = SLAP_CB_CONTINUE, i; 1042 1043 if ( op->o_bd->be_chk_controls ) { 1044 rc = ( *op->o_bd->be_chk_controls )( op, rs ); 1045 } 1046 1047 if ( rc == SLAP_CB_CONTINUE ) { 1048 rc = backend_check_controls( op, rs ); 1049 } 1050 1051 if ( rc != LDAP_SUCCESS ) { 1052 return rs->sr_err; 1053 } 1054 1055 restrictops |= op->o_bd->be_restrictops; 1056 requires |= op->o_bd->be_requires; 1057 bssf = &op->o_bd->be_ssf_set.sss_ssf; 1058 fssf = &ssfs.sss_ssf; 1059 for ( i=0; i < (int)(sizeof(ssfs)/sizeof(slap_ssf_t)); i++ ) { 1060 if ( bssf[i] ) fssf[i] = bssf[i]; 1061 } 1062 } 1063 1064 switch( op->o_tag ) { 1065 case LDAP_REQ_ADD: 1066 opflag = SLAP_RESTRICT_OP_ADD; 1067 updateop++; 1068 break; 1069 case LDAP_REQ_BIND: 1070 opflag = SLAP_RESTRICT_OP_BIND; 1071 session++; 1072 break; 1073 case LDAP_REQ_COMPARE: 1074 opflag = SLAP_RESTRICT_OP_COMPARE; 1075 break; 1076 case LDAP_REQ_DELETE: 1077 updateop++; 1078 opflag = SLAP_RESTRICT_OP_DELETE; 1079 break; 1080 case LDAP_REQ_EXTENDED: 1081 opflag = SLAP_RESTRICT_OP_EXTENDED; 1082 1083 if( !opdata ) { 1084 /* treat unspecified as a modify */ 1085 opflag = SLAP_RESTRICT_OP_MODIFY; 1086 updateop++; 1087 break; 1088 } 1089 1090 if( bvmatch( opdata, &slap_EXOP_START_TLS ) ) { 1091 session++; 1092 starttls++; 1093 exopflag = SLAP_RESTRICT_EXOP_START_TLS; 1094 break; 1095 } 1096 1097 if( bvmatch( opdata, &slap_EXOP_WHOAMI ) ) { 1098 exopflag = SLAP_RESTRICT_EXOP_WHOAMI; 1099 break; 1100 } 1101 1102 if ( bvmatch( opdata, &slap_EXOP_CANCEL ) ) { 1103 exopflag = SLAP_RESTRICT_EXOP_CANCEL; 1104 break; 1105 } 1106 1107 if ( bvmatch( opdata, &slap_EXOP_MODIFY_PASSWD ) ) { 1108 exopflag = SLAP_RESTRICT_EXOP_MODIFY_PASSWD; 1109 updateop++; 1110 break; 1111 } 1112 1113 /* treat everything else as a modify */ 1114 opflag = SLAP_RESTRICT_OP_MODIFY; 1115 updateop++; 1116 break; 1117 1118 case LDAP_REQ_MODIFY: 1119 updateop++; 1120 opflag = SLAP_RESTRICT_OP_MODIFY; 1121 break; 1122 case LDAP_REQ_RENAME: 1123 updateop++; 1124 opflag = SLAP_RESTRICT_OP_RENAME; 1125 break; 1126 case LDAP_REQ_SEARCH: 1127 opflag = SLAP_RESTRICT_OP_SEARCH; 1128 break; 1129 case LDAP_REQ_UNBIND: 1130 session++; 1131 opflag = 0; 1132 break; 1133 default: 1134 rs->sr_text = "restrict operations internal error"; 1135 rs->sr_err = LDAP_OTHER; 1136 return rs->sr_err; 1137 } 1138 1139 if ( !starttls ) { 1140 /* these checks don't apply to StartTLS */ 1141 1142 rs->sr_err = LDAP_CONFIDENTIALITY_REQUIRED; 1143 if( op->o_transport_ssf < ssf->sss_transport ) { 1144 rs->sr_text = op->o_transport_ssf 1145 ? "stronger transport confidentiality required" 1146 : "transport confidentiality required"; 1147 return rs->sr_err; 1148 } 1149 1150 if( op->o_tls_ssf < ssf->sss_tls ) { 1151 rs->sr_text = op->o_tls_ssf 1152 ? "stronger TLS confidentiality required" 1153 : "TLS confidentiality required"; 1154 return rs->sr_err; 1155 } 1156 1157 1158 if( op->o_tag == LDAP_REQ_BIND && opdata == NULL ) { 1159 /* simple bind specific check */ 1160 if( op->o_ssf < ssf->sss_simple_bind ) { 1161 rs->sr_text = op->o_ssf 1162 ? "stronger confidentiality required" 1163 : "confidentiality required"; 1164 return rs->sr_err; 1165 } 1166 } 1167 1168 if( op->o_tag != LDAP_REQ_BIND || opdata == NULL ) { 1169 /* these checks don't apply to SASL bind */ 1170 1171 if( op->o_sasl_ssf < ssf->sss_sasl ) { 1172 rs->sr_text = op->o_sasl_ssf 1173 ? "stronger SASL confidentiality required" 1174 : "SASL confidentiality required"; 1175 return rs->sr_err; 1176 } 1177 1178 if( op->o_ssf < ssf->sss_ssf ) { 1179 rs->sr_text = op->o_ssf 1180 ? "stronger confidentiality required" 1181 : "confidentiality required"; 1182 return rs->sr_err; 1183 } 1184 } 1185 1186 if( updateop ) { 1187 if( op->o_transport_ssf < ssf->sss_update_transport ) { 1188 rs->sr_text = op->o_transport_ssf 1189 ? "stronger transport confidentiality required for update" 1190 : "transport confidentiality required for update"; 1191 return rs->sr_err; 1192 } 1193 1194 if( op->o_tls_ssf < ssf->sss_update_tls ) { 1195 rs->sr_text = op->o_tls_ssf 1196 ? "stronger TLS confidentiality required for update" 1197 : "TLS confidentiality required for update"; 1198 return rs->sr_err; 1199 } 1200 1201 if( op->o_sasl_ssf < ssf->sss_update_sasl ) { 1202 rs->sr_text = op->o_sasl_ssf 1203 ? "stronger SASL confidentiality required for update" 1204 : "SASL confidentiality required for update"; 1205 return rs->sr_err; 1206 } 1207 1208 if( op->o_ssf < ssf->sss_update_ssf ) { 1209 rs->sr_text = op->o_ssf 1210 ? "stronger confidentiality required for update" 1211 : "confidentiality required for update"; 1212 return rs->sr_err; 1213 } 1214 1215 if( !( global_allows & SLAP_ALLOW_UPDATE_ANON ) && 1216 BER_BVISEMPTY( &op->o_ndn ) ) 1217 { 1218 rs->sr_text = "modifications require authentication"; 1219 rs->sr_err = LDAP_STRONG_AUTH_REQUIRED; 1220 return rs->sr_err; 1221 } 1222 1223 #ifdef SLAP_X_LISTENER_MOD 1224 if ( op->o_conn->c_listener && 1225 ! ( op->o_conn->c_listener->sl_perms & ( !BER_BVISEMPTY( &op->o_ndn ) 1226 ? (S_IWUSR|S_IWOTH) : S_IWOTH ) ) ) 1227 { 1228 /* no "w" mode means readonly */ 1229 rs->sr_text = "modifications not allowed on this listener"; 1230 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 1231 return rs->sr_err; 1232 } 1233 #endif /* SLAP_X_LISTENER_MOD */ 1234 } 1235 } 1236 1237 if ( !session ) { 1238 /* these checks don't apply to Bind, StartTLS, or Unbind */ 1239 1240 if( requires & SLAP_REQUIRE_STRONG ) { 1241 /* should check mechanism */ 1242 if( ( op->o_transport_ssf < ssf->sss_transport 1243 && op->o_authtype == LDAP_AUTH_SIMPLE ) 1244 || BER_BVISEMPTY( &op->o_dn ) ) 1245 { 1246 rs->sr_text = "strong(er) authentication required"; 1247 rs->sr_err = LDAP_STRONG_AUTH_REQUIRED; 1248 return rs->sr_err; 1249 } 1250 } 1251 1252 if( requires & SLAP_REQUIRE_SASL ) { 1253 if( op->o_authtype != LDAP_AUTH_SASL || BER_BVISEMPTY( &op->o_dn ) ) { 1254 rs->sr_text = "SASL authentication required"; 1255 rs->sr_err = LDAP_STRONG_AUTH_REQUIRED; 1256 return rs->sr_err; 1257 } 1258 } 1259 1260 if( requires & SLAP_REQUIRE_AUTHC ) { 1261 if( BER_BVISEMPTY( &op->o_dn ) ) { 1262 rs->sr_text = "authentication required"; 1263 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 1264 return rs->sr_err; 1265 } 1266 } 1267 1268 if( requires & SLAP_REQUIRE_BIND ) { 1269 int version; 1270 ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); 1271 version = op->o_conn->c_protocol; 1272 ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); 1273 1274 if( !version ) { 1275 /* no bind has occurred */ 1276 rs->sr_text = "BIND required"; 1277 rs->sr_err = LDAP_OPERATIONS_ERROR; 1278 return rs->sr_err; 1279 } 1280 } 1281 1282 if( requires & SLAP_REQUIRE_LDAP_V3 ) { 1283 if( op->o_protocol < LDAP_VERSION3 ) { 1284 /* no bind has occurred */ 1285 rs->sr_text = "operation restricted to LDAPv3 clients"; 1286 rs->sr_err = LDAP_OPERATIONS_ERROR; 1287 return rs->sr_err; 1288 } 1289 } 1290 1291 #ifdef SLAP_X_LISTENER_MOD 1292 if ( !starttls && BER_BVISEMPTY( &op->o_dn ) ) { 1293 if ( op->o_conn->c_listener && 1294 !( op->o_conn->c_listener->sl_perms & S_IXOTH )) 1295 { 1296 /* no "x" mode means bind required */ 1297 rs->sr_text = "bind required on this listener"; 1298 rs->sr_err = LDAP_STRONG_AUTH_REQUIRED; 1299 return rs->sr_err; 1300 } 1301 } 1302 1303 if ( !starttls && !updateop ) { 1304 if ( op->o_conn->c_listener && 1305 !( op->o_conn->c_listener->sl_perms & 1306 ( !BER_BVISEMPTY( &op->o_dn ) 1307 ? (S_IRUSR|S_IROTH) : S_IROTH ))) 1308 { 1309 /* no "r" mode means no read */ 1310 rs->sr_text = "read not allowed on this listener"; 1311 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 1312 return rs->sr_err; 1313 } 1314 } 1315 #endif /* SLAP_X_LISTENER_MOD */ 1316 1317 } 1318 1319 if( ( restrictops & opflag ) 1320 || ( exopflag && ( restrictops & exopflag ) ) 1321 || (( restrictops & SLAP_RESTRICT_READONLY ) && updateop )) { 1322 if( ( restrictops & SLAP_RESTRICT_OP_MASK) == SLAP_RESTRICT_OP_READS ) { 1323 rs->sr_text = "read operations restricted"; 1324 } else if ( restrictops & exopflag ) { 1325 rs->sr_text = "extended operation restricted"; 1326 } else { 1327 rs->sr_text = "operation restricted"; 1328 } 1329 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 1330 return rs->sr_err; 1331 } 1332 1333 rs->sr_err = LDAP_SUCCESS; 1334 return rs->sr_err; 1335 } 1336 1337 int backend_check_referrals( Operation *op, SlapReply *rs ) 1338 { 1339 rs->sr_err = LDAP_SUCCESS; 1340 1341 if( op->o_bd->be_chk_referrals ) { 1342 rs->sr_err = op->o_bd->be_chk_referrals( op, rs ); 1343 1344 if( rs->sr_err != LDAP_SUCCESS && rs->sr_err != LDAP_REFERRAL ) { 1345 send_ldap_result( op, rs ); 1346 } 1347 } 1348 1349 return rs->sr_err; 1350 } 1351 1352 int 1353 be_entry_get_rw( 1354 Operation *op, 1355 struct berval *ndn, 1356 ObjectClass *oc, 1357 AttributeDescription *at, 1358 int rw, 1359 Entry **e ) 1360 { 1361 *e = NULL; 1362 1363 if ( op->o_bd == NULL ) { 1364 return LDAP_NO_SUCH_OBJECT; 1365 } 1366 1367 if ( op->o_bd->be_fetch ) { 1368 return op->o_bd->be_fetch( op, ndn, oc, at, rw, e ); 1369 } 1370 1371 return LDAP_UNWILLING_TO_PERFORM; 1372 } 1373 1374 int 1375 fe_acl_group( 1376 Operation *op, 1377 Entry *target, 1378 struct berval *gr_ndn, 1379 struct berval *op_ndn, 1380 ObjectClass *group_oc, 1381 AttributeDescription *group_at ) 1382 { 1383 Entry *e; 1384 void *o_priv = op->o_private, *e_priv = NULL; 1385 Attribute *a; 1386 int rc; 1387 GroupAssertion *g; 1388 Backend *be = op->o_bd; 1389 OpExtra *oex; 1390 1391 LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) { 1392 if ( oex->oe_key == (void *)backend_group ) 1393 break; 1394 } 1395 1396 if ( oex && ((OpExtraDB *)oex)->oe_db ) 1397 op->o_bd = ((OpExtraDB *)oex)->oe_db; 1398 1399 if ( !op->o_bd || !SLAP_DBHIDDEN( op->o_bd )) 1400 op->o_bd = select_backend( gr_ndn, 0 ); 1401 1402 for ( g = op->o_groups; g; g = g->ga_next ) { 1403 if ( g->ga_be != op->o_bd || g->ga_oc != group_oc || 1404 g->ga_at != group_at || g->ga_len != gr_ndn->bv_len ) 1405 { 1406 continue; 1407 } 1408 if ( strcmp( g->ga_ndn, gr_ndn->bv_val ) == 0 ) { 1409 break; 1410 } 1411 } 1412 1413 if ( g ) { 1414 rc = g->ga_res; 1415 goto done; 1416 } 1417 1418 if ( target && dn_match( &target->e_nname, gr_ndn ) ) { 1419 e = target; 1420 rc = 0; 1421 1422 } else { 1423 op->o_private = NULL; 1424 rc = be_entry_get_rw( op, gr_ndn, group_oc, group_at, 0, &e ); 1425 e_priv = op->o_private; 1426 op->o_private = o_priv; 1427 } 1428 1429 if ( e ) { 1430 a = attr_find( e->e_attrs, group_at ); 1431 if ( a ) { 1432 /* If the attribute is a subtype of labeledURI, 1433 * treat this as a dynamic group ala groupOfURLs 1434 */ 1435 if ( is_at_subtype( group_at->ad_type, 1436 slap_schema.si_ad_labeledURI->ad_type ) ) 1437 { 1438 int i; 1439 LDAPURLDesc *ludp; 1440 struct berval bv, nbase; 1441 Filter *filter; 1442 Entry *user = NULL; 1443 void *user_priv = NULL; 1444 Backend *b2 = op->o_bd; 1445 1446 if ( target && dn_match( &target->e_nname, op_ndn ) ) { 1447 user = target; 1448 } 1449 1450 rc = LDAP_COMPARE_FALSE; 1451 for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) { 1452 if ( ldap_url_parse( a->a_vals[i].bv_val, &ludp ) != 1453 LDAP_URL_SUCCESS ) 1454 { 1455 continue; 1456 } 1457 1458 BER_BVZERO( &nbase ); 1459 1460 /* host, attrs and extensions parts must be empty */ 1461 if ( ( ludp->lud_host && *ludp->lud_host ) 1462 || ludp->lud_attrs 1463 || ludp->lud_exts ) 1464 { 1465 goto loopit; 1466 } 1467 1468 ber_str2bv( ludp->lud_dn, 0, 0, &bv ); 1469 if ( dnNormalize( 0, NULL, NULL, &bv, &nbase, 1470 op->o_tmpmemctx ) != LDAP_SUCCESS ) 1471 { 1472 goto loopit; 1473 } 1474 1475 switch ( ludp->lud_scope ) { 1476 case LDAP_SCOPE_BASE: 1477 if ( !dn_match( &nbase, op_ndn ) ) { 1478 goto loopit; 1479 } 1480 break; 1481 case LDAP_SCOPE_ONELEVEL: 1482 dnParent( op_ndn, &bv ); 1483 if ( !dn_match( &nbase, &bv ) ) { 1484 goto loopit; 1485 } 1486 break; 1487 case LDAP_SCOPE_SUBTREE: 1488 if ( !dnIsSuffix( op_ndn, &nbase ) ) { 1489 goto loopit; 1490 } 1491 break; 1492 case LDAP_SCOPE_SUBORDINATE: 1493 if ( dn_match( &nbase, op_ndn ) || 1494 !dnIsSuffix( op_ndn, &nbase ) ) 1495 { 1496 goto loopit; 1497 } 1498 } 1499 1500 /* NOTE: this could be NULL 1501 * if no filter is provided, 1502 * or if filter parsing fails. 1503 * In the latter case, 1504 * we should give up. */ 1505 if ( ludp->lud_filter != NULL && ludp->lud_filter != '\0') { 1506 filter = str2filter_x( op, ludp->lud_filter ); 1507 if ( filter == NULL ) { 1508 /* give up... */ 1509 rc = LDAP_OTHER; 1510 goto loopit; 1511 } 1512 1513 /* only get user if required 1514 * and not available yet */ 1515 if ( user == NULL ) { 1516 int rc2; 1517 1518 op->o_bd = select_backend( op_ndn, 0 ); 1519 op->o_private = NULL; 1520 rc2 = be_entry_get_rw( op, op_ndn, NULL, NULL, 0, &user ); 1521 user_priv = op->o_private; 1522 op->o_private = o_priv; 1523 if ( rc2 != 0 ) { 1524 /* give up... */ 1525 rc = LDAP_OTHER; 1526 goto loopit; 1527 } 1528 } 1529 1530 if ( test_filter( NULL, user, filter ) == 1531 LDAP_COMPARE_TRUE ) 1532 { 1533 rc = 0; 1534 } 1535 filter_free_x( op, filter, 1 ); 1536 } 1537 loopit: 1538 ldap_free_urldesc( ludp ); 1539 if ( !BER_BVISNULL( &nbase ) ) { 1540 op->o_tmpfree( nbase.bv_val, op->o_tmpmemctx ); 1541 } 1542 if ( rc != LDAP_COMPARE_FALSE ) { 1543 break; 1544 } 1545 } 1546 1547 if ( user != NULL && user != target ) { 1548 op->o_private = user_priv; 1549 be_entry_release_r( op, user ); 1550 op->o_private = o_priv; 1551 } 1552 op->o_bd = b2; 1553 1554 } else { 1555 rc = attr_valfind( a, 1556 SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | 1557 SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, 1558 op_ndn, NULL, op->o_tmpmemctx ); 1559 if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) { 1560 rc = LDAP_COMPARE_FALSE; 1561 } 1562 } 1563 1564 } else { 1565 rc = LDAP_NO_SUCH_ATTRIBUTE; 1566 } 1567 1568 if ( e != target ) { 1569 op->o_private = e_priv; 1570 be_entry_release_r( op, e ); 1571 op->o_private = o_priv; 1572 } 1573 1574 } else { 1575 rc = LDAP_NO_SUCH_OBJECT; 1576 } 1577 1578 if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache ) { 1579 g = op->o_tmpalloc( sizeof( GroupAssertion ) + gr_ndn->bv_len, 1580 op->o_tmpmemctx ); 1581 g->ga_be = op->o_bd; 1582 g->ga_oc = group_oc; 1583 g->ga_at = group_at; 1584 g->ga_res = rc; 1585 g->ga_len = gr_ndn->bv_len; 1586 strcpy( g->ga_ndn, gr_ndn->bv_val ); 1587 g->ga_next = op->o_groups; 1588 op->o_groups = g; 1589 } 1590 1591 done: 1592 op->o_bd = be; 1593 return rc; 1594 } 1595 1596 int 1597 backend_group( 1598 Operation *op, 1599 Entry *target, 1600 struct berval *gr_ndn, 1601 struct berval *op_ndn, 1602 ObjectClass *group_oc, 1603 AttributeDescription *group_at ) 1604 { 1605 int rc; 1606 BackendDB *be_orig; 1607 OpExtraDB oex; 1608 1609 if ( op->o_abandon ) { 1610 return SLAPD_ABANDON; 1611 } 1612 1613 oex.oe_db = op->o_bd; 1614 oex.oe.oe_key = (void *)backend_group; 1615 LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next); 1616 1617 be_orig = op->o_bd; 1618 op->o_bd = frontendDB; 1619 rc = frontendDB->be_group( op, target, gr_ndn, 1620 op_ndn, group_oc, group_at ); 1621 op->o_bd = be_orig; 1622 LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next); 1623 1624 return rc; 1625 } 1626 1627 int 1628 fe_acl_attribute( 1629 Operation *op, 1630 Entry *target, 1631 struct berval *edn, 1632 AttributeDescription *entry_at, 1633 BerVarray *vals, 1634 slap_access_t access ) 1635 { 1636 Entry *e = NULL; 1637 void *o_priv = op->o_private, *e_priv = NULL; 1638 Attribute *a = NULL; 1639 int freeattr = 0, i, j, rc = LDAP_SUCCESS; 1640 AccessControlState acl_state = ACL_STATE_INIT; 1641 Backend *be = op->o_bd; 1642 OpExtra *oex; 1643 1644 LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) { 1645 if ( oex->oe_key == (void *)backend_attribute ) 1646 break; 1647 } 1648 1649 if ( oex && ((OpExtraDB *)oex)->oe_db ) 1650 op->o_bd = ((OpExtraDB *)oex)->oe_db; 1651 1652 if ( !op->o_bd || !SLAP_DBHIDDEN( op->o_bd )) 1653 op->o_bd = select_backend( edn, 0 ); 1654 1655 if ( target && dn_match( &target->e_nname, edn ) ) { 1656 e = target; 1657 1658 } else { 1659 op->o_private = NULL; 1660 rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &e ); 1661 e_priv = op->o_private; 1662 op->o_private = o_priv; 1663 } 1664 1665 if ( e ) { 1666 if ( entry_at == slap_schema.si_ad_entry || entry_at == slap_schema.si_ad_children ) { 1667 assert( vals == NULL ); 1668 1669 rc = LDAP_SUCCESS; 1670 if ( op->o_conn && access > ACL_NONE && 1671 access_allowed( op, e, entry_at, NULL, 1672 access, &acl_state ) == 0 ) 1673 { 1674 rc = LDAP_INSUFFICIENT_ACCESS; 1675 } 1676 goto freeit; 1677 } 1678 1679 a = attr_find( e->e_attrs, entry_at ); 1680 if ( a == NULL ) { 1681 SlapReply rs = { REP_SEARCH }; 1682 AttributeName anlist[ 2 ]; 1683 1684 anlist[ 0 ].an_name = entry_at->ad_cname; 1685 anlist[ 0 ].an_desc = entry_at; 1686 BER_BVZERO( &anlist[ 1 ].an_name ); 1687 rs.sr_attrs = anlist; 1688 1689 /* NOTE: backend_operational() is also called 1690 * when returning results, so it's supposed 1691 * to do no harm to entries */ 1692 rs.sr_entry = e; 1693 rc = backend_operational( op, &rs ); 1694 1695 if ( rc == LDAP_SUCCESS ) { 1696 if ( rs.sr_operational_attrs ) { 1697 freeattr = 1; 1698 a = rs.sr_operational_attrs; 1699 1700 } else { 1701 rc = LDAP_NO_SUCH_ATTRIBUTE; 1702 } 1703 } 1704 } 1705 1706 if ( a ) { 1707 BerVarray v; 1708 1709 if ( op->o_conn && access > ACL_NONE && 1710 access_allowed( op, e, entry_at, NULL, 1711 access, &acl_state ) == 0 ) 1712 { 1713 rc = LDAP_INSUFFICIENT_ACCESS; 1714 goto freeit; 1715 } 1716 1717 i = a->a_numvals; 1718 v = op->o_tmpalloc( sizeof(struct berval) * ( i + 1 ), 1719 op->o_tmpmemctx ); 1720 for ( i = 0, j = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) 1721 { 1722 if ( op->o_conn && access > ACL_NONE && 1723 access_allowed( op, e, entry_at, 1724 &a->a_nvals[i], 1725 access, 1726 &acl_state ) == 0 ) 1727 { 1728 continue; 1729 } 1730 ber_dupbv_x( &v[j], &a->a_nvals[i], 1731 op->o_tmpmemctx ); 1732 if ( !BER_BVISNULL( &v[j] ) ) { 1733 j++; 1734 } 1735 } 1736 if ( j == 0 ) { 1737 op->o_tmpfree( v, op->o_tmpmemctx ); 1738 *vals = NULL; 1739 rc = LDAP_INSUFFICIENT_ACCESS; 1740 1741 } else { 1742 BER_BVZERO( &v[j] ); 1743 *vals = v; 1744 rc = LDAP_SUCCESS; 1745 } 1746 } 1747 freeit: if ( e != target ) { 1748 op->o_private = e_priv; 1749 be_entry_release_r( op, e ); 1750 op->o_private = o_priv; 1751 } 1752 if ( freeattr ) { 1753 attr_free( a ); 1754 } 1755 } 1756 1757 op->o_bd = be; 1758 return rc; 1759 } 1760 1761 int 1762 backend_attribute( 1763 Operation *op, 1764 Entry *target, 1765 struct berval *edn, 1766 AttributeDescription *entry_at, 1767 BerVarray *vals, 1768 slap_access_t access ) 1769 { 1770 int rc; 1771 BackendDB *be_orig; 1772 OpExtraDB oex; 1773 1774 oex.oe_db = op->o_bd; 1775 oex.oe.oe_key = (void *)backend_attribute; 1776 LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next); 1777 1778 be_orig = op->o_bd; 1779 op->o_bd = frontendDB; 1780 rc = frontendDB->be_attribute( op, target, edn, 1781 entry_at, vals, access ); 1782 op->o_bd = be_orig; 1783 LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next); 1784 1785 return rc; 1786 } 1787 1788 int 1789 backend_access( 1790 Operation *op, 1791 Entry *target, 1792 struct berval *edn, 1793 AttributeDescription *entry_at, 1794 struct berval *nval, 1795 slap_access_t access, 1796 slap_mask_t *mask ) 1797 { 1798 Entry *e = NULL; 1799 void *o_priv, *e_priv = NULL; 1800 int rc = LDAP_INSUFFICIENT_ACCESS; 1801 Backend *be; 1802 1803 /* pedantic */ 1804 assert( op != NULL ); 1805 assert( op->o_conn != NULL ); 1806 assert( edn != NULL ); 1807 assert( access > ACL_NONE ); 1808 1809 be = op->o_bd; 1810 o_priv = op->o_private; 1811 1812 if ( !op->o_bd ) { 1813 op->o_bd = select_backend( edn, 0 ); 1814 } 1815 1816 if ( target && dn_match( &target->e_nname, edn ) ) { 1817 e = target; 1818 1819 } else { 1820 op->o_private = NULL; 1821 rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &e ); 1822 e_priv = op->o_private; 1823 op->o_private = o_priv; 1824 } 1825 1826 if ( e ) { 1827 Attribute *a = NULL; 1828 int freeattr = 0; 1829 1830 if ( entry_at == NULL ) { 1831 entry_at = slap_schema.si_ad_entry; 1832 } 1833 1834 if ( entry_at == slap_schema.si_ad_entry || entry_at == slap_schema.si_ad_children ) 1835 { 1836 if ( access_allowed_mask( op, e, entry_at, 1837 NULL, access, NULL, mask ) == 0 ) 1838 { 1839 rc = LDAP_INSUFFICIENT_ACCESS; 1840 1841 } else { 1842 rc = LDAP_SUCCESS; 1843 } 1844 1845 } else { 1846 a = attr_find( e->e_attrs, entry_at ); 1847 if ( a == NULL ) { 1848 SlapReply rs = { REP_SEARCH }; 1849 AttributeName anlist[ 2 ]; 1850 1851 anlist[ 0 ].an_name = entry_at->ad_cname; 1852 anlist[ 0 ].an_desc = entry_at; 1853 BER_BVZERO( &anlist[ 1 ].an_name ); 1854 rs.sr_attrs = anlist; 1855 1856 rs.sr_attr_flags = slap_attr_flags( rs.sr_attrs ); 1857 1858 /* NOTE: backend_operational() is also called 1859 * when returning results, so it's supposed 1860 * to do no harm to entries */ 1861 rs.sr_entry = e; 1862 rc = backend_operational( op, &rs ); 1863 1864 if ( rc == LDAP_SUCCESS ) { 1865 if ( rs.sr_operational_attrs ) { 1866 freeattr = 1; 1867 a = rs.sr_operational_attrs; 1868 1869 } else { 1870 rc = LDAP_NO_SUCH_OBJECT; 1871 } 1872 } 1873 } 1874 1875 if ( a ) { 1876 if ( access_allowed_mask( op, e, entry_at, 1877 nval, access, NULL, mask ) == 0 ) 1878 { 1879 rc = LDAP_INSUFFICIENT_ACCESS; 1880 goto freeit; 1881 } 1882 rc = LDAP_SUCCESS; 1883 } 1884 } 1885 freeit: if ( e != target ) { 1886 op->o_private = e_priv; 1887 be_entry_release_r( op, e ); 1888 op->o_private = o_priv; 1889 } 1890 if ( freeattr ) { 1891 attr_free( a ); 1892 } 1893 } 1894 1895 op->o_bd = be; 1896 return rc; 1897 } 1898 1899 int 1900 fe_aux_operational( 1901 Operation *op, 1902 SlapReply *rs ) 1903 { 1904 Attribute **ap; 1905 int rc = LDAP_SUCCESS; 1906 BackendDB *be_orig = op->o_bd; 1907 OpExtra *oex; 1908 1909 LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) { 1910 if ( oex->oe_key == (void *)backend_operational ) 1911 break; 1912 } 1913 1914 for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) 1915 /* just count them */ ; 1916 1917 /* 1918 * If operational attributes (allegedly) are required, 1919 * and the backend supports specific operational attributes, 1920 * add them to the attribute list 1921 */ 1922 if ( !( rs->sr_flags & REP_NO_ENTRYDN ) 1923 && ( SLAP_OPATTRS( rs->sr_attr_flags ) || ( rs->sr_attrs && 1924 ad_inlist( slap_schema.si_ad_entryDN, rs->sr_attrs ) ) ) ) 1925 { 1926 *ap = slap_operational_entryDN( rs->sr_entry ); 1927 ap = &(*ap)->a_next; 1928 } 1929 1930 if ( !( rs->sr_flags & REP_NO_SUBSCHEMA) 1931 && ( SLAP_OPATTRS( rs->sr_attr_flags ) || ( rs->sr_attrs && 1932 ad_inlist( slap_schema.si_ad_subschemaSubentry, rs->sr_attrs ) ) ) ) 1933 { 1934 *ap = slap_operational_subschemaSubentry( op->o_bd ); 1935 ap = &(*ap)->a_next; 1936 } 1937 1938 /* Let the overlays have a chance at this */ 1939 if ( oex && ((OpExtraDB *)oex)->oe_db ) 1940 op->o_bd = ((OpExtraDB *)oex)->oe_db; 1941 1942 if ( !op->o_bd || !SLAP_DBHIDDEN( op->o_bd )) 1943 op->o_bd = select_backend( &op->o_req_ndn, 0 ); 1944 1945 if ( op->o_bd != NULL && !be_match( op->o_bd, frontendDB ) && 1946 ( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) && 1947 op->o_bd->be_operational != NULL ) 1948 { 1949 rc = op->o_bd->be_operational( op, rs ); 1950 } 1951 op->o_bd = be_orig; 1952 1953 return rc; 1954 } 1955 1956 int backend_operational( Operation *op, SlapReply *rs ) 1957 { 1958 int rc; 1959 BackendDB *be_orig; 1960 OpExtraDB oex; 1961 1962 oex.oe_db = op->o_bd; 1963 oex.oe.oe_key = (void *)backend_operational; 1964 LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next); 1965 1966 /* Moved this into the frontend so global overlays are called */ 1967 1968 be_orig = op->o_bd; 1969 op->o_bd = frontendDB; 1970 rc = frontendDB->be_operational( op, rs ); 1971 op->o_bd = be_orig; 1972 LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next); 1973 1974 return rc; 1975 } 1976 1977 /* helper that calls the bi_tool_entry_first_x() variant with default args; 1978 * use to initialize a backend's bi_tool_entry_first() when appropriate 1979 */ 1980 ID 1981 backend_tool_entry_first( BackendDB *be ) 1982 { 1983 return be->bd_info->bi_tool_entry_first_x( be, 1984 NULL, LDAP_SCOPE_DEFAULT, NULL ); 1985 } 1986