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