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