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 /source4 | |
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)
Diffstat (limited to 'source4')
-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; } |