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