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