2 Unix SMB/CIFS implementation.
4 endpoint server for the lsarpc pipe
6 Copyright (C) Andrew Tridgell 2004
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "rpc_server/lsa/lsa.h"
34 .rtype = SID_NAME_WKN_GRP,
37 .name = "CREATOR OWNER",
38 .sid = SID_CREATOR_OWNER,
39 .rtype = SID_NAME_WKN_GRP,
42 .name = "CREATOR GROUP",
43 .sid = SID_CREATOR_GROUP,
44 .rtype = SID_NAME_WKN_GRP,
47 .domain = "NT AUTHORITY",
50 .rtype = SID_NAME_WKN_GRP,
53 .domain = "NT AUTHORITY",
55 .sid = SID_NT_NETWORK,
56 .rtype = SID_NAME_WKN_GRP,
59 .domain = "NT AUTHORITY",
62 .rtype = SID_NAME_WKN_GRP,
65 .domain = "NT AUTHORITY",
66 .name = "Interactive",
67 .sid = SID_NT_INTERACTIVE,
68 .rtype = SID_NAME_WKN_GRP,
71 .domain = "NT AUTHORITY",
73 .sid = SID_NT_SERVICE,
74 .rtype = SID_NAME_WKN_GRP,
77 .domain = "NT AUTHORITY",
78 .name = "ANONYMOUS LOGON",
79 .sid = SID_NT_ANONYMOUS,
80 .rtype = SID_NAME_WKN_GRP,
83 .domain = "NT AUTHORITY",
86 .rtype = SID_NAME_WKN_GRP,
89 .domain = "NT AUTHORITY",
90 .name = "ServerLogon",
91 .sid = SID_NT_ENTERPRISE_DCS,
92 .rtype = SID_NAME_WKN_GRP,
95 .domain = "NT AUTHORITY",
98 .rtype = SID_NAME_WKN_GRP,
101 .domain = "NT AUTHORITY",
102 .name = "Authenticated Users",
103 .sid = SID_NT_AUTHENTICATED_USERS,
104 .rtype = SID_NAME_WKN_GRP,
107 .domain = "NT AUTHORITY",
108 .name = "Restricted",
109 .sid = SID_NT_RESTRICTED,
110 .rtype = SID_NAME_WKN_GRP,
113 .domain = "NT AUTHORITY",
114 .name = "Termainal Server User",
115 .sid = SID_NT_TERMINAL_SERVER_USERS,
116 .rtype = SID_NAME_WKN_GRP,
119 .domain = "NT AUTHORITY",
120 .name = "Remote Interactive Logon",
121 .sid = SID_NT_REMOTE_INTERACTIVE,
122 .rtype = SID_NAME_WKN_GRP,
125 .domain = "NT AUTHORITY",
126 .name = "This Organization",
127 .sid = SID_NT_THIS_ORGANISATION,
128 .rtype = SID_NAME_WKN_GRP,
131 .domain = "NT AUTHORITY",
133 .sid = SID_NT_SYSTEM,
134 .rtype = SID_NAME_WKN_GRP,
137 .domain = "NT AUTHORITY",
138 .name = "Local Service",
139 .sid = SID_NT_LOCAL_SERVICE,
140 .rtype = SID_NAME_WKN_GRP,
143 .domain = "NT AUTHORITY",
144 .name = "Network Service",
145 .sid = SID_NT_NETWORK_SERVICE,
146 .rtype = SID_NAME_WKN_GRP,
153 static NTSTATUS lookup_well_known_names(TALLOC_CTX *mem_ctx, const char *domain,
154 const char *name, const char **authority_name,
155 struct dom_sid **sid, uint32_t *rtype)
158 for (i=0; well_known[i].sid; i++) {
160 if (strcasecmp_m(domain, well_known[i].domain) == 0
161 && strcasecmp_m(name, well_known[i].name) == 0) {
162 *authority_name = well_known[i].domain;
163 *sid = dom_sid_parse_talloc(mem_ctx, well_known[i].sid);
164 *rtype = well_known[i].rtype;
168 if (strcasecmp_m(name, well_known[i].name) == 0) {
169 *authority_name = well_known[i].domain;
170 *sid = dom_sid_parse_talloc(mem_ctx, well_known[i].sid);
171 *rtype = well_known[i].rtype;
176 return NT_STATUS_NOT_FOUND;
179 static NTSTATUS lookup_well_known_sids(TALLOC_CTX *mem_ctx,
180 const char *sid_str, const char **authority_name,
181 const char **name, uint32_t *rtype)
184 for (i=0; well_known[i].sid; i++) {
185 if (strcasecmp_m(sid_str, well_known[i].sid) == 0) {
186 *authority_name = well_known[i].domain;
187 *name = well_known[i].name;
188 *rtype = well_known[i].rtype;
192 return NT_STATUS_NOT_FOUND;
196 lookup a SID for 1 name
198 static NTSTATUS dcesrv_lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
199 const char *name, const char **authority_name,
200 struct dom_sid **sid, enum lsa_SidType *rtype)
203 struct ldb_message **res;
204 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
207 const char *username;
208 struct ldb_dn *domain_dn;
209 struct dom_sid *domain_sid;
212 p = strchr_m(name, '\\');
214 domain = talloc_strndup(mem_ctx, name, p-name);
216 return NT_STATUS_NO_MEMORY;
219 } else if (strchr_m(name, '@')) {
220 status = crack_name_to_nt4_name(mem_ctx, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, name, &domain, &username);
221 if (!NT_STATUS_IS_OK(status)) {
230 /* Look up table of well known names */
231 status = lookup_well_known_names(mem_ctx, NULL, username, authority_name, sid, rtype);
232 if (NT_STATUS_IS_OK(status)) {
236 if (strcasecmp_m(username, NAME_NT_AUTHORITY) == 0) {
237 *authority_name = NAME_NT_AUTHORITY;
238 *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
239 *rtype = SID_NAME_DOMAIN;
242 if (strcasecmp_m(username, NAME_BUILTIN) == 0) {
243 *authority_name = NAME_BUILTIN;
244 *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
245 *rtype = SID_NAME_DOMAIN;
248 if (strcasecmp_m(username, state->domain_dns) == 0) {
249 *authority_name = state->domain_name;
250 *sid = state->domain_sid;
251 *rtype = SID_NAME_DOMAIN;
254 if (strcasecmp_m(username, state->domain_name) == 0) {
255 *authority_name = state->domain_name;
256 *sid = state->domain_sid;
257 *rtype = SID_NAME_DOMAIN;
261 /* Perhaps this is a well known user? */
262 name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_NT_AUTHORITY, username);
264 return NT_STATUS_NO_MEMORY;
266 status = dcesrv_lsa_lookup_name(state, mem_ctx, name, authority_name, sid, rtype);
267 if (NT_STATUS_IS_OK(status)) {
271 /* Perhaps this is a BUILTIN user? */
272 name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_BUILTIN, username);
274 return NT_STATUS_NO_MEMORY;
276 status = dcesrv_lsa_lookup_name(state, mem_ctx, name, authority_name, sid, rtype);
277 if (NT_STATUS_IS_OK(status)) {
281 /* OK, I give up - perhaps we need to assume the user is in our domain? */
282 name = talloc_asprintf(mem_ctx, "%s\\%s", state->domain_name, username);
284 return NT_STATUS_NO_MEMORY;
286 status = dcesrv_lsa_lookup_name(state, mem_ctx, name, authority_name, sid, rtype);
287 if (NT_STATUS_IS_OK(status)) {
291 return STATUS_SOME_UNMAPPED;
292 } else if (strcasecmp_m(domain, NAME_NT_AUTHORITY) == 0) {
294 *authority_name = NAME_NT_AUTHORITY;
295 *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
296 *rtype = SID_NAME_DOMAIN;
300 /* Look up table of well known names */
301 return lookup_well_known_names(mem_ctx, domain, username, authority_name,
303 } else if (strcasecmp_m(domain, NAME_BUILTIN) == 0) {
304 *authority_name = NAME_BUILTIN;
305 domain_dn = state->builtin_dn;
306 } else if (strcasecmp_m(domain, state->domain_dns) == 0) {
307 *authority_name = state->domain_name;
308 domain_dn = state->domain_dn;
309 } else if (strcasecmp_m(domain, state->domain_name) == 0) {
310 *authority_name = state->domain_name;
311 domain_dn = state->domain_dn;
313 /* Not local, need to ask winbind in future */
314 return STATUS_SOME_UNMAPPED;
317 ret = gendb_search_dn(state->sam_ldb, mem_ctx, domain_dn, &res, attrs);
319 domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
320 if (domain_sid == NULL) {
321 return NT_STATUS_INVALID_SID;
324 return NT_STATUS_INVALID_SID;
329 *rtype = SID_NAME_DOMAIN;
333 ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
334 "(&(sAMAccountName=%s)(objectSid=*))",
335 ldb_binary_encode_string(mem_ctx, username));
337 return NT_STATUS_INVALID_SID;
340 for (i=0; i < ret; i++) {
341 *sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid");
343 return NT_STATUS_INVALID_SID;
346 /* Check that this is in the domain */
347 if (!dom_sid_in_domain(domain_sid, *sid)) {
351 atype = samdb_result_uint(res[i], "sAMAccountType", 0);
353 *rtype = samdb_atype_map(atype);
354 if (*rtype == SID_NAME_UNKNOWN) {
355 return STATUS_SOME_UNMAPPED;
361 /* need to add a call into sidmap to check for a allocated sid */
363 return NT_STATUS_INVALID_SID;
368 add to the lsa_RefDomainList for LookupSids and LookupNames
370 static NTSTATUS dcesrv_lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
371 enum lsa_SidType rtype,
372 const char *authority_name,
374 struct lsa_RefDomainList *domains,
377 struct dom_sid *authority_sid;
380 if (rtype != SID_NAME_DOMAIN) {
381 authority_sid = dom_sid_dup(mem_ctx, sid);
382 if (authority_sid == NULL) {
383 return NT_STATUS_NO_MEMORY;
385 authority_sid->num_auths--;
390 /* see if we've already done this authority name */
391 for (i=0;i<domains->count;i++) {
392 if (strcasecmp_m(authority_name, domains->domains[i].name.string) == 0) {
398 domains->domains = talloc_realloc(domains,
400 struct lsa_DomainInfo,
402 if (domains->domains == NULL) {
403 return NT_STATUS_NO_MEMORY;
405 domains->domains[i].name.string = authority_name;
406 domains->domains[i].sid = authority_sid;
408 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
415 lookup a name for 1 SID
417 static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
418 struct dom_sid *sid, const char *sid_str,
419 const char **authority_name,
420 const char **name, enum lsa_SidType *rtype)
425 struct ldb_message **res;
426 struct ldb_dn *domain_dn;
427 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "cn", NULL};
429 status = lookup_well_known_sids(mem_ctx, sid_str, authority_name, name, rtype);
430 if (NT_STATUS_IS_OK(status)) {
434 if (dom_sid_in_domain(state->domain_sid, sid)) {
435 *authority_name = state->domain_name;
436 domain_dn = state->domain_dn;
437 } else if (dom_sid_in_domain(state->builtin_sid, sid)) {
438 *authority_name = NAME_BUILTIN;
439 domain_dn = state->builtin_dn;
441 /* Not well known, our domain or built in */
443 /* In future, we must look at SID histories, and at trusted domains via winbind */
445 return NT_STATUS_NOT_FOUND;
448 ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
449 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
451 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
453 *name = ldb_msg_find_attr_as_string(res[0], "cn", NULL);
455 *name = talloc_strdup(mem_ctx, sid_str);
456 NT_STATUS_HAVE_NO_MEMORY(*name);
460 atype = samdb_result_uint(res[0], "sAMAccountType", 0);
462 *rtype = samdb_atype_map(atype);
467 /* need to re-add a call into sidmap to check for a allocated sid */
468 /* status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, rtype); */
470 return NT_STATUS_NOT_FOUND;
477 NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
479 struct lsa_LookupSids2 *r)
481 struct lsa_policy_state *state;
483 NTSTATUS status = NT_STATUS_OK;
485 r->out.domains = NULL;
487 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
488 if (!NT_STATUS_IS_OK(status)) {
492 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
493 if (r->out.domains == NULL) {
494 return NT_STATUS_NO_MEMORY;
497 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
498 if (r->out.names == NULL) {
499 return NT_STATUS_NO_MEMORY;
504 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
505 r->in.sids->num_sids);
506 if (r->out.names->names == NULL) {
507 return NT_STATUS_NO_MEMORY;
510 for (i=0;i<r->in.sids->num_sids;i++) {
511 struct dom_sid *sid = r->in.sids->sids[i].sid;
512 char *sid_str = dom_sid_string(mem_ctx, sid);
513 const char *name, *authority_name;
514 enum lsa_SidType rtype;
518 r->out.names->count++;
520 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
521 r->out.names->names[i].name.string = sid_str;
522 r->out.names->names[i].sid_index = 0xFFFFFFFF;
523 r->out.names->names[i].unknown = 0;
525 if (sid_str == NULL) {
526 r->out.names->names[i].name.string = "(SIDERROR)";
527 status = STATUS_SOME_UNMAPPED;
531 status2 = dcesrv_lsa_lookup_sid(state, mem_ctx, sid, sid_str,
532 &authority_name, &name, &rtype);
533 if (!NT_STATUS_IS_OK(status2)) {
534 status = STATUS_SOME_UNMAPPED;
538 /* set up the authority table */
539 status2 = dcesrv_lsa_authority_list(state, mem_ctx, rtype,
541 r->out.domains, &sid_index);
542 if (!NT_STATUS_IS_OK(status2)) {
546 r->out.names->names[i].sid_type = rtype;
547 r->out.names->names[i].name.string = name;
548 r->out.names->names[i].sid_index = sid_index;
549 r->out.names->names[i].unknown = 0;
554 if (*r->out.count == 0) {
555 return NT_STATUS_NONE_MAPPED;
557 if (*r->out.count != r->in.sids->num_sids) {
558 return STATUS_SOME_UNMAPPED;
568 Identical to LookupSids2, but doesn't take a policy handle
571 NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
573 struct lsa_LookupSids3 *r)
575 struct lsa_LookupSids2 r2;
576 struct lsa_OpenPolicy2 pol;
578 struct dcesrv_handle *h;
580 /* No policy handle on the wire, so make one up here */
581 r2.in.handle = talloc(mem_ctx, struct policy_handle);
583 return NT_STATUS_NO_MEMORY;
586 pol.out.handle = r2.in.handle;
587 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
589 pol.in.system_name = NULL;
590 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
591 if (!NT_STATUS_IS_OK(status)) {
595 /* ensure this handle goes away at the end of this call */
596 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
597 talloc_steal(mem_ctx, h);
599 r2.in.sids = r->in.sids;
600 r2.in.names = r->in.names;
601 r2.in.level = r->in.level;
602 r2.in.count = r->in.count;
603 r2.in.unknown1 = r->in.unknown1;
604 r2.in.unknown2 = r->in.unknown2;
605 r2.out.count = r->out.count;
606 r2.out.names = r->out.names;
608 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
609 if (dce_call->fault_code != 0) {
613 r->out.domains = r2.out.domains;
614 r->out.names = r2.out.names;
615 r->out.count = r2.out.count;
624 NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
625 struct lsa_LookupSids *r)
627 struct lsa_LookupSids2 r2;
631 r2.in.handle = r->in.handle;
632 r2.in.sids = r->in.sids;
634 r2.in.level = r->in.level;
635 r2.in.count = r->in.count;
638 r2.out.count = r->out.count;
641 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
642 if (dce_call->fault_code != 0) {
646 r->out.domains = r2.out.domains;
652 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
653 if (r->out.names == NULL) {
654 return NT_STATUS_NO_MEMORY;
656 r->out.names->count = r2.out.names->count;
657 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
658 r->out.names->count);
659 if (r->out.names->names == NULL) {
660 return NT_STATUS_NO_MEMORY;
662 for (i=0;i<r->out.names->count;i++) {
663 r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
664 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
665 r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
675 NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
677 struct lsa_LookupNames3 *r)
679 struct lsa_policy_state *policy_state;
680 struct dcesrv_handle *policy_handle;
683 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
685 policy_state = policy_handle->data;
687 r->out.domains = NULL;
689 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
690 if (r->out.domains == NULL) {
691 return NT_STATUS_NO_MEMORY;
694 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
695 if (r->out.sids == NULL) {
696 return NT_STATUS_NO_MEMORY;
701 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
703 if (r->out.sids->sids == NULL) {
704 return NT_STATUS_NO_MEMORY;
707 for (i=0;i<r->in.num_names;i++) {
708 const char *name = r->in.names[i].string;
709 const char *authority_name;
712 enum lsa_SidType rtype;
715 r->out.sids->count++;
717 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
718 r->out.sids->sids[i].sid = NULL;
719 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
720 r->out.sids->sids[i].unknown = 0;
722 status2 = dcesrv_lsa_lookup_name(policy_state, mem_ctx, name, &authority_name, &sid, &rtype);
723 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
727 status2 = dcesrv_lsa_authority_list(policy_state, mem_ctx, rtype, authority_name,
728 sid, r->out.domains, &sid_index);
729 if (!NT_STATUS_IS_OK(status2)) {
733 r->out.sids->sids[i].sid_type = rtype;
734 r->out.sids->sids[i].sid = sid;
735 r->out.sids->sids[i].sid_index = sid_index;
736 r->out.sids->sids[i].unknown = 0;
741 if (*r->out.count == 0) {
742 return NT_STATUS_NONE_MAPPED;
744 if (*r->out.count != r->in.num_names) {
745 return STATUS_SOME_UNMAPPED;
754 Identical to LookupNames3, but doesn't take a policy handle
757 NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
758 struct lsa_LookupNames4 *r)
760 struct lsa_LookupNames3 r2;
761 struct lsa_OpenPolicy2 pol;
763 struct dcesrv_handle *h;
765 /* No policy handle on the wire, so make one up here */
766 r2.in.handle = talloc(mem_ctx, struct policy_handle);
768 return NT_STATUS_NO_MEMORY;
771 pol.out.handle = r2.in.handle;
772 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
774 pol.in.system_name = NULL;
775 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
776 if (!NT_STATUS_IS_OK(status)) {
780 /* ensure this handle goes away at the end of this call */
781 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
782 talloc_steal(mem_ctx, h);
784 r2.in.num_names = r->in.num_names;
785 r2.in.names = r->in.names;
786 r2.in.sids = r->in.sids;
787 r2.in.count = r->in.count;
788 r2.in.unknown1 = r->in.unknown1;
789 r2.in.unknown2 = r->in.unknown2;
790 r2.out.domains = r->out.domains;
791 r2.out.sids = r->out.sids;
792 r2.out.count = r->out.count;
794 status = dcesrv_lsa_LookupNames3(dce_call, mem_ctx, &r2);
795 if (dce_call->fault_code != 0) {
799 r->out.domains = r2.out.domains;
800 r->out.sids = r2.out.sids;
801 r->out.count = r2.out.count;
808 NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
810 struct lsa_LookupNames2 *r)
812 struct lsa_policy_state *state;
813 struct dcesrv_handle *h;
816 r->out.domains = NULL;
818 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
822 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
823 if (r->out.domains == NULL) {
824 return NT_STATUS_NO_MEMORY;
827 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
828 if (r->out.sids == NULL) {
829 return NT_STATUS_NO_MEMORY;
834 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
836 if (r->out.sids->sids == NULL) {
837 return NT_STATUS_NO_MEMORY;
840 for (i=0;i<r->in.num_names;i++) {
841 const char *name = r->in.names[i].string;
842 const char *authority_name;
844 uint32_t rtype, sid_index;
847 r->out.sids->count++;
849 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
850 r->out.sids->sids[i].rid = 0xFFFFFFFF;
851 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
852 r->out.sids->sids[i].unknown = 0;
854 status2 = dcesrv_lsa_lookup_name(state, mem_ctx, name,
855 &authority_name, &sid, &rtype);
856 if (!NT_STATUS_IS_OK(status2)) {
860 status2 = dcesrv_lsa_authority_list(state, mem_ctx, rtype, authority_name,
861 sid, r->out.domains, &sid_index);
862 if (!NT_STATUS_IS_OK(status2)) {
866 r->out.sids->sids[i].sid_type = rtype;
867 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
868 r->out.sids->sids[i].sid_index = sid_index;
869 r->out.sids->sids[i].unknown = 0;
874 if (*r->out.count == 0) {
875 return NT_STATUS_NONE_MAPPED;
877 if (*r->out.count != r->in.num_names) {
878 return STATUS_SOME_UNMAPPED;
887 NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
888 struct lsa_LookupNames *r)
890 struct lsa_LookupNames2 r2;
894 r2.in.handle = r->in.handle;
895 r2.in.num_names = r->in.num_names;
896 r2.in.names = r->in.names;
898 r2.in.level = r->in.level;
899 r2.in.count = r->in.count;
902 r2.out.count = r->out.count;
904 status = dcesrv_lsa_LookupNames2(dce_call, mem_ctx, &r2);
905 if (dce_call->fault_code != 0) {
909 r->out.domains = r2.out.domains;
910 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
911 if (r->out.sids == NULL) {
912 return NT_STATUS_NO_MEMORY;
914 r->out.sids->count = r2.out.sids->count;
915 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
917 if (r->out.sids->sids == NULL) {
918 return NT_STATUS_NO_MEMORY;
920 for (i=0;i<r->out.sids->count;i++) {
921 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
922 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
923 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;