[SCM] Samba Shared Repository - branch master updated

Matthias Dieter Wallnöfer mdw at samba.org
Sun May 30 15:13:45 MDT 2010


The branch, master has been updated
       via  5a0b3cf... s4:tests/python/passwords.py - fix filter
       via  327fa70... ldb:ldb_tdb/ldb_tdb.c - quiet a warning regarding TDB -> LDB error code conversions
       via  463d5f0... s4:samldb LDB module - deny delete operations on some important attributes
       via  092331d... s4:ldap.py - add a test which shows the modification behaviour of important attributes
       via  08653ac... s4:samldb LDB module - rework the group change code to be again synchronous
       via  c30c452... s4:ldap.py - add more test cases to show invalid primary group change behaviour
      from  f3b0485... s3-waf: Set HAVE_GSSAPI if gssapi libs were found

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 5a0b3cf93db3ebf79d81b9ef09669835569549f9
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun May 30 22:46:50 2010 +0200

    s4:tests/python/passwords.py - fix filter

commit 327fa70f3fe2f3917df509f783822a3b42a266f0
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun May 30 21:58:11 2010 +0200

    ldb:ldb_tdb/ldb_tdb.c - quiet a warning regarding TDB -> LDB error code conversions

commit 463d5f0afc5b378bf8143558b8b8f372680f9768
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue May 11 21:43:36 2010 +0200

    s4:samldb LDB module - deny delete operations on some important attributes
    
    Add operations are denied since these are single-valued - only replace is
    allowed.
    
    This is only provisorily at the moment - we need to implement the triggers
    specified in MS-ADTS.

commit 092331d2d8c39ccfbd97c5e357705efb54f1ab6f
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue May 11 21:35:46 2010 +0200

    s4:ldap.py - add a test which shows the modification behaviour of important attributes
    
    This shows how important attributes of SAM objects do behave when you launch
    add and delete modify requests on them.

commit 08653ac9c26a4456d9ca7365c1773d021e5be51c
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun May 30 21:08:05 2010 +0200

    s4:samldb LDB module - rework the group change code to be again synchronous

commit c30c4529f59f25e2846e33bdd3676aed51c10dcc
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue May 11 17:00:54 2010 +0200

    s4:ldap.py - add more test cases to show invalid primary group change behaviour

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/samdb/ldb_modules/samldb.c   |  395 ++++++-----------------------
 source4/lib/ldb/ldb_tdb/ldb_tdb.c         |    2 +
 source4/lib/ldb/tests/python/ldap.py      |  127 +++++++++
 source4/lib/ldb/tests/python/passwords.py |    2 +-
 4 files changed, 213 insertions(+), 313 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 4d1659d..d7ce48f 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -68,20 +68,6 @@ struct samldb_ctx {
 	/* used in conjunction with "sid" in "samldb_dn_from_sid" */
 	struct ldb_dn *res_dn;
 
-	/* used in conjunction with "dn" in "samldb_sid_from_dn" */
-	struct dom_sid *res_sid;
-
-	/* used in "samldb_user_dn_to_prim_group_rid" */
-	uint32_t prim_group_rid;
-
-	/* used in "samldb_group_add_member" and "samldb_group_del_member" */
-	struct ldb_dn *group_dn;
-	struct ldb_dn *member_dn;
-
-	/* used in "samldb_primary_group_change" */
-	struct ldb_dn *user_dn;
-	struct ldb_dn *old_prim_group_dn, *new_prim_group_dn;
-
 	/* all the async steps necessary to complete the operation */
 	struct samldb_step *steps;
 	struct samldb_step *curstep;
@@ -1133,339 +1119,115 @@ static int samldb_schema_info_update(struct samldb_ctx *ac)
 	return LDB_SUCCESS;
 }
 
-/*
- * samldb_user_dn_to_prim_group_rid (async)
- */
 
-static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac);
-
-static int samldb_user_dn_to_prim_group_rid_callback(struct ldb_request *req,
-	struct ldb_reply *ares)
+static int samldb_prim_group_change(struct samldb_ctx *ac)
 {
 	struct ldb_context *ldb;
-	struct samldb_ctx *ac;
+	const char * attrs[] = { "primaryGroupID", "memberOf", NULL };
+	struct ldb_result *res;
+	struct ldb_message_element *el;
+	struct ldb_message *msg;
+	uint32_t rid;
+	struct dom_sid *sid;
+	struct ldb_dn *prev_prim_group_dn, *new_prim_group_dn;
 	int ret;
 
-	ac = talloc_get_type(req->context, struct samldb_ctx);
 	ldb = ldb_module_get_ctx(ac->module);
 
-	if (!ares) {
-		ret = LDB_ERR_OPERATIONS_ERROR;
-		goto done;
-	}
-	if (ares->error != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, ares->controls,
-					ares->response, ares->error);
-	}
-
-	switch (ares->type) {
-	case LDB_REPLY_ENTRY:
-		/* save entry */
-		if (ac->prim_group_rid != 0) {
-			/* one too many! */
-			ldb_set_errstring(ldb,
-				"Invalid number of results while searching "
-				"for domain objects!");
-			ret = LDB_ERR_OPERATIONS_ERROR;
-			break;
-		}
-		ac->prim_group_rid = samdb_result_uint(ares->message,
-			"primaryGroupID", ~0);
-
-		talloc_free(ares);
-		ret = LDB_SUCCESS;
-		break;
+	/* Fetch informations from the existing object */
 
-	case LDB_REPLY_REFERRAL:
-		/* ignore */
-		talloc_free(ares);
-		ret = LDB_SUCCESS;
-		break;
-
-	case LDB_REPLY_DONE:
-		talloc_free(ares);
-		if (ac->prim_group_rid == 0) {
-			ldb_asprintf_errstring(ldb,
-				"Unable to get the primary group RID!");
-			ret = LDB_ERR_OPERATIONS_ERROR;
-			break;
-		}
-
-		/* found, go on */
-		ret = samldb_next_step(ac);
-		break;
-	}
-
-done:
+	ret = ldb_search(ldb, ac, &res, ac->msg->dn, LDB_SCOPE_BASE, attrs,
+			 NULL);
 	if (ret != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, NULL, NULL, ret);
-	}
-
-	return LDB_SUCCESS;
-}
-
-/* Locates the "primaryGroupID" attribute from a certain user specified as
- * "user_dn". Saves the result in "prim_group_rid". */
-static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac)
-{
-	struct ldb_context *ldb;
-	static const char * const attrs[] = { "primaryGroupID", NULL };
-	struct ldb_request *req;
-	int ret;
-
-	ldb = ldb_module_get_ctx(ac->module);
-
-	if (ac->user_dn == NULL)
-		return LDB_ERR_OPERATIONS_ERROR;
-
-	ret = ldb_build_search_req(&req, ldb, ac,
-				ac->user_dn,
-				LDB_SCOPE_BASE,
-				NULL, attrs,
-				NULL,
-				ac, samldb_user_dn_to_prim_group_rid_callback,
-				ac->req);
-	if (ret != LDB_SUCCESS)
 		return ret;
-
-	return ldb_next_request(ac->module, req);
-}
-
-/*
- * samldb_group_add_member (async)
- * samldb_group_del_member (async)
- */
-
-static int samldb_group_add_del_member_callback(struct ldb_request *req,
-	struct ldb_reply *ares)
-{
-	struct ldb_context *ldb;
-	struct samldb_ctx *ac;
-	int ret;
-
-	ac = talloc_get_type(req->context, struct samldb_ctx);
-	ldb = ldb_module_get_ctx(ac->module);
-
-	if (!ares) {
-		ret = LDB_ERR_OPERATIONS_ERROR;
-		goto done;
-	}
-
-	if (ares->type == LDB_REPLY_REFERRAL) {
-		return ldb_module_send_referral(ac->req, ares->referral);
 	}
 
-	if (ares->error != LDB_SUCCESS) {
-		if (ares->error == LDB_ERR_NO_SUCH_ATTRIBUTE) {
-			/* On error "NO_SUCH_ATTRIBUTE" (delete of an invalid
-			 * "member" attribute) return "UNWILLING_TO_PERFORM" */
-			ares->error = LDB_ERR_UNWILLING_TO_PERFORM;
-		}
-		return ldb_module_done(ac->req, ares->controls,
-					ares->response, ares->error);
-	}
-	if (ares->type != LDB_REPLY_DONE) {
-		ldb_set_errstring(ldb,
-			"Invalid reply type!");
-		ret = LDB_ERR_OPERATIONS_ERROR;
-		goto done;
-	}
-
-	ret = samldb_next_step(ac);
+	/* Finds out the DN of the old primary group */
 
-done:
-	if (ret != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, NULL, NULL, ret);
+	rid = samdb_result_uint(res->msgs[0], "primaryGroupID", (uint32_t) -1);
+	if (rid == (uint32_t) -1) {
+		/* User objects do always have a mandatory "primaryGroupID"
+		 * attribute. If this doesn't exist then the object is of the
+		 * wrong type. This is the exact Windows error code */
+		return LDB_ERR_OBJECT_CLASS_VIOLATION;
 	}
 
-	return LDB_SUCCESS;
-}
-
-/* Adds a member with DN "member_dn" to a group with DN "group_dn" */
-static int samldb_group_add_member(struct samldb_ctx *ac)
-{
-	struct ldb_context *ldb;
-	struct ldb_request *req;
-	struct ldb_message *msg;
-	int ret;
-
-	ldb = ldb_module_get_ctx(ac->module);
-
-	if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
+	sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
+	if (sid == NULL) {
 		return LDB_ERR_OPERATIONS_ERROR;
+	}
 
-	msg = ldb_msg_new(ac);
-	msg->dn = ac->group_dn;
-	samdb_msg_add_addval(ldb, ac, msg, "member",
-		ldb_dn_get_linearized(ac->member_dn));
-
-	ret = ldb_build_mod_req(&req, ldb, ac,
-				msg, NULL,
-				ac, samldb_group_add_del_member_callback,
-				ac->req);
-	if (ret != LDB_SUCCESS)
-		return ret;
-
-	return ldb_next_request(ac->module, req);
-}
-
-/* Removes a member with DN "member_dn" from a group with DN "group_dn" */
-static int samldb_group_del_member(struct samldb_ctx *ac)
-{
-	struct ldb_context *ldb;
-	struct ldb_request *req;
-	struct ldb_message *msg;
-	int ret;
-
-	ldb = ldb_module_get_ctx(ac->module);
-
-	if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
+	prev_prim_group_dn = samdb_search_dn(ldb, ac, NULL, "(objectSID=%s)",
+					     dom_sid_string(ac, sid));
+	if (prev_prim_group_dn == NULL) {
 		return LDB_ERR_OPERATIONS_ERROR;
+	}
 
-	msg = ldb_msg_new(ac);
-	msg->dn = ac->group_dn;
-	samdb_msg_add_delval(ldb, ac, msg, "member",
-		ldb_dn_get_linearized(ac->member_dn));
-
-	ret = ldb_build_mod_req(&req, ldb, ac,
-				msg, NULL,
-				ac, samldb_group_add_del_member_callback,
-				ac->req);
-	if (ret != LDB_SUCCESS)
-		return ret;
-
-	return ldb_next_request(ac->module, req);
-}
-
-
-static int samldb_prim_group_change_1(struct samldb_ctx *ac)
-{
-	struct ldb_context *ldb;
-	uint32_t rid;
-
-	ldb = ldb_module_get_ctx(ac->module);
+	/* Finds out the DN of the new primary group */
 
-	ac->user_dn = ac->msg->dn;
+	rid = samdb_result_uint(ac->msg, "primaryGroupID", (uint32_t) -1);
+	if (rid == (uint32_t) -1) {
+		/* we aren't affected of any primary group change */
+		return ldb_next_request(ac->module, ac->req);
+	}
 
-	rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0);
-	ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
-	if (ac->sid == NULL)
+	sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
+	if (sid == NULL) {
 		return LDB_ERR_OPERATIONS_ERROR;
-	ac->res_dn = NULL;
-
-	ac->prim_group_rid = 0;
-
-	return samldb_next_step(ac);
-}
-
-static int samldb_prim_group_change_2(struct samldb_ctx *ac)
-{
-	struct ldb_context *ldb;
-
-	ldb = ldb_module_get_ctx(ac->module);
+	}
 
-	if (ac->res_dn != NULL)
-		ac->new_prim_group_dn = ac->res_dn;
-	else
+	new_prim_group_dn = samdb_search_dn(ldb, ac, NULL, "(objectSID=%s)",
+					    dom_sid_string(ac, sid));
+	if (new_prim_group_dn == NULL) {
+		/* Here we know if the specified new primary group candidate is
+		 * valid or not. */
 		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
 
-	ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
-		ac->prim_group_rid);
-	if (ac->sid == NULL)
-		return LDB_ERR_OPERATIONS_ERROR;
-	ac->res_dn = NULL;
-
-	return samldb_next_step(ac);
-}
-
-static int samldb_prim_group_change_4(struct samldb_ctx *ac);
-static int samldb_prim_group_change_5(struct samldb_ctx *ac);
-static int samldb_prim_group_change_6(struct samldb_ctx *ac);
-
-static int samldb_prim_group_change_3(struct samldb_ctx *ac)
-{
-	int ret;
-
-	if (ac->res_dn != NULL)
-		ac->old_prim_group_dn = ac->res_dn;
-	else
+	el = samdb_find_attribute(ldb, res->msgs[0], "memberOf",
+				  ldb_dn_get_linearized(new_prim_group_dn));
+	if (el == NULL) {
+		/* We need to be already a normal member of the new primary
+		 * group in order to be successful. */
 		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
 
-	/* Only update when the primary group changed */
-	if (ldb_dn_compare(ac->old_prim_group_dn, ac->new_prim_group_dn) != 0) {
-		ac->member_dn = ac->user_dn;
-		/* Remove the "member" attribute of the actual (new) primary
-		 * group */
+	/* Only update the "member" attributes when we really do have a change */
+	if (ldb_dn_compare(new_prim_group_dn, prev_prim_group_dn) != 0) {
+		/* Remove the "member" attribute on the new primary group */
+		msg = talloc_zero(ac, struct ldb_message);
+		msg->dn = new_prim_group_dn;
 
-		ret = samldb_add_step(ac, samldb_prim_group_change_4);
-		if (ret != LDB_SUCCESS) return ret;
+		ret = samdb_msg_add_delval(ldb, ac, msg, "member",
+					   ldb_dn_get_linearized(ac->msg->dn));
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
 
-		ret = samldb_add_step(ac, samldb_group_del_member);
-		if (ret != LDB_SUCCESS) return ret;
+		ret = dsdb_module_modify(ac->module, msg, 0);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
 
 		/* Add a "member" attribute for the previous primary group */
+		msg = talloc_zero(ac, struct ldb_message);
+		msg->dn = prev_prim_group_dn;
 
-		ret = samldb_add_step(ac, samldb_prim_group_change_5);
-		if (ret != LDB_SUCCESS) return ret;
+		ret = samdb_msg_add_addval(ldb, ac, msg, "member",
+					   ldb_dn_get_linearized(ac->msg->dn));
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
 
-		ret = samldb_add_step(ac, samldb_group_add_member);
-		if (ret != LDB_SUCCESS) return ret;
+		ret = dsdb_module_modify(ac->module, msg, 0);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
 	}
 
-	ret = samldb_add_step(ac, samldb_prim_group_change_6);
-	if (ret != LDB_SUCCESS) return ret;
-
-	return samldb_next_step(ac);
-}
-
-static int samldb_prim_group_change_4(struct samldb_ctx *ac)
-{
-	ac->group_dn = ac->new_prim_group_dn;
-
-	return samldb_next_step(ac);
-}
-
-static int samldb_prim_group_change_5(struct samldb_ctx *ac)
-{
-	ac->group_dn = ac->old_prim_group_dn;
-
-	return samldb_next_step(ac);
-}
-
-static int samldb_prim_group_change_6(struct samldb_ctx *ac)
-{
 	return ldb_next_request(ac->module, ac->req);
 }
 
-static int samldb_prim_group_change(struct samldb_ctx *ac)
-{
-	int ret;
-
-	/* Finds out the DN of the new primary group */
-
-	ret = samldb_add_step(ac, samldb_prim_group_change_1);
-	if (ret != LDB_SUCCESS) return ret;
-
-	ret = samldb_add_step(ac, samldb_dn_from_sid);
-	if (ret != LDB_SUCCESS) return ret;
-
-	ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
-	if (ret != LDB_SUCCESS) return ret;
-
-	/* Finds out the DN of the old primary group */
-
-	ret = samldb_add_step(ac, samldb_prim_group_change_2);
-	if (ret != LDB_SUCCESS) return ret;
-
-	ret = samldb_add_step(ac, samldb_dn_from_sid);
-	if (ret != LDB_SUCCESS) return ret;
-
-	ret = samldb_add_step(ac, samldb_prim_group_change_3);
-	if (ret != LDB_SUCCESS) return ret;
-
-	return samldb_first_step(ac);
-}
-
 
 static int samldb_member_check(struct samldb_ctx *ac)
 {
@@ -1713,7 +1475,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 	/* TODO: do not modify original request, create a new one */
 
 	el = ldb_msg_find_element(req->op.mod.message, "groupType");
-	if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
+	if (el && (el->flags == LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
 		uint32_t group_type;
 
 		req->op.mod.message = msg = ldb_msg_copy_shallow(req,
@@ -1730,9 +1492,12 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 		el2 = ldb_msg_find_element(msg, "sAMAccountType");
 		el2->flags = LDB_FLAG_MOD_REPLACE;
 	}
+	if (el && (el->flags == LDB_FLAG_MOD_DELETE)) {
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
 
 	el = ldb_msg_find_element(req->op.mod.message, "primaryGroupID");
-	if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
+	if (el && (el->flags == LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
 		struct samldb_ctx *ac;
 
 		ac = samldb_ctx_init(module, req);
@@ -1744,9 +1509,12 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 
 		return samldb_prim_group_change(ac);
 	}
+	if (el && (el->flags == LDB_FLAG_MOD_DELETE)) {
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
 
 	el = ldb_msg_find_element(req->op.mod.message, "userAccountControl");
-	if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
+	if (el && (el->flags == LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
 		uint32_t user_account_control;
 
 		req->op.mod.message = msg = ldb_msg_copy_shallow(req,
@@ -1785,6 +1553,9 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 			}
 		}
 	}
+	if (el && (el->flags == LDB_FLAG_MOD_DELETE)) {
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
 
 	el = ldb_msg_find_element(req->op.mod.message, "member");
 	if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 8ff6479..42e1bd5 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -77,6 +77,8 @@ int ltdb_err_map(enum TDB_ERROR tdb_code)
 		return LDB_ERR_NO_SUCH_OBJECT;
 	case TDB_ERR_RDONLY:
 		return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+	default:
+		break;
 	}
 	return LDB_ERR_OTHER;
 }
diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py
index aa1febd..51ba341 100755
--- a/source4/lib/ldb/tests/python/ldap.py
+++ b/source4/lib/ldb/tests/python/ldap.py


-- 
Samba Shared Repository


More information about the samba-cvs mailing list