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
45NTSTATUS 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
107NTSTATUS 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
168NTSTATUS 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
219NTSTATUS 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
336NTSTATUS 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
439NTSTATUS 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
533NTSTATUS 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
633NTSTATUS 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
727NTSTATUS 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
809NTSTATUS 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
862NTSTATUS 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
940NTSTATUS 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
993NTSTATUS 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
1046NTSTATUS 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
1113NTSTATUS cli_lsa_lookup_priv_value(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_LOOKUP_PRIV_VALUE q;
1118	LSA_R_LOOKUP_PRIV_VALUE 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_lookup_priv_value(&q, pol, name);
1132
1133	if (!lsa_io_q_lookup_priv_value("", &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_lookup_priv_value("", &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
1164NTSTATUS 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
1219NTSTATUS 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
1276done:
1277
1278	return result;
1279}
1280
1281
1282
1283/* add account rights to an account. */
1284
1285NTSTATUS 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	}
1319done:
1320
1321	return result;
1322}
1323
1324
1325/* remove account rights for an account. */
1326
1327NTSTATUS 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	}
1361done:
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
1372BOOL 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 \
1393machine %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. \
1407Error 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. \
1423Error 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. \
1435Error 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/** @} **/
1471