summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Dieter Wallnöfer <mdw@samba.org>2010-10-31 21:04:26 +0100
committerMatthias Dieter Wallnöfer <mdw@samba.org>2010-10-31 21:04:26 +0100
commit51f4de8fc85c314f23ca09ec88001f4dd2253b7f (patch)
tree99adbe75b5a6d6b495cf353c9085df95f9dce20b
parent229f3cc9e85eaf9909464886d152216f7ba44b7b (diff)
downloadsamba-51f4de8fc85c314f23ca09ec88001f4dd2253b7f.tar.gz
samba-51f4de8fc85c314f23ca09ec88001f4dd2253b7f.tar.bz2
samba-51f4de8fc85c314f23ca09ec88001f4dd2253b7f.zip
s4:samldb LDB module - validate "sAMAccountName" modifications
Also the "sAMAccountName" attribute is protected against corruption (e.g. two accounts with the same name).
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 79b557d5c8..b91ca3e83b 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -186,6 +186,9 @@ static int samldb_check_sAMAccountName(struct samldb_ctx *ac)
return ldb_operr(ldb);
}
if (ret == 1) {
+ ldb_asprintf_errstring(ldb,
+ "samldb: Account name (sAMAccountName) '%s' already in use!",
+ name);
return LDB_ERR_ENTRY_ALREADY_EXISTS;
}
@@ -1354,6 +1357,69 @@ static int samldb_group_type_change(struct samldb_ctx *ac)
return LDB_SUCCESS;
}
+static int samldb_sam_accountname_check(struct samldb_ctx *ac)
+{
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+ const char *no_attrs[] = { NULL };
+ struct ldb_result *res;
+ const char *sam_accountname, *enc_str;
+ struct ldb_message_element *el;
+ struct ldb_message *tmp_msg;
+ int ret;
+
+ ret = samldb_get_single_valued_attr(ac, "sAMAccountName", &el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ if (el == NULL) {
+ /* we are not affected */
+ return LDB_SUCCESS;
+ }
+
+ /* Create a temporary message for fetching the "sAMAccountName" */
+ 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;
+ }
+ sam_accountname = ldb_msg_find_attr_as_string(tmp_msg, "sAMAccountName",
+ NULL);
+ talloc_free(tmp_msg);
+
+ if (sam_accountname == NULL) {
+ return ldb_operr(ldb);
+ }
+
+ enc_str = ldb_binary_encode_string(ac, sam_accountname);
+ if (enc_str == NULL) {
+ return ldb_module_oom(ac->module);
+ }
+
+ /* Make sure that a "sAMAccountName" is only used once */
+
+ ret = ldb_search(ldb, ac, &res, NULL, LDB_SCOPE_SUBTREE, no_attrs,
+ "(sAMAccountName=%s)", enc_str);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ if (res->count > 1) {
+ return ldb_operr(ldb);
+ } else if (res->count == 1) {
+ if (ldb_dn_compare(res->msgs[0]->dn, ac->msg->dn) != 0) {
+ ldb_asprintf_errstring(ldb,
+ "samldb: Account name (sAMAccountName) '%s' already in use!",
+ sam_accountname);
+ return LDB_ERR_ENTRY_ALREADY_EXISTS;
+ }
+ }
+ talloc_free(res);
+
+ return LDB_SUCCESS;
+}
+
static int samldb_member_check(struct samldb_ctx *ac)
{
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
@@ -1768,6 +1834,14 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
}
}
+ el = ldb_msg_find_element(ac->msg, "sAMAccountName");
+ if (el != NULL) {
+ ret = samldb_sam_accountname_check(ac);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
el = ldb_msg_find_element(ac->msg, "member");
if (el != NULL) {
ret = samldb_member_check(ac);