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