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