6b5d7f82d4a4beb997d4eb2113d05524359080e0
[samba.git] / source3 / rpc_client / cli_lsarpc.c
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.
10
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.
15
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.
20
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/>.
23 */
24
25 #include "includes.h"
26 #include "../librpc/gen_ndr/cli_lsa.h"
27 #include "rpc_client/cli_lsarpc.h"
28 #include "rpc_client/init_lsa.h"
29 #include "../libcli/security/security.h"
30
31 /** @defgroup lsa LSA - Local Security Architecture
32  *  @ingroup rpc_client
33  *
34  * @{
35  **/
36
37 /**
38  * @file cli_lsarpc.c
39  *
40  * RPC client routines for the LSA RPC pipe.  LSA means "local
41  * security authority", which is half of a password database.
42  **/
43
44 NTSTATUS dcerpc_lsa_open_policy(struct dcerpc_binding_handle *h,
45                                 TALLOC_CTX *mem_ctx,
46                                 bool sec_qos,
47                                 uint32_t des_access,
48                                 struct policy_handle *pol,
49                                 NTSTATUS *result)
50 {
51         struct lsa_ObjectAttribute attr;
52         struct lsa_QosInfo qos;
53         uint16_t system_name = '\\';
54
55         ZERO_STRUCT(attr);
56
57         attr.len        = 0x18;
58
59         if (sec_qos) {
60                 qos.len                 = 0xc;
61                 qos.impersonation_level = 2;
62                 qos.context_mode        = 1;
63                 qos.effective_only      = 0;
64
65                 attr.sec_qos            = &qos;
66         }
67
68         return dcerpc_lsa_OpenPolicy(h,
69                                      mem_ctx,
70                                      &system_name,
71                                      &attr,
72                                      des_access,
73                                      pol,
74                                      result);
75 }
76
77 /** Open a LSA policy handle
78  *
79  * @param cli Handle on an initialised SMB connection */
80
81 NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
82                                 TALLOC_CTX *mem_ctx,
83                                 bool sec_qos, uint32 des_access,
84                                 struct policy_handle *pol)
85 {
86         NTSTATUS status;
87         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
88
89         status = dcerpc_lsa_open_policy(cli->binding_handle,
90                                         mem_ctx,
91                                         sec_qos,
92                                         des_access,
93                                         pol,
94                                         &result);
95         if (!NT_STATUS_IS_OK(status)) {
96                 return status;
97         }
98
99         return result;
100 }
101
102 NTSTATUS dcerpc_lsa_open_policy2(struct dcerpc_binding_handle *h,
103                                  TALLOC_CTX *mem_ctx,
104                                  const char *srv_name_slash,
105                                  bool sec_qos,
106                                  uint32_t des_access,
107                                  struct policy_handle *pol,
108                                  NTSTATUS *result)
109 {
110         struct lsa_ObjectAttribute attr;
111         struct lsa_QosInfo qos;
112
113         ZERO_STRUCT(attr);
114
115         attr.len        = 0x18;
116
117         if (sec_qos) {
118                 qos.len                 = 0xc;
119                 qos.impersonation_level = 2;
120                 qos.context_mode        = 1;
121                 qos.effective_only      = 0;
122
123                 attr.sec_qos            = &qos;
124         }
125
126         return dcerpc_lsa_OpenPolicy2(h,
127                                       mem_ctx,
128                                       srv_name_slash,
129                                       &attr,
130                                       des_access,
131                                       pol,
132                                       result);
133 }
134
135 /** Open a LSA policy handle
136   *
137   * @param cli Handle on an initialised SMB connection
138   */
139
140 NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
141                                  TALLOC_CTX *mem_ctx, bool sec_qos,
142                                  uint32 des_access, struct policy_handle *pol)
143 {
144         NTSTATUS status;
145         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
146
147         status = dcerpc_lsa_open_policy(cli->binding_handle,
148                                         mem_ctx,
149                                         sec_qos,
150                                         des_access,
151                                         pol,
152                                         &result);
153         if (!NT_STATUS_IS_OK(status)) {
154                 return status;
155         }
156
157         return result;
158 }
159
160 /* Lookup a list of sids
161  *
162  * internal version withOUT memory allocation of the target arrays.
163  * this assumes suffciently sized arrays to store domains, names and types. */
164
165 static NTSTATUS dcerpc_lsa_lookup_sids_noalloc(struct dcerpc_binding_handle *h,
166                                                TALLOC_CTX *mem_ctx,
167                                                struct policy_handle *pol,
168                                                int num_sids,
169                                                const struct dom_sid *sids,
170                                                char **domains,
171                                                char **names,
172                                                enum lsa_SidType *types,
173                                                bool use_lookupsids3,
174                                                NTSTATUS *presult)
175 {
176         NTSTATUS status = NT_STATUS_OK;
177         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
178         struct lsa_SidArray sid_array;
179         struct lsa_RefDomainList *ref_domains = NULL;
180         struct lsa_TransNameArray lsa_names;
181         enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL;
182         uint32_t count = 0;
183         int i;
184
185         ZERO_STRUCT(lsa_names);
186
187         sid_array.num_sids = num_sids;
188         sid_array.sids = TALLOC_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids);
189         if (sid_array.sids == NULL) {
190                 return NT_STATUS_NO_MEMORY;
191         }
192
193         for (i = 0; i<num_sids; i++) {
194                 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]);
195                 if (!sid_array.sids[i].sid) {
196                         return NT_STATUS_NO_MEMORY;
197                 }
198         }
199
200         if (use_lookupsids3) {
201                 struct lsa_TransNameArray2 lsa_names2;
202                 uint32_t n;
203
204                 ZERO_STRUCT(lsa_names2);
205
206                 status = dcerpc_lsa_LookupSids3(h,
207                                                 mem_ctx,
208                                                 &sid_array,
209                                                 &ref_domains,
210                                                 &lsa_names2,
211                                                 level,
212                                                 &count,
213                                                 0,
214                                                 0,
215                                                 &result);
216                 if (NT_STATUS_IS_OK(status)) {
217                         return status;
218                 }
219
220                 if(!NT_STATUS_IS_ERR(result)) {
221                         lsa_names.count = lsa_names2.count;
222                         lsa_names.names = talloc_array(mem_ctx,
223                                                        struct lsa_TranslatedName,
224                                                        lsa_names.count);
225                         if (lsa_names.names == NULL) {
226                                 return NT_STATUS_NO_MEMORY;
227                         }
228                         for (n=0; n < lsa_names.count; n++) {
229                                 lsa_names.names[n].sid_type     = lsa_names2.names[n].sid_type;
230                                 lsa_names.names[n].name         = lsa_names2.names[n].name;
231                                 lsa_names.names[n].sid_index    = lsa_names2.names[n].sid_index;
232                         }
233                 }
234
235         } else {
236                 status = dcerpc_lsa_LookupSids(h,
237                                                mem_ctx,
238                                                pol,
239                                                &sid_array,
240                                                &ref_domains,
241                                                &lsa_names,
242                                                level,
243                                                &count,
244                                                &result);
245         }
246
247         DEBUG(10, ("LSA_LOOKUPSIDS returned status: '%s', result: '%s', "
248                    "mapped count = %d'\n",
249                    nt_errstr(status), nt_errstr(result), count));
250
251         if (!NT_STATUS_IS_OK(status)) {
252                 return status;
253         }
254
255         if (!NT_STATUS_IS_OK(result) &&
256             !NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) &&
257             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
258         {
259                 *presult = result;
260                 return status;
261         }
262
263         /* Return output parameters */
264         if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
265             (count == 0))
266         {
267                 for (i = 0; i < num_sids; i++) {
268                         (names)[i] = NULL;
269                         (domains)[i] = NULL;
270                         (types)[i] = SID_NAME_UNKNOWN;
271                 }
272                 *presult = NT_STATUS_NONE_MAPPED;
273                 return status;
274         }
275
276         for (i = 0; i < num_sids; i++) {
277                 const char *name, *dom_name;
278                 uint32_t dom_idx = lsa_names.names[i].sid_index;
279
280                 /* Translate optimised name through domain index array */
281
282                 if (dom_idx != 0xffffffff) {
283
284                         dom_name = ref_domains->domains[dom_idx].name.string;
285                         name = lsa_names.names[i].name.string;
286
287                         if (name) {
288                                 (names)[i] = talloc_strdup(names, name);
289                                 if ((names)[i] == NULL) {
290                                         DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n"));
291                                         *presult = NT_STATUS_UNSUCCESSFUL;
292                                         return status;
293                                 }
294                         } else {
295                                 (names)[i] = NULL;
296                         }
297                         domains[i] = talloc_strdup(domains,
298                                                    dom_name ? dom_name : "");
299                         (types)[i] = lsa_names.names[i].sid_type;
300                         if (((domains)[i] == NULL)) {
301                                 DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n"));
302                                 *presult = NT_STATUS_UNSUCCESSFUL;
303                                 return status;
304                         }
305
306                 } else {
307                         (names)[i] = NULL;
308                         (domains)[i] = NULL;
309                         (types)[i] = SID_NAME_UNKNOWN;
310                 }
311         }
312
313         *presult = NT_STATUS_OK;
314         return status;
315 }
316
317 /* Lookup a list of sids
318  *
319  * do it the right way: there is a limit (of 20480 for w2k3) entries
320  * returned by this call. when the sids list contains more entries,
321  * empty lists are returned. This version of lsa_lookup_sids passes
322  * the list of sids in hunks of LOOKUP_SIDS_HUNK_SIZE to the lsa call. */
323
324 /* This constant defines the limit of how many sids to look up
325  * in one call (maximum). the limit from the server side is
326  * at 20480 for win2k3, but we keep it at a save 1000 for now. */
327 #define LOOKUP_SIDS_HUNK_SIZE 1000
328
329 static NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h,
330                                                TALLOC_CTX *mem_ctx,
331                                                struct policy_handle *pol,
332                                                int num_sids,
333                                                const struct dom_sid *sids,
334                                                char ***pdomains,
335                                                char ***pnames,
336                                                enum lsa_SidType **ptypes,
337                                                bool use_lookupsids3,
338                                                NTSTATUS *presult)
339 {
340         NTSTATUS status;
341         NTSTATUS result = NT_STATUS_OK;
342         int sids_left = 0;
343         int sids_processed = 0;
344         const struct dom_sid *hunk_sids = sids;
345         char **hunk_domains;
346         char **hunk_names;
347         enum lsa_SidType *hunk_types;
348         char **domains = NULL;
349         char **names = NULL;
350         enum lsa_SidType *types = NULL;
351         bool have_mapped = false;
352         bool have_unmapped = false;
353
354         if (num_sids) {
355                 if (!(domains = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
356                         DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
357                         result = NT_STATUS_NO_MEMORY;
358                         goto fail;
359                 }
360
361                 if (!(names = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
362                         DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
363                         result = NT_STATUS_NO_MEMORY;
364                         goto fail;
365                 }
366
367                 if (!(types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_sids))) {
368                         DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
369                         result = NT_STATUS_NO_MEMORY;
370                         goto fail;
371                 }
372         }
373
374         sids_left = num_sids;
375         hunk_domains = domains;
376         hunk_names = names;
377         hunk_types = types;
378
379         while (sids_left > 0) {
380                 int hunk_num_sids;
381                 NTSTATUS hunk_result;
382
383                 hunk_num_sids = ((sids_left > LOOKUP_SIDS_HUNK_SIZE)
384                                 ? LOOKUP_SIDS_HUNK_SIZE
385                                 : sids_left);
386
387                 DEBUG(10, ("rpccli_lsa_lookup_sids: processing items "
388                            "%d -- %d of %d.\n",
389                            sids_processed,
390                            sids_processed + hunk_num_sids - 1,
391                            num_sids));
392
393                 status = dcerpc_lsa_lookup_sids_noalloc(h,
394                                                         mem_ctx,
395                                                         pol,
396                                                         hunk_num_sids,
397                                                         hunk_sids,
398                                                         hunk_domains,
399                                                         hunk_names,
400                                                         hunk_types,
401                                                         use_lookupsids3,
402                                                         &hunk_result);
403                 if (!NT_STATUS_IS_OK(status)) {
404                         goto fail;
405                 }
406
407                 if (!NT_STATUS_IS_OK(hunk_result) &&
408                     !NT_STATUS_EQUAL(hunk_result, STATUS_SOME_UNMAPPED) &&
409                     !NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED))
410                 {
411                         /* An actual error occured */
412                         *presult = hunk_result;
413                         goto fail;
414                 }
415
416                 if (NT_STATUS_IS_OK(hunk_result)) {
417                         have_mapped = true;
418                 }
419                 if (NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED)) {
420                         have_unmapped = true;
421                 }
422                 if (NT_STATUS_EQUAL(hunk_result, STATUS_SOME_UNMAPPED)) {
423                         int i;
424                         for (i=0; i<hunk_num_sids; i++) {
425                                 if (hunk_types[i] == SID_NAME_UNKNOWN) {
426                                         have_unmapped = true;
427                                 } else {
428                                         have_mapped = true;
429                                 }
430                         }
431                 }
432
433                 sids_left -= hunk_num_sids;
434                 sids_processed += hunk_num_sids; /* only used in DEBUG */
435                 hunk_sids += hunk_num_sids;
436                 hunk_domains += hunk_num_sids;
437                 hunk_names += hunk_num_sids;
438                 hunk_types += hunk_num_sids;
439         }
440
441         *pdomains = domains;
442         *pnames = names;
443         *ptypes = types;
444
445         if (!have_mapped) {
446                 result = NT_STATUS_NONE_MAPPED;
447         }
448         if (have_unmapped) {
449                 result = STATUS_SOME_UNMAPPED;
450         }
451         *presult = result;
452
453         return status;
454
455 fail:
456         TALLOC_FREE(domains);
457         TALLOC_FREE(names);
458         TALLOC_FREE(types);
459
460         return status;
461 }
462
463 NTSTATUS dcerpc_lsa_lookup_sids(struct dcerpc_binding_handle *h,
464                                 TALLOC_CTX *mem_ctx,
465                                 struct policy_handle *pol,
466                                 int num_sids,
467                                 const struct dom_sid *sids,
468                                 char ***pdomains,
469                                 char ***pnames,
470                                 enum lsa_SidType **ptypes,
471                                 NTSTATUS *result)
472 {
473         return dcerpc_lsa_lookup_sids_generic(h,
474                                               mem_ctx,
475                                               pol,
476                                               num_sids,
477                                               sids,
478                                               pdomains,
479                                               pnames,
480                                               ptypes,
481                                               false,
482                                               result);
483 }
484
485 NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
486                                 TALLOC_CTX *mem_ctx,
487                                 struct policy_handle *pol,
488                                 int num_sids,
489                                 const struct dom_sid *sids,
490                                 char ***pdomains,
491                                 char ***pnames,
492                                 enum lsa_SidType **ptypes)
493 {
494         NTSTATUS status;
495         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
496
497         status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle,
498                                                 mem_ctx,
499                                                 pol,
500                                                 num_sids,
501                                                 sids,
502                                                 pdomains,
503                                                 pnames,
504                                                 ptypes,
505                                                 false,
506                                                 &result);
507         if (!NT_STATUS_IS_OK(status)) {
508                 return status;
509         }
510
511         return result;
512 }
513
514 NTSTATUS dcerpc_lsa_lookup_sids3(struct dcerpc_binding_handle *h,
515                                  TALLOC_CTX *mem_ctx,
516                                  struct policy_handle *pol,
517                                  int num_sids,
518                                  const struct dom_sid *sids,
519                                  char ***pdomains,
520                                  char ***pnames,
521                                  enum lsa_SidType **ptypes,
522                                  NTSTATUS *result)
523 {
524         return dcerpc_lsa_lookup_sids_generic(h,
525                                               mem_ctx,
526                                               pol,
527                                               num_sids,
528                                               sids,
529                                               pdomains,
530                                               pnames,
531                                               ptypes,
532                                               true,
533                                               result);
534 }
535
536 NTSTATUS rpccli_lsa_lookup_sids3(struct rpc_pipe_client *cli,
537                                  TALLOC_CTX *mem_ctx,
538                                  struct policy_handle *pol,
539                                  int num_sids,
540                                  const struct dom_sid *sids,
541                                  char ***pdomains,
542                                  char ***pnames,
543                                  enum lsa_SidType **ptypes)
544 {
545         NTSTATUS status;
546         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
547
548         status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle,
549                                                 mem_ctx,
550                                                 pol,
551                                                 num_sids,
552                                                 sids,
553                                                 pdomains,
554                                                 pnames,
555                                                 ptypes,
556                                                 true,
557                                                 &result);
558         if (!NT_STATUS_IS_OK(status)) {
559                 return status;
560         }
561
562         return result;
563 }
564
565 /** Lookup a list of names */
566
567 static NTSTATUS dcerpc_lsa_lookup_names_generic(struct dcerpc_binding_handle *h,
568                                                 TALLOC_CTX *mem_ctx,
569                                                 struct policy_handle *pol,
570                                                 uint32_t num_names,
571                                                 const char **names,
572                                                 const char ***dom_names,
573                                                 enum lsa_LookupNamesLevel level,
574                                                 struct dom_sid **sids,
575                                                 enum lsa_SidType **types,
576                                                 bool use_lookupnames4,
577                                                 NTSTATUS *presult)
578 {
579         NTSTATUS status;
580         struct lsa_String *lsa_names = NULL;
581         struct lsa_RefDomainList *domains = NULL;
582         struct lsa_TransSidArray sid_array;
583         struct lsa_TransSidArray3 sid_array3;
584         uint32_t count = 0;
585         uint32_t i;
586
587         ZERO_STRUCT(sid_array);
588         ZERO_STRUCT(sid_array3);
589
590         lsa_names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names);
591         if (lsa_names == NULL) {
592                 return NT_STATUS_NO_MEMORY;
593         }
594
595         for (i = 0; i < num_names; i++) {
596                 init_lsa_String(&lsa_names[i], names[i]);
597         }
598
599         if (use_lookupnames4) {
600                 status = dcerpc_lsa_LookupNames4(h,
601                                                  mem_ctx,
602                                                  num_names,
603                                                  lsa_names,
604                                                  &domains,
605                                                  &sid_array3,
606                                                  level,
607                                                  &count,
608                                                  0,
609                                                  0,
610                                                  presult);
611         } else {
612                 status = dcerpc_lsa_LookupNames(h,
613                                                 mem_ctx,
614                                                 pol,
615                                                 num_names,
616                                                 lsa_names,
617                                                 &domains,
618                                                 &sid_array,
619                                                 level,
620                                                 &count,
621                                                 presult);
622         }
623         if (!NT_STATUS_IS_OK(status)) {
624                 goto done;
625         }
626
627         if (!NT_STATUS_IS_OK(*presult) &&
628             !NT_STATUS_EQUAL(*presult, STATUS_SOME_UNMAPPED)) {
629                 /* An actual error occured */
630                 goto done;
631         }
632
633         /* Return output parameters */
634         if (count == 0) {
635                 *presult = NT_STATUS_NONE_MAPPED;
636                 goto done;
637         }
638
639         if (num_names) {
640                 if (!((*sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_names)))) {
641                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
642                         *presult = NT_STATUS_NO_MEMORY;
643                         goto done;
644                 }
645
646                 if (!((*types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_names)))) {
647                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
648                         *presult = NT_STATUS_NO_MEMORY;
649                         goto done;
650                 }
651
652                 if (dom_names != NULL) {
653                         *dom_names = TALLOC_ARRAY(mem_ctx, const char *, num_names);
654                         if (*dom_names == NULL) {
655                                 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
656                                 *presult = NT_STATUS_NO_MEMORY;
657                                 goto done;
658                         }
659                 }
660         } else {
661                 *sids = NULL;
662                 *types = NULL;
663                 if (dom_names != NULL) {
664                         *dom_names = NULL;
665                 }
666         }
667
668         for (i = 0; i < num_names; i++) {
669                 uint32_t dom_idx;
670                 struct dom_sid *sid = &(*sids)[i];
671
672                 if (use_lookupnames4) {
673                         dom_idx         = sid_array3.sids[i].sid_index;
674                         (*types)[i]     = sid_array3.sids[i].sid_type;
675                 } else {
676                         dom_idx         = sid_array.sids[i].sid_index;
677                         (*types)[i]     = sid_array.sids[i].sid_type;
678                 }
679
680                 /* Translate optimised sid through domain index array */
681
682                 if (dom_idx == 0xffffffff) {
683                         /* Nothing to do, this is unknown */
684                         ZERO_STRUCTP(sid);
685                         (*types)[i] = SID_NAME_UNKNOWN;
686                         continue;
687                 }
688
689                 if (use_lookupnames4) {
690                         sid_copy(sid, sid_array3.sids[i].sid);
691                 } else {
692                         sid_copy(sid, domains->domains[dom_idx].sid);
693
694                         if (sid_array.sids[i].rid != 0xffffffff) {
695                                 sid_append_rid(sid, sid_array.sids[i].rid);
696                         }
697                 }
698
699                 if (dom_names == NULL) {
700                         continue;
701                 }
702
703                 (*dom_names)[i] = domains->domains[dom_idx].name.string;
704         }
705
706  done:
707         return status;
708 }
709
710 NTSTATUS dcerpc_lsa_lookup_names(struct dcerpc_binding_handle *h,
711                                  TALLOC_CTX *mem_ctx,
712                                  struct policy_handle *pol,
713                                  uint32_t num_names,
714                                  const char **names,
715                                  const char ***dom_names,
716                                  enum lsa_LookupNamesLevel level,
717                                  struct dom_sid **sids,
718                                  enum lsa_SidType **types,
719                                  NTSTATUS *result)
720 {
721         return dcerpc_lsa_lookup_names_generic(h,
722                                                mem_ctx,
723                                                pol,
724                                                num_names,
725                                                names,
726                                                dom_names,
727                                                level,
728                                                sids,
729                                                types,
730                                                false,
731                                                result);
732 }
733
734 NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
735                                  TALLOC_CTX *mem_ctx,
736                                  struct policy_handle *pol,
737                                  int num_names,
738                                  const char **names,
739                                  const char ***dom_names,
740                                  int level,
741                                  struct dom_sid **sids,
742                                  enum lsa_SidType **types)
743 {
744         NTSTATUS status;
745         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
746
747         status = dcerpc_lsa_lookup_names(cli->binding_handle,
748                                          mem_ctx,
749                                          pol,
750                                          num_names,
751                                          names,
752                                          dom_names,
753                                          level,
754                                          sids,
755                                          types,
756                                          &result);
757         if (!NT_STATUS_IS_OK(status)) {
758                 return status;
759         }
760
761         return result;
762 }
763
764 NTSTATUS dcerpc_lsa_lookup_names4(struct dcerpc_binding_handle *h,
765                                   TALLOC_CTX *mem_ctx,
766                                   struct policy_handle *pol,
767                                   uint32_t num_names,
768                                   const char **names,
769                                   const char ***dom_names,
770                                   enum lsa_LookupNamesLevel level,
771                                   struct dom_sid **sids,
772                                   enum lsa_SidType **types,
773                                   NTSTATUS *result)
774 {
775         return dcerpc_lsa_lookup_names_generic(h,
776                                                mem_ctx,
777                                                pol,
778                                                num_names,
779                                                names,
780                                                dom_names,
781                                                level,
782                                                sids,
783                                                types,
784                                                true,
785                                                result);
786 }
787
788 NTSTATUS rpccli_lsa_lookup_names4(struct rpc_pipe_client *cli,
789                                   TALLOC_CTX *mem_ctx,
790                                   struct policy_handle *pol,
791                                   int num_names,
792                                   const char **names,
793                                   const char ***dom_names,
794                                   int level,
795                                   struct dom_sid **sids,
796                                   enum lsa_SidType **types)
797 {
798         NTSTATUS status;
799         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
800
801         status = dcerpc_lsa_lookup_names4(cli->binding_handle,
802                                           mem_ctx,
803                                           pol,
804                                           num_names,
805                                           names,
806                                           dom_names,
807                                           level,
808                                           sids,
809                                           types,
810                                           &result);
811         if (!NT_STATUS_IS_OK(status)) {
812                 return status;
813         }
814
815         return result;
816 }