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