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