Apply const to rpccli_lsa_query_info_policy() and rpccli_lsa_query_info_policy2().
[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                                       const char **domain_name,
546                                       DOM_SID **domain_sid)
547 {
548         prs_struct qbuf, rbuf;
549         LSA_Q_QUERY_INFO q;
550         LSA_R_QUERY_INFO r;
551         NTSTATUS result;
552
553         ZERO_STRUCT(q);
554         ZERO_STRUCT(r);
555
556         init_q_query(&q, pol, info_class);
557
558         CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFOPOLICY,
559                 q, r,
560                 qbuf, rbuf,
561                 lsa_io_q_query,
562                 lsa_io_r_query,
563                 NT_STATUS_UNSUCCESSFUL);
564
565         result = r.status;
566
567         if (!NT_STATUS_IS_OK(result)) {
568                 goto done;
569         }
570
571         /* Return output parameters */
572
573         switch (info_class) {
574
575         case 3:
576                 if (domain_name && (r.ctr.info.id3.buffer_dom_name != 0)) {
577                         *domain_name = unistr2_to_ascii_talloc(mem_ctx,
578                                                    &r.ctr.info.id3.
579                                                    uni_domain_name);
580                         if (!*domain_name) {
581                                 return NT_STATUS_NO_MEMORY;
582                         }
583                 }
584
585                 if (domain_sid && (r.ctr.info.id3.buffer_dom_sid != 0)) {
586                         *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
587                         if (!*domain_sid) {
588                                 return NT_STATUS_NO_MEMORY;
589                         }
590                         sid_copy(*domain_sid, &r.ctr.info.id3.dom_sid.sid);
591                 }
592
593                 break;
594
595         case 5:
596
597                 if (domain_name && (r.ctr.info.id5.buffer_dom_name != 0)) {
598                         *domain_name = unistr2_to_ascii_talloc(mem_ctx,
599                                                    &r.ctr.info.id5.
600                                                    uni_domain_name);
601                         if (!*domain_name) {
602                                 return NT_STATUS_NO_MEMORY;
603                         }
604                 }
605
606                 if (domain_sid && (r.ctr.info.id5.buffer_dom_sid != 0)) {
607                         *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
608                         if (!*domain_sid) {
609                                 return NT_STATUS_NO_MEMORY;
610                         }
611                         sid_copy(*domain_sid, &r.ctr.info.id5.dom_sid.sid);
612                 }
613                 break;
614
615         default:
616                 DEBUG(3, ("unknown info class %d\n", info_class));
617                 break;
618         }
619
620  done:
621
622         return result;
623 }
624
625 /** Query info policy2
626  *
627  *  @param domain_name - returned remote server's domain name
628  *  @param dns_name - returned remote server's dns domain name
629  *  @param forest_name - returned remote server's forest name
630  *  @param domain_guid - returned remote server's domain guid
631  *  @param domain_sid - returned remote server's domain sid */
632
633 NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli,
634                                        TALLOC_CTX *mem_ctx,
635                                        POLICY_HND *pol, uint16 info_class,
636                                        const char **domain_name,
637                                        const char **dns_name,
638                                        const char **forest_name,
639                                        struct GUID **domain_guid,
640                                        DOM_SID **domain_sid)
641 {
642         prs_struct qbuf, rbuf;
643         LSA_Q_QUERY_INFO2 q;
644         LSA_R_QUERY_INFO2 r;
645         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
646
647         if (info_class != 12)
648                 goto done;
649
650         ZERO_STRUCT(q);
651         ZERO_STRUCT(r);
652
653         init_q_query2(&q, pol, info_class);
654
655         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYINFO2,
656                 q, r,
657                 qbuf, rbuf,
658                 lsa_io_q_query_info2,
659                 lsa_io_r_query_info2,
660                 NT_STATUS_UNSUCCESSFUL);
661
662         result = r.status;
663
664         if (!NT_STATUS_IS_OK(result)) {
665                 goto done;
666         }
667
668         /* Return output parameters */
669
670         ZERO_STRUCTP(domain_guid);
671
672         if (domain_name && r.ctr.info.id12.hdr_nb_dom_name.buffer) {
673                 *domain_name = unistr2_to_ascii_talloc(mem_ctx,
674                                             &r.ctr.info.id12
675                                             .uni_nb_dom_name);
676                 if (!*domain_name) {
677                         return NT_STATUS_NO_MEMORY;
678                 }
679         }
680         if (dns_name && r.ctr.info.id12.hdr_dns_dom_name.buffer) {
681                 *dns_name = unistr2_to_ascii_talloc(mem_ctx,
682                                          &r.ctr.info.id12
683                                          .uni_dns_dom_name);
684                 if (!*dns_name) {
685                         return NT_STATUS_NO_MEMORY;
686                 }
687         }
688         if (forest_name && r.ctr.info.id12.hdr_forest_name.buffer) {
689                 *forest_name = unistr2_to_ascii_talloc(mem_ctx,
690                                             &r.ctr.info.id12
691                                             .uni_forest_name);
692                 if (!*forest_name) {
693                         return NT_STATUS_NO_MEMORY;
694                 }
695         }
696
697         if (domain_guid) {
698                 *domain_guid = TALLOC_P(mem_ctx, struct GUID);
699                 if (!*domain_guid) {
700                         return NT_STATUS_NO_MEMORY;
701                 }
702                 memcpy(*domain_guid,
703                        &r.ctr.info.id12.dom_guid,
704                        sizeof(struct GUID));
705         }
706
707         if (domain_sid && r.ctr.info.id12.ptr_dom_sid != 0) {
708                 *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
709                 if (!*domain_sid) {
710                         return NT_STATUS_NO_MEMORY;
711                 }
712                 sid_copy(*domain_sid,
713                          &r.ctr.info.id12.dom_sid.sid);
714         }
715
716  done:
717
718         return result;
719 }
720
721 /**
722  * Enumerate list of trusted domains
723  *
724  * @param cli client state (cli_state) structure of the connection
725  * @param mem_ctx memory context
726  * @param pol opened lsa policy handle
727  * @param enum_ctx enumeration context ie. index of first returned domain entry
728  * @param pref_num_domains preferred max number of entries returned in one response
729  * @param num_domains total number of trusted domains returned by response
730  * @param domain_names returned trusted domain names
731  * @param domain_sids returned trusted domain sids
732  *
733  * @return nt status code of response
734  **/
735
736 NTSTATUS rpccli_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
737                                    TALLOC_CTX *mem_ctx,
738                                    POLICY_HND *pol, uint32 *enum_ctx,
739                                    uint32 *num_domains,
740                                    char ***domain_names, DOM_SID **domain_sids)
741 {
742         prs_struct qbuf, rbuf;
743         LSA_Q_ENUM_TRUST_DOM in;
744         LSA_R_ENUM_TRUST_DOM out;
745         int i;
746         fstring tmp;
747
748         ZERO_STRUCT(in);
749         ZERO_STRUCT(out);
750
751         /* 64k is enough for about 2000 trusted domains */
752
753         init_q_enum_trust_dom(&in, pol, *enum_ctx, 0x10000);
754
755         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMTRUSTDOM,
756                     in, out,
757                     qbuf, rbuf,
758                     lsa_io_q_enum_trust_dom,
759                     lsa_io_r_enum_trust_dom,
760                     NT_STATUS_UNSUCCESSFUL );
761
762
763         /* check for an actual error */
764
765         if ( !NT_STATUS_IS_OK(out.status)
766                 && !NT_STATUS_EQUAL(out.status, NT_STATUS_NO_MORE_ENTRIES)
767                 && !NT_STATUS_EQUAL(out.status, STATUS_MORE_ENTRIES) )
768         {
769                 return out.status;
770         }
771
772         /* Return output parameters */
773
774         *num_domains  = out.count;
775         *enum_ctx     = out.enum_context;
776
777         if ( out.count ) {
778
779                 /* Allocate memory for trusted domain names and sids */
780
781                 if ( !(*domain_names = TALLOC_ARRAY(mem_ctx, char *, out.count)) ) {
782                         DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
783                         return NT_STATUS_NO_MEMORY;
784                 }
785
786                 if ( !(*domain_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, out.count)) ) {
787                         DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
788                         return NT_STATUS_NO_MEMORY;
789                 }
790
791                 /* Copy across names and sids */
792
793                 for (i = 0; i < out.count; i++) {
794
795                         rpcstr_pull( tmp, out.domlist->domains[i].name.string->buffer,
796                                 sizeof(tmp), out.domlist->domains[i].name.length, 0);
797                         (*domain_names)[i] = talloc_strdup(mem_ctx, tmp);
798
799                         sid_copy(&(*domain_sids)[i], &out.domlist->domains[i].sid->sid );
800                 }
801         }
802
803         return out.status;
804 }
805
806 /** Enumerate privileges*/
807
808 NTSTATUS rpccli_lsa_enum_privilege(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
809                                 POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length,
810                                 uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low)
811 {
812         prs_struct qbuf, rbuf;
813         LSA_Q_ENUM_PRIVS q;
814         LSA_R_ENUM_PRIVS r;
815         NTSTATUS result;
816         int i;
817
818         ZERO_STRUCT(q);
819         ZERO_STRUCT(r);
820
821         init_q_enum_privs(&q, pol, *enum_context, pref_max_length);
822
823         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_PRIVS,
824                 q, r,
825                 qbuf, rbuf,
826                 lsa_io_q_enum_privs,
827                 lsa_io_r_enum_privs,
828                 NT_STATUS_UNSUCCESSFUL);
829
830         result = r.status;
831
832         if (!NT_STATUS_IS_OK(result)) {
833                 goto done;
834         }
835
836         /* Return output parameters */
837
838         *enum_context = r.enum_context;
839         *count = r.count;
840
841         if (r.count) {
842                 if (!((*privs_name = TALLOC_ARRAY(mem_ctx, char *, r.count)))) {
843                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
844                         result = NT_STATUS_UNSUCCESSFUL;
845                         goto done;
846                 }
847
848                 if (!((*privs_high = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {
849                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
850                         result = NT_STATUS_UNSUCCESSFUL;
851                         goto done;
852                 }
853
854                 if (!((*privs_low = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {
855                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
856                         result = NT_STATUS_UNSUCCESSFUL;
857                         goto done;
858                 }
859         } else {
860                 *privs_name = NULL;
861                 *privs_high = NULL;
862                 *privs_low = NULL;
863         }
864
865         for (i = 0; i < r.count; i++) {
866                 fstring name;
867
868                 rpcstr_pull_unistr2_fstring( name, &r.privs[i].name);
869
870                 (*privs_name)[i] = talloc_strdup(mem_ctx, name);
871
872                 (*privs_high)[i] = r.privs[i].luid_high;
873                 (*privs_low)[i] = r.privs[i].luid_low;
874         }
875
876  done:
877
878         return result;
879 }
880
881 /** Get privilege name */
882
883 NTSTATUS rpccli_lsa_get_dispname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
884                               POLICY_HND *pol, const char *name,
885                               uint16 lang_id, uint16 lang_id_sys,
886                               fstring description, uint16 *lang_id_desc)
887 {
888         prs_struct qbuf, rbuf;
889         LSA_Q_PRIV_GET_DISPNAME q;
890         LSA_R_PRIV_GET_DISPNAME r;
891         NTSTATUS result;
892
893         ZERO_STRUCT(q);
894         ZERO_STRUCT(r);
895
896         init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys);
897
898         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_PRIV_GET_DISPNAME,
899                 q, r,
900                 qbuf, rbuf,
901                 lsa_io_q_priv_get_dispname,
902                 lsa_io_r_priv_get_dispname,
903                 NT_STATUS_UNSUCCESSFUL);
904
905         result = r.status;
906
907         if (!NT_STATUS_IS_OK(result)) {
908                 goto done;
909         }
910
911         /* Return output parameters */
912
913         rpcstr_pull_unistr2_fstring(description , &r.desc);
914         *lang_id_desc = r.lang_id;
915
916  done:
917
918         return result;
919 }
920
921 /** Enumerate list of SIDs  */
922
923 NTSTATUS rpccli_lsa_enum_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
924                                 POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length,
925                                 uint32 *num_sids, DOM_SID **sids)
926 {
927         prs_struct qbuf, rbuf;
928         LSA_Q_ENUM_ACCOUNTS q;
929         LSA_R_ENUM_ACCOUNTS r;
930         NTSTATUS result;
931         int i;
932
933         ZERO_STRUCT(q);
934         ZERO_STRUCT(r);
935
936         init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length);
937
938         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_ACCOUNTS,
939                 q, r,
940                 qbuf, rbuf,
941                 lsa_io_q_enum_accounts,
942                 lsa_io_r_enum_accounts,
943                 NT_STATUS_UNSUCCESSFUL);
944
945         result = r.status;
946
947         if (!NT_STATUS_IS_OK(result)) {
948                 goto done;
949         }
950
951         if (r.sids.num_entries==0)
952                 goto done;
953
954         /* Return output parameters */
955
956         *sids = TALLOC_ARRAY(mem_ctx, DOM_SID, r.sids.num_entries);
957         if (!*sids) {
958                 DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n"));
959                 result = NT_STATUS_UNSUCCESSFUL;
960                 goto done;
961         }
962
963         /* Copy across names and sids */
964
965         for (i = 0; i < r.sids.num_entries; i++) {
966                 sid_copy(&(*sids)[i], &r.sids.sid[i].sid);
967         }
968
969         *num_sids= r.sids.num_entries;
970         *enum_ctx = r.enum_context;
971
972  done:
973
974         return result;
975 }
976
977 /** Create a LSA user handle
978  *
979  * @param cli Handle on an initialised SMB connection
980  *
981  * FIXME: The code is actually identical to open account
982  * TODO: Check and code what the function should exactly do
983  *
984  * */
985
986 NTSTATUS rpccli_lsa_create_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
987                              POLICY_HND *dom_pol, DOM_SID *sid, uint32 desired_access,
988                              POLICY_HND *user_pol)
989 {
990         prs_struct qbuf, rbuf;
991         LSA_Q_CREATEACCOUNT q;
992         LSA_R_CREATEACCOUNT r;
993         NTSTATUS result;
994
995         ZERO_STRUCT(q);
996         ZERO_STRUCT(r);
997
998         /* Initialise input parameters */
999
1000         init_lsa_q_create_account(&q, dom_pol, sid, desired_access);
1001
1002         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_CREATEACCOUNT,
1003                 q, r,
1004                 qbuf, rbuf,
1005                 lsa_io_q_create_account,
1006                 lsa_io_r_create_account,
1007                 NT_STATUS_UNSUCCESSFUL);
1008
1009         /* Return output parameters */
1010
1011         result = r.status;
1012
1013         if (NT_STATUS_IS_OK(result)) {
1014                 *user_pol = r.pol;
1015         }
1016
1017         return result;
1018 }
1019
1020 /** Open a LSA user handle
1021  *
1022  * @param cli Handle on an initialised SMB connection */
1023
1024 NTSTATUS rpccli_lsa_open_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1025                              POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access,
1026                              POLICY_HND *user_pol)
1027 {
1028         prs_struct qbuf, rbuf;
1029         LSA_Q_OPENACCOUNT q;
1030         LSA_R_OPENACCOUNT r;
1031         NTSTATUS result;
1032
1033         ZERO_STRUCT(q);
1034         ZERO_STRUCT(r);
1035
1036         /* Initialise input parameters */
1037
1038         init_lsa_q_open_account(&q, dom_pol, sid, des_access);
1039
1040         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENACCOUNT,
1041                 q, r,
1042                 qbuf, rbuf,
1043                 lsa_io_q_open_account,
1044                 lsa_io_r_open_account,
1045                 NT_STATUS_UNSUCCESSFUL);
1046
1047         /* Return output parameters */
1048
1049         result = r.status;
1050
1051         if (NT_STATUS_IS_OK(result)) {
1052                 *user_pol = r.pol;
1053         }
1054
1055         return result;
1056 }
1057
1058 /** Enumerate user privileges
1059  *
1060  * @param cli Handle on an initialised SMB connection */
1061
1062 NTSTATUS rpccli_lsa_enum_privsaccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1063                              POLICY_HND *pol, uint32 *count, LUID_ATTR **set)
1064 {
1065         prs_struct qbuf, rbuf;
1066         LSA_Q_ENUMPRIVSACCOUNT q;
1067         LSA_R_ENUMPRIVSACCOUNT r;
1068         NTSTATUS result;
1069         int i;
1070
1071         ZERO_STRUCT(q);
1072         ZERO_STRUCT(r);
1073
1074         /* Initialise input parameters */
1075
1076         init_lsa_q_enum_privsaccount(&q, pol);
1077
1078         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMPRIVSACCOUNT,
1079                 q, r,
1080                 qbuf, rbuf,
1081                 lsa_io_q_enum_privsaccount,
1082                 lsa_io_r_enum_privsaccount,
1083                 NT_STATUS_UNSUCCESSFUL);
1084
1085         /* Return output parameters */
1086
1087         result = r.status;
1088
1089         if (!NT_STATUS_IS_OK(result)) {
1090                 goto done;
1091         }
1092
1093         if (r.count == 0)
1094                 goto done;
1095
1096         if (!((*set = TALLOC_ARRAY(mem_ctx, LUID_ATTR, r.count)))) {
1097                 DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n"));
1098                 result = NT_STATUS_UNSUCCESSFUL;
1099                 goto done;
1100         }
1101
1102         for (i=0; i<r.count; i++) {
1103                 (*set)[i].luid.low = r.set.set[i].luid.low;
1104                 (*set)[i].luid.high = r.set.set[i].luid.high;
1105                 (*set)[i].attr = r.set.set[i].attr;
1106         }
1107
1108         *count=r.count;
1109  done:
1110
1111         return result;
1112 }
1113
1114 /** Get a privilege value given its name */
1115
1116 NTSTATUS rpccli_lsa_lookup_priv_value(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1117                                  POLICY_HND *pol, const char *name, LUID *luid)
1118 {
1119         prs_struct qbuf, rbuf;
1120         LSA_Q_LOOKUP_PRIV_VALUE q;
1121         LSA_R_LOOKUP_PRIV_VALUE r;
1122         NTSTATUS result;
1123
1124         ZERO_STRUCT(q);
1125         ZERO_STRUCT(r);
1126
1127         /* Marshall data and send request */
1128
1129         init_lsa_q_lookup_priv_value(&q, pol, name);
1130
1131         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPPRIVVALUE,
1132                 q, r,
1133                 qbuf, rbuf,
1134                 lsa_io_q_lookup_priv_value,
1135                 lsa_io_r_lookup_priv_value,
1136                 NT_STATUS_UNSUCCESSFUL);
1137
1138         result = r.status;
1139
1140         if (!NT_STATUS_IS_OK(result)) {
1141                 goto done;
1142         }
1143
1144         /* Return output parameters */
1145
1146         (*luid).low=r.luid.low;
1147         (*luid).high=r.luid.high;
1148
1149  done:
1150
1151         return result;
1152 }
1153
1154 /** Query LSA security object */
1155
1156 NTSTATUS rpccli_lsa_query_secobj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1157                               POLICY_HND *pol, uint32 sec_info,
1158                               SEC_DESC_BUF **psdb)
1159 {
1160         prs_struct qbuf, rbuf;
1161         LSA_Q_QUERY_SEC_OBJ q;
1162         LSA_R_QUERY_SEC_OBJ r;
1163         NTSTATUS result;
1164
1165         ZERO_STRUCT(q);
1166         ZERO_STRUCT(r);
1167
1168         /* Marshall data and send request */
1169
1170         init_q_query_sec_obj(&q, pol, sec_info);
1171
1172         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYSECOBJ,
1173                 q, r,
1174                 qbuf, rbuf,
1175                 lsa_io_q_query_sec_obj,
1176                 lsa_io_r_query_sec_obj,
1177                 NT_STATUS_UNSUCCESSFUL);
1178
1179         result = r.status;
1180
1181         if (!NT_STATUS_IS_OK(result)) {
1182                 goto done;
1183         }
1184
1185         /* Return output parameters */
1186
1187         if (psdb)
1188                 *psdb = r.buf;
1189
1190  done:
1191
1192         return result;
1193 }
1194
1195
1196 /* Enumerate account rights This is similar to enum_privileges but
1197    takes a SID directly, avoiding the open_account call.
1198 */
1199
1200 NTSTATUS rpccli_lsa_enum_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1201                                      POLICY_HND *pol, DOM_SID *sid,
1202                                      uint32 *count, char ***priv_names)
1203 {
1204         prs_struct qbuf, rbuf;
1205         LSA_Q_ENUM_ACCT_RIGHTS q;
1206         LSA_R_ENUM_ACCT_RIGHTS r;
1207         NTSTATUS result;
1208         int i;
1209         fstring *privileges;
1210         char **names;
1211
1212         ZERO_STRUCT(q);
1213         ZERO_STRUCT(r);
1214
1215         /* Marshall data and send request */
1216         init_q_enum_acct_rights(&q, pol, 2, sid);
1217
1218         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMACCTRIGHTS,
1219                 q, r,
1220                 qbuf, rbuf,
1221                 lsa_io_q_enum_acct_rights,
1222                 lsa_io_r_enum_acct_rights,
1223                 NT_STATUS_UNSUCCESSFUL);
1224
1225         result = r.status;
1226
1227         if (!NT_STATUS_IS_OK(result)) {
1228                 goto done;
1229         }
1230
1231         *count = r.count;
1232         if (! *count) {
1233                 goto done;
1234         }
1235
1236
1237         privileges = TALLOC_ARRAY( mem_ctx, fstring, *count );
1238         names      = TALLOC_ARRAY( mem_ctx, char *, *count );
1239
1240         if ((privileges == NULL) || (names == NULL)) {
1241                 TALLOC_FREE(privileges);
1242                 TALLOC_FREE(names);
1243                 return NT_STATUS_NO_MEMORY;
1244         }
1245
1246         for ( i=0; i<*count; i++ ) {
1247                 UNISTR4 *uni_string = &r.rights->strings[i];
1248
1249                 if ( !uni_string->string )
1250                         continue;
1251
1252                 rpcstr_pull( privileges[i], uni_string->string->buffer, sizeof(privileges[i]), -1, STR_TERMINATE );
1253
1254                 /* now copy to the return array */
1255                 names[i] = talloc_strdup( mem_ctx, privileges[i] );
1256         }
1257
1258         *priv_names = names;
1259
1260 done:
1261
1262         return result;
1263 }
1264
1265
1266
1267 /* add account rights to an account. */
1268
1269 NTSTATUS rpccli_lsa_add_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1270                                     POLICY_HND *pol, DOM_SID sid,
1271                                         uint32 count, const char **privs_name)
1272 {
1273         prs_struct qbuf, rbuf;
1274         LSA_Q_ADD_ACCT_RIGHTS q;
1275         LSA_R_ADD_ACCT_RIGHTS r;
1276         NTSTATUS result;
1277
1278         ZERO_STRUCT(q);
1279         ZERO_STRUCT(r);
1280
1281         /* Marshall data and send request */
1282         init_q_add_acct_rights(&q, pol, &sid, count, privs_name);
1283
1284         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ADDACCTRIGHTS,
1285                 q, r,
1286                 qbuf, rbuf,
1287                 lsa_io_q_add_acct_rights,
1288                 lsa_io_r_add_acct_rights,
1289                 NT_STATUS_UNSUCCESSFUL);
1290
1291         result = r.status;
1292
1293         if (!NT_STATUS_IS_OK(result)) {
1294                 goto done;
1295         }
1296 done:
1297
1298         return result;
1299 }
1300
1301
1302 /* remove account rights for an account. */
1303
1304 NTSTATUS rpccli_lsa_remove_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1305                                        POLICY_HND *pol, DOM_SID sid, bool removeall,
1306                                        uint32 count, const char **privs_name)
1307 {
1308         prs_struct qbuf, rbuf;
1309         LSA_Q_REMOVE_ACCT_RIGHTS q;
1310         LSA_R_REMOVE_ACCT_RIGHTS r;
1311         NTSTATUS result;
1312
1313         ZERO_STRUCT(q);
1314         ZERO_STRUCT(r);
1315
1316         /* Marshall data and send request */
1317         init_q_remove_acct_rights(&q, pol, &sid, removeall?1:0, count, privs_name);
1318
1319         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_REMOVEACCTRIGHTS,
1320                 q, r,
1321                 qbuf, rbuf,
1322                 lsa_io_q_remove_acct_rights,
1323                 lsa_io_r_remove_acct_rights,
1324                 NT_STATUS_UNSUCCESSFUL);
1325
1326         result = r.status;
1327
1328         if (!NT_STATUS_IS_OK(result)) {
1329                 goto done;
1330         }
1331 done:
1332
1333         return result;
1334 }
1335
1336
1337 #if 0
1338
1339 /** An example of how to use the routines in this file.  Fetch a DOMAIN
1340     sid. Does complete cli setup / teardown anonymously. */
1341
1342 bool fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid)
1343 {
1344         struct cli_state cli;
1345         NTSTATUS result;
1346         POLICY_HND lsa_pol;
1347         bool ret = False;
1348
1349         ZERO_STRUCT(cli);
1350         if(cli_initialise(&cli) == False) {
1351                 DEBUG(0,("fetch_domain_sid: unable to initialize client connection.\n"));
1352                 return False;
1353         }
1354
1355         if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
1356                 DEBUG(0,("fetch_domain_sid: Can't resolve address for %s\n", remote_machine));
1357                 goto done;
1358         }
1359
1360         if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
1361                 DEBUG(0,("fetch_domain_sid: unable to connect to SMB server on \
1362 machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1363                 goto done;
1364         }
1365
1366         if (!attempt_netbios_session_request(&cli, global_myname(), remote_machine, &cli.dest_ip)) {
1367                 DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS session request.\n",
1368                         remote_machine));
1369                 goto done;
1370         }
1371
1372         cli.protocol = PROTOCOL_NT1;
1373
1374         if (!cli_negprot(&cli)) {
1375                 DEBUG(0,("fetch_domain_sid: machine %s rejected the negotiate protocol. \
1376 Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1377                 goto done;
1378         }
1379
1380         if (cli.protocol != PROTOCOL_NT1) {
1381                 DEBUG(0,("fetch_domain_sid: machine %s didn't negotiate NT protocol.\n",
1382                         remote_machine));
1383                 goto done;
1384         }
1385
1386         /*
1387          * Do an anonymous session setup.
1388          */
1389
1390         if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
1391                 DEBUG(0,("fetch_domain_sid: machine %s rejected the session setup. \
1392 Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1393                 goto done;
1394         }
1395
1396         if (!(cli.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
1397                 DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n",
1398                         remote_machine));
1399                 goto done;
1400         }
1401
1402         if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
1403                 DEBUG(0,("fetch_domain_sid: machine %s rejected the tconX on the IPC$ share. \
1404 Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1405                 goto done;
1406         }
1407
1408         /* Fetch domain sid */
1409
1410         if (!cli_nt_session_open(&cli, PI_LSARPC)) {
1411                 DEBUG(0, ("fetch_domain_sid: Error connecting to SAM pipe\n"));
1412                 goto done;
1413         }
1414
1415         result = cli_lsa_open_policy(&cli, cli.mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, &lsa_pol);
1416         if (!NT_STATUS_IS_OK(result)) {
1417                 DEBUG(0, ("fetch_domain_sid: Error opening lsa policy handle. %s\n",
1418                         nt_errstr(result) ));
1419                 goto done;
1420         }
1421
1422         result = cli_lsa_query_info_policy(&cli, cli.mem_ctx, &lsa_pol, 5, domain, psid);
1423         if (!NT_STATUS_IS_OK(result)) {
1424                 DEBUG(0, ("fetch_domain_sid: Error querying lsa policy handle. %s\n",
1425                         nt_errstr(result) ));
1426                 goto done;
1427         }
1428
1429         ret = True;
1430
1431   done:
1432
1433         cli_shutdown(&cli);
1434         return ret;
1435 }
1436
1437 #endif