diff options
author | Volker Lendecke <vlendec@samba.org> | 2004-12-27 11:27:30 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:07:39 -0500 |
commit | 2333ea56f3822d594b5f03c863e4be99ae4a625b (patch) | |
tree | 1cbd8b1d905de00d78c5cd80c5f51a5f0b5918df /source4 | |
parent | 296c0d8eacc9f61810974f996982dfe6c93dfa01 (diff) | |
download | samba-2333ea56f3822d594b5f03c863e4be99ae4a625b.tar.gz samba-2333ea56f3822d594b5f03c863e4be99ae4a625b.tar.bz2 samba-2333ea56f3822d594b5f03c863e4be99ae4a625b.zip |
r4375: Implement samr_OpenAlias, samr_QueryAliasInfo and samr_SetAliasInfo. Fix IDL
for samr_SetAliasInfo.
Volker
(This used to be commit d70e2371903fb21e24ab2e23d04ee4b0b2ef55e5)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/librpc/idl/samr.idl | 14 | ||||
-rw-r--r-- | source4/rpc_server/samr/dcesrv_samr.c | 154 | ||||
-rw-r--r-- | source4/torture/rpc/samr.c | 4 |
3 files changed, 163 insertions, 9 deletions
diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl index 58e0601606..38e16011e1 100644 --- a/source4/librpc/idl/samr.idl +++ b/source4/librpc/idl/samr.idl @@ -480,10 +480,16 @@ samr_String description; } samr_AliasInfoAll; + typedef enum { + AliasInfoAll = 1, + AliasInfoName = 2, + AliasInfoDescription = 3 + } AliasInfo; + typedef union { - [case(1)] samr_AliasInfoAll all; - [case(2)] samr_String name; - [case(3)] samr_String description; + [case(AliasInfoAll)] samr_AliasInfoAll all; + [case(AliasInfoName)] samr_String name; + [case(AliasInfoDescription)] samr_String description; } samr_AliasInfo; NTSTATUS samr_QueryAliasInfo( @@ -497,7 +503,7 @@ NTSTATUS samr_SetAliasInfo( [in,ref] policy_handle *alias_handle, [in] uint16 level, - [in,switch_is(level)] samr_AliasInfo info + [in,switch_is(level),ref] samr_AliasInfo *info ); /************************/ diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 6ab50fa4df..59f5ec9d8a 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -1599,7 +1599,75 @@ static NTSTATUS samr_SetMemberAttributesOfGroup(struct dcesrv_call_state *dce_ca static NTSTATUS samr_OpenAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_OpenAlias *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + struct samr_domain_state *d_state; + struct samr_account_state *a_state; + struct dcesrv_handle *h; + const char *aliasname, *sidstr; + struct ldb_message **msgs; + struct dcesrv_handle *g_handle; + const char * const attrs[2] = { "sAMAccountName", NULL }; + int ret; + + ZERO_STRUCTP(r->out.alias_handle); + + DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); + + d_state = h->data; + + /* form the alias SID */ + sidstr = talloc_asprintf(mem_ctx, "%s-%u", d_state->domain_sid, + r->in.rid); + if (sidstr == NULL) + return NT_STATUS_NO_MEMORY; + + /* search for the group record */ + ret = samdb_search(d_state->sam_ctx, + mem_ctx, d_state->domain_dn, &msgs, attrs, + "(&(objectSid=%s)(objectclass=group)" + "(|(grouptype=%s)(grouptype=%s)))", + sidstr, + ldb_hexstr(mem_ctx, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP), + ldb_hexstr(mem_ctx, GTYPE_SECURITY_DOMAIN_LOCAL_GROUP)); + if (ret == 0) { + return NT_STATUS_NO_SUCH_ALIAS; + } + if (ret != 1) { + DEBUG(0,("Found %d records matching sid %s\n", ret, sidstr)); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + aliasname = samdb_result_string(msgs[0], "sAMAccountName", NULL); + if (aliasname == NULL) { + DEBUG(0,("sAMAccountName field missing for sid %s\n", sidstr)); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + a_state = talloc_p(d_state, struct samr_account_state); + if (!a_state) { + return NT_STATUS_NO_MEMORY; + } + a_state->sam_ctx = d_state->sam_ctx; + a_state->access_mask = r->in.access_mask; + a_state->domain_state = talloc_reference(a_state, d_state); + a_state->account_dn = talloc_steal(a_state, msgs[0]->dn); + a_state->account_sid = talloc_steal(a_state, sidstr); + a_state->account_name = talloc_strdup(a_state, aliasname); + if (!a_state->account_name) { + return NT_STATUS_NO_MEMORY; + } + + /* create the policy handle */ + g_handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_ALIAS); + if (!g_handle) { + return NT_STATUS_NO_MEMORY; + } + + g_handle->data = a_state; + g_handle->destroy = samr_handle_destroy; + + *r->out.alias_handle = g_handle->wire_handle; + + return NT_STATUS_OK; } @@ -1609,7 +1677,52 @@ static NTSTATUS samr_OpenAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *m static NTSTATUS samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_QueryAliasInfo *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + struct dcesrv_handle *h; + struct samr_account_state *a_state; + struct ldb_message *msg, **res; + const char * const attrs[4] = { "sAMAccountName", "description", + "numMembers", NULL }; + int ret; + + r->out.info = NULL; + + DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS); + + a_state = h->data; + + /* pull all the alias attributes */ + ret = samdb_search(a_state->sam_ctx, mem_ctx, NULL, &res, attrs, + "dn=%s", a_state->account_dn); + if (ret != 1) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + msg = res[0]; + + /* allocate the info structure */ + r->out.info = talloc_p(mem_ctx, union samr_AliasInfo); + if (r->out.info == NULL) { + return NT_STATUS_NO_MEMORY; + } + ZERO_STRUCTP(r->out.info); + + switch(r->in.level) { + case AliasInfoAll: + QUERY_STRING(msg, all.name.string, "sAMAccountName"); + QUERY_UINT (msg, all.num_members, "numMembers"); + QUERY_STRING(msg, all.description.string, "description"); + break; + case AliasInfoName: + QUERY_STRING(msg, name.string, "sAMAccountName"); + break; + case AliasInfoDescription: + QUERY_STRING(msg, description.string, "description"); + break; + default: + r->out.info = NULL; + return NT_STATUS_INVALID_INFO_CLASS; + } + + return NT_STATUS_OK; } @@ -1619,7 +1732,42 @@ static NTSTATUS samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_C static NTSTATUS samr_SetAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_SetAliasInfo *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + struct dcesrv_handle *h; + struct samr_account_state *a_state; + struct ldb_message mod, *msg = &mod; + int ret; + + DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS); + + a_state = h->data; + + ZERO_STRUCT(mod); + mod.dn = talloc_strdup(mem_ctx, a_state->account_dn); + if (!mod.dn) { + return NT_STATUS_NO_MEMORY; + } + + switch (r->in.level) { + case AliasInfoDescription: + SET_STRING(msg, description.string, "description"); + break; + case AliasInfoName: + /* On W2k3 this does not change the name, it changes the + * sAMAccountName attribute */ + SET_STRING(msg, name.string, "sAMAccountName"); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + } + + /* modify the samdb record */ + ret = samdb_replace(a_state->sam_ctx, mem_ctx, &mod); + if (ret != 0) { + /* we really need samdb.c to return NTSTATUS */ + return NT_STATUS_UNSUCCESSFUL; + } + + return NT_STATUS_OK; } diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index c7456e2fda..66cc8a5d26 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -630,8 +630,8 @@ static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.alias_handle = handle; r.in.level = levels[i]; switch (r.in.level) { - case 2 : init_samr_String(&r.in.info.name,TEST_ALIASNAME); break; - case 3 : init_samr_String(&r.in.info.description, + case 2 : init_samr_String(&r.in.info->name,TEST_ALIASNAME); break; + case 3 : init_samr_String(&r.in.info->description, "Test Description, should test I18N as well"); break; } |