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