summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-11-18 05:17:24 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:58 -0500
commit9b6c08a0d19929c8928e692de2156e81decc4048 (patch)
tree895d615f5f5bfd0bd528e46f43d816e20917345a
parent0b691afe81c2778de30f20c03ab2a5f29473f799 (diff)
downloadsamba-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.idl14
-rw-r--r--source4/rpc_server/lsa/dcesrv_lsa.c126
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;
}