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 event_context *ev_ctx,
199 struct loadparm_context *lp_ctx,
200 struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
201 const char *name, const char **authority_name,
202 struct dom_sid **sid, enum lsa_SidType *rtype)
205 struct ldb_message **res;
206 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
209 const char *username;
210 struct ldb_dn *domain_dn;
211 struct dom_sid *domain_sid;
214 p = strchr_m(name, '\\');
216 domain = talloc_strndup(mem_ctx, name, p-name);
218 return NT_STATUS_NO_MEMORY;
221 } else if (strchr_m(name, '@')) {
222 status = crack_name_to_nt4_name(mem_ctx, ev_ctx, lp_ctx, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, name, &domain, &username);
223 if (!NT_STATUS_IS_OK(status)) {
224 DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n", name, nt_errstr(status)));
233 /* Look up table of well known names */
234 status = lookup_well_known_names(mem_ctx, NULL, username, authority_name, sid, rtype);
235 if (NT_STATUS_IS_OK(status)) {
239 if (strcasecmp_m(username, NAME_NT_AUTHORITY) == 0) {
240 *authority_name = NAME_NT_AUTHORITY;
241 *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
242 *rtype = SID_NAME_DOMAIN;
245 if (strcasecmp_m(username, NAME_BUILTIN) == 0) {
246 *authority_name = NAME_BUILTIN;
247 *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
248 *rtype = SID_NAME_DOMAIN;
251 if (strcasecmp_m(username, state->domain_dns) == 0) {
252 *authority_name = state->domain_name;
253 *sid = state->domain_sid;
254 *rtype = SID_NAME_DOMAIN;
257 if (strcasecmp_m(username, state->domain_name) == 0) {
258 *authority_name = state->domain_name;
259 *sid = state->domain_sid;
260 *rtype = SID_NAME_DOMAIN;
264 /* Perhaps this is a well known user? */
265 name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_NT_AUTHORITY, username);
267 return NT_STATUS_NO_MEMORY;
269 status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
270 if (NT_STATUS_IS_OK(status)) {
274 /* Perhaps this is a BUILTIN user? */
275 name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_BUILTIN, username);
277 return NT_STATUS_NO_MEMORY;
279 status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
280 if (NT_STATUS_IS_OK(status)) {
284 /* OK, I give up - perhaps we need to assume the user is in our domain? */
285 name = talloc_asprintf(mem_ctx, "%s\\%s", state->domain_name, username);
287 return NT_STATUS_NO_MEMORY;
289 status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
290 if (NT_STATUS_IS_OK(status)) {
294 return STATUS_SOME_UNMAPPED;
295 } else if (strcasecmp_m(domain, NAME_NT_AUTHORITY) == 0) {
297 *authority_name = NAME_NT_AUTHORITY;
298 *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
299 *rtype = SID_NAME_DOMAIN;
303 /* Look up table of well known names */
304 return lookup_well_known_names(mem_ctx, domain, username, authority_name,
306 } else if (strcasecmp_m(domain, NAME_BUILTIN) == 0) {
307 *authority_name = NAME_BUILTIN;
308 domain_dn = state->builtin_dn;
309 } else if (strcasecmp_m(domain, state->domain_dns) == 0) {
310 *authority_name = state->domain_name;
311 domain_dn = state->domain_dn;
312 } else if (strcasecmp_m(domain, state->domain_name) == 0) {
313 *authority_name = state->domain_name;
314 domain_dn = state->domain_dn;
316 /* Not local, need to ask winbind in future */
317 return STATUS_SOME_UNMAPPED;
320 ret = gendb_search_dn(state->sam_ldb, mem_ctx, domain_dn, &res, attrs);
322 domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
323 if (domain_sid == NULL) {
324 return NT_STATUS_INVALID_SID;
327 return NT_STATUS_INVALID_SID;
332 *rtype = SID_NAME_DOMAIN;
336 ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
337 "(&(sAMAccountName=%s)(objectSid=*))",
338 ldb_binary_encode_string(mem_ctx, username));
340 return NT_STATUS_INVALID_SID;
343 for (i=0; i < ret; i++) {
344 *sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid");
346 return NT_STATUS_INVALID_SID;
349 /* Check that this is in the domain */
350 if (!dom_sid_in_domain(domain_sid, *sid)) {
354 atype = samdb_result_uint(res[i], "sAMAccountType", 0);
356 *rtype = samdb_atype_map(atype);
357 if (*rtype == SID_NAME_UNKNOWN) {
358 return STATUS_SOME_UNMAPPED;
364 /* need to check for an allocated sid */
366 return NT_STATUS_INVALID_SID;
371 add to the lsa_RefDomainList for LookupSids and LookupNames
373 static NTSTATUS dcesrv_lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
374 enum lsa_SidType rtype,
375 const char *authority_name,
377 struct lsa_RefDomainList *domains,
380 struct dom_sid *authority_sid;
383 if (rtype != SID_NAME_DOMAIN) {
384 authority_sid = dom_sid_dup(mem_ctx, sid);
385 if (authority_sid == NULL) {
386 return NT_STATUS_NO_MEMORY;
388 authority_sid->num_auths--;
393 /* see if we've already done this authority name */
394 for (i=0;i<domains->count;i++) {
395 if (strcasecmp_m(authority_name, domains->domains[i].name.string) == 0) {
401 domains->domains = talloc_realloc(domains,
403 struct lsa_DomainInfo,
405 if (domains->domains == NULL) {
406 return NT_STATUS_NO_MEMORY;
408 domains->domains[i].name.string = authority_name;
409 domains->domains[i].sid = authority_sid;
411 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
418 lookup a name for 1 SID
420 static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
421 struct dom_sid *sid, const char *sid_str,
422 const char **authority_name,
423 const char **name, enum lsa_SidType *rtype)
428 struct ldb_message **res;
429 struct ldb_dn *domain_dn;
430 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "cn", NULL};
432 status = lookup_well_known_sids(mem_ctx, sid_str, authority_name, name, rtype);
433 if (NT_STATUS_IS_OK(status)) {
437 if (dom_sid_in_domain(state->domain_sid, sid)) {
438 *authority_name = state->domain_name;
439 domain_dn = state->domain_dn;
440 } else if (dom_sid_in_domain(state->builtin_sid, sid)) {
441 *authority_name = NAME_BUILTIN;
442 domain_dn = state->builtin_dn;
444 /* Not well known, our domain or built in */
446 /* In future, we must look at SID histories, and at trusted domains via winbind */
448 return NT_STATUS_NOT_FOUND;
451 ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
452 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
454 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
456 *name = ldb_msg_find_attr_as_string(res[0], "cn", NULL);
458 *name = talloc_strdup(mem_ctx, sid_str);
459 NT_STATUS_HAVE_NO_MEMORY(*name);
463 atype = samdb_result_uint(res[0], "sAMAccountType", 0);
465 *rtype = samdb_atype_map(atype);
470 /* need to re-add a check for an allocated sid */
472 return NT_STATUS_NOT_FOUND;
479 NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
481 struct lsa_LookupSids2 *r)
483 struct lsa_policy_state *state;
485 NTSTATUS status = NT_STATUS_OK;
487 r->out.domains = NULL;
489 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
490 if (!NT_STATUS_IS_OK(status)) {
494 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
495 if (r->out.domains == NULL) {
496 return NT_STATUS_NO_MEMORY;
499 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
500 if (r->out.names == NULL) {
501 return NT_STATUS_NO_MEMORY;
506 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
507 r->in.sids->num_sids);
508 if (r->out.names->names == NULL) {
509 return NT_STATUS_NO_MEMORY;
512 for (i=0;i<r->in.sids->num_sids;i++) {
513 struct dom_sid *sid = r->in.sids->sids[i].sid;
514 char *sid_str = dom_sid_string(mem_ctx, sid);
515 const char *name, *authority_name;
516 enum lsa_SidType rtype;
520 r->out.names->count++;
522 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
523 r->out.names->names[i].name.string = sid_str;
524 r->out.names->names[i].sid_index = 0xFFFFFFFF;
525 r->out.names->names[i].unknown = 0;
527 if (sid_str == NULL) {
528 r->out.names->names[i].name.string = "(SIDERROR)";
529 status = STATUS_SOME_UNMAPPED;
533 status2 = dcesrv_lsa_lookup_sid(state, mem_ctx, sid, sid_str,
534 &authority_name, &name, &rtype);
535 if (!NT_STATUS_IS_OK(status2)) {
536 status = STATUS_SOME_UNMAPPED;
540 /* set up the authority table */
541 status2 = dcesrv_lsa_authority_list(state, mem_ctx, rtype,
543 r->out.domains, &sid_index);
544 if (!NT_STATUS_IS_OK(status2)) {
548 r->out.names->names[i].sid_type = rtype;
549 r->out.names->names[i].name.string = name;
550 r->out.names->names[i].sid_index = sid_index;
551 r->out.names->names[i].unknown = 0;
556 if (*r->out.count == 0) {
557 return NT_STATUS_NONE_MAPPED;
559 if (*r->out.count != r->in.sids->num_sids) {
560 return STATUS_SOME_UNMAPPED;
570 Identical to LookupSids2, but doesn't take a policy handle
573 NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
575 struct lsa_LookupSids3 *r)
577 struct lsa_LookupSids2 r2;
578 struct lsa_OpenPolicy2 pol;
580 struct dcesrv_handle *h;
582 /* No policy handle on the wire, so make one up here */
583 r2.in.handle = talloc(mem_ctx, struct policy_handle);
585 return NT_STATUS_NO_MEMORY;
588 pol.out.handle = r2.in.handle;
589 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
591 pol.in.system_name = NULL;
592 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
593 if (!NT_STATUS_IS_OK(status)) {
597 /* ensure this handle goes away at the end of this call */
598 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
599 talloc_steal(mem_ctx, h);
601 r2.in.sids = r->in.sids;
602 r2.in.names = r->in.names;
603 r2.in.level = r->in.level;
604 r2.in.count = r->in.count;
605 r2.in.unknown1 = r->in.unknown1;
606 r2.in.unknown2 = r->in.unknown2;
607 r2.out.count = r->out.count;
608 r2.out.names = r->out.names;
610 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
611 if (dce_call->fault_code != 0) {
615 r->out.domains = r2.out.domains;
616 r->out.names = r2.out.names;
617 r->out.count = r2.out.count;
626 NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
627 struct lsa_LookupSids *r)
629 struct lsa_LookupSids2 r2;
633 r2.in.handle = r->in.handle;
634 r2.in.sids = r->in.sids;
636 r2.in.level = r->in.level;
637 r2.in.count = r->in.count;
640 r2.out.count = r->out.count;
643 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
644 if (dce_call->fault_code != 0) {
648 r->out.domains = r2.out.domains;
654 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
655 if (r->out.names == NULL) {
656 return NT_STATUS_NO_MEMORY;
658 r->out.names->count = r2.out.names->count;
659 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
660 r->out.names->count);
661 if (r->out.names->names == NULL) {
662 return NT_STATUS_NO_MEMORY;
664 for (i=0;i<r->out.names->count;i++) {
665 r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
666 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
667 r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
677 NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
679 struct lsa_LookupNames3 *r)
681 struct lsa_policy_state *policy_state;
682 struct dcesrv_handle *policy_handle;
684 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
686 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
688 policy_state = policy_handle->data;
690 r->out.domains = NULL;
692 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
693 if (r->out.domains == NULL) {
694 return NT_STATUS_NO_MEMORY;
697 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
698 if (r->out.sids == NULL) {
699 return NT_STATUS_NO_MEMORY;
704 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
706 if (r->out.sids->sids == NULL) {
707 return NT_STATUS_NO_MEMORY;
710 for (i=0;i<r->in.num_names;i++) {
711 const char *name = r->in.names[i].string;
712 const char *authority_name;
715 enum lsa_SidType rtype;
718 r->out.sids->count++;
720 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
721 r->out.sids->sids[i].sid = NULL;
722 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
723 r->out.sids->sids[i].unknown = 0;
725 status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, policy_state, mem_ctx, name, &authority_name, &sid, &rtype);
726 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
730 status2 = dcesrv_lsa_authority_list(policy_state, mem_ctx, rtype, authority_name,
731 sid, r->out.domains, &sid_index);
732 if (!NT_STATUS_IS_OK(status2)) {
736 r->out.sids->sids[i].sid_type = rtype;
737 r->out.sids->sids[i].sid = sid;
738 r->out.sids->sids[i].sid_index = sid_index;
739 r->out.sids->sids[i].unknown = 0;
744 if (*r->out.count == 0) {
745 return NT_STATUS_NONE_MAPPED;
747 if (*r->out.count != r->in.num_names) {
748 return STATUS_SOME_UNMAPPED;
757 Identical to LookupNames3, but doesn't take a policy handle
760 NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
761 struct lsa_LookupNames4 *r)
763 struct lsa_LookupNames3 r2;
764 struct lsa_OpenPolicy2 pol;
766 struct dcesrv_handle *h;
768 /* No policy handle on the wire, so make one up here */
769 r2.in.handle = talloc(mem_ctx, struct policy_handle);
771 return NT_STATUS_NO_MEMORY;
774 pol.out.handle = r2.in.handle;
775 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
777 pol.in.system_name = NULL;
778 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
779 if (!NT_STATUS_IS_OK(status)) {
783 /* ensure this handle goes away at the end of this call */
784 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
785 talloc_steal(mem_ctx, h);
787 r2.in.num_names = r->in.num_names;
788 r2.in.names = r->in.names;
789 r2.in.sids = r->in.sids;
790 r2.in.count = r->in.count;
791 r2.in.unknown1 = r->in.unknown1;
792 r2.in.unknown2 = r->in.unknown2;
793 r2.out.domains = r->out.domains;
794 r2.out.sids = r->out.sids;
795 r2.out.count = r->out.count;
797 status = dcesrv_lsa_LookupNames3(dce_call, mem_ctx, &r2);
798 if (dce_call->fault_code != 0) {
802 r->out.domains = r2.out.domains;
803 r->out.sids = r2.out.sids;
804 r->out.count = r2.out.count;
811 NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
813 struct lsa_LookupNames2 *r)
815 struct lsa_policy_state *state;
816 struct dcesrv_handle *h;
818 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
820 r->out.domains = NULL;
822 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
826 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
827 if (r->out.domains == NULL) {
828 return NT_STATUS_NO_MEMORY;
831 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
832 if (r->out.sids == NULL) {
833 return NT_STATUS_NO_MEMORY;
838 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
840 if (r->out.sids->sids == NULL) {
841 return NT_STATUS_NO_MEMORY;
844 for (i=0;i<r->in.num_names;i++) {
845 const char *name = r->in.names[i].string;
846 const char *authority_name;
848 uint32_t rtype, sid_index;
851 r->out.sids->count++;
853 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
854 r->out.sids->sids[i].rid = 0xFFFFFFFF;
855 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
856 r->out.sids->sids[i].unknown = 0;
858 status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, state, mem_ctx, name,
859 &authority_name, &sid, &rtype);
860 if (!NT_STATUS_IS_OK(status2)) {
864 status2 = dcesrv_lsa_authority_list(state, mem_ctx, rtype, authority_name,
865 sid, r->out.domains, &sid_index);
866 if (!NT_STATUS_IS_OK(status2)) {
870 r->out.sids->sids[i].sid_type = rtype;
871 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
872 r->out.sids->sids[i].sid_index = sid_index;
873 r->out.sids->sids[i].unknown = 0;
878 if (*r->out.count == 0) {
879 return NT_STATUS_NONE_MAPPED;
881 if (*r->out.count != r->in.num_names) {
882 return STATUS_SOME_UNMAPPED;
891 NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
892 struct lsa_LookupNames *r)
894 struct lsa_LookupNames2 r2;
898 r2.in.handle = r->in.handle;
899 r2.in.num_names = r->in.num_names;
900 r2.in.names = r->in.names;
902 r2.in.level = r->in.level;
903 r2.in.count = r->in.count;
906 r2.out.count = r->out.count;
908 status = dcesrv_lsa_LookupNames2(dce_call, mem_ctx, &r2);
909 if (dce_call->fault_code != 0) {
913 r->out.domains = r2.out.domains;
914 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
915 if (r->out.sids == NULL) {
916 return NT_STATUS_NO_MEMORY;
918 r->out.sids->count = r2.out.sids->count;
919 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
921 if (r->out.sids->sids == NULL) {
922 return NT_STATUS_NO_MEMORY;
924 for (i=0;i<r->out.sids->count;i++) {
925 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
926 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
927 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;