util:datablob: data_blob_pad checks its alignment assumption
[samba.git] / source3 / rpc_client / cli_lsarpc.c
blobcf2572ed61cff09d7c0a8fb4559c3068de5985e7
1 /*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
4 Copyright (C) Tim Potter 2000-2001,
5 Copyright (C) Andrew Tridgell 1992-1997,2000,
6 Copyright (C) Rafal Szczesniak 2002
7 Copyright (C) Jeremy Allison 2005.
8 Copyright (C) Michael Adam 2007.
9 Copyright (C) Guenther Deschner 2008.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "includes.h"
26 #include "rpc_client/rpc_client.h"
27 #include "../librpc/gen_ndr/ndr_lsa_c.h"
28 #include "rpc_client/cli_lsarpc.h"
29 #include "rpc_client/init_lsa.h"
30 #include "../libcli/security/security.h"
31 #include "lsa.h"
33 /** @defgroup lsa LSA - Local Security Architecture
34 * @ingroup rpc_client
36 * @{
37 **/
39 /**
40 * @file cli_lsarpc.c
42 * RPC client routines for the LSA RPC pipe. LSA means "local
43 * security authority", which is half of a password database.
44 **/
46 NTSTATUS dcerpc_lsa_open_policy(struct dcerpc_binding_handle *h,
47 TALLOC_CTX *mem_ctx,
48 bool sec_qos,
49 uint32_t des_access,
50 struct policy_handle *pol,
51 NTSTATUS *result)
53 struct lsa_ObjectAttribute attr = { .len = 0x18, };
54 struct lsa_QosInfo qos;
55 uint16_t system_name = '\\';
57 if (sec_qos) {
58 qos.len = 0xc;
59 qos.impersonation_level = 2;
60 qos.context_mode = 1;
61 qos.effective_only = 0;
63 attr.sec_qos = &qos;
66 return dcerpc_lsa_OpenPolicy(h,
67 mem_ctx,
68 &system_name,
69 &attr,
70 des_access,
71 pol,
72 result);
75 /** Open a LSA policy handle
77 * @param cli Handle on an initialised SMB connection */
79 NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
80 TALLOC_CTX *mem_ctx,
81 bool sec_qos, uint32_t des_access,
82 struct policy_handle *pol)
84 NTSTATUS status;
85 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
87 status = dcerpc_lsa_open_policy(cli->binding_handle,
88 mem_ctx,
89 sec_qos,
90 des_access,
91 pol,
92 &result);
93 if (!NT_STATUS_IS_OK(status)) {
94 return status;
97 return result;
100 NTSTATUS dcerpc_lsa_open_policy2(struct dcerpc_binding_handle *h,
101 TALLOC_CTX *mem_ctx,
102 const char *srv_name_slash,
103 bool sec_qos,
104 uint32_t des_access,
105 struct policy_handle *pol,
106 NTSTATUS *result)
108 struct lsa_ObjectAttribute attr = { .len = 0x18, };
109 struct lsa_QosInfo qos;
111 if (sec_qos) {
112 qos.len = 0xc;
113 qos.impersonation_level = 2;
114 qos.context_mode = 1;
115 qos.effective_only = 0;
117 attr.sec_qos = &qos;
120 return dcerpc_lsa_OpenPolicy2(h,
121 mem_ctx,
122 srv_name_slash,
123 &attr,
124 des_access,
125 pol,
126 result);
129 NTSTATUS dcerpc_lsa_open_policy3(struct dcerpc_binding_handle *h,
130 TALLOC_CTX *mem_ctx,
131 const char *srv_name_slash,
132 bool sec_qos,
133 uint32_t des_access,
134 uint32_t *out_version,
135 union lsa_revision_info *out_revision_info,
136 struct policy_handle *pol,
137 NTSTATUS *result)
139 struct lsa_ObjectAttribute attr = { .len = 0x18, };
140 struct lsa_QosInfo qos;
141 union lsa_revision_info in_revision_info = {
142 .info1 = {
143 .revision = 1,
146 uint32_t in_version = 1;
148 if (sec_qos) {
149 qos.len = 0xc;
150 qos.impersonation_level = 2;
151 qos.context_mode = 1;
152 qos.effective_only = 0;
154 attr.sec_qos = &qos;
157 return dcerpc_lsa_OpenPolicy3(h,
158 mem_ctx,
159 srv_name_slash,
160 &attr,
161 des_access,
162 in_version,
163 &in_revision_info,
164 out_version,
165 out_revision_info,
166 pol,
167 result);
170 NTSTATUS dcerpc_lsa_open_policy_fallback(struct dcerpc_binding_handle *h,
171 TALLOC_CTX *mem_ctx,
172 const char *srv_name_slash,
173 bool sec_qos,
174 uint32_t desired_access,
175 uint32_t *out_version,
176 union lsa_revision_info *out_revision_info,
177 struct policy_handle *pol,
178 NTSTATUS *result)
180 NTSTATUS status;
182 status = dcerpc_lsa_open_policy3(h,
183 mem_ctx,
184 srv_name_slash,
185 sec_qos,
186 desired_access,
187 out_version,
188 out_revision_info,
189 pol,
190 result);
191 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
192 *out_version = 1;
193 *out_revision_info = (union lsa_revision_info) {
194 .info1 = {
195 .revision = 1,
199 status = dcerpc_lsa_open_policy2(h,
200 mem_ctx,
201 srv_name_slash,
202 sec_qos,
203 desired_access,
204 pol,
205 result);
208 return status;
211 /* Lookup a list of sids
213 * internal version withOUT memory allocation of the target arrays.
214 * this assumes sufficiently sized arrays to store domains, names and types. */
216 static NTSTATUS dcerpc_lsa_lookup_sids_noalloc(struct dcerpc_binding_handle *h,
217 TALLOC_CTX *mem_ctx,
218 TALLOC_CTX *domains_ctx,
219 TALLOC_CTX *names_ctx,
220 struct policy_handle *pol,
221 int num_sids,
222 const struct dom_sid *sids,
223 enum lsa_LookupNamesLevel level,
224 char **domains,
225 char **names,
226 enum lsa_SidType *types,
227 bool use_lookupsids3,
228 NTSTATUS *presult)
230 NTSTATUS status;
231 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
232 struct lsa_SidArray sid_array;
233 struct lsa_RefDomainList *ref_domains = NULL;
234 struct lsa_TransNameArray lsa_names = { .count = 0, };
235 uint32_t count = 0;
236 int i;
238 sid_array.num_sids = num_sids;
239 sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr, num_sids);
240 if (sid_array.sids == NULL) {
241 return NT_STATUS_NO_MEMORY;
244 for (i = 0; i<num_sids; i++) {
245 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]);
246 if (!sid_array.sids[i].sid) {
247 return NT_STATUS_NO_MEMORY;
251 if (use_lookupsids3) {
252 struct lsa_TransNameArray2 lsa_names2;
253 uint32_t n;
255 ZERO_STRUCT(lsa_names2);
257 status = dcerpc_lsa_LookupSids3(h,
258 mem_ctx,
259 &sid_array,
260 &ref_domains,
261 &lsa_names2,
262 level,
263 &count,
264 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES,
265 LSA_CLIENT_REVISION_2,
266 &result);
267 if (!NT_STATUS_IS_OK(status)) {
268 return status;
271 if (!NT_STATUS_LOOKUP_ERR(result)) {
272 lsa_names.count = lsa_names2.count;
273 lsa_names.names = talloc_array(mem_ctx,
274 struct lsa_TranslatedName,
275 lsa_names.count);
276 if (lsa_names.names == NULL) {
277 return NT_STATUS_NO_MEMORY;
279 for (n=0; n < lsa_names.count; n++) {
280 lsa_names.names[n].sid_type = lsa_names2.names[n].sid_type;
281 lsa_names.names[n].name = lsa_names2.names[n].name;
282 lsa_names.names[n].sid_index = lsa_names2.names[n].sid_index;
286 } else {
287 status = dcerpc_lsa_LookupSids(h,
288 mem_ctx,
289 pol,
290 &sid_array,
291 &ref_domains,
292 &lsa_names,
293 level,
294 &count,
295 &result);
298 DEBUG(10, ("LSA_LOOKUPSIDS returned status: '%s', result: '%s', "
299 "mapped count = %d'\n",
300 nt_errstr(status), nt_errstr(result), count));
302 if (!NT_STATUS_IS_OK(status)) {
303 return status;
306 if (NT_STATUS_LOOKUP_ERR(result)) {
307 *presult = result;
308 return status;
311 /* Return output parameters */
312 if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
313 (count == 0))
315 for (i = 0; i < num_sids; i++) {
316 (names)[i] = NULL;
317 (domains)[i] = NULL;
318 (types)[i] = SID_NAME_UNKNOWN;
320 *presult = NT_STATUS_NONE_MAPPED;
321 return status;
324 for (i = 0; i < num_sids; i++) {
325 const char *name, *dom_name;
326 uint32_t dom_idx;
328 if (i >= lsa_names.count) {
329 *presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
330 return status;
333 dom_idx = lsa_names.names[i].sid_index;
335 /* Translate optimised name through domain index array */
337 if (dom_idx != 0xffffffff) {
338 if (ref_domains == NULL) {
339 *presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
340 return status;
342 if (dom_idx >= ref_domains->count) {
343 *presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
344 return status;
347 dom_name = ref_domains->domains[dom_idx].name.string;
348 name = lsa_names.names[i].name.string;
350 if (name) {
351 (names)[i] = talloc_strdup(names_ctx, name);
352 if ((names)[i] == NULL) {
353 DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n"));
354 *presult = NT_STATUS_UNSUCCESSFUL;
355 return status;
357 } else {
358 (names)[i] = NULL;
360 domains[i] = talloc_strdup(domains_ctx,
361 dom_name ? dom_name : "");
362 (types)[i] = lsa_names.names[i].sid_type;
363 if ((domains)[i] == NULL) {
364 DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n"));
365 *presult = NT_STATUS_UNSUCCESSFUL;
366 return status;
369 } else {
370 (names)[i] = NULL;
371 (domains)[i] = NULL;
372 (types)[i] = SID_NAME_UNKNOWN;
376 *presult = NT_STATUS_OK;
377 return status;
380 /* Lookup a list of sids
382 * do it the right way: there is a limit (of 20480 for w2k3) entries
383 * returned by this call. when the sids list contains more entries,
384 * empty lists are returned. This version of lsa_lookup_sids passes
385 * the list of sids in hunks of LOOKUP_SIDS_HUNK_SIZE to the lsa call. */
387 /* This constant defines the limit of how many sids to look up
388 * in one call (maximum). the limit from the server side is
389 * at 20480 for win2k3, but we keep it at a save 1000 for now. */
390 #define LOOKUP_SIDS_HUNK_SIZE 1000
392 NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h,
393 TALLOC_CTX *mem_ctx,
394 struct policy_handle *pol,
395 int num_sids,
396 const struct dom_sid *sids,
397 enum lsa_LookupNamesLevel level,
398 char ***pdomains,
399 char ***pnames,
400 enum lsa_SidType **ptypes,
401 bool use_lookupsids3,
402 NTSTATUS *presult)
404 NTSTATUS status = NT_STATUS_OK;
405 NTSTATUS result = NT_STATUS_OK;
406 int sids_left = 0;
407 int sids_processed = 0;
408 const struct dom_sid *hunk_sids = sids;
409 char **hunk_domains;
410 char **hunk_names;
411 enum lsa_SidType *hunk_types;
412 char **domains = NULL;
413 char **names = NULL;
414 enum lsa_SidType *types = NULL;
415 bool have_mapped = false;
416 bool have_unmapped = false;
418 if (num_sids) {
419 domains = talloc_zero_array(mem_ctx, char *, num_sids);
420 if (domains == NULL) {
421 DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
422 status = NT_STATUS_NO_MEMORY;
423 goto fail;
426 names = talloc_zero_array(mem_ctx, char *, num_sids);
427 if (names == NULL) {
428 DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
429 status = NT_STATUS_NO_MEMORY;
430 goto fail;
433 types = talloc_zero_array(mem_ctx, enum lsa_SidType, num_sids);
434 if (types == NULL) {
435 DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
436 status = NT_STATUS_NO_MEMORY;
437 goto fail;
441 sids_left = num_sids;
442 hunk_domains = domains;
443 hunk_names = names;
444 hunk_types = types;
446 while (sids_left > 0) {
447 int hunk_num_sids;
448 NTSTATUS hunk_result = NT_STATUS_UNSUCCESSFUL;
450 hunk_num_sids = ((sids_left > LOOKUP_SIDS_HUNK_SIZE)
451 ? LOOKUP_SIDS_HUNK_SIZE
452 : sids_left);
454 DEBUG(10, ("rpccli_lsa_lookup_sids: processing items "
455 "%d -- %d of %d.\n",
456 sids_processed,
457 sids_processed + hunk_num_sids - 1,
458 num_sids));
460 status = dcerpc_lsa_lookup_sids_noalloc(h,
461 mem_ctx,
462 (TALLOC_CTX *)domains,
463 (TALLOC_CTX *)names,
464 pol,
465 hunk_num_sids,
466 hunk_sids,
467 level,
468 hunk_domains,
469 hunk_names,
470 hunk_types,
471 use_lookupsids3,
472 &hunk_result);
473 if (!NT_STATUS_IS_OK(status)) {
474 goto fail;
477 if (!NT_STATUS_IS_OK(hunk_result) &&
478 !NT_STATUS_EQUAL(hunk_result, STATUS_SOME_UNMAPPED) &&
479 !NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED))
481 /* An actual error occurred */
482 *presult = hunk_result;
483 goto fail;
486 if (NT_STATUS_IS_OK(hunk_result)) {
487 have_mapped = true;
489 if (NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED)) {
490 have_unmapped = true;
492 if (NT_STATUS_EQUAL(hunk_result, STATUS_SOME_UNMAPPED)) {
493 int i;
494 for (i=0; i<hunk_num_sids; i++) {
495 if (hunk_types[i] == SID_NAME_UNKNOWN) {
496 have_unmapped = true;
497 } else {
498 have_mapped = true;
503 sids_left -= hunk_num_sids;
504 sids_processed += hunk_num_sids;
505 hunk_sids += hunk_num_sids;
506 hunk_domains += hunk_num_sids;
507 hunk_names += hunk_num_sids;
508 hunk_types += hunk_num_sids;
511 *pdomains = domains;
512 *pnames = names;
513 *ptypes = types;
515 if (!have_mapped) {
516 result = NT_STATUS_NONE_MAPPED;
518 if (have_unmapped) {
519 result = STATUS_SOME_UNMAPPED;
521 *presult = result;
523 return status;
525 fail:
526 TALLOC_FREE(domains);
527 TALLOC_FREE(names);
528 TALLOC_FREE(types);
530 return status;
533 NTSTATUS dcerpc_lsa_lookup_sids(struct dcerpc_binding_handle *h,
534 TALLOC_CTX *mem_ctx,
535 struct policy_handle *pol,
536 int num_sids,
537 const struct dom_sid *sids,
538 char ***pdomains,
539 char ***pnames,
540 enum lsa_SidType **ptypes,
541 NTSTATUS *result)
543 enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL;
544 return dcerpc_lsa_lookup_sids_generic(h,
545 mem_ctx,
546 pol,
547 num_sids,
548 sids,
549 level,
550 pdomains,
551 pnames,
552 ptypes,
553 false,
554 result);
557 NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
558 TALLOC_CTX *mem_ctx,
559 struct policy_handle *pol,
560 int num_sids,
561 const struct dom_sid *sids,
562 char ***pdomains,
563 char ***pnames,
564 enum lsa_SidType **ptypes)
566 NTSTATUS status;
567 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
568 enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL;
570 status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle,
571 mem_ctx,
572 pol,
573 num_sids,
574 sids,
575 level,
576 pdomains,
577 pnames,
578 ptypes,
579 false,
580 &result);
581 if (!NT_STATUS_IS_OK(status)) {
582 return status;
585 return result;
588 NTSTATUS dcerpc_lsa_lookup_sids3(struct dcerpc_binding_handle *h,
589 TALLOC_CTX *mem_ctx,
590 struct policy_handle *pol,
591 int num_sids,
592 const struct dom_sid *sids,
593 char ***pdomains,
594 char ***pnames,
595 enum lsa_SidType **ptypes,
596 NTSTATUS *result)
598 enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL;
599 return dcerpc_lsa_lookup_sids_generic(h,
600 mem_ctx,
601 pol,
602 num_sids,
603 sids,
604 level,
605 pdomains,
606 pnames,
607 ptypes,
608 true,
609 result);
612 /** Lookup a list of names */
614 NTSTATUS dcerpc_lsa_lookup_names_generic(struct dcerpc_binding_handle *h,
615 TALLOC_CTX *mem_ctx,
616 struct policy_handle *pol,
617 uint32_t num_names,
618 const char **names,
619 const char ***dom_names,
620 enum lsa_LookupNamesLevel level,
621 struct dom_sid **sids,
622 enum lsa_SidType **types,
623 bool use_lookupnames4,
624 NTSTATUS *presult)
626 NTSTATUS status;
627 struct lsa_String *lsa_names = NULL;
628 struct lsa_RefDomainList *domains = NULL;
629 struct lsa_TransSidArray sid_array = { .count = 0, };
630 struct lsa_TransSidArray3 sid_array3 = { .count = 0, };
631 uint32_t count = 0;
632 uint32_t i;
634 lsa_names = talloc_array(mem_ctx, struct lsa_String, num_names);
635 if (lsa_names == NULL) {
636 return NT_STATUS_NO_MEMORY;
639 for (i = 0; i < num_names; i++) {
640 init_lsa_String(&lsa_names[i], names[i]);
643 if (use_lookupnames4) {
644 status = dcerpc_lsa_LookupNames4(h,
645 mem_ctx,
646 num_names,
647 lsa_names,
648 &domains,
649 &sid_array3,
650 level,
651 &count,
652 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES,
653 LSA_CLIENT_REVISION_2,
654 presult);
655 } else {
656 status = dcerpc_lsa_LookupNames(h,
657 mem_ctx,
658 pol,
659 num_names,
660 lsa_names,
661 &domains,
662 &sid_array,
663 level,
664 &count,
665 presult);
667 if (!NT_STATUS_IS_OK(status)) {
668 goto done;
671 if (!NT_STATUS_IS_OK(*presult) &&
672 !NT_STATUS_EQUAL(*presult, STATUS_SOME_UNMAPPED)) {
673 /* An actual error occurred */
674 goto done;
677 /* Return output parameters */
678 if (count == 0) {
679 *presult = NT_STATUS_NONE_MAPPED;
680 goto done;
683 if (num_names) {
684 *sids = talloc_zero_array(mem_ctx, struct dom_sid, num_names);
685 if (*sids == NULL) {
686 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
687 *presult = NT_STATUS_NO_MEMORY;
688 goto done;
691 *types = talloc_zero_array(mem_ctx, enum lsa_SidType, num_names);
692 if (*types == NULL) {
693 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
694 *presult = NT_STATUS_NO_MEMORY;
695 goto done;
698 if (dom_names != NULL) {
699 *dom_names = talloc_zero_array(mem_ctx, const char *, num_names);
700 if (*dom_names == NULL) {
701 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
702 *presult = NT_STATUS_NO_MEMORY;
703 goto done;
706 } else {
707 *sids = NULL;
708 *types = NULL;
709 if (dom_names != NULL) {
710 *dom_names = NULL;
714 for (i = 0; i < num_names; i++) {
715 uint32_t dom_idx;
716 struct dom_sid *sid = &(*sids)[i];
718 if (use_lookupnames4) {
719 if (i >= sid_array3.count) {
720 *presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
721 goto done;
724 dom_idx = sid_array3.sids[i].sid_index;
725 (*types)[i] = sid_array3.sids[i].sid_type;
726 } else {
727 if (i >= sid_array.count) {
728 *presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
729 goto done;
732 dom_idx = sid_array.sids[i].sid_index;
733 (*types)[i] = sid_array.sids[i].sid_type;
736 /* Translate optimised sid through domain index array */
738 if (dom_idx == 0xffffffff) {
739 /* Nothing to do, this is unknown */
740 ZERO_STRUCTP(sid);
741 (*types)[i] = SID_NAME_UNKNOWN;
742 continue;
744 if (domains == NULL) {
745 *presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
746 goto done;
748 if (dom_idx >= domains->count) {
749 *presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
750 goto done;
753 if (use_lookupnames4) {
754 if (sid_array3.sids[i].sid != NULL) {
755 sid_copy(sid, sid_array3.sids[i].sid);
756 } else {
757 ZERO_STRUCTP(sid);
758 (*types)[i] = SID_NAME_UNKNOWN;
760 } else {
761 if (domains->domains[dom_idx].sid != NULL) {
762 sid_copy(sid, domains->domains[dom_idx].sid);
764 if (sid_array.sids[i].rid != 0xffffffff) {
765 sid_append_rid(sid,
766 sid_array.sids[i].rid);
768 } else {
769 ZERO_STRUCTP(sid);
770 (*types)[i] = SID_NAME_UNKNOWN;
774 if (dom_names == NULL) {
775 continue;
778 (*dom_names)[i] = domains->domains[dom_idx].name.string;
781 done:
782 return status;
785 NTSTATUS dcerpc_lsa_lookup_names(struct dcerpc_binding_handle *h,
786 TALLOC_CTX *mem_ctx,
787 struct policy_handle *pol,
788 uint32_t num_names,
789 const char **names,
790 const char ***dom_names,
791 enum lsa_LookupNamesLevel level,
792 struct dom_sid **sids,
793 enum lsa_SidType **types,
794 NTSTATUS *result)
796 return dcerpc_lsa_lookup_names_generic(h,
797 mem_ctx,
798 pol,
799 num_names,
800 names,
801 dom_names,
802 level,
803 sids,
804 types,
805 false,
806 result);
809 NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
810 TALLOC_CTX *mem_ctx,
811 struct policy_handle *pol,
812 int num_names,
813 const char **names,
814 const char ***dom_names,
815 int level,
816 struct dom_sid **sids,
817 enum lsa_SidType **types)
819 NTSTATUS status;
820 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
822 status = dcerpc_lsa_lookup_names(cli->binding_handle,
823 mem_ctx,
824 pol,
825 num_names,
826 names,
827 dom_names,
828 level,
829 sids,
830 types,
831 &result);
832 if (!NT_STATUS_IS_OK(status)) {
833 return status;
836 return result;
839 NTSTATUS dcerpc_lsa_lookup_names4(struct dcerpc_binding_handle *h,
840 TALLOC_CTX *mem_ctx,
841 struct policy_handle *pol,
842 uint32_t num_names,
843 const char **names,
844 const char ***dom_names,
845 enum lsa_LookupNamesLevel level,
846 struct dom_sid **sids,
847 enum lsa_SidType **types,
848 NTSTATUS *result)
850 return dcerpc_lsa_lookup_names_generic(h,
851 mem_ctx,
852 pol,
853 num_names,
854 names,
855 dom_names,
856 level,
857 sids,
858 types,
859 true,
860 result);