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