diff --git a/dirsrvtests/tests/suites/acl/misc_test.py b/dirsrvtests/tests/suites/acl/misc_test.py index 5f0e3eb72f..c640e60ad9 100644 --- a/dirsrvtests/tests/suites/acl/misc_test.py +++ b/dirsrvtests/tests/suites/acl/misc_test.py @@ -12,7 +12,7 @@ import os import pytest -from lib389._constants import DEFAULT_SUFFIX, PW_DM +from lib389._constants import DEFAULT_SUFFIX, PW_DM, DN_DM from lib389.idm.user import UserAccount, UserAccounts from lib389._mapped_object import DSLdapObject from lib389.idm.account import Accounts, Anonymous @@ -408,14 +408,112 @@ def test_do_bind_as_201_distinct_users(topo, clean, aci_of_user): user = uas.create_test_user(uid=i, gid=i) user.set('userPassword', PW_DM) - for i in range(len(uas.list())): - uas.list()[i].bind(PW_DM) + users = uas.list() + for user in users: + user.bind(PW_DM) ACLPlugin(topo.standalone).replace("nsslapd-aclpb-max-selected-acls", '220') topo.standalone.restart() - for i in range(len(uas.list())): - uas.list()[i].bind(PW_DM) + users = uas.list() + for user in users: + user.bind(PW_DM) + + +def test_info_disclosure(request, topo): + """Test that a search returns 32 when base entry does not exist + + :id: f6dec4c2-65a3-41e4-a4c0-146196863333 + :setup: Standalone Instance + :steps: + 1. Add aci + 2. Add test user + 3. Bind as user and search for non-existent entry + :expectedresults: + 1. Success + 2. Success + 3. Error 32 is returned + """ + + ACI_TARGET = "(targetattr = \"*\")(target = \"ldap:///%s\")" % (DEFAULT_SUFFIX) + ACI_ALLOW = "(version 3.0; acl \"Read/Search permission for all users\"; allow (read,search)" + ACI_SUBJECT = "(userdn=\"ldap:///all\");)" + ACI = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT + + # Get current ACi's so we can restore them when we are done + suffix = Domain(topo.standalone, DEFAULT_SUFFIX) + preserved_acis = suffix.get_attr_vals_utf8('aci') + + def finofaci(): + domain = Domain(topo.standalone, DEFAULT_SUFFIX) + try: + domain.remove_all('aci') + domain.replace_values('aci', preserved_acis) + except: + pass + request.addfinalizer(finofaci) + + # Remove aci's + suffix.remove_all('aci') + + # Add test user + USER_DN = "uid=test,ou=people," + DEFAULT_SUFFIX + users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) + users.create(properties={ + 'uid': 'test', + 'cn': 'test', + 'sn': 'test', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/test', + 'userPassword': PW_DM + }) + + # bind as user + conn = UserAccount(topo.standalone, USER_DN).bind(PW_DM) + + # Search fo existing base DN + test = Domain(conn, DEFAULT_SUFFIX) + try: + test.get_attr_vals_utf8_l('dc') + assert False + except IndexError: + pass + + # Search for a non existent bases + subtree = Domain(conn, "ou=does_not_exist," + DEFAULT_SUFFIX) + try: + subtree.get_attr_vals_utf8_l('objectclass') + except IndexError: + pass + subtree = Domain(conn, "ou=also does not exist,ou=does_not_exist," + DEFAULT_SUFFIX) + try: + subtree.get_attr_vals_utf8_l('objectclass') + except IndexError: + pass + # Try ONE level search instead of BASE + try: + Accounts(conn, "ou=does_not_exist," + DEFAULT_SUFFIX).filter("(objectclass=top)", ldap.SCOPE_ONELEVEL) + except IndexError: + pass + + # add aci + suffix.add('aci', ACI) + + # Search for a non existent entry which should raise an exception + with pytest.raises(ldap.NO_SUCH_OBJECT): + conn = UserAccount(topo.standalone, USER_DN).bind(PW_DM) + subtree = Domain(conn, "ou=does_not_exist," + DEFAULT_SUFFIX) + subtree.get_attr_vals_utf8_l('objectclass') + with pytest.raises(ldap.NO_SUCH_OBJECT): + conn = UserAccount(topo.standalone, USER_DN).bind(PW_DM) + subtree = Domain(conn, "ou=also does not exist,ou=does_not_exist," + DEFAULT_SUFFIX) + subtree.get_attr_vals_utf8_l('objectclass') + with pytest.raises(ldap.NO_SUCH_OBJECT): + conn = UserAccount(topo.standalone, USER_DN).bind(PW_DM) + DN = "ou=also does not exist,ou=does_not_exist," + DEFAULT_SUFFIX + Accounts(conn, DN).filter("(objectclass=top)", ldap.SCOPE_ONELEVEL, strict=True) + if __name__ == "__main__": CURRENT_FILE = os.path.realpath(__file__) diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c index e9246b2aa2..83af9fd1dd 100644 --- a/ldap/servers/plugins/acl/acl.c +++ b/ldap/servers/plugins/acl/acl.c @@ -2111,10 +2111,11 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a aci_right = aci->aci_access; res_right = aclpb->aclpb_access; if (!(aci_right & res_right)) { - /* If we are looking for read/search and the acl has read/search - ** then go further because if targets match we may keep that - ** acl in the entry cache list. - */ + /* + * If we are looking for read/search and the acl has read/search + * then go further because if targets match we may keep that + * acl in the entry cache list. + */ if (!((res_right & (SLAPI_ACL_SEARCH | SLAPI_ACL_READ)) && (aci_right & (SLAPI_ACL_SEARCH | SLAPI_ACL_READ)))) { matches = ACL_FALSE; @@ -2122,30 +2123,29 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a } } - - /* first Let's see if the entry is under the subtree where the - ** ACL resides. We can't let somebody affect a target beyond the - ** scope of where the ACL resides - ** Example: ACL is located in "ou=engineering, o=ace industry, c=us - ** but if the target is "o=ace industry, c=us", then we are in trouble. - ** - ** If the aci is in the rootdse and the entry is not, then we do not - ** match--ie. acis in the rootdse do NOT apply below...for the moment. - ** - */ + /* + * First Let's see if the entry is under the subtree where the + * ACL resides. We can't let somebody affect a target beyond the + * scope of where the ACL resides + * Example: ACL is located in "ou=engineering, o=ace industry, c=us + * but if the target is "o=ace industry, c=us", then we are in trouble. + * + * If the aci is in the rootdse and the entry is not, then we do not + * match--ie. acis in the rootdse do NOT apply below...for the moment. + */ res_ndn = slapi_sdn_get_ndn(aclpb->aclpb_curr_entry_sdn); aci_ndn = slapi_sdn_get_ndn(aci->aci_sdn); - if (!slapi_sdn_issuffix(aclpb->aclpb_curr_entry_sdn, aci->aci_sdn) || (!slapi_is_rootdse(res_ndn) && slapi_is_rootdse(aci_ndn))) { - - /* cant' poke around */ + if (!slapi_sdn_issuffix(aclpb->aclpb_curr_entry_sdn, aci->aci_sdn) || + (!slapi_is_rootdse(res_ndn) && slapi_is_rootdse(aci_ndn))) + { + /* can't poke around */ matches = ACL_FALSE; goto acl__resource_match_aci_EXIT; } /* - ** We have a single ACI which we need to find if it applies to - ** the resource or not. - */ + * We have a single ACI which we need to find if it applies to the resource or not. + */ if ((aci->aci_type & ACI_TARGET_DN) && (aclpb->aclpb_curr_entry_sdn)) { char *avaType; struct berval *avaValue; @@ -2173,25 +2173,23 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a char *avaType; struct berval *avaValue; char logbuf[1024]; - - /* We are evaluating the moddn permission. - * The aci contains target_to and target_from - * - * target_to filter must be checked against the resource ndn that was stored in - * aclpb->aclpb_curr_entry_sdn - * - * target_from filter must be check against the entry ndn that is in aclpb->aclpb_moddn_source_sdn - * (sdn was stored in the pblock) - */ + /* + * We are evaluating the moddn permission. + * The aci contains target_to and target_from + * + * target_to filter must be checked against the resource ndn that was stored in + * aclpb->aclpb_curr_entry_sdn + * + * target_from filter must be check against the entry ndn that is in aclpb->aclpb_moddn_source_sdn + * (sdn was stored in the pblock) + */ if (aci->target_to) { f = aci->target_to; dn_matched = ACL_TRUE; /* Now check if the filter is a simple or substring filter */ if (aci->aci_type & ACI_TARGET_MODDN_TO_PATTERN) { - /* This is a filter with substring - * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com - */ + /* This is a filter with substring e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com */ slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_to substring: %s\n", slapi_filter_to_string(f, logbuf, sizeof(logbuf))); if ((rv = acl_match_substring(f, (char *)res_ndn, 0 /* match suffix */)) != ACL_TRUE) { @@ -2204,9 +2202,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a } } } else { - /* This is a filter without substring - * e.g. ldap:///cn=accounts,dc=example,dc=com - */ + /* This is a filter without substring e.g. ldap:///cn=accounts,dc=example,dc=com */ slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_to: %s\n", slapi_filter_to_string(f, logbuf, sizeof(logbuf))); slapi_filter_get_ava(f, &avaType, &avaValue); @@ -2230,8 +2226,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a /* Now check if the filter is a simple or substring filter */ if (aci->aci_type & ACI_TARGET_MODDN_FROM_PATTERN) { /* This is a filter with substring - * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com - */ + * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com + */ slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_from substring: %s\n", slapi_filter_to_string(f, logbuf, sizeof(logbuf))); if ((rv = acl_match_substring(f, (char *)slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn), 0 /* match suffix */)) != ACL_TRUE) { @@ -2243,11 +2239,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a goto acl__resource_match_aci_EXIT; } } - } else { - /* This is a filter without substring - * e.g. ldap:///cn=accounts,dc=example,dc=com - */ + /* This is a filter without substring e.g. ldap:///cn=accounts,dc=example,dc=com */ slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_from: %s\n", slapi_filter_to_string(f, logbuf, sizeof(logbuf))); if (!slapi_dn_issuffix(slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn), avaValue->bv_val)) { @@ -2269,10 +2262,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a } if (aci->aci_type & ACI_TARGET_PATTERN) { - f = aci->target; dn_matched = ACL_TRUE; - if ((rv = acl_match_substring(f, (char *)res_ndn, 0 /* match suffux */)) != ACL_TRUE) { dn_matched = ACL_FALSE; if (rv == ACL_ERR) { @@ -2296,7 +2287,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a /* * Is it a (target="ldap://cn=*,($dn),o=sun.com") kind of thing. - */ + */ if (aci->aci_type & ACI_TARGET_MACRO_DN) { /* * See if the ($dn) component matches the string and @@ -2306,8 +2297,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a * entry is the same one don't recalculate it-- * this flag only works for search right now, could * also optimise for mods by making it work for mods. - */ - + */ if ((aclpb->aclpb_res_type & ACLPB_NEW_ENTRY) == 0) { /* * Here same entry so just look up the matched value, @@ -2356,8 +2346,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a * If there is already an entry for this aci in this * aclpb then remove it--it's an old value for a * different entry. - */ - + */ acl_ht_add_and_freeOld(aclpb->aclpb_macro_ht, (PLHashNumber)aci->aci_index, matched_val); @@ -2381,30 +2370,27 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a } /* - ** Here, if there's a targetfilter field, see if it matches. - ** - ** The commented out code below was an erroneous attempt to skip - ** this test. It is wrong because: 1. you need to store - ** whether the last test matched or not (you cannot just assume it did) - ** and 2. It may not be the same aci, so the previous matched - ** value is a function of the aci. - ** May be interesting to build such a cache...but no evidence for - ** for that right now. See Bug 383424. - ** - ** - ** && ((aclpb->aclpb_state & ACLPB_SEARCH_BASED_ON_LIST) || - ** (aclpb->aclpb_res_type & ACLPB_NEW_ENTRY)) - */ + * Here, if there's a targetfilter field, see if it matches. + * + * The commented out code below was an erroneous attempt to skip + * this test. It is wrong because: 1. you need to store + * whether the last test matched or not (you cannot just assume it did) + * and 2. It may not be the same aci, so the previous matched + * value is a function of the aci. + * May be interesting to build such a cache...but no evidence for + * for that right now. See Bug 383424. + * + * + * && ((aclpb->aclpb_state & ACLPB_SEARCH_BASED_ON_LIST) || + * (aclpb->aclpb_res_type & ACLPB_NEW_ENTRY)) + */ if (aci->aci_type & ACI_TARGET_FILTER) { int filter_matched = ACL_TRUE; - /* * Check for macros. * For targetfilter we need to fake the lasinfo structure--it's * created "naturally" for subjects but not targets. - */ - - + */ if (aci->aci_type & ACI_TARGET_FILTER_MACRO_DN) { lasInfo *lasinfo = NULL; @@ -2419,11 +2405,9 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a ACL_EVAL_TARGET_FILTER); slapi_ch_free((void **)&lasinfo); } else { - - if (slapi_vattr_filter_test(NULL, aclpb->aclpb_curr_entry, aci->targetFilter, - 0 /*don't do acess chk*/) != 0) { + 0 /*don't do access check*/) != 0) { filter_matched = ACL_FALSE; } } @@ -2450,7 +2434,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a * Check to see if we need to evaluate any targetattrfilters. * They look as follows: * (targetattrfilters="add=sn:(sn=rob) && gn:(gn!=byrne), - * del=sn:(sn=rob) && gn:(gn=byrne)") + * del=sn:(sn=rob) && gn:(gn=byrne)") * * For ADD/DELETE: * If theres's a targetattrfilter then each add/del filter @@ -2458,29 +2442,25 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a * by each value of the attribute in the entry. * * For MODIFY: - * If there's a targetattrfilter then the add/del filter + * If there's a targetattrfilter then the add/del filter * must be satisfied by the attribute to be added/deleted. * (MODIFY acl is evaluated one value at a time). * * - */ - + */ if (((aclpb->aclpb_access & SLAPI_ACL_ADD) && (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) || ((aclpb->aclpb_access & SLAPI_ACL_DELETE) && - (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS))) { - + (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS))) + { Targetattrfilter **attrFilterArray = NULL; - Targetattrfilter *attrFilter = NULL; - Slapi_Attr *attr_ptr = NULL; Slapi_Value *sval; const struct berval *attrVal; int k; int done; - if ((aclpb->aclpb_access & SLAPI_ACL_ADD) && (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) { @@ -2497,28 +2477,20 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a while (attrFilterArray && attrFilterArray[num_attrs] && attr_matched) { attrFilter = attrFilterArray[num_attrs]; - /* - * If this filter applies to an attribute in the entry, - * apply it to the entry. - * Otherwise just ignore it. - * - */ - - if (slapi_entry_attr_find(aclpb->aclpb_curr_entry, - attrFilter->attr_str, - &attr_ptr) == 0) { - + * If this filter applies to an attribute in the entry, + * apply it to the entry. + * Otherwise just ignore it. + * + */ + if (slapi_entry_attr_find(aclpb->aclpb_curr_entry, attrFilter->attr_str, &attr_ptr) == 0) { /* - * This is an applicable filter. - * The filter is to be appplied to the entry being added - * or deleted. - * The filter needs to be satisfied by _each_ occurence - * of the attribute in the entry--otherwise you - * could satisfy the filter and then put loads of other - * values in on the back of it. - */ - + * This is an applicable filter. + * The filter is to be applied to the entry being added or deleted. + * The filter needs to be satisfied by _each_ occurrence of the + * attribute in the entry--otherwise you could satisfy the filter + * and then put loads of other values in on the back of it. + */ sval = NULL; attrVal = NULL; k = slapi_attr_first_value(attr_ptr, &sval); @@ -2528,12 +2500,11 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a if (acl__make_filter_test_entry(&aclpb->aclpb_filter_test_entry, attrFilter->attr_str, - (struct berval *)attrVal) == LDAP_SUCCESS) { - + (struct berval *)attrVal) == LDAP_SUCCESS) + { attr_matched = acl__test_filter(aclpb->aclpb_filter_test_entry, attrFilter->filter, - 1 /* Do filter sense evaluation below */ - ); + 1 /* Do filter sense evaluation below */); done = !attr_matched; slapi_entry_free(aclpb->aclpb_filter_test_entry); } @@ -2542,19 +2513,19 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a } /* while */ /* - * Here, we applied an applicable filter to the entry. - * So if attr_matched is ACL_TRUE then every value - * of the attribute in the entry satisfied the filter. - * Otherwise, attr_matched is ACL_FALSE and not every - * value satisfied the filter, so we will teminate the - * scan of the filter list. - */ + * Here, we applied an applicable filter to the entry. + * So if attr_matched is ACL_TRUE then every value + * of the attribute in the entry satisfied the filter. + * Otherwise, attr_matched is ACL_FALSE and not every + * value satisfied the filter, so we will terminate the + * scan of the filter list. + */ } num_attrs++; } /* while */ -/* + /* * Here, we've applied all the applicable filters to the entry. * Each one must have been satisfied by all the values of the attribute. * The result of this is stored in attr_matched. @@ -2585,7 +2556,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a } else if (((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) && (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) || ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) && - (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS))) { + (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS))) + { /* * Here, it's a modify add/del and we have attr filters. * So, we need to scan the add/del filter list to find the filter @@ -2629,11 +2601,10 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a * Otherwise, ignore the targetattrfilters. */ if (found) { - if (acl__make_filter_test_entry(&aclpb->aclpb_filter_test_entry, aclpb->aclpb_curr_attrEval->attrEval_name, - aclpb->aclpb_curr_attrVal) == LDAP_SUCCESS) { - + aclpb->aclpb_curr_attrVal) == LDAP_SUCCESS) + { attr_matched = acl__test_filter(aclpb->aclpb_filter_test_entry, attrFilter->filter, 1 /* Do filter sense evaluation below */ @@ -2651,20 +2622,21 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a * Here this attribute appeared and was matched in a * targetattrfilters list, so record this fact so we do * not have to scan the targetattr list for the attribute. - */ + */ attr_matched_in_targetattrfilters = 1; } } /* targetvaluefilters */ - /* There are 3 cases by which acis are selected. - ** 1) By scanning the whole list and picking based on the resource. - ** 2) By picking a subset of the list which will be used for the whole - ** acl evaluation. - ** 3) A finer granularity, i.e, a selected list of acls which will be - ** used for only that entry's evaluation. - */ + /* + * There are 3 cases by which acis are selected. + * 1) By scanning the whole list and picking based on the resource. + * 2) By picking a subset of the list which will be used for the whole + * acl evaluation. + * 3) A finer granularity, i.e, a selected list of acls which will be + * used for only that entry's evaluation. + */ if (!(skip_attrEval) && (aclpb->aclpb_state & ACLPB_SEARCH_BASED_ON_ENTRY_LIST) && (res_right & SLAPI_ACL_SEARCH) && ((aci->aci_access & SLAPI_ACL_READ) || (aci->aci_access & SLAPI_ACL_SEARCH))) { @@ -2680,7 +2652,6 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a } } - /* If we are suppose to skip attr eval, then let's skip it */ if ((aclpb->aclpb_access & SLAPI_ACL_SEARCH) && (!skip_attrEval) && (aclpb->aclpb_res_type & ACLPB_NEW_ENTRY)) { @@ -2697,9 +2668,10 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a goto acl__resource_match_aci_EXIT; } - /* We need to check again because we don't want to select this handle - ** if the right doesn't match for now. - */ + /* + * We need to check again because we don't want to select this handle + * if the right doesn't match for now. + */ if (!(aci_right & res_right)) { matches = ACL_FALSE; goto acl__resource_match_aci_EXIT; @@ -2718,20 +2690,16 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a * rbyrneXXX if we had a proper permission for modrdn eg SLAPI_ACL_MODRDN * then we would not need this crappy way of telling it was a MODRDN * request ie. SLAPI_ACL_WRITE && !(c_attrEval). - */ - + */ c_attrEval = aclpb->aclpb_curr_attrEval; /* * If we've already matched on targattrfilter then do not * bother to look at the attrlist. - */ - + */ if (!attr_matched_in_targetattrfilters) { - /* match target attr */ - if ((c_attrEval) && - (aci->aci_type & ACI_TARGET_ATTR)) { + if ((c_attrEval) && (aci->aci_type & ACI_TARGET_ATTR)) { /* there is a target ATTR */ Targetattr **attrArray = aci->targetAttr; Targetattr *attr = NULL; @@ -2773,46 +2741,43 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a matches = (attr_matched ? ACL_TRUE : ACL_FALSE); } - aclpb->aclpb_state &= ~ACLPB_ATTR_STAR_MATCHED; /* figure out how it matched, i.e star matched */ - if (matches && star_matched && num_attrs == 1 && - !(aclpb->aclpb_state & ACLPB_FOUND_ATTR_RULE)) + if (matches && star_matched && num_attrs == 1 && !(aclpb->aclpb_state & ACLPB_FOUND_ATTR_RULE)) { aclpb->aclpb_state |= ACLPB_ATTR_STAR_MATCHED; - else { + } else { /* we are here means that there is a specific - ** attr in the rule for this resource. - ** We need to avoid this case - ** Rule 1: (targetattr = "uid") - ** Rule 2: (targetattr = "*") - ** we cannot use STAR optimization - */ + * attr in the rule for this resource. + * We need to avoid this case + * Rule 1: (targetattr = "uid") + * Rule 2: (targetattr = "*") + * we cannot use STAR optimization + */ aclpb->aclpb_state |= ACLPB_FOUND_ATTR_RULE; aclpb->aclpb_state &= ~ACLPB_ATTR_STAR_MATCHED; } - } else if ((c_attrEval) || - (aci->aci_type & ACI_TARGET_ATTR)) { + } else if ((c_attrEval) || (aci->aci_type & ACI_TARGET_ATTR)) { if ((aci_right & ACL_RIGHTS_TARGETATTR_NOT_NEEDED) && (aclpb->aclpb_access & ACL_RIGHTS_TARGETATTR_NOT_NEEDED)) { /* - ** Targetattr rule doesn't make any sense - ** in this case. So select this rule - ** default: matches = ACL_TRUE; - */ + * Targetattr rule doesn't make any sense + * in this case. So select this rule + * default: matches = ACL_TRUE; + */ ; - } else if (aci_right & SLAPI_ACL_WRITE && + } else if ((aci_right & SLAPI_ACL_WRITE) && (aci->aci_type & ACI_TARGET_ATTR) && !(c_attrEval) && (aci->aci_type & ACI_HAS_ALLOW_RULE)) { /* We need to handle modrdn operation. Modrdn doesn't - ** change any attrs but changes the RDN and so (attr=NULL). - ** Here we found an acl which has a targetattr but - ** the resource doesn't need one. In that case, we should - ** consider this acl. - ** the opposite is true if it is a deny rule, only a deny without - ** any targetattr should deny modrdn - ** default: matches = ACL_TRUE; - */ + * change any attrs but changes the RDN and so (attr=NULL). + * Here we found an acl which has a targetattr but + * the resource doesn't need one. In that case, we should + * consider this acl. + * the opposite is true if it is a deny rule, only a deny without + * any targetattr should deny modrdn + * default: matches = ACL_TRUE; + */ ; } else { matches = ACL_FALSE; @@ -2821,16 +2786,16 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a } /* !attr_matched_in_targetattrfilters */ /* - ** Here we are testing if we find a entry test rule (which should - ** be rare). In that case, just remember it. An entry test rule - ** doesn't have "(targetattr)". - */ + * Here we are testing if we find a entry test rule (which should + * be rare). In that case, just remember it. An entry test rule + * doesn't have "(targetattr)". + */ if ((aclpb->aclpb_state & ACLPB_EVALUATING_FIRST_ATTR) && (!(aci->aci_type & ACI_TARGET_ATTR))) { aclpb->aclpb_state |= ACLPB_FOUND_A_ENTRY_TEST_RULE; } -/* + /* * Generic exit point for this routine: * matches is ACL_TRUE if the aci matches the target of the resource, * ACL_FALSE othrewise. @@ -2853,6 +2818,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a return (matches); } + /* Macro to determine if the cached result is valid or not. */ #define ACL_CACHED_RESULT_VALID(result) \ (((result & ACLPB_CACHE_READ_RES_ALLOW) && \ diff --git a/ldap/servers/slapd/back-ldbm/findentry.c b/ldap/servers/slapd/back-ldbm/findentry.c index 6e53a0aeae..bff751c881 100644 --- a/ldap/servers/slapd/back-ldbm/findentry.c +++ b/ldap/servers/slapd/back-ldbm/findentry.c @@ -93,7 +93,6 @@ find_entry_internal_dn( size_t tries = 0; int isroot = 0; int op_type; - char *errbuf = NULL; /* get the managedsait ldap message control */ slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait); @@ -207,8 +206,8 @@ find_entry_internal_dn( break; } if (acl_type > 0) { - err = plugin_call_acl_plugin(pb, me->ep_entry, NULL, NULL, acl_type, - ACLPLUGIN_ACCESS_DEFAULT, &errbuf); + char *dummy_attr = "1.1"; + err = slapi_access_allowed(pb, me->ep_entry, dummy_attr, NULL, acl_type); } if (((acl_type > 0) && err) || (op_type == SLAPI_OPERATION_BIND)) { /* @@ -237,7 +236,6 @@ find_entry_internal_dn( CACHE_RETURN(&inst->inst_cache, &me); } - slapi_ch_free_string(&errbuf); slapi_log_err(SLAPI_LOG_TRACE, "find_entry_internal_dn", "<= Not found (%s)\n", slapi_sdn_get_dn(sdn)); return (NULL); diff --git a/src/lib389/lib389/_mapped_object.py b/src/lib389/lib389/_mapped_object.py index 4a8ec7847f..dd2707d752 100644 --- a/src/lib389/lib389/_mapped_object.py +++ b/src/lib389/lib389/_mapped_object.py @@ -1236,7 +1236,7 @@ def ensure_state(self, rdn=None, properties=None): # Now actually commit the creation req return co.ensure_state(rdn, properties, self._basedn) - def filter(self, search, scope=None): + def filter(self, search, scope=None, strict=False): # This will yield and & filter for objectClass with as many terms as needed. if search: search_filter = _gen_and([self._get_objectclass_filter(), search]) @@ -1257,6 +1257,8 @@ def filter(self, search, scope=None): insts = [self._entry_to_instance(dn=r.dn, entry=r) for r in results] except ldap.NO_SUCH_OBJECT: # There are no objects to select from, se we return an empty array + if strict: + raise ldap.NO_SUCH_OBJECT insts = [] return insts