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