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