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 loadparm_context *lp_ctx,
199 struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
200 const char *name, const char **authority_name,
201 struct dom_sid **sid, enum lsa_SidType *rtype)
204 struct ldb_message **res;
205 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
208 const char *username;
209 struct ldb_dn *domain_dn;
210 struct dom_sid *domain_sid;
213 p = strchr_m(name, '\\');
215 domain = talloc_strndup(mem_ctx, name, p-name);
217 return NT_STATUS_NO_MEMORY;
220 } else if (strchr_m(name, '@')) {
221 status = crack_name_to_nt4_name(mem_ctx, lp_ctx, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, name, &domain, &username);
222 if (!NT_STATUS_IS_OK(status)) {
223 DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n", name, nt_errstr(status)));
232 /* Look up table of well known names */
233 status = lookup_well_known_names(mem_ctx, NULL, username, authority_name, sid, rtype);
234 if (NT_STATUS_IS_OK(status)) {
238 if (strcasecmp_m(username, NAME_NT_AUTHORITY) == 0) {
239 *authority_name = NAME_NT_AUTHORITY;
240 *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
241 *rtype = SID_NAME_DOMAIN;
244 if (strcasecmp_m(username, NAME_BUILTIN) == 0) {
245 *authority_name = NAME_BUILTIN;
246 *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
247 *rtype = SID_NAME_DOMAIN;
250 if (strcasecmp_m(username, state->domain_dns) == 0) {
251 *authority_name = state->domain_name;
252 *sid = state->domain_sid;
253 *rtype = SID_NAME_DOMAIN;
256 if (strcasecmp_m(username, state->domain_name) == 0) {
257 *authority_name = state->domain_name;
258 *sid = state->domain_sid;
259 *rtype = SID_NAME_DOMAIN;
263 /* Perhaps this is a well known user? */
264 name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_NT_AUTHORITY, username);
266 return NT_STATUS_NO_MEMORY;
268 status = dcesrv_lsa_lookup_name(lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
269 if (NT_STATUS_IS_OK(status)) {
273 /* Perhaps this is a BUILTIN user? */
274 name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_BUILTIN, username);
276 return NT_STATUS_NO_MEMORY;
278 status = dcesrv_lsa_lookup_name(lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
279 if (NT_STATUS_IS_OK(status)) {
283 /* OK, I give up - perhaps we need to assume the user is in our domain? */
284 name = talloc_asprintf(mem_ctx, "%s\\%s", state->domain_name, username);
286 return NT_STATUS_NO_MEMORY;
288 status = dcesrv_lsa_lookup_name(lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
289 if (NT_STATUS_IS_OK(status)) {
293 return STATUS_SOME_UNMAPPED;
294 } else if (strcasecmp_m(domain, NAME_NT_AUTHORITY) == 0) {
296 *authority_name = NAME_NT_AUTHORITY;
297 *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
298 *rtype = SID_NAME_DOMAIN;
302 /* Look up table of well known names */
303 return lookup_well_known_names(mem_ctx, domain, username, authority_name,
305 } else if (strcasecmp_m(domain, NAME_BUILTIN) == 0) {
306 *authority_name = NAME_BUILTIN;
307 domain_dn = state->builtin_dn;
308 } else if (strcasecmp_m(domain, state->domain_dns) == 0) {
309 *authority_name = state->domain_name;
310 domain_dn = state->domain_dn;
311 } else if (strcasecmp_m(domain, state->domain_name) == 0) {
312 *authority_name = state->domain_name;
313 domain_dn = state->domain_dn;
315 /* Not local, need to ask winbind in future */
316 return STATUS_SOME_UNMAPPED;
319 ret = gendb_search_dn(state->sam_ldb, mem_ctx, domain_dn, &res, attrs);
321 domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
322 if (domain_sid == NULL) {
323 return NT_STATUS_INVALID_SID;
326 return NT_STATUS_INVALID_SID;
331 *rtype = SID_NAME_DOMAIN;
335 ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
336 "(&(sAMAccountName=%s)(objectSid=*))",
337 ldb_binary_encode_string(mem_ctx, username));
339 return NT_STATUS_INVALID_SID;
342 for (i=0; i < ret; i++) {
343 *sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid");
345 return NT_STATUS_INVALID_SID;
348 /* Check that this is in the domain */
349 if (!dom_sid_in_domain(domain_sid, *sid)) {
353 atype = samdb_result_uint(res[i], "sAMAccountType", 0);
355 *rtype = samdb_atype_map(atype);
356 if (*rtype == SID_NAME_UNKNOWN) {
357 return STATUS_SOME_UNMAPPED;
363 /* need to check for an allocated sid */
365 return NT_STATUS_INVALID_SID;
370 add to the lsa_RefDomainList for LookupSids and LookupNames
372 static NTSTATUS dcesrv_lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
373 enum lsa_SidType rtype,
374 const char *authority_name,
376 struct lsa_RefDomainList *domains,
379 struct dom_sid *authority_sid;
382 if (rtype != SID_NAME_DOMAIN) {
383 authority_sid = dom_sid_dup(mem_ctx, sid);
384 if (authority_sid == NULL) {
385 return NT_STATUS_NO_MEMORY;
387 authority_sid->num_auths--;
392 /* see if we've already done this authority name */
393 for (i=0;i<domains->count;i++) {
394 if (strcasecmp_m(authority_name, domains->domains[i].name.string) == 0) {
400 domains->domains = talloc_realloc(domains,
402 struct lsa_DomainInfo,
404 if (domains->domains == NULL) {
405 return NT_STATUS_NO_MEMORY;
407 domains->domains[i].name.string = authority_name;
408 domains->domains[i].sid = authority_sid;
410 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
417 lookup a name for 1 SID
419 static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
420 struct dom_sid *sid, const char *sid_str,
421 const char **authority_name,
422 const char **name, enum lsa_SidType *rtype)
427 struct ldb_message **res;
428 struct ldb_dn *domain_dn;
429 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "cn", NULL};
431 status = lookup_well_known_sids(mem_ctx, sid_str, authority_name, name, rtype);
432 if (NT_STATUS_IS_OK(status)) {
436 if (dom_sid_in_domain(state->domain_sid, sid)) {
437 *authority_name = state->domain_name;
438 domain_dn = state->domain_dn;
439 } else if (dom_sid_in_domain(state->builtin_sid, sid)) {
440 *authority_name = NAME_BUILTIN;
441 domain_dn = state->builtin_dn;
443 /* Not well known, our domain or built in */
445 /* In future, we must look at SID histories, and at trusted domains via winbind */
447 return NT_STATUS_NOT_FOUND;
450 ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
451 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
453 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
455 *name = ldb_msg_find_attr_as_string(res[0], "cn", NULL);
457 *name = talloc_strdup(mem_ctx, sid_str);
458 NT_STATUS_HAVE_NO_MEMORY(*name);
462 atype = samdb_result_uint(res[0], "sAMAccountType", 0);
464 *rtype = samdb_atype_map(atype);
469 /* need to re-add a check for an allocated sid */
471 return NT_STATUS_NOT_FOUND;
478 NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
480 struct lsa_LookupSids2 *r)
482 struct lsa_policy_state *state;
484 NTSTATUS status = NT_STATUS_OK;
486 r->out.domains = NULL;
488 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
489 if (!NT_STATUS_IS_OK(status)) {
493 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
494 if (r->out.domains == NULL) {
495 return NT_STATUS_NO_MEMORY;
498 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
499 if (r->out.names == NULL) {
500 return NT_STATUS_NO_MEMORY;
505 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
506 r->in.sids->num_sids);
507 if (r->out.names->names == NULL) {
508 return NT_STATUS_NO_MEMORY;
511 for (i=0;i<r->in.sids->num_sids;i++) {
512 struct dom_sid *sid = r->in.sids->sids[i].sid;
513 char *sid_str = dom_sid_string(mem_ctx, sid);
514 const char *name, *authority_name;
515 enum lsa_SidType rtype;
519 r->out.names->count++;
521 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
522 r->out.names->names[i].name.string = sid_str;
523 r->out.names->names[i].sid_index = 0xFFFFFFFF;
524 r->out.names->names[i].unknown = 0;
526 if (sid_str == NULL) {
527 r->out.names->names[i].name.string = "(SIDERROR)";
528 status = STATUS_SOME_UNMAPPED;
532 status2 = dcesrv_lsa_lookup_sid(state, mem_ctx, sid, sid_str,
533 &authority_name, &name, &rtype);
534 if (!NT_STATUS_IS_OK(status2)) {
535 status = STATUS_SOME_UNMAPPED;
539 /* set up the authority table */
540 status2 = dcesrv_lsa_authority_list(state, mem_ctx, rtype,
542 r->out.domains, &sid_index);
543 if (!NT_STATUS_IS_OK(status2)) {
547 r->out.names->names[i].sid_type = rtype;
548 r->out.names->names[i].name.string = name;
549 r->out.names->names[i].sid_index = sid_index;
550 r->out.names->names[i].unknown = 0;
555 if (*r->out.count == 0) {
556 return NT_STATUS_NONE_MAPPED;
558 if (*r->out.count != r->in.sids->num_sids) {
559 return STATUS_SOME_UNMAPPED;
569 Identical to LookupSids2, but doesn't take a policy handle
572 NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
574 struct lsa_LookupSids3 *r)
576 struct lsa_LookupSids2 r2;
577 struct lsa_OpenPolicy2 pol;
579 struct dcesrv_handle *h;
581 /* No policy handle on the wire, so make one up here */
582 r2.in.handle = talloc(mem_ctx, struct policy_handle);
584 return NT_STATUS_NO_MEMORY;
587 pol.out.handle = r2.in.handle;
588 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
590 pol.in.system_name = NULL;
591 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
592 if (!NT_STATUS_IS_OK(status)) {
596 /* ensure this handle goes away at the end of this call */
597 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
598 talloc_steal(mem_ctx, h);
600 r2.in.sids = r->in.sids;
601 r2.in.names = r->in.names;
602 r2.in.level = r->in.level;
603 r2.in.count = r->in.count;
604 r2.in.unknown1 = r->in.unknown1;
605 r2.in.unknown2 = r->in.unknown2;
606 r2.out.count = r->out.count;
607 r2.out.names = r->out.names;
609 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
610 if (dce_call->fault_code != 0) {
614 r->out.domains = r2.out.domains;
615 r->out.names = r2.out.names;
616 r->out.count = r2.out.count;
625 NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
626 struct lsa_LookupSids *r)
628 struct lsa_LookupSids2 r2;
632 r2.in.handle = r->in.handle;
633 r2.in.sids = r->in.sids;
635 r2.in.level = r->in.level;
636 r2.in.count = r->in.count;
639 r2.out.count = r->out.count;
642 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
643 if (dce_call->fault_code != 0) {
647 r->out.domains = r2.out.domains;
653 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
654 if (r->out.names == NULL) {
655 return NT_STATUS_NO_MEMORY;
657 r->out.names->count = r2.out.names->count;
658 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
659 r->out.names->count);
660 if (r->out.names->names == NULL) {
661 return NT_STATUS_NO_MEMORY;
663 for (i=0;i<r->out.names->count;i++) {
664 r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
665 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
666 r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
676 NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
678 struct lsa_LookupNames3 *r)
680 struct lsa_policy_state *policy_state;
681 struct dcesrv_handle *policy_handle;
683 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
685 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
687 policy_state = policy_handle->data;
689 r->out.domains = NULL;
691 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
692 if (r->out.domains == NULL) {
693 return NT_STATUS_NO_MEMORY;
696 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
697 if (r->out.sids == NULL) {
698 return NT_STATUS_NO_MEMORY;
703 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
705 if (r->out.sids->sids == NULL) {
706 return NT_STATUS_NO_MEMORY;
709 for (i=0;i<r->in.num_names;i++) {
710 const char *name = r->in.names[i].string;
711 const char *authority_name;
714 enum lsa_SidType rtype;
717 r->out.sids->count++;
719 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
720 r->out.sids->sids[i].sid = NULL;
721 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
722 r->out.sids->sids[i].unknown = 0;
724 status2 = dcesrv_lsa_lookup_name(lp_ctx, policy_state, mem_ctx, name, &authority_name, &sid, &rtype);
725 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
729 status2 = dcesrv_lsa_authority_list(policy_state, mem_ctx, rtype, authority_name,
730 sid, r->out.domains, &sid_index);
731 if (!NT_STATUS_IS_OK(status2)) {
735 r->out.sids->sids[i].sid_type = rtype;
736 r->out.sids->sids[i].sid = sid;
737 r->out.sids->sids[i].sid_index = sid_index;
738 r->out.sids->sids[i].unknown = 0;
743 if (*r->out.count == 0) {
744 return NT_STATUS_NONE_MAPPED;
746 if (*r->out.count != r->in.num_names) {
747 return STATUS_SOME_UNMAPPED;
756 Identical to LookupNames3, but doesn't take a policy handle
759 NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
760 struct lsa_LookupNames4 *r)
762 struct lsa_LookupNames3 r2;
763 struct lsa_OpenPolicy2 pol;
765 struct dcesrv_handle *h;
767 /* No policy handle on the wire, so make one up here */
768 r2.in.handle = talloc(mem_ctx, struct policy_handle);
770 return NT_STATUS_NO_MEMORY;
773 pol.out.handle = r2.in.handle;
774 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
776 pol.in.system_name = NULL;
777 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
778 if (!NT_STATUS_IS_OK(status)) {
782 /* ensure this handle goes away at the end of this call */
783 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
784 talloc_steal(mem_ctx, h);
786 r2.in.num_names = r->in.num_names;
787 r2.in.names = r->in.names;
788 r2.in.sids = r->in.sids;
789 r2.in.count = r->in.count;
790 r2.in.unknown1 = r->in.unknown1;
791 r2.in.unknown2 = r->in.unknown2;
792 r2.out.domains = r->out.domains;
793 r2.out.sids = r->out.sids;
794 r2.out.count = r->out.count;
796 status = dcesrv_lsa_LookupNames3(dce_call, mem_ctx, &r2);
797 if (dce_call->fault_code != 0) {
801 r->out.domains = r2.out.domains;
802 r->out.sids = r2.out.sids;
803 r->out.count = r2.out.count;
810 NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
812 struct lsa_LookupNames2 *r)
814 struct lsa_policy_state *state;
815 struct dcesrv_handle *h;
817 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
819 r->out.domains = NULL;
821 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
825 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
826 if (r->out.domains == NULL) {
827 return NT_STATUS_NO_MEMORY;
830 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
831 if (r->out.sids == NULL) {
832 return NT_STATUS_NO_MEMORY;
837 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
839 if (r->out.sids->sids == NULL) {
840 return NT_STATUS_NO_MEMORY;
843 for (i=0;i<r->in.num_names;i++) {
844 const char *name = r->in.names[i].string;
845 const char *authority_name;
847 uint32_t rtype, sid_index;
850 r->out.sids->count++;
852 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
853 r->out.sids->sids[i].rid = 0xFFFFFFFF;
854 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
855 r->out.sids->sids[i].unknown = 0;
857 status2 = dcesrv_lsa_lookup_name(lp_ctx, state, mem_ctx, name,
858 &authority_name, &sid, &rtype);
859 if (!NT_STATUS_IS_OK(status2)) {
863 status2 = dcesrv_lsa_authority_list(state, mem_ctx, rtype, authority_name,
864 sid, r->out.domains, &sid_index);
865 if (!NT_STATUS_IS_OK(status2)) {
869 r->out.sids->sids[i].sid_type = rtype;
870 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
871 r->out.sids->sids[i].sid_index = sid_index;
872 r->out.sids->sids[i].unknown = 0;
877 if (*r->out.count == 0) {
878 return NT_STATUS_NONE_MAPPED;
880 if (*r->out.count != r->in.num_names) {
881 return STATUS_SOME_UNMAPPED;
890 NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
891 struct lsa_LookupNames *r)
893 struct lsa_LookupNames2 r2;
897 r2.in.handle = r->in.handle;
898 r2.in.num_names = r->in.num_names;
899 r2.in.names = r->in.names;
901 r2.in.level = r->in.level;
902 r2.in.count = r->in.count;
905 r2.out.count = r->out.count;
907 status = dcesrv_lsa_LookupNames2(dce_call, mem_ctx, &r2);
908 if (dce_call->fault_code != 0) {
912 r->out.domains = r2.out.domains;
913 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
914 if (r->out.sids == NULL) {
915 return NT_STATUS_NO_MEMORY;
917 r->out.sids->count = r2.out.sids->count;
918 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
920 if (r->out.sids->sids == NULL) {
921 return NT_STATUS_NO_MEMORY;
923 for (i=0;i<r->out.sids->count;i++) {
924 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
925 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
926 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;