diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-11-18 05:17:24 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:05:58 -0500 |
commit | 9b6c08a0d19929c8928e692de2156e81decc4048 (patch) | |
tree | 895d615f5f5bfd0bd528e46f43d816e20917345a | |
parent | 0b691afe81c2778de30f20c03ab2a5f29473f799 (diff) | |
download | samba-9b6c08a0d19929c8928e692de2156e81decc4048.tar.gz samba-9b6c08a0d19929c8928e692de2156e81decc4048.tar.bz2 samba-9b6c08a0d19929c8928e692de2156e81decc4048.zip |
r3837: added support for LsaLookupSids in the LSA rpc server. This allows the GUI ACL editor on w2k to
correctly display names instead of SIDs.
(This used to be commit fdaa753578c7b80806d4040ed131f87ddbf988e0)
-rw-r--r-- | source4/librpc/idl/lsa.idl | 14 | ||||
-rw-r--r-- | source4/rpc_server/lsa/dcesrv_lsa.c | 126 |
2 files changed, 131 insertions, 9 deletions
diff --git a/source4/librpc/idl/lsa.idl b/source4/librpc/idl/lsa.idl index d3d3ad3da6..d0bf2ad3e1 100644 --- a/source4/librpc/idl/lsa.idl +++ b/source4/librpc/idl/lsa.idl @@ -237,14 +237,14 @@ } lsa_SidPtr; typedef [public] struct { - uint32 num_sids; + [range(0,1000)] uint32 num_sids; [size_is(num_sids)] lsa_SidPtr *sids; } lsa_SidArray; NTSTATUS lsa_EnumAccounts ( [in,ref] policy_handle *handle, [in,out,ref] uint32 *resume_handle, - [in] uint32 num_entries, + [in,range(0,1000)] uint32 num_entries, [out,ref] lsa_SidArray *sids ); @@ -281,7 +281,7 @@ NTSTATUS lsa_EnumTrustDom ( [in,ref] policy_handle *handle, [in,out,ref] uint32 *resume_handle, - [in] uint32 num_entries, + [in,range(0,1000)] uint32 num_entries, [out,ref] lsa_DomainList *domains ); @@ -296,19 +296,19 @@ } lsa_TranslatedSid; typedef struct { - uint32 count; + [range(0,1000)] uint32 count; [size_is(count)] lsa_TranslatedSid *sids; } lsa_TransSidArray; typedef struct { - uint32 count; + [range(0,1000)] uint32 count; [size_is(count)] lsa_TrustInformation *domains; uint32 max_count; } lsa_RefDomainList; NTSTATUS lsa_LookupNames ( [in,ref] policy_handle *handle, - [in] uint32 num_names, + [in,range(0,1000)] uint32 num_names, [in,ref,size_is(num_names)] lsa_Name *names, [out] lsa_RefDomainList *domains, [in,out,ref] lsa_TransSidArray *sids, @@ -327,7 +327,7 @@ } lsa_TranslatedName; typedef struct { - uint32 count; + [range(0,1000)] uint32 count; [size_is(count)] lsa_TranslatedName *names; } lsa_TransNameArray; diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index a1821963bf..ce9f9f39ff 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -22,8 +22,10 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_lsa.h" +#include "librpc/gen_ndr/ndr_samr.h" #include "rpc_server/dcerpc_server.h" #include "rpc_server/common/common.h" +#include "lib/ldb/include/ldb.h" /* this type allows us to distinguish handle types @@ -384,9 +386,129 @@ static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX * lsa_LookupSids */ static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct lsa_LookupSids *r) + struct lsa_LookupSids *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + struct lsa_policy_state *state; + struct dcesrv_handle *h; + int i; + NTSTATUS status = NT_STATUS_OK; + + r->out.domains = NULL; + + DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); + + state = h->data; + + r->out.domains = talloc_zero_p(mem_ctx, struct lsa_RefDomainList); + if (r->out.domains == NULL) { + return NT_STATUS_NO_MEMORY; + } + + r->out.names = talloc_zero_p(mem_ctx, struct lsa_TransNameArray); + if (r->out.domains == NULL) { + return NT_STATUS_NO_MEMORY; + } + + *r->out.count = 0; + + r->out.names->names = talloc_array_p(r->out.names, struct lsa_TranslatedName, + r->in.sids->num_sids); + if (r->out.names->names == NULL) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0;i<r->in.sids->num_sids;i++) { + const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL}; + struct dom_sid *sid = r->in.sids->sids[i].sid; + char *sid_str = dom_sid_string(mem_ctx, sid); + int ret, j; + struct ldb_message **res; + const char *name, *authority_name; + struct dom_sid *authority_sid; + uint32_t atype, rtype; + const struct { + const char *sid_prefix; + const char *authority_name; + } authority_names[] = { + { "S-1-5", "NT AUTHORITY" } + }; + + r->out.names->count++; + (*r->out.count)++; + + r->out.names->names[i].sid_type = SID_NAME_UNKNOWN; + r->out.names->names[i].name.name = sid_str; + r->out.names->names[i].sid_index = 0xFFFFFFFF; + + if (sid_str == NULL) { + r->out.names->names[i].name.name = "(SIDERROR)"; + status = STATUS_SOME_UNMAPPED; + continue; + } + + /* work out the authority name */ + authority_name = talloc_strndup(mem_ctx, sid_str, 5); + authority_sid = dom_sid_parse_talloc(mem_ctx, authority_name); + if (!authority_name || !authority_sid) { + return NT_STATUS_NO_MEMORY; + } + for (j=0;j<ARRAY_SIZE(authority_names);j++) { + if (strncmp(sid_str, authority_names[j].sid_prefix, + strlen(authority_names[j].sid_prefix)) == 0) { + authority_name = authority_names[j].authority_name; + break; + } + } + + /* see if we've already done this authority name */ + for (j=0;j<r->out.domains->count;j++) { + if (strcmp(authority_name, r->out.domains->domains[j].name.name) == 0) { + break; + } + } + if (j == r->out.domains->count) { + r->out.domains->domains = talloc_realloc_p(r->out.domains, + r->out.domains->domains, + struct lsa_TrustInformation, + r->out.domains->count+1); + if (r->out.domains == NULL) { + return NT_STATUS_NO_MEMORY; + } + r->out.domains->domains[j].name.name = authority_name; + r->out.domains->domains[j].sid = authority_sid; + r->out.domains->count++; + } + + ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "objectSid=%s", sid_str); + if (ret != 1) { + status = STATUS_SOME_UNMAPPED; + continue; + } + + name = ldb_msg_find_string(res[0], "sAMAccountName", NULL); + if (name == NULL) { + status = STATUS_SOME_UNMAPPED; + continue; + } + + atype = samdb_result_uint(res[0], "sAMAccountType", 0); + if (atype == 0) { + status = STATUS_SOME_UNMAPPED; + continue; + } + + rtype = samdb_atype_map(atype); + if (rtype == SID_NAME_UNKNOWN) { + status = STATUS_SOME_UNMAPPED; + continue; + } + + r->out.names->names[i].sid_type = rtype; + r->out.names->names[i].name.name = name; + r->out.names->names[i].sid_index = 0; + } + + return status; } |