From: Kurt Zeilenga Date: Thu, 10 Oct 2002 03:47:28 +0000 (+0000) Subject: "entry" ACLs for add/delete/rename X-Git-Tag: OPENLDAP_REL_ENG_2_1_6~12 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=ce843b8ff0b11cdee7b78305fc8e1cdf2da8e65a;p=openldap "entry" ACLs for add/delete/rename --- diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index d00d88d0c5..76fac90435 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -28,6 +28,7 @@ bdb_add( char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof textbuf; AttributeDescription *children = slap_schema.si_ad_children; + AttributeDescription *entry = slap_schema.si_ad_entry; DB_TXN *ltid = NULL; struct bdb_op_info opinfo; #ifdef BDB_SUBENTRIES @@ -86,6 +87,11 @@ bdb_add( if( 0 ) { retry: /* transaction retry */ + if( p ) { + /* free parent and reader lock */ + bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); + p = NULL; + } rc = TXN_ABORT( ltid ); ltid = NULL; op->o_private = NULL; @@ -208,9 +214,6 @@ retry: /* transaction retry */ switch( opinfo.boi_err ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: - /* free parent and reader lock */ - bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); - p = NULL; goto retry; } @@ -298,12 +301,14 @@ retry: /* transaction retry */ */ if ( !be_isroot( be, &op->o_ndn )) { if ( be_issuffix( be, (struct berval *)&slap_empty_bv ) - || be_isupdate( be, &op->o_ndn ) ) { + || be_isupdate( be, &op->o_ndn ) ) + { p = (Entry *)&slap_entry_root; /* check parent for "children" acl */ rc = access_allowed( be, conn, op, p, children, NULL, ACL_WRITE, NULL ); + p = NULL; switch( opinfo.boi_err ) { @@ -366,6 +371,28 @@ retry: /* transaction retry */ #endif } + rc = access_allowed( be, conn, op, e, + entry, NULL, ACL_WRITE, NULL ); + + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + + if ( ! rc ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, DETAIL1, + "bdb_add: no write access to entry\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "bdb_add: no write access to entry\n", + 0, 0, 0 ); +#endif + rc = LDAP_INSUFFICIENT_ACCESS; + text = "no write access to entry"; + goto return_results;; + } + /* dn2id index */ rc = bdb_dn2id_add( be, ltid, &pdn, e ); if ( rc != 0 ) { diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 6052c6ea91..5a19eb1e59 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -31,6 +31,7 @@ bdb_delete( const char *text; int manageDSAit = get_manageDSAit( op ); AttributeDescription *children = slap_schema.si_ad_children; + AttributeDescription *entry = slap_schema.si_ad_entry; DB_TXN *ltid = NULL; struct bdb_op_info opinfo; @@ -165,13 +166,14 @@ retry: /* transaction retry */ if ( !rc ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, - "<=- bdb_delete: no access to parent\n", 0, 0, 0 ); + "<=- bdb_delete: no write access to parent\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, - "<=- bdb_delete: no access to parent\n", + "<=- bdb_delete: no write access to parent\n", 0, 0, 0 ); #endif rc = LDAP_INSUFFICIENT_ACCESS; + text = "no write access to parent"; goto return_results; } @@ -185,6 +187,7 @@ retry: /* transaction retry */ /* check parent for "children" acl */ rc = access_allowed( be, conn, op, p, children, NULL, ACL_WRITE, NULL ); + p = NULL; switch( opinfo.boi_err ) { @@ -203,6 +206,7 @@ retry: /* transaction retry */ "to parent\n", 0, 0, 0 ); #endif rc = LDAP_INSUFFICIENT_ACCESS; + text = "no write access to parent"; goto return_results; } @@ -286,6 +290,29 @@ retry: /* transaction retry */ goto done; } + rc = access_allowed( be, conn, op, e, + entry, NULL, ACL_WRITE, NULL ); + + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + + if ( !rc ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, DETAIL1, + "<=- bdb_delete: no write access to entry\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "<=- bdb_delete: no write access to entry\n", + 0, 0, 0 ); +#endif + rc = LDAP_INSUFFICIENT_ACCESS; + text = "no write access to entry"; + goto return_results; + } + if ( !manageDSAit && is_entry_referral( e ) ) { /* entry is a referral, don't allow delete */ BerVarray refs = get_entry_referrals( be, diff --git a/servers/slapd/back-bdb/group.c b/servers/slapd/back-bdb/group.c index 20b768bbdb..ad9b979b5b 100644 --- a/servers/slapd/back-bdb/group.c +++ b/servers/slapd/back-bdb/group.c @@ -30,8 +30,7 @@ bdb_group( struct berval *gr_ndn, struct berval *op_ndn, ObjectClass *group_oc, - AttributeDescription *group_at -) + AttributeDescription *group_at ) { struct bdb_info *bdb = (struct bdb_info *) be->be_private; struct bdb_op_info *boi = NULL; @@ -58,18 +57,19 @@ bdb_group( op_ndn->bv_val, gr_ndn->bv_val, group_oc_name ); #else Debug( LDAP_DEBUG_ARGS, - "=> bdb_group: gr dn: \"%s\"\n", + "=> bdb_group: group ndn: \"%s\"\n", gr_ndn->bv_val, 0, 0 ); Debug( LDAP_DEBUG_ARGS, - "=> bdb_group: op dn: \"%s\"\n", + "=> bdb_group: op ndn: \"%s\"\n", op_ndn->bv_val, 0, 0 ); + Debug( LDAP_DEBUG_ARGS, "=> bdb_group: oc: \"%s\" at: \"%s\"\n", group_oc_name, group_at_name, 0 ); Debug( LDAP_DEBUG_ARGS, - "=> bdb_group: tr dn: \"%s\"\n", + "=> bdb_group: tr ndn: \"%s\"\n", target->e_ndn, 0, 0 ); #endif diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index 54b6de974e..6017044122 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -28,6 +28,7 @@ bdb_modrdn( { struct bdb_info *bdb = (struct bdb_info *) be->be_private; AttributeDescription *children = slap_schema.si_ad_children; + AttributeDescription *entry = slap_schema.si_ad_entry; struct berval p_dn, p_ndn; struct berval new_dn = {0, NULL}, new_ndn = {0, NULL}; int isroot = -1; @@ -177,6 +178,28 @@ retry: /* transaction retry */ goto done; } + /* check write on old entry */ + rc = access_allowed( be, conn, op, e, + entry, NULL, ACL_WRITE, NULL ); + + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + + if ( ! rc ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "==>bdb_modrdn: no access to entry\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "no access to entry\n", 0, + 0, 0 ); +#endif + rc = LDAP_INSUFFICIENT_ACCESS; + goto return_results; + } + if (!manageDSAit && is_entry_referral( e ) ) { /* parent is a referral, don't allow add */ /* parent is an alias, don't allow add */ @@ -536,7 +559,7 @@ retry: /* transaction retry */ new_parent_dn = np_dn; } - + /* Build target dn and make sure target entry doesn't exist already. */ build_new_dn( &new_dn, new_parent_dn, newrdn ); diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c index 65d1d11370..d6ac6fb83d 100644 --- a/servers/slapd/back-ldbm/add.c +++ b/servers/slapd/back-ldbm/add.c @@ -31,6 +31,7 @@ ldbm_back_add( ID id = NOID; const char *text = NULL; AttributeDescription *children = slap_schema.si_ad_children; + AttributeDescription *entry = slap_schema.si_ad_entry; char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof textbuf; @@ -40,23 +41,8 @@ ldbm_back_add( Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0); #endif - /* grab giant lock for writing */ - ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); - - if ( ( rc = dn2id( be, &e->e_nname, &id ) ) || id != NOID ) { - /* if (rc) something bad happened to ldbm cache */ - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - send_ldap_result( conn, op, - rc ? LDAP_OTHER : LDAP_ALREADY_EXISTS, - NULL, NULL, NULL, NULL ); - return( -1 ); - } - rc = entry_schema_check( be, e, NULL, &text, textbuf, textlen ); - if ( rc != LDAP_SUCCESS ) { - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - #ifdef NEW_LOGGING LDAP_LOG( BACK_LDBM, ERR, "ldbm_back_add: entry (%s) failed schema check.\n", e->e_dn, 0, 0 ); @@ -70,6 +56,36 @@ ldbm_back_add( return( -1 ); } + if ( ! access_allowed( be, conn, op, e, + entry, NULL, ACL_WRITE, NULL ) ) + { +#ifdef NEW_LOGGING + LDAP_LOG( BACK_LDBM, ERR, + "ldbm_back_add: No write access to entry (%s).\n", + e->e_dn, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "no write access to entry\n", 0, + 0, 0 ); +#endif + + send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, + NULL, "no write access to entry", NULL, NULL ); + + return -1; + } + + /* grab giant lock for writing */ + ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); + + if ( ( rc = dn2id( be, &e->e_nname, &id ) ) || id != NOID ) { + /* if (rc) something bad happened to ldbm cache */ + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + send_ldap_result( conn, op, + rc ? LDAP_OTHER : LDAP_ALREADY_EXISTS, + NULL, NULL, NULL, NULL ); + return( -1 ); + } + /* * Get the parent dn and see if the corresponding entry exists. * If the parent does not exist, only allow the "root" user to diff --git a/servers/slapd/back-ldbm/delete.c b/servers/slapd/back-ldbm/delete.c index d33e957f67..1622554140 100644 --- a/servers/slapd/back-ldbm/delete.c +++ b/servers/slapd/back-ldbm/delete.c @@ -32,6 +32,7 @@ ldbm_back_delete( int rc = -1; int manageDSAit = get_manageDSAit( op ); AttributeDescription *children = slap_schema.si_ad_children; + AttributeDescription *entry = slap_schema.si_ad_entry; #ifdef NEW_LOGGING LDAP_LOG( BACK_LDBM, ENTRY, "ldbm_back_delete: %s\n", dn->bv_val, 0, 0 ); @@ -78,6 +79,27 @@ ldbm_back_delete( return( -1 ); } + /* check entry for "entry" acl */ + if ( ! access_allowed( be, conn, op, e, + entry, NULL, ACL_WRITE, NULL ) ) + { +#ifdef NEW_LOGGING + LDAP_LOG( BACK_LDBM, ERR, + "ldbm_back_delete: no write access to entry of (%s)\n", + dn->bv_val, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "<=- ldbm_back_delete: no write access to entry\n", 0, + 0, 0 ); +#endif + + send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, + NULL, "no write access to entry", NULL, NULL ); + + rc = 1; + goto return_results; + } + if ( !manageDSAit && is_entry_referral( e ) ) { /* parent is a referral, don't allow add */ /* parent is an alias, don't allow add */ @@ -101,7 +123,6 @@ ldbm_back_delete( goto return_results; } - if ( has_children( be, e ) ) { #ifdef NEW_LOGGING LDAP_LOG( BACK_LDBM, ERR, @@ -149,7 +170,7 @@ ldbm_back_delete( #endif send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, - NULL, NULL, NULL, NULL ); + NULL, "no write access to parent", NULL, NULL ); goto return_results; } @@ -175,9 +196,8 @@ ldbm_back_delete( "access to parent\n", 0, 0, 0 ); #endif - send_ldap_result( conn, op, - LDAP_INSUFFICIENT_ACCESS, - NULL, NULL, NULL, NULL ); + send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, + NULL, "no write access to parent", NULL, NULL ); goto return_results; } diff --git a/servers/slapd/back-ldbm/modrdn.c b/servers/slapd/back-ldbm/modrdn.c index 5ba4e9afb6..f71cfc6150 100644 --- a/servers/slapd/back-ldbm/modrdn.c +++ b/servers/slapd/back-ldbm/modrdn.c @@ -47,6 +47,7 @@ ldbm_back_modrdn( ) { AttributeDescription *children = slap_schema.si_ad_children; + AttributeDescription *entry = slap_schema.si_ad_entry; struct ldbminfo *li = (struct ldbminfo *) be->be_private; struct berval p_dn, p_ndn; struct berval new_dn = { 0, NULL}, new_ndn = { 0, NULL }; @@ -115,6 +116,26 @@ ldbm_back_modrdn( return( -1 ); } + /* check entry for "entry" acl */ + if ( ! access_allowed( be, conn, op, e, + entry, NULL, ACL_WRITE, NULL ) ) + { +#ifdef NEW_LOGGING + LDAP_LOG( BACK_LDBM, ERR, + "ldbm_back_modrdn: no write access to entry of (%s)\n", + dn->bv_val, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "<=- ldbm_back_modrdn: no write access to entry\n", 0, + 0, 0 ); +#endif + + send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, + NULL, "no write access to entry", NULL, NULL ); + + goto return_results; + } + if (!manageDSAit && is_entry_referral( e ) ) { /* parent is a referral, don't allow add */ /* parent is an alias, don't allow add */