7c89dfcc02dda74ab86b80f6a2f0121b4ac53198
[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 create domain alias
38 ****************************************************************************/
39 BOOL create_samr_domain_alias(struct cli_state *cli, uint16 fnum, 
40                                 POLICY_HND *pol_open_domain,
41                                 const char *acct_name, const char *acct_desc,
42                                 uint32 *rid)
43 {
44         POLICY_HND pol_open_alias;
45         ALIAS_INFO_CTR ctr;
46         BOOL ret = True;
47
48         if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
49
50         /* send create alias */
51         if (!samr_create_dom_alias(cli, fnum,
52                                 pol_open_domain,
53                                 acct_name,
54                                 &pol_open_alias, rid))
55         {
56                 return False;
57         }
58
59         DEBUG(5,("create_samr_domain_alias: name: %s rid 0x%x\n",
60                   acct_name, *rid));
61
62         ctr.switch_value1 = 3;
63         make_samr_alias_info3(&ctr.alias.info3, acct_desc);
64
65         /* send set alias info */
66         if (!samr_set_aliasinfo(cli, fnum,
67                                 &pol_open_alias,
68                                 &ctr))
69         {
70                 DEBUG(5,("create_samr_domain_alias: error in samr_set_aliasinfo\n"));
71                 ret = False;
72         }
73
74         return samr_close(cli, fnum,&pol_open_alias) && ret;
75 }
76
77 /****************************************************************************
78 do a SAMR create domain group
79 ****************************************************************************/
80 BOOL create_samr_domain_group(struct cli_state *cli, uint16 fnum, 
81                                 POLICY_HND *pol_open_domain,
82                                 const char *acct_name, const char *acct_desc,
83                                 uint32 *rid)
84 {
85         POLICY_HND pol_open_group;
86         GROUP_INFO_CTR ctr;
87         BOOL ret = True;
88
89         if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
90
91         /* send create group*/
92         if (!samr_create_dom_group(cli, fnum,
93                                 pol_open_domain,
94                                 acct_name,
95                                 &pol_open_group, rid))
96         {
97                 return False;
98         }
99
100         DEBUG(5,("create_samr_domain_group: name: %s rid 0x%x\n",
101                   acct_name, *rid));
102
103         ctr.switch_value1 = 4;
104         ctr.switch_value2 = 4;
105         make_samr_group_info4(&ctr.group.info4, acct_desc);
106
107         /* send user groups query */
108         if (!samr_set_groupinfo(cli, fnum,
109                                 &pol_open_group,
110                                 &ctr))
111         {
112                 DEBUG(5,("create_samr_domain_group: error in samr_set_groupinfo\n"));
113                 ret = False;
114         }
115
116         return samr_close(cli, fnum,&pol_open_group) && ret;
117 }
118
119 /****************************************************************************
120 do a SAMR query user groups
121 ****************************************************************************/
122 BOOL get_samr_query_usergroups(struct cli_state *cli, uint16 fnum, 
123                                 POLICY_HND *pol_open_domain, uint32 user_rid,
124                                 uint32 *num_groups, DOM_GID *gid)
125 {
126         POLICY_HND pol_open_user;
127         BOOL ret = True;
128
129         if (pol_open_domain == NULL || num_groups == NULL || gid == NULL) return False;
130
131         /* send open domain (on user sid) */
132         if (!samr_open_user(cli, fnum,
133                                 pol_open_domain,
134                                 0x02011b, user_rid,
135                                 &pol_open_user))
136         {
137                 return False;
138         }
139
140         /* send user groups query */
141         if (!samr_query_usergroups(cli, fnum,
142                                 &pol_open_user,
143                                 num_groups, gid))
144         {
145                 DEBUG(5,("samr_query_usergroups: error in query user groups\n"));
146                 ret = False;
147         }
148
149         return samr_close(cli, fnum,&pol_open_user) && ret;
150 }
151
152 /****************************************************************************
153 do a SAMR delete group 
154 ****************************************************************************/
155 BOOL delete_samr_dom_group(struct cli_state *cli, uint16 fnum, 
156                                 POLICY_HND *pol_open_domain,
157                                 uint32 group_rid)
158 {
159         POLICY_HND pol_open_group;
160
161         if (pol_open_domain == NULL) return False;
162
163         /* send open domain (on group rid) */
164         if (!samr_open_group(cli, fnum,pol_open_domain,
165                                 0x00000010, group_rid,
166                                 &pol_open_group))
167         {
168                 return False;
169         }
170
171         /* send group delete */
172         if (!samr_delete_dom_group(cli, fnum,&pol_open_group))
173                                 
174         {
175                 DEBUG(5,("delete_samr_dom_group: error in delete domain group\n"));
176                 samr_close(cli, fnum,&pol_open_group);
177                 return False;
178         }
179
180         return True;
181 }
182
183
184 /****************************************************************************
185 do a SAMR query group members 
186 ****************************************************************************/
187 BOOL get_samr_query_groupmem(struct cli_state *cli, uint16 fnum, 
188                                 POLICY_HND *pol_open_domain,
189                                 uint32 group_rid, uint32 *num_mem,
190                                 uint32 *rid, uint32 *attr)
191 {
192         POLICY_HND pol_open_group;
193         BOOL ret = True;
194
195         if (pol_open_domain == NULL || num_mem == NULL || rid == NULL || attr == NULL) return False;
196
197         /* send open domain (on group sid) */
198         if (!samr_open_group(cli, fnum,pol_open_domain,
199                                 0x00000010, group_rid,
200                                 &pol_open_group))
201         {
202                 return False;
203         }
204
205         /* send group info query */
206         if (!samr_query_groupmem(cli, fnum,&pol_open_group, num_mem, rid, attr))
207                                 
208         {
209                 DEBUG(5,("samr_query_group: error in query group members\n"));
210                 ret = False;
211         }
212
213         return samr_close(cli, fnum,&pol_open_group) && ret;
214 }
215
216 /****************************************************************************
217 do a SAMR delete alias 
218 ****************************************************************************/
219 BOOL delete_samr_dom_alias(struct cli_state *cli, uint16 fnum, 
220                                 POLICY_HND *pol_open_domain,
221                                 uint32 alias_rid)
222 {
223         POLICY_HND pol_open_alias;
224
225         if (pol_open_domain == NULL) return False;
226
227         /* send open domain (on alias rid) */
228         if (!samr_open_alias(cli, fnum,pol_open_domain,
229                                 0x000f001f, alias_rid, &pol_open_alias))
230         {
231                 return False;
232         }
233
234         /* send alias delete */
235         if (!samr_delete_dom_alias(cli, fnum,&pol_open_alias))
236                                 
237         {
238                 DEBUG(5,("delete_samr_dom_alias: error in delete domain alias\n"));
239                 samr_close(cli, fnum,&pol_open_alias);
240                 return False;
241         }
242
243         return True;
244 }
245
246
247 /****************************************************************************
248 do a SAMR query alias members 
249 ****************************************************************************/
250 BOOL get_samr_query_aliasmem(struct cli_state *cli, uint16 fnum, 
251                                 POLICY_HND *pol_open_domain,
252                                 uint32 alias_rid, uint32 *num_mem, DOM_SID2 *sid)
253 {
254         POLICY_HND pol_open_alias;
255         BOOL ret = True;
256
257         if (pol_open_domain == NULL || num_mem == NULL || sid == NULL) return False;
258
259         /* send open domain (on alias sid) */
260         if (!samr_open_alias(cli, fnum, pol_open_domain,
261                                 0x000f001f, alias_rid,
262                                 &pol_open_alias))
263         {
264                 return False;
265         }
266
267         /* send alias info query */
268         if (!samr_query_aliasmem(cli, fnum, &pol_open_alias, num_mem, sid))
269                                 
270         {
271                 DEBUG(5,("samr_query_alias: error in query alias members\n"));
272                 ret = False;
273         }
274
275         return samr_close(cli, fnum,&pol_open_alias) && ret;
276 }
277
278 /****************************************************************************
279 do a SAMR query user info
280 ****************************************************************************/
281 BOOL get_samr_query_userinfo(struct cli_state *cli, uint16 fnum, 
282                                 POLICY_HND *pol_open_domain,
283                                 uint32 info_level,
284                                 uint32 user_rid, SAM_USER_INFO_21 *usr)
285 {
286         POLICY_HND pol_open_user;
287         BOOL ret = True;
288
289         if (pol_open_domain == NULL || usr == NULL) return False;
290
291         bzero(usr, sizeof(*usr));
292
293         /* send open domain (on user sid) */
294         if (!samr_open_user(cli, fnum,
295                                 pol_open_domain,
296                                 0x02011b, user_rid,
297                                 &pol_open_user))
298         {
299                 return False;
300         }
301
302         /* send user info query */
303         if (!samr_query_userinfo(cli, fnum,
304                                 &pol_open_user,
305                                 info_level, (void*)usr))
306         {
307                 DEBUG(5,("samr_query_userinfo: error in query user info, level 0x%x\n",
308                           info_level));
309                 ret = False;
310         }
311
312         return samr_close(cli, fnum,&pol_open_user) && ret;
313 }
314
315 /****************************************************************************
316 do a SAMR query group info
317 ****************************************************************************/
318 BOOL get_samr_query_groupinfo(struct cli_state *cli, uint16 fnum, 
319                                 POLICY_HND *pol_open_domain,
320                                 uint32 info_level,
321                                 uint32 group_rid, GROUP_INFO_CTR *ctr)
322 {
323         POLICY_HND pol_open_group;
324         BOOL ret = True;
325
326         if (pol_open_domain == NULL || ctr == NULL) return False;
327
328         bzero(ctr, sizeof(*ctr));
329
330         /* send open domain (on group sid) */
331         if (!samr_open_group(cli, fnum,
332                                 pol_open_domain,
333                                 0x00000010, group_rid, &pol_open_group))
334         {
335                 return False;
336         }
337
338         /* send group info query */
339         if (!samr_query_groupinfo(cli, fnum,
340                                 &pol_open_group,
341                                 info_level, ctr))
342         {
343                 DEBUG(5,("samr_query_groupinfo: error in query group info, level 0x%x\n",
344                           info_level));
345                 ret = False;
346         }
347
348         return samr_close(cli, fnum,&pol_open_group) && ret;
349 }
350
351 /****************************************************************************
352 do a SAMR change user password command
353 ****************************************************************************/
354 BOOL samr_chgpasswd_user(struct cli_state *cli, uint16 fnum,
355                 char *srv_name, char *user_name,
356                 char nt_newpass[516], uchar nt_oldhash[16],
357                 char lm_newpass[516], uchar lm_oldhash[16])
358 {
359         prs_struct data;
360         prs_struct rdata;
361
362         SAMR_Q_CHGPASSWD_USER q_e;
363         BOOL valid_pwc = False;
364
365         /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
366
367         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
368         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
369
370         DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
371                 srv_name, user_name));
372
373         make_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
374                                    nt_newpass, nt_oldhash,
375                                    lm_newpass, lm_oldhash);
376
377         /* turn parameters into data stream */
378         samr_io_q_chgpasswd_user("", &q_e, &data, 0);
379
380         /* send the data on \PIPE\ */
381         if (rpc_api_pipe_req(cli, fnum, SAMR_CHGPASSWD_USER, &data, &rdata))
382         {
383                 SAMR_R_CHGPASSWD_USER r_e;
384                 BOOL p;
385
386                 samr_io_r_chgpasswd_user("", &r_e, &rdata, 0);
387
388                 p = rdata.offset != 0;
389                 if (p && r_e.status != 0)
390                 {
391                         /* report error code */
392                         DEBUG(0,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
393                         p = False;
394                 }
395
396                 if (p)
397                 {
398                         valid_pwc = True;
399                 }
400         }
401
402         prs_mem_free(&data   );
403         prs_mem_free(&rdata  );
404
405         return valid_pwc;
406 }
407
408 /****************************************************************************
409 do a SAMR unknown 0x38 command
410 ****************************************************************************/
411 BOOL samr_unknown_38(struct cli_state *cli, uint16 fnum, char *srv_name)
412 {
413         prs_struct data;
414         prs_struct rdata;
415
416         SAMR_Q_UNKNOWN_38 q_e;
417         BOOL valid_un8 = False;
418
419         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
420
421         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
422         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
423
424         DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name));
425
426         make_samr_q_unknown_38(&q_e, srv_name);
427
428         /* turn parameters into data stream */
429         samr_io_q_unknown_38("", &q_e, &data, 0);
430
431         /* send the data on \PIPE\ */
432         if (rpc_api_pipe_req(cli, fnum, SAMR_UNKNOWN_38, &data, &rdata))
433         {
434                 SAMR_R_UNKNOWN_38 r_e;
435                 BOOL p;
436
437                 samr_io_r_unknown_38("", &r_e, &rdata, 0);
438
439                 p = rdata.offset != 0;
440 #if 0
441                 if (p && r_e.status != 0)
442                 {
443                         /* report error code */
444                         DEBUG(0,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status)));
445                         p = False;
446                 }
447 #endif
448                 if (p)
449                 {
450                         valid_un8 = True;
451                 }
452         }
453
454         prs_mem_free(&data   );
455         prs_mem_free(&rdata  );
456
457         return valid_un8;
458 }
459
460 /****************************************************************************
461 do a SAMR unknown 0x8 command
462 ****************************************************************************/
463 BOOL samr_query_dom_info(struct cli_state *cli, uint16 fnum, 
464                                 POLICY_HND *domain_pol, uint16 switch_value)
465 {
466         prs_struct data;
467         prs_struct rdata;
468
469         SAMR_Q_QUERY_DOMAIN_INFO q_e;
470         BOOL valid_un8 = False;
471
472         DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
473
474         if (domain_pol == NULL) return False;
475
476         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
477
478         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
479         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
480
481         /* store the parameters */
482         make_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
483
484         /* turn parameters into data stream */
485         samr_io_q_query_dom_info("", &q_e, &data, 0);
486
487         /* send the data on \PIPE\ */
488         if (rpc_api_pipe_req(cli, fnum, SAMR_QUERY_DOMAIN_INFO, &data, &rdata))
489         {
490                 SAMR_R_QUERY_DOMAIN_INFO r_e;
491                 BOOL p;
492
493                 samr_io_r_query_dom_info("", &r_e, &rdata, 0);
494
495                 p = rdata.offset != 0;
496                 if (p && r_e.status != 0)
497                 {
498                         /* report error code */
499                         DEBUG(0,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status)));
500                         p = False;
501                 }
502
503                 if (p)
504                 {
505                         valid_un8 = True;
506                 }
507         }
508
509         prs_mem_free(&data   );
510         prs_mem_free(&rdata  );
511
512         return valid_un8;
513 }
514
515 /****************************************************************************
516 do a SAMR enumerate groups
517 ****************************************************************************/
518 BOOL samr_enum_dom_groups(struct cli_state *cli, uint16 fnum, 
519                                 POLICY_HND *pol, uint32 size,
520                                 struct acct_info **sam,
521                                 int *num_sam_groups)
522 {
523         prs_struct data;
524         prs_struct rdata;
525
526         SAMR_Q_ENUM_DOM_GROUPS q_e;
527         BOOL valid_pol = False;
528
529         DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
530
531         if (pol == NULL || num_sam_groups == NULL) return False;
532
533         /* create and send a MSRPC command with api SAMR_ENUM_DOM_GROUPS */
534
535         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
536         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
537
538         /* store the parameters */
539         make_samr_q_enum_dom_groups(&q_e, pol, 3, 0, size);
540
541         /* turn parameters into data stream */
542         samr_io_q_enum_dom_groups("", &q_e, &data, 0);
543
544         /* send the data on \PIPE\ */
545         if (rpc_api_pipe_req(cli, fnum, SAMR_ENUM_DOM_GROUPS, &data, &rdata))
546         {
547                 SAMR_R_ENUM_DOM_GROUPS r_e;
548                 BOOL p;
549
550                 samr_io_r_enum_dom_groups("", &r_e, &rdata, 0);
551
552                 p = rdata.offset != 0;
553                 if (p && r_e.status != 0)
554                 {
555                         /* report error code */
556                         DEBUG(0,("SAMR_R_ENUM_DOM_GROUPS: %s\n", get_nt_error_msg(r_e.status)));
557                         p = False;
558                 }
559
560                 if (p)
561                 {
562                         int i;
563                         int name_idx = 0;
564                         int desc_idx = 0;
565
566                         *num_sam_groups = r_e.num_entries2;
567                         if (*num_sam_groups > MAX_SAM_ENTRIES)
568                         {
569                                 *num_sam_groups = MAX_SAM_ENTRIES;
570                                 DEBUG(2,("samr_enum_dom_groups: sam user entries limited to %d\n",
571                                           *num_sam_groups));
572                         }
573
574                         *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_groups));
575                                     
576                         if ((*sam) == NULL)
577                         {
578                                 *num_sam_groups = 0;
579                         }
580
581                         for (i = 0; i < *num_sam_groups; i++)
582                         {
583                                 (*sam)[i].rid = r_e.sam[i].rid_grp;
584                                 (*sam)[i].acct_name[0] = 0;
585                                 (*sam)[i].acct_desc[0] = 0;
586                                 if (r_e.sam[i].hdr_grp_name.buffer)
587                                 {
588                                         fstrcpy((*sam)[i].acct_name, unistr2_to_str(&r_e.str[name_idx].uni_grp_name));
589                                         name_idx++;
590                                 }
591                                 if (r_e.sam[i].hdr_grp_desc.buffer)
592                                 {
593                                         fstrcpy((*sam)[i].acct_desc, unistr2_to_str(&r_e.str[desc_idx].uni_grp_desc));
594                                         desc_idx++;
595                                 }
596                                 DEBUG(5,("samr_enum_dom_groups: idx: %4d rid: %8x acct: %s desc: %s\n",
597                                           i, (*sam)[i].rid, (*sam)[i].acct_name, (*sam)[i].acct_desc));
598                         }
599                         valid_pol = True;
600                 }
601         }
602
603         prs_mem_free(&data   );
604         prs_mem_free(&rdata  );
605
606         return valid_pol;
607 }
608
609 /****************************************************************************
610 do a SAMR enumerate aliases
611 ****************************************************************************/
612 BOOL samr_enum_dom_aliases(struct cli_state *cli, uint16 fnum, 
613                                 POLICY_HND *pol, uint32 size,
614                                 struct acct_info **sam,
615                                 int *num_sam_aliases)
616 {
617         prs_struct data;
618         prs_struct rdata;
619
620         SAMR_Q_ENUM_DOM_ALIASES q_e;
621         BOOL valid_pol = False;
622
623         DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
624
625         if (pol == NULL || num_sam_aliases == NULL) return False;
626
627         /* create and send a MSRPC command with api SAMR_ENUM_DOM_ALIASES */
628
629         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
630         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
631
632         /* store the parameters */
633         make_samr_q_enum_dom_aliases(&q_e, pol, size);
634
635         /* turn parameters into data stream */
636         samr_io_q_enum_dom_aliases("", &q_e, &data, 0);
637
638         /* send the data on \PIPE\ */
639         if (rpc_api_pipe_req(cli, fnum, SAMR_ENUM_DOM_ALIASES, &data, &rdata))
640         {
641                 SAMR_R_ENUM_DOM_ALIASES r_e;
642                 BOOL p;
643
644                 samr_io_r_enum_dom_aliases("", &r_e, &rdata, 0);
645
646                 p = rdata.offset != 0;
647                 if (p && r_e.status != 0)
648                 {
649                         /* report error code */
650                         DEBUG(0,("SAMR_R_ENUM_DOM_ALIASES: %s\n", get_nt_error_msg(r_e.status)));
651                         p = False;
652                 }
653
654                 if (p)
655                 {
656                         int i;
657                         int name_idx = 0;
658
659                         *num_sam_aliases = r_e.num_entries2;
660                         if (*num_sam_aliases > MAX_SAM_ENTRIES)
661                         {
662                                 *num_sam_aliases = MAX_SAM_ENTRIES;
663                                 DEBUG(2,("samr_enum_dom_aliases: sam user entries limited to %d\n",
664                                           *num_sam_aliases));
665                         }
666
667                         *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_aliases));
668                                     
669                         if ((*sam) == NULL)
670                         {
671                                 *num_sam_aliases = 0;
672                         }
673
674                         for (i = 0; i < *num_sam_aliases; i++)
675                         {
676                                 (*sam)[i].rid = r_e.sam[i].rid;
677                                 (*sam)[i].acct_name[0] = 0;
678                                 (*sam)[i].acct_desc[0] = 0;
679                                 if (r_e.sam[i].hdr_name.buffer)
680                                 {
681                                         fstrcpy((*sam)[i].acct_name, unistr2_to_str(&r_e.uni_grp_name[name_idx]));
682                                         name_idx++;
683                                 }
684                                 DEBUG(5,("samr_enum_dom_aliases: idx: %4d rid: %8x acct: %s\n",
685                                           i, (*sam)[i].rid, (*sam)[i].acct_name));
686                         }
687                         valid_pol = True;
688                 }
689         }
690
691         prs_mem_free(&data   );
692         prs_mem_free(&rdata  );
693
694         return valid_pol;
695 }
696
697 /****************************************************************************
698 do a SAMR enumerate users
699 ****************************************************************************/
700 BOOL samr_enum_dom_users(struct cli_state *cli, uint16 fnum, 
701                                 POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
702                                 uint16 acb_mask, uint16 unk_1, uint32 size,
703                                 struct acct_info **sam,
704                                 int *num_sam_users)
705 {
706         prs_struct data;
707         prs_struct rdata;
708
709         SAMR_Q_ENUM_DOM_USERS q_e;
710         BOOL valid_pol = False;
711
712         DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
713
714         if (pol == NULL || num_sam_users == NULL) return False;
715
716         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
717
718         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
719         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
720
721         /* store the parameters */
722         make_samr_q_enum_dom_users(&q_e, pol,
723                                    num_entries, unk_0,
724                                    acb_mask, unk_1, size);
725
726         /* turn parameters into data stream */
727         samr_io_q_enum_dom_users("", &q_e, &data, 0);
728
729         /* send the data on \PIPE\ */
730         if (rpc_api_pipe_req(cli, fnum, SAMR_ENUM_DOM_USERS, &data, &rdata))
731         {
732                 SAMR_R_ENUM_DOM_USERS r_e;
733                 BOOL p;
734
735                 samr_io_r_enum_dom_users("", &r_e, &rdata, 0);
736
737                 p = rdata.offset != 0;
738                 if (p && r_e.status != 0)
739                 {
740                         /* report error code */
741                         DEBUG(0,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
742                         p = False;
743                 }
744
745                 if (p)
746                 {
747                         int i;
748                         int name_idx = 0;
749
750                         *num_sam_users = r_e.num_entries2;
751                         if (*num_sam_users > MAX_SAM_ENTRIES)
752                         {
753                                 *num_sam_users = MAX_SAM_ENTRIES;
754                                 DEBUG(2,("samr_enum_dom_users: sam user entries limited to %d\n",
755                                           *num_sam_users));
756                         }
757
758                         *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_users));
759                                     
760                         if ((*sam) == NULL)
761                         {
762                                 *num_sam_users = 0;
763                         }
764
765                         for (i = 0; i < *num_sam_users; i++)
766                         {
767                                 (*sam)[i].rid = r_e.sam[i].rid;
768                                 (*sam)[i].acct_name[0] = 0;
769                                 (*sam)[i].acct_desc[0] = 0;
770                                 if (r_e.sam[i].hdr_name.buffer)
771                                 {
772                                         fstrcpy((*sam)[i].acct_name, unistr2_to_str(&r_e.uni_acct_name[name_idx]));
773                                         name_idx++;
774                                 }
775                                 DEBUG(5,("samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
776                                           i, (*sam)[i].rid, (*sam)[i].acct_name));
777                         }
778                         valid_pol = True;
779                 }
780         }
781
782         prs_mem_free(&data   );
783         prs_mem_free(&rdata  );
784
785         return valid_pol;
786 }
787
788 /****************************************************************************
789 do a SAMR Connect
790 ****************************************************************************/
791 BOOL samr_connect(struct cli_state *cli, uint16 fnum, 
792                                 char *srv_name, uint32 unknown_0,
793                                 POLICY_HND *connect_pol)
794 {
795         prs_struct data;
796         prs_struct rdata;
797
798         SAMR_Q_CONNECT q_o;
799         BOOL valid_pol = False;
800
801         DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
802                                 srv_name, unknown_0));
803
804         if (srv_name == NULL || connect_pol == NULL) return False;
805
806         /* create and send a MSRPC command with api SAMR_CONNECT */
807
808         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
809         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
810
811         /* store the parameters */
812         make_samr_q_connect(&q_o, srv_name, unknown_0);
813
814         /* turn parameters into data stream */
815         samr_io_q_connect("", &q_o,  &data, 0);
816
817         /* send the data on \PIPE\ */
818         if (rpc_api_pipe_req(cli, fnum, SAMR_CONNECT, &data, &rdata))
819         {
820                 SAMR_R_CONNECT r_o;
821                 BOOL p;
822
823                 samr_io_r_connect("", &r_o, &rdata, 0);
824                 p = rdata.offset != 0;
825                 
826                 if (p && r_o.status != 0)
827                 {
828                         /* report error code */
829                         DEBUG(0,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
830                         p = False;
831                 }
832
833                 if (p)
834                 {
835                         memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
836                         valid_pol = True;
837                 }
838         }
839
840         prs_mem_free(&data   );
841         prs_mem_free(&rdata  );
842
843         return valid_pol;
844 }
845
846 /****************************************************************************
847 do a SAMR Open User
848 ****************************************************************************/
849 BOOL samr_open_user(struct cli_state *cli, uint16 fnum, 
850                                 POLICY_HND *pol, uint32 unk_0, uint32 rid, 
851                                 POLICY_HND *user_pol)
852 {
853         prs_struct data;
854         prs_struct rdata;
855
856         SAMR_Q_OPEN_USER q_o;
857         BOOL valid_pol = False;
858
859         DEBUG(4,("SAMR Open User.  unk_0: %08x RID:%x\n",
860                   unk_0, rid));
861
862         if (pol == NULL || user_pol == NULL) return False;
863
864         /* create and send a MSRPC command with api SAMR_OPEN_USER */
865
866         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
867         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
868
869         /* store the parameters */
870         make_samr_q_open_user(&q_o, pol, unk_0, rid);
871
872         /* turn parameters into data stream */
873         samr_io_q_open_user("", &q_o,  &data, 0);
874
875         /* send the data on \PIPE\ */
876         if (rpc_api_pipe_req(cli, fnum, SAMR_OPEN_USER, &data, &rdata))
877         {
878                 SAMR_R_OPEN_USER r_o;
879                 BOOL p;
880
881                 samr_io_r_open_user("", &r_o, &rdata, 0);
882                 p = rdata.offset != 0;
883                 
884                 if (p && r_o.status != 0)
885                 {
886                         /* report error code */
887                         DEBUG(0,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
888                         p = False;
889                 }
890
891                 if (p)
892                 {
893                         memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
894                         valid_pol = True;
895                 }
896         }
897
898         prs_mem_free(&data   );
899         prs_mem_free(&rdata  );
900
901         return valid_pol;
902 }
903
904 /****************************************************************************
905 do a SAMR Open Alias
906 ****************************************************************************/
907 BOOL samr_open_alias(struct cli_state *cli, uint16 fnum, 
908                                 POLICY_HND *domain_pol,
909                                 uint32 flags, uint32 rid,
910                                 POLICY_HND *alias_pol)
911 {
912         prs_struct data;
913         prs_struct rdata;
914
915         SAMR_Q_OPEN_ALIAS q_o;
916         BOOL valid_pol = False;
917
918         DEBUG(4,("SAMR Open Alias. RID:%x\n", rid));
919
920         if (alias_pol == NULL || domain_pol == NULL) return False;
921
922         /* create and send a MSRPC command with api SAMR_OPEN_ALIAS */
923
924         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
925         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
926
927         /* store the parameters */
928         make_samr_q_open_alias(&q_o, domain_pol, flags, rid);
929
930         /* turn parameters into data stream */
931         samr_io_q_open_alias("", &q_o,  &data, 0);
932
933         /* send the data on \PIPE\ */
934         if (rpc_api_pipe_req(cli, fnum, SAMR_OPEN_ALIAS, &data, &rdata))
935         {
936                 SAMR_R_OPEN_ALIAS r_o;
937                 BOOL p;
938
939                 samr_io_r_open_alias("", &r_o, &rdata, 0);
940                 p = rdata.offset != 0;
941
942                 if (p && r_o.status != 0)
943                 {
944                         /* report error code */
945                         DEBUG(0,("SAMR_R_OPEN_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
946                         p = False;
947                 }
948
949                 if (p)
950                 {
951                         memcpy(alias_pol, &r_o.pol, sizeof(r_o.pol));
952                         valid_pol = True;
953                 }
954         }
955
956         prs_mem_free(&data   );
957         prs_mem_free(&rdata  );
958
959         return valid_pol;
960 }
961
962 /****************************************************************************
963 do a SAMR Delete Alias Member
964 ****************************************************************************/
965 BOOL samr_del_aliasmem(struct cli_state *cli, uint16 fnum, 
966                                 POLICY_HND *alias_pol, DOM_SID *sid)
967 {
968         prs_struct data;
969         prs_struct rdata;
970
971         SAMR_Q_DEL_ALIASMEM q_o;
972         BOOL valid_pol = False;
973
974         if (alias_pol == NULL || sid == NULL) return False;
975
976         /* create and send a MSRPC command with api SAMR_DEL_ALIASMEM */
977
978         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
979         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
980
981         DEBUG(4,("SAMR Delete Alias Member.\n"));
982
983         /* store the parameters */
984         make_samr_q_del_aliasmem(&q_o, alias_pol, sid);
985
986         /* turn parameters into data stream */
987         samr_io_q_del_aliasmem("", &q_o,  &data, 0);
988
989         /* send the data on \PIPE\ */
990         if (rpc_api_pipe_req(cli, fnum, SAMR_DEL_ALIASMEM, &data, &rdata))
991         {
992                 SAMR_R_DEL_ALIASMEM r_o;
993                 BOOL p;
994
995                 samr_io_r_del_aliasmem("", &r_o, &rdata, 0);
996                 p = rdata.offset != 0;
997
998                 if (p && r_o.status != 0)
999                 {
1000                         /* report error code */
1001                         DEBUG(0,("SAMR_R_DEL_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
1002                         p = False;
1003                 }
1004
1005                 if (p)
1006                 {
1007                         valid_pol = True;
1008                 }
1009         }
1010
1011         prs_mem_free(&data   );
1012         prs_mem_free(&rdata  );
1013
1014         return valid_pol;
1015 }
1016
1017 /****************************************************************************
1018 do a SAMR Add Alias Member
1019 ****************************************************************************/
1020 BOOL samr_add_aliasmem(struct cli_state *cli, uint16 fnum, 
1021                                 POLICY_HND *alias_pol, DOM_SID *sid)
1022 {
1023         prs_struct data;
1024         prs_struct rdata;
1025
1026         SAMR_Q_ADD_ALIASMEM q_o;
1027         BOOL valid_pol = False;
1028
1029         if (alias_pol == NULL || sid == NULL) return False;
1030
1031         /* create and send a MSRPC command with api SAMR_ADD_ALIASMEM */
1032
1033         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1034         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1035
1036         DEBUG(4,("SAMR Add Alias Member.\n"));
1037
1038         /* store the parameters */
1039         make_samr_q_add_aliasmem(&q_o, alias_pol, sid);
1040
1041         /* turn parameters into data stream */
1042         samr_io_q_add_aliasmem("", &q_o,  &data, 0);
1043
1044         /* send the data on \PIPE\ */
1045         if (rpc_api_pipe_req(cli, fnum, SAMR_ADD_ALIASMEM, &data, &rdata))
1046         {
1047                 SAMR_R_ADD_ALIASMEM r_o;
1048                 BOOL p;
1049
1050                 samr_io_r_add_aliasmem("", &r_o, &rdata, 0);
1051                 p = rdata.offset != 0;
1052
1053                 if (p && r_o.status != 0)
1054                 {
1055                         /* report error code */
1056                         DEBUG(0,("SAMR_R_ADD_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
1057                         p = False;
1058                 }
1059
1060                 if (p)
1061                 {
1062                         valid_pol = True;
1063                 }
1064         }
1065
1066         prs_mem_free(&data   );
1067         prs_mem_free(&rdata  );
1068
1069         return valid_pol;
1070 }
1071
1072 /****************************************************************************
1073 do a SAMR Delete Domain Alias
1074 ****************************************************************************/
1075 BOOL samr_delete_dom_alias(struct cli_state *cli, uint16 fnum, 
1076                                 POLICY_HND *alias_pol)
1077 {
1078         prs_struct data;
1079         prs_struct rdata;
1080
1081         SAMR_Q_DELETE_DOM_ALIAS q_o;
1082         BOOL valid_pol = False;
1083
1084         if (alias_pol == NULL) return False;
1085
1086         /* delete and send a MSRPC command with api SAMR_DELETE_DOM_ALIAS */
1087
1088         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1089         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1090
1091         DEBUG(4,("SAMR Delete Domain Alias.\n"));
1092
1093         /* store the parameters */
1094         make_samr_q_delete_dom_alias(&q_o, alias_pol);
1095
1096         /* turn parameters into data stream */
1097         samr_io_q_delete_dom_alias("", &q_o,  &data, 0);
1098
1099         /* send the data on \PIPE\ */
1100         if (rpc_api_pipe_req(cli, fnum, SAMR_DELETE_DOM_ALIAS, &data, &rdata))
1101         {
1102                 SAMR_R_DELETE_DOM_ALIAS r_o;
1103                 BOOL p;
1104
1105                 samr_io_r_delete_dom_alias("", &r_o, &rdata, 0);
1106                 p = rdata.offset != 0;
1107
1108                 if (p && r_o.status != 0)
1109                 {
1110                         /* report error code */
1111                         DEBUG(0,("SAMR_R_DELETE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
1112                         p = False;
1113                 }
1114
1115                 if (p)
1116                 {
1117                         valid_pol = True;
1118                 }
1119         }
1120
1121         prs_mem_free(&data   );
1122         prs_mem_free(&rdata  );
1123
1124         return valid_pol;
1125 }
1126
1127 /****************************************************************************
1128 do a SAMR Create Domain Alias
1129 ****************************************************************************/
1130 BOOL samr_create_dom_alias(struct cli_state *cli, uint16 fnum, 
1131                                 POLICY_HND *domain_pol, const char *acct_name,
1132                                 POLICY_HND *alias_pol, uint32 *rid)
1133 {
1134         prs_struct data;
1135         prs_struct rdata;
1136
1137         SAMR_Q_CREATE_DOM_ALIAS q_o;
1138         BOOL valid_pol = False;
1139
1140         if (alias_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
1141
1142         /* create and send a MSRPC command with api SAMR_CREATE_DOM_ALIAS */
1143
1144         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1145         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1146
1147         DEBUG(4,("SAMR Create Domain Alias. Name:%s\n", acct_name));
1148
1149         /* store the parameters */
1150         make_samr_q_create_dom_alias(&q_o, domain_pol, acct_name);
1151
1152         /* turn parameters into data stream */
1153         samr_io_q_create_dom_alias("", &q_o,  &data, 0);
1154
1155         /* send the data on \PIPE\ */
1156         if (rpc_api_pipe_req(cli, fnum, SAMR_CREATE_DOM_ALIAS, &data, &rdata))
1157         {
1158                 SAMR_R_CREATE_DOM_ALIAS r_o;
1159                 BOOL p;
1160
1161                 samr_io_r_create_dom_alias("", &r_o, &rdata, 0);
1162                 p = rdata.offset != 0;
1163
1164                 if (p && r_o.status != 0)
1165                 {
1166                         /* report error code */
1167                         DEBUG(0,("SAMR_R_CREATE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
1168                         p = False;
1169                 }
1170
1171                 if (p)
1172                 {
1173                         memcpy(alias_pol, &r_o.alias_pol, sizeof(r_o.alias_pol));
1174                         *rid = r_o.rid;
1175                         valid_pol = True;
1176                 }
1177         }
1178
1179         prs_mem_free(&data   );
1180         prs_mem_free(&rdata  );
1181
1182         return valid_pol;
1183 }
1184
1185 /****************************************************************************
1186 do a SAMR Set Alias Info
1187 ****************************************************************************/
1188 BOOL samr_set_aliasinfo(struct cli_state *cli, uint16 fnum, 
1189                                 POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
1190 {
1191         prs_struct data;
1192         prs_struct rdata;
1193
1194         SAMR_Q_SET_ALIASINFO q_o;
1195         BOOL valid_pol = False;
1196
1197         if (alias_pol == NULL || ctr == NULL) return False;
1198
1199         /* create and send a MSRPC command with api SAMR_SET_ALIASINFO */
1200
1201         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1202         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1203
1204         DEBUG(4,("SAMR Set Alias Info\n"));
1205
1206         /* store the parameters */
1207         make_samr_q_set_aliasinfo(&q_o, alias_pol, ctr);
1208
1209         /* turn parameters into data stream */
1210         samr_io_q_set_aliasinfo("", &q_o,  &data, 0);
1211
1212         /* send the data on \PIPE\ */
1213         if (rpc_api_pipe_req(cli, fnum, SAMR_SET_ALIASINFO, &data, &rdata))
1214         {
1215                 SAMR_R_SET_ALIASINFO r_o;
1216                 BOOL p;
1217
1218                 samr_io_r_set_aliasinfo("", &r_o, &rdata, 0);
1219                 p = rdata.offset != 0;
1220
1221                 if (p && r_o.status != 0)
1222                 {
1223                         /* report error code */
1224                         DEBUG(0,("SAMR_R_SET_ALIASINFO: %s\n", get_nt_error_msg(r_o.status)));
1225                         p = False;
1226                 }
1227
1228                 if (p)
1229                 {
1230                         valid_pol = True;
1231                 }
1232         }
1233
1234         prs_mem_free(&data   );
1235         prs_mem_free(&rdata  );
1236
1237         return valid_pol;
1238 }
1239
1240 /****************************************************************************
1241 do a SAMR Open Group
1242 ****************************************************************************/
1243 BOOL samr_open_group(struct cli_state *cli, uint16 fnum, 
1244                                 POLICY_HND *domain_pol,
1245                                 uint32 flags, uint32 rid,
1246                                 POLICY_HND *group_pol)
1247 {
1248         prs_struct data;
1249         prs_struct rdata;
1250
1251         SAMR_Q_OPEN_GROUP q_o;
1252         BOOL valid_pol = False;
1253
1254         DEBUG(4,("SAMR Open Group. RID:%x\n", rid));
1255
1256         if (group_pol == NULL || domain_pol == NULL) return False;
1257
1258         /* create and send a MSRPC command with api SAMR_OPEN_GROUP */
1259
1260         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1261         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1262
1263         /* store the parameters */
1264         make_samr_q_open_group(&q_o, domain_pol, flags, rid);
1265
1266         /* turn parameters into data stream */
1267         samr_io_q_open_group("", &q_o,  &data, 0);
1268
1269         /* send the data on \PIPE\ */
1270         if (rpc_api_pipe_req(cli, fnum, SAMR_OPEN_GROUP, &data, &rdata))
1271         {
1272                 SAMR_R_OPEN_GROUP r_o;
1273                 BOOL p;
1274
1275                 samr_io_r_open_group("", &r_o, &rdata, 0);
1276                 p = rdata.offset != 0;
1277
1278                 if (p && r_o.status != 0)
1279                 {
1280                         /* report error code */
1281                         DEBUG(0,("SAMR_R_OPEN_GROUP: %s\n", get_nt_error_msg(r_o.status)));
1282                         p = False;
1283                 }
1284
1285                 if (p)
1286                 {
1287                         memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
1288                         valid_pol = True;
1289                 }
1290         }
1291
1292         prs_mem_free(&data   );
1293         prs_mem_free(&rdata  );
1294
1295         return valid_pol;
1296 }
1297
1298 /****************************************************************************
1299 do a SAMR Delete Group Member
1300 ****************************************************************************/
1301 BOOL samr_del_groupmem(struct cli_state *cli, uint16 fnum, 
1302                                 POLICY_HND *group_pol, uint32 rid)
1303 {
1304         prs_struct data;
1305         prs_struct rdata;
1306
1307         SAMR_Q_DEL_GROUPMEM q_o;
1308         BOOL valid_pol = False;
1309
1310         if (group_pol == NULL) return False;
1311
1312         /* create and send a MSRPC command with api SAMR_DEL_GROUPMEM */
1313
1314         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1315         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1316
1317         DEBUG(4,("SAMR Delete Group Member.\n"));
1318
1319         /* store the parameters */
1320         make_samr_q_del_groupmem(&q_o, group_pol, rid);
1321
1322         /* turn parameters into data stream */
1323         samr_io_q_del_groupmem("", &q_o,  &data, 0);
1324
1325         /* send the data on \PIPE\ */
1326         if (rpc_api_pipe_req(cli, fnum, SAMR_DEL_GROUPMEM, &data, &rdata))
1327         {
1328                 SAMR_R_DEL_GROUPMEM r_o;
1329                 BOOL p;
1330
1331                 samr_io_r_del_groupmem("", &r_o, &rdata, 0);
1332                 p = rdata.offset != 0;
1333
1334                 if (p && r_o.status != 0)
1335                 {
1336                         /* report error code */
1337                         DEBUG(0,("SAMR_R_DEL_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
1338                         p = False;
1339                 }
1340
1341                 if (p)
1342                 {
1343                         valid_pol = True;
1344                 }
1345         }
1346
1347         prs_mem_free(&data   );
1348         prs_mem_free(&rdata  );
1349
1350         return valid_pol;
1351 }
1352
1353 /****************************************************************************
1354 do a SAMR Add Group Member
1355 ****************************************************************************/
1356 BOOL samr_add_groupmem(struct cli_state *cli, uint16 fnum, 
1357                                 POLICY_HND *group_pol, uint32 rid)
1358 {
1359         prs_struct data;
1360         prs_struct rdata;
1361
1362         SAMR_Q_ADD_GROUPMEM q_o;
1363         BOOL valid_pol = False;
1364
1365         if (group_pol == NULL) return False;
1366
1367         /* create and send a MSRPC command with api SAMR_ADD_GROUPMEM */
1368
1369         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1370         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1371
1372         DEBUG(4,("SAMR Add Group Member.\n"));
1373
1374         /* store the parameters */
1375         make_samr_q_add_groupmem(&q_o, group_pol, rid);
1376
1377         /* turn parameters into data stream */
1378         samr_io_q_add_groupmem("", &q_o,  &data, 0);
1379
1380         /* send the data on \PIPE\ */
1381         if (rpc_api_pipe_req(cli, fnum, SAMR_ADD_GROUPMEM, &data, &rdata))
1382         {
1383                 SAMR_R_ADD_GROUPMEM r_o;
1384                 BOOL p;
1385
1386                 samr_io_r_add_groupmem("", &r_o, &rdata, 0);
1387                 p = rdata.offset != 0;
1388
1389                 if (p && r_o.status != 0)
1390                 {
1391                         /* report error code */
1392                         DEBUG(0,("SAMR_R_ADD_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
1393                         p = False;
1394                 }
1395
1396                 if (p)
1397                 {
1398                         valid_pol = True;
1399                 }
1400         }
1401
1402         prs_mem_free(&data   );
1403         prs_mem_free(&rdata  );
1404
1405         return valid_pol;
1406 }
1407
1408 /****************************************************************************
1409 do a SAMR Delete Domain Group
1410 ****************************************************************************/
1411 BOOL samr_delete_dom_group(struct cli_state *cli, uint16 fnum, POLICY_HND *group_pol)
1412 {
1413         prs_struct data;
1414         prs_struct rdata;
1415
1416         SAMR_Q_DELETE_DOM_GROUP q_o;
1417         BOOL valid_pol = False;
1418
1419         if (group_pol == NULL) return False;
1420
1421         /* delete and send a MSRPC command with api SAMR_DELETE_DOM_GROUP */
1422
1423         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1424         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1425
1426         DEBUG(4,("SAMR Delete Domain Group.\n"));
1427
1428         /* store the parameters */
1429         make_samr_q_delete_dom_group(&q_o, group_pol);
1430
1431         /* turn parameters into data stream */
1432         samr_io_q_delete_dom_group("", &q_o,  &data, 0);
1433
1434         /* send the data on \PIPE\ */
1435         if (rpc_api_pipe_req(cli, fnum, SAMR_DELETE_DOM_GROUP, &data, &rdata))
1436         {
1437                 SAMR_R_DELETE_DOM_GROUP r_o;
1438                 BOOL p;
1439
1440                 samr_io_r_delete_dom_group("", &r_o, &rdata, 0);
1441                 p = rdata.offset != 0;
1442
1443                 if (p && r_o.status != 0)
1444                 {
1445                         /* report error code */
1446                         DEBUG(0,("SAMR_R_DELETE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
1447                         p = False;
1448                 }
1449
1450                 if (p)
1451                 {
1452                         valid_pol = True;
1453                 }
1454         }
1455
1456         prs_mem_free(&data   );
1457         prs_mem_free(&rdata  );
1458
1459         return valid_pol;
1460 }
1461
1462 /****************************************************************************
1463 do a SAMR Create Domain Group
1464 ****************************************************************************/
1465 BOOL samr_create_dom_group(struct cli_state *cli, uint16 fnum, 
1466                                 POLICY_HND *domain_pol, const char *acct_name,
1467                                 POLICY_HND *group_pol, uint32 *rid)
1468 {
1469         prs_struct data;
1470         prs_struct rdata;
1471
1472         SAMR_Q_CREATE_DOM_GROUP q_o;
1473         BOOL valid_pol = False;
1474
1475         if (group_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
1476
1477         /* create and send a MSRPC command with api SAMR_CREATE_DOM_GROUP */
1478
1479         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1480         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1481
1482         DEBUG(4,("SAMR Create Domain Group. Name:%s\n", acct_name));
1483
1484         /* store the parameters */
1485         make_samr_q_create_dom_group(&q_o, domain_pol, acct_name);
1486
1487         /* turn parameters into data stream */
1488         samr_io_q_create_dom_group("", &q_o,  &data, 0);
1489
1490         /* send the data on \PIPE\ */
1491         if (rpc_api_pipe_req(cli, fnum, SAMR_CREATE_DOM_GROUP, &data, &rdata))
1492         {
1493                 SAMR_R_CREATE_DOM_GROUP r_o;
1494                 BOOL p;
1495
1496                 samr_io_r_create_dom_group("", &r_o, &rdata, 0);
1497                 p = rdata.offset != 0;
1498
1499                 if (p && r_o.status != 0)
1500                 {
1501                         /* report error code */
1502                         DEBUG(0,("SAMR_R_CREATE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
1503                         p = False;
1504                 }
1505
1506                 if (p)
1507                 {
1508                         memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
1509                         *rid = r_o.rid;
1510                         valid_pol = True;
1511                 }
1512         }
1513
1514         prs_mem_free(&data   );
1515         prs_mem_free(&rdata  );
1516
1517         return valid_pol;
1518 }
1519
1520 /****************************************************************************
1521 do a SAMR Set Group Info
1522 ****************************************************************************/
1523 BOOL samr_set_groupinfo(struct cli_state *cli, uint16 fnum, 
1524                                 POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
1525 {
1526         prs_struct data;
1527         prs_struct rdata;
1528
1529         SAMR_Q_SET_GROUPINFO q_o;
1530         BOOL valid_pol = False;
1531
1532         if (group_pol == NULL || ctr == NULL) return False;
1533
1534         /* create and send a MSRPC command with api SAMR_SET_GROUPINFO */
1535
1536         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1537         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1538
1539         DEBUG(4,("SAMR Set Group Info\n"));
1540
1541         /* store the parameters */
1542         make_samr_q_set_groupinfo(&q_o, group_pol, ctr);
1543
1544         /* turn parameters into data stream */
1545         samr_io_q_set_groupinfo("", &q_o,  &data, 0);
1546
1547         /* send the data on \PIPE\ */
1548         if (rpc_api_pipe_req(cli, fnum, SAMR_SET_GROUPINFO, &data, &rdata))
1549         {
1550                 SAMR_R_SET_GROUPINFO r_o;
1551                 BOOL p;
1552
1553                 samr_io_r_set_groupinfo("", &r_o, &rdata, 0);
1554                 p = rdata.offset != 0;
1555
1556                 if (p && r_o.status != 0)
1557                 {
1558                         /* report error code */
1559                         DEBUG(0,("SAMR_R_SET_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
1560                         p = False;
1561                 }
1562
1563                 if (p)
1564                 {
1565                         valid_pol = True;
1566                 }
1567         }
1568
1569         prs_mem_free(&data   );
1570         prs_mem_free(&rdata  );
1571
1572         return valid_pol;
1573 }
1574
1575 /****************************************************************************
1576 do a SAMR Open Domain
1577 ****************************************************************************/
1578 BOOL samr_open_domain(struct cli_state *cli, uint16 fnum, 
1579                                 POLICY_HND *connect_pol, uint32 flags, DOM_SID *sid,
1580                                 POLICY_HND *domain_pol)
1581 {
1582         pstring sid_str;
1583         prs_struct data;
1584         prs_struct rdata;
1585
1586         SAMR_Q_OPEN_DOMAIN q_o;
1587         BOOL valid_pol = False;
1588
1589         sid_to_string(sid_str, sid);
1590         DEBUG(4,("SAMR Open Domain.  SID:%s Flags:%x\n", sid_str, flags));
1591
1592         if (connect_pol == NULL || sid == NULL || domain_pol == NULL) return False;
1593
1594         /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
1595
1596         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1597         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1598
1599         /* store the parameters */
1600         make_samr_q_open_domain(&q_o, connect_pol, flags, sid);
1601
1602         /* turn parameters into data stream */
1603         samr_io_q_open_domain("", &q_o,  &data, 0);
1604
1605         /* send the data on \PIPE\ */
1606         if (rpc_api_pipe_req(cli, fnum, SAMR_OPEN_DOMAIN, &data, &rdata))
1607         {
1608                 SAMR_R_OPEN_DOMAIN r_o;
1609                 BOOL p;
1610
1611                 samr_io_r_open_domain("", &r_o, &rdata, 0);
1612                 p = rdata.offset != 0;
1613
1614                 if (p && r_o.status != 0)
1615                 {
1616                         /* report error code */
1617                         DEBUG(0,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
1618                         p = False;
1619                 }
1620
1621                 if (p)
1622                 {
1623                         memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
1624                         valid_pol = True;
1625                 }
1626         }
1627
1628         prs_mem_free(&data   );
1629         prs_mem_free(&rdata  );
1630
1631         return valid_pol;
1632 }
1633
1634 /****************************************************************************
1635 do a SAMR Query Lookup Names
1636 ****************************************************************************/
1637 BOOL samr_query_lookup_names(struct cli_state *cli, uint16 fnum, 
1638                                 POLICY_HND *pol, uint32 flags,
1639                                 uint32 num_names, const char **names,
1640                                 uint32 *num_rids,
1641                                 uint32 rid[MAX_LOOKUP_SIDS],
1642                                 uint32 type[MAX_LOOKUP_SIDS])
1643 {
1644         prs_struct data;
1645         prs_struct rdata;
1646
1647         SAMR_Q_LOOKUP_NAMES q_o;
1648         BOOL valid_query = False;
1649
1650         if (pol == NULL || flags == 0 || num_names == 0 || names == NULL ||
1651             num_rids == NULL || rid == NULL || type == NULL ) return False;
1652
1653         /* create and send a MSRPC command with api SAMR_LOOKUP_NAMES */
1654
1655         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1656         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1657
1658         DEBUG(4,("SAMR Query Lookup NAMES.\n"));
1659
1660         /* store the parameters */
1661         make_samr_q_lookup_names(&q_o, pol, flags, num_names, names);
1662
1663         /* turn parameters into data stream */
1664         samr_io_q_lookup_names("", &q_o, &data, 0);
1665
1666         /* send the data on \PIPE\ */
1667         if (rpc_api_pipe_req(cli, fnum, SAMR_LOOKUP_NAMES, &data, &rdata))
1668         {
1669                 SAMR_R_LOOKUP_NAMES r_o;
1670                 BOOL p;
1671
1672                 samr_io_r_lookup_names("", &r_o, &rdata, 0);
1673                 p = rdata.offset != 0;
1674                 
1675                 if (p && r_o.status != 0)
1676                 {
1677                         /* report error code */
1678                         DEBUG(0,("SAMR_R_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_o.status)));
1679                         p = False;
1680                 }
1681
1682                 if (p)
1683                 {
1684                         if (r_o.ptr_rids != 0 && r_o.ptr_types != 0 &&
1685                             r_o.num_types1 == r_o.num_rids1)
1686                         {
1687                                 int i;
1688
1689                                 valid_query = True;
1690                                 *num_rids = r_o.num_rids1;
1691
1692                                 for (i = 0; i < r_o.num_rids1; i++)
1693                                 {
1694                                         rid[i] = r_o.rid[i];
1695                                 }
1696                                 for (i = 0; i < r_o.num_types1; i++)
1697                                 {
1698                                         type[i] = r_o.type[i];
1699                                 }
1700                         }
1701                         else if (r_o.ptr_rids == 0 && r_o.ptr_types == 0)
1702                         {
1703                                 valid_query = True;
1704                                 *num_rids = 0;
1705                         }
1706                         else
1707                         {
1708                                 p = False;
1709                         }
1710                 }
1711         }
1712
1713         prs_mem_free(&data   );
1714         prs_mem_free(&rdata  );
1715
1716         return valid_query;
1717 }
1718
1719 /****************************************************************************
1720 do a SAMR Query Lookup RIDS
1721 ****************************************************************************/
1722 BOOL samr_query_lookup_rids(struct cli_state *cli, uint16 fnum, 
1723                                 POLICY_HND *pol, uint32 flags,
1724                                 uint32 num_rids, uint32 *rids,
1725                                 uint32 *num_names,
1726                                 fstring names[MAX_LOOKUP_SIDS],
1727                                 uint32  type [MAX_LOOKUP_SIDS])
1728 {
1729         prs_struct data;
1730         prs_struct rdata;
1731
1732         SAMR_Q_LOOKUP_RIDS q_o;
1733         BOOL valid_query = False;
1734
1735         if (pol == NULL || flags == 0 || num_rids == 0 || rids == NULL ||
1736             num_names == NULL || names == NULL || type == NULL ) return False;
1737
1738         /* create and send a MSRPC command with api SAMR_LOOKUP_RIDS */
1739
1740         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1741         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1742
1743         DEBUG(4,("SAMR Query Lookup RIDs.\n"));
1744
1745         /* store the parameters */
1746         make_samr_q_lookup_rids(&q_o, pol, flags, num_rids, rids);
1747
1748         /* turn parameters into data stream */
1749         samr_io_q_lookup_rids("", &q_o,  &data, 0);
1750
1751         /* send the data on \PIPE\ */
1752         if (rpc_api_pipe_req(cli, fnum, SAMR_LOOKUP_RIDS, &data, &rdata))
1753         {
1754                 SAMR_R_LOOKUP_RIDS r_o;
1755                 BOOL p;
1756
1757                 samr_io_r_lookup_rids("", &r_o, &rdata, 0);
1758                 p = rdata.offset != 0;
1759                 
1760                 if (p && r_o.status != 0)
1761                 {
1762                         /* report error code */
1763                         DEBUG(0,("SAMR_R_LOOKUP_RIDS: %s\n", get_nt_error_msg(r_o.status)));
1764                         p = False;
1765                 }
1766
1767                 if (p)
1768                 {
1769                         if (r_o.ptr_names != 0 && r_o.ptr_types != 0 &&
1770                             r_o.num_types1 == r_o.num_names1)
1771                         {
1772                                 int i;
1773
1774                                 valid_query = True;
1775                                 *num_names = r_o.num_names1;
1776
1777                                 for (i = 0; i < r_o.num_names1; i++)
1778                                 {
1779                                         fstrcpy(names[i], unistr2_to_str(&r_o.uni_name[i]));
1780                                 }
1781                                 for (i = 0; i < r_o.num_types1; i++)
1782                                 {
1783                                         type[i] = r_o.type[i];
1784                                 }
1785                         }
1786                         else if (r_o.ptr_names == 0 && r_o.ptr_types == 0)
1787                         {
1788                                 valid_query = True;
1789                                 *num_names = 0;
1790                         }
1791                         else
1792                         {
1793                                 p = False;
1794                         }
1795                 }
1796         }
1797
1798         prs_mem_free(&data   );
1799         prs_mem_free(&rdata  );
1800
1801         return valid_query;
1802 }
1803
1804 /****************************************************************************
1805 do a SAMR Query Alias Members
1806 ****************************************************************************/
1807 BOOL samr_query_aliasmem(struct cli_state *cli, uint16 fnum, 
1808                                 POLICY_HND *alias_pol, 
1809                                 uint32 *num_mem, DOM_SID2 *sid)
1810 {
1811         prs_struct data;
1812         prs_struct rdata;
1813
1814         SAMR_Q_QUERY_ALIASMEM q_o;
1815         BOOL valid_query = False;
1816
1817         DEBUG(4,("SAMR Query Alias Members.\n"));
1818
1819         if (alias_pol == NULL || sid == NULL || num_mem == NULL) return False;
1820
1821         /* create and send a MSRPC command with api SAMR_QUERY_ALIASMEM */
1822
1823         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1824         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1825
1826         /* store the parameters */
1827         make_samr_q_query_aliasmem(&q_o, alias_pol);
1828
1829         /* turn parameters into data stream */
1830         samr_io_q_query_aliasmem("", &q_o,  &data, 0);
1831
1832         /* send the data on \PIPE\ */
1833         if (rpc_api_pipe_req(cli, fnum, SAMR_QUERY_ALIASMEM, &data, &rdata))
1834         {
1835                 SAMR_R_QUERY_ALIASMEM r_o;
1836                 BOOL p;
1837
1838                 /* get user info */
1839                 r_o.sid = sid;
1840
1841                 samr_io_r_query_aliasmem("", &r_o, &rdata, 0);
1842                 p = rdata.offset != 0;
1843                 
1844                 if (p && r_o.status != 0)
1845                 {
1846                         /* report error code */
1847                         DEBUG(0,("SAMR_R_QUERY_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
1848                         p = False;
1849                 }
1850
1851                 if (p && r_o.ptr != 0)
1852                 {
1853                         valid_query = True;
1854                         *num_mem = r_o.num_sids;
1855                 }
1856
1857         }
1858
1859         prs_mem_free(&data   );
1860         prs_mem_free(&rdata  );
1861
1862         return valid_query;
1863 }
1864
1865 /****************************************************************************
1866 do a SAMR Query User Aliases
1867 ****************************************************************************/
1868 BOOL samr_query_useraliases(struct cli_state *cli, uint16 fnum, 
1869                                 POLICY_HND *pol, DOM_SID *sid,
1870                                 uint32 *num_aliases, uint32 *rid)
1871 {
1872         prs_struct data;
1873         prs_struct rdata;
1874
1875         SAMR_Q_QUERY_USERALIASES q_o;
1876         BOOL valid_query = False;
1877
1878         DEBUG(4,("SAMR Query User Aliases.\n"));
1879
1880         if (pol == NULL || sid == NULL || rid == NULL || num_aliases == 0) return False;
1881
1882         /* create and send a MSRPC command with api SAMR_QUERY_USERALIASES */
1883
1884         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1885         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1886
1887         /* store the parameters */
1888         make_samr_q_query_useraliases(&q_o, pol, sid);
1889
1890         /* turn parameters into data stream */
1891         samr_io_q_query_useraliases("", &q_o,  &data, 0);
1892
1893         /* send the data on \PIPE\ */
1894         if (rpc_api_pipe_req(cli, fnum, SAMR_QUERY_USERALIASES, &data, &rdata))
1895         {
1896                 SAMR_R_QUERY_USERALIASES r_o;
1897                 BOOL p;
1898
1899                 /* get user info */
1900                 r_o.rid = rid;
1901
1902                 samr_io_r_query_useraliases("", &r_o, &rdata, 0);
1903                 p = rdata.offset != 0;
1904                 
1905                 if (p && r_o.status != 0)
1906                 {
1907                         /* report error code */
1908                         DEBUG(0,("SAMR_R_QUERY_USERALIASES: %s\n", get_nt_error_msg(r_o.status)));
1909                         p = False;
1910                 }
1911
1912                 if (p && r_o.ptr != 0)
1913                 {
1914                         valid_query = True;
1915                         *num_aliases = r_o.num_entries;
1916                 }
1917
1918         }
1919
1920         prs_mem_free(&data   );
1921         prs_mem_free(&rdata  );
1922
1923         return valid_query;
1924 }
1925
1926 /****************************************************************************
1927 do a SAMR Query Group Members
1928 ****************************************************************************/
1929 BOOL samr_query_groupmem(struct cli_state *cli, uint16 fnum, 
1930                                 POLICY_HND *group_pol, 
1931                                 uint32 *num_mem, uint32 *rid, uint32 *attr)
1932 {
1933         prs_struct data;
1934         prs_struct rdata;
1935
1936         SAMR_Q_QUERY_GROUPMEM q_o;
1937         BOOL valid_query = False;
1938
1939         DEBUG(4,("SAMR Query Group Members.\n"));
1940
1941         if (group_pol == NULL || rid == NULL || attr == NULL || num_mem == NULL) return False;
1942
1943         /* create and send a MSRPC command with api SAMR_QUERY_GROUPMEM */
1944
1945         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1946         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1947
1948         /* store the parameters */
1949         make_samr_q_query_groupmem(&q_o, group_pol);
1950
1951         /* turn parameters into data stream */
1952         samr_io_q_query_groupmem("", &q_o,  &data, 0);
1953
1954         /* send the data on \PIPE\ */
1955         if (rpc_api_pipe_req(cli, fnum, SAMR_QUERY_GROUPMEM, &data, &rdata))
1956         {
1957                 SAMR_R_QUERY_GROUPMEM r_o;
1958                 BOOL p;
1959
1960                 /* get user info */
1961                 r_o.rid  = rid;
1962                 r_o.attr = attr;
1963
1964                 samr_io_r_query_groupmem("", &r_o, &rdata, 0);
1965                 p = rdata.offset != 0;
1966                 
1967                 if (p && r_o.status != 0)
1968                 {
1969                         /* report error code */
1970                         DEBUG(0,("SAMR_R_QUERY_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
1971                         p = False;
1972                 }
1973
1974                 if (p && r_o.ptr != 0 &&
1975                     r_o.ptr_rids != 0 && r_o.ptr_attrs != 0 &&
1976                     r_o.num_rids == r_o.num_attrs)
1977                 {
1978                         valid_query = True;
1979                         *num_mem = r_o.num_rids;
1980                 }
1981
1982         }
1983
1984         prs_mem_free(&data   );
1985         prs_mem_free(&rdata  );
1986
1987         return valid_query;
1988 }
1989
1990 /****************************************************************************
1991 do a SAMR Query User Groups
1992 ****************************************************************************/
1993 BOOL samr_query_usergroups(struct cli_state *cli, uint16 fnum, 
1994                                 POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid)
1995 {
1996         prs_struct data;
1997         prs_struct rdata;
1998
1999         SAMR_Q_QUERY_USERGROUPS q_o;
2000         BOOL valid_query = False;
2001
2002         DEBUG(4,("SAMR Query User Groups.\n"));
2003
2004         if (pol == NULL || gid == NULL || num_groups == 0) return False;
2005
2006         /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
2007
2008         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2009         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2010
2011         /* store the parameters */
2012         make_samr_q_query_usergroups(&q_o, pol);
2013
2014         /* turn parameters into data stream */
2015         samr_io_q_query_usergroups("", &q_o,  &data, 0);
2016
2017         /* send the data on \PIPE\ */
2018         if (rpc_api_pipe_req(cli, fnum, SAMR_QUERY_USERGROUPS, &data, &rdata))
2019         {
2020                 SAMR_R_QUERY_USERGROUPS r_o;
2021                 BOOL p;
2022
2023                 /* get user info */
2024                 r_o.gid = gid;
2025
2026                 samr_io_r_query_usergroups("", &r_o, &rdata, 0);
2027                 p = rdata.offset != 0;
2028                 
2029                 if (p && r_o.status != 0)
2030                 {
2031                         /* report error code */
2032                         DEBUG(0,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
2033                         p = False;
2034                 }
2035
2036                 if (p && r_o.ptr_0 != 0)
2037                 {
2038                         valid_query = True;
2039                         *num_groups = r_o.num_entries;
2040                 }
2041
2042         }
2043
2044         prs_mem_free(&data   );
2045         prs_mem_free(&rdata  );
2046
2047         return valid_query;
2048 }
2049
2050 /****************************************************************************
2051 do a SAMR Query Group Info
2052 ****************************************************************************/
2053 BOOL samr_query_groupinfo(struct cli_state *cli, uint16 fnum, 
2054                                 POLICY_HND *pol,
2055                                 uint16 switch_value, GROUP_INFO_CTR* ctr)
2056 {
2057         prs_struct data;
2058         prs_struct rdata;
2059
2060         SAMR_Q_QUERY_GROUPINFO q_o;
2061         BOOL valid_query = False;
2062
2063         DEBUG(4,("SAMR Query Group Info.  level: %d\n", switch_value));
2064
2065         if (pol == NULL || ctr == NULL || switch_value == 0) return False;
2066
2067         /* create and send a MSRPC command with api SAMR_QUERY_GROUPINFO */
2068
2069         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2070         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2071
2072         /* store the parameters */
2073         make_samr_q_query_groupinfo(&q_o, pol, switch_value);
2074
2075         /* turn parameters into data stream */
2076         samr_io_q_query_groupinfo("", &q_o,  &data, 0);
2077
2078         /* send the data on \PIPE\ */
2079         if (rpc_api_pipe_req(cli, fnum, SAMR_QUERY_GROUPINFO, &data, &rdata))
2080         {
2081                 SAMR_R_QUERY_GROUPINFO r_o;
2082                 BOOL p;
2083
2084                 /* get user info */
2085                 r_o.ctr = ctr;
2086
2087                 samr_io_r_query_groupinfo("", &r_o, &rdata, 0);
2088                 p = rdata.offset != 0;
2089                 
2090                 if (p && r_o.status != 0)
2091                 {
2092                         /* report error code */
2093                         DEBUG(0,("SAMR_R_QUERY_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
2094                         p = False;
2095                 }
2096
2097                 if (p && r_o.ctr->switch_value1 != switch_value)
2098                 {
2099                         DEBUG(0,("SAMR_R_QUERY_GROUPINFO: received incorrect level %d\n",
2100                                   r_o.ctr->switch_value1));
2101                 }
2102
2103                 if (p && r_o.ptr != 0)
2104                 {
2105                         valid_query = True;
2106                 }
2107         }
2108
2109         prs_mem_free(&data   );
2110         prs_mem_free(&rdata  );
2111
2112         return valid_query;
2113 }
2114
2115 /****************************************************************************
2116 do a SAMR Query User Info
2117 ****************************************************************************/
2118 BOOL samr_query_userinfo(struct cli_state *cli, uint16 fnum, 
2119                                 POLICY_HND *pol, uint16 switch_value, void* usr)
2120 {
2121         prs_struct data;
2122         prs_struct rdata;
2123
2124         SAMR_Q_QUERY_USERINFO q_o;
2125         BOOL valid_query = False;
2126
2127         DEBUG(4,("SAMR Query User Info.  level: %d\n", switch_value));
2128
2129         if (pol == NULL || usr == NULL || switch_value == 0) return False;
2130
2131         /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
2132
2133         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2134         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2135
2136         /* store the parameters */
2137         make_samr_q_query_userinfo(&q_o, pol, switch_value);
2138
2139         /* turn parameters into data stream */
2140         samr_io_q_query_userinfo("", &q_o,  &data, 0);
2141
2142         /* send the data on \PIPE\ */
2143         if (rpc_api_pipe_req(cli, fnum, SAMR_QUERY_USERINFO, &data, &rdata))
2144         {
2145                 SAMR_R_QUERY_USERINFO r_o;
2146                 BOOL p;
2147
2148                 /* get user info */
2149                 r_o.info.id = usr;
2150
2151                 samr_io_r_query_userinfo("", &r_o, &rdata, 0);
2152                 p = rdata.offset != 0;
2153                 
2154                 if (p && r_o.status != 0)
2155                 {
2156                         /* report error code */
2157                         DEBUG(0,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
2158                         p = False;
2159                 }
2160
2161                 if (p && r_o.switch_value != switch_value)
2162                 {
2163                         DEBUG(0,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
2164                                   r_o.switch_value));
2165                 }
2166
2167                 if (p && r_o.ptr != 0)
2168                 {
2169                         valid_query = True;
2170                 }
2171         }
2172
2173         prs_mem_free(&data   );
2174         prs_mem_free(&rdata  );
2175
2176         return valid_query;
2177 }
2178
2179 /****************************************************************************
2180 do a SAMR Close
2181 ****************************************************************************/
2182 BOOL samr_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd)
2183 {
2184         prs_struct data;
2185         prs_struct rdata;
2186
2187         SAMR_Q_CLOSE_HND q_c;
2188         BOOL valid_close = False;
2189
2190         DEBUG(4,("SAMR Close\n"));
2191
2192         if (hnd == NULL) return False;
2193
2194         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2195         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2196
2197         /* create and send a MSRPC command with api SAMR_CLOSE_HND */
2198
2199         /* store the parameters */
2200         make_samr_q_close_hnd(&q_c, hnd);
2201
2202         /* turn parameters into data stream */
2203         samr_io_q_close_hnd("", &q_c,  &data, 0);
2204
2205         /* send the data on \PIPE\ */
2206         if (rpc_api_pipe_req(cli, fnum, SAMR_CLOSE_HND, &data, &rdata))
2207         {
2208                 SAMR_R_CLOSE_HND r_c;
2209                 BOOL p;
2210
2211                 samr_io_r_close_hnd("", &r_c, &rdata, 0);
2212                 p = rdata.offset != 0;
2213
2214                 if (p && r_c.status != 0)
2215                 {
2216                         /* report error code */
2217                         DEBUG(0,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
2218                         p = False;
2219                 }
2220
2221                 if (p)
2222                 {
2223                         /* check that the returned policy handle is all zeros */
2224                         int i;
2225                         valid_close = True;
2226
2227                         for (i = 0; i < sizeof(r_c.pol.data); i++)
2228                         {
2229                                 if (r_c.pol.data[i] != 0)
2230                                 {
2231                                         valid_close = False;
2232                                         break;
2233                                 }
2234                         }       
2235                         if (!valid_close)
2236                         {
2237                                 DEBUG(0,("SAMR_CLOSE_HND: non-zero handle returned\n"));
2238                         }
2239                 }
2240         }
2241
2242         prs_mem_free(&data   );
2243         prs_mem_free(&rdata  );
2244
2245         return valid_close;
2246 }
2247