|
|
ed9856 |
From 21bfb590a53c078d3dfeb982497f049d4627c71d Mon Sep 17 00:00:00 2001
|
|
|
ed9856 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
ed9856 |
Date: Wed, 20 Jan 2021 16:42:15 -0500
|
|
|
ed9856 |
Subject: [PATCH] Issue 5442 - Search results are different between RHDS10 and
|
|
|
ed9856 |
RHDS11
|
|
|
ed9856 |
|
|
|
ed9856 |
Bug Description: In 1.4.x we introduced a change that was overly strict about
|
|
|
ed9856 |
how a search on a non-existent subtree returned its error code.
|
|
|
ed9856 |
It was changed from returning an error 32 to an error 0 with
|
|
|
ed9856 |
zero entries returned.
|
|
|
ed9856 |
|
|
|
ed9856 |
Fix Description: When finding the entry and processing acl's make sure to
|
|
|
ed9856 |
gather the aci's that match the resource even if the resource
|
|
|
ed9856 |
does not exist. This requires some extra checks when processing
|
|
|
ed9856 |
the target attribute.
|
|
|
ed9856 |
|
|
|
ed9856 |
relates: https://github.com/389ds/389-ds-base/issues/4542
|
|
|
ed9856 |
|
|
|
ed9856 |
Reviewed by: firstyear, elkris, and tbordaz (Thanks!)
|
|
|
ed9856 |
|
|
|
ed9856 |
Apply Thierry's changes
|
|
|
ed9856 |
|
|
|
ed9856 |
round 2
|
|
|
ed9856 |
|
|
|
ed9856 |
Apply more suggestions from Thierry
|
|
|
ed9856 |
---
|
|
|
ed9856 |
ldap/servers/plugins/acl/acl.c | 296 ++++++++++-------------
|
|
|
ed9856 |
ldap/servers/slapd/back-ldbm/findentry.c | 6 +-
|
|
|
ed9856 |
src/lib389/lib389/_mapped_object.py | 1 +
|
|
|
ed9856 |
3 files changed, 134 insertions(+), 169 deletions(-)
|
|
|
ed9856 |
|
|
|
ed9856 |
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
|
|
|
ed9856 |
index 6d105f4fa..ecd23aa88 100644
|
|
|
ed9856 |
--- a/ldap/servers/plugins/acl/acl.c
|
|
|
ed9856 |
+++ b/ldap/servers/plugins/acl/acl.c
|
|
|
ed9856 |
@@ -2109,10 +2109,11 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
aci_right = aci->aci_access;
|
|
|
ed9856 |
res_right = aclpb->aclpb_access;
|
|
|
ed9856 |
if (!(aci_right & res_right)) {
|
|
|
ed9856 |
- /* If we are looking for read/search and the acl has read/search
|
|
|
ed9856 |
- ** then go further because if targets match we may keep that
|
|
|
ed9856 |
- ** acl in the entry cache list.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ /*
|
|
|
ed9856 |
+ * If we are looking for read/search and the acl has read/search
|
|
|
ed9856 |
+ * then go further because if targets match we may keep that
|
|
|
ed9856 |
+ * acl in the entry cache list.
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if (!((res_right & (SLAPI_ACL_SEARCH | SLAPI_ACL_READ)) &&
|
|
|
ed9856 |
(aci_right & (SLAPI_ACL_SEARCH | SLAPI_ACL_READ)))) {
|
|
|
ed9856 |
matches = ACL_FALSE;
|
|
|
ed9856 |
@@ -2120,30 +2121,29 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
}
|
|
|
ed9856 |
}
|
|
|
ed9856 |
|
|
|
ed9856 |
-
|
|
|
ed9856 |
- /* first Let's see if the entry is under the subtree where the
|
|
|
ed9856 |
- ** ACL resides. We can't let somebody affect a target beyond the
|
|
|
ed9856 |
- ** scope of where the ACL resides
|
|
|
ed9856 |
- ** Example: ACL is located in "ou=engineering, o=ace industry, c=us
|
|
|
ed9856 |
- ** but if the target is "o=ace industry, c=us", then we are in trouble.
|
|
|
ed9856 |
- **
|
|
|
ed9856 |
- ** If the aci is in the rootdse and the entry is not, then we do not
|
|
|
ed9856 |
- ** match--ie. acis in the rootdse do NOT apply below...for the moment.
|
|
|
ed9856 |
- **
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ /*
|
|
|
ed9856 |
+ * First Let's see if the entry is under the subtree where the
|
|
|
ed9856 |
+ * ACL resides. We can't let somebody affect a target beyond the
|
|
|
ed9856 |
+ * scope of where the ACL resides
|
|
|
ed9856 |
+ * Example: ACL is located in "ou=engineering, o=ace industry, c=us
|
|
|
ed9856 |
+ * but if the target is "o=ace industry, c=us", then we are in trouble.
|
|
|
ed9856 |
+ *
|
|
|
ed9856 |
+ * If the aci is in the rootdse and the entry is not, then we do not
|
|
|
ed9856 |
+ * match--ie. acis in the rootdse do NOT apply below...for the moment.
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
res_ndn = slapi_sdn_get_ndn(aclpb->aclpb_curr_entry_sdn);
|
|
|
ed9856 |
aci_ndn = slapi_sdn_get_ndn(aci->aci_sdn);
|
|
|
ed9856 |
- if (!slapi_sdn_issuffix(aclpb->aclpb_curr_entry_sdn, aci->aci_sdn) || (!slapi_is_rootdse(res_ndn) && slapi_is_rootdse(aci_ndn))) {
|
|
|
ed9856 |
-
|
|
|
ed9856 |
- /* cant' poke around */
|
|
|
ed9856 |
+ if (!slapi_sdn_issuffix(aclpb->aclpb_curr_entry_sdn, aci->aci_sdn) ||
|
|
|
ed9856 |
+ (!slapi_is_rootdse(res_ndn) && slapi_is_rootdse(aci_ndn)))
|
|
|
ed9856 |
+ {
|
|
|
ed9856 |
+ /* can't poke around */
|
|
|
ed9856 |
matches = ACL_FALSE;
|
|
|
ed9856 |
goto acl__resource_match_aci_EXIT;
|
|
|
ed9856 |
}
|
|
|
ed9856 |
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
- ** We have a single ACI which we need to find if it applies to
|
|
|
ed9856 |
- ** the resource or not.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ * We have a single ACI which we need to find if it applies to the resource or not.
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if ((aci->aci_type & ACI_TARGET_DN) && (aclpb->aclpb_curr_entry_sdn)) {
|
|
|
ed9856 |
char *avaType;
|
|
|
ed9856 |
struct berval *avaValue;
|
|
|
ed9856 |
@@ -2171,25 +2171,23 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
char *avaType;
|
|
|
ed9856 |
struct berval *avaValue;
|
|
|
ed9856 |
char logbuf[1024];
|
|
|
ed9856 |
-
|
|
|
ed9856 |
- /* We are evaluating the moddn permission.
|
|
|
ed9856 |
- * The aci contains target_to and target_from
|
|
|
ed9856 |
- *
|
|
|
ed9856 |
- * target_to filter must be checked against the resource ndn that was stored in
|
|
|
ed9856 |
- * aclpb->aclpb_curr_entry_sdn
|
|
|
ed9856 |
- *
|
|
|
ed9856 |
- * target_from filter must be check against the entry ndn that is in aclpb->aclpb_moddn_source_sdn
|
|
|
ed9856 |
- * (sdn was stored in the pblock)
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ /*
|
|
|
ed9856 |
+ * We are evaluating the moddn permission.
|
|
|
ed9856 |
+ * The aci contains target_to and target_from
|
|
|
ed9856 |
+ *
|
|
|
ed9856 |
+ * target_to filter must be checked against the resource ndn that was stored in
|
|
|
ed9856 |
+ * aclpb->aclpb_curr_entry_sdn
|
|
|
ed9856 |
+ *
|
|
|
ed9856 |
+ * target_from filter must be check against the entry ndn that is in aclpb->aclpb_moddn_source_sdn
|
|
|
ed9856 |
+ * (sdn was stored in the pblock)
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if (aci->target_to) {
|
|
|
ed9856 |
f = aci->target_to;
|
|
|
ed9856 |
dn_matched = ACL_TRUE;
|
|
|
ed9856 |
|
|
|
ed9856 |
/* Now check if the filter is a simple or substring filter */
|
|
|
ed9856 |
if (aci->aci_type & ACI_TARGET_MODDN_TO_PATTERN) {
|
|
|
ed9856 |
- /* This is a filter with substring
|
|
|
ed9856 |
- * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ /* This is a filter with substring e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com */
|
|
|
ed9856 |
slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_to substring: %s\n",
|
|
|
ed9856 |
slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
|
|
ed9856 |
if ((rv = acl_match_substring(f, (char *)res_ndn, 0 /* match suffix */)) != ACL_TRUE) {
|
|
|
ed9856 |
@@ -2202,9 +2200,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
}
|
|
|
ed9856 |
}
|
|
|
ed9856 |
} else {
|
|
|
ed9856 |
- /* This is a filter without substring
|
|
|
ed9856 |
- * e.g. ldap:///cn=accounts,dc=example,dc=com
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ /* This is a filter without substring e.g. ldap:///cn=accounts,dc=example,dc=com */
|
|
|
ed9856 |
slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_to: %s\n",
|
|
|
ed9856 |
slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
|
|
ed9856 |
slapi_filter_get_ava(f, &avaType, &avaValue);
|
|
|
ed9856 |
@@ -2228,8 +2224,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
/* Now check if the filter is a simple or substring filter */
|
|
|
ed9856 |
if (aci->aci_type & ACI_TARGET_MODDN_FROM_PATTERN) {
|
|
|
ed9856 |
/* This is a filter with substring
|
|
|
ed9856 |
- * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_from substring: %s\n",
|
|
|
ed9856 |
slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
|
|
ed9856 |
if ((rv = acl_match_substring(f, (char *)slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn), 0 /* match suffix */)) != ACL_TRUE) {
|
|
|
ed9856 |
@@ -2241,11 +2237,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
goto acl__resource_match_aci_EXIT;
|
|
|
ed9856 |
}
|
|
|
ed9856 |
}
|
|
|
ed9856 |
-
|
|
|
ed9856 |
} else {
|
|
|
ed9856 |
- /* This is a filter without substring
|
|
|
ed9856 |
- * e.g. ldap:///cn=accounts,dc=example,dc=com
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ /* This is a filter without substring e.g. ldap:///cn=accounts,dc=example,dc=com */
|
|
|
ed9856 |
slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_from: %s\n",
|
|
|
ed9856 |
slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
|
|
ed9856 |
if (!slapi_dn_issuffix(slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn), avaValue->bv_val)) {
|
|
|
ed9856 |
@@ -2267,10 +2260,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
}
|
|
|
ed9856 |
|
|
|
ed9856 |
if (aci->aci_type & ACI_TARGET_PATTERN) {
|
|
|
ed9856 |
-
|
|
|
ed9856 |
f = aci->target;
|
|
|
ed9856 |
dn_matched = ACL_TRUE;
|
|
|
ed9856 |
-
|
|
|
ed9856 |
if ((rv = acl_match_substring(f, (char *)res_ndn, 0 /* match suffux */)) != ACL_TRUE) {
|
|
|
ed9856 |
dn_matched = ACL_FALSE;
|
|
|
ed9856 |
if (rv == ACL_ERR) {
|
|
|
ed9856 |
@@ -2294,7 +2285,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
* Is it a (target="ldap://cn=*,($dn),o=sun.com") kind of thing.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if (aci->aci_type & ACI_TARGET_MACRO_DN) {
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
* See if the ($dn) component matches the string and
|
|
|
ed9856 |
@@ -2304,8 +2295,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
* entry is the same one don't recalculate it--
|
|
|
ed9856 |
* this flag only works for search right now, could
|
|
|
ed9856 |
* also optimise for mods by making it work for mods.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if ((aclpb->aclpb_res_type & ACLPB_NEW_ENTRY) == 0) {
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
* Here same entry so just look up the matched value,
|
|
|
ed9856 |
@@ -2354,8 +2344,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
* If there is already an entry for this aci in this
|
|
|
ed9856 |
* aclpb then remove it--it's an old value for a
|
|
|
ed9856 |
* different entry.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
acl_ht_add_and_freeOld(aclpb->aclpb_macro_ht,
|
|
|
ed9856 |
(PLHashNumber)aci->aci_index,
|
|
|
ed9856 |
matched_val);
|
|
|
ed9856 |
@@ -2379,30 +2368,27 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
}
|
|
|
ed9856 |
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
- ** Here, if there's a targetfilter field, see if it matches.
|
|
|
ed9856 |
- **
|
|
|
ed9856 |
- ** The commented out code below was an erroneous attempt to skip
|
|
|
ed9856 |
- ** this test. It is wrong because: 1. you need to store
|
|
|
ed9856 |
- ** whether the last test matched or not (you cannot just assume it did)
|
|
|
ed9856 |
- ** and 2. It may not be the same aci, so the previous matched
|
|
|
ed9856 |
- ** value is a function of the aci.
|
|
|
ed9856 |
- ** May be interesting to build such a cache...but no evidence for
|
|
|
ed9856 |
- ** for that right now. See Bug 383424.
|
|
|
ed9856 |
- **
|
|
|
ed9856 |
- **
|
|
|
ed9856 |
- ** && ((aclpb->aclpb_state & ACLPB_SEARCH_BASED_ON_LIST) ||
|
|
|
ed9856 |
- ** (aclpb->aclpb_res_type & ACLPB_NEW_ENTRY))
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ * Here, if there's a targetfilter field, see if it matches.
|
|
|
ed9856 |
+ *
|
|
|
ed9856 |
+ * The commented out code below was an erroneous attempt to skip
|
|
|
ed9856 |
+ * this test. It is wrong because: 1. you need to store
|
|
|
ed9856 |
+ * whether the last test matched or not (you cannot just assume it did)
|
|
|
ed9856 |
+ * and 2. It may not be the same aci, so the previous matched
|
|
|
ed9856 |
+ * value is a function of the aci.
|
|
|
ed9856 |
+ * May be interesting to build such a cache...but no evidence for
|
|
|
ed9856 |
+ * for that right now. See Bug 383424.
|
|
|
ed9856 |
+ *
|
|
|
ed9856 |
+ *
|
|
|
ed9856 |
+ * && ((aclpb->aclpb_state & ACLPB_SEARCH_BASED_ON_LIST) ||
|
|
|
ed9856 |
+ * (aclpb->aclpb_res_type & ACLPB_NEW_ENTRY))
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if (aci->aci_type & ACI_TARGET_FILTER) {
|
|
|
ed9856 |
int filter_matched = ACL_TRUE;
|
|
|
ed9856 |
-
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
* Check for macros.
|
|
|
ed9856 |
* For targetfilter we need to fake the lasinfo structure--it's
|
|
|
ed9856 |
* created "naturally" for subjects but not targets.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
-
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if (aci->aci_type & ACI_TARGET_FILTER_MACRO_DN) {
|
|
|
ed9856 |
|
|
|
ed9856 |
lasInfo *lasinfo = NULL;
|
|
|
ed9856 |
@@ -2417,11 +2403,9 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
ACL_EVAL_TARGET_FILTER);
|
|
|
ed9856 |
slapi_ch_free((void **)&lasinfo);
|
|
|
ed9856 |
} else {
|
|
|
ed9856 |
-
|
|
|
ed9856 |
-
|
|
|
ed9856 |
if (slapi_vattr_filter_test(NULL, aclpb->aclpb_curr_entry,
|
|
|
ed9856 |
aci->targetFilter,
|
|
|
ed9856 |
- 0 /*don't do acess chk*/) != 0) {
|
|
|
ed9856 |
+ 0 /*don't do access check*/) != 0) {
|
|
|
ed9856 |
filter_matched = ACL_FALSE;
|
|
|
ed9856 |
}
|
|
|
ed9856 |
}
|
|
|
ed9856 |
@@ -2448,7 +2432,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
* Check to see if we need to evaluate any targetattrfilters.
|
|
|
ed9856 |
* They look as follows:
|
|
|
ed9856 |
* (targetattrfilters="add=sn:(sn=rob) && gn:(gn!=byrne),
|
|
|
ed9856 |
- * del=sn:(sn=rob) && gn:(gn=byrne)")
|
|
|
ed9856 |
+ * del=sn:(sn=rob) && gn:(gn=byrne)")
|
|
|
ed9856 |
*
|
|
|
ed9856 |
* For ADD/DELETE:
|
|
|
ed9856 |
* If theres's a targetattrfilter then each add/del filter
|
|
|
ed9856 |
@@ -2456,29 +2440,25 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
* by each value of the attribute in the entry.
|
|
|
ed9856 |
*
|
|
|
ed9856 |
* For MODIFY:
|
|
|
ed9856 |
- * If there's a targetattrfilter then the add/del filter
|
|
|
ed9856 |
+ * If there's a targetattrfilter then the add/del filter
|
|
|
ed9856 |
* must be satisfied by the attribute to be added/deleted.
|
|
|
ed9856 |
* (MODIFY acl is evaluated one value at a time).
|
|
|
ed9856 |
*
|
|
|
ed9856 |
*
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if (((aclpb->aclpb_access & SLAPI_ACL_ADD) &&
|
|
|
ed9856 |
(aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) ||
|
|
|
ed9856 |
((aclpb->aclpb_access & SLAPI_ACL_DELETE) &&
|
|
|
ed9856 |
- (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS))) {
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)))
|
|
|
ed9856 |
+ {
|
|
|
ed9856 |
Targetattrfilter **attrFilterArray = NULL;
|
|
|
ed9856 |
-
|
|
|
ed9856 |
Targetattrfilter *attrFilter = NULL;
|
|
|
ed9856 |
-
|
|
|
ed9856 |
Slapi_Attr *attr_ptr = NULL;
|
|
|
ed9856 |
Slapi_Value *sval;
|
|
|
ed9856 |
const struct berval *attrVal;
|
|
|
ed9856 |
int k;
|
|
|
ed9856 |
int done;
|
|
|
ed9856 |
|
|
|
ed9856 |
-
|
|
|
ed9856 |
if ((aclpb->aclpb_access & SLAPI_ACL_ADD) &&
|
|
|
ed9856 |
(aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) {
|
|
|
ed9856 |
|
|
|
ed9856 |
@@ -2495,28 +2475,20 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
|
|
|
ed9856 |
while (attrFilterArray && attrFilterArray[num_attrs] && attr_matched) {
|
|
|
ed9856 |
attrFilter = attrFilterArray[num_attrs];
|
|
|
ed9856 |
-
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
- * If this filter applies to an attribute in the entry,
|
|
|
ed9856 |
- * apply it to the entry.
|
|
|
ed9856 |
- * Otherwise just ignore it.
|
|
|
ed9856 |
- *
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
-
|
|
|
ed9856 |
- if (slapi_entry_attr_find(aclpb->aclpb_curr_entry,
|
|
|
ed9856 |
- attrFilter->attr_str,
|
|
|
ed9856 |
- &attr_ptr) == 0) {
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ * If this filter applies to an attribute in the entry,
|
|
|
ed9856 |
+ * apply it to the entry.
|
|
|
ed9856 |
+ * Otherwise just ignore it.
|
|
|
ed9856 |
+ *
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
+ if (slapi_entry_attr_find(aclpb->aclpb_curr_entry, attrFilter->attr_str, &attr_ptr) == 0) {
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
- * This is an applicable filter.
|
|
|
ed9856 |
- * The filter is to be appplied to the entry being added
|
|
|
ed9856 |
- * or deleted.
|
|
|
ed9856 |
- * The filter needs to be satisfied by _each_ occurence
|
|
|
ed9856 |
- * of the attribute in the entry--otherwise you
|
|
|
ed9856 |
- * could satisfy the filter and then put loads of other
|
|
|
ed9856 |
- * values in on the back of it.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ * This is an applicable filter.
|
|
|
ed9856 |
+ * The filter is to be applied to the entry being added or deleted.
|
|
|
ed9856 |
+ * The filter needs to be satisfied by _each_ occurrence of the
|
|
|
ed9856 |
+ * attribute in the entry--otherwise you could satisfy the filter
|
|
|
ed9856 |
+ * and then put loads of other values in on the back of it.
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
sval = NULL;
|
|
|
ed9856 |
attrVal = NULL;
|
|
|
ed9856 |
k = slapi_attr_first_value(attr_ptr, &sval);
|
|
|
ed9856 |
@@ -2526,12 +2498,11 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
|
|
|
ed9856 |
if (acl__make_filter_test_entry(&aclpb->aclpb_filter_test_entry,
|
|
|
ed9856 |
attrFilter->attr_str,
|
|
|
ed9856 |
- (struct berval *)attrVal) == LDAP_SUCCESS) {
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ (struct berval *)attrVal) == LDAP_SUCCESS)
|
|
|
ed9856 |
+ {
|
|
|
ed9856 |
attr_matched = acl__test_filter(aclpb->aclpb_filter_test_entry,
|
|
|
ed9856 |
attrFilter->filter,
|
|
|
ed9856 |
- 1 /* Do filter sense evaluation below */
|
|
|
ed9856 |
- );
|
|
|
ed9856 |
+ 1 /* Do filter sense evaluation below */);
|
|
|
ed9856 |
done = !attr_matched;
|
|
|
ed9856 |
slapi_entry_free(aclpb->aclpb_filter_test_entry);
|
|
|
ed9856 |
}
|
|
|
ed9856 |
@@ -2540,19 +2511,19 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
} /* while */
|
|
|
ed9856 |
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
- * Here, we applied an applicable filter to the entry.
|
|
|
ed9856 |
- * So if attr_matched is ACL_TRUE then every value
|
|
|
ed9856 |
- * of the attribute in the entry satisfied the filter.
|
|
|
ed9856 |
- * Otherwise, attr_matched is ACL_FALSE and not every
|
|
|
ed9856 |
- * value satisfied the filter, so we will teminate the
|
|
|
ed9856 |
- * scan of the filter list.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ * Here, we applied an applicable filter to the entry.
|
|
|
ed9856 |
+ * So if attr_matched is ACL_TRUE then every value
|
|
|
ed9856 |
+ * of the attribute in the entry satisfied the filter.
|
|
|
ed9856 |
+ * Otherwise, attr_matched is ACL_FALSE and not every
|
|
|
ed9856 |
+ * value satisfied the filter, so we will terminate the
|
|
|
ed9856 |
+ * scan of the filter list.
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
}
|
|
|
ed9856 |
|
|
|
ed9856 |
num_attrs++;
|
|
|
ed9856 |
} /* while */
|
|
|
ed9856 |
|
|
|
ed9856 |
-/*
|
|
|
ed9856 |
+ /*
|
|
|
ed9856 |
* Here, we've applied all the applicable filters to the entry.
|
|
|
ed9856 |
* Each one must have been satisfied by all the values of the attribute.
|
|
|
ed9856 |
* The result of this is stored in attr_matched.
|
|
|
ed9856 |
@@ -2583,7 +2554,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
} else if (((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) &&
|
|
|
ed9856 |
(aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) ||
|
|
|
ed9856 |
((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) &&
|
|
|
ed9856 |
- (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS))) {
|
|
|
ed9856 |
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)))
|
|
|
ed9856 |
+ {
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
* Here, it's a modify add/del and we have attr filters.
|
|
|
ed9856 |
* So, we need to scan the add/del filter list to find the filter
|
|
|
ed9856 |
@@ -2633,11 +2605,10 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
*/
|
|
|
ed9856 |
|
|
|
ed9856 |
if (found) {
|
|
|
ed9856 |
-
|
|
|
ed9856 |
if (acl__make_filter_test_entry(&aclpb->aclpb_filter_test_entry,
|
|
|
ed9856 |
aclpb->aclpb_curr_attrEval->attrEval_name,
|
|
|
ed9856 |
- aclpb->aclpb_curr_attrVal) == LDAP_SUCCESS) {
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ aclpb->aclpb_curr_attrVal) == LDAP_SUCCESS)
|
|
|
ed9856 |
+ {
|
|
|
ed9856 |
attr_matched = acl__test_filter(aclpb->aclpb_filter_test_entry,
|
|
|
ed9856 |
attrFilter->filter,
|
|
|
ed9856 |
1 /* Do filter sense evaluation below */
|
|
|
ed9856 |
@@ -2655,20 +2626,21 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
* Here this attribute appeared and was matched in a
|
|
|
ed9856 |
* targetattrfilters list, so record this fact so we do
|
|
|
ed9856 |
* not have to scan the targetattr list for the attribute.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
|
|
|
ed9856 |
attr_matched_in_targetattrfilters = 1;
|
|
|
ed9856 |
}
|
|
|
ed9856 |
} /* targetvaluefilters */
|
|
|
ed9856 |
|
|
|
ed9856 |
|
|
|
ed9856 |
- /* There are 3 cases by which acis are selected.
|
|
|
ed9856 |
- ** 1) By scanning the whole list and picking based on the resource.
|
|
|
ed9856 |
- ** 2) By picking a subset of the list which will be used for the whole
|
|
|
ed9856 |
- ** acl evaluation.
|
|
|
ed9856 |
- ** 3) A finer granularity, i.e, a selected list of acls which will be
|
|
|
ed9856 |
- ** used for only that entry's evaluation.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ /*
|
|
|
ed9856 |
+ * There are 3 cases by which acis are selected.
|
|
|
ed9856 |
+ * 1) By scanning the whole list and picking based on the resource.
|
|
|
ed9856 |
+ * 2) By picking a subset of the list which will be used for the whole
|
|
|
ed9856 |
+ * acl evaluation.
|
|
|
ed9856 |
+ * 3) A finer granularity, i.e, a selected list of acls which will be
|
|
|
ed9856 |
+ * used for only that entry's evaluation.
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if (!(skip_attrEval) && (aclpb->aclpb_state & ACLPB_SEARCH_BASED_ON_ENTRY_LIST) &&
|
|
|
ed9856 |
(res_right & SLAPI_ACL_SEARCH) &&
|
|
|
ed9856 |
((aci->aci_access & SLAPI_ACL_READ) || (aci->aci_access & SLAPI_ACL_SEARCH))) {
|
|
|
ed9856 |
@@ -2684,7 +2656,6 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
}
|
|
|
ed9856 |
}
|
|
|
ed9856 |
|
|
|
ed9856 |
-
|
|
|
ed9856 |
/* If we are suppose to skip attr eval, then let's skip it */
|
|
|
ed9856 |
if ((aclpb->aclpb_access & SLAPI_ACL_SEARCH) && (!skip_attrEval) &&
|
|
|
ed9856 |
(aclpb->aclpb_res_type & ACLPB_NEW_ENTRY)) {
|
|
|
ed9856 |
@@ -2701,9 +2672,10 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
goto acl__resource_match_aci_EXIT;
|
|
|
ed9856 |
}
|
|
|
ed9856 |
|
|
|
ed9856 |
- /* We need to check again because we don't want to select this handle
|
|
|
ed9856 |
- ** if the right doesn't match for now.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ /*
|
|
|
ed9856 |
+ * We need to check again because we don't want to select this handle
|
|
|
ed9856 |
+ * if the right doesn't match for now.
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if (!(aci_right & res_right)) {
|
|
|
ed9856 |
matches = ACL_FALSE;
|
|
|
ed9856 |
goto acl__resource_match_aci_EXIT;
|
|
|
ed9856 |
@@ -2722,20 +2694,16 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
* rbyrneXXX if we had a proper permission for modrdn eg SLAPI_ACL_MODRDN
|
|
|
ed9856 |
* then we would not need this crappy way of telling it was a MODRDN
|
|
|
ed9856 |
* request ie. SLAPI_ACL_WRITE && !(c_attrEval).
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
c_attrEval = aclpb->aclpb_curr_attrEval;
|
|
|
ed9856 |
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
* If we've already matched on targattrfilter then do not
|
|
|
ed9856 |
* bother to look at the attrlist.
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
-
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if (!attr_matched_in_targetattrfilters) {
|
|
|
ed9856 |
-
|
|
|
ed9856 |
/* match target attr */
|
|
|
ed9856 |
- if ((c_attrEval) &&
|
|
|
ed9856 |
- (aci->aci_type & ACI_TARGET_ATTR)) {
|
|
|
ed9856 |
+ if ((c_attrEval) && (aci->aci_type & ACI_TARGET_ATTR)) {
|
|
|
ed9856 |
/* there is a target ATTR */
|
|
|
ed9856 |
Targetattr **attrArray = aci->targetAttr;
|
|
|
ed9856 |
Targetattr *attr = NULL;
|
|
|
ed9856 |
@@ -2777,46 +2745,43 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
matches = (attr_matched ? ACL_TRUE : ACL_FALSE);
|
|
|
ed9856 |
}
|
|
|
ed9856 |
|
|
|
ed9856 |
-
|
|
|
ed9856 |
aclpb->aclpb_state &= ~ACLPB_ATTR_STAR_MATCHED;
|
|
|
ed9856 |
/* figure out how it matched, i.e star matched */
|
|
|
ed9856 |
- if (matches && star_matched && num_attrs == 1 &&
|
|
|
ed9856 |
- !(aclpb->aclpb_state & ACLPB_FOUND_ATTR_RULE))
|
|
|
ed9856 |
+ if (matches && star_matched && num_attrs == 1 && !(aclpb->aclpb_state & ACLPB_FOUND_ATTR_RULE)) {
|
|
|
ed9856 |
aclpb->aclpb_state |= ACLPB_ATTR_STAR_MATCHED;
|
|
|
ed9856 |
- else {
|
|
|
ed9856 |
+ } else {
|
|
|
ed9856 |
/* we are here means that there is a specific
|
|
|
ed9856 |
- ** attr in the rule for this resource.
|
|
|
ed9856 |
- ** We need to avoid this case
|
|
|
ed9856 |
- ** Rule 1: (targetattr = "uid")
|
|
|
ed9856 |
- ** Rule 2: (targetattr = "*")
|
|
|
ed9856 |
- ** we cannot use STAR optimization
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ * attr in the rule for this resource.
|
|
|
ed9856 |
+ * We need to avoid this case
|
|
|
ed9856 |
+ * Rule 1: (targetattr = "uid")
|
|
|
ed9856 |
+ * Rule 2: (targetattr = "*")
|
|
|
ed9856 |
+ * we cannot use STAR optimization
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
aclpb->aclpb_state |= ACLPB_FOUND_ATTR_RULE;
|
|
|
ed9856 |
aclpb->aclpb_state &= ~ACLPB_ATTR_STAR_MATCHED;
|
|
|
ed9856 |
}
|
|
|
ed9856 |
- } else if ((c_attrEval) ||
|
|
|
ed9856 |
- (aci->aci_type & ACI_TARGET_ATTR)) {
|
|
|
ed9856 |
+ } else if ((c_attrEval) || (aci->aci_type & ACI_TARGET_ATTR)) {
|
|
|
ed9856 |
if ((aci_right & ACL_RIGHTS_TARGETATTR_NOT_NEEDED) &&
|
|
|
ed9856 |
(aclpb->aclpb_access & ACL_RIGHTS_TARGETATTR_NOT_NEEDED)) {
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
- ** Targetattr rule doesn't make any sense
|
|
|
ed9856 |
- ** in this case. So select this rule
|
|
|
ed9856 |
- ** default: matches = ACL_TRUE;
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ * Targetattr rule doesn't make any sense
|
|
|
ed9856 |
+ * in this case. So select this rule
|
|
|
ed9856 |
+ * default: matches = ACL_TRUE;
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
;
|
|
|
ed9856 |
- } else if (aci_right & SLAPI_ACL_WRITE &&
|
|
|
ed9856 |
+ } else if ((aci_right & SLAPI_ACL_WRITE) &&
|
|
|
ed9856 |
(aci->aci_type & ACI_TARGET_ATTR) &&
|
|
|
ed9856 |
!(c_attrEval) &&
|
|
|
ed9856 |
(aci->aci_type & ACI_HAS_ALLOW_RULE)) {
|
|
|
ed9856 |
/* We need to handle modrdn operation. Modrdn doesn't
|
|
|
ed9856 |
- ** change any attrs but changes the RDN and so (attr=NULL).
|
|
|
ed9856 |
- ** Here we found an acl which has a targetattr but
|
|
|
ed9856 |
- ** the resource doesn't need one. In that case, we should
|
|
|
ed9856 |
- ** consider this acl.
|
|
|
ed9856 |
- ** the opposite is true if it is a deny rule, only a deny without
|
|
|
ed9856 |
- ** any targetattr should deny modrdn
|
|
|
ed9856 |
- ** default: matches = ACL_TRUE;
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ * change any attrs but changes the RDN and so (attr=NULL).
|
|
|
ed9856 |
+ * Here we found an acl which has a targetattr but
|
|
|
ed9856 |
+ * the resource doesn't need one. In that case, we should
|
|
|
ed9856 |
+ * consider this acl.
|
|
|
ed9856 |
+ * the opposite is true if it is a deny rule, only a deny without
|
|
|
ed9856 |
+ * any targetattr should deny modrdn
|
|
|
ed9856 |
+ * default: matches = ACL_TRUE;
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
;
|
|
|
ed9856 |
} else {
|
|
|
ed9856 |
matches = ACL_FALSE;
|
|
|
ed9856 |
@@ -2825,16 +2790,16 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
|
|
ed9856 |
} /* !attr_matched_in_targetattrfilters */
|
|
|
ed9856 |
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
- ** Here we are testing if we find a entry test rule (which should
|
|
|
ed9856 |
- ** be rare). In that case, just remember it. An entry test rule
|
|
|
ed9856 |
- ** doesn't have "(targetattr)".
|
|
|
ed9856 |
- */
|
|
|
ed9856 |
+ * Here we are testing if we find a entry test rule (which should
|
|
|
ed9856 |
+ * be rare). In that case, just remember it. An entry test rule
|
|
|
ed9856 |
+ * doesn't have "(targetattr)".
|
|
|
ed9856 |
+ */
|
|
|
ed9856 |
if ((aclpb->aclpb_state & ACLPB_EVALUATING_FIRST_ATTR) &&
|
|
|
ed9856 |
(!(aci->aci_type & ACI_TARGET_ATTR))) {
|
|
|
ed9856 |
aclpb->aclpb_state |= ACLPB_FOUND_A_ENTRY_TEST_RULE;
|
|
|
ed9856 |
}
|
|
|
ed9856 |
|
|
|
ed9856 |
-/*
|
|
|
ed9856 |
+ /*
|
|
|
ed9856 |
* Generic exit point for this routine:
|
|
|
ed9856 |
* matches is ACL_TRUE if the aci matches the target of the resource,
|
|
|
ed9856 |
* ACL_FALSE othrewise.
|
|
|
ed9856 |
@@ -2857,6 +2822,7 @@ acl__resource_match_aci_EXIT:
|
|
|
ed9856 |
|
|
|
ed9856 |
return (matches);
|
|
|
ed9856 |
}
|
|
|
ed9856 |
+
|
|
|
ed9856 |
/* Macro to determine if the cached result is valid or not. */
|
|
|
ed9856 |
#define ACL_CACHED_RESULT_VALID(result) \
|
|
|
ed9856 |
(((result & ACLPB_CACHE_READ_RES_ALLOW) && \
|
|
|
ed9856 |
diff --git a/ldap/servers/slapd/back-ldbm/findentry.c b/ldap/servers/slapd/back-ldbm/findentry.c
|
|
|
ed9856 |
index 6e53a0aea..bff751c88 100644
|
|
|
ed9856 |
--- a/ldap/servers/slapd/back-ldbm/findentry.c
|
|
|
ed9856 |
+++ b/ldap/servers/slapd/back-ldbm/findentry.c
|
|
|
ed9856 |
@@ -93,7 +93,6 @@ find_entry_internal_dn(
|
|
|
ed9856 |
size_t tries = 0;
|
|
|
ed9856 |
int isroot = 0;
|
|
|
ed9856 |
int op_type;
|
|
|
ed9856 |
- char *errbuf = NULL;
|
|
|
ed9856 |
|
|
|
ed9856 |
/* get the managedsait ldap message control */
|
|
|
ed9856 |
slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait);
|
|
|
ed9856 |
@@ -207,8 +206,8 @@ find_entry_internal_dn(
|
|
|
ed9856 |
break;
|
|
|
ed9856 |
}
|
|
|
ed9856 |
if (acl_type > 0) {
|
|
|
ed9856 |
- err = plugin_call_acl_plugin(pb, me->ep_entry, NULL, NULL, acl_type,
|
|
|
ed9856 |
- ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
|
|
|
ed9856 |
+ char *dummy_attr = "1.1";
|
|
|
ed9856 |
+ err = slapi_access_allowed(pb, me->ep_entry, dummy_attr, NULL, acl_type);
|
|
|
ed9856 |
}
|
|
|
ed9856 |
if (((acl_type > 0) && err) || (op_type == SLAPI_OPERATION_BIND)) {
|
|
|
ed9856 |
/*
|
|
|
ed9856 |
@@ -237,7 +236,6 @@ find_entry_internal_dn(
|
|
|
ed9856 |
CACHE_RETURN(&inst->inst_cache, &me);
|
|
|
ed9856 |
}
|
|
|
ed9856 |
|
|
|
ed9856 |
- slapi_ch_free_string(&errbuf);
|
|
|
ed9856 |
slapi_log_err(SLAPI_LOG_TRACE, "find_entry_internal_dn", "<= Not found (%s)\n",
|
|
|
ed9856 |
slapi_sdn_get_dn(sdn));
|
|
|
ed9856 |
return (NULL);
|
|
|
ed9856 |
diff --git a/src/lib389/lib389/_mapped_object.py b/src/lib389/lib389/_mapped_object.py
|
|
|
ed9856 |
index f73cb25f3..ada3f4976 100644
|
|
|
ed9856 |
--- a/src/lib389/lib389/_mapped_object.py
|
|
|
ed9856 |
+++ b/src/lib389/lib389/_mapped_object.py
|
|
|
ed9856 |
@@ -838,3 +838,4 @@ class DSLdapObjects(DSLogging):
|
|
|
ed9856 |
(rdn, properties) = self._validate(rdn, properties)
|
|
|
ed9856 |
# Now actually commit the creation req
|
|
|
ed9856 |
return co.create(rdn, properties, self._basedn)
|
|
|
ed9856 |
+
|
|
|
ed9856 |
--
|
|
|
ed9856 |
2.26.2
|
|
|
ed9856 |
|