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