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