Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR
[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    Copyright (C) Jeremy Allison 1999.
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24
25
26 #ifdef SYSLOG
27 #undef SYSLOG
28 #endif
29
30 #include "includes.h"
31
32 extern int DEBUGLEVEL;
33
34 /****************************************************************************
35 do a SAMR query user groups
36 ****************************************************************************/
37 BOOL get_samr_query_usergroups(struct cli_state *cli, 
38                                 POLICY_HND *pol_open_domain, uint32 user_rid,
39                                 uint32 *num_groups, DOM_GID *gid)
40 {
41         POLICY_HND pol_open_user;
42         if (pol_open_domain == NULL || num_groups == NULL || gid == NULL)
43                 return False;
44
45         /* send open domain (on user sid) */
46         if (!do_samr_open_user(cli,
47                                 pol_open_domain,
48                                 0x02011b, user_rid,
49                                 &pol_open_user))
50         {
51                 return False;
52         }
53
54         /* send user groups query */
55         if (!do_samr_query_usergroups(cli,
56                                 &pol_open_user,
57                                 num_groups, gid))
58         {
59                 DEBUG(5,("do_samr_query_usergroups: error in query user groups\n"));
60         }
61
62         return do_samr_close(cli, &pol_open_user);
63 }
64
65 #if 0
66 /* DOES NOT COMPILE WITH THE NEW SAMR PARSE CODE. JRA. */
67
68 /****************************************************************************
69 do a SAMR query user info
70 ****************************************************************************/
71 BOOL get_samr_query_userinfo(struct cli_state *cli, 
72                                 POLICY_HND *pol_open_domain,
73                                 uint32 info_level,
74                                 uint32 user_rid, SAM_USER_INFO_21 *usr)
75 {
76         POLICY_HND pol_open_user;
77         if (pol_open_domain == NULL || usr == NULL)
78                 return False;
79
80         memset((char *)usr, '\0', sizeof(*usr));
81
82         /* send open domain (on user sid) */
83         if (!do_samr_open_user(cli,
84                                 pol_open_domain,
85                                 0x02011b, user_rid,
86                                 &pol_open_user))
87         {
88                 return False;
89         }
90
91         /* send user info query */
92         if (!do_samr_query_userinfo(cli,
93                                 &pol_open_user,
94                                 info_level, (void*)usr))
95         {
96                 DEBUG(5,("do_samr_query_userinfo: error in query user info, level 0x%x\n",
97                           info_level));
98         }
99
100         return do_samr_close(cli, &pol_open_user);
101 }
102 #endif
103
104 /****************************************************************************
105 do a SAMR change user password command
106 ****************************************************************************/
107 BOOL do_samr_chgpasswd_user(struct cli_state *cli,
108                 char *srv_name, char *user_name,
109                 char nt_newpass[516], uchar nt_oldhash[16],
110                 char lm_newpass[516], uchar lm_oldhash[16])
111 {
112         prs_struct data;
113         prs_struct rdata;
114         SAMR_Q_CHGPASSWD_USER q_e;
115         SAMR_R_CHGPASSWD_USER r_e;
116
117         /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
118
119         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
120         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
121
122         DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
123                 srv_name, user_name));
124
125         init_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
126                                    nt_newpass, nt_oldhash,
127                                    lm_newpass, lm_oldhash);
128
129         /* turn parameters into data stream */
130         if(!samr_io_q_chgpasswd_user("", &q_e, &data, 0)) {
131                 prs_mem_free(&data);
132                 prs_mem_free(&rdata);
133                 return False;
134         }
135
136         /* send the data on \PIPE\ */
137         if (!rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &data, &rdata)) {
138                 prs_mem_free(&data);
139                 prs_mem_free(&rdata);
140                 return False;
141         }
142
143         prs_mem_free(&data);
144
145         if(!samr_io_r_chgpasswd_user("", &r_e, &rdata, 0)) {
146                 prs_mem_free(&rdata);
147                 return False;
148         }
149
150         if (r_e.status != 0) {
151                 /* report error code */
152                 DEBUG(0,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
153                 prs_mem_free(&rdata);
154                 return False;
155         }
156
157         prs_mem_free(&rdata);
158
159         return True;
160 }
161
162 #if 0 
163
164 /* CURRENTLY THIS DOESN'T COMPILE AND IS NOT USED ANYWHERE. JRA. */
165
166 /****************************************************************************
167 do a SAMR unknown 0x38 command
168 ****************************************************************************/
169 BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name)
170 {
171         prs_struct data;
172         prs_struct rdata;
173
174         SAMR_Q_UNKNOWN_38 q_e;
175         SAMR_R_UNKNOWN_38 r_e;
176
177         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
178
179         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
180         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
181
182         DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name));
183
184         init_samr_q_unknown_38(&q_e, srv_name);
185
186         /* turn parameters into data stream */
187         if(!samr_io_q_unknown_38("", &q_e, &data, 0)) {
188                 prs_mem_free(&data);
189                 prs_mem_free(&rdata);
190                 return False;
191         }
192
193         /* send the data on \PIPE\ */
194         if (!rpc_api_pipe_req(cli, SAMR_UNKNOWN_38, &data, &rdata)) {
195                 prs_mem_free(&data);
196                 prs_mem_free(&rdata);
197                 return False;
198         }
199
200         prs_mem_free(&data);
201
202         if(!samr_io_r_unknown_38("", &r_e, &rdata, 0)) {
203                 prs_mem_free(&rdata);
204                 return False;
205         }
206
207         if (r_e.status != 0) {
208                 /* report error code */
209                 DEBUG(0,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status)));
210                 prs_mem_free(&rdata);
211                 return False;
212         }
213
214         prs_mem_free(&rdata);
215
216         return True;
217 }
218 #endif
219
220 /****************************************************************************
221 do a SAMR unknown 0x8 command
222 ****************************************************************************/
223 BOOL do_samr_query_dom_info(struct cli_state *cli, 
224                                 POLICY_HND *domain_pol, uint16 switch_value)
225 {
226         prs_struct data;
227         prs_struct rdata;
228         SAMR_Q_QUERY_DOMAIN_INFO q_e;
229         SAMR_R_QUERY_DOMAIN_INFO r_e;
230
231         if (domain_pol == NULL)
232                 return False;
233
234         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
235
236         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
237         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
238
239         DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
240
241         /* store the parameters */
242         init_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
243
244         /* turn parameters into data stream */
245         if(!samr_io_q_query_dom_info("", &q_e, &data, 0)) {
246                 prs_mem_free(&data);
247                 prs_mem_free(&rdata);
248                 return False;
249         }
250
251         /* send the data on \PIPE\ */
252         if (!rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &data, &rdata)) {
253                 prs_mem_free(&data);
254                 prs_mem_free(&rdata);
255                 return False;
256         }
257
258         prs_mem_free(&data);
259
260         if(!samr_io_r_query_dom_info("", &r_e, &rdata, 0)) {
261                 prs_mem_free(&rdata);
262                 return False;
263         }
264
265         if (r_e.status != 0) {
266                 /* report error code */
267                 DEBUG(0,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status)));
268                 prs_mem_free(&rdata);
269                 return False;
270         }
271
272         prs_mem_free(&rdata);
273
274         return True;
275 }
276
277 #if 0
278
279 /* CURRENTLY DOESN'T COMPILE WITH THE NEW SAMR PARSE CODE. JRA */
280
281 /****************************************************************************
282 do a SAMR enumerate users
283 ****************************************************************************/
284 BOOL do_samr_enum_dom_users(struct cli_state *cli, 
285                                 POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
286                                 uint16 acb_mask, uint16 unk_1, uint32 size,
287                                 struct acct_info **sam,
288                                 int *num_sam_users)
289 {
290         prs_struct data;
291         prs_struct rdata;
292         SAMR_Q_ENUM_DOM_USERS q_e;
293         SAMR_R_ENUM_DOM_USERS r_e;
294         int i;
295         int name_idx = 0;
296
297         if (pol == NULL || num_sam_users == NULL)
298                 return False;
299
300         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
301
302         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
303         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
304
305         DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
306
307         /* store the parameters */
308         init_samr_q_enum_dom_users(&q_e, pol,
309                                    num_entries, unk_0,
310                                    acb_mask, unk_1, size);
311
312         /* turn parameters into data stream */
313         if(!samr_io_q_enum_dom_users("", &q_e, &data, 0)) {
314                 prs_mem_free(&data);
315                 prs_mem_free(&rdata);
316                 return False;
317         }
318
319         /* send the data on \PIPE\ */
320         if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &data, &rdata)) {
321                 prs_mem_free(&data);
322                 prs_mem_free(&rdata);
323                 return False;
324         }
325
326         prs_mem_free(&data);
327
328         if(!samr_io_r_enum_dom_users("", &r_e, &rdata, 0)) {
329                 prs_mem_free(&rdata);
330                 return False;
331         }
332
333         if (r_e.status != 0) {
334                 /* report error code */
335                 DEBUG(0,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
336                 prs_mem_free(&rdata);
337                 return False;
338         }
339
340         *num_sam_users = r_e.num_entries2;
341         if (*num_sam_users > MAX_SAM_ENTRIES) {
342                 *num_sam_users = MAX_SAM_ENTRIES;
343                 DEBUG(2,("do_samr_enum_dom_users: sam user entries limited to %d\n",
344                           *num_sam_users));
345         }
346
347         *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_users));
348                                     
349         if ((*sam) == NULL)
350                 *num_sam_users = 0;
351
352         for (i = 0; i < *num_sam_users; i++) {
353                 (*sam)[i].smb_userid = r_e.sam[i].rid;
354                 if (r_e.sam[i].hdr_name.buffer) {
355                         char *acct_name = dos_unistrn2(r_e.uni_acct_name[name_idx].buffer,
356                                                    r_e.uni_acct_name[name_idx].uni_str_len);
357                         fstrcpy((*sam)[i].acct_name, acct_name);
358                         name_idx++;
359                 } else {
360                         memset((char *)(*sam)[i].acct_name, '\0', sizeof((*sam)[i].acct_name));
361                 }
362
363                 DEBUG(5,("do_samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
364                           i, (*sam)[i].smb_userid, (*sam)[i].acct_name));
365         }
366
367         prs_mem_free(&rdata  );
368
369         return True;
370 }
371 #endif
372
373 /****************************************************************************
374 do a SAMR Connect
375 ****************************************************************************/
376 BOOL do_samr_connect(struct cli_state *cli, 
377                                 char *srv_name, uint32 unknown_0,
378                                 POLICY_HND *connect_pol)
379 {
380         prs_struct data;
381         prs_struct rdata;
382         SAMR_Q_CONNECT q_o;
383         SAMR_R_CONNECT r_o;
384
385         if (srv_name == NULL || connect_pol == NULL)
386                 return False;
387
388         /* create and send a MSRPC command with api SAMR_CONNECT */
389
390         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
391         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
392
393         DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
394                                 srv_name, unknown_0));
395
396         /* store the parameters */
397         init_samr_q_connect(&q_o, srv_name, unknown_0);
398
399         /* turn parameters into data stream */
400         if(!samr_io_q_connect("", &q_o,  &data, 0)) {
401                 prs_mem_free(&data);
402                 prs_mem_free(&rdata);
403                 return False;
404         }
405
406         /* send the data on \PIPE\ */
407         if (!rpc_api_pipe_req(cli, SAMR_CONNECT, &data, &rdata)) {
408                 prs_mem_free(&data);
409                 prs_mem_free(&rdata);
410                 return False;
411         }
412
413         prs_mem_free(&data);
414
415         if(!samr_io_r_connect("", &r_o, &rdata, 0)) {
416                 prs_mem_free(&rdata);
417                 return False;
418         }
419                 
420         if (r_o.status != 0) {
421                 /* report error code */
422                 DEBUG(0,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
423                 prs_mem_free(&rdata);
424                 return False;
425         }
426
427         memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
428
429         prs_mem_free(&rdata);
430
431         return True;
432 }
433
434 /****************************************************************************
435 do a SAMR Open User
436 ****************************************************************************/
437 BOOL do_samr_open_user(struct cli_state *cli, 
438                                 POLICY_HND *pol, uint32 unk_0, uint32 rid, 
439                                 POLICY_HND *user_pol)
440 {
441         prs_struct data;
442         prs_struct rdata;
443         SAMR_Q_OPEN_USER q_o;
444         SAMR_R_OPEN_USER r_o;
445
446         if (pol == NULL || user_pol == NULL)
447                 return False;
448
449         /* create and send a MSRPC command with api SAMR_OPEN_USER */
450
451         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
452         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
453
454         DEBUG(4,("SAMR Open User.  unk_0: %08x RID:%x\n",
455                   unk_0, rid));
456
457         /* store the parameters */
458         init_samr_q_open_user(&q_o, pol, unk_0, rid);
459
460         /* turn parameters into data stream */
461         if(!samr_io_q_open_user("", &q_o,  &data, 0)) {
462                 prs_mem_free(&data);
463                 prs_mem_free(&rdata);
464                 return False;
465         }
466
467         /* send the data on \PIPE\ */
468         if (!rpc_api_pipe_req(cli, SAMR_OPEN_USER, &data, &rdata)) {
469                 prs_mem_free(&data);
470                 prs_mem_free(&rdata);
471                 return False;
472         }
473
474         prs_mem_free(&data);
475
476         if(!samr_io_r_open_user("", &r_o, &rdata, 0)) {
477                 prs_mem_free(&rdata);
478                 return False;
479         }
480                 
481         if (r_o.status != 0) {
482                 /* report error code */
483                 DEBUG(0,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
484                 prs_mem_free(&rdata);
485                 return False;
486         }
487
488         memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
489
490         prs_mem_free(&rdata);
491
492         return True;
493 }
494
495 /****************************************************************************
496 do a SAMR Open Domain
497 ****************************************************************************/
498 BOOL do_samr_open_domain(struct cli_state *cli, 
499                                 POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
500                                 POLICY_HND *domain_pol)
501 {
502         prs_struct data;
503         prs_struct rdata;
504         pstring sid_str;
505         SAMR_Q_OPEN_DOMAIN q_o;
506         SAMR_R_OPEN_DOMAIN r_o;
507
508         if (connect_pol == NULL || sid == NULL || domain_pol == NULL)
509                 return False;
510
511         /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
512
513         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
514         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
515
516         sid_to_string(sid_str, sid);
517         DEBUG(4,("SAMR Open Domain.  SID:%s RID:%x\n", sid_str, rid));
518
519         /* store the parameters */
520         init_samr_q_open_domain(&q_o, connect_pol, rid, sid);
521
522         /* turn parameters into data stream */
523         if(!samr_io_q_open_domain("", &q_o,  &data, 0)) {
524                 prs_mem_free(&data);
525                 prs_mem_free(&rdata);
526                 return False;
527         }
528
529         /* send the data on \PIPE\ */
530         if (!rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &data, &rdata)) {
531                 prs_mem_free(&data);
532                 prs_mem_free(&rdata);
533                 return False;
534         }
535
536         prs_mem_free(&data);
537
538         if(!samr_io_r_open_domain("", &r_o, &rdata, 0)) {
539                 prs_mem_free(&rdata);
540                 return False;
541         }
542
543         if (r_o.status != 0) {
544                 /* report error code */
545                 DEBUG(0,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
546                 prs_mem_free(&rdata);
547                 return False;
548         }
549
550         memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
551
552         prs_mem_free(&rdata);
553
554         return True;
555 }
556
557 #if 0
558
559 /* CURRENTLY DOES NOT COMPILE AND IS NOT USED ANYWHERE. JRA. */
560
561 /****************************************************************************
562 do a SAMR Query Unknown 12
563 ****************************************************************************/
564 BOOL do_samr_query_unknown_12(struct cli_state *cli, 
565                                 POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
566                                 uint32 *num_aliases,
567                                 fstring als_names    [MAX_LOOKUP_SIDS],
568                                 uint32  num_als_users[MAX_LOOKUP_SIDS])
569 {
570         prs_struct data;
571         prs_struct rdata;
572         SAMR_Q_LOOKUP_RIDS q_o;
573         SAMR_R_LOOKUP_RIDS r_o;
574
575         if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL ||
576             num_aliases == NULL || als_names == NULL || num_als_users == NULL )
577                         return False;
578
579         /* create and send a MSRPC command with api SAMR_UNKNOWN_12 */
580
581         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
582         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
583
584         DEBUG(4,("SAMR Query Unknown 12.\n"));
585
586         /* store the parameters */
587         init_samr_q_lookup_rids(&q_o, pol, rid, num_gids, gids);
588
589         /* turn parameters into data stream */
590         if(!samr_io_q_lookup_rids("", &q_o,  &data, 0)) {
591                 prs_mem_free(&data);
592                 prs_mem_free(&rdata);
593                 return False;
594         }
595
596         /* send the data on \PIPE\ */
597         if (!rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &data, &rdata)) {
598                 prs_mem_free(&data);
599                 prs_mem_free(&rdata);
600                 return False;
601         }
602
603         prs_mem_free(&data);
604
605         if(!samr_io_r_lookup_rids("", &r_o, &rdata, 0)) {
606                 prs_mem_free(&rdata);
607                 return False;
608         }
609                 
610         if (r_o.status != 0) {
611                 /* report error code */
612                 DEBUG(0,("SAMR_R_UNKNOWN_12: %s\n", get_nt_error_msg(r_o.status)));
613                 prs_mem_free(&rdata);
614                 return False;
615         }
616
617         if (r_o.ptr_aliases != 0 && r_o.ptr_als_usrs != 0 &&
618             r_o.num_als_usrs1 == r_o.num_aliases1) {
619                 int i;
620
621                 *num_aliases = r_o.num_aliases1;
622
623                 for (i = 0; i < r_o.num_aliases1; i++) {
624                         fstrcpy(als_names[i], dos_unistrn2(r_o.uni_als_name[i].buffer,
625                                                 r_o.uni_als_name[i].uni_str_len));
626                 }
627                 for (i = 0; i < r_o.num_als_usrs1; i++) {
628                         num_als_users[i] = r_o.num_als_usrs[i];
629                 }
630         } else if (r_o.ptr_aliases == 0 && r_o.ptr_als_usrs == 0) {
631                 *num_aliases = 0;
632         } else {
633                 prs_mem_free(&rdata);
634                 return False;
635         }
636
637         prs_mem_free(&rdata);
638
639         return True;
640 }
641 #endif
642
643 /****************************************************************************
644 do a SAMR Query User Groups
645 ****************************************************************************/
646 BOOL do_samr_query_usergroups(struct cli_state *cli, 
647                                 POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid)
648 {
649         prs_struct data;
650         prs_struct rdata;
651         SAMR_Q_QUERY_USERGROUPS q_o;
652         SAMR_R_QUERY_USERGROUPS r_o;
653
654         if (pol == NULL || gid == NULL || num_groups == 0)
655                 return False;
656
657         /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
658
659         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
660         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
661
662         DEBUG(4,("SAMR Query User Groups.\n"));
663
664         /* store the parameters */
665         init_samr_q_query_usergroups(&q_o, pol);
666
667         /* turn parameters into data stream */
668         if(!samr_io_q_query_usergroups("", &q_o,  &data, 0)) {
669                 prs_mem_free(&data);
670                 prs_mem_free(&rdata);
671                 return False;
672         }
673
674         /* send the data on \PIPE\ */
675         if (!rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &data, &rdata)) {
676                 prs_mem_free(&data);
677                 prs_mem_free(&rdata);
678                 return False;
679         }
680
681         prs_mem_free(&data);
682
683         /* get user info */
684         r_o.gid = gid;
685
686         if(!samr_io_r_query_usergroups("", &r_o, &rdata, 0)) {
687                 prs_mem_free(&rdata);
688                 return False;
689         }
690                 
691         if (r_o.status != 0) {
692                 /* report error code */
693                 DEBUG(0,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
694                 prs_mem_free(&rdata);
695                 return False;
696         }
697
698         *num_groups = r_o.num_entries;
699
700         prs_mem_free(&rdata);
701
702         return True;
703 }
704
705 #if 0
706
707 /* CURRENTLY DOES NOT COMPILE WITH THE NEW SAMR PARSE CODE. JRA */
708
709 /****************************************************************************
710 do a SAMR Query User Info
711 ****************************************************************************/
712 BOOL do_samr_query_userinfo(struct cli_state *cli, 
713                                 POLICY_HND *pol, uint16 switch_value, void* usr)
714 {
715         prs_struct data;
716         prs_struct rdata;
717         SAMR_Q_QUERY_USERINFO q_o;
718         SAMR_R_QUERY_USERINFO r_o;
719
720         if (pol == NULL || usr == NULL || switch_value == 0)
721                 return False;
722
723         /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
724
725         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
726         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
727
728         DEBUG(4,("SAMR Query User Info.  level: %d\n", switch_value));
729
730         /* store the parameters */
731         init_samr_q_query_userinfo(&q_o, pol, switch_value);
732
733         /* turn parameters into data stream */
734         if(!samr_io_q_query_userinfo("", &q_o,  &data, 0)) {
735                 prs_mem_free(&data);
736                 prs_mem_free(&rdata);
737                 return False;
738         }
739
740         /* send the data on \PIPE\ */
741         if (!rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &data, &rdata)) {
742                 prs_mem_free(&data);
743                 prs_mem_free(&rdata);
744                 return False;
745         }
746
747         prs_mem_free(&data);
748
749         /* get user info */
750         r_o.info.id = usr;
751
752         if(!samr_io_r_query_userinfo("", &r_o, &rdata, 0)) {
753                 prs_mem_free(&rdata);
754                 return False;
755         }
756                 
757         if (r_o.status != 0) {
758                 /* report error code */
759                 DEBUG(0,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
760                 prs_mem_free(&rdata);
761                 return False;
762         }
763
764         if (r_o.switch_value != switch_value) {
765                 DEBUG(0,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
766                           r_o.switch_value));
767                 prs_mem_free(&rdata);
768                 return False;
769         }
770
771         if (r_o.ptr == 0) {
772                 prs_mem_free(&rdata);
773                 return False;
774         }
775
776         prs_mem_free(&rdata);
777
778         return True;
779 }
780
781 #endif
782
783 /****************************************************************************
784 do a SAMR Close
785 ****************************************************************************/
786 BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd)
787 {
788         prs_struct data;
789         prs_struct rdata;
790         SAMR_Q_CLOSE_HND q_c;
791         SAMR_R_CLOSE_HND r_c;
792
793         if (hnd == NULL)
794                 return False;
795
796         prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
797         prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
798
799         /* create and send a MSRPC command with api SAMR_CLOSE_HND */
800
801         DEBUG(4,("SAMR Close\n"));
802
803         /* store the parameters */
804         init_samr_q_close_hnd(&q_c, hnd);
805
806         /* turn parameters into data stream */
807         if(!samr_io_q_close_hnd("", &q_c,  &data, 0)) {
808                 prs_mem_free(&data);
809                 prs_mem_free(&rdata);
810                 return False;
811         }
812
813         /* send the data on \PIPE\ */
814         if (!rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &data, &rdata)) {
815                 prs_mem_free(&data);
816                 prs_mem_free(&rdata);
817                 return False;
818         }
819
820         prs_mem_free(&data);
821
822         if(!samr_io_r_close_hnd("", &r_c, &rdata, 0)) {
823                 prs_mem_free(&rdata);
824                 return False;
825         }
826
827         if (r_c.status != 0) {
828                 /* report error code */
829                 DEBUG(0,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
830                 prs_mem_free(&rdata);
831                 return False;
832         }
833
834         /* check that the returned policy handle is all zeros */
835
836         if (IVAL(&r_c.pol.data1,0) || IVAL(&r_c.pol.data2,0) || SVAL(&r_c.pol.data3,0) ||
837                 SVAL(&r_c.pol.data4,0) || IVAL(r_c.pol.data5,0) || IVAL(r_c.pol.data5,4) ) {
838                         DEBUG(0,("SAMR_CLOSE_HND: non-zero handle returned\n"));
839                         prs_mem_free(&rdata);
840                         return False;
841         }       
842
843         prs_mem_free(&rdata);
844
845         return True;
846 }