From 1f6bb31d9d8e1a95aa38c99940c9e114ed420802 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sat, 29 Apr 2006 01:26:07 +0000 Subject: [PATCH] Honor ACLs, don't just require root any more --- servers/slapd/bconfig.c | 72 ++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index fe96605739..aa6b5ace24 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -86,7 +86,7 @@ static ConfigFile *cfn; static Avlnode *CfOcTree; static int config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, - SlapReply *rs, int *renumber ); + SlapReply *rs, int *renumber, Operation *op ); static ConfigDriver config_fname; static ConfigDriver config_cfdir; @@ -2937,7 +2937,7 @@ config_ldif_resp( Operation *op, SlapReply *rs ) setup_cookie *sc = op->o_callback->sc_private; sc->cfb->cb_got_ldif = 1; - rs->sr_err = config_add_internal( sc->cfb, rs->sr_entry, sc->ca, NULL, NULL ); + rs->sr_err = config_add_internal( sc->cfb, rs->sr_entry, sc->ca, NULL, NULL, NULL ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "config error processing %s: %s\n", rs->sr_entry->e_name.bv_val, sc->ca->msg, 0 ); @@ -3559,7 +3559,8 @@ cfAddOverlay( CfEntryInfo *p, Entry *e, struct config_args_s *ca ) /* Parse an LDAP entry into config directives */ static int -config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs, int *renum ) +config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs, + int *renum, Operation *op ) { CfEntryInfo *ce, *last; ConfigOCs **colst; @@ -3585,6 +3586,15 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs, i return LDAP_NO_SUCH_OBJECT; } + if ( op ) { + /* No parent, must be root. This will never happen... */ + if ( !last && !be_isroot( op ) && !be_shadow_update( op )) + return LDAP_NO_SUCH_OBJECT; + if ( !access_allowed( op, last->ce_entry, slap_schema.si_ad_children, + NULL, ACL_WADD, NULL )) + return LDAP_INSUFFICIENT_ACCESS; + } + oc_at = attr_find( e->e_attrs, slap_schema.si_ad_objectClass ); if ( !oc_at ) return LDAP_OBJECT_CLASS_VIOLATION; @@ -3766,7 +3776,8 @@ config_back_add( Operation *op, SlapReply *rs ) int renumber; ConfigArgs ca; - if ( !be_isroot( op ) ) { + if ( !access_allowed( op, op->ora_e, slap_schema.si_ad_entry, + NULL, ACL_WADD, NULL )) { rs->sr_err = LDAP_INSUFFICIENT_ACCESS; goto out; } @@ -3784,7 +3795,7 @@ config_back_add( Operation *op, SlapReply *rs ) */ /* NOTE: by now we do not accept adds that require renumbering */ renumber = -1; - rs->sr_err = config_add_internal( cfb, op->ora_e, &ca, rs, &renumber ); + rs->sr_err = config_add_internal( cfb, op->ora_e, &ca, rs, &renumber, op ); if ( rs->sr_err != LDAP_SUCCESS ) { rs->sr_text = ca.msg; goto out2; @@ -4103,11 +4114,6 @@ config_back_modify( Operation *op, SlapReply *rs ) char *ptr; AttributeDescription *rad = NULL; - if ( !be_isroot( op ) ) { - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - goto out; - } - cfb = (CfBackInfo *)op->o_bd->be_private; ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last ); @@ -4118,6 +4124,11 @@ config_back_modify( Operation *op, SlapReply *rs ) goto out; } + if ( !acl_check_modlist( op, ce->ce_entry, op->orm_modlist )) { + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + goto out; + } + /* Get type of RDN */ rdn = ce->ce_entry->e_nname; ptr = strchr( rdn.bv_val, '=' ); @@ -4178,11 +4189,6 @@ config_back_modrdn( Operation *op, SlapReply *rs ) CfBackInfo *cfb; CfEntryInfo *ce, *last; - if ( !be_isroot( op ) ) { - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - goto out; - } - cfb = (CfBackInfo *)op->o_bd->be_private; ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last ); @@ -4192,6 +4198,22 @@ config_back_modrdn( Operation *op, SlapReply *rs ) rs->sr_err = LDAP_NO_SUCH_OBJECT; goto out; } + if ( !access_allowed( op, ce->ce_entry, slap_schema.si_ad_entry, + NULL, ACL_WRITE, NULL )) { + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + goto out; + } + { Entry *parent; + if ( ce->ce_parent ) + parent = ce->ce_parent->ce_entry; + else + parent = (Entry *)&slap_entry_root; + if ( !access_allowed( op, parent, slap_schema.si_ad_children, + NULL, ACL_WRITE, NULL )) { + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + goto out; + } + } /* We don't allow moving objects to new parents. * Generally we only allow reordering a set of ordered entries. @@ -4216,11 +4238,7 @@ config_back_search( Operation *op, SlapReply *rs ) { CfBackInfo *cfb; CfEntryInfo *ce, *last; - - if ( !be_isroot( op ) ) { - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - goto out; - } + slap_mask_t mask; cfb = (CfBackInfo *)op->o_bd->be_private; @@ -4231,6 +4249,16 @@ config_back_search( Operation *op, SlapReply *rs ) rs->sr_err = LDAP_NO_SUCH_OBJECT; goto out; } + if ( !access_allowed_mask( op, ce->ce_entry, slap_schema.si_ad_entry, NULL, + ACL_SEARCH, NULL, &mask )) + { + if ( !ACL_GRANT( mask, ACL_DISCLOSE )) { + rs->sr_err = LDAP_NO_SUCH_OBJECT; + } else { + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + } + goto out; + } switch ( op->ors_scope ) { case LDAP_SCOPE_BASE: case LDAP_SCOPE_SUBTREE: @@ -4847,7 +4875,7 @@ config_tool_entry_put( BackendDB *be, Entry *e, struct berval *text ) ConfigArgs ca; if ( bi && bi->bi_tool_entry_put && - config_add_internal( cfb, e, &ca, NULL, NULL ) == 0 ) + config_add_internal( cfb, e, &ca, NULL, NULL, NULL ) == 0 ) return bi->bi_tool_entry_put( &cfb->cb_db, e, text ); else return NOID; @@ -4930,7 +4958,7 @@ config_back_initialize( BackendInfo *bi ) bi->bi_chk_referrals = 0; - bi->bi_access_allowed = slap_access_always_allowed; + bi->bi_access_allowed = slap_access_allowed; bi->bi_connection_init = 0; bi->bi_connection_destroy = 0; -- 2.39.2