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