[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Wed Oct 21 08:49:03 UTC 2020
The branch, master has been updated
via 7223f6453b1 s4:dsdb:acl_read: Implement "List Object" mode feature
via ffc0bdc6d49 s4:dsdb:util: add dsdb_do_list_object() helper
via e1529bedb2b s4:dsdb:acl_read: defer LDB_ERR_NO_SUCH_OBJECT
via faff8e6c897 s4:dsdb:acl_read: make use of aclread_check_object_visible() for the search base
via c4a3028de72 s4:dsdb:acl_read: fully set up 'struct aclread_context' before the search base acl check
via d2dd7c2a5c1 s4:dsdb:acl_read: introduce aclread_check_object_visible() helper
via 06d13440673 s4:dsdb:tests: add AclVisibiltyTests
via 80347deb544 python/tests: add DynamicTestCase setUpDynamicTestCases() infrastructure
from 6aa396b0cd1 ctdb-common: Avoid aliasing errors during code optimization
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 7223f6453b1b38c933c9480c637ffd06d9f39b97
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Oct 13 12:43:39 2020 +0200
s4:dsdb:acl_read: Implement "List Object" mode feature
See [MS-ADTS] 5.1.3.3.6 Checking Object Visibility
I tried to avoid any possible overhead for the common cases:
- SEC_ADS_LIST (List Children) is already granted by default
- fDoListObject is off by default
Overhead is only added if the administrator turned on
the fDoListObject feature and removed SEC_ADS_LIST (List Children)
from a parent object.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Wed Oct 21 08:48:02 UTC 2020 on sn-devel-184
commit ffc0bdc6d49e88da1ee408956365da163ff3e1b2
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Oct 6 11:21:34 2020 +0200
s4:dsdb:util: add dsdb_do_list_object() helper
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit e1529bedb2b6c8553e69a42537ac0cffd03af6d6
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Oct 12 17:59:34 2020 +0200
s4:dsdb:acl_read: defer LDB_ERR_NO_SUCH_OBJECT
We may need to return child objects even if the base dn
is invisible.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit faff8e6c89777c38443e561235073c336cfb2e9c
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Oct 6 15:10:33 2020 +0200
s4:dsdb:acl_read: make use of aclread_check_object_visible() for the search base
We should only have one place to do access checks.
Use 'git show -w' to see the minimal diff.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit c4a3028de726d6708f57d02f9162a4d62d1b6ae7
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Oct 6 15:10:33 2020 +0200
s4:dsdb:acl_read: fully set up 'struct aclread_context' before the search base acl check
This makes further change much easier.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit d2dd7c2a5c1f8ee30f0f3b41f933d082b0c75f7c
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Oct 6 15:07:19 2020 +0200
s4:dsdb:acl_read: introduce aclread_check_object_visible() helper
In future this will do more than aclread_check_parent(),
if we implement fDoListObject and SEC_ADS_LIST_OBJECT handling.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 06d134406739e76b97273db3023855150dbaebbc
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Oct 7 13:21:06 2020 +0200
s4:dsdb:tests: add AclVisibiltyTests
This tests a sorts of combinations in order to
demonstrate the visibility of objects depending on:
- with or without fDoListObject
- with or without explicit DENY ACEs
- A hierachy of objects with 4 levels from the base dn
- SEC_ADS_LIST (List Children)
- SEC_ADS_LIST_LIST_OBJECT (List Object)
- SEC_ADS_READ_PROP
- all possible scopes and basedns
This demonstrates that NO_SUCH_OBJECT doesn't depend purely
on the visibility of the base dn, it's still possible to
get children returned und an invisible base dn.
It also demonstrates the additional behavior with "List Object" mode.
See [MS-ADTS] 5.1.3.3.6 Checking Object Visibility
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 80347deb544b38be6c6814e5d1b82e48ebe83fd1
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Apr 20 20:00:51 2020 +0200
python/tests: add DynamicTestCase setUpDynamicTestCases() infrastructure
This can be used in order to run a sepcific test (coded just once)
with an autogenerated set of arguments.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14531
Pair-Programmed-With: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
-----------------------------------------------------------------------
Summary of changes:
python/samba/tests/__init__.py | 27 +++
source4/dsdb/samdb/ldb_modules/acl_read.c | 185 +++++++++++++----
source4/dsdb/samdb/ldb_modules/util.c | 21 ++
source4/dsdb/tests/python/acl.py | 321 +++++++++++++++++++++++++++++-
source4/selftest/tests.py | 2 +-
5 files changed, 514 insertions(+), 42 deletions(-)
Changeset truncated at 500 lines:
diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py
index 7f7e68d961c..a5a8acdcc41 100644
--- a/python/samba/tests/__init__.py
+++ b/python/samba/tests/__init__.py
@@ -61,10 +61,37 @@ BINDIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
HEXDUMP_FILTER = bytearray([x if ((len(repr(chr(x))) == 3) and (x < 127)) else ord('.') for x in range(256)])
+def DynamicTestCase(cls):
+ cls.setUpDynamicTestCases()
+ return cls
class TestCase(unittest.TestCase):
"""A Samba test case."""
+ @classmethod
+ def generate_dynamic_test(cls, fnname, suffix, *args):
+ """
+ fnname is something like "test_dynamic_sum"
+ suffix is something like "1plus2"
+ argstr could be (1, 2)
+
+ This would generate a test case called
+ "test_dynamic_sum_1plus2(self)" that
+ calls
+ self._test_dynamic_sum_with_args(1, 2)
+ """
+ def fn(self):
+ getattr(self, "_%s_with_args" % fnname)(*args)
+ setattr(cls, "%s_%s" % (fnname, suffix), fn)
+
+ @classmethod
+ def setUpDynamicTestCases(cls):
+ """This can be implemented in order to call cls.generate_dynamic_test()
+ In order to implement autogenerated testcase permutations.
+ """
+ msg = "%s needs setUpDynamicTestCases() if @DynamicTestCase is used!" % (cls)
+ raise Exception(msg)
+
def setUp(self):
super(TestCase, self).setUp()
test_debug_level = os.getenv("TEST_DEBUG_LEVEL")
diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c
index 7249a1a6c11..b221dcde445 100644
--- a/source4/dsdb/samdb/ldb_modules/acl_read.c
+++ b/source4/dsdb/samdb/ldb_modules/acl_read.c
@@ -52,6 +52,11 @@ struct aclread_context {
bool added_objectClass;
bool indirsync;
+ bool do_list_object_initialized;
+ bool do_list_object;
+ bool base_invisible;
+ uint64_t num_entries;
+
/* cache on the last parent we checked in this search */
struct ldb_dn *last_parent_dn;
int last_parent_check_ret;
@@ -154,6 +159,100 @@ static int aclread_check_parent(struct aclread_context *ac,
return ret;
}
+static int aclread_check_object_visible(struct aclread_context *ac,
+ struct ldb_message *msg,
+ struct ldb_request *req)
+{
+ uint32_t instanceType;
+ int ret;
+
+ /* get the object instance type */
+ instanceType = ldb_msg_find_attr_as_uint(msg,
+ "instanceType", 0);
+ if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) {
+ /*
+ * NC_HEAD objects are always visible
+ */
+ return LDB_SUCCESS;
+ }
+
+ ret = aclread_check_parent(ac, msg, req);
+ if (ret == LDB_SUCCESS) {
+ /*
+ * SEC_ADS_LIST (List Children) alone
+ * on the parent is enough to make the
+ * object visible.
+ */
+ return LDB_SUCCESS;
+ }
+ if (ret != LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
+ return ret;
+ }
+
+ if (!ac->do_list_object_initialized) {
+ /*
+ * We only call dsdb_do_list_object() once
+ * and only when needed in order to
+ * check the dSHeuristics for fDoListObject.
+ */
+ ac->do_list_object = dsdb_do_list_object(ac->module, ac, req);
+ ac->do_list_object_initialized = true;
+ }
+
+ if (ac->do_list_object) {
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct ldb_dn *parent_dn = NULL;
+
+ /*
+ * Here we're in "List Object" mode (fDoListObject=true).
+ *
+ * If SEC_ADS_LIST (List Children) is not
+ * granted on the parent, we need to check if
+ * SEC_ADS_LIST_OBJECT (List Object) is granted
+ * on the parent and also on the object itself.
+ *
+ * We could optimize this similar to aclread_check_parent(),
+ * but that would require quite a bit of restructuring,
+ * so that we cache the granted access bits instead
+ * of just the result for 'SEC_ADS_LIST (List Children)'.
+ *
+ * But as this is the uncommon case and
+ * 'SEC_ADS_LIST (List Children)' is most likely granted
+ * on most of the objects, we'll just implement what
+ * we have to.
+ */
+
+ parent_dn = ldb_dn_get_parent(frame, msg->dn);
+ if (parent_dn == NULL) {
+ TALLOC_FREE(frame);
+ return ldb_oom(ldb_module_get_ctx(ac->module));
+ }
+ ret = dsdb_module_check_access_on_dn(ac->module,
+ frame,
+ parent_dn,
+ SEC_ADS_LIST_OBJECT,
+ NULL, req);
+ if (ret != LDB_SUCCESS) {
+ TALLOC_FREE(frame);
+ return ret;
+ }
+ ret = dsdb_module_check_access_on_dn(ac->module,
+ frame,
+ msg->dn,
+ SEC_ADS_LIST_OBJECT,
+ NULL, req);
+ if (ret != LDB_SUCCESS) {
+ TALLOC_FREE(frame);
+ return ret;
+ }
+
+ TALLOC_FREE(frame);
+ return LDB_SUCCESS;
+ }
+
+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+}
+
/*
* The sd returned from this function is valid until the next call on
* this module context
@@ -466,7 +565,6 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares)
struct security_descriptor *sd = NULL;
struct dom_sid *sid = NULL;
TALLOC_CTX *tmp_ctx;
- uint32_t instanceType;
const struct dsdb_class *objectclass;
bool suppress_result = false;
@@ -509,14 +607,12 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares)
}
sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
- /* get the object instance type */
- instanceType = ldb_msg_find_attr_as_uint(msg,
- "instanceType", 0);
- if (!ldb_dn_is_null(msg->dn) && !(instanceType & INSTANCE_TYPE_IS_NC_HEAD))
- {
- /* the object has a parent, so we have to check for visibility */
- ret = aclread_check_parent(ac, msg, req);
-
+ if (!ldb_dn_is_null(msg->dn)) {
+ /*
+ * this is a real object, so we have
+ * to check for visibility
+ */
+ ret = aclread_check_object_visible(ac, msg, req);
if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
talloc_free(tmp_ctx);
return LDB_SUCCESS;
@@ -697,10 +793,21 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares)
}
talloc_free(tmp_ctx);
+ ac->num_entries++;
return ldb_module_send_entry(ac->req, ret_msg, ares->controls);
case LDB_REPLY_REFERRAL:
return ldb_module_send_referral(ac->req, ares->referral);
case LDB_REPLY_DONE:
+ if (ac->base_invisible && ac->num_entries == 0) {
+ /*
+ * If the base is invisible and we didn't
+ * returned any object, we need to return
+ * NO_SUCH_OBJECT.
+ */
+ return ldb_module_done(ac->req,
+ NULL, NULL,
+ LDB_ERR_NO_SUCH_OBJECT);
+ }
return ldb_module_done(ac->req, ares->controls,
ares->response, LDB_SUCCESS);
@@ -728,7 +835,6 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req)
static const char * const _all_attrs[] = { "*", NULL };
bool all_attrs = false;
const char * const *attrs = NULL;
- uint32_t instanceType;
static const char *acl_attrs[] = {
"instanceType",
NULL
@@ -749,36 +855,6 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req)
return ldb_next_request(module, req);
}
- /* check accessibility of base */
- if (!ldb_dn_is_null(req->op.search.base)) {
- ret = dsdb_module_search_dn(module, req, &res, req->op.search.base,
- acl_attrs,
- DSDB_FLAG_NEXT_MODULE |
- DSDB_FLAG_AS_SYSTEM |
- DSDB_SEARCH_SHOW_RECYCLED,
- req);
- if (ret != LDB_SUCCESS) {
- return ldb_error(ldb, ret,
- "acl_read: Error retrieving instanceType for base.");
- }
- instanceType = ldb_msg_find_attr_as_uint(res->msgs[0],
- "instanceType", 0);
- if (instanceType != 0 && !(instanceType & INSTANCE_TYPE_IS_NC_HEAD))
- {
- /* the object has a parent, so we have to check for visibility */
- struct ldb_dn *parent_dn = ldb_dn_get_parent(req, req->op.search.base);
- ret = dsdb_module_check_access_on_dn(module,
- req,
- parent_dn,
- SEC_ADS_LIST,
- NULL, req);
- if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
- return ldb_module_done(req, NULL, NULL, LDB_ERR_NO_SUCH_OBJECT);
- } else if (ret != LDB_SUCCESS) {
- return ldb_module_done(req, NULL, NULL, ret);
- }
- }
- }
ac = talloc_zero(req, struct aclread_context);
if (ac == NULL) {
return ldb_oom(ldb);
@@ -851,6 +927,35 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req)
}
ac->attrs = req->op.search.attrs;
+
+ /* check accessibility of base */
+ if (!ldb_dn_is_null(req->op.search.base)) {
+ ret = dsdb_module_search_dn(module, req, &res, req->op.search.base,
+ acl_attrs,
+ DSDB_FLAG_NEXT_MODULE |
+ DSDB_FLAG_AS_SYSTEM |
+ DSDB_SEARCH_SHOW_RECYCLED,
+ req);
+ if (ret != LDB_SUCCESS) {
+ return ldb_error(ldb, ret,
+ "acl_read: Error retrieving instanceType for base.");
+ }
+ ret = aclread_check_object_visible(ac, res->msgs[0], req);
+ if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
+ if (req->op.search.scope == LDB_SCOPE_BASE) {
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_NO_SUCH_OBJECT);
+ }
+ /*
+ * Defer LDB_ERR_NO_SUCH_OBJECT,
+ * we may return sub objects
+ */
+ ac->base_invisible = true;
+ } else if (ret != LDB_SUCCESS) {
+ return ldb_module_done(req, NULL, NULL, ret);
+ }
+ }
+
ret = ldb_build_search_req_ex(&down_req,
ldb, ac,
req->op.search.base,
diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c
index 8bc17030500..0e8b72233f4 100644
--- a/source4/dsdb/samdb/ldb_modules/util.c
+++ b/source4/dsdb/samdb/ldb_modules/util.c
@@ -1412,6 +1412,27 @@ bool dsdb_user_password_support(struct ldb_module *module,
return result;
}
+bool dsdb_do_list_object(struct ldb_module *module,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_request *parent)
+{
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ bool result;
+ const struct ldb_val *hr_val = dsdb_module_find_dsheuristics(module,
+ tmp_ctx,
+ parent);
+ if (hr_val == NULL || hr_val->length < DS_HR_DOLISTOBJECT) {
+ result = false;
+ } else if (hr_val->data[DS_HR_DOLISTOBJECT -1] == '1') {
+ result = true;
+ } else {
+ result = false;
+ }
+
+ talloc_free(tmp_ctx);
+ return result;
+}
+
/*
show the chain of requests, useful for debugging async requests
*/
diff --git a/source4/dsdb/tests/python/acl.py b/source4/dsdb/tests/python/acl.py
index 33810ac6895..a859196ee94 100755
--- a/source4/dsdb/tests/python/acl.py
+++ b/source4/dsdb/tests/python/acl.py
@@ -10,6 +10,7 @@ import re
sys.path.insert(0, "bin/python")
import samba
+from samba.tests import DynamicTestCase
from samba.tests.subunitrun import SubunitOptions, TestProgram
from samba.common import get_string
@@ -17,7 +18,7 @@ import samba.getopt as options
from samba.join import DCJoinContext
from ldb import (
- SCOPE_BASE, SCOPE_SUBTREE, LdbError, ERR_NO_SUCH_OBJECT,
+ SCOPE_BASE, SCOPE_ONELEVEL, SCOPE_SUBTREE, LdbError, ERR_NO_SUCH_OBJECT,
ERR_UNWILLING_TO_PERFORM, ERR_INSUFFICIENT_ACCESS_RIGHTS)
from ldb import ERR_CONSTRAINT_VIOLATION
from ldb import ERR_OPERATIONS_ERROR
@@ -2189,6 +2190,324 @@ class AclSPNTests(AclTests):
def test_spn_rodc(self):
self.dc_spn_test(self.rodcctx)
+# tests SEC_ADS_LIST vs. SEC_ADS_LIST_OBJECT
+ at DynamicTestCase
+class AclVisibiltyTests(AclTests):
+
+ envs = {
+ "No": False,
+ "Do": True,
+ }
+ modes = {
+ "Allow": False,
+ "Deny": True,
+ }
+ perms = {
+ "nn": 0,
+ "Cn": security.SEC_ADS_LIST,
+ "nO": security.SEC_ADS_LIST_OBJECT,
+ "CO": security.SEC_ADS_LIST | security.SEC_ADS_LIST_OBJECT,
+ }
+
+ @classmethod
+ def setUpDynamicTestCases(cls):
+ for le in cls.envs.keys():
+ for lm in cls.modes.keys():
+ for l1 in cls.perms.keys():
+ for l2 in cls.perms.keys():
+ for l3 in cls.perms.keys():
+ tname = "%s_%s_%s_%s_%s" % (le, lm, l1, l2, l3)
+ ve = cls.envs[le]
+ vm = cls.modes[lm]
+ v1 = cls.perms[l1]
+ v2 = cls.perms[l2]
+ v3 = cls.perms[l3]
+ targs = (tname, ve, vm, v1, v2, v3)
+ cls.generate_dynamic_test("test_visibility",
+ tname, *targs)
+ return
+
+ def setUp(self):
+ super(AclVisibiltyTests, self).setUp()
+
+ strict_checking = samba.tests.env_get_var_value('STRICT_CHECKING', allow_missing=True)
+ if strict_checking is None:
+ strict_checking = '1'
+ self.strict_checking = bool(int(strict_checking))
+
+ # Get the old "dSHeuristics" if it was set
+ self.dsheuristics = self.ldb_admin.get_dsheuristics()
+ # Reset the "dSHeuristics" as they were before
+ self.addCleanup(self.ldb_admin.set_dsheuristics, self.dsheuristics)
+
+ # Domain Admins and SYSTEM get full access
+ self.sddl_dacl = "D:PAI(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)"
+ self.set_dacl_control = ["sd_flags:1:%d" % security.SECINFO_DACL]
+
+ self.level_idxs = [ 1, 2, 3, 4 ]
+ self.oul1 = "OU=acl_visibility_oul1"
+ self.oul1_dn_str = "%s,%s" % (self.oul1, self.base_dn)
+ self.oul2 = "OU=oul2,%s" % self.oul1
+ self.oul2_dn_str = "%s,%s" % (self.oul2, self.base_dn)
+ self.oul3 = "OU=oul3,%s" % self.oul2
+ self.oul3_dn_str = "%s,%s" % (self.oul3, self.base_dn)
+ self.user_name = "acl_visibility_user"
+ self.user_dn_str = "CN=%s,%s" % (self.user_name, self.oul3_dn_str)
+ delete_force(self.ldb_admin, self.user_dn_str)
+ delete_force(self.ldb_admin, self.oul3_dn_str)
+ delete_force(self.ldb_admin, self.oul2_dn_str)
+ delete_force(self.ldb_admin, self.oul1_dn_str)
+ self.ldb_admin.create_ou(self.oul1_dn_str)
+ self.sd_utils.modify_sd_on_dn(self.oul1_dn_str,
+ self.sddl_dacl,
+ controls=self.set_dacl_control)
+ self.ldb_admin.create_ou(self.oul2_dn_str)
+ self.sd_utils.modify_sd_on_dn(self.oul2_dn_str,
+ self.sddl_dacl,
+ controls=self.set_dacl_control)
+ self.ldb_admin.create_ou(self.oul3_dn_str)
+ self.sd_utils.modify_sd_on_dn(self.oul3_dn_str,
+ self.sddl_dacl,
+ controls=self.set_dacl_control)
+
+ self.ldb_admin.newuser(self.user_name, self.user_pass, userou=self.oul3)
+ self.user_sid = self.sd_utils.get_object_sid(self.user_dn_str)
+ self.ldb_user = self.get_ldb_connection(self.user_name, self.user_pass)
+
+ def tearDown(self):
+ super(AclVisibiltyTests, self).tearDown()
+ delete_force(self.ldb_admin, self.user_dn_str)
+ delete_force(self.ldb_admin, self.oul3_dn_str)
+ delete_force(self.ldb_admin, self.oul2_dn_str)
+ delete_force(self.ldb_admin, self.oul1_dn_str)
+
+ del self.ldb_user
+
+ def _test_visibility_with_args(self,
+ tname,
+ fDoListObject,
+ modeDeny,
+ l1_allow,
+ l2_allow,
+ l3_allow):
+ l1_deny = 0
+ l2_deny = 0
+ l3_deny = 0
+ if modeDeny:
+ l1_deny = ~l1_allow
+ l2_deny = ~l2_allow
+ l3_deny = ~l3_allow
+ print("Testing: fDoListObject=%s, modeDeny=%s, l1_allow=0x%02x, l2_allow=0x%02x, l3_allow=0x%02x)" % (
+ fDoListObject, modeDeny, l1_allow, l2_allow, l3_allow))
+ if fDoListObject:
+ self.ldb_admin.set_dsheuristics("001")
+ else:
+ self.ldb_admin.set_dsheuristics("000")
+
+ def _generate_dacl(allow, deny):
+ dacl = self.sddl_dacl
+ drights = ""
+ if deny & security.SEC_ADS_LIST:
+ drights += "LC"
+ if deny & security.SEC_ADS_LIST_OBJECT:
+ drights += "LO"
+ if len(drights) > 0:
+ dacl += "(D;;%s;;;%s)" % (drights, self.user_sid)
+ arights = ""
+ if allow & security.SEC_ADS_LIST:
+ arights += "LC"
+ if allow & security.SEC_ADS_LIST_OBJECT:
+ arights += "LO"
+ if len(arights) > 0:
+ dacl += "(A;;%s;;;%s)" % (arights, self.user_sid)
+ print("dacl: %s" % dacl)
+ return dacl
+
+ l1_dacl = _generate_dacl(l1_allow, l1_deny)
+ l2_dacl = _generate_dacl(l2_allow, l2_deny)
+ l3_dacl = _generate_dacl(l3_allow, l3_deny)
+ self.sd_utils.modify_sd_on_dn(self.oul1_dn_str,
+ l1_dacl,
+ controls=self.set_dacl_control)
+ self.sd_utils.modify_sd_on_dn(self.oul2_dn_str,
+ l2_dacl,
+ controls=self.set_dacl_control)
+ self.sd_utils.modify_sd_on_dn(self.oul3_dn_str,
+ l3_dacl,
+ controls=self.set_dacl_control)
+
+ def _generate_levels(_l1_allow,
+ _l1_deny,
+ _l2_allow,
+ _l2_deny,
+ _l3_allow,
+ _l3_deny):
--
Samba Shared Repository
More information about the samba-cvs
mailing list