shuffling msrpc code around so that it can be used independently of rpcclient
[samba.git] / source / rpc_client / cli_lsarpc.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25
26 #ifdef SYSLOG
27 #undef SYSLOG
28 #endif
29
30 #include "includes.h"
31
32 extern int DEBUGLEVEL;
33
34
35 /****************************************************************************
36  obtain the sid from the PDC.  do some verification along the way...
37 ****************************************************************************/
38 BOOL get_domain_sids(const char *myname,
39                                 DOM_SID *sid3, DOM_SID *sid5, char *servers)
40 {
41         uint16 nt_pipe_fnum;
42         POLICY_HND pol;
43         fstring srv_name;
44         struct cli_state cli;
45         BOOL res = True;
46         fstring dom3;
47         fstring dom5;
48
49         if (sid3 == NULL && sid5 == NULL)
50         {
51                 /* don't waste my time... */
52                 return False;
53         }
54
55         if (!cli_connect_serverlist(&cli, servers))
56         {
57                 DEBUG(0,("get_domain_sids: unable to initialise client connection.\n"));
58                 return False;
59         }
60
61         /*
62          * Ok - we have an anonymous connection to the IPC$ share.
63          * Now start the NT Domain stuff :-).
64          */
65
66         fstrcpy(dom3, "");
67         fstrcpy(dom5, "");
68         if (sid3 != NULL)
69         {
70                 ZERO_STRUCTP(sid3);
71         }
72         if (sid5 != NULL)
73         {
74                 ZERO_STRUCTP(sid5);
75         }
76
77         fstrcpy(srv_name, "\\\\");
78         fstrcat(srv_name, myname);
79         strupper(srv_name);
80
81         /* open LSARPC session. */
82         res = res ? cli_nt_session_open(&cli, PIPE_LSARPC, &nt_pipe_fnum) : False;
83
84         /* lookup domain controller; receive a policy handle */
85         res = res ? lsa_open_policy(&cli, nt_pipe_fnum, srv_name, &pol, False) : False;
86
87         if (sid3 != NULL)
88         {
89                 /* send client info query, level 3.  receive domain name and sid */
90                 res = res ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 3, dom3, sid3) : False;
91         }
92
93         if (sid5 != NULL)
94         {
95                 /* send client info query, level 5.  receive domain name and sid */
96                 res = res ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 5, dom5, sid5) : False;
97         }
98
99         /* close policy handle */
100         res = res ? lsa_close(&cli, nt_pipe_fnum, &pol) : False;
101
102         /* close the session */
103         cli_nt_session_close(&cli, nt_pipe_fnum);
104         cli_ulogoff(&cli);
105         cli_shutdown(&cli);
106
107         if (res)
108         {
109                 pstring sid;
110                 DEBUG(2,("LSA Query Info Policy\n"));
111                 if (sid3 != NULL)
112                 {
113                         sid_to_string(sid, sid3);
114                         DEBUG(2,("Domain Member     - Domain: %s SID: %s\n", dom3, sid));
115                 }
116                 if (sid5 != NULL)
117                 {
118                         sid_to_string(sid, sid5);
119                         DEBUG(2,("Domain Controller - Domain: %s SID: %s\n", dom5, sid));
120                 }
121         }
122         else
123         {
124                 DEBUG(1,("lsa query info failed\n"));
125         }
126
127         return res;
128 }
129
130 /****************************************************************************
131  obtain a sid and domain name from a Domain Controller.  
132 ****************************************************************************/
133 BOOL get_trust_sid_and_domain(const char* myname, char *server,
134                                 DOM_SID *sid,
135                                 char *domain, size_t len)
136 {
137         uint16 nt_pipe_fnum;
138         POLICY_HND pol;
139         fstring srv_name;
140         struct cli_state cli;
141         BOOL res = True;
142         BOOL res1 = True;
143         DOM_SID sid3;
144         DOM_SID sid5;
145         fstring dom3;
146         fstring dom5;
147
148         if (!cli_connect_serverlist(&cli, server))
149         {
150                 DEBUG(0,("get_trust_sid: unable to initialise client connection.\n"));
151                 return False;
152         }
153
154         fstrcpy(dom3, "");
155         fstrcpy(dom5, "");
156         ZERO_STRUCT(sid3);
157         ZERO_STRUCT(sid5);
158
159         fstrcpy(srv_name, "\\\\");
160         fstrcat(srv_name, myname);
161         strupper(srv_name);
162
163         /* open LSARPC session. */
164         res = res ? cli_nt_session_open(&cli, PIPE_LSARPC, &nt_pipe_fnum) : False;
165
166         /* lookup domain controller; receive a policy handle */
167         res = res ? lsa_open_policy(&cli, nt_pipe_fnum, srv_name, &pol, False) : False;
168
169         /* send client info query, level 3.  receive domain name and sid */
170         res1 = res ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 3, dom3, &sid3) : False;
171
172         /* send client info query, level 5.  receive domain name and sid */
173         res1 = res1 ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 5, dom5, &sid5) : False;
174
175         /* close policy handle */
176         res = res ? lsa_close(&cli, nt_pipe_fnum, &pol) : False;
177
178         /* close the session */
179         cli_nt_session_close(&cli, nt_pipe_fnum);
180         cli_ulogoff(&cli);
181         cli_shutdown(&cli);
182
183         if (res1)
184         {
185                 pstring sid_str;
186                 DEBUG(2,("LSA Query Info Policy\n"));
187                 sid_to_string(sid_str, &sid3);
188                 DEBUG(2,("Domain Member     - Domain: %s SID: %s\n",
189                           dom3, sid_str));
190                 sid_to_string(sid_str, &sid5);
191                 DEBUG(2,("Domain Controller - Domain: %s SID: %s\n",
192                           dom5, sid_str));
193
194                 if (dom5[0] != 0 && sid_equal(&sid3, &sid5))
195                 {
196                         safe_strcpy(domain, dom5, len);
197                         sid_copy(sid, &sid5);
198                 }
199                 else
200                 {
201                         DEBUG(2,("Server %s is not a PDC\n", server));
202                         return False;
203                 }
204
205         }
206         else
207         {
208                 DEBUG(1,("lsa query info failed\n"));
209         }
210
211         return res1;
212 }
213
214 /****************************************************************************
215 do a LSA Open Policy
216 ****************************************************************************/
217 BOOL lsa_open_policy(struct cli_state *cli, uint16 fnum,
218                         const char *server_name, POLICY_HND *hnd,
219                         BOOL sec_qos)
220 {
221         prs_struct rbuf;
222         prs_struct buf; 
223         LSA_Q_OPEN_POL q_o;
224         LSA_SEC_QOS qos;
225         BOOL valid_pol = False;
226
227         if (hnd == NULL) return False;
228
229         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
230         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
231
232         /* create and send a MSRPC command with api LSA_OPENPOLICY */
233
234         DEBUG(4,("LSA Open Policy\n"));
235
236         /* store the parameters */
237         if (sec_qos)
238         {
239                 make_lsa_sec_qos(&qos, 2, 1, 0, 0x20000000);
240                 make_q_open_pol(&q_o, 0x5c, 0, 0x02000000, &qos);
241         }
242         else
243         {
244                 make_q_open_pol(&q_o, 0x5c, 0, 0x1, NULL);
245         }
246
247         /* turn parameters into data stream */
248         lsa_io_q_open_pol("", &q_o, &buf, 0);
249
250         /* send the data on \PIPE\ */
251         if (rpc_api_pipe_req(cli, fnum, LSA_OPENPOLICY, &buf, &rbuf))
252         {
253                 LSA_R_OPEN_POL r_o;
254                 BOOL p;
255
256                 lsa_io_r_open_pol("", &r_o, &rbuf, 0);
257                 p = rbuf.offset != 0;
258
259                 if (p && r_o.status != 0)
260                 {
261                         /* report error code */
262                         DEBUG(0,("LSA_OPENPOLICY: %s\n", get_nt_error_msg(r_o.status)));
263                         p = False;
264                 }
265
266                 if (p)
267                 {
268                         /* ok, at last: we're happy. return the policy handle */
269                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
270                         valid_pol = True;
271                 }
272         }
273
274         prs_mem_free(&rbuf);
275         prs_mem_free(&buf );
276
277         return valid_pol;
278 }
279
280 /****************************************************************************
281 do a LSA Open Policy2
282 ****************************************************************************/
283 BOOL lsa_open_policy2(struct cli_state *cli, uint16 fnum,
284                         const char *server_name, POLICY_HND *hnd,
285                         BOOL sec_qos)
286 {
287         prs_struct rbuf;
288         prs_struct buf; 
289         LSA_Q_OPEN_POL2 q_o;
290         LSA_SEC_QOS qos;
291         BOOL valid_pol = False;
292
293         if (hnd == NULL) return False;
294
295         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
296         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
297
298         /* create and send a MSRPC command with api LSA_OPENPOLICY2 */
299
300         DEBUG(4,("LSA Open Policy2\n"));
301
302         /* store the parameters */
303         if (sec_qos)
304         {
305                 make_lsa_sec_qos(&qos, 2, 1, 0, 0x02000000);
306                 make_q_open_pol2(&q_o, server_name, 0, 0x02000000, &qos);
307         }
308         else
309         {
310                 make_q_open_pol2(&q_o, server_name, 0, 0x02000000, NULL);
311         }
312
313         /* turn parameters into data stream */
314         lsa_io_q_open_pol2("", &q_o, &buf, 0);
315
316         /* send the data on \PIPE\ */
317         if (rpc_api_pipe_req(cli, fnum, LSA_OPENPOLICY2, &buf, &rbuf))
318         {
319                 LSA_R_OPEN_POL2 r_o;
320                 BOOL p;
321
322                 lsa_io_r_open_pol2("", &r_o, &rbuf, 0);
323                 p = rbuf.offset != 0;
324
325                 if (p && r_o.status != 0)
326                 {
327                         /* report error code */
328                         DEBUG(0,("LSA_OPENPOLICY2: %s\n", get_nt_error_msg(r_o.status)));
329                         p = False;
330                 }
331
332                 if (p)
333                 {
334                         /* ok, at last: we're happy. return the policy handle */
335                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
336                         valid_pol = True;
337                 }
338         }
339
340         prs_mem_free(&rbuf);
341         prs_mem_free(&buf );
342
343         return valid_pol;
344 }
345
346 /****************************************************************************
347 do a LSA Open Secret
348 ****************************************************************************/
349 BOOL lsa_open_secret(struct cli_state *cli, uint16 fnum,
350                                 const POLICY_HND *hnd_pol,
351                                 const char *secret_name,
352                                 uint32 des_access,
353                                 POLICY_HND *hnd_secret)
354 {
355         prs_struct rbuf;
356         prs_struct buf; 
357         LSA_Q_OPEN_SECRET q_o;
358         BOOL valid_pol = False;
359
360         if (hnd_pol == NULL) return False;
361
362         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
363         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
364
365         /* create and send a MSRPC command with api LSA_OPENSECRET */
366
367         DEBUG(4,("LSA Open Secret\n"));
368
369         make_q_open_secret(&q_o, hnd_pol, secret_name, des_access);
370
371         /* turn parameters into data stream */
372         lsa_io_q_open_secret("", &q_o, &buf, 0);
373
374         /* send the data on \PIPE\ */
375         if (rpc_api_pipe_req(cli, fnum, LSA_OPENSECRET, &buf, &rbuf))
376         {
377                 LSA_R_OPEN_SECRET r_o;
378                 BOOL p;
379
380                 lsa_io_r_open_secret("", &r_o, &rbuf, 0);
381                 p = rbuf.offset != 0;
382
383                 if (p && r_o.status != 0)
384                 {
385                         /* report error code */
386                         DEBUG(0,("LSA_OPENSECRET: %s\n", get_nt_error_msg(r_o.status)));
387                         p = False;
388                 }
389
390                 if (p)
391                 {
392                         /* ok, at last: we're happy. return the policy handle */
393                         memcpy(hnd_secret, r_o.pol.data, sizeof(hnd_secret->data));
394                         valid_pol = True;
395                 }
396         }
397
398         prs_mem_free(&rbuf);
399         prs_mem_free(&buf );
400
401         return valid_pol;
402 }
403
404 /****************************************************************************
405 do a LSA Query Secret
406 ****************************************************************************/
407 BOOL lsa_query_secret(struct cli_state *cli, uint16 fnum,
408                       POLICY_HND *pol, STRING2 *enc_secret,
409                       NTTIME *last_update)
410 {
411         prs_struct rbuf;
412         prs_struct buf; 
413         LSA_Q_QUERY_SECRET q_q;
414         BOOL valid_info = False;
415
416         if (pol == NULL) return False;
417
418         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
419         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
420
421         /* create and send a MSRPC command with api LSA_QUERYSECRET */
422
423         DEBUG(4,("LSA Query Secret\n"));
424
425         make_q_query_secret(&q_q, pol);
426
427         /* turn parameters into data stream */
428         lsa_io_q_query_secret("", &q_q, &buf, 0);
429
430         /* send the data on \PIPE\ */
431         if (rpc_api_pipe_req(cli, fnum, LSA_QUERYSECRET, &buf, &rbuf))
432         {
433                 LSA_R_QUERY_SECRET r_q;
434                 BOOL p;
435
436                 lsa_io_r_query_secret("", &r_q, &rbuf, 0);
437                 p = rbuf.offset != 0;
438
439                 if (p && r_q.status != 0)
440                 {
441                         /* report error code */
442                         DEBUG(0,("LSA_QUERYSECRET: %s\n", get_nt_error_msg(r_q.status)));
443                         p = False;
444                 }
445
446                 if (p && (r_q.info.ptr_value != 0) &&
447                     (r_q.info.value.ptr_secret != 0) &&
448                     (r_q.info.ptr_update != 0))
449                 {
450                         memcpy(enc_secret,  &(r_q.info.value.enc_secret), sizeof(STRING2));
451                         memcpy(last_update, &(r_q.info.last_update),      sizeof(NTTIME));
452                         valid_info = True;
453                 }
454         }
455
456         prs_mem_free(&rbuf);
457         prs_mem_free(&buf );
458
459         return valid_info;
460 }
461
462
463 /****************************************************************************
464 do a LSA Lookup Names
465 ****************************************************************************/
466 BOOL lsa_lookup_names(struct cli_state *cli, uint16 fnum,
467                         POLICY_HND *hnd,
468                         int num_names,
469                         char **names,
470                         DOM_SID **sids,
471                         uint8 **types,
472                         int *num_sids)
473 {
474         prs_struct rbuf;
475         prs_struct buf; 
476         LSA_Q_LOOKUP_NAMES q_l;
477         BOOL valid_response = False;
478
479         if (hnd == NULL || num_sids == 0 || sids == NULL) return False;
480
481         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
482         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
483
484         /* create and send a MSRPC command with api LSA_LOOKUP_NAMES */
485
486         DEBUG(4,("LSA Lookup NAMEs\n"));
487
488         /* store the parameters */
489         make_q_lookup_names(&q_l, hnd, num_names, names);
490
491         /* turn parameters into data stream */
492         lsa_io_q_lookup_names("", &q_l, &buf, 0);
493
494         /* send the data on \PIPE\ */
495         if (rpc_api_pipe_req(cli, fnum, LSA_LOOKUPNAMES, &buf, &rbuf))
496         {
497                 LSA_R_LOOKUP_NAMES r_l;
498                 DOM_R_REF ref;
499                 DOM_RID2 t_rids[MAX_LOOKUP_SIDS];
500                 BOOL p;
501
502                 ZERO_STRUCT(ref);
503                 ZERO_STRUCT(t_rids);
504
505                 r_l.dom_ref = &ref;
506                 r_l.dom_rid = t_rids;
507
508                 lsa_io_r_lookup_names("", &r_l, &rbuf, 0);
509                 p = rbuf.offset != 0;
510                 
511                 if (p && r_l.status != 0)
512                 {
513                         /* report error code */
514                         DEBUG(1,("LSA_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_l.status)));
515                         p = False;
516                 }
517
518                 if (p)
519                 {
520                         if (r_l.ptr_dom_ref != 0 && r_l.ptr_entries != 0)
521                         {
522                                 valid_response = True;
523                         }
524                 }
525
526                 if (num_sids != NULL && valid_response)
527                 {
528                         (*num_sids) = r_l.num_entries;
529                 }
530                 if (valid_response)
531                 {
532                         uint32 i;
533                         for (i = 0; i < r_l.num_entries; i++)
534                         {
535                                 if (t_rids[i].rid_idx >= ref.num_ref_doms_1 &&
536                                     t_rids[i].rid_idx != 0xffffffff)
537                                 {
538                                         DEBUG(0,("LSA_LOOKUP_NAMES: domain index %d out of bounds\n",
539                                                   t_rids[i].rid_idx));
540                                         valid_response = False;
541                                         break;
542                                 }
543                         }
544                 }
545
546                 if (types != NULL && valid_response && r_l.num_entries != 0)
547                 {
548                         (*types) = (uint8*)malloc((*num_sids) * sizeof(uint8));
549                 }
550
551                 if (sids != NULL && valid_response && r_l.num_entries != 0)
552                 {
553                         (*sids) = (DOM_SID*)malloc((*num_sids) * sizeof(DOM_SID));
554                 }
555
556                 if (sids != NULL && (*sids) != NULL)
557                 {
558                         int i;
559                         /* take each name, construct a SID */
560                         for (i = 0; i < (*num_sids); i++)
561                         {
562                                 uint32 dom_idx = t_rids[i].rid_idx;
563                                 uint32 dom_rid = t_rids[i].rid;
564                                 DOM_SID *sid = &(*sids)[i];
565                                 if (dom_idx != 0xffffffff)
566                                 {
567                                         sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid);
568                                         if (dom_rid != 0xffffffff)
569                                         {
570                                                 sid_append_rid(sid, dom_rid);
571                                         }
572                                         if (types != NULL && (*types) != NULL)
573                                         {
574                                                 (*types)[i] = t_rids[i].type;
575                                         }
576                                 }
577                                 else
578                                 {
579                                         ZERO_STRUCTP(sid);
580                                         if (types != NULL && (*types) != NULL)
581                                         {
582                                                 (*types)[i] = SID_NAME_UNKNOWN;
583                                         }
584                                 }
585                         }
586                 }
587         }
588
589         prs_mem_free(&rbuf);
590         prs_mem_free(&buf );
591
592         return valid_response;
593 }
594
595 /****************************************************************************
596 do a LSA Lookup SIDs
597 ****************************************************************************/
598 BOOL lsa_lookup_sids(struct cli_state *cli, uint16 fnum,
599                         POLICY_HND *hnd,
600                         int num_sids,
601                         DOM_SID **sids,
602                         char ***names,
603                         uint8 **types,
604                         int *num_names)
605 {
606         prs_struct rbuf;
607         prs_struct buf; 
608         LSA_Q_LOOKUP_SIDS q_l;
609         BOOL valid_response = False;
610
611         ZERO_STRUCT(q_l);
612
613         if (hnd == NULL || num_sids == 0 || sids == NULL) return False;
614
615         if (num_names != NULL)
616         {
617                 *num_names = 0;
618         }
619         if (types != NULL)
620         {
621                 *types = NULL;
622         }
623         if (names != NULL)
624         {
625                 *names = NULL;
626         }
627
628         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
629         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
630
631         /* create and send a MSRPC command with api LSA_LOOKUP_SIDS */
632
633         DEBUG(4,("LSA Lookup SIDs\n"));
634
635         /* store the parameters */
636         make_q_lookup_sids(&q_l, hnd, num_sids, sids, 1);
637
638         /* turn parameters into data stream */
639         lsa_io_q_lookup_sids("", &q_l, &buf, 0);
640
641         /* send the data on \PIPE\ */
642         if (rpc_api_pipe_req(cli, fnum, LSA_LOOKUPSIDS, &buf, &rbuf))
643         {
644                 LSA_R_LOOKUP_SIDS r_l;
645                 DOM_R_REF ref;
646                 LSA_TRANS_NAME_ENUM t_names;
647                 BOOL p;
648
649                 r_l.dom_ref = &ref;
650                 r_l.names   = &t_names;
651
652                 lsa_io_r_lookup_sids("", &r_l, &rbuf, 0);
653                 p = rbuf.offset != 0;
654                 
655                 if (p && r_l.status != 0 &&
656                          r_l.status != 0x107 &&
657                          r_l.status != (0xC0000000 | NT_STATUS_NONE_MAPPED))
658                 {
659                         /* report error code */
660                         DEBUG(1,("LSA_LOOKUP_SIDS: %s\n", get_nt_error_msg(r_l.status)));
661                         p = False;
662                 }
663
664                 if (p)
665                 {
666                         if (t_names.ptr_trans_names != 0 && r_l.ptr_dom_ref != 0)
667                         {
668                                 valid_response = True;
669                         }
670                 }
671
672                 if (num_names != NULL && valid_response)
673                 {
674                         (*num_names) = t_names.num_entries;
675                 }
676                 if (valid_response)
677                 {
678                         uint32 i;
679                         for (i = 0; i < t_names.num_entries; i++)
680                         {
681                                 if (t_names.name[i].domain_idx >= ref.num_ref_doms_1)
682                                 {
683                                         DEBUG(0,("LSA_LOOKUP_SIDS: domain index out of bounds\n"));
684                                         valid_response = False;
685                                         break;
686                                 }
687                         }
688                 }
689
690                 if (types != NULL && valid_response && (*num_names) != 0)
691                 {
692                         (*types) = (uint8*)malloc((*num_names) * sizeof(uint8));
693                 }
694
695                 if (names != NULL && valid_response && (*num_names) != 0)
696                 {
697                         (*names) = (char**)malloc((*num_names) * sizeof(char*));
698                 }
699
700                 if (names != NULL && (*names) != NULL)
701                 {
702                         int i;
703                         /* take each name, construct a \DOMAIN\name string */
704                         for (i = 0; i < (*num_names); i++)
705                         {
706                                 fstring name;
707                                 fstring dom_name;
708                                 fstring full_name;
709                                 uint32 dom_idx = t_names.name[i].domain_idx;
710
711                                 if (dom_idx != 0xffffffff)
712                                 {
713                                         unistr2_to_ascii(dom_name, &ref.ref_dom[dom_idx].uni_dom_name, sizeof(dom_name)-1);
714                                         unistr2_to_ascii(name, &t_names.uni_name[i], sizeof(name)-1);
715                                         
716                                         memset(full_name, 0, sizeof(full_name));
717
718                                         slprintf(full_name, sizeof(full_name)-1, "%s\\%s",
719                                                  dom_name, name);
720
721                                         (*names)[i] = strdup(full_name);
722                                         if (types != NULL && (*types) != NULL)
723                                         {
724                                                 (*types)[i] = t_names.name[i].sid_name_use;
725                                         }
726                                 }
727                                 else
728                                 {
729                                         (*names)[i] = NULL;
730                                         if (types != NULL && (*types) != NULL)
731                                         {
732                                                 (*types)[i] = SID_NAME_UNKNOWN;
733                                         }
734                                 }
735                         }
736                 }
737         }
738
739         prs_mem_free(&rbuf);
740         prs_mem_free(&buf );
741
742         return valid_response;
743 }
744
745 /****************************************************************************
746 do a LSA Query Info Policy
747 ****************************************************************************/
748 BOOL lsa_query_info_pol(struct cli_state *cli, uint16 fnum,
749                         POLICY_HND *hnd, uint16 info_class,
750                         fstring domain_name, DOM_SID *domain_sid)
751 {
752         prs_struct rbuf;
753         prs_struct buf; 
754         LSA_Q_QUERY_INFO q_q;
755         BOOL valid_response = False;
756
757         ZERO_STRUCTP(domain_sid);
758         domain_name[0] = 0;
759
760         if (hnd == NULL || domain_name == NULL || domain_sid == NULL) return False;
761
762         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
763         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
764
765         /* create and send a MSRPC command with api LSA_QUERYINFOPOLICY */
766
767         DEBUG(4,("LSA Query Info Policy\n"));
768
769         /* store the parameters */
770         make_q_query(&q_q, hnd, info_class);
771
772         /* turn parameters into data stream */
773         lsa_io_q_query("", &q_q, &buf, 0);
774
775         /* send the data on \PIPE\ */
776         if (rpc_api_pipe_req(cli, fnum, LSA_QUERYINFOPOLICY, &buf, &rbuf))
777         {
778                 LSA_R_QUERY_INFO r_q;
779                 BOOL p;
780
781                 lsa_io_r_query("", &r_q, &rbuf, 0);
782                 p = rbuf.offset != 0;
783                 
784                 if (p && r_q.status != 0)
785                 {
786                         /* report error code */
787                         DEBUG(0,("LSA_QUERYINFOPOLICY: %s\n", get_nt_error_msg(r_q.status)));
788                         p = False;
789                 }
790
791                 if (p && r_q.info_class != q_q.info_class)
792                 {
793                         /* report different info classes */
794                         DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n",
795                                         q_q.info_class, r_q.info_class));
796                         p = False;
797                 }
798
799                 if (p)
800                 {
801                         fstring sid_str;
802                         /* ok, at last: we're happy. */
803                         switch (r_q.info_class)
804                         {
805                                 case 3:
806                                 {
807                                         if (r_q.dom.id3.buffer_dom_name != 0)
808                                         {
809                                                 unistr2_to_ascii(domain_name, &r_q.dom.id3.uni_domain_name, sizeof(fstring)-1);
810                                         }
811                                         if (r_q.dom.id3.buffer_dom_sid != 0)
812                                         {
813                                                 *domain_sid = r_q.dom.id3.dom_sid.sid;
814                                         }
815
816                                         valid_response = True;
817                                         break;
818                                 }
819                                 case 5:
820                                 {
821                                         if (r_q.dom.id5.buffer_dom_name != 0)
822                                         {
823                                                 unistr2_to_ascii(domain_name, &r_q.dom.id5.uni_domain_name, sizeof(fstring)-1);
824                                         }
825                                         if (r_q.dom.id5.buffer_dom_sid != 0)
826                                         {
827                                                 *domain_sid = r_q.dom.id5.dom_sid.sid;
828                                         }
829
830                                         valid_response = True;
831                                         break;
832                                 }
833                                 default:
834                                 {
835                                         DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n"));
836                                         domain_name[0] = 0;
837
838                                         break;
839                                 }
840                         }
841                 
842                         sid_to_string(sid_str, domain_sid);
843                         DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s  domain sid:%s\n",
844                                   r_q.info_class, domain_name, sid_str));
845                 }
846         }
847
848         prs_mem_free(&rbuf);
849         prs_mem_free(&buf );
850
851         return valid_response;
852 }
853
854 /****************************************************************************
855 do a LSA Enumerate Trusted Domain 
856 ****************************************************************************/
857 BOOL lsa_enum_trust_dom(struct cli_state *cli, uint16 fnum,
858                         POLICY_HND *hnd, uint32 *enum_ctx,
859                         uint32 *num_doms, char ***names,
860                         DOM_SID ***sids)
861 {
862         prs_struct rbuf;
863         prs_struct buf; 
864         LSA_Q_ENUM_TRUST_DOM q_q;
865         BOOL valid_response = False;
866
867         if (hnd == NULL || num_doms == NULL || names == NULL) return False;
868
869         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
870         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
871
872         /* create and send a MSRPC command with api LSA_ENUMTRUSTDOM */
873
874         DEBUG(4,("LSA Query Info Policy\n"));
875
876         /* store the parameters */
877         make_q_enum_trust_dom(&q_q, hnd, *enum_ctx, 0xffffffff);
878
879         /* turn parameters into data stream */
880         lsa_io_q_enum_trust_dom("", &q_q, &buf, 0);
881
882         /* send the data on \PIPE\ */
883         if (rpc_api_pipe_req(cli, fnum, LSA_ENUMTRUSTDOM, &buf, &rbuf))
884         {
885                 LSA_R_ENUM_TRUST_DOM r_q;
886                 BOOL p;
887
888                 lsa_io_r_enum_trust_dom("", &r_q, &rbuf, 0);
889                 p = rbuf.offset != 0;
890                 
891                 if (p && r_q.status != 0)
892                 {
893                         /* report error code */
894                         DEBUG(0,("LSA_ENUMTRUSTDOM: %s\n", get_nt_error_msg(r_q.status)));
895                         p = r_q.status == 0x8000001a;
896                 }
897
898                 if (p)
899                 {
900                         uint32 i;
901                         uint32 num_sids = 0;
902                         valid_response = True;
903
904                         for (i = 0; i < r_q.num_domains; i++)
905                         {
906                                 fstring tmp;
907                                 unistr2_to_ascii(tmp, &r_q.uni_domain_name[i],
908                                                  sizeof(tmp)-1);
909                                 add_chars_to_array(num_doms, names, tmp);
910                                 add_sid_to_array(&num_sids, sids,
911                                                  &r_q.domain_sid[i].sid);
912                         }
913
914                         if (r_q.status == 0x0)
915                         {
916                                 *enum_ctx = r_q.enum_context;
917                         }
918                         else
919                         {
920                                 *enum_ctx = 0;
921                         }
922                 }
923         }
924
925         prs_mem_free(&rbuf);
926         prs_mem_free(&buf );
927
928         return valid_response;
929 }
930
931 /****************************************************************************
932 do a LSA Close
933 ****************************************************************************/
934 BOOL lsa_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd)
935 {
936         prs_struct rbuf;
937         prs_struct buf; 
938         LSA_Q_CLOSE q_c;
939     BOOL valid_close = False;
940
941         if (hnd == NULL) return False;
942
943         /* create and send a MSRPC command with api LSA_OPENPOLICY */
944
945         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
946         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
947
948         DEBUG(4,("LSA Close\n"));
949
950         /* store the parameters */
951         make_lsa_q_close(&q_c, hnd);
952
953         /* turn parameters into data stream */
954         lsa_io_q_close("", &q_c, &buf, 0);
955
956         /* send the data on \PIPE\ */
957         if (rpc_api_pipe_req(cli, fnum, LSA_CLOSE, &buf, &rbuf))
958         {
959                 LSA_R_CLOSE r_c;
960                 BOOL p;
961
962                 lsa_io_r_close("", &r_c, &rbuf, 0);
963                 p = rbuf.offset != 0;
964
965                 if (p && r_c.status != 0)
966                 {
967                         /* report error code */
968                         DEBUG(0,("LSA_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
969                         p = False;
970                 }
971
972                 if (p)
973                 {
974                         /* check that the returned policy handle is all zeros */
975                         uint32 i;
976                         valid_close = True;
977
978                         for (i = 0; i < sizeof(r_c.pol.data); i++)
979                         {
980                                 if (r_c.pol.data[i] != 0)
981                                 {
982                                         valid_close = False;
983                                         break;
984                                 }
985                         }       
986                         if (!valid_close)
987                         {
988                                 DEBUG(0,("LSA_CLOSE: non-zero handle returned\n"));
989                         }
990                 }
991         }
992
993         prs_mem_free(&rbuf);
994         prs_mem_free(&buf );
995
996         return valid_close;
997 }
998
999