summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-12-22 09:32:26 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:47:37 -0500
commit77f4910b57db6264d5b6b7f67cab3518a2f2ca4a (patch)
tree161db82868e01decd64601d1da327208c9e6a666
parentb1ea93c01641da0f55bf4d97499e13b651c5b20c (diff)
downloadsamba-77f4910b57db6264d5b6b7f67cab3518a2f2ca4a.tar.gz
samba-77f4910b57db6264d5b6b7f67cab3518a2f2ca4a.tar.bz2
samba-77f4910b57db6264d5b6b7f67cab3518a2f2ca4a.zip
r12427: Move SAMR CreateUser2 to transactions, and re-add support for
different computer account types. (Earlier code changes removed the BDC case). We don't use the TemplateDomainController, so just have a TemplateServer in provision_templates.ldif Andrew Bartlett (This used to be commit c4520ba2e6fad42a137983a2e1dbcd9c26db74e9)
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c2
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c79
-rw-r--r--source4/setup/provision_templates.ldif24
3 files changed, 78 insertions, 27 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 6f98298f6b..a959cc9bb4 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -406,7 +406,7 @@ static struct ldb_message *samldb_fill_user_or_computer_object(struct ldb_module
}
if (samldb_find_attribute(msg, "objectclass", "computer") != NULL) {
- if (samldb_copy_template(module, msg2, "(&(CN=TemplateMemberServer)(objectclass=userTemplate))") != 0) {
+ if (samldb_copy_template(module, msg2, "(&(CN=TemplateServer)(objectclass=userTemplate))") != 0) {
ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb_fill_user_or_computer_object: Error copying computer template!\n");
return NULL;
}
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 3de85388dd..42be226022 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -724,6 +724,16 @@ static NTSTATUS samr_CreateUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX
char *cn_name;
int cn_name_len;
+ const char *attrs[] = {
+ "objectSid",
+ "userAccountControl",
+ NULL
+ };
+
+ uint32_t user_account_control;
+
+ struct ldb_message **msgs;
+
ZERO_STRUCTP(r->out.user_handle);
*r->out.access_granted = 0;
*r->out.rid = 0;
@@ -738,17 +748,25 @@ static NTSTATUS samr_CreateUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX
return NT_STATUS_INVALID_PARAMETER;
}
+ ret = ldb_transaction_start(d_state->sam_ctx);
+ if (ret != 0) {
+ DEBUG(0,("Failed to start a transaction for user creation\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
/* check if the user already exists */
name = samdb_search_string(d_state->sam_ctx, mem_ctx, NULL,
"sAMAccountName",
"(&(sAMAccountName=%s)(objectclass=user))",
ldb_binary_encode_string(mem_ctx, account_name));
if (name != NULL) {
+ ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_USER_EXISTS;
}
msg = ldb_msg_new(mem_ctx);
if (msg == NULL) {
+ ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_NO_MEMORY;
}
@@ -782,19 +800,25 @@ static NTSTATUS samr_CreateUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX
obj_class = "user";
} else {
+ ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_INVALID_PARAMETER;
}
/* add core elements to the ldb_message for the user */
msg->dn = ldb_dn_build_child(mem_ctx, "CN", cn_name, ldb_dn_build_child(mem_ctx, "CN", container, d_state->domain_dn));
if (!msg->dn) {
+ ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_NO_MEMORY;
}
samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "sAMAccountName", account_name);
samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", obj_class);
+
+ /* Start a transaction, so we can query and do a subsequent atomic modify */
+
/* create the user */
ret = samdb_add(d_state->sam_ctx, mem_ctx, msg);
if (ret != 0) {
+ ldb_transaction_cancel(d_state->sam_ctx);
DEBUG(0,("Failed to create user record %s\n",
ldb_dn_linearize(mem_ctx, msg->dn)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -802,6 +826,7 @@ static NTSTATUS samr_CreateUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX
a_state = talloc(d_state, struct samr_account_state);
if (!a_state) {
+ ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_NO_MEMORY;
}
a_state->sam_ctx = d_state->sam_ctx;
@@ -809,14 +834,60 @@ static NTSTATUS samr_CreateUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX
a_state->domain_state = talloc_reference(a_state, d_state);
a_state->account_dn = talloc_steal(a_state, msg->dn);
- /* retrieve the sid for the user just created */
- sid = samdb_search_dom_sid(d_state->sam_ctx, a_state,
- msg->dn, "objectSid", NULL);
+ /* retrieve the sid and account control bits for the user just created */
+ ret = gendb_search_dn(d_state->sam_ctx, a_state,
+ msg->dn, &msgs, attrs);
+
+ if (ret != 1) {
+ ldb_transaction_cancel(d_state->sam_ctx);
+ DEBUG(0,("Apparently we failed to create an account record, as %s now doesn't exist\n",
+ ldb_dn_linearize(mem_ctx, msg->dn)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ sid = samdb_result_dom_sid(mem_ctx, msgs[0], "objectSid");
if (sid == NULL) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ user_account_control = samdb_result_uint(msgs[0], "userAccountControl", 0);
+ user_account_control = (user_account_control & ~(UF_NORMAL_ACCOUNT|UF_INTERDOMAIN_TRUST_ACCOUNT|UF_WORKSTATION_TRUST_ACCOUNT|UF_SERVER_TRUST_ACCOUNT));
+ user_account_control |= samdb_acb2uf(r->in.acct_flags);
+
+ talloc_free(msg);
+ msg = ldb_msg_new(mem_ctx);
+ if (msg == NULL) {
+ ldb_transaction_cancel(d_state->sam_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ msg->dn = a_state->account_dn;
+
+ if (samdb_msg_add_uint(a_state->sam_ctx, mem_ctx, msg,
+ "userAccountControl",
+ user_account_control) != 0) {
+ ldb_transaction_cancel(d_state->sam_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* modify the samdb record */
+ ret = samdb_replace(a_state->sam_ctx, mem_ctx, msg);
+ if (ret != 0) {
+ DEBUG(0,("Failed to modify account record %s to set userAccountControl\n",
+ ldb_dn_linearize(mem_ctx, msg->dn)));
+ ldb_transaction_cancel(d_state->sam_ctx);
+
+ /* we really need samdb.c to return NTSTATUS */
return NT_STATUS_UNSUCCESSFUL;
}
- a_state->account_name = talloc_strdup(a_state, account_name);
+ ldb_transaction_commit(d_state->sam_ctx);
+ if (ret != 0) {
+ DEBUG(0,("Failed to commit transaction to add and modify account record %s\n",
+ ldb_dn_linearize(mem_ctx, msg->dn)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ a_state->account_name = talloc_steal(a_state, account_name);
if (!a_state->account_name) {
return NT_STATUS_NO_MEMORY;
}
diff --git a/source4/setup/provision_templates.ldif b/source4/setup/provision_templates.ldif
index 3693f46558..6305b498f4 100644
--- a/source4/setup/provision_templates.ldif
+++ b/source4/setup/provision_templates.ldif
@@ -38,11 +38,11 @@ logonCount: 0
sAMAccountType: 0x30000000
objectCategory: CN=Person,CN=Schema,CN=Configuration,${BASEDN}
-dn: CN=TemplateMemberServer,CN=Templates,${BASEDN}
+dn: CN=TemplateServer,CN=Templates,${BASEDN}
objectClass: top
objectClass: Template
objectClass: userTemplate
-cn: TemplateMemberServer
+cn: TemplateServer
instanceType: 4
userAccountControl: 0x1002
badPwdCount: 0
@@ -58,26 +58,6 @@ logonCount: 0
sAMAccountType: 0x30000001
objectCategory: CN=Computer,CN=Schema,CN=Configuration,${BASEDN}
-dn: CN=TemplateDomainController,CN=Templates,${BASEDN}
-objectClass: top
-objectClass: Template
-objectClass: userTemplate
-cn: TemplateDomainController
-instanceType: 4
-userAccountControl: 0x2002
-badPwdCount: 0
-codePage: 0
-countryCode: 0
-badPasswordTime: 0
-lastLogoff: 0
-lastLogon: 0
-pwdLastSet: 0
-primaryGroupID: 513
-accountExpires: -1
-logonCount: 0
-sAMAccountType: 0x30000001
-objectCategory: CN=Computer,CN=Schema,CN=Configuration,${BASEDN}
-
dn: CN=TemplateTrustingDomain,CN=Templates,${BASEDN}
objectClass: top
objectClass: Template