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