From 1375454b842450a75cc64ded83d3003294b9cb88 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sat, 27 May 2006 10:58:52 +0000 Subject: [PATCH] ITS#4552 from HEAD - use ACLs to control adding suffix entry or children of virtual suffix. --- doc/man/man5/slapd.access.5 | 13 +++ servers/slapd/back-bdb/add.c | 161 ++++++++++++++++------------------- 2 files changed, 88 insertions(+), 86 deletions(-) diff --git a/doc/man/man5/slapd.access.5 b/doc/man/man5/slapd.access.5 index cdd08fa715..0cbd3c8dac 100644 --- a/doc/man/man5/slapd.access.5 +++ b/doc/man/man5/slapd.access.5 @@ -1,6 +1,7 @@ .TH SLAPD.ACCESS 5 "RELEASEDATE" "OpenLDAP LDVERSION" .\" Copyright 1998-2006 The OpenLDAP Foundation All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. +.\" $OpenLDAP$ .SH NAME slapd.access \- access configuration for slapd, the stand-alone LDAP daemon .SH SYNOPSIS @@ -826,11 +827,13 @@ as the first access rule. As a consequence, unless the operation is performed with the .B updatedn identity, control is passed straight to the subsequent rules. + .SH OPERATION REQUIREMENTS Operations require different privileges on different portions of entries. The following summary applies to primary database backends such as the BDB and HDB backends. Requirements for other backends may (and often do) differ. + .LP The .B add @@ -843,6 +846,10 @@ of the entry being added, and privileges on the pseudo-attribute .B children of the entry's parent. +When adding the suffix entry of a database, write access to +.B children +of the empty DN ("") is required. + .LP The .B bind @@ -850,12 +857,14 @@ operation, when credentials are stored in the directory, requires .B auth (=x) privileges on the attribute the credentials are stored in (usually .BR userPassword ). + .LP The .B compare operation requires .B compare (=c) privileges on the attribute that is being compared. + .LP The .B delete @@ -868,12 +877,14 @@ of the entry being deleted, and privileges on the .B children pseudo-attribute of the entry's parent. + .LP The .B modify operation requires .B write (=w) privileges on the attributes being modified. + .LP The .B modrdn @@ -893,6 +904,7 @@ privileges are also required on the attributes that are present in the old relative DN if .B deleteoldrdn is set to 1. + .LP The .B search @@ -925,6 +937,7 @@ access to the attribute holding the referral information (generally the .B ref attribute). + .LP Some internal operations and some .B controls diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index 9a57f7c5a8..7642e235df 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -83,7 +83,9 @@ bdb_add(Operation *op, SlapReply *rs ) retry: /* transaction retry */ if( p ) { /* free parent and reader lock */ - bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); + if ( p != (Entry *)&slap_entry_root ) { + bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); + } p = NULL; } rs->sr_err = TXN_ABORT( ltid ); @@ -155,102 +157,89 @@ retry: /* transaction retry */ } p = ei->bei_e; - if ( p ) { - if ( !bvmatch( &pdn, &p->e_nname ) ) { - rs->sr_matched = ber_strdup_x( p->e_name.bv_val, - op->o_tmpmemctx ); - rs->sr_ref = is_entry_referral( p ) - ? get_entry_referrals( op, p ) - : NULL; - bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); - p = NULL; - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(bdb_add) ": parent " - "does not exist\n", 0, 0, 0 ); - - rs->sr_err = LDAP_REFERRAL; - rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; - goto return_results; - } - - rs->sr_err = access_allowed( op, p, - children, NULL, ACL_WADD, NULL ); + if ( !p ) + p = (Entry *)&slap_entry_root; + + if ( !bvmatch( &pdn, &p->e_nname ) ) { + rs->sr_matched = ber_strdup_x( p->e_name.bv_val, + op->o_tmpmemctx ); + rs->sr_ref = is_entry_referral( p ) + ? get_entry_referrals( op, p ) + : NULL; + bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); + p = NULL; + Debug( LDAP_DEBUG_TRACE, + LDAP_XSTRING(bdb_add) ": parent " + "does not exist\n", 0, 0, 0 ); - if ( ! rs->sr_err ) { - switch( opinfo.boi_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } + rs->sr_err = LDAP_REFERRAL; + rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; + goto return_results; + } - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(bdb_add) ": no write access to parent\n", - 0, 0, 0 ); - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - rs->sr_text = "no write access to parent"; - goto return_results;; - } + rs->sr_err = access_allowed( op, p, + children, NULL, ACL_WADD, NULL ); - if ( is_entry_subentry( p ) ) { - /* parent is a subentry, don't allow add */ - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(bdb_add) ": parent is subentry\n", - 0, 0, 0 ); - rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION; - rs->sr_text = "parent is a subentry"; - goto return_results;; - } - if ( is_entry_alias( p ) ) { - /* parent is an alias, don't allow add */ - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(bdb_add) ": parent is alias\n", - 0, 0, 0 ); - rs->sr_err = LDAP_ALIAS_PROBLEM; - rs->sr_text = "parent is an alias"; - goto return_results;; + if ( ! rs->sr_err ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; } - if ( is_entry_referral( p ) ) { - /* parent is a referral, don't allow add */ - rs->sr_matched = ber_strdup_x( p->e_name.bv_val, - op->o_tmpmemctx ); - rs->sr_ref = get_entry_referrals( op, p ); - bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); - p = NULL; - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(bdb_add) ": parent is referral\n", - 0, 0, 0 ); - - rs->sr_err = LDAP_REFERRAL; - rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; - goto return_results; - } + Debug( LDAP_DEBUG_TRACE, + LDAP_XSTRING(bdb_add) ": no write access to parent\n", + 0, 0, 0 ); + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + rs->sr_text = "no write access to parent"; + goto return_results;; + } - if ( subentry ) { - /* FIXME: */ - /* parent must be an administrative point of the required kind */ - } + if ( is_entry_subentry( p ) ) { + /* parent is a subentry, don't allow add */ + Debug( LDAP_DEBUG_TRACE, + LDAP_XSTRING(bdb_add) ": parent is subentry\n", + 0, 0, 0 ); + rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION; + rs->sr_text = "parent is a subentry"; + goto return_results;; + } + if ( is_entry_alias( p ) ) { + /* parent is an alias, don't allow add */ + Debug( LDAP_DEBUG_TRACE, + LDAP_XSTRING(bdb_add) ": parent is alias\n", + 0, 0, 0 ); + rs->sr_err = LDAP_ALIAS_PROBLEM; + rs->sr_text = "parent is an alias"; + goto return_results;; + } - /* free parent and reader lock */ + if ( is_entry_referral( p ) ) { + /* parent is a referral, don't allow add */ + rs->sr_matched = ber_strdup_x( p->e_name.bv_val, + op->o_tmpmemctx ); + rs->sr_ref = get_entry_referrals( op, p ); bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); p = NULL; + Debug( LDAP_DEBUG_TRACE, + LDAP_XSTRING(bdb_add) ": parent is referral\n", + 0, 0, 0 ); - } else { - /* - * no parent! - * if not attempting to add entry at suffix or with parent "" - */ - if ((( !be_isroot( op ) && !be_shadow_update(op) ) - || pdn.bv_len > 0 ) && !is_entry_glue( op->oq_add.rs_e )) - { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(bdb_add) ": %s denied\n", - pdn.bv_len == 0 ? "suffix" : "entry at root", - 0, 0 ); - rs->sr_err = LDAP_NO_SUCH_OBJECT; - goto return_results; - } + rs->sr_err = LDAP_REFERRAL; + rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; + goto return_results; + } + + if ( subentry ) { + /* FIXME: */ + /* parent must be an administrative point of the required kind */ + } + + /* free parent and reader lock */ + if ( p != (Entry *)&slap_entry_root ) { + bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); } + p = NULL; rs->sr_err = access_allowed( op, op->oq_add.rs_e, entry, NULL, ACL_WADD, NULL ); -- 2.39.2