Merge branch 'v3-2-test' of git://git.samba.org/samba into v3-2-test
[ira/wip.git] / source / rpc_client / cli_lsarpc.c
1 /*
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4    Copyright (C) Tim Potter                        2000-2001,
5    Copyright (C) Andrew Tridgell              1992-1997,2000,
6    Copyright (C) Rafal Szczesniak                       2002
7    Copyright (C) Jeremy Allison                         2005.
8    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_to_ascii_talloc(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_to_ascii_talloc(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_to_ascii_talloc(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_to_ascii_talloc(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_to_ascii_talloc(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 /**
720  * Enumerate list of trusted domains
721  *
722  * @param cli client state (cli_state) structure of the connection
723  * @param mem_ctx memory context
724  * @param pol opened lsa policy handle
725  * @param enum_ctx enumeration context ie. index of first returned domain entry
726  * @param pref_num_domains preferred max number of entries returned in one response
727  * @param num_domains total number of trusted domains returned by response
728  * @param domain_names returned trusted domain names
729  * @param domain_sids returned trusted domain sids
730  *
731  * @return nt status code of response
732  **/
733
734 NTSTATUS rpccli_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
735                                    TALLOC_CTX *mem_ctx,
736                                    POLICY_HND *pol, uint32 *enum_ctx,
737                                    uint32 *num_domains,
738                                    char ***domain_names, DOM_SID **domain_sids)
739 {
740         prs_struct qbuf, rbuf;
741         LSA_Q_ENUM_TRUST_DOM in;
742         LSA_R_ENUM_TRUST_DOM out;
743         int i;
744         fstring tmp;
745
746         ZERO_STRUCT(in);
747         ZERO_STRUCT(out);
748
749         /* 64k is enough for about 2000 trusted domains */
750
751         init_q_enum_trust_dom(&in, pol, *enum_ctx, 0x10000);
752
753         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMTRUSTDOM,
754                     in, out,
755                     qbuf, rbuf,
756                     lsa_io_q_enum_trust_dom,
757                     lsa_io_r_enum_trust_dom,
758                     NT_STATUS_UNSUCCESSFUL );
759
760
761         /* check for an actual error */
762
763         if ( !NT_STATUS_IS_OK(out.status)
764                 && !NT_STATUS_EQUAL(out.status, NT_STATUS_NO_MORE_ENTRIES)
765                 && !NT_STATUS_EQUAL(out.status, STATUS_MORE_ENTRIES) )
766         {
767                 return out.status;
768         }
769
770         /* Return output parameters */
771
772         *num_domains  = out.count;
773         *enum_ctx     = out.enum_context;
774
775         if ( out.count ) {
776
777                 /* Allocate memory for trusted domain names and sids */
778
779                 if ( !(*domain_names = TALLOC_ARRAY(mem_ctx, char *, out.count)) ) {
780                         DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
781                         return NT_STATUS_NO_MEMORY;
782                 }
783
784                 if ( !(*domain_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, out.count)) ) {
785                         DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
786                         return NT_STATUS_NO_MEMORY;
787                 }
788
789                 /* Copy across names and sids */
790
791                 for (i = 0; i < out.count; i++) {
792
793                         rpcstr_pull( tmp, out.domlist->domains[i].name.string->buffer,
794                                 sizeof(tmp), out.domlist->domains[i].name.length, 0);
795                         (*domain_names)[i] = talloc_strdup(mem_ctx, tmp);
796
797                         sid_copy(&(*domain_sids)[i], &out.domlist->domains[i].sid->sid );
798                 }
799         }
800
801         return out.status;
802 }
803
804 /** Enumerate privileges*/
805
806 NTSTATUS rpccli_lsa_enum_privilege(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
807                                 POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length,
808                                 uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low)
809 {
810         prs_struct qbuf, rbuf;
811         LSA_Q_ENUM_PRIVS q;
812         LSA_R_ENUM_PRIVS r;
813         NTSTATUS result;
814         int i;
815
816         ZERO_STRUCT(q);
817         ZERO_STRUCT(r);
818
819         init_q_enum_privs(&q, pol, *enum_context, pref_max_length);
820
821         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_PRIVS,
822                 q, r,
823                 qbuf, rbuf,
824                 lsa_io_q_enum_privs,
825                 lsa_io_r_enum_privs,
826                 NT_STATUS_UNSUCCESSFUL);
827
828         result = r.status;
829
830         if (!NT_STATUS_IS_OK(result)) {
831                 goto done;
832         }
833
834         /* Return output parameters */
835
836         *enum_context = r.enum_context;
837         *count = r.count;
838
839         if (r.count) {
840                 if (!((*privs_name = TALLOC_ARRAY(mem_ctx, char *, r.count)))) {
841                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
842                         result = NT_STATUS_UNSUCCESSFUL;
843                         goto done;
844                 }
845
846                 if (!((*privs_high = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {
847                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
848                         result = NT_STATUS_UNSUCCESSFUL;
849                         goto done;
850                 }
851
852                 if (!((*privs_low = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {
853                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
854                         result = NT_STATUS_UNSUCCESSFUL;
855                         goto done;
856                 }
857         } else {
858                 *privs_name = NULL;
859                 *privs_high = NULL;
860                 *privs_low = NULL;
861         }
862
863         for (i = 0; i < r.count; i++) {
864                 fstring name;
865
866                 rpcstr_pull_unistr2_fstring( name, &r.privs[i].name);
867
868                 (*privs_name)[i] = talloc_strdup(mem_ctx, name);
869
870                 (*privs_high)[i] = r.privs[i].luid_high;
871                 (*privs_low)[i] = r.privs[i].luid_low;
872         }
873
874  done:
875
876         return result;
877 }
878
879 /** Get privilege name */
880
881 NTSTATUS rpccli_lsa_get_dispname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
882                               POLICY_HND *pol, const char *name,
883                               uint16 lang_id, uint16 lang_id_sys,
884                               fstring description, uint16 *lang_id_desc)
885 {
886         prs_struct qbuf, rbuf;
887         LSA_Q_PRIV_GET_DISPNAME q;
888         LSA_R_PRIV_GET_DISPNAME r;
889         NTSTATUS result;
890
891         ZERO_STRUCT(q);
892         ZERO_STRUCT(r);
893
894         init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys);
895
896         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_PRIV_GET_DISPNAME,
897                 q, r,
898                 qbuf, rbuf,
899                 lsa_io_q_priv_get_dispname,
900                 lsa_io_r_priv_get_dispname,
901                 NT_STATUS_UNSUCCESSFUL);
902
903         result = r.status;
904
905         if (!NT_STATUS_IS_OK(result)) {
906                 goto done;
907         }
908
909         /* Return output parameters */
910
911         rpcstr_pull_unistr2_fstring(description , &r.desc);
912         *lang_id_desc = r.lang_id;
913
914  done:
915
916         return result;
917 }
918
919 /** Enumerate list of SIDs  */
920
921 NTSTATUS rpccli_lsa_enum_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
922                                 POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length,
923                                 uint32 *num_sids, DOM_SID **sids)
924 {
925         prs_struct qbuf, rbuf;
926         LSA_Q_ENUM_ACCOUNTS q;
927         LSA_R_ENUM_ACCOUNTS r;
928         NTSTATUS result;
929         int i;
930
931         ZERO_STRUCT(q);
932         ZERO_STRUCT(r);
933
934         init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length);
935
936         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_ACCOUNTS,
937                 q, r,
938                 qbuf, rbuf,
939                 lsa_io_q_enum_accounts,
940                 lsa_io_r_enum_accounts,
941                 NT_STATUS_UNSUCCESSFUL);
942
943         result = r.status;
944
945         if (!NT_STATUS_IS_OK(result)) {
946                 goto done;
947         }
948
949         if (r.sids.num_entries==0)
950                 goto done;
951
952         /* Return output parameters */
953
954         *sids = TALLOC_ARRAY(mem_ctx, DOM_SID, r.sids.num_entries);
955         if (!*sids) {
956                 DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n"));
957                 result = NT_STATUS_UNSUCCESSFUL;
958                 goto done;
959         }
960
961         /* Copy across names and sids */
962
963         for (i = 0; i < r.sids.num_entries; i++) {
964                 sid_copy(&(*sids)[i], &r.sids.sid[i].sid);
965         }
966
967         *num_sids= r.sids.num_entries;
968         *enum_ctx = r.enum_context;
969
970  done:
971
972         return result;
973 }
974
975 /** Create a LSA user handle
976  *
977  * @param cli Handle on an initialised SMB connection
978  *
979  * FIXME: The code is actually identical to open account
980  * TODO: Check and code what the function should exactly do
981  *
982  * */
983
984 NTSTATUS rpccli_lsa_create_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
985                              POLICY_HND *dom_pol, DOM_SID *sid, uint32 desired_access,
986                              POLICY_HND *user_pol)
987 {
988         prs_struct qbuf, rbuf;
989         LSA_Q_CREATEACCOUNT q;
990         LSA_R_CREATEACCOUNT r;
991         NTSTATUS result;
992
993         ZERO_STRUCT(q);
994         ZERO_STRUCT(r);
995
996         /* Initialise input parameters */
997
998         init_lsa_q_create_account(&q, dom_pol, sid, desired_access);
999
1000         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_CREATEACCOUNT,
1001                 q, r,
1002                 qbuf, rbuf,
1003                 lsa_io_q_create_account,
1004                 lsa_io_r_create_account,
1005                 NT_STATUS_UNSUCCESSFUL);
1006
1007         /* Return output parameters */
1008
1009         result = r.status;
1010
1011         if (NT_STATUS_IS_OK(result)) {
1012                 *user_pol = r.pol;
1013         }
1014
1015         return result;
1016 }
1017
1018 /** Open a LSA user handle
1019  *
1020  * @param cli Handle on an initialised SMB connection */
1021
1022 NTSTATUS rpccli_lsa_open_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1023                              POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access,
1024                              POLICY_HND *user_pol)
1025 {
1026         prs_struct qbuf, rbuf;
1027         LSA_Q_OPENACCOUNT q;
1028         LSA_R_OPENACCOUNT r;
1029         NTSTATUS result;
1030
1031         ZERO_STRUCT(q);
1032         ZERO_STRUCT(r);
1033
1034         /* Initialise input parameters */
1035
1036         init_lsa_q_open_account(&q, dom_pol, sid, des_access);
1037
1038         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENACCOUNT,
1039                 q, r,
1040                 qbuf, rbuf,
1041                 lsa_io_q_open_account,
1042                 lsa_io_r_open_account,
1043                 NT_STATUS_UNSUCCESSFUL);
1044
1045         /* Return output parameters */
1046
1047         result = r.status;
1048
1049         if (NT_STATUS_IS_OK(result)) {
1050                 *user_pol = r.pol;
1051         }
1052
1053         return result;
1054 }
1055
1056 /** Enumerate user privileges
1057  *
1058  * @param cli Handle on an initialised SMB connection */
1059
1060 NTSTATUS rpccli_lsa_enum_privsaccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1061                              POLICY_HND *pol, uint32 *count, LUID_ATTR **set)
1062 {
1063         prs_struct qbuf, rbuf;
1064         LSA_Q_ENUMPRIVSACCOUNT q;
1065         LSA_R_ENUMPRIVSACCOUNT r;
1066         NTSTATUS result;
1067         int i;
1068
1069         ZERO_STRUCT(q);
1070         ZERO_STRUCT(r);
1071
1072         /* Initialise input parameters */
1073
1074         init_lsa_q_enum_privsaccount(&q, pol);
1075
1076         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMPRIVSACCOUNT,
1077                 q, r,
1078                 qbuf, rbuf,
1079                 lsa_io_q_enum_privsaccount,
1080                 lsa_io_r_enum_privsaccount,
1081                 NT_STATUS_UNSUCCESSFUL);
1082
1083         /* Return output parameters */
1084
1085         result = r.status;
1086
1087         if (!NT_STATUS_IS_OK(result)) {
1088                 goto done;
1089         }
1090
1091         if (r.count == 0)
1092                 goto done;
1093
1094         if (!((*set = TALLOC_ARRAY(mem_ctx, LUID_ATTR, r.count)))) {
1095                 DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n"));
1096                 result = NT_STATUS_UNSUCCESSFUL;
1097                 goto done;
1098         }
1099
1100         for (i=0; i<r.count; i++) {
1101                 (*set)[i].luid.low = r.set.set[i].luid.low;
1102                 (*set)[i].luid.high = r.set.set[i].luid.high;
1103                 (*set)[i].attr = r.set.set[i].attr;
1104         }
1105
1106         *count=r.count;
1107  done:
1108
1109         return result;
1110 }
1111
1112 /** Get a privilege value given its name */
1113
1114 NTSTATUS rpccli_lsa_lookup_priv_value(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1115                                  POLICY_HND *pol, const char *name, LUID *luid)
1116 {
1117         prs_struct qbuf, rbuf;
1118         LSA_Q_LOOKUP_PRIV_VALUE q;
1119         LSA_R_LOOKUP_PRIV_VALUE r;
1120         NTSTATUS result;
1121
1122         ZERO_STRUCT(q);
1123         ZERO_STRUCT(r);
1124
1125         /* Marshall data and send request */
1126
1127         init_lsa_q_lookup_priv_value(&q, pol, name);
1128
1129         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPPRIVVALUE,
1130                 q, r,
1131                 qbuf, rbuf,
1132                 lsa_io_q_lookup_priv_value,
1133                 lsa_io_r_lookup_priv_value,
1134                 NT_STATUS_UNSUCCESSFUL);
1135
1136         result = r.status;
1137
1138         if (!NT_STATUS_IS_OK(result)) {
1139                 goto done;
1140         }
1141
1142         /* Return output parameters */
1143
1144         (*luid).low=r.luid.low;
1145         (*luid).high=r.luid.high;
1146
1147  done:
1148
1149         return result;
1150 }
1151
1152 /** Query LSA security object */
1153
1154 NTSTATUS rpccli_lsa_query_secobj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1155                               POLICY_HND *pol, uint32 sec_info,
1156                               SEC_DESC_BUF **psdb)
1157 {
1158         prs_struct qbuf, rbuf;
1159         LSA_Q_QUERY_SEC_OBJ q;
1160         LSA_R_QUERY_SEC_OBJ r;
1161         NTSTATUS result;
1162
1163         ZERO_STRUCT(q);
1164         ZERO_STRUCT(r);
1165
1166         /* Marshall data and send request */
1167
1168         init_q_query_sec_obj(&q, pol, sec_info);
1169
1170         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYSECOBJ,
1171                 q, r,
1172                 qbuf, rbuf,
1173                 lsa_io_q_query_sec_obj,
1174                 lsa_io_r_query_sec_obj,
1175                 NT_STATUS_UNSUCCESSFUL);
1176
1177         result = r.status;
1178
1179         if (!NT_STATUS_IS_OK(result)) {
1180                 goto done;
1181         }
1182
1183         /* Return output parameters */
1184
1185         if (psdb)
1186                 *psdb = r.buf;
1187
1188  done:
1189
1190         return result;
1191 }
1192
1193
1194 /* Enumerate account rights This is similar to enum_privileges but
1195    takes a SID directly, avoiding the open_account call.
1196 */
1197
1198 NTSTATUS rpccli_lsa_enum_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1199                                      POLICY_HND *pol, DOM_SID *sid,
1200                                      uint32 *count, char ***priv_names)
1201 {
1202         prs_struct qbuf, rbuf;
1203         LSA_Q_ENUM_ACCT_RIGHTS q;
1204         LSA_R_ENUM_ACCT_RIGHTS r;
1205         NTSTATUS result;
1206         int i;
1207         fstring *privileges;
1208         char **names;
1209
1210         ZERO_STRUCT(q);
1211         ZERO_STRUCT(r);
1212
1213         /* Marshall data and send request */
1214         init_q_enum_acct_rights(&q, pol, 2, sid);
1215
1216         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMACCTRIGHTS,
1217                 q, r,
1218                 qbuf, rbuf,
1219                 lsa_io_q_enum_acct_rights,
1220                 lsa_io_r_enum_acct_rights,
1221                 NT_STATUS_UNSUCCESSFUL);
1222
1223         result = r.status;
1224
1225         if (!NT_STATUS_IS_OK(result)) {
1226                 goto done;
1227         }
1228
1229         *count = r.count;
1230         if (! *count) {
1231                 goto done;
1232         }
1233
1234
1235         privileges = TALLOC_ARRAY( mem_ctx, fstring, *count );
1236         names      = TALLOC_ARRAY( mem_ctx, char *, *count );
1237
1238         if ((privileges == NULL) || (names == NULL)) {
1239                 TALLOC_FREE(privileges);
1240                 TALLOC_FREE(names);
1241                 return NT_STATUS_NO_MEMORY;
1242         }
1243
1244         for ( i=0; i<*count; i++ ) {
1245                 UNISTR4 *uni_string = &r.rights->strings[i];
1246
1247                 if ( !uni_string->string )
1248                         continue;
1249
1250                 rpcstr_pull( privileges[i], uni_string->string->buffer, sizeof(privileges[i]), -1, STR_TERMINATE );
1251
1252                 /* now copy to the return array */
1253                 names[i] = talloc_strdup( mem_ctx, privileges[i] );
1254         }
1255
1256         *priv_names = names;
1257
1258 done:
1259
1260         return result;
1261 }
1262
1263
1264
1265 /* add account rights to an account. */
1266
1267 NTSTATUS rpccli_lsa_add_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1268                                     POLICY_HND *pol, DOM_SID sid,
1269                                         uint32 count, const char **privs_name)
1270 {
1271         prs_struct qbuf, rbuf;
1272         LSA_Q_ADD_ACCT_RIGHTS q;
1273         LSA_R_ADD_ACCT_RIGHTS r;
1274         NTSTATUS result;
1275
1276         ZERO_STRUCT(q);
1277         ZERO_STRUCT(r);
1278
1279         /* Marshall data and send request */
1280         init_q_add_acct_rights(&q, pol, &sid, count, privs_name);
1281
1282         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ADDACCTRIGHTS,
1283                 q, r,
1284                 qbuf, rbuf,
1285                 lsa_io_q_add_acct_rights,
1286                 lsa_io_r_add_acct_rights,
1287                 NT_STATUS_UNSUCCESSFUL);
1288
1289         result = r.status;
1290
1291         if (!NT_STATUS_IS_OK(result)) {
1292                 goto done;
1293         }
1294 done:
1295
1296         return result;
1297 }
1298
1299
1300 /* remove account rights for an account. */
1301
1302 NTSTATUS rpccli_lsa_remove_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1303                                        POLICY_HND *pol, DOM_SID sid, bool removeall,
1304                                        uint32 count, const char **privs_name)
1305 {
1306         prs_struct qbuf, rbuf;
1307         LSA_Q_REMOVE_ACCT_RIGHTS q;
1308         LSA_R_REMOVE_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_remove_acct_rights(&q, pol, &sid, removeall?1:0, count, privs_name);
1316
1317         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_REMOVEACCTRIGHTS,
1318                 q, r,
1319                 qbuf, rbuf,
1320                 lsa_io_q_remove_acct_rights,
1321                 lsa_io_r_remove_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 #if 0
1336
1337 /** An example of how to use the routines in this file.  Fetch a DOMAIN
1338     sid. Does complete cli setup / teardown anonymously. */
1339
1340 bool fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid)
1341 {
1342         struct cli_state cli;
1343         NTSTATUS result;
1344         POLICY_HND lsa_pol;
1345         bool ret = False;
1346
1347         ZERO_STRUCT(cli);
1348         if(cli_initialise(&cli) == False) {
1349                 DEBUG(0,("fetch_domain_sid: unable to initialize client connection.\n"));
1350                 return False;
1351         }
1352
1353         if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
1354                 DEBUG(0,("fetch_domain_sid: Can't resolve address for %s\n", remote_machine));
1355                 goto done;
1356         }
1357
1358         if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
1359                 DEBUG(0,("fetch_domain_sid: unable to connect to SMB server on \
1360 machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1361                 goto done;
1362         }
1363
1364         if (!attempt_netbios_session_request(&cli, global_myname(), remote_machine, &cli.dest_ip)) {
1365                 DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS session request.\n",
1366                         remote_machine));
1367                 goto done;
1368         }
1369
1370         cli.protocol = PROTOCOL_NT1;
1371
1372         if (!cli_negprot(&cli)) {
1373                 DEBUG(0,("fetch_domain_sid: machine %s rejected the negotiate protocol. \
1374 Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1375                 goto done;
1376         }
1377
1378         if (cli.protocol != PROTOCOL_NT1) {
1379                 DEBUG(0,("fetch_domain_sid: machine %s didn't negotiate NT protocol.\n",
1380                         remote_machine));
1381                 goto done;
1382         }
1383
1384         /*
1385          * Do an anonymous session setup.
1386          */
1387
1388         if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
1389                 DEBUG(0,("fetch_domain_sid: machine %s rejected the session setup. \
1390 Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1391                 goto done;
1392         }
1393
1394         if (!(cli.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
1395                 DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n",
1396                         remote_machine));
1397                 goto done;
1398         }
1399
1400         if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
1401                 DEBUG(0,("fetch_domain_sid: machine %s rejected the tconX on the IPC$ share. \
1402 Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1403                 goto done;
1404         }
1405
1406         /* Fetch domain sid */
1407
1408         if (!cli_nt_session_open(&cli, PI_LSARPC)) {
1409                 DEBUG(0, ("fetch_domain_sid: Error connecting to SAM pipe\n"));
1410                 goto done;
1411         }
1412
1413         result = cli_lsa_open_policy(&cli, cli.mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, &lsa_pol);
1414         if (!NT_STATUS_IS_OK(result)) {
1415                 DEBUG(0, ("fetch_domain_sid: Error opening lsa policy handle. %s\n",
1416                         nt_errstr(result) ));
1417                 goto done;
1418         }
1419
1420         result = cli_lsa_query_info_policy(&cli, cli.mem_ctx, &lsa_pol, 5, domain, psid);
1421         if (!NT_STATUS_IS_OK(result)) {
1422                 DEBUG(0, ("fetch_domain_sid: Error querying lsa policy handle. %s\n",
1423                         nt_errstr(result) ));
1424                 goto done;
1425         }
1426
1427         ret = True;
1428
1429   done:
1430
1431         cli_shutdown(&cli);
1432         return ret;
1433 }
1434
1435 #endif