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