From 77f4910b57db6264d5b6b7f67cab3518a2f2ca4a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 22 Dec 2005 09:32:26 +0000 Subject: 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) --- source4/dsdb/samdb/ldb_modules/samldb.c | 2 +- source4/rpc_server/samr/dcesrv_samr.c | 79 +++++++++++++++++++++++++++++++-- source4/setup/provision_templates.ldif | 24 +--------- 3 files changed, 78 insertions(+), 27 deletions(-) (limited to 'source4') 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 -- cgit