/* lsa_LookupSids */ NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_LookupSids *r) { enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); struct lsa_LookupSids2 r2; NTSTATUS status; uint32_t i; if (transport != NCACN_NP && transport != NCALRPC) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } ZERO_STRUCT(r2); r2.in.handle = r->in.handle; r2.in.sids = r->in.sids; r2.in.names = NULL; r2.in.level = r->in.level; r2.in.count = r->in.count; r2.in.lookup_options = 0; r2.in.client_revision = 0; r2.out.count = r->out.count; r2.out.names = NULL; r2.out.domains = r->out.domains; status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2); /* we deliberately don't check for error from the above, as even on error we are supposed to return the names */ r->out.domains = r2.out.domains; if (!r2.out.names) { r->out.names = NULL; return status; } r->out.names = talloc(mem_ctx, struct lsa_TransNameArray); if (r->out.names == NULL) { return NT_STATUS_NO_MEMORY; } r->out.names->count = r2.out.names->count; r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName, r->out.names->count); if (r->out.names->names == NULL) { return NT_STATUS_NO_MEMORY; } for (i=0;i<r->out.names->count;i++) { r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type; r->out.names->names[i].name.string = r2.out.names->names[i].name.string; r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index; } return status; }
/* lsa_LookupSids */ NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_LookupSids *r) { struct lsa_LookupSids2 r2; NTSTATUS status; int i; ZERO_STRUCT(r2); r2.in.handle = r->in.handle; r2.in.sids = r->in.sids; r2.in.names = NULL; r2.in.level = r->in.level; r2.in.count = r->in.count; r2.in.lookup_options = 0; r2.in.client_revision = 0; r2.out.count = r->out.count; r2.out.names = NULL; r2.out.domains = r->out.domains; status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2); /* we deliberately don't check for error from the above, as even on error we are supposed to return the names */ r->out.domains = r2.out.domains; if (!r2.out.names) { r->out.names = NULL; return status; } r->out.names = talloc(mem_ctx, struct lsa_TransNameArray); if (r->out.names == NULL) { return NT_STATUS_NO_MEMORY; } r->out.names->count = r2.out.names->count; r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName, r->out.names->count); if (r->out.names->names == NULL) { return NT_STATUS_NO_MEMORY; } for (i=0; i<r->out.names->count; i++) { r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type; r->out.names->names[i].name.string = r2.out.names->names[i].name.string; r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index; } return status; }
/* lsa_LookupSids3 Identical to LookupSids2, but doesn't take a policy handle */ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_LookupSids3 *r) { struct lsa_LookupSids2 r2; struct lsa_OpenPolicy2 pol; NTSTATUS status; struct dcesrv_handle *h; ZERO_STRUCT(r2); /* No policy handle on the wire, so make one up here */ r2.in.handle = talloc(mem_ctx, struct policy_handle); if (!r2.in.handle) { return NT_STATUS_NO_MEMORY; } pol.out.handle = r2.in.handle; pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; pol.in.attr = NULL; pol.in.system_name = NULL; status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol); if (!NT_STATUS_IS_OK(status)) { return status; } /* ensure this handle goes away at the end of this call */ DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY); talloc_steal(mem_ctx, h); r2.in.sids = r->in.sids; r2.in.names = r->in.names; r2.in.level = r->in.level; r2.in.count = r->in.count; r2.in.lookup_options = r->in.lookup_options; r2.in.client_revision = r->in.client_revision; r2.out.count = r->out.count; r2.out.names = r->out.names; r2.out.domains = r->out.domains; status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2); r->out.domains = r2.out.domains; r->out.names = r2.out.names; r->out.count = r2.out.count; return status; }