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