[SCM] Samba Shared Repository - branch master updated
Matthias Dieter Wallnöfer
mdw at samba.org
Sat Oct 30 13:08:01 MDT 2010
The branch, master has been updated
via 9401189 s4:samldb LDB module - make the "userAccountControl" and "groupType" modify handlers separate functions
via 098ea71 s4:samldb LDB module - add a new function which handles special cases for single-valued attribute on SAM modifications
via 095c8b2 s4:samldb LDB module - primary group change - free temporary messages to save memory
from c0ebf5d s4:sam.py - add a short double swap "primaryGroupID" test
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 9401189d5435632bcc6a177845ce03beaa804113
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Sat Oct 30 19:56:54 2010 +0200
s4:samldb LDB module - make the "userAccountControl" and "groupType" modify handlers separate functions
It's easier to maintain afterwards
Autobuild-User: Matthias Dieter Wallnöfer <mdw at samba.org>
Autobuild-Date: Sat Oct 30 19:07:20 UTC 2010 on sn-devel-104
commit 098ea71728eb6389ff4c5314d17df533f79a07a8
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Sat Oct 30 19:37:30 2010 +0200
s4:samldb LDB module - add a new function which handles special cases for single-valued attribute on SAM modifications
This saves quiet some work.
commit 095c8b2078128838f6b830613e80cbdcf49e10cf
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Sat Oct 30 19:56:24 2010 +0200
s4:samldb LDB module - primary group change - free temporary messages to save memory
-----------------------------------------------------------------------
Summary of changes:
source4/dsdb/samdb/ldb_modules/samldb.c | 380 ++++++++++++++++++------------
1 files changed, 228 insertions(+), 152 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 44c8fee..9b6d6e0 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -751,6 +751,53 @@ static int samldb_schema_info_update(struct samldb_ctx *ac)
}
/*
+ * Gets back a single-valued attribute by the rules of the SAM triggers when
+ * performing a modify operation
+ */
+static int samldb_get_single_valued_attr(struct samldb_ctx *ac,
+ const char *attr_name,
+ struct ldb_message_element **attr)
+{
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+ struct ldb_message_element *el = NULL;
+ unsigned int i;
+
+ /* We've to walk over all modification entries and consider the
+ * "attr_name" 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.
+ */
+ for (i = 0; i < ac->msg->num_elements; i++) {
+ if (ldb_attr_cmp(ac->msg->elements[i].name, attr_name) != 0) {
+ continue;
+ }
+
+ el = &ac->msg->elements[i];
+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_ADD) {
+ ldb_asprintf_errstring(ldb,
+ "samldb: attribute '%s' already exists!",
+ attr_name);
+ return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+ }
+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
+ ldb_asprintf_errstring(ldb,
+ "samldb: attribute '%s' cannot be deleted!",
+ attr_name);
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+ }
+
+ *attr = el;
+ return LDB_SUCCESS;
+}
+
+/*
* "Objectclass" trigger (MS-SAMR 3.1.1.8.1)
*
* Has to be invoked on "add" and "modify" operations on "user", "computer" and
@@ -1002,41 +1049,17 @@ 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;
- }
+ ret = samldb_get_single_valued_attr(ac, "primaryGroupID", &el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
if (el == NULL) {
+ /* we are not affected */
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,
@@ -1109,7 +1132,7 @@ 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);
+ msg = ldb_msg_new(ac->msg);
if (msg == NULL) {
return ldb_module_oom(ac->module);
}
@@ -1125,9 +1148,10 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
if (ret != LDB_SUCCESS) {
return ret;
}
+ talloc_free(msg);
/* Add a "member" attribute for the previous primary group */
- msg = talloc_zero(ac, struct ldb_message);
+ msg = ldb_msg_new(ac->msg);
if (msg == NULL) {
return ldb_module_oom(ac->module);
}
@@ -1143,6 +1167,7 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
if (ret != LDB_SUCCESS) {
return ret;
}
+ talloc_free(msg);
}
talloc_free(res);
@@ -1163,6 +1188,169 @@ static int samldb_prim_group_trigger(struct samldb_ctx *ac)
return ret;
}
+static int samldb_user_account_control_change(struct samldb_ctx *ac)
+{
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+ uint32_t user_account_control, account_type;
+ struct ldb_message_element *el;
+ struct ldb_message *tmp_msg;
+ int ret;
+
+ ret = samldb_get_single_valued_attr(ac, "userAccountControl", &el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ if (el == NULL) {
+ /* we are not affected */
+ return LDB_SUCCESS;
+ }
+
+ /* Create a temporary message for fetching the "userAccountControl" */
+ tmp_msg = ldb_msg_new(ac->msg);
+ if (tmp_msg == NULL) {
+ return ldb_module_oom(ac->module);
+ }
+ ret = ldb_msg_add(tmp_msg, el, 0);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ user_account_control = ldb_msg_find_attr_as_uint(tmp_msg,
+ "userAccountControl",
+ 0);
+ talloc_free(tmp_msg);
+
+ /* Temporary duplicate accounts aren't allowed */
+ if ((user_account_control & UF_TEMP_DUPLICATE_ACCOUNT) != 0) {
+ return LDB_ERR_OTHER;
+ }
+
+ account_type = ds_uf2atype(user_account_control);
+ if (account_type == 0) {
+ ldb_set_errstring(ldb, "samldb: Unrecognized account type!");
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+ ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, "sAMAccountType",
+ account_type);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ el = ldb_msg_find_element(ac->msg, "sAMAccountType");
+ el->flags = LDB_FLAG_MOD_REPLACE;
+
+ if (user_account_control
+ & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) {
+ ret = samdb_msg_add_string(ldb, ac->msg, ac->msg,
+ "isCriticalSystemObject", "TRUE");
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ el = ldb_msg_find_element(ac->msg,
+ "isCriticalSystemObject");
+ el->flags = LDB_FLAG_MOD_REPLACE;
+ }
+
+ if (!ldb_msg_find_element(ac->msg, "primaryGroupID")) {
+ uint32_t rid = ds_uf2prim_group_rid(user_account_control);
+ ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg,
+ "primaryGroupID", rid);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ el = ldb_msg_find_element(ac->msg,
+ "primaryGroupID");
+ el->flags = LDB_FLAG_MOD_REPLACE;
+ }
+
+ return LDB_SUCCESS;
+}
+
+static int samldb_group_type_change(struct samldb_ctx *ac)
+{
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+ uint32_t group_type, old_group_type, account_type;
+ struct ldb_message_element *el;
+ struct ldb_message *tmp_msg;
+ int ret;
+
+ ret = samldb_get_single_valued_attr(ac, "groupType", &el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ if (el == NULL) {
+ /* we are not affected */
+ return LDB_SUCCESS;
+ }
+
+ /* Create a temporary message for fetching the "groupType" */
+ tmp_msg = ldb_msg_new(ac->msg);
+ if (tmp_msg == NULL) {
+ return ldb_module_oom(ac->module);
+ }
+ ret = ldb_msg_add(tmp_msg, el, 0);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ group_type = ldb_msg_find_attr_as_uint(tmp_msg, "groupType", 0);
+ talloc_free(tmp_msg);
+
+ old_group_type = samdb_search_uint(ldb, ac, 0, ac->msg->dn,
+ "groupType", NULL);
+ if (old_group_type == 0) {
+ return ldb_operr(ldb);
+ }
+
+ /* Group type switching isn't so easy as it seems: We can only
+ * change in this directions: global <-> universal <-> local
+ * On each step also the group type itself
+ * (security/distribution) is variable. */
+
+ switch (group_type) {
+ case GTYPE_SECURITY_GLOBAL_GROUP:
+ case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
+ /* change to "universal" allowed */
+ if ((old_group_type == GTYPE_SECURITY_DOMAIN_LOCAL_GROUP) ||
+ (old_group_type == GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP)) {
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+ break;
+
+ case GTYPE_SECURITY_UNIVERSAL_GROUP:
+ case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP:
+ /* each change allowed */
+ break;
+
+ case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
+ case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP:
+ /* change to "universal" allowed */
+ if ((old_group_type == GTYPE_SECURITY_GLOBAL_GROUP) ||
+ (old_group_type == GTYPE_DISTRIBUTION_GLOBAL_GROUP)) {
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+ break;
+
+ case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
+ default:
+ /* we don't allow this "groupType" values */
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ break;
+ }
+
+ account_type = ds_gtype2atype(group_type);
+ if (account_type == 0) {
+ ldb_set_errstring(ldb, "samldb: Unrecognized account type!");
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+ ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, "sAMAccountType",
+ account_type);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ el = ldb_msg_find_element(ac->msg, "sAMAccountType");
+ el->flags = LDB_FLAG_MOD_REPLACE;
+
+ return LDB_SUCCESS;
+}
+
static int samldb_member_check(struct samldb_ctx *ac)
{
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
@@ -1354,10 +1542,9 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_context *ldb;
struct samldb_ctx *ac;
- struct ldb_message_element *el, *el2;
+ struct ldb_message_element *el;
bool modified = false;
int ret;
- uint32_t account_type;
if (ldb_dn_is_special(req->op.mod.message->dn)) {
/* do not manipulate our control entries */
@@ -1406,75 +1593,6 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
return ldb_operr(ldb);
}
- el = ldb_msg_find_element(ac->msg, "groupType");
- if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE)
- && el->num_values == 1) {
- uint32_t group_type, old_group_type;
-
- modified = true;
-
- group_type = ldb_msg_find_attr_as_uint(ac->msg, "groupType", 0);
- old_group_type = samdb_search_uint(ldb, ac, 0, ac->msg->dn,
- "groupType", NULL);
- if (old_group_type == 0) {
- return ldb_operr(ldb);
- }
-
- /* Group type switching isn't so easy as it seems: We can only
- * change in this directions: global <-> universal <-> local
- * On each step also the group type itself
- * (security/distribution) is variable. */
-
- switch (group_type) {
- case GTYPE_SECURITY_GLOBAL_GROUP:
- case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
- /* change to "universal" allowed */
- if ((old_group_type == GTYPE_SECURITY_DOMAIN_LOCAL_GROUP) ||
- (old_group_type == GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP)) {
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
- break;
-
- case GTYPE_SECURITY_UNIVERSAL_GROUP:
- case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP:
- /* each change allowed */
- break;
-
- case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
- case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP:
- /* change to "universal" allowed */
- if ((old_group_type == GTYPE_SECURITY_GLOBAL_GROUP) ||
- (old_group_type == GTYPE_DISTRIBUTION_GLOBAL_GROUP)) {
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
- break;
-
- case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
- default:
- /* we don't allow this "groupType" values */
- return LDB_ERR_UNWILLING_TO_PERFORM;
- break;
- }
-
- account_type = ds_gtype2atype(group_type);
- if (account_type == 0) {
- ldb_set_errstring(ldb, "samldb: Unrecognized account type!");
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg,
- "sAMAccountType",
- account_type);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
- el2 = ldb_msg_find_element(ac->msg, "sAMAccountType");
- el2->flags = LDB_FLAG_MOD_REPLACE;
- }
- el = ldb_msg_find_element(ac->msg, "groupType");
- 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, "primaryGroupID");
if (el != NULL) {
ret = samldb_prim_group_change(ac);
@@ -1484,64 +1602,22 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
}
el = ldb_msg_find_element(ac->msg, "userAccountControl");
- if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE)
- && el->num_values == 1) {
- uint32_t user_account_control;
-
+ if (el != NULL) {
modified = true;
-
- user_account_control = ldb_msg_find_attr_as_uint(ac->msg,
- "userAccountControl",
- 0);
-
- /* Temporary duplicate accounts aren't allowed */
- if ((user_account_control & UF_TEMP_DUPLICATE_ACCOUNT) != 0) {
- return LDB_ERR_OTHER;
- }
-
- account_type = ds_uf2atype(user_account_control);
- if (account_type == 0) {
- ldb_set_errstring(ldb, "samldb: Unrecognized account type!");
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg,
- "sAMAccountType",
- account_type);
+ ret = samldb_user_account_control_change(ac);
if (ret != LDB_SUCCESS) {
return ret;
}
- el2 = ldb_msg_find_element(ac->msg, "sAMAccountType");
- el2->flags = LDB_FLAG_MOD_REPLACE;
-
- if (user_account_control & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) {
- ret = samdb_msg_add_string(ldb, ac->msg, ac->msg,
- "isCriticalSystemObject",
- "TRUE");
- if (ret != LDB_SUCCESS) {
- return ret;
- }
- el2 = ldb_msg_find_element(ac->msg,
- "isCriticalSystemObject");
- el2->flags = LDB_FLAG_MOD_REPLACE;
- }
-
- if (!ldb_msg_find_element(ac->msg, "primaryGroupID")) {
- uint32_t rid = ds_uf2prim_group_rid(user_account_control);
+ }
- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg,
- "primaryGroupID", rid);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
- el2 = ldb_msg_find_element(ac->msg,
- "primaryGroupID");
- el2->flags = LDB_FLAG_MOD_REPLACE;
+ el = ldb_msg_find_element(ac->msg, "groupType");
+ if (el != NULL) {
+ modified = true;
+ ret = samldb_group_type_change(ac);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
}
- el = ldb_msg_find_element(ac->msg, "userAccountControl");
- 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, "member");
if (el != NULL) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list