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