From 59241c0c9aa2d64d66eb04e81aa5500681604061 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 9 May 2004 11:21:46 +0000 Subject: [PATCH] r605: Implement CreateDomainGroup, essentially cut&paste from CreateUser2. Volker --- source/provision.ldif | 10 ++ source/rpc_server/samr/dcesrv_samr.c | 144 ++++++++++++++++++++++++--- source/rpc_server/samr/samdb.c | 4 + 3 files changed, 146 insertions(+), 12 deletions(-) diff --git a/source/provision.ldif b/source/provision.ldif index 0e30667bc34..edb61012b6c 100644 --- a/source/provision.ldif +++ b/source/provision.ldif @@ -18,6 +18,8 @@ domain: builtinDomain person: organizationalPerson organizationalPerson: user user: computer +template: userTemplate +template: groupTemplate dn: ${BASEDN} objectClass: top @@ -771,3 +773,11 @@ primaryGroupID: 513 accountExpires: -1 logonCount: 0 sAMAccountType: 0x30000000 + +dn: CN=TemplateGroup,CN=Templates,${BASEDN} +objectClass: top +objectClass: groupTemplate +cn: TemplateGroup +name: TemplateGroup +instanceType: 4 +sAMAccountType: 0x10000000 diff --git a/source/rpc_server/samr/dcesrv_samr.c b/source/rpc_server/samr/dcesrv_samr.c index a4e5d4f189b..b14d807d355 100644 --- a/source/rpc_server/samr/dcesrv_samr.c +++ b/source/rpc_server/samr/dcesrv_samr.c @@ -431,6 +431,15 @@ static NTSTATUS samr_SetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CT DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } +/* + destroy an open account context +*/ +static void samr_Account_destroy(struct dcesrv_connection *conn, struct dcesrv_handle *h) +{ + struct samr_account_state *state = h->data; + samr_Domain_close(conn, state->domain_state); + talloc_destroy(state->mem_ctx); +} /* samr_CreateDomainGroup @@ -438,7 +447,129 @@ static NTSTATUS samr_SetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CT static NTSTATUS samr_CreateDomainGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_CreateDomainGroup *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + struct samr_domain_state *d_state; + struct samr_account_state *state; + struct dcesrv_handle *h; + const char *name; + struct ldb_message msg; + uint32 rid; + const char *groupname, *sidstr; + time_t now = time(NULL); + TALLOC_CTX *mem_ctx2; + struct dcesrv_handle *g_handle; + int ret; + NTSTATUS status; + + ZERO_STRUCTP(r->out.group_handle); + *r->out.rid = 0; + + DCESRV_PULL_HANDLE(h, r->in.handle, SAMR_HANDLE_DOMAIN); + + d_state = h->data; + + groupname = r->in.name->name; + + if (groupname == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* check if the group already exists */ + name = samdb_search_string(d_state->sam_ctx, mem_ctx, d_state->basedn, + "name", + "(&(sAMAccountName=%s)(objectclass=group))", + groupname); + if (name != NULL) { + return NT_STATUS_GROUP_EXISTS; + } + + ZERO_STRUCT(msg); + + /* pull in all the template attributes */ + ret = samdb_copy_template(d_state->sam_ctx, mem_ctx, &msg, + "(&(name=TemplateGroup)(objectclass=groupTemplate))"); + if (ret != 0) { + DEBUG(1,("Failed to load TemplateUser from samdb\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + /* allocate a rid */ + status = samdb_allocate_next_id(d_state->sam_ctx, mem_ctx, + d_state->basedn, "nextRid", &rid); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* and the group SID */ + sidstr = talloc_asprintf(mem_ctx, "%s-%u", d_state->domain_sid, rid); + if (!sidstr) { + return NT_STATUS_NO_MEMORY; + } + + /* add core elements to the ldb_message for the user */ + msg.dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Users,%s", groupname, + d_state->basedn); + if (!msg.dn) { + return NT_STATUS_NO_MEMORY; + } + samdb_msg_add_string(d_state->sam_ctx, mem_ctx, &msg, + "name", groupname); + samdb_msg_add_string(d_state->sam_ctx, mem_ctx, &msg, + "cn", groupname); + samdb_msg_add_string(d_state->sam_ctx, mem_ctx, &msg, + "sAMAccountName", groupname); + samdb_msg_add_string(d_state->sam_ctx, mem_ctx, &msg, + "objectClass", "group"); + samdb_msg_add_string(d_state->sam_ctx, mem_ctx, &msg, + "objectSid", sidstr); + samdb_msg_set_ldaptime(d_state->sam_ctx, mem_ctx, &msg, + "whenCreated", now); + samdb_msg_set_ldaptime(d_state->sam_ctx, mem_ctx, &msg, + "whenChanged", now); + + /* create the group */ + ret = samdb_add(d_state->sam_ctx, mem_ctx, &msg); + if (ret != 0) { + DEBUG(1,("Failed to create group record %s\n", msg.dn)); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + /* create user state and new policy handle */ + mem_ctx2 = talloc_init("CreateDomainGroup(%s)", groupname); + if (!mem_ctx2) { + return NT_STATUS_NO_MEMORY; + } + + state = talloc_p(mem_ctx2, struct samr_account_state); + if (!state) { + return NT_STATUS_NO_MEMORY; + } + state->mem_ctx = mem_ctx2; + state->sam_ctx = d_state->sam_ctx; + state->access_mask = r->in.access_mask; + state->domain_state = d_state; + state->basedn = talloc_steal(mem_ctx, mem_ctx2, msg.dn); + state->account_sid = talloc_strdup(mem_ctx2, sidstr); + state->account_name = talloc_strdup(mem_ctx2, groupname); + if (!state->account_name || !state->account_sid) { + return NT_STATUS_NO_MEMORY; + } + + /* create the policy handle */ + g_handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_GROUP); + if (!g_handle) { + return NT_STATUS_NO_MEMORY; + } + + g_handle->data = state; + g_handle->destroy = samr_Account_destroy; + + /* the domain state is in use one more time */ + d_state->reference_count++; + + *r->out.group_handle = g_handle->wire_handle; + *r->out.rid = rid; + + return NT_STATUS_OK; } @@ -452,17 +583,6 @@ static NTSTATUS samr_EnumDomainGroups(struct dcesrv_call_state *dce_call, TALLOC } -/* - destroy an open account context -*/ -static void samr_Account_destroy(struct dcesrv_connection *conn, struct dcesrv_handle *h) -{ - struct samr_account_state *state = h->data; - samr_Domain_close(conn, state->domain_state); - talloc_destroy(state->mem_ctx); -} - - /* samr_CreateUser2 diff --git a/source/rpc_server/samr/samdb.c b/source/rpc_server/samr/samdb.c index 5aae82e39d1..af915e599fc 100644 --- a/source/rpc_server/samr/samdb.c +++ b/source/rpc_server/samr/samdb.c @@ -429,6 +429,10 @@ int samdb_copy_template(void *ctx, TALLOC_CTX *mem_ctx, strcasecmp((char *)el->values[j].data, "userTemplate") == 0) { continue; } + if (strcasecmp(el->name, "objectClass") == 0 && + strcasecmp((char *)el->values[j].data, "groupTemplate") == 0) { + continue; + } samdb_msg_add_string(ctx, mem_ctx, msg, el->name, (char *)el->values[j].data); }