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