r25225: Add a debug message.
[ira/wip.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    
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.
13    
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.
18    
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/>.
21 */
22
23 #include "includes.h"
24
25 /** @defgroup lsa LSA - Local Security Architecture
26  *  @ingroup rpc_client
27  *
28  * @{
29  **/
30
31 /**
32  * @file cli_lsarpc.c
33  *
34  * RPC client routines for the LSA RPC pipe.  LSA means "local
35  * security authority", which is half of a password database.
36  **/
37
38 /** Open a LSA policy handle
39  *
40  * @param cli Handle on an initialised SMB connection */
41
42 NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
43                                 TALLOC_CTX *mem_ctx,
44                                 BOOL sec_qos, uint32 des_access,
45                                 POLICY_HND *pol)
46 {
47         prs_struct qbuf, rbuf;
48         LSA_Q_OPEN_POL q;
49         LSA_R_OPEN_POL r;
50         LSA_SEC_QOS qos;
51         NTSTATUS result;
52
53         ZERO_STRUCT(q);
54         ZERO_STRUCT(r);
55
56         /* Initialise input parameters */
57
58         if (sec_qos) {
59                 init_lsa_sec_qos(&qos, 2, 1, 0);
60                 init_q_open_pol(&q, '\\', 0, des_access, &qos);
61         } else {
62                 init_q_open_pol(&q, '\\', 0, des_access, NULL);
63         }
64
65         /* Marshall data and send request */
66
67         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENPOLICY,
68                         q, r,
69                         qbuf, rbuf,
70                         lsa_io_q_open_pol,
71                         lsa_io_r_open_pol,
72                         NT_STATUS_UNSUCCESSFUL );
73
74         /* Return output parameters */
75
76         result = r.status;
77
78         if (NT_STATUS_IS_OK(result)) {
79                 *pol = r.pol;
80         }
81
82         return result;
83 }
84
85 /** Open a LSA policy handle
86   *
87   * @param cli Handle on an initialised SMB connection 
88   */
89
90 NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
91                                  TALLOC_CTX *mem_ctx, BOOL sec_qos,
92                                  uint32 des_access, POLICY_HND *pol)
93 {
94         prs_struct qbuf, rbuf;
95         LSA_Q_OPEN_POL2 q;
96         LSA_R_OPEN_POL2 r;
97         LSA_SEC_QOS qos;
98         NTSTATUS result;
99         char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
100
101         ZERO_STRUCT(q);
102         ZERO_STRUCT(r);
103
104         if (sec_qos) {
105                 init_lsa_sec_qos(&qos, 2, 1, 0);
106                 init_q_open_pol2(&q, srv_name_slash, 0, des_access, &qos);
107         } else {
108                 init_q_open_pol2(&q, srv_name_slash, 0, des_access, NULL);
109         }
110
111         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENPOLICY2,
112                         q, r,
113                         qbuf, rbuf,
114                         lsa_io_q_open_pol2,
115                         lsa_io_r_open_pol2,
116                         NT_STATUS_UNSUCCESSFUL );
117
118         /* Return output parameters */
119
120         result = r.status;
121
122         if (NT_STATUS_IS_OK(result)) {
123                 *pol = r.pol;
124         }
125
126         return result;
127 }
128
129 /* Lookup a list of sids
130  *
131  * internal version withOUT memory allocation of the target arrays.
132  * this assumes suffciently sized arrays to store domains, names and types. */
133
134 static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli,
135                                                TALLOC_CTX *mem_ctx,
136                                                POLICY_HND *pol,
137                                                int num_sids,
138                                                const DOM_SID *sids,
139                                                char **domains,
140                                                char **names,
141                                                enum lsa_SidType *types)
142 {
143         prs_struct qbuf, rbuf;
144         LSA_Q_LOOKUP_SIDS q;
145         LSA_R_LOOKUP_SIDS r;
146         DOM_R_REF ref;
147         NTSTATUS result = NT_STATUS_OK;
148         TALLOC_CTX *tmp_ctx = NULL;
149         int i;
150
151         tmp_ctx = talloc_new(mem_ctx);
152         if (!tmp_ctx) {
153                 DEBUG(0, ("rpccli_lsa_lookup_sids_noalloc: out of memory!\n"));
154                 result = NT_STATUS_UNSUCCESSFUL;
155                 goto done;
156         }
157
158         ZERO_STRUCT(q);
159         ZERO_STRUCT(r);
160
161         init_q_lookup_sids(tmp_ctx, &q, pol, num_sids, sids, 1);
162
163         ZERO_STRUCT(ref);
164
165         r.dom_ref = &ref;
166
167         CLI_DO_RPC( cli, tmp_ctx, PI_LSARPC, LSA_LOOKUPSIDS,
168                         q, r,
169                         qbuf, rbuf,
170                         lsa_io_q_lookup_sids,
171                         lsa_io_r_lookup_sids,
172                         NT_STATUS_UNSUCCESSFUL );
173
174         DEBUG(10, ("LSA_LOOKUPSIDS returned '%s', mapped count = %d'\n",
175                    nt_errstr(r.status), r.mapped_count));
176
177         if (!NT_STATUS_IS_OK(r.status) &&
178             !NT_STATUS_EQUAL(r.status, NT_STATUS_NONE_MAPPED) &&
179             !NT_STATUS_EQUAL(r.status, STATUS_SOME_UNMAPPED)) 
180         {
181                 /* An actual error occured */
182                 result = r.status;
183                 goto done;
184         }
185
186         /* Return output parameters */
187
188         if (NT_STATUS_EQUAL(r.status, NT_STATUS_NONE_MAPPED) ||
189             (r.mapped_count == 0))
190         {
191                 for (i = 0; i < num_sids; i++) {
192                         (names)[i] = NULL;
193                         (domains)[i] = NULL;
194                         (types)[i] = SID_NAME_UNKNOWN;
195                 }
196                 result = NT_STATUS_NONE_MAPPED;
197                 goto done;
198         }
199
200         for (i = 0; i < num_sids; i++) {
201                 fstring name, dom_name;
202                 uint32 dom_idx = r.names.name[i].domain_idx;
203
204                 /* Translate optimised name through domain index array */
205
206                 if (dom_idx != 0xffffffff) {
207
208                         rpcstr_pull_unistr2_fstring(
209                                 dom_name, &ref.ref_dom[dom_idx].uni_dom_name);
210                         rpcstr_pull_unistr2_fstring(
211                                 name, &r.names.uni_name[i]);
212
213                         (names)[i] = talloc_strdup(mem_ctx, name);
214                         (domains)[i] = talloc_strdup(mem_ctx, dom_name);
215                         (types)[i] = (enum lsa_SidType)r.names.name[i].sid_name_use;
216                         
217                         if (((names)[i] == NULL) || ((domains)[i] == NULL)) {
218                                 DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n"));
219                                 result = NT_STATUS_UNSUCCESSFUL;
220                                 goto done;
221                         }
222
223                 } else {
224                         (names)[i] = NULL;
225                         (domains)[i] = NULL;
226                         (types)[i] = SID_NAME_UNKNOWN;
227                 }
228         }
229
230 done:
231         TALLOC_FREE(tmp_ctx);
232         return result;
233 }
234
235 /* Lookup a list of sids 
236  *
237  * do it the right way: there is a limit (of 20480 for w2k3) entries
238  * returned by this call. when the sids list contains more entries,
239  * empty lists are returned. This version of lsa_lookup_sids passes
240  * the list of sids in hunks of LOOKUP_SIDS_HUNK_SIZE to the lsa call. */
241
242 /* This constant defines the limit of how many sids to look up
243  * in one call (maximum). the limit from the server side is
244  * at 20480 for win2k3, but we keep it at a save 1000 for now. */
245 #define LOOKUP_SIDS_HUNK_SIZE 1000
246
247 NTSTATUS rpccli_lsa_lookup_sids_all(struct rpc_pipe_client *cli,
248                                     TALLOC_CTX *mem_ctx,
249                                     POLICY_HND *pol, 
250                                     int num_sids,
251                                     const DOM_SID *sids, 
252                                     char ***domains,
253                                     char ***names,
254                                     enum lsa_SidType **types)
255 {
256         NTSTATUS result = NT_STATUS_OK;
257         int sids_left = 0;
258         int sids_processed = 0;
259         const DOM_SID *hunk_sids = sids;
260         char **hunk_domains = NULL;
261         char **hunk_names = NULL;
262         enum lsa_SidType *hunk_types = NULL;
263
264         if (num_sids) {
265                 if (!((*domains) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
266                         DEBUG(0, ("rpccli_lsa_lookup_sids_all(): out of memory\n"));
267                         result = NT_STATUS_NO_MEMORY;
268                         goto fail;
269                 }
270
271                 if (!((*names) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
272                         DEBUG(0, ("rpccli_lsa_lookup_sids_all(): out of memory\n"));
273                         result = NT_STATUS_NO_MEMORY;
274                         goto fail;
275                 }
276
277                 if (!((*types) = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_sids))) {
278                         DEBUG(0, ("rpccli_lsa_lookup_sids_all(): out of memory\n"));
279                         result = NT_STATUS_NO_MEMORY;
280                         goto fail;
281                 }
282         } else {
283                 (*domains) = NULL;
284                 (*names) = NULL;
285                 (*types) = NULL;
286         }
287         
288         sids_left = num_sids;
289         hunk_domains = *domains;
290         hunk_names = *names;
291         hunk_types = *types;
292
293         while (sids_left > 0) {
294                 int hunk_num_sids;
295                 NTSTATUS hunk_result = NT_STATUS_OK;
296
297                 hunk_num_sids = ((sids_left > LOOKUP_SIDS_HUNK_SIZE) 
298                                 ? LOOKUP_SIDS_HUNK_SIZE 
299                                 : sids_left);
300
301                 DEBUG(10, ("rpccli_lsa_lookup_sids_all: processing items "
302                            "%d -- %d of %d.\n", 
303                            sids_processed, 
304                            sids_processed + hunk_num_sids - 1,
305                            num_sids));
306
307                 hunk_result = rpccli_lsa_lookup_sids_noalloc(cli,
308                                                              mem_ctx,
309                                                              pol,
310                                                              hunk_num_sids, 
311                                                              hunk_sids,
312                                                              hunk_domains,
313                                                              hunk_names,
314                                                              hunk_types);
315
316                 if (!NT_STATUS_IS_OK(hunk_result) &&
317                     !NT_STATUS_EQUAL(hunk_result, STATUS_SOME_UNMAPPED) &&
318                     !NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED)) 
319                 {
320                         /* An actual error occured */
321                         result = hunk_result;
322                         goto fail;
323                 }
324
325                 /* adapt overall result */
326                 if (( NT_STATUS_IS_OK(result) && 
327                      !NT_STATUS_IS_OK(hunk_result)) 
328                     ||
329                     ( NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) &&
330                      !NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED)))
331                 {
332                         result = STATUS_SOME_UNMAPPED;
333                 }
334
335                 sids_left -= hunk_num_sids;
336                 sids_processed += hunk_num_sids; /* only used in DEBUG */
337                 hunk_sids += hunk_num_sids;
338                 hunk_domains += hunk_num_sids;
339                 hunk_names += hunk_num_sids;
340                 hunk_types += hunk_num_sids;
341         }
342
343         return result;
344
345 fail:
346         TALLOC_FREE(*domains);
347         TALLOC_FREE(*names);
348         TALLOC_FREE(*types);
349         return result;
350 }
351
352 /** Lookup a list of sids */
353
354 NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
355                                 TALLOC_CTX *mem_ctx,
356                                 POLICY_HND *pol, int num_sids,
357                                 const DOM_SID *sids, 
358                                 char ***domains,
359                                 char ***names,
360                                 enum lsa_SidType **types)
361 {
362         prs_struct qbuf, rbuf;
363         LSA_Q_LOOKUP_SIDS q;
364         LSA_R_LOOKUP_SIDS r;
365         DOM_R_REF ref;
366         NTSTATUS result = NT_STATUS_OK;
367         int i;
368
369         ZERO_STRUCT(q);
370         ZERO_STRUCT(r);
371
372         init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1);
373
374         ZERO_STRUCT(ref);
375
376         r.dom_ref = &ref;
377
378         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPSIDS,
379                         q, r,
380                         qbuf, rbuf,
381                         lsa_io_q_lookup_sids,
382                         lsa_io_r_lookup_sids,
383                         NT_STATUS_UNSUCCESSFUL );
384
385         if (!NT_STATUS_IS_OK(r.status) &&
386             !NT_STATUS_EQUAL(r.status, STATUS_SOME_UNMAPPED)) {
387           
388                 /* An actual error occured */
389                 result = r.status;
390
391                 goto done;
392         }
393
394         /* Return output parameters */
395
396         if (r.mapped_count == 0) {
397                 result = NT_STATUS_NONE_MAPPED;
398                 goto done;
399         }
400
401         if (num_sids) {
402                 if (!((*domains) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
403                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
404                         result = NT_STATUS_NO_MEMORY;
405                         goto done;
406                 }
407
408                 if (!((*names) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
409                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
410                         result = NT_STATUS_NO_MEMORY;
411                         goto done;
412                 }
413
414                 if (!((*types) = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_sids))) {
415                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
416                         result = NT_STATUS_NO_MEMORY;
417                         goto done;
418                 }
419         } else {
420                 (*domains) = NULL;
421                 (*names) = NULL;
422                 (*types) = NULL;
423         }
424                 
425         for (i = 0; i < num_sids; i++) {
426                 fstring name, dom_name;
427                 uint32 dom_idx = r.names.name[i].domain_idx;
428
429                 /* Translate optimised name through domain index array */
430
431                 if (dom_idx != 0xffffffff) {
432
433                         rpcstr_pull_unistr2_fstring(
434                                 dom_name, &ref.ref_dom[dom_idx].uni_dom_name);
435                         rpcstr_pull_unistr2_fstring(
436                                 name, &r.names.uni_name[i]);
437
438                         (*names)[i] = talloc_strdup(mem_ctx, name);
439                         (*domains)[i] = talloc_strdup(mem_ctx, dom_name);
440                         (*types)[i] = (enum lsa_SidType)r.names.name[i].sid_name_use;
441                         
442                         if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) {
443                                 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
444                                 result = NT_STATUS_UNSUCCESSFUL;
445                                 goto done;
446                         }
447
448                 } else {
449                         (*names)[i] = NULL;
450                         (*domains)[i] = NULL;
451                         (*types)[i] = SID_NAME_UNKNOWN;
452                 }
453         }
454
455  done:
456
457         return result;
458 }
459
460 /** Lookup a list of names */
461
462 NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
463                                  TALLOC_CTX *mem_ctx,
464                                  POLICY_HND *pol, int num_names, 
465                                  const char **names,
466                                  const char ***dom_names,
467                                  int level,
468                                  DOM_SID **sids,
469                                  enum lsa_SidType **types)
470 {
471         prs_struct qbuf, rbuf;
472         LSA_Q_LOOKUP_NAMES q;
473         LSA_R_LOOKUP_NAMES r;
474         DOM_R_REF ref;
475         NTSTATUS result;
476         int i;
477         
478         ZERO_STRUCT(q);
479         ZERO_STRUCT(r);
480
481         ZERO_STRUCT(ref);
482         r.dom_ref = &ref;
483
484         init_q_lookup_names(mem_ctx, &q, pol, num_names, names, level);
485
486         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPNAMES,
487                         q, r,
488                         qbuf, rbuf,
489                         lsa_io_q_lookup_names,
490                         lsa_io_r_lookup_names,
491                         NT_STATUS_UNSUCCESSFUL);
492
493         result = r.status;
494
495         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
496             NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
497
498                 /* An actual error occured */
499
500                 goto done;
501         }
502
503         /* Return output parameters */
504
505         if (r.mapped_count == 0) {
506                 result = NT_STATUS_NONE_MAPPED;
507                 goto done;
508         }
509
510         if (num_names) {
511                 if (!((*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_names)))) {
512                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
513                         result = NT_STATUS_NO_MEMORY;
514                         goto done;
515                 }
516
517                 if (!((*types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_names)))) {
518                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
519                         result = NT_STATUS_NO_MEMORY;
520                         goto done;
521                 }
522
523                 if (dom_names != NULL) {
524                         *dom_names = TALLOC_ARRAY(mem_ctx, const char *, num_names);
525                         if (*dom_names == NULL) {
526                                 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
527                                 result = NT_STATUS_NO_MEMORY;
528                                 goto done;
529                         }
530                 }
531         } else {
532                 *sids = NULL;
533                 *types = NULL;
534                 if (dom_names != NULL) {
535                         *dom_names = NULL;
536                 }
537         }
538
539         for (i = 0; i < num_names; i++) {
540                 DOM_RID *t_rids = r.dom_rid;
541                 uint32 dom_idx = t_rids[i].rid_idx;
542                 uint32 dom_rid = t_rids[i].rid;
543                 DOM_SID *sid = &(*sids)[i];
544
545                 /* Translate optimised sid through domain index array */
546
547                 if (dom_idx == 0xffffffff) {
548                         /* Nothing to do, this is unknown */
549                         ZERO_STRUCTP(sid);
550                         (*types)[i] = SID_NAME_UNKNOWN;
551                         continue;
552                 }
553
554                 sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid);
555
556                 if (dom_rid != 0xffffffff) {
557                         sid_append_rid(sid, dom_rid);
558                 }
559
560                 (*types)[i] = (enum lsa_SidType)t_rids[i].type;
561
562                 if (dom_names == NULL) {
563                         continue;
564                 }
565
566                 (*dom_names)[i] = rpcstr_pull_unistr2_talloc(
567                         *dom_names, &ref.ref_dom[dom_idx].uni_dom_name);
568         }
569
570  done:
571
572         return result;
573 }
574
575 NTSTATUS rpccli_lsa_query_info_policy_new(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
576                                           POLICY_HND *pol, uint16 info_class,
577                                           LSA_INFO_CTR *ctr) 
578 {
579         prs_struct qbuf, rbuf;
580         LSA_Q_QUERY_INFO q;
581         LSA_R_QUERY_INFO r;
582         NTSTATUS result;
583
584         ZERO_STRUCT(q);
585         ZERO_STRUCT(r);
586
587         init_q_query(&q, pol, info_class);
588
589         CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFOPOLICY,
590                 q, r,
591                 qbuf, rbuf,
592                 lsa_io_q_query,
593                 lsa_io_r_query,
594                 NT_STATUS_UNSUCCESSFUL);
595
596         result = r.status;
597
598         if (!NT_STATUS_IS_OK(result)) {
599                 goto done;
600         }
601
602  done:
603
604         *ctr = r.ctr;
605         
606         return result;
607 }
608
609 NTSTATUS rpccli_lsa_query_info_policy2_new(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
610                                           POLICY_HND *pol, uint16 info_class,
611                                           LSA_INFO_CTR2 *ctr) 
612 {
613         prs_struct qbuf, rbuf;
614         LSA_Q_QUERY_INFO2 q;
615         LSA_R_QUERY_INFO2 r;
616         NTSTATUS result;
617
618         ZERO_STRUCT(q);
619         ZERO_STRUCT(r);
620
621         init_q_query2(&q, pol, info_class);
622
623         CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFO2,
624                 q, r,
625                 qbuf, rbuf,
626                 lsa_io_q_query_info2,
627                 lsa_io_r_query_info2,
628                 NT_STATUS_UNSUCCESSFUL);
629
630         result = r.status;
631
632         if (!NT_STATUS_IS_OK(result)) {
633                 goto done;
634         }
635
636  done:
637
638         *ctr = r.ctr;
639         
640         return result;
641 }
642
643
644
645 /** Query info policy
646  *
647  *  @param domain_sid - returned remote server's domain sid */
648
649 NTSTATUS rpccli_lsa_query_info_policy(struct rpc_pipe_client *cli,
650                                       TALLOC_CTX *mem_ctx,
651                                       POLICY_HND *pol, uint16 info_class, 
652                                       char **domain_name, DOM_SID **domain_sid)
653 {
654         prs_struct qbuf, rbuf;
655         LSA_Q_QUERY_INFO q;
656         LSA_R_QUERY_INFO r;
657         NTSTATUS result;
658
659         ZERO_STRUCT(q);
660         ZERO_STRUCT(r);
661
662         init_q_query(&q, pol, info_class);
663
664         CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFOPOLICY,
665                 q, r,
666                 qbuf, rbuf,
667                 lsa_io_q_query,
668                 lsa_io_r_query,
669                 NT_STATUS_UNSUCCESSFUL);
670
671         result = r.status;
672
673         if (!NT_STATUS_IS_OK(result)) {
674                 goto done;
675         }
676
677         /* Return output parameters */
678
679         switch (info_class) {
680
681         case 3:
682                 if (domain_name && (r.ctr.info.id3.buffer_dom_name != 0)) {
683                         *domain_name = unistr2_tdup(mem_ctx, 
684                                                    &r.ctr.info.id3.
685                                                    uni_domain_name);
686                         if (!*domain_name) {
687                                 return NT_STATUS_NO_MEMORY;
688                         }
689                 }
690
691                 if (domain_sid && (r.ctr.info.id3.buffer_dom_sid != 0)) {
692                         *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
693                         if (!*domain_sid) {
694                                 return NT_STATUS_NO_MEMORY;
695                         }
696                         sid_copy(*domain_sid, &r.ctr.info.id3.dom_sid.sid);
697                 }
698
699                 break;
700
701         case 5:
702                 
703                 if (domain_name && (r.ctr.info.id5.buffer_dom_name != 0)) {
704                         *domain_name = unistr2_tdup(mem_ctx, 
705                                                    &r.ctr.info.id5.
706                                                    uni_domain_name);
707                         if (!*domain_name) {
708                                 return NT_STATUS_NO_MEMORY;
709                         }
710                 }
711                         
712                 if (domain_sid && (r.ctr.info.id5.buffer_dom_sid != 0)) {
713                         *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
714                         if (!*domain_sid) {
715                                 return NT_STATUS_NO_MEMORY;
716                         }
717                         sid_copy(*domain_sid, &r.ctr.info.id5.dom_sid.sid);
718                 }
719                 break;
720                         
721         default:
722                 DEBUG(3, ("unknown info class %d\n", info_class));
723                 break;                
724         }
725         
726  done:
727
728         return result;
729 }
730
731 /** Query info policy2
732  *
733  *  @param domain_name - returned remote server's domain name
734  *  @param dns_name - returned remote server's dns domain name
735  *  @param forest_name - returned remote server's forest name
736  *  @param domain_guid - returned remote server's domain guid
737  *  @param domain_sid - returned remote server's domain sid */
738
739 NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli,
740                                        TALLOC_CTX *mem_ctx,
741                                        POLICY_HND *pol, uint16 info_class, 
742                                        char **domain_name, char **dns_name,
743                                        char **forest_name,
744                                        struct GUID **domain_guid,
745                                        DOM_SID **domain_sid)
746 {
747         prs_struct qbuf, rbuf;
748         LSA_Q_QUERY_INFO2 q;
749         LSA_R_QUERY_INFO2 r;
750         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
751
752         if (info_class != 12)
753                 goto done;
754
755         ZERO_STRUCT(q);
756         ZERO_STRUCT(r);
757
758         init_q_query2(&q, pol, info_class);
759
760         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYINFO2,
761                 q, r,
762                 qbuf, rbuf,
763                 lsa_io_q_query_info2,
764                 lsa_io_r_query_info2,
765                 NT_STATUS_UNSUCCESSFUL);
766
767         result = r.status;
768
769         if (!NT_STATUS_IS_OK(result)) {
770                 goto done;
771         }
772
773         /* Return output parameters */
774
775         ZERO_STRUCTP(domain_guid);
776
777         if (domain_name && r.ctr.info.id12.hdr_nb_dom_name.buffer) {
778                 *domain_name = unistr2_tdup(mem_ctx, 
779                                             &r.ctr.info.id12
780                                             .uni_nb_dom_name);
781                 if (!*domain_name) {
782                         return NT_STATUS_NO_MEMORY;
783                 }
784         }
785         if (dns_name && r.ctr.info.id12.hdr_dns_dom_name.buffer) {
786                 *dns_name = unistr2_tdup(mem_ctx, 
787                                          &r.ctr.info.id12
788                                          .uni_dns_dom_name);
789                 if (!*dns_name) {
790                         return NT_STATUS_NO_MEMORY;
791                 }
792         }
793         if (forest_name && r.ctr.info.id12.hdr_forest_name.buffer) {
794                 *forest_name = unistr2_tdup(mem_ctx, 
795                                             &r.ctr.info.id12
796                                             .uni_forest_name);
797                 if (!*forest_name) {
798                         return NT_STATUS_NO_MEMORY;
799                 }
800         }
801         
802         if (domain_guid) {
803                 *domain_guid = TALLOC_P(mem_ctx, struct GUID);
804                 if (!*domain_guid) {
805                         return NT_STATUS_NO_MEMORY;
806                 }
807                 memcpy(*domain_guid, 
808                        &r.ctr.info.id12.dom_guid, 
809                        sizeof(struct GUID));
810         }
811
812         if (domain_sid && r.ctr.info.id12.ptr_dom_sid != 0) {
813                 *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
814                 if (!*domain_sid) {
815                         return NT_STATUS_NO_MEMORY;
816                 }
817                 sid_copy(*domain_sid, 
818                          &r.ctr.info.id12.dom_sid.sid);
819         }
820         
821  done:
822
823         return result;
824 }
825
826 NTSTATUS rpccli_lsa_set_info_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
827                                     POLICY_HND *pol, uint16 info_class,
828                                     LSA_INFO_CTR ctr) 
829 {
830         prs_struct qbuf, rbuf;
831         LSA_Q_SET_INFO q;
832         LSA_R_SET_INFO r;
833         NTSTATUS result;
834
835         ZERO_STRUCT(q);
836         ZERO_STRUCT(r);
837
838         init_q_set(&q, pol, info_class, ctr);
839
840         CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_SETINFOPOLICY,
841                 q, r,
842                 qbuf, rbuf,
843                 lsa_io_q_set,
844                 lsa_io_r_set,
845                 NT_STATUS_UNSUCCESSFUL);
846
847         result = r.status;
848
849         if (!NT_STATUS_IS_OK(result)) {
850                 goto done;
851         }
852
853         /* Return output parameters */
854
855  done:
856
857         return result;
858 }
859
860
861 /**
862  * Enumerate list of trusted domains
863  *
864  * @param cli client state (cli_state) structure of the connection
865  * @param mem_ctx memory context
866  * @param pol opened lsa policy handle
867  * @param enum_ctx enumeration context ie. index of first returned domain entry
868  * @param pref_num_domains preferred max number of entries returned in one response
869  * @param num_domains total number of trusted domains returned by response
870  * @param domain_names returned trusted domain names
871  * @param domain_sids returned trusted domain sids
872  *
873  * @return nt status code of response
874  **/
875
876 NTSTATUS rpccli_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
877                                    TALLOC_CTX *mem_ctx,
878                                    POLICY_HND *pol, uint32 *enum_ctx, 
879                                    uint32 *num_domains,
880                                    char ***domain_names, DOM_SID **domain_sids)
881 {
882         prs_struct qbuf, rbuf;
883         LSA_Q_ENUM_TRUST_DOM in;
884         LSA_R_ENUM_TRUST_DOM out;
885         int i;
886         fstring tmp;
887
888         ZERO_STRUCT(in);
889         ZERO_STRUCT(out);
890
891         /* 64k is enough for about 2000 trusted domains */
892         
893         init_q_enum_trust_dom(&in, pol, *enum_ctx, 0x10000);
894
895         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMTRUSTDOM, 
896                     in, out, 
897                     qbuf, rbuf,
898                     lsa_io_q_enum_trust_dom,
899                     lsa_io_r_enum_trust_dom, 
900                     NT_STATUS_UNSUCCESSFUL );
901
902
903         /* check for an actual error */
904
905         if ( !NT_STATUS_IS_OK(out.status) 
906                 && !NT_STATUS_EQUAL(out.status, NT_STATUS_NO_MORE_ENTRIES) 
907                 && !NT_STATUS_EQUAL(out.status, STATUS_MORE_ENTRIES) )
908         {
909                 return out.status;
910         }
911                 
912         /* Return output parameters */
913
914         *num_domains  = out.count;
915         *enum_ctx     = out.enum_context;
916         
917         if ( out.count ) {
918
919                 /* Allocate memory for trusted domain names and sids */
920
921                 if ( !(*domain_names = TALLOC_ARRAY(mem_ctx, char *, out.count)) ) {
922                         DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
923                         return NT_STATUS_NO_MEMORY;
924                 }
925
926                 if ( !(*domain_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, out.count)) ) {
927                         DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
928                         return NT_STATUS_NO_MEMORY;
929                 }
930
931                 /* Copy across names and sids */
932
933                 for (i = 0; i < out.count; i++) {
934
935                         rpcstr_pull( tmp, out.domlist->domains[i].name.string->buffer, 
936                                 sizeof(tmp), out.domlist->domains[i].name.length, 0);
937                         (*domain_names)[i] = talloc_strdup(mem_ctx, tmp);
938
939                         sid_copy(&(*domain_sids)[i], &out.domlist->domains[i].sid->sid );
940                 }
941         }
942
943         return out.status;
944 }
945
946 /** Enumerate privileges*/
947
948 NTSTATUS rpccli_lsa_enum_privilege(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
949                                 POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length,
950                                 uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low)
951 {
952         prs_struct qbuf, rbuf;
953         LSA_Q_ENUM_PRIVS q;
954         LSA_R_ENUM_PRIVS r;
955         NTSTATUS result;
956         int i;
957
958         ZERO_STRUCT(q);
959         ZERO_STRUCT(r);
960
961         init_q_enum_privs(&q, pol, *enum_context, pref_max_length);
962
963         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_PRIVS,
964                 q, r,
965                 qbuf, rbuf,
966                 lsa_io_q_enum_privs,
967                 lsa_io_r_enum_privs,
968                 NT_STATUS_UNSUCCESSFUL);
969
970         result = r.status;
971
972         if (!NT_STATUS_IS_OK(result)) {
973                 goto done;
974         }
975
976         /* Return output parameters */
977
978         *enum_context = r.enum_context;
979         *count = r.count;
980
981         if (r.count) {
982                 if (!((*privs_name = TALLOC_ARRAY(mem_ctx, char *, r.count)))) {
983                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
984                         result = NT_STATUS_UNSUCCESSFUL;
985                         goto done;
986                 }
987
988                 if (!((*privs_high = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {
989                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
990                         result = NT_STATUS_UNSUCCESSFUL;
991                         goto done;
992                 }
993
994                 if (!((*privs_low = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {
995                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
996                         result = NT_STATUS_UNSUCCESSFUL;
997                         goto done;
998                 }
999         } else {
1000                 *privs_name = NULL;
1001                 *privs_high = NULL;
1002                 *privs_low = NULL;
1003         }
1004
1005         for (i = 0; i < r.count; i++) {
1006                 fstring name;
1007
1008                 rpcstr_pull_unistr2_fstring( name, &r.privs[i].name);
1009
1010                 (*privs_name)[i] = talloc_strdup(mem_ctx, name);
1011
1012                 (*privs_high)[i] = r.privs[i].luid_high;
1013                 (*privs_low)[i] = r.privs[i].luid_low;
1014         }
1015
1016  done:
1017
1018         return result;
1019 }
1020
1021 /** Get privilege name */
1022
1023 NTSTATUS rpccli_lsa_get_dispname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1024                               POLICY_HND *pol, const char *name, 
1025                               uint16 lang_id, uint16 lang_id_sys,
1026                               fstring description, uint16 *lang_id_desc)
1027 {
1028         prs_struct qbuf, rbuf;
1029         LSA_Q_PRIV_GET_DISPNAME q;
1030         LSA_R_PRIV_GET_DISPNAME r;
1031         NTSTATUS result;
1032
1033         ZERO_STRUCT(q);
1034         ZERO_STRUCT(r);
1035
1036         init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys);
1037
1038         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_PRIV_GET_DISPNAME,
1039                 q, r,
1040                 qbuf, rbuf,
1041                 lsa_io_q_priv_get_dispname,
1042                 lsa_io_r_priv_get_dispname,
1043                 NT_STATUS_UNSUCCESSFUL);
1044
1045         result = r.status;
1046
1047         if (!NT_STATUS_IS_OK(result)) {
1048                 goto done;
1049         }
1050
1051         /* Return output parameters */
1052         
1053         rpcstr_pull_unistr2_fstring(description , &r.desc);
1054         *lang_id_desc = r.lang_id;
1055
1056  done:
1057
1058         return result;
1059 }
1060
1061 /** Enumerate list of SIDs  */
1062
1063 NTSTATUS rpccli_lsa_enum_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1064                                 POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length, 
1065                                 uint32 *num_sids, DOM_SID **sids)
1066 {
1067         prs_struct qbuf, rbuf;
1068         LSA_Q_ENUM_ACCOUNTS q;
1069         LSA_R_ENUM_ACCOUNTS r;
1070         NTSTATUS result;
1071         int i;
1072
1073         ZERO_STRUCT(q);
1074         ZERO_STRUCT(r);
1075
1076         init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length);
1077
1078         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_ACCOUNTS,
1079                 q, r,
1080                 qbuf, rbuf,
1081                 lsa_io_q_enum_accounts,
1082                 lsa_io_r_enum_accounts,
1083                 NT_STATUS_UNSUCCESSFUL);
1084
1085         result = r.status;
1086
1087         if (!NT_STATUS_IS_OK(result)) {
1088                 goto done;
1089         }
1090
1091         if (r.sids.num_entries==0)
1092                 goto done;
1093
1094         /* Return output parameters */
1095
1096         *sids = TALLOC_ARRAY(mem_ctx, DOM_SID, r.sids.num_entries);
1097         if (!*sids) {
1098                 DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n"));
1099                 result = NT_STATUS_UNSUCCESSFUL;
1100                 goto done;
1101         }
1102
1103         /* Copy across names and sids */
1104
1105         for (i = 0; i < r.sids.num_entries; i++) {
1106                 sid_copy(&(*sids)[i], &r.sids.sid[i].sid);
1107         }
1108
1109         *num_sids= r.sids.num_entries;
1110         *enum_ctx = r.enum_context;
1111
1112  done:
1113
1114         return result;
1115 }
1116
1117 /** Create a LSA user handle
1118  *
1119  * @param cli Handle on an initialised SMB connection
1120  *
1121  * FIXME: The code is actually identical to open account
1122  * TODO: Check and code what the function should exactly do
1123  *
1124  * */
1125
1126 NTSTATUS rpccli_lsa_create_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1127                              POLICY_HND *dom_pol, DOM_SID *sid, uint32 desired_access, 
1128                              POLICY_HND *user_pol)
1129 {
1130         prs_struct qbuf, rbuf;
1131         LSA_Q_CREATEACCOUNT q;
1132         LSA_R_CREATEACCOUNT r;
1133         NTSTATUS result;
1134
1135         ZERO_STRUCT(q);
1136         ZERO_STRUCT(r);
1137
1138         /* Initialise input parameters */
1139
1140         init_lsa_q_create_account(&q, dom_pol, sid, desired_access);
1141
1142         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_CREATEACCOUNT,
1143                 q, r,
1144                 qbuf, rbuf,
1145                 lsa_io_q_create_account,
1146                 lsa_io_r_create_account,
1147                 NT_STATUS_UNSUCCESSFUL);
1148
1149         /* Return output parameters */
1150
1151         result = r.status;
1152
1153         if (NT_STATUS_IS_OK(result)) {
1154                 *user_pol = r.pol;
1155         }
1156
1157         return result;
1158 }
1159
1160 /** Open a LSA user handle
1161  *
1162  * @param cli Handle on an initialised SMB connection */
1163
1164 NTSTATUS rpccli_lsa_open_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1165                              POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access, 
1166                              POLICY_HND *user_pol)
1167 {
1168         prs_struct qbuf, rbuf;
1169         LSA_Q_OPENACCOUNT q;
1170         LSA_R_OPENACCOUNT r;
1171         NTSTATUS result;
1172
1173         ZERO_STRUCT(q);
1174         ZERO_STRUCT(r);
1175
1176         /* Initialise input parameters */
1177
1178         init_lsa_q_open_account(&q, dom_pol, sid, des_access);
1179
1180         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENACCOUNT,
1181                 q, r,
1182                 qbuf, rbuf,
1183                 lsa_io_q_open_account,
1184                 lsa_io_r_open_account,
1185                 NT_STATUS_UNSUCCESSFUL);
1186
1187         /* Return output parameters */
1188
1189         result = r.status;
1190
1191         if (NT_STATUS_IS_OK(result)) {
1192                 *user_pol = r.pol;
1193         }
1194
1195         return result;
1196 }
1197
1198 /** Enumerate user privileges
1199  *
1200  * @param cli Handle on an initialised SMB connection */
1201
1202 NTSTATUS rpccli_lsa_enum_privsaccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1203                              POLICY_HND *pol, uint32 *count, LUID_ATTR **set)
1204 {
1205         prs_struct qbuf, rbuf;
1206         LSA_Q_ENUMPRIVSACCOUNT q;
1207         LSA_R_ENUMPRIVSACCOUNT r;
1208         NTSTATUS result;
1209         int i;
1210
1211         ZERO_STRUCT(q);
1212         ZERO_STRUCT(r);
1213
1214         /* Initialise input parameters */
1215
1216         init_lsa_q_enum_privsaccount(&q, pol);
1217
1218         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMPRIVSACCOUNT,
1219                 q, r,
1220                 qbuf, rbuf,
1221                 lsa_io_q_enum_privsaccount,
1222                 lsa_io_r_enum_privsaccount,
1223                 NT_STATUS_UNSUCCESSFUL);
1224
1225         /* Return output parameters */
1226
1227         result = r.status;
1228
1229         if (!NT_STATUS_IS_OK(result)) {
1230                 goto done;
1231         }
1232
1233         if (r.count == 0)
1234                 goto done;
1235
1236         if (!((*set = TALLOC_ARRAY(mem_ctx, LUID_ATTR, r.count)))) {
1237                 DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n"));
1238                 result = NT_STATUS_UNSUCCESSFUL;
1239                 goto done;
1240         }
1241
1242         for (i=0; i<r.count; i++) {
1243                 (*set)[i].luid.low = r.set.set[i].luid.low;
1244                 (*set)[i].luid.high = r.set.set[i].luid.high;
1245                 (*set)[i].attr = r.set.set[i].attr;
1246         }
1247
1248         *count=r.count;
1249  done:
1250
1251         return result;
1252 }
1253
1254 /** Get a privilege value given its name */
1255
1256 NTSTATUS rpccli_lsa_lookup_priv_value(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1257                                  POLICY_HND *pol, const char *name, LUID *luid)
1258 {
1259         prs_struct qbuf, rbuf;
1260         LSA_Q_LOOKUP_PRIV_VALUE q;
1261         LSA_R_LOOKUP_PRIV_VALUE r;
1262         NTSTATUS result;
1263
1264         ZERO_STRUCT(q);
1265         ZERO_STRUCT(r);
1266
1267         /* Marshall data and send request */
1268
1269         init_lsa_q_lookup_priv_value(&q, pol, name);
1270
1271         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPPRIVVALUE,
1272                 q, r,
1273                 qbuf, rbuf,
1274                 lsa_io_q_lookup_priv_value,
1275                 lsa_io_r_lookup_priv_value,
1276                 NT_STATUS_UNSUCCESSFUL);
1277
1278         result = r.status;
1279
1280         if (!NT_STATUS_IS_OK(result)) {
1281                 goto done;
1282         }
1283
1284         /* Return output parameters */
1285
1286         (*luid).low=r.luid.low;
1287         (*luid).high=r.luid.high;
1288
1289  done:
1290
1291         return result;
1292 }
1293
1294 /** Query LSA security object */
1295
1296 NTSTATUS rpccli_lsa_query_secobj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1297                               POLICY_HND *pol, uint32 sec_info, 
1298                               SEC_DESC_BUF **psdb)
1299 {
1300         prs_struct qbuf, rbuf;
1301         LSA_Q_QUERY_SEC_OBJ q;
1302         LSA_R_QUERY_SEC_OBJ r;
1303         NTSTATUS result;
1304
1305         ZERO_STRUCT(q);
1306         ZERO_STRUCT(r);
1307
1308         /* Marshall data and send request */
1309
1310         init_q_query_sec_obj(&q, pol, sec_info);
1311
1312         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYSECOBJ,
1313                 q, r,
1314                 qbuf, rbuf,
1315                 lsa_io_q_query_sec_obj,
1316                 lsa_io_r_query_sec_obj,
1317                 NT_STATUS_UNSUCCESSFUL);
1318
1319         result = r.status;
1320
1321         if (!NT_STATUS_IS_OK(result)) {
1322                 goto done;
1323         }
1324
1325         /* Return output parameters */
1326
1327         if (psdb)
1328                 *psdb = r.buf;
1329
1330  done:
1331
1332         return result;
1333 }
1334
1335
1336 /* Enumerate account rights This is similar to enum_privileges but
1337    takes a SID directly, avoiding the open_account call.
1338 */
1339
1340 NTSTATUS rpccli_lsa_enum_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1341                                      POLICY_HND *pol, DOM_SID *sid,
1342                                      uint32 *count, char ***priv_names)
1343 {
1344         prs_struct qbuf, rbuf;
1345         LSA_Q_ENUM_ACCT_RIGHTS q;
1346         LSA_R_ENUM_ACCT_RIGHTS r;
1347         NTSTATUS result;
1348         int i;
1349         fstring *privileges;
1350         char **names;
1351
1352         ZERO_STRUCT(q);
1353         ZERO_STRUCT(r);
1354
1355         /* Marshall data and send request */
1356         init_q_enum_acct_rights(&q, pol, 2, sid);
1357
1358         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMACCTRIGHTS,
1359                 q, r,
1360                 qbuf, rbuf,
1361                 lsa_io_q_enum_acct_rights,
1362                 lsa_io_r_enum_acct_rights,
1363                 NT_STATUS_UNSUCCESSFUL);
1364
1365         result = r.status;
1366
1367         if (!NT_STATUS_IS_OK(result)) {
1368                 goto done;
1369         }
1370
1371         *count = r.count;
1372         if (! *count) {
1373                 goto done;
1374         }
1375
1376         
1377         privileges = TALLOC_ARRAY( mem_ctx, fstring, *count );
1378         names      = TALLOC_ARRAY( mem_ctx, char *, *count );
1379
1380         if ((privileges == NULL) || (names == NULL)) {
1381                 TALLOC_FREE(privileges);
1382                 TALLOC_FREE(names);
1383                 return NT_STATUS_NO_MEMORY;
1384         }
1385
1386         for ( i=0; i<*count; i++ ) {
1387                 UNISTR4 *uni_string = &r.rights->strings[i];
1388
1389                 if ( !uni_string->string )
1390                         continue;
1391
1392                 rpcstr_pull( privileges[i], uni_string->string->buffer, sizeof(privileges[i]), -1, STR_TERMINATE );
1393                         
1394                 /* now copy to the return array */
1395                 names[i] = talloc_strdup( mem_ctx, privileges[i] );
1396         }
1397         
1398         *priv_names = names;
1399
1400 done:
1401
1402         return result;
1403 }
1404
1405
1406
1407 /* add account rights to an account. */
1408
1409 NTSTATUS rpccli_lsa_add_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1410                                     POLICY_HND *pol, DOM_SID sid,
1411                                         uint32 count, const char **privs_name)
1412 {
1413         prs_struct qbuf, rbuf;
1414         LSA_Q_ADD_ACCT_RIGHTS q;
1415         LSA_R_ADD_ACCT_RIGHTS r;
1416         NTSTATUS result;
1417
1418         ZERO_STRUCT(q);
1419         ZERO_STRUCT(r);
1420
1421         /* Marshall data and send request */
1422         init_q_add_acct_rights(&q, pol, &sid, count, privs_name);
1423
1424         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ADDACCTRIGHTS,
1425                 q, r,
1426                 qbuf, rbuf,
1427                 lsa_io_q_add_acct_rights,
1428                 lsa_io_r_add_acct_rights,
1429                 NT_STATUS_UNSUCCESSFUL);
1430
1431         result = r.status;
1432
1433         if (!NT_STATUS_IS_OK(result)) {
1434                 goto done;
1435         }
1436 done:
1437
1438         return result;
1439 }
1440
1441
1442 /* remove account rights for an account. */
1443
1444 NTSTATUS rpccli_lsa_remove_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1445                                        POLICY_HND *pol, DOM_SID sid, BOOL removeall,
1446                                        uint32 count, const char **privs_name)
1447 {
1448         prs_struct qbuf, rbuf;
1449         LSA_Q_REMOVE_ACCT_RIGHTS q;
1450         LSA_R_REMOVE_ACCT_RIGHTS r;
1451         NTSTATUS result;
1452
1453         ZERO_STRUCT(q);
1454         ZERO_STRUCT(r);
1455
1456         /* Marshall data and send request */
1457         init_q_remove_acct_rights(&q, pol, &sid, removeall?1:0, count, privs_name);
1458
1459         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_REMOVEACCTRIGHTS,
1460                 q, r,
1461                 qbuf, rbuf,
1462                 lsa_io_q_remove_acct_rights,
1463                 lsa_io_r_remove_acct_rights,
1464                 NT_STATUS_UNSUCCESSFUL);
1465
1466         result = r.status;
1467
1468         if (!NT_STATUS_IS_OK(result)) {
1469                 goto done;
1470         }
1471 done:
1472
1473         return result;
1474 }
1475
1476
1477 #if 0
1478
1479 /** An example of how to use the routines in this file.  Fetch a DOMAIN
1480     sid. Does complete cli setup / teardown anonymously. */
1481
1482 BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid)
1483 {
1484         extern pstring global_myname;
1485         struct cli_state *cli;
1486         NTSTATUS result;
1487         POLICY_HND lsa_pol;
1488         BOOL ret = False;
1489  
1490         ZERO_STRUCT(cli);
1491         if((cli = cli_initialise()) == NULL) {
1492                 DEBUG(0,("fetch_domain_sid: unable to initialize client connection.\n"));
1493                 return False;
1494         }
1495  
1496         if(!resolve_name( remote_machine, &cli->dest_ip, 0x20)) {
1497                 DEBUG(0,("fetch_domain_sid: Can't resolve address for %s\n", remote_machine));
1498                 goto done;
1499         }
1500  
1501         if (!cli_connect(cli, remote_machine, &cli->dest_ip)) {
1502                 DEBUG(0,("fetch_domain_sid: unable to connect to SMB server on \
1503 machine %s. Error was : %s.\n", remote_machine, cli_errstr(cli) ));
1504                 goto done;
1505         }
1506
1507         if (!attempt_netbios_session_request(cli, global_myname, remote_machine, &cli->dest_ip)) {
1508                 DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS session request.\n", 
1509                         remote_machine));
1510                 goto done;
1511         }
1512  
1513         cli->protocol = PROTOCOL_NT1;
1514  
1515         if (!cli_negprot(cli)) {
1516                 DEBUG(0,("fetch_domain_sid: machine %s rejected the negotiate protocol. \
1517 Error was : %s.\n", remote_machine, cli_errstr(cli) ));
1518                 goto done;
1519         }
1520  
1521         if (cli->protocol != PROTOCOL_NT1) {
1522                 DEBUG(0,("fetch_domain_sid: machine %s didn't negotiate NT protocol.\n",
1523                         remote_machine));
1524                 goto done;
1525         }
1526  
1527         /*
1528          * Do an anonymous session setup.
1529          */
1530  
1531         if (!cli_session_setup(cli, "", "", 0, "", 0, "")) {
1532                 DEBUG(0,("fetch_domain_sid: machine %s rejected the session setup. \
1533 Error was : %s.\n", remote_machine, cli_errstr(cli) ));
1534                 goto done;
1535         }
1536  
1537         if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
1538                 DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n",
1539                         remote_machine));
1540                 goto done;
1541         }
1542
1543         if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
1544                 DEBUG(0,("fetch_domain_sid: machine %s rejected the tconX on the IPC$ share. \
1545 Error was : %s.\n", remote_machine, cli_errstr(cli) ));
1546                 goto done;
1547         }
1548
1549         /* Fetch domain sid */
1550  
1551         if (!cli_nt_session_open(cli, PI_LSARPC)) {
1552                 DEBUG(0, ("fetch_domain_sid: Error connecting to SAM pipe\n"));
1553                 goto done;
1554         }
1555  
1556         result = cli_lsa_open_policy(cli, cli->mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, &lsa_pol);
1557         if (!NT_STATUS_IS_OK(result)) {
1558                 DEBUG(0, ("fetch_domain_sid: Error opening lsa policy handle. %s\n",
1559                         nt_errstr(result) ));
1560                 goto done;
1561         }
1562  
1563         result = cli_lsa_query_info_policy(cli, cli->mem_ctx, &lsa_pol, 5, domain, psid);
1564         if (!NT_STATUS_IS_OK(result)) {
1565                 DEBUG(0, ("fetch_domain_sid: Error querying lsa policy handle. %s\n",
1566                         nt_errstr(result) ));
1567                 goto done;
1568         }
1569  
1570         ret = True;
1571
1572   done:
1573
1574         cli_shutdown(cli);
1575         return ret;
1576 }
1577
1578 #endif
1579
1580 NTSTATUS rpccli_lsa_open_trusted_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1581                                      POLICY_HND *pol, DOM_SID *dom_sid, uint32 access_mask,
1582                                      POLICY_HND *trustdom_pol)
1583 {
1584         prs_struct qbuf, rbuf;
1585         LSA_Q_OPEN_TRUSTED_DOMAIN q;
1586         LSA_R_OPEN_TRUSTED_DOMAIN r;
1587         NTSTATUS result;
1588
1589         ZERO_STRUCT(q);
1590         ZERO_STRUCT(r);
1591
1592         /* Initialise input parameters */
1593
1594         init_lsa_q_open_trusted_domain(&q, pol, dom_sid, access_mask);
1595
1596         /* Marshall data and send request */
1597
1598         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENTRUSTDOM,
1599                 q, r,
1600                 qbuf, rbuf,
1601                 lsa_io_q_open_trusted_domain,
1602                 lsa_io_r_open_trusted_domain,
1603                 NT_STATUS_UNSUCCESSFUL);
1604
1605         /* Return output parameters */
1606         
1607         result = r.status;
1608
1609         if (NT_STATUS_IS_OK(result)) {
1610                 *trustdom_pol = r.handle;
1611         }
1612
1613         return result;
1614 }
1615
1616 NTSTATUS rpccli_lsa_query_trusted_domain_info(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1617                                            POLICY_HND *pol, 
1618                                            uint16 info_class,  
1619                                            LSA_TRUSTED_DOMAIN_INFO **info)
1620 {
1621         prs_struct qbuf, rbuf;
1622         LSA_Q_QUERY_TRUSTED_DOMAIN_INFO q;
1623         LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
1624         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1625
1626         ZERO_STRUCT(q);
1627         ZERO_STRUCT(r);
1628
1629         /* Marshall data and send request */
1630
1631         init_q_query_trusted_domain_info(&q, pol, info_class); 
1632
1633         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFO,
1634                 q, r,
1635                 qbuf, rbuf,
1636                 lsa_io_q_query_trusted_domain_info,
1637                 lsa_io_r_query_trusted_domain_info,
1638                 NT_STATUS_UNSUCCESSFUL);
1639
1640         result = r.status;
1641
1642         if (!NT_STATUS_IS_OK(result)) {
1643                 goto done;
1644         }
1645
1646         *info = r.info;
1647                 
1648 done:
1649         return result;
1650 }
1651
1652 NTSTATUS rpccli_lsa_open_trusted_domain_by_name(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1653                                                 POLICY_HND *pol, const char *name, uint32 access_mask,
1654                                                 POLICY_HND *trustdom_pol)
1655 {
1656         prs_struct qbuf, rbuf;
1657         LSA_Q_OPEN_TRUSTED_DOMAIN_BY_NAME q;
1658         LSA_R_OPEN_TRUSTED_DOMAIN_BY_NAME r;
1659         NTSTATUS result;
1660
1661         ZERO_STRUCT(q);
1662         ZERO_STRUCT(r);
1663
1664         /* Initialise input parameters */
1665
1666         init_lsa_q_open_trusted_domain_by_name(&q, pol, name, access_mask);
1667
1668         /* Marshall data and send request */
1669
1670         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENTRUSTDOMBYNAME,
1671                 q, r,
1672                 qbuf, rbuf,
1673                 lsa_io_q_open_trusted_domain_by_name,
1674                 lsa_io_r_open_trusted_domain_by_name,
1675                 NT_STATUS_UNSUCCESSFUL);
1676
1677         /* Return output parameters */
1678         
1679         result = r.status;
1680
1681         if (NT_STATUS_IS_OK(result)) {
1682                 *trustdom_pol = r.handle;
1683         }
1684
1685         return result;
1686 }
1687
1688
1689 NTSTATUS rpccli_lsa_query_trusted_domain_info_by_sid(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1690                                                   POLICY_HND *pol, 
1691                                                   uint16 info_class, DOM_SID *dom_sid, 
1692                                                   LSA_TRUSTED_DOMAIN_INFO **info)
1693 {
1694         prs_struct qbuf, rbuf;
1695         LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID q;
1696         LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
1697         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1698
1699         ZERO_STRUCT(q);
1700         ZERO_STRUCT(r);
1701
1702         /* Marshall data and send request */
1703
1704         init_q_query_trusted_domain_info_by_sid(&q, pol, info_class, dom_sid); 
1705
1706         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYSID,
1707                 q, r,
1708                 qbuf, rbuf,
1709                 lsa_io_q_query_trusted_domain_info_by_sid,
1710                 lsa_io_r_query_trusted_domain_info,
1711                 NT_STATUS_UNSUCCESSFUL);
1712
1713         result = r.status;
1714
1715         if (!NT_STATUS_IS_OK(result)) {
1716                 goto done;
1717         }
1718
1719         *info = r.info;
1720
1721 done:
1722
1723         return result;
1724 }
1725
1726 NTSTATUS rpccli_lsa_query_trusted_domain_info_by_name(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1727                                                    POLICY_HND *pol, 
1728                                                    uint16 info_class, const char *domain_name, 
1729                                                    LSA_TRUSTED_DOMAIN_INFO **info)
1730 {
1731         prs_struct qbuf, rbuf;
1732         LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME q;
1733         LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
1734         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1735
1736         ZERO_STRUCT(q);
1737         ZERO_STRUCT(r);
1738
1739         /* Marshall data and send request */
1740
1741         init_q_query_trusted_domain_info_by_name(&q, pol, info_class, domain_name); 
1742
1743         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYNAME,
1744                 q, r,
1745                 qbuf, rbuf,
1746                 lsa_io_q_query_trusted_domain_info_by_name,
1747                 lsa_io_r_query_trusted_domain_info,
1748                 NT_STATUS_UNSUCCESSFUL);
1749
1750         result = r.status;
1751
1752         if (!NT_STATUS_IS_OK(result)) {
1753                 goto done;
1754         }
1755
1756         *info = r.info;
1757
1758 done:
1759         
1760         return result;
1761 }
1762
1763 NTSTATUS cli_lsa_query_domain_info_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1764                                           POLICY_HND *pol, 
1765                                           uint16 info_class, LSA_DOM_INFO_UNION **info)
1766 {
1767         prs_struct qbuf, rbuf;
1768         LSA_Q_QUERY_DOM_INFO_POLICY q;
1769         LSA_R_QUERY_DOM_INFO_POLICY r;
1770         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1771
1772         ZERO_STRUCT(q);
1773         ZERO_STRUCT(r);
1774
1775         /* Marshall data and send request */
1776
1777         init_q_query_dom_info(&q, pol, info_class); 
1778
1779         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYDOMINFOPOL, 
1780                 q, r,
1781                 qbuf, rbuf,
1782                 lsa_io_q_query_dom_info,
1783                 lsa_io_r_query_dom_info,
1784                 NT_STATUS_UNSUCCESSFUL);
1785
1786         result = r.status;
1787
1788         if (!NT_STATUS_IS_OK(result)) {
1789                 goto done;
1790         }
1791
1792         *info = r.info;
1793
1794 done:
1795         return result;
1796 }
1797