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