6e0e6ab71b8adfbb5c68124f060d4d6bac49670f
[samba.git] / source3 / rpc_client / cli_samr.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NT Domain Authentication SMB / MSRPC client
5    Copyright (C) Andrew Tridgell 1994-1997
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24
25 #ifdef SYSLOG
26 #undef SYSLOG
27 #endif
28
29 #include "includes.h"
30 #include "nterr.h"
31
32 extern int DEBUGLEVEL;
33
34
35
36 /****************************************************************************
37 do a SAMR query user groups
38 ****************************************************************************/
39 BOOL create_samr_domain_group(struct cli_state *cli, 
40                                 POLICY_HND *pol_open_domain,
41                                 const char *acct_name, const char *acct_desc,
42                                 uint32 *rid)
43 {
44         POLICY_HND pol_open_group;
45         GROUP_INFO_CTR ctr;
46         if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
47
48         /* send create group*/
49         if (!samr_create_dom_group(cli,
50                                 pol_open_domain,
51                                 acct_name,
52                                 &pol_open_group, rid))
53         {
54                 return False;
55         }
56
57         DEBUG(5,("create_samr_domain_group: name: %s rid 0x%x\n",
58                   acct_name, *rid));
59
60         ctr.switch_value1 = 4;
61         ctr.switch_value2 = 4;
62         make_samr_group_info4(&ctr.group.info4, acct_desc);
63
64         /* send user groups query */
65         if (!samr_set_groupinfo(cli,
66                                 &pol_open_group,
67                                 &ctr))
68         {
69                 DEBUG(5,("create_samr_domain_group: error in samr_set_groupinfo\n"));
70         }
71
72         return samr_close(cli, &pol_open_group);
73 }
74
75 /****************************************************************************
76 do a SAMR query user groups
77 ****************************************************************************/
78 BOOL get_samr_query_usergroups(struct cli_state *cli, 
79                                 POLICY_HND *pol_open_domain, uint32 user_rid,
80                                 uint32 *num_groups, DOM_GID *gid)
81 {
82         POLICY_HND pol_open_user;
83         if (pol_open_domain == NULL || num_groups == NULL || gid == NULL) return False;
84
85         /* send open domain (on user sid) */
86         if (!samr_open_user(cli,
87                                 pol_open_domain,
88                                 0x02011b, user_rid,
89                                 &pol_open_user))
90         {
91                 return False;
92         }
93
94         /* send user groups query */
95         if (!samr_query_usergroups(cli,
96                                 &pol_open_user,
97                                 num_groups, gid))
98         {
99                 DEBUG(5,("samr_query_usergroups: error in query user groups\n"));
100         }
101
102         return samr_close(cli, &pol_open_user);
103 }
104
105 /****************************************************************************
106 do a SAMR query user info
107 ****************************************************************************/
108 BOOL get_samr_query_userinfo(struct cli_state *cli, 
109                                 POLICY_HND *pol_open_domain,
110                                 uint32 info_level,
111                                 uint32 user_rid, SAM_USER_INFO_21 *usr)
112 {
113         POLICY_HND pol_open_user;
114         if (pol_open_domain == NULL || usr == NULL) return False;
115
116         bzero(usr, sizeof(*usr));
117
118         /* send open domain (on user sid) */
119         if (!samr_open_user(cli,
120                                 pol_open_domain,
121                                 0x02011b, user_rid,
122                                 &pol_open_user))
123         {
124                 return False;
125         }
126
127         /* send user info query */
128         if (!samr_query_userinfo(cli,
129                                 &pol_open_user,
130                                 info_level, (void*)usr))
131         {
132                 DEBUG(5,("samr_query_userinfo: error in query user info, level 0x%x\n",
133                           info_level));
134         }
135
136         return samr_close(cli, &pol_open_user);
137 }
138
139 /****************************************************************************
140 do a SAMR change user password command
141 ****************************************************************************/
142 BOOL samr_chgpasswd_user(struct cli_state *cli,
143                 char *srv_name, char *user_name,
144                 char nt_newpass[516], uchar nt_oldhash[16],
145                 char lm_newpass[516], uchar lm_oldhash[16])
146 {
147         prs_struct data;
148         prs_struct rdata;
149
150         SAMR_Q_CHGPASSWD_USER q_e;
151         BOOL valid_pwc = False;
152
153         /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
154
155         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
156         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
157
158         DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
159                 srv_name, user_name));
160
161         make_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
162                                    nt_newpass, nt_oldhash,
163                                    lm_newpass, lm_oldhash);
164
165         /* turn parameters into data stream */
166         samr_io_q_chgpasswd_user("", &q_e, &data, 0);
167
168         /* send the data on \PIPE\ */
169         if (rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &data, &rdata))
170         {
171                 SAMR_R_CHGPASSWD_USER r_e;
172                 BOOL p;
173
174                 samr_io_r_chgpasswd_user("", &r_e, &rdata, 0);
175
176                 p = rdata.offset != 0;
177                 if (p && r_e.status != 0)
178                 {
179                         /* report error code */
180                         DEBUG(0,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
181                         p = False;
182                 }
183
184                 if (p)
185                 {
186                         valid_pwc = True;
187                 }
188         }
189
190         prs_mem_free(&data   );
191         prs_mem_free(&rdata  );
192
193         return valid_pwc;
194 }
195
196 /****************************************************************************
197 do a SAMR unknown 0x38 command
198 ****************************************************************************/
199 BOOL samr_unknown_38(struct cli_state *cli, char *srv_name)
200 {
201         prs_struct data;
202         prs_struct rdata;
203
204         SAMR_Q_UNKNOWN_38 q_e;
205         BOOL valid_un8 = False;
206
207         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
208
209         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
210         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
211
212         DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name));
213
214         make_samr_q_unknown_38(&q_e, srv_name);
215
216         /* turn parameters into data stream */
217         samr_io_q_unknown_38("", &q_e, &data, 0);
218
219         /* send the data on \PIPE\ */
220         if (rpc_api_pipe_req(cli, SAMR_UNKNOWN_38, &data, &rdata))
221         {
222                 SAMR_R_UNKNOWN_38 r_e;
223                 BOOL p;
224
225                 samr_io_r_unknown_38("", &r_e, &rdata, 0);
226
227                 p = rdata.offset != 0;
228 #if 0
229                 if (p && r_e.status != 0)
230                 {
231                         /* report error code */
232                         DEBUG(0,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status)));
233                         p = False;
234                 }
235 #endif
236                 if (p)
237                 {
238                         valid_un8 = True;
239                 }
240         }
241
242         prs_mem_free(&data   );
243         prs_mem_free(&rdata  );
244
245         return valid_un8;
246 }
247
248 /****************************************************************************
249 do a SAMR unknown 0x8 command
250 ****************************************************************************/
251 BOOL samr_query_dom_info(struct cli_state *cli, 
252                                 POLICY_HND *domain_pol, uint16 switch_value)
253 {
254         prs_struct data;
255         prs_struct rdata;
256
257         SAMR_Q_QUERY_DOMAIN_INFO q_e;
258         BOOL valid_un8 = False;
259
260         DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
261
262         if (domain_pol == NULL) return False;
263
264         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
265
266         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
267         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
268
269         /* store the parameters */
270         make_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
271
272         /* turn parameters into data stream */
273         samr_io_q_query_dom_info("", &q_e, &data, 0);
274
275         /* send the data on \PIPE\ */
276         if (rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &data, &rdata))
277         {
278 #if 0
279                 SAMR_R_QUERY_DOMAIN_INFO r_e;
280                 BOOL p;
281
282                 samr_io_r_query_dom_info("", &r_e, &rdata, 0);
283
284                 p = rdata.offset != 0;
285                 if (p && r_e.status != 0)
286                 {
287                         /* report error code */
288                         DEBUG(0,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status)));
289                         p = False;
290                 }
291
292                 if (p)
293                 {
294                         valid_un8 = True;
295                 }
296 #endif
297         }
298
299         prs_mem_free(&data   );
300         prs_mem_free(&rdata  );
301
302         return valid_un8;
303 }
304
305 /****************************************************************************
306 do a SAMR enumerate users
307 ****************************************************************************/
308 BOOL samr_enum_dom_users(struct cli_state *cli, 
309                                 POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
310                                 uint16 acb_mask, uint16 unk_1, uint32 size,
311                                 struct acct_info **sam,
312                                 int *num_sam_users)
313 {
314         prs_struct data;
315         prs_struct rdata;
316
317         SAMR_Q_ENUM_DOM_USERS q_e;
318         BOOL valid_pol = False;
319
320         DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
321
322         if (pol == NULL || num_sam_users == NULL) return False;
323
324         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
325
326         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
327         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
328
329         /* store the parameters */
330         make_samr_q_enum_dom_users(&q_e, pol,
331                                    num_entries, unk_0,
332                                    acb_mask, unk_1, size);
333
334         /* turn parameters into data stream */
335         samr_io_q_enum_dom_users("", &q_e, &data, 0);
336
337         /* send the data on \PIPE\ */
338         if (rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &data, &rdata))
339         {
340                 SAMR_R_ENUM_DOM_USERS r_e;
341                 BOOL p;
342
343                 samr_io_r_enum_dom_users("", &r_e, &rdata, 0);
344
345                 p = rdata.offset != 0;
346                 if (p && r_e.status != 0)
347                 {
348                         /* report error code */
349                         DEBUG(0,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
350                         p = False;
351                 }
352
353                 if (p)
354                 {
355                         int i;
356                         int name_idx = 0;
357
358                         *num_sam_users = r_e.num_entries2;
359                         if (*num_sam_users > MAX_SAM_ENTRIES)
360                         {
361                                 *num_sam_users = MAX_SAM_ENTRIES;
362                                 DEBUG(2,("samr_enum_dom_users: sam user entries limited to %d\n",
363                                           *num_sam_users));
364                         }
365
366                         *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_users));
367                                     
368                         if ((*sam) == NULL)
369                         {
370                                 *num_sam_users = 0;
371                         }
372
373                         for (i = 0; i < *num_sam_users; i++)
374                         {
375
376                                 (*sam)[i].user_rid = r_e.sam[i].rid;
377                                 if (r_e.sam[i].hdr_name.buffer)
378                                 {
379                                         char *acct_name = unistrn2(r_e.uni_acct_name[name_idx].buffer,
380                                                                    r_e.uni_acct_name[name_idx].uni_str_len);
381                                         fstrcpy((*sam)[i].acct_name, acct_name);
382                                         name_idx++;
383                                 }
384                                 else
385                                 {
386                                         bzero((*sam)[i].acct_name, sizeof((*sam)[i].acct_name));
387                                 }
388                                 DEBUG(5,("samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
389                                           i, (*sam)[i].user_rid, (*sam)[i].acct_name));
390                         }
391                         valid_pol = True;
392                 }
393         }
394
395         prs_mem_free(&data   );
396         prs_mem_free(&rdata  );
397
398         return valid_pol;
399 }
400
401 /****************************************************************************
402 do a SAMR Connect
403 ****************************************************************************/
404 BOOL samr_connect(struct cli_state *cli, 
405                                 char *srv_name, uint32 unknown_0,
406                                 POLICY_HND *connect_pol)
407 {
408         prs_struct data;
409         prs_struct rdata;
410
411         SAMR_Q_CONNECT q_o;
412         BOOL valid_pol = False;
413
414         DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
415                                 srv_name, unknown_0));
416
417         if (srv_name == NULL || connect_pol == NULL) return False;
418
419         /* create and send a MSRPC command with api SAMR_CONNECT */
420
421         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
422         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
423
424         /* store the parameters */
425         make_samr_q_connect(&q_o, srv_name, unknown_0);
426
427         /* turn parameters into data stream */
428         samr_io_q_connect("", &q_o,  &data, 0);
429
430         /* send the data on \PIPE\ */
431         if (rpc_api_pipe_req(cli, SAMR_CONNECT, &data, &rdata))
432         {
433                 SAMR_R_CONNECT r_o;
434                 BOOL p;
435
436                 samr_io_r_connect("", &r_o, &rdata, 0);
437                 p = rdata.offset != 0;
438                 
439                 if (p && r_o.status != 0)
440                 {
441                         /* report error code */
442                         DEBUG(0,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
443                         p = False;
444                 }
445
446                 if (p)
447                 {
448                         memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
449                         valid_pol = True;
450                 }
451         }
452
453         prs_mem_free(&data   );
454         prs_mem_free(&rdata  );
455
456         return valid_pol;
457 }
458
459 /****************************************************************************
460 do a SAMR Open User
461 ****************************************************************************/
462 BOOL samr_open_user(struct cli_state *cli, 
463                                 POLICY_HND *pol, uint32 unk_0, uint32 rid, 
464                                 POLICY_HND *user_pol)
465 {
466         prs_struct data;
467         prs_struct rdata;
468
469         SAMR_Q_OPEN_USER q_o;
470         BOOL valid_pol = False;
471
472         DEBUG(4,("SAMR Open User.  unk_0: %08x RID:%x\n",
473                   unk_0, rid));
474
475         if (pol == NULL || user_pol == NULL) return False;
476
477         /* create and send a MSRPC command with api SAMR_OPEN_USER */
478
479         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
480         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
481
482         /* store the parameters */
483         make_samr_q_open_user(&q_o, pol, unk_0, rid);
484
485         /* turn parameters into data stream */
486         samr_io_q_open_user("", &q_o,  &data, 0);
487
488         /* send the data on \PIPE\ */
489         if (rpc_api_pipe_req(cli, SAMR_OPEN_USER, &data, &rdata))
490         {
491                 SAMR_R_OPEN_USER r_o;
492                 BOOL p;
493
494                 samr_io_r_open_user("", &r_o, &rdata, 0);
495                 p = rdata.offset != 0;
496                 
497                 if (p && r_o.status != 0)
498                 {
499                         /* report error code */
500                         DEBUG(0,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
501                         p = False;
502                 }
503
504                 if (p)
505                 {
506                         memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
507                         valid_pol = True;
508                 }
509         }
510
511         prs_mem_free(&data   );
512         prs_mem_free(&rdata  );
513
514         return valid_pol;
515 }
516
517 /****************************************************************************
518 do a SAMR Open Group
519 ****************************************************************************/
520 BOOL samr_open_group(struct cli_state *cli, 
521                                 POLICY_HND *domain_pol, uint32 rid,
522                                 POLICY_HND *group_pol)
523 {
524         prs_struct data;
525         prs_struct rdata;
526
527         SAMR_Q_OPEN_GROUP q_o;
528         BOOL valid_pol = False;
529
530         DEBUG(4,("SAMR Open Group. RID:%x\n", rid));
531
532         if (group_pol == NULL || domain_pol == NULL) return False;
533
534         /* create and send a MSRPC command with api SAMR_OPEN_GROUP */
535
536         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
537         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
538
539         /* store the parameters */
540         make_samr_q_open_group(&q_o, domain_pol, 0x0001, rid);
541
542         /* turn parameters into data stream */
543         samr_io_q_open_group("", &q_o,  &data, 0);
544
545         /* send the data on \PIPE\ */
546         if (rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &data, &rdata))
547         {
548                 SAMR_R_OPEN_GROUP r_o;
549                 BOOL p;
550
551                 samr_io_r_open_group("", &r_o, &rdata, 0);
552                 p = rdata.offset != 0;
553
554                 if (p && r_o.status != 0)
555                 {
556                         /* report error code */
557                         DEBUG(0,("SAMR_R_OPEN_GROUP: %s\n", get_nt_error_msg(r_o.status)));
558                         p = False;
559                 }
560
561                 if (p)
562                 {
563                         memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
564                         valid_pol = True;
565                 }
566         }
567
568         prs_mem_free(&data   );
569         prs_mem_free(&rdata  );
570
571         return valid_pol;
572 }
573
574 /****************************************************************************
575 do a SAMR Create Domain Group
576 ****************************************************************************/
577 BOOL samr_create_dom_group(struct cli_state *cli, 
578                                 POLICY_HND *domain_pol, const char *acct_name,
579                                 POLICY_HND *group_pol, uint32 *rid)
580 {
581         prs_struct data;
582         prs_struct rdata;
583
584         SAMR_Q_CREATE_DOM_GROUP q_o;
585         BOOL valid_pol = False;
586
587         if (group_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
588
589         /* create and send a MSRPC command with api SAMR_CREATE_DOM_GROUP */
590
591         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
592         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
593
594         DEBUG(4,("SAMR Create Domain Group. Name:%s\n", acct_name));
595
596         /* store the parameters */
597         make_samr_q_create_dom_group(&q_o, domain_pol, acct_name);
598
599         /* turn parameters into data stream */
600         samr_io_q_create_dom_group("", &q_o,  &data, 0);
601
602         /* send the data on \PIPE\ */
603         if (rpc_api_pipe_req(cli, SAMR_CREATE_DOM_GROUP, &data, &rdata))
604         {
605                 SAMR_R_CREATE_DOM_GROUP r_o;
606                 BOOL p;
607
608                 samr_io_r_create_dom_group("", &r_o, &rdata, 0);
609                 p = rdata.offset != 0;
610
611                 if (p && r_o.status != 0)
612                 {
613                         /* report error code */
614                         DEBUG(0,("SAMR_R_CREATE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
615                         p = False;
616                 }
617
618                 if (p)
619                 {
620                         memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
621                         *rid = r_o.rid;
622                         valid_pol = True;
623                 }
624         }
625
626         prs_mem_free(&data   );
627         prs_mem_free(&rdata  );
628
629         return valid_pol;
630 }
631
632 /****************************************************************************
633 do a SAMR Set Group Info
634 ****************************************************************************/
635 BOOL samr_set_groupinfo(struct cli_state *cli, 
636                                 POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
637 {
638         prs_struct data;
639         prs_struct rdata;
640
641         SAMR_Q_SET_GROUPINFO q_o;
642         BOOL valid_pol = False;
643
644         if (group_pol == NULL || ctr == NULL) return False;
645
646         /* create and send a MSRPC command with api SAMR_SET_GROUPINFO */
647
648         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
649         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
650
651         DEBUG(4,("SAMR Set Group Info\n"));
652
653         /* store the parameters */
654         make_samr_q_set_groupinfo(&q_o, group_pol, ctr);
655
656         /* turn parameters into data stream */
657         samr_io_q_set_groupinfo("", &q_o,  &data, 0);
658
659         /* send the data on \PIPE\ */
660         if (rpc_api_pipe_req(cli, SAMR_SET_GROUPINFO, &data, &rdata))
661         {
662                 SAMR_R_SET_GROUPINFO r_o;
663                 BOOL p;
664
665                 samr_io_r_set_groupinfo("", &r_o, &rdata, 0);
666                 p = rdata.offset != 0;
667
668                 if (p && r_o.status != 0)
669                 {
670                         /* report error code */
671                         DEBUG(0,("SAMR_R_SET_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
672                         p = False;
673                 }
674
675                 if (p)
676                 {
677                         valid_pol = True;
678                 }
679         }
680
681         prs_mem_free(&data   );
682         prs_mem_free(&rdata  );
683
684         return valid_pol;
685 }
686
687 /****************************************************************************
688 do a SAMR Open Domain
689 ****************************************************************************/
690 BOOL samr_open_domain(struct cli_state *cli, 
691                                 POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
692                                 POLICY_HND *domain_pol)
693 {
694         pstring sid_str;
695         prs_struct data;
696         prs_struct rdata;
697
698         SAMR_Q_OPEN_DOMAIN q_o;
699         BOOL valid_pol = False;
700
701         sid_to_string(sid_str, sid);
702         DEBUG(4,("SAMR Open Domain.  SID:%s RID:%x\n", sid_str, rid));
703
704         if (connect_pol == NULL || sid == NULL || domain_pol == NULL) return False;
705
706         /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
707
708         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
709         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
710
711         /* store the parameters */
712         make_samr_q_open_domain(&q_o, connect_pol, rid, sid);
713
714         /* turn parameters into data stream */
715         samr_io_q_open_domain("", &q_o,  &data, 0);
716
717         /* send the data on \PIPE\ */
718         if (rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &data, &rdata))
719         {
720                 SAMR_R_OPEN_DOMAIN r_o;
721                 BOOL p;
722
723                 samr_io_r_open_domain("", &r_o, &rdata, 0);
724                 p = rdata.offset != 0;
725
726                 if (p && r_o.status != 0)
727                 {
728                         /* report error code */
729                         DEBUG(0,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
730                         p = False;
731                 }
732
733                 if (p)
734                 {
735                         memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
736                         valid_pol = True;
737                 }
738         }
739
740         prs_mem_free(&data   );
741         prs_mem_free(&rdata  );
742
743         return valid_pol;
744 }
745
746 /****************************************************************************
747 do a SAMR Query Unknown 12
748 ****************************************************************************/
749 BOOL samr_query_unknown_12(struct cli_state *cli, 
750                                 POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
751                                 uint32 *num_names,
752                                 fstring names[MAX_LOOKUP_SIDS],
753                                 uint32  type [MAX_LOOKUP_SIDS])
754 {
755         prs_struct data;
756         prs_struct rdata;
757
758         SAMR_Q_UNKNOWN_12 q_o;
759         BOOL valid_query = False;
760
761         if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL ||
762             num_names == NULL || names == NULL || type == NULL ) return False;
763
764         /* create and send a MSRPC command with api SAMR_UNKNOWN_12 */
765
766         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
767         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
768
769         DEBUG(4,("SAMR Query Unknown 12.\n"));
770
771         /* store the parameters */
772         make_samr_q_unknown_12(&q_o, pol, rid, num_gids, gids);
773
774         /* turn parameters into data stream */
775         samr_io_q_unknown_12("", &q_o,  &data, 0);
776
777         /* send the data on \PIPE\ */
778         if (rpc_api_pipe_req(cli, SAMR_UNKNOWN_12, &data, &rdata))
779         {
780                 SAMR_R_UNKNOWN_12 r_o;
781                 BOOL p;
782
783                 samr_io_r_unknown_12("", &r_o, &rdata, 0);
784                 p = rdata.offset != 0;
785                 
786                 if (p && r_o.status != 0)
787                 {
788                         /* report error code */
789                         DEBUG(0,("SAMR_R_UNKNOWN_12: %s\n", get_nt_error_msg(r_o.status)));
790                         p = False;
791                 }
792
793                 if (p)
794                 {
795                         if (r_o.ptr_names != 0 && r_o.ptr_types != 0 &&
796                             r_o.num_types1 == r_o.num_names1)
797                         {
798                                 int i;
799
800                                 valid_query = True;
801                                 *num_names = r_o.num_names1;
802
803                                 for (i = 0; i < r_o.num_names1; i++)
804                                 {
805                                         fstrcpy(names[i], unistr2_to_str(&r_o.uni_name[i]));
806                                 }
807                                 for (i = 0; i < r_o.num_types1; i++)
808                                 {
809                                         type[i] = r_o.type[i];
810                                 }
811                         }
812                         else if (r_o.ptr_names == 0 && r_o.ptr_types == 0)
813                         {
814                                 valid_query = True;
815                                 *num_names = 0;
816                         }
817                         else
818                         {
819                                 p = False;
820                         }
821                 }
822         }
823
824         prs_mem_free(&data   );
825         prs_mem_free(&rdata  );
826
827         return valid_query;
828 }
829
830 /****************************************************************************
831 do a SAMR Query User Aliases
832 ****************************************************************************/
833 BOOL samr_query_useraliases(struct cli_state *cli, 
834                                 POLICY_HND *pol, DOM_SID *sid,
835                                 uint32 *num_aliases, uint32 *rid)
836 {
837         prs_struct data;
838         prs_struct rdata;
839
840         SAMR_Q_QUERY_USERALIASES q_o;
841         BOOL valid_query = False;
842
843         DEBUG(4,("SAMR Query User Aliases.\n"));
844
845         if (pol == NULL || sid == NULL || rid == NULL || num_aliases == 0) return False;
846
847         /* create and send a MSRPC command with api SAMR_QUERY_USERALIASES */
848
849         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
850         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
851
852         /* store the parameters */
853         make_samr_q_query_useraliases(&q_o, pol, sid);
854
855         /* turn parameters into data stream */
856         samr_io_q_query_useraliases("", &q_o,  &data, 0);
857
858         /* send the data on \PIPE\ */
859         if (rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &data, &rdata))
860         {
861                 SAMR_R_QUERY_USERALIASES r_o;
862                 BOOL p;
863
864                 /* get user info */
865                 r_o.rid = rid;
866
867                 samr_io_r_query_useraliases("", &r_o, &rdata, 0);
868                 p = rdata.offset != 0;
869                 
870                 if (p && r_o.status != 0)
871                 {
872                         /* report error code */
873                         DEBUG(0,("SAMR_R_QUERY_USERALIASES: %s\n", get_nt_error_msg(r_o.status)));
874                         p = False;
875                 }
876
877                 if (p && r_o.ptr != 0)
878                 {
879                         valid_query = True;
880                         *num_aliases = r_o.num_entries;
881                 }
882
883         }
884
885         prs_mem_free(&data   );
886         prs_mem_free(&rdata  );
887
888         return valid_query;
889 }
890
891 /****************************************************************************
892 do a SAMR Query User Groups
893 ****************************************************************************/
894 BOOL samr_query_usergroups(struct cli_state *cli, 
895                                 POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid)
896 {
897         prs_struct data;
898         prs_struct rdata;
899
900         SAMR_Q_QUERY_USERGROUPS q_o;
901         BOOL valid_query = False;
902
903         DEBUG(4,("SAMR Query User Groups.\n"));
904
905         if (pol == NULL || gid == NULL || num_groups == 0) return False;
906
907         /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
908
909         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
910         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
911
912         /* store the parameters */
913         make_samr_q_query_usergroups(&q_o, pol);
914
915         /* turn parameters into data stream */
916         samr_io_q_query_usergroups("", &q_o,  &data, 0);
917
918         /* send the data on \PIPE\ */
919         if (rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &data, &rdata))
920         {
921                 SAMR_R_QUERY_USERGROUPS r_o;
922                 BOOL p;
923
924                 /* get user info */
925                 r_o.gid = gid;
926
927                 samr_io_r_query_usergroups("", &r_o, &rdata, 0);
928                 p = rdata.offset != 0;
929                 
930                 if (p && r_o.status != 0)
931                 {
932                         /* report error code */
933                         DEBUG(0,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
934                         p = False;
935                 }
936
937                 if (p && r_o.ptr_0 != 0)
938                 {
939                         valid_query = True;
940                         *num_groups = r_o.num_entries;
941                 }
942
943         }
944
945         prs_mem_free(&data   );
946         prs_mem_free(&rdata  );
947
948         return valid_query;
949 }
950
951 /****************************************************************************
952 do a SAMR Query User Info
953 ****************************************************************************/
954 BOOL samr_query_userinfo(struct cli_state *cli, 
955                                 POLICY_HND *pol, uint16 switch_value, void* usr)
956 {
957         prs_struct data;
958         prs_struct rdata;
959
960         SAMR_Q_QUERY_USERINFO q_o;
961         BOOL valid_query = False;
962
963         DEBUG(4,("SAMR Query User Info.  level: %d\n", switch_value));
964
965         if (pol == NULL || usr == NULL || switch_value == 0) return False;
966
967         /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
968
969         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
970         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
971
972         /* store the parameters */
973         make_samr_q_query_userinfo(&q_o, pol, switch_value);
974
975         /* turn parameters into data stream */
976         samr_io_q_query_userinfo("", &q_o,  &data, 0);
977
978         /* send the data on \PIPE\ */
979         if (rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &data, &rdata))
980         {
981                 SAMR_R_QUERY_USERINFO r_o;
982                 BOOL p;
983
984                 /* get user info */
985                 r_o.info.id = usr;
986
987                 samr_io_r_query_userinfo("", &r_o, &rdata, 0);
988                 p = rdata.offset != 0;
989                 
990                 if (p && r_o.status != 0)
991                 {
992                         /* report error code */
993                         DEBUG(0,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
994                         p = False;
995                 }
996
997                 if (p && r_o.switch_value != switch_value)
998                 {
999                         DEBUG(0,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
1000                                   r_o.switch_value));
1001                 }
1002
1003                 if (p && r_o.ptr != 0)
1004                 {
1005                         valid_query = True;
1006                 }
1007         }
1008
1009         prs_mem_free(&data   );
1010         prs_mem_free(&rdata  );
1011
1012         return valid_query;
1013 }
1014
1015 /****************************************************************************
1016 do a SAMR Close
1017 ****************************************************************************/
1018 BOOL samr_close(struct cli_state *cli, POLICY_HND *hnd)
1019 {
1020         prs_struct data;
1021         prs_struct rdata;
1022
1023         SAMR_Q_CLOSE_HND q_c;
1024         BOOL valid_close = False;
1025
1026         DEBUG(4,("SAMR Close\n"));
1027
1028         if (hnd == NULL) return False;
1029
1030         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1031         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1032
1033         /* create and send a MSRPC command with api SAMR_CLOSE_HND */
1034
1035         /* store the parameters */
1036         make_samr_q_close_hnd(&q_c, hnd);
1037
1038         /* turn parameters into data stream */
1039         samr_io_q_close_hnd("", &q_c,  &data, 0);
1040
1041         /* send the data on \PIPE\ */
1042         if (rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &data, &rdata))
1043         {
1044                 SAMR_R_CLOSE_HND r_c;
1045                 BOOL p;
1046
1047                 samr_io_r_close_hnd("", &r_c, &rdata, 0);
1048                 p = rdata.offset != 0;
1049
1050                 if (p && r_c.status != 0)
1051                 {
1052                         /* report error code */
1053                         DEBUG(0,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
1054                         p = False;
1055                 }
1056
1057                 if (p)
1058                 {
1059                         /* check that the returned policy handle is all zeros */
1060                         int i;
1061                         valid_close = True;
1062
1063                         for (i = 0; i < sizeof(r_c.pol.data); i++)
1064                         {
1065                                 if (r_c.pol.data[i] != 0)
1066                                 {
1067                                         valid_close = False;
1068                                         break;
1069                                 }
1070                         }       
1071                         if (!valid_close)
1072                         {
1073                                 DEBUG(0,("SAMR_CLOSE_HND: non-zero handle returned\n"));
1074                         }
1075                 }
1076         }
1077
1078         prs_mem_free(&data   );
1079         prs_mem_free(&rdata  );
1080
1081         return valid_close;
1082 }
1083