[SCM] Samba Shared Repository - branch master updated
Matthias Dieter Wallnöfer
mdw at samba.org
Sat Oct 30 12:16:01 MDT 2010
The branch, master has been updated
via c0ebf5d s4:sam.py - add a short double swap "primaryGroupID" test
via 98fefa8 s4:samldb LDB module - adapt the "samldb_prim_group_change" trigger to support multiple "primaryGroupID" modification entries
via 02355fc s4:samr RPC server - the LDB error codes for adding or deleting a group member have changed
via c664f01 s4:sam.py - enhance "member" tests
via 4987467 s4:samldb LDB module - "member" trigger
via 5a2c3ad s4:rpc_server/common.h - quiet compilation warnings
from b548674 provision: fix wrong tests
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit c0ebf5d7435c3c4968eefafc6c566dc818e600a0
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Sat Oct 30 17:48:51 2010 +0200
s4:sam.py - add a short double swap "primaryGroupID" test
It's not really meaningful but can happen.
Autobuild-User: Matthias Dieter Wallnöfer <mdw at samba.org>
Autobuild-Date: Sat Oct 30 18:15:31 UTC 2010 on sn-devel-104
commit 98fefa8a017bbb67f6c33080c8a80c77c34e42b8
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Sat Oct 30 17:43:17 2010 +0200
s4:samldb LDB module - adapt the "samldb_prim_group_change" trigger to support multiple "primaryGroupID" modification entries
commit 02355fc6fd176312b61198e626cfe1fbb1ed5ac5
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Sat Oct 30 18:32:43 2010 +0200
s4:samr RPC server - the LDB error codes for adding or deleting a group member have changed
commit c664f010d387af483dce41816d5d222bd8d84f46
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Sat Oct 30 18:09:12 2010 +0200
s4:sam.py - enhance "member" tests
commit 4987467b785a5870cb338881c8916b4268006cd6
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Sat Oct 30 17:12:48 2010 +0200
s4:samldb LDB module - "member" trigger
- adapt the "samldb_member_check" trigger to support multiple "member"
modification entries. There can exist special modification messages which
delete and add members in one operation
- support the right error codes when modifications do fail
(ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM)
commit 5a2c3ad2fa198b260bd8f0934fad0e3113c9f670
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Sat Oct 30 17:55:56 2010 +0200
s4:rpc_server/common.h - quiet compilation warnings
-----------------------------------------------------------------------
Summary of changes:
source4/dsdb/samdb/ldb_modules/samldb.c | 172 ++++++++++++++++++++++---------
source4/dsdb/tests/python/sam.py | 44 ++++++++
source4/rpc_server/common/common.h | 2 +
source4/rpc_server/samr/dcesrv_samr.c | 6 +-
4 files changed, 172 insertions(+), 52 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 924c05e..44c8fee 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -1002,8 +1002,41 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
uint32_t rid;
struct dom_sid *sid;
struct ldb_dn *prev_prim_group_dn, *new_prim_group_dn;
+ unsigned int i;
int ret;
+ /* We've to walk over all modification entries and consider the
+ * "primaryGroupID" ones.
+ *
+ * 1.) Add operations aren't allowed and there is returned
+ * "ATTRIBUTE_OR_VALUE_EXISTS".
+ * 2.) Replace operations are allowed but the last one is taken
+ * 3.) Delete operations are also not allowed and there is returned
+ * "UNWILLING_TO_PERFORM".
+ *
+ * If "el" is afterwards NULL then that means we've nothing to do here.
+ */
+ el = NULL;
+ for (i = 0; i < ac->msg->num_elements; i++) {
+ if (ldb_attr_cmp(ac->msg->elements[i].name,
+ "primaryGroupID") != 0) {
+ continue;
+ }
+
+ el = &ac->msg->elements[i];
+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_ADD) {
+ return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+ }
+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+ }
+ if (el == NULL) {
+ return LDB_SUCCESS;
+ }
+
+ /* Okay, now for sure we are performing a "primaryGroupID" replace */
+
/* Fetch informations from the existing object */
ret = ldb_search(ldb, ac, &res, ac->msg->dn, LDB_SCOPE_BASE, attrs,
@@ -1033,9 +1066,20 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
return ldb_operr(ldb);
}
- /* Finds out the DN of the new primary group */
+ /* Finds out the DN of the new primary group
+ * Notice: in order to parse the primary group ID correctly we create
+ * a temporary message here. */
- rid = ldb_msg_find_attr_as_uint(ac->msg, "primaryGroupID", (uint32_t) -1);
+ msg = ldb_msg_new(ac->msg);
+ if (msg == NULL) {
+ return ldb_module_oom(ac->module);
+ }
+ ret = ldb_msg_add(msg, el, 0);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ rid = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", (uint32_t) -1);
+ talloc_free(msg);
if (rid == (uint32_t) -1) {
/* we aren't affected of any primary group change */
return LDB_SUCCESS;
@@ -1066,6 +1110,9 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
/* Remove the "member" attribute on the new primary group */
msg = talloc_zero(ac, struct ldb_message);
+ if (msg == NULL) {
+ return ldb_module_oom(ac->module);
+ }
msg->dn = new_prim_group_dn;
ret = samdb_msg_add_delval(ldb, msg, msg, "member",
@@ -1081,6 +1128,9 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
/* Add a "member" attribute for the previous primary group */
msg = talloc_zero(ac, struct ldb_message);
+ if (msg == NULL) {
+ return ldb_module_oom(ac->module);
+ }
msg->dn = prev_prim_group_dn;
ret = samdb_msg_add_addval(ldb, msg, msg, "member",
@@ -1095,6 +1145,8 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
}
}
+ talloc_free(res);
+
return LDB_SUCCESS;
}
@@ -1113,55 +1165,86 @@ static int samldb_prim_group_trigger(struct samldb_ctx *ac)
static int samldb_member_check(struct samldb_ctx *ac)
{
- struct ldb_context *ldb;
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
struct ldb_message_element *el;
struct ldb_dn *member_dn, *group_dn;
uint32_t prim_group_rid;
struct dom_sid *sid;
- unsigned int i;
-
- ldb = ldb_module_get_ctx(ac->module);
-
- el = ldb_msg_find_element(ac->msg, "member");
- if (el == NULL) {
- /* we aren't affected */
- return LDB_SUCCESS;
- }
+ unsigned int i, j;
+ int cnt;
- for (i = 0; i < el->num_values; i++) {
- /* Denies to add "member"s to groups which are primary ones
- * for them */
- member_dn = ldb_dn_from_ldb_val(ac, ldb, &el->values[i]);
- if (!ldb_dn_validate(member_dn)) {
- return ldb_operr(ldb);
- }
-
- prim_group_rid = samdb_search_uint(ldb, ac, (uint32_t) -1,
- member_dn, "primaryGroupID",
- NULL);
- if (prim_group_rid == (uint32_t) -1) {
- /* the member hasn't to be a user account -> therefore
- * no check needed in this case. */
+ /* We've to walk over all modification entries and consider the "member"
+ * ones. */
+ for (i = 0; i < ac->msg->num_elements; i++) {
+ if (ldb_attr_cmp(ac->msg->elements[i].name, "member") != 0) {
continue;
}
- sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
- prim_group_rid);
- if (sid == NULL) {
- return ldb_operr(ldb);
- }
-
- group_dn = samdb_search_dn(ldb, ac, NULL, "(objectSid=%s)",
- ldap_encode_ndr_dom_sid(ac, sid));
- if (group_dn == NULL) {
- return ldb_operr(ldb);
- }
+ el = &ac->msg->elements[i];
+ for (j = 0; j < el->num_values; j++) {
+ member_dn = ldb_dn_from_ldb_val(ac, ldb,
+ &el->values[j]);
+ if (!ldb_dn_validate(member_dn)) {
+ return ldb_operr(ldb);
+ }
- if (ldb_dn_compare(group_dn, ac->msg->dn) == 0) {
- if (LDB_FLAG_MOD_TYPE(el->flags)
+ /* The "member" attribute can be modified with the
+ * following restrictions (beside a valid DN):
+ *
+ * - "add" operations can only be performed when the
+ * member still doesn't exist - if not then return
+ * ERR_ENTRY_ALREADY_EXISTS (not
+ * ERR_ATTRIBUTE_OR_VALUE_EXISTS!)
+ * - "delete" operations can only be performed when the
+ * member does exist - if not then return
+ * ERR_UNWILLING_TO_PERFORM (not
+ * ERR_NO_SUCH_ATTRIBUTE!)
+ * - primary group check
+ */
+ cnt = samdb_search_count(ldb, ac, ac->msg->dn,
+ "(member=%s)",
+ ldb_dn_get_linearized(member_dn));
+ if (cnt < 0) {
+ return ldb_operr(ldb);
+ }
+ if ((cnt > 0) && (LDB_FLAG_MOD_TYPE(el->flags)
+ == LDB_FLAG_MOD_ADD)) {
+ return LDB_ERR_ENTRY_ALREADY_EXISTS;
+ }
+ if ((cnt == 0) && LDB_FLAG_MOD_TYPE(el->flags)
== LDB_FLAG_MOD_DELETE) {
return LDB_ERR_UNWILLING_TO_PERFORM;
- } else {
+ }
+
+ /* Denies to add "member"s to groups which are primary
+ * ones for them - in this case return
+ * ERR_ENTRY_ALREADY_EXISTS. */
+
+ prim_group_rid = samdb_search_uint(ldb, ac,
+ (uint32_t) -1,
+ member_dn,
+ "primaryGroupID",
+ NULL);
+ if (prim_group_rid == (uint32_t) -1) {
+ /* the member hasn't to be a user account ->
+ * therefore no check needed in this case. */
+ continue;
+ }
+
+ sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
+ prim_group_rid);
+ if (sid == NULL) {
+ return ldb_operr(ldb);
+ }
+
+ group_dn = samdb_search_dn(ldb, ac, NULL,
+ "(objectSid=%s)",
+ ldap_encode_ndr_dom_sid(ac, sid));
+ if (group_dn == NULL) {
+ return ldb_operr(ldb);
+ }
+
+ if (ldb_dn_compare(group_dn, ac->msg->dn) == 0) {
return LDB_ERR_ENTRY_ALREADY_EXISTS;
}
}
@@ -1393,19 +1476,12 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
}
el = ldb_msg_find_element(ac->msg, "primaryGroupID");
- if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE)
- && el->num_values == 1) {
- modified = true;
-
+ if (el != NULL) {
ret = samldb_prim_group_change(ac);
if (ret != LDB_SUCCESS) {
return ret;
}
}
- el = ldb_msg_find_element(ac->msg, "primaryGroupID");
- if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE)) {
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
el = ldb_msg_find_element(ac->msg, "userAccountControl");
if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE)
diff --git a/source4/dsdb/tests/python/sam.py b/source4/dsdb/tests/python/sam.py
index 43e57f9..bbcc4a8 100755
--- a/source4/dsdb/tests/python/sam.py
+++ b/source4/dsdb/tests/python/sam.py
@@ -402,6 +402,15 @@ class SamTests(unittest.TestCase):
FLAG_MOD_REPLACE, "primaryGroupID")
ldb.modify(m)
+ # Swap the groups (does not really make sense but does the same)
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["primaryGroupID"] = MessageElement(str(group_rid_1),
+ FLAG_MOD_REPLACE, "primaryGroupID")
+ m["primaryGroupID"] = MessageElement(str(group_rid_2),
+ FLAG_MOD_REPLACE, "primaryGroupID")
+ ldb.modify(m)
+
# Old primary group should contain a "member" attribute for the user,
# the new shouldn't contain anymore one
res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
@@ -427,6 +436,17 @@ class SamTests(unittest.TestCase):
except LdbError, (num, _):
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ # Delete invalid group member
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
+ m["member"] = MessageElement("cn=ldaptestuser1,cn=users," + self.base_dn,
+ FLAG_MOD_DELETE, "member")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
# Also this should be denied
try:
ldb.add({
@@ -455,6 +475,17 @@ class SamTests(unittest.TestCase):
FLAG_MOD_ADD, "member")
ldb.modify(m)
+ # Already added
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
+ m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
+ FLAG_MOD_ADD, "member")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
+
# Invalid member
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
@@ -478,6 +509,19 @@ class SamTests(unittest.TestCase):
except LdbError, (num, _):
self.assertEquals(num, ERR_NO_SUCH_OBJECT)
+ # Invalid member
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
+ m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
+ FLAG_MOD_REPLACE, "member")
+ m["member"] = MessageElement("cn=ldaptestuser1,cn=users," + self.base_dn,
+ FLAG_MOD_ADD, "member")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_NO_SUCH_OBJECT)
+
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
m["member"] = MessageElement(["cn=ldaptestuser,cn=users," + self.base_dn,
diff --git a/source4/rpc_server/common/common.h b/source4/rpc_server/common/common.h
index 3f3275b..240ef29 100644
--- a/source4/rpc_server/common/common.h
+++ b/source4/rpc_server/common/common.h
@@ -24,10 +24,12 @@
#define _DCERPC_SERVER_COMMON_H_
struct share_config;
+struct dcesrv_connection;
struct dcesrv_context;
struct dcesrv_context;
struct dcesrv_call_state;
struct ndr_interface_table;
+struct ncacn_packet;
struct dcerpc_server_info {
const char *domain_name;
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 3c08851..dbc9c1e 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -1994,7 +1994,6 @@ static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, T
switch (ret) {
case LDB_SUCCESS:
return NT_STATUS_OK;
- case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
case LDB_ERR_ENTRY_ALREADY_EXISTS:
return NT_STATUS_MEMBER_IN_GROUP;
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
@@ -2099,7 +2098,7 @@ static NTSTATUS dcesrv_samr_DeleteGroupMember(struct dcesrv_call_state *dce_call
switch (ret) {
case LDB_SUCCESS:
return NT_STATUS_OK;
- case LDB_ERR_NO_SUCH_ATTRIBUTE:
+ case LDB_ERR_UNWILLING_TO_PERFORM:
return NT_STATUS_MEMBER_NOT_IN_GROUP;
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
return NT_STATUS_ACCESS_DENIED;
@@ -2468,7 +2467,6 @@ static NTSTATUS dcesrv_samr_AddAliasMember(struct dcesrv_call_state *dce_call, T
switch (ret) {
case LDB_SUCCESS:
return NT_STATUS_OK;
- case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
case LDB_ERR_ENTRY_ALREADY_EXISTS:
return NT_STATUS_MEMBER_IN_GROUP;
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
@@ -2521,7 +2519,7 @@ static NTSTATUS dcesrv_samr_DeleteAliasMember(struct dcesrv_call_state *dce_call
switch (ret) {
case LDB_SUCCESS:
return NT_STATUS_OK;
- case LDB_ERR_NO_SUCH_ATTRIBUTE:
+ case LDB_ERR_UNWILLING_TO_PERFORM:
return NT_STATUS_MEMBER_NOT_IN_GROUP;
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
return NT_STATUS_ACCESS_DENIED;
--
Samba Shared Repository
More information about the samba-cvs
mailing list