summaryrefslogtreecommitdiff
path: root/source4/rpc_server/lsa/dcesrv_lsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/rpc_server/lsa/dcesrv_lsa.c')
-rw-r--r--source4/rpc_server/lsa/dcesrv_lsa.c126
1 files changed, 124 insertions, 2 deletions
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;
}