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