9a68016c666902875453a48b949319db356de0f9
[kai/samba.git] / source3 / rpc_client / cli_samr.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NT Domain Authentication SMB / MSRPC client
5    Copyright (C) Andrew Tridgell 1994-1997
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
7    
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
24
25 #ifdef SYSLOG
26 #undef SYSLOG
27 #endif
28
29 #include "includes.h"
30 #include "nterr.h"
31
32 extern int DEBUGLEVEL;
33
34 /****************************************************************************
35 do a SAMR change user password command
36 ****************************************************************************/
37 BOOL samr_chgpasswd_user( struct cli_connection *con, 
38                 char *srv_name, char *user_name,
39                 char nt_newpass[516], uchar nt_oldhash[16],
40                 char lm_newpass[516], uchar lm_oldhash[16])
41 {
42         prs_struct data;
43         prs_struct rdata;
44
45         SAMR_Q_CHGPASSWD_USER q_e;
46         BOOL valid_pwc = False;
47
48         /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
49
50         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
51         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
52
53         DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
54                 srv_name, user_name));
55
56         make_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
57                                    nt_newpass, nt_oldhash,
58                                    lm_newpass, lm_oldhash);
59
60         /* turn parameters into data stream */
61         samr_io_q_chgpasswd_user("", &q_e, &data, 0);
62
63         dbgflush();
64
65         /* send the data on \PIPE\ */
66         if (rpc_con_pipe_req(con, SAMR_CHGPASSWD_USER, &data, &rdata))
67         {
68                 SAMR_R_CHGPASSWD_USER r_e;
69                 BOOL p;
70
71                 samr_io_r_chgpasswd_user("", &r_e, &rdata, 0);
72
73                 p = rdata.offset != 0;
74                 if (p && r_e.status != 0)
75                 {
76                         /* report error code */
77                         DEBUG(4,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
78                         p = False;
79                 }
80
81                 if (p)
82                 {
83                         valid_pwc = True;
84                 }
85         }
86
87         prs_mem_free(&data   );
88         prs_mem_free(&rdata  );
89
90         return valid_pwc;
91 }
92
93
94 /****************************************************************************
95 do a SAMR unknown 0x38 command
96 ****************************************************************************/
97 BOOL samr_unknown_38(struct cli_connection *con, char *srv_name)
98 {
99         prs_struct data;
100         prs_struct rdata;
101
102         SAMR_Q_UNKNOWN_38 q_e;
103         BOOL valid_un8 = False;
104
105         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
106
107         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
108         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
109
110         DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name));
111
112         make_samr_q_unknown_38(&q_e, srv_name);
113
114         /* turn parameters into data stream */
115         samr_io_q_unknown_38("", &q_e, &data, 0);
116
117         /* send the data on \PIPE\ */
118         if (rpc_con_pipe_req(con, SAMR_GET_DOM_PWINFO, &data, &rdata))
119         {
120                 SAMR_R_UNKNOWN_38 r_e;
121                 BOOL p;
122
123                 samr_io_r_unknown_38("", &r_e, &rdata, 0);
124
125                 p = rdata.offset != 0;
126 #if 0
127                 if (p && r_e.status != 0)
128                 {
129                         /* report error code */
130                         DEBUG(4,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status)));
131                         p = False;
132                 }
133 #endif
134                 if (p)
135                 {
136                         valid_un8 = True;
137                 }
138         }
139
140         prs_mem_free(&data   );
141         prs_mem_free(&rdata  );
142
143         return valid_un8;
144 }
145
146 /****************************************************************************
147 do a SAMR unknown 0x8 command
148 ****************************************************************************/
149 BOOL samr_query_dom_info(  POLICY_HND *domain_pol, uint16 switch_value,
150                                 SAM_UNK_CTR *ctr)
151 {
152         prs_struct data;
153         prs_struct rdata;
154
155         SAMR_Q_QUERY_DOMAIN_INFO q_e;
156         BOOL valid_un8 = False;
157
158         DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
159
160         if (domain_pol == NULL) return False;
161
162         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
163
164         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
165         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
166
167         /* store the parameters */
168         make_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
169
170         /* turn parameters into data stream */
171         samr_io_q_query_dom_info("", &q_e, &data, 0);
172
173         /* send the data on \PIPE\ */
174         if (rpc_hnd_pipe_req(domain_pol, SAMR_QUERY_DOMAIN_INFO, &data, &rdata))
175         {
176                 SAMR_R_QUERY_DOMAIN_INFO r_e;
177                 BOOL p;
178
179                 r_e.ctr = ctr;
180                 samr_io_r_query_dom_info("", &r_e, &rdata, 0);
181
182                 p = rdata.offset != 0;
183                 if (p && r_e.status != 0)
184                 {
185                         /* report error code */
186                         DEBUG(4,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status)));
187                         p = False;
188                 }
189
190                 if (p)
191                 {
192                         valid_un8 = True;
193                 }
194         }
195
196         prs_mem_free(&data   );
197         prs_mem_free(&rdata  );
198
199         return valid_un8;
200 }
201
202 /****************************************************************************
203 do a SAMR enumerate Domains
204 ****************************************************************************/
205 uint32 samr_enum_domains(  POLICY_HND *pol,
206                                 uint32 *start_idx, uint32 size,
207                                 struct acct_info **sam,
208                                 uint32 *num_sam_domains)
209 {
210         uint32 status = 0x0;
211         prs_struct data;
212         prs_struct rdata;
213
214         SAMR_Q_ENUM_DOMAINS q_e;
215
216         DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
217
218         if (pol == NULL || num_sam_domains == NULL || sam == NULL)
219         {
220                 return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
221         }
222
223         /* create and send a MSRPC command with api SAMR_ENUM_DOMAINS */
224
225         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
226         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
227
228         /* store the parameters */
229         make_samr_q_enum_domains(&q_e, pol, *start_idx, size);
230
231         /* turn parameters into data stream */
232         samr_io_q_enum_domains("", &q_e, &data, 0);
233
234         /* send the data on \PIPE\ */
235         if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOMAINS, &data, &rdata))
236         {
237                 SAMR_R_ENUM_DOMAINS r_e;
238                 BOOL p;
239
240                 samr_io_r_enum_domains("", &r_e, &rdata, 0);
241
242                 status = r_e.status;
243                 p = rdata.offset != 0;
244                 if (p && r_e.status != 0)
245                 {
246                         /* report error code */
247                         DEBUG(4,("SAMR_R_ENUM_DOMAINS: %s\n", get_nt_error_msg(r_e.status)));
248                         p = (r_e.status == STATUS_MORE_ENTRIES);
249                 }
250
251                 if (p)
252                 {
253                         uint32 i = (*num_sam_domains);
254                         uint32 j = 0;
255                         uint32 name_idx = 0;
256
257                         (*num_sam_domains) += r_e.num_entries2;
258                         (*sam) = (struct acct_info*) Realloc((*sam),
259                                sizeof(struct acct_info) * (*num_sam_domains));
260                                     
261                         if ((*sam) == NULL)
262                         {
263                                 (*num_sam_domains) = 0;
264                                 i = 0;
265                         }
266
267                         for (j = 0; i < (*num_sam_domains) && j < r_e.num_entries2; j++, i++)
268                         {
269                                 (*sam)[i].rid = r_e.sam[j].rid;
270                                 (*sam)[i].acct_name[0] = 0;
271                                 (*sam)[i].acct_desc[0] = 0;
272                                 if (r_e.sam[j].hdr_name.buffer)
273                                 {
274                                         unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_dom_name[name_idx], sizeof((*sam)[i].acct_name)-1);
275                                         name_idx++;
276                                 }
277                                 DEBUG(5,("samr_enum_domains: idx: %4d rid: %8x acct: %s\n",
278                                           i, (*sam)[i].rid, (*sam)[i].acct_name));
279                         }
280                         (*start_idx) = r_e.next_idx;
281                 }
282                 else if (status == 0x0)
283                 {
284                         status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
285                 }
286
287                 if (r_e.sam != NULL)
288                 {
289                         free(r_e.sam);
290                 }
291                 if (r_e.uni_dom_name != NULL)
292                 {
293                         free(r_e.uni_dom_name);
294                 }
295         }
296
297         prs_mem_free(&data   );
298         prs_mem_free(&rdata  );
299
300         return status;
301 }
302
303 /****************************************************************************
304 do a SAMR enumerate groups
305 ****************************************************************************/
306 uint32 samr_enum_dom_groups(  POLICY_HND *pol,
307                                 uint32 *start_idx, uint32 size,
308                                 struct acct_info **sam,
309                                 uint32 *num_sam_groups)
310 {
311         uint32 status = 0x0;
312         prs_struct data;
313         prs_struct rdata;
314
315         SAMR_Q_ENUM_DOM_GROUPS q_e;
316
317         DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
318
319         if (pol == NULL || num_sam_groups == NULL)
320         {
321                 return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
322         }
323
324         /* create and send a MSRPC command with api SAMR_ENUM_DOM_GROUPS */
325
326         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
327         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
328
329         /* store the parameters */
330         make_samr_q_enum_dom_groups(&q_e, pol, *start_idx, size);
331
332         /* turn parameters into data stream */
333         samr_io_q_enum_dom_groups("", &q_e, &data, 0);
334
335         /* send the data on \PIPE\ */
336         if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_GROUPS, &data, &rdata))
337         {
338                 SAMR_R_ENUM_DOM_GROUPS r_e;
339                 BOOL p;
340
341                 samr_io_r_enum_dom_groups("", &r_e, &rdata, 0);
342
343                 status = r_e.status;
344                 p = rdata.offset != 0;
345                 if (p && r_e.status != 0)
346                 {
347                         /* report error code */
348                         DEBUG(4,("SAMR_R_ENUM_DOM_GROUPS: %s\n", get_nt_error_msg(r_e.status)));
349                         p = (r_e.status == STATUS_MORE_ENTRIES);
350                 }
351
352                 if (p)
353                 {
354                         uint32 i = (*num_sam_groups);
355                         uint32 j = 0;
356                         uint32 name_idx = 0;
357
358                         (*num_sam_groups) += r_e.num_entries2;
359                         (*sam) = (struct acct_info*) Realloc((*sam),
360                                sizeof(struct acct_info) * (*num_sam_groups));
361                                     
362                         if ((*sam) == NULL)
363                         {
364                                 (*num_sam_groups) = 0;
365                                 i = 0;
366                         }
367
368                         for (j = 0; i < (*num_sam_groups) && j < r_e.num_entries2; j++, i++)
369                         {
370                                 (*sam)[i].rid = r_e.sam[j].rid;
371                                 (*sam)[i].acct_name[0] = 0;
372                                 (*sam)[i].acct_desc[0] = 0;
373                                 if (r_e.sam[j].hdr_name.buffer)
374                                 {
375                                         unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_grp_name[name_idx], sizeof((*sam)[i].acct_name)-1);
376                                         name_idx++;
377                                 }
378                                 DEBUG(5,("samr_enum_dom_groups: idx: %4d rid: %8x acct: %s\n",
379                                           i, (*sam)[i].rid, (*sam)[i].acct_name));
380                         }
381                         (*start_idx) = r_e.next_idx;
382                 }
383                 else if (status == 0x0)
384                 {
385                         status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
386                 }
387
388                 if (r_e.sam != NULL)
389                 {
390                         free(r_e.sam);
391                 }
392                 if (r_e.uni_grp_name != NULL)
393                 {
394                         free(r_e.uni_grp_name);
395                 }
396         }
397
398         prs_mem_free(&data   );
399         prs_mem_free(&rdata  );
400
401         return status;
402 }
403
404 /****************************************************************************
405 do a SAMR enumerate aliases
406 ****************************************************************************/
407 uint32 samr_enum_dom_aliases(  POLICY_HND *pol,
408                                 uint32 *start_idx, uint32 size,
409                                 struct acct_info **sam,
410                                 uint32 *num_sam_aliases)
411 {
412         uint32 status = 0x0;
413         prs_struct data;
414         prs_struct rdata;
415
416         SAMR_Q_ENUM_DOM_ALIASES q_e;
417
418         DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
419
420         if (pol == NULL || num_sam_aliases == NULL)
421         {
422                 return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
423         }
424
425         /* create and send a MSRPC command with api SAMR_ENUM_DOM_ALIASES */
426
427         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
428         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
429
430         /* store the parameters */
431         make_samr_q_enum_dom_aliases(&q_e, pol, *start_idx, size);
432
433         /* turn parameters into data stream */
434         samr_io_q_enum_dom_aliases("", &q_e, &data, 0);
435
436         /* send the data on \PIPE\ */
437         if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_ALIASES, &data, &rdata))
438         {
439                 SAMR_R_ENUM_DOM_ALIASES r_e;
440                 BOOL p;
441
442                 samr_io_r_enum_dom_aliases("", &r_e, &rdata, 0);
443
444                 p = rdata.offset != 0;
445                 if (p && r_e.status != 0)
446                 {
447                         /* report error code */
448                         DEBUG(4,("SAMR_R_ENUM_DOM_ALIASES: %s\n", get_nt_error_msg(r_e.status)));
449                         p = (r_e.status == STATUS_MORE_ENTRIES);
450                 }
451
452                 if (p)
453                 {
454                         uint32 i = (*num_sam_aliases);
455                         uint32 j = 0;
456                         uint32 name_idx = 0;
457
458                         (*num_sam_aliases) += r_e.num_entries2;
459                         (*sam) = (struct acct_info*) Realloc((*sam),
460                                sizeof(struct acct_info) * (*num_sam_aliases));
461                                     
462                         if ((*sam) == NULL)
463                         {
464                                 (*num_sam_aliases) = 0;
465                                 i = 0;
466                         }
467
468                         for (j = 0; i < (*num_sam_aliases) && j < r_e.num_entries2; j++, i++)
469                         {
470                                 (*sam)[i].rid = r_e.sam[j].rid;
471                                 (*sam)[i].acct_name[0] = 0;
472                                 (*sam)[i].acct_desc[0] = 0;
473                                 if (r_e.sam[j].hdr_name.buffer)
474                                 {
475                                         unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_grp_name[name_idx], sizeof((*sam)[i].acct_name)-1);
476                                         name_idx++;
477                                 }
478                                 DEBUG(5,("samr_enum_dom_aliases: idx: %4d rid: %8x acct: %s\n",
479                                           i, (*sam)[i].rid, (*sam)[i].acct_name));
480                         }
481                         (*start_idx) = r_e.next_idx;
482                 }
483                 else if (status == 0x0)
484                 {
485                         status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
486                 }
487
488                 if (r_e.sam != NULL)
489                 {
490                         free(r_e.sam);
491                 }
492                 if (r_e.uni_grp_name != NULL)
493                 {
494                         free(r_e.uni_grp_name);
495                 }
496         }
497
498         prs_mem_free(&data   );
499         prs_mem_free(&rdata  );
500
501         return status;
502 }
503
504 /****************************************************************************
505 do a SAMR enumerate users
506 ****************************************************************************/
507 uint32 samr_enum_dom_users(  POLICY_HND *pol, uint32 *start_idx, 
508                                 uint16 acb_mask, uint16 unk_1, uint32 size,
509                                 struct acct_info **sam,
510                                 uint32 *num_sam_users)
511 {
512         uint32 status = 0x0;
513         prs_struct data;
514         prs_struct rdata;
515
516         SAMR_Q_ENUM_DOM_USERS q_e;
517
518         DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
519
520         if (pol == NULL || num_sam_users == NULL)
521         {
522                 return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
523         }
524
525         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
526
527         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
528         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
529
530         /* store the parameters */
531         make_samr_q_enum_dom_users(&q_e, pol, *start_idx,
532                                    acb_mask, unk_1, size);
533
534         /* turn parameters into data stream */
535         samr_io_q_enum_dom_users("", &q_e, &data, 0);
536
537         /* send the data on \PIPE\ */
538         if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_USERS, &data, &rdata))
539         {
540                 SAMR_R_ENUM_DOM_USERS r_e;
541                 BOOL p;
542
543                 samr_io_r_enum_dom_users("", &r_e, &rdata, 0);
544
545                 status = r_e.status;
546                 p = rdata.offset != 0;
547
548                 if (p && r_e.status != 0)
549                 {
550                         /* report error code */
551                         DEBUG(4,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
552                         p = (r_e.status == STATUS_MORE_ENTRIES);
553                 }
554
555                 if (p)
556                 {
557                         uint32 i = (*num_sam_users);
558                         uint32 j = 0;
559                         uint32 name_idx = 0;
560
561                         (*num_sam_users) += r_e.num_entries2;
562                         (*sam) = (struct acct_info*) Realloc((*sam),
563                                sizeof(struct acct_info) * (*num_sam_users));
564                                     
565                         if ((*sam) == NULL)
566                         {
567                                 (*num_sam_users) = 0;
568                                 i = 0;
569                         }
570
571                         for (j = 0; i < (*num_sam_users) && j < r_e.num_entries2; j++, i++)
572                         {
573                                 (*sam)[i].rid = r_e.sam[j].rid;
574                                 (*sam)[i].acct_name[0] = 0;
575                                 (*sam)[i].acct_desc[0] = 0;
576                                 if (r_e.sam[j].hdr_name.buffer)
577                                 {
578                                         unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_acct_name[name_idx], sizeof((*sam)[i].acct_name)-1);
579                                         name_idx++;
580                                 }
581                                 DEBUG(5,("samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
582                                           i, (*sam)[i].rid, (*sam)[i].acct_name));
583                         }
584                         (*start_idx) = r_e.next_idx;
585                 }
586                 else if (status == 0x0)
587                 {
588                         status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
589                 }
590
591                 if (r_e.sam != NULL)
592                 {
593                         free(r_e.sam);
594                 }
595                 if (r_e.uni_acct_name != NULL)
596                 {
597                         free(r_e.uni_acct_name);
598                 }
599         }
600         else
601         {
602                 status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
603         }
604
605         prs_mem_free(&data   );
606         prs_mem_free(&rdata  );
607
608         return status;
609 }
610
611 /****************************************************************************
612 do a SAMR Connect
613 ****************************************************************************/
614 BOOL samr_connect(  const char *srv_name, uint32 unknown_0,
615                                 POLICY_HND *connect_pol)
616 {
617         prs_struct data;
618         prs_struct rdata;
619
620         SAMR_Q_CONNECT q_o;
621         BOOL valid_pol = False;
622
623         struct cli_connection *con = NULL;
624
625         if (!cli_connection_init(srv_name, PIPE_SAMR, &con))
626         {
627                 return False;
628         }
629
630         DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
631                                 srv_name, unknown_0));
632
633         if (srv_name == NULL || connect_pol == NULL) return False;
634
635         /* create and send a MSRPC command with api SAMR_CONNECT */
636
637         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
638         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
639
640         /* store the parameters */
641         make_samr_q_connect(&q_o, srv_name, unknown_0);
642
643         /* turn parameters into data stream */
644         samr_io_q_connect("", &q_o,  &data, 0);
645
646         /* send the data on \PIPE\ */
647         if (rpc_con_pipe_req(con, SAMR_CONNECT, &data, &rdata))
648         {
649                 SAMR_R_CONNECT r_o;
650                 BOOL p;
651
652                 samr_io_r_connect("", &r_o, &rdata, 0);
653                 p = rdata.offset != 0;
654                 
655                 if (p && r_o.status != 0)
656                 {
657                         /* report error code */
658                         DEBUG(4,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
659                         p = False;
660                 }
661
662                 if (p)
663                 {
664                         memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
665                         valid_pol = register_policy_hnd(connect_pol) &&
666                                     set_policy_con(connect_pol, con,
667                                                          cli_connection_unlink);
668                 }
669         }
670
671         prs_mem_free(&data   );
672         prs_mem_free(&rdata  );
673
674         return valid_pol;
675 }
676
677 /****************************************************************************
678 do a SAMR Open User
679 ****************************************************************************/
680 BOOL samr_open_user(  const POLICY_HND *pol,
681                                 uint32 unk_0, uint32 rid, 
682                                 POLICY_HND *user_pol)
683 {
684         prs_struct data;
685         prs_struct rdata;
686
687         SAMR_Q_OPEN_USER q_o;
688         BOOL valid_pol = False;
689
690         DEBUG(4,("SAMR Open User.  unk_0: %08x RID:%x\n",
691                   unk_0, rid));
692
693         if (pol == NULL || user_pol == NULL) return False;
694
695         /* create and send a MSRPC command with api SAMR_OPEN_USER */
696
697         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
698         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
699
700         /* store the parameters */
701         make_samr_q_open_user(&q_o, pol, unk_0, rid);
702
703         /* turn parameters into data stream */
704         samr_io_q_open_user("", &q_o,  &data, 0);
705
706         /* send the data on \PIPE\ */
707         if (rpc_hnd_pipe_req(pol, SAMR_OPEN_USER, &data, &rdata))
708         {
709                 SAMR_R_OPEN_USER r_o;
710                 BOOL p;
711
712                 samr_io_r_open_user("", &r_o, &rdata, 0);
713                 p = rdata.offset != 0;
714                 
715                 if (p && r_o.status != 0)
716                 {
717                         /* report error code */
718                         DEBUG(4,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
719                         p = False;
720                 }
721
722                 if (p)
723                 {
724                         memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
725                         valid_pol = cli_pol_link(user_pol, pol);
726                 }
727         }
728
729         prs_mem_free(&data   );
730         prs_mem_free(&rdata  );
731
732         return valid_pol;
733 }
734
735 /****************************************************************************
736 do a SAMR Open Alias
737 ****************************************************************************/
738 BOOL samr_open_alias(  const POLICY_HND *domain_pol,
739                                 uint32 flags, uint32 rid,
740                                 POLICY_HND *alias_pol)
741 {
742         prs_struct data;
743         prs_struct rdata;
744
745         SAMR_Q_OPEN_ALIAS q_o;
746         BOOL valid_pol = False;
747
748         DEBUG(4,("SAMR Open Alias. RID:%x\n", rid));
749
750         if (alias_pol == NULL || domain_pol == NULL) return False;
751
752         /* create and send a MSRPC command with api SAMR_OPEN_ALIAS */
753
754         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
755         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
756
757         /* store the parameters */
758         make_samr_q_open_alias(&q_o, domain_pol, flags, rid);
759
760         /* turn parameters into data stream */
761         samr_io_q_open_alias("", &q_o,  &data, 0);
762
763         /* send the data on \PIPE\ */
764         if (rpc_hnd_pipe_req(domain_pol, SAMR_OPEN_ALIAS, &data, &rdata))
765         {
766                 SAMR_R_OPEN_ALIAS r_o;
767                 BOOL p;
768
769                 samr_io_r_open_alias("", &r_o, &rdata, 0);
770                 p = rdata.offset != 0;
771
772                 if (p && r_o.status != 0)
773                 {
774                         /* report error code */
775                         DEBUG(4,("SAMR_R_OPEN_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
776                         p = False;
777                 }
778
779                 if (p)
780                 {
781                         memcpy(alias_pol, &r_o.pol, sizeof(r_o.pol));
782                         valid_pol = cli_pol_link(alias_pol, domain_pol);
783                 }
784         }
785
786         prs_mem_free(&data   );
787         prs_mem_free(&rdata  );
788
789         return valid_pol;
790 }
791
792 /****************************************************************************
793 do a SAMR Delete Alias Member
794 ****************************************************************************/
795 BOOL samr_del_aliasmem(  POLICY_HND *alias_pol, DOM_SID *sid)
796 {
797         prs_struct data;
798         prs_struct rdata;
799
800         SAMR_Q_DEL_ALIASMEM q_o;
801         BOOL valid_pol = False;
802
803         if (alias_pol == NULL || sid == NULL) return False;
804
805         /* create and send a MSRPC command with api SAMR_DEL_ALIASMEM */
806
807         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
808         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
809
810         DEBUG(4,("SAMR Delete Alias Member.\n"));
811
812         /* store the parameters */
813         make_samr_q_del_aliasmem(&q_o, alias_pol, sid);
814
815         /* turn parameters into data stream */
816         samr_io_q_del_aliasmem("", &q_o,  &data, 0);
817
818         /* send the data on \PIPE\ */
819         if (rpc_hnd_pipe_req(alias_pol, SAMR_DEL_ALIASMEM, &data, &rdata))
820         {
821                 SAMR_R_DEL_ALIASMEM r_o;
822                 BOOL p;
823
824                 samr_io_r_del_aliasmem("", &r_o, &rdata, 0);
825                 p = rdata.offset != 0;
826
827                 if (p && r_o.status != 0)
828                 {
829                         /* report error code */
830                         DEBUG(4,("SAMR_R_DEL_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
831                         p = False;
832                 }
833
834                 if (p)
835                 {
836                         valid_pol = True;
837                 }
838         }
839
840         prs_mem_free(&data   );
841         prs_mem_free(&rdata  );
842
843         return valid_pol;
844 }
845
846 /****************************************************************************
847 do a SAMR Add Alias Member
848 ****************************************************************************/
849 BOOL samr_add_aliasmem(  POLICY_HND *alias_pol, DOM_SID *sid)
850 {
851         prs_struct data;
852         prs_struct rdata;
853
854         SAMR_Q_ADD_ALIASMEM q_o;
855         BOOL valid_pol = False;
856
857         if (alias_pol == NULL || sid == NULL) return False;
858
859         /* create and send a MSRPC command with api SAMR_ADD_ALIASMEM */
860
861         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
862         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
863
864         DEBUG(4,("SAMR Add Alias Member.\n"));
865
866         /* store the parameters */
867         make_samr_q_add_aliasmem(&q_o, alias_pol, sid);
868
869         /* turn parameters into data stream */
870         samr_io_q_add_aliasmem("", &q_o,  &data, 0);
871
872         /* send the data on \PIPE\ */
873         if (rpc_hnd_pipe_req(alias_pol, SAMR_ADD_ALIASMEM, &data, &rdata))
874         {
875                 SAMR_R_ADD_ALIASMEM r_o;
876                 BOOL p;
877
878                 samr_io_r_add_aliasmem("", &r_o, &rdata, 0);
879                 p = rdata.offset != 0;
880
881                 if (p && r_o.status != 0)
882                 {
883                         /* report error code */
884                         DEBUG(4,("SAMR_R_ADD_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
885                         p = False;
886                 }
887
888                 if (p)
889                 {
890                         valid_pol = True;
891                 }
892         }
893
894         prs_mem_free(&data   );
895         prs_mem_free(&rdata  );
896
897         return valid_pol;
898 }
899
900 /****************************************************************************
901 do a SAMR Delete Domain Alias
902 ****************************************************************************/
903 BOOL samr_delete_dom_alias(  POLICY_HND *alias_pol)
904 {
905         prs_struct data;
906         prs_struct rdata;
907
908         SAMR_Q_DELETE_DOM_ALIAS q_o;
909         BOOL valid_pol = False;
910
911         if (alias_pol == NULL) return False;
912
913         /* delete and send a MSRPC command with api SAMR_DELETE_DOM_ALIAS */
914
915         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
916         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
917
918         DEBUG(4,("SAMR Delete Domain Alias.\n"));
919
920         /* store the parameters */
921         make_samr_q_delete_dom_alias(&q_o, alias_pol);
922
923         /* turn parameters into data stream */
924         samr_io_q_delete_dom_alias("", &q_o,  &data, 0);
925
926         /* send the data on \PIPE\ */
927         if (rpc_hnd_pipe_req(alias_pol, SAMR_DELETE_DOM_ALIAS, &data, &rdata))
928         {
929                 SAMR_R_DELETE_DOM_ALIAS r_o;
930                 BOOL p;
931
932                 samr_io_r_delete_dom_alias("", &r_o, &rdata, 0);
933                 p = rdata.offset != 0;
934
935                 if (p && r_o.status != 0)
936                 {
937                         /* report error code */
938                         DEBUG(4,("SAMR_R_DELETE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
939                         p = False;
940                 }
941
942                 if (p)
943                 {
944                         valid_pol = True;
945                 }
946         }
947
948         prs_mem_free(&data   );
949         prs_mem_free(&rdata  );
950
951         return valid_pol;
952 }
953
954 /****************************************************************************
955 do a SAMR Create Domain User
956 ****************************************************************************/
957 uint32 samr_create_dom_user(  POLICY_HND *domain_pol, const char *acct_name,
958                                 uint32 unk_0, uint32 unk_1,
959                                 POLICY_HND *user_pol, uint32 *rid)
960 {
961         prs_struct data;
962         prs_struct rdata;
963         uint32 status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
964
965         SAMR_Q_CREATE_USER q_o;
966
967         if (user_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
968
969         /* create and send a MSRPC command with api SAMR_CREATE_USER */
970
971         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
972         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
973
974         DEBUG(4,("SAMR Create Domain User. Name:%s\n", acct_name));
975
976         /* store the parameters */
977         make_samr_q_create_user(&q_o, domain_pol, acct_name, unk_0, unk_1);
978
979         /* turn parameters into data stream */
980         samr_io_q_create_user("", &q_o,  &data, 0);
981
982         /* send the data on \PIPE\ */
983         if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_USER, &data, &rdata))
984         {
985                 SAMR_R_CREATE_USER r_o;
986                 BOOL p;
987
988                 samr_io_r_create_user("", &r_o, &rdata, 0);
989                 p = rdata.offset != 0;
990                 status = r_o.status;
991
992                 if (p && r_o.status != 0)
993                 {
994                         /* report error code */
995                         DEBUG(4,("SAMR_R_CREATE_USER: %s\n", get_nt_error_msg(r_o.status)));
996                         p = r_o.status != NT_STATUS_USER_EXISTS;
997                 }
998
999                 if (p)
1000                 {
1001                         memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
1002                         *rid = r_o.user_rid;
1003                         if (!cli_pol_link(user_pol, domain_pol))
1004                         {
1005                                 status = NT_STATUS_INVALID_HANDLE | 0xC0000000;
1006                         }
1007                 }
1008         }
1009
1010         prs_mem_free(&data   );
1011         prs_mem_free(&rdata  );
1012
1013         return status;
1014 }
1015
1016 /****************************************************************************
1017 do a SAMR Create Domain Alias
1018 ****************************************************************************/
1019 BOOL samr_create_dom_alias(  POLICY_HND *domain_pol, const char *acct_name,
1020                                 POLICY_HND *alias_pol, uint32 *rid)
1021 {
1022         prs_struct data;
1023         prs_struct rdata;
1024
1025         SAMR_Q_CREATE_DOM_ALIAS q_o;
1026         BOOL valid_pol = False;
1027
1028         if (alias_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
1029
1030         /* create and send a MSRPC command with api SAMR_CREATE_DOM_ALIAS */
1031
1032         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1033         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1034
1035         DEBUG(4,("SAMR Create Domain Alias. Name:%s\n", acct_name));
1036
1037         /* store the parameters */
1038         make_samr_q_create_dom_alias(&q_o, domain_pol, acct_name);
1039
1040         /* turn parameters into data stream */
1041         samr_io_q_create_dom_alias("", &q_o,  &data, 0);
1042
1043         /* send the data on \PIPE\ */
1044         if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_DOM_ALIAS, &data, &rdata))
1045         {
1046                 SAMR_R_CREATE_DOM_ALIAS r_o;
1047                 BOOL p;
1048
1049                 samr_io_r_create_dom_alias("", &r_o, &rdata, 0);
1050                 p = rdata.offset != 0;
1051
1052                 if (p && r_o.status != 0)
1053                 {
1054                         /* report error code */
1055                         DEBUG(4,("SAMR_R_CREATE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
1056                         p = False;
1057                 }
1058
1059                 if (p)
1060                 {
1061                         memcpy(alias_pol, &r_o.alias_pol, sizeof(r_o.alias_pol));
1062                         *rid = r_o.rid;
1063                         valid_pol = cli_pol_link(alias_pol, domain_pol);
1064                 }
1065         }
1066
1067         prs_mem_free(&data   );
1068         prs_mem_free(&rdata  );
1069
1070         return valid_pol;
1071 }
1072
1073 /****************************************************************************
1074 do a SAMR Get Alias Info
1075 ****************************************************************************/
1076 BOOL samr_query_aliasinfo(  POLICY_HND *alias_pol, uint16 switch_value,
1077                                 ALIAS_INFO_CTR *ctr)
1078 {
1079         prs_struct data;
1080         prs_struct rdata;
1081
1082         SAMR_Q_QUERY_ALIASINFO q_o;
1083         BOOL valid_pol = False;
1084
1085         if (alias_pol == NULL || ctr == NULL) return False;
1086
1087         /* create and send a MSRPC command with api SAMR_GET_ALIASINFO */
1088
1089         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1090         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1091
1092         DEBUG(4,("SAMR Get Alias Info\n"));
1093
1094         /* store the parameters */
1095         make_samr_q_query_aliasinfo(&q_o, alias_pol, switch_value);
1096
1097         /* turn parameters into data stream */
1098         samr_io_q_query_aliasinfo("", &q_o,  &data, 0);
1099
1100         /* send the data on \PIPE\ */
1101         if (rpc_hnd_pipe_req(alias_pol, SAMR_QUERY_ALIASINFO, &data, &rdata))
1102         {
1103                 SAMR_R_QUERY_ALIASINFO r_o;
1104                 BOOL p;
1105
1106                 /* get alias info */
1107                 r_o.ctr = ctr;
1108
1109                 samr_io_r_query_aliasinfo("", &r_o, &rdata, 0);
1110                 p = rdata.offset != 0;
1111
1112                 if (p && r_o.status != 0)
1113                 {
1114                         /* report error code */
1115                         DEBUG(4,("SAMR_R_QUERY_ALIASINFO: %s\n", get_nt_error_msg(r_o.status)));
1116                         p = False;
1117                 }
1118
1119                 if (p)
1120                 {
1121                         valid_pol = True;
1122                 }
1123         }
1124
1125         prs_mem_free(&data   );
1126         prs_mem_free(&rdata  );
1127
1128         return valid_pol;
1129 }
1130
1131 /****************************************************************************
1132 do a SAMR Set Alias Info
1133 ****************************************************************************/
1134 BOOL samr_set_aliasinfo(  POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
1135 {
1136         prs_struct data;
1137         prs_struct rdata;
1138
1139         SAMR_Q_SET_ALIASINFO q_o;
1140         BOOL valid_pol = False;
1141
1142         if (alias_pol == NULL || ctr == NULL) return False;
1143
1144         /* create and send a MSRPC command with api SAMR_SET_ALIASINFO */
1145
1146         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1147         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1148
1149         DEBUG(4,("SAMR Set Alias Info\n"));
1150
1151         /* store the parameters */
1152         make_samr_q_set_aliasinfo(&q_o, alias_pol, ctr);
1153
1154         /* turn parameters into data stream */
1155         samr_io_q_set_aliasinfo("", &q_o,  &data, 0);
1156
1157         /* send the data on \PIPE\ */
1158         if (rpc_hnd_pipe_req(alias_pol, SAMR_SET_ALIASINFO, &data, &rdata))
1159         {
1160                 SAMR_R_SET_ALIASINFO r_o;
1161                 BOOL p;
1162
1163                 samr_io_r_set_aliasinfo("", &r_o, &rdata, 0);
1164                 p = rdata.offset != 0;
1165
1166                 if (p && r_o.status != 0)
1167                 {
1168                         /* report error code */
1169                         DEBUG(4,("SAMR_R_SET_ALIASINFO: %s\n", get_nt_error_msg(r_o.status)));
1170                         p = False;
1171                 }
1172
1173                 if (p)
1174                 {
1175                         valid_pol = True;
1176                 }
1177         }
1178
1179         prs_mem_free(&data   );
1180         prs_mem_free(&rdata  );
1181
1182         return valid_pol;
1183 }
1184
1185 /****************************************************************************
1186 do a SAMR Open Group
1187 ****************************************************************************/
1188 BOOL samr_open_group(  const POLICY_HND *domain_pol,
1189                                 uint32 flags, uint32 rid,
1190                                 POLICY_HND *group_pol)
1191 {
1192         prs_struct data;
1193         prs_struct rdata;
1194
1195         SAMR_Q_OPEN_GROUP q_o;
1196         BOOL valid_pol = False;
1197
1198         DEBUG(4,("SAMR Open Group. RID:%x\n", rid));
1199
1200         if (group_pol == NULL || domain_pol == NULL) return False;
1201
1202         /* create and send a MSRPC command with api SAMR_OPEN_GROUP */
1203
1204         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1205         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1206
1207         /* store the parameters */
1208         make_samr_q_open_group(&q_o, domain_pol, flags, rid);
1209
1210         /* turn parameters into data stream */
1211         samr_io_q_open_group("", &q_o,  &data, 0);
1212
1213         /* send the data on \PIPE\ */
1214         if (rpc_hnd_pipe_req(domain_pol, SAMR_OPEN_GROUP, &data, &rdata))
1215         {
1216                 SAMR_R_OPEN_GROUP r_o;
1217                 BOOL p;
1218
1219                 samr_io_r_open_group("", &r_o, &rdata, 0);
1220                 p = rdata.offset != 0;
1221
1222                 if (p && r_o.status != 0)
1223                 {
1224                         /* report error code */
1225                         DEBUG(4,("SAMR_R_OPEN_GROUP: %s\n", get_nt_error_msg(r_o.status)));
1226                         p = False;
1227                 }
1228
1229                 if (p)
1230                 {
1231                         memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
1232                         valid_pol = cli_pol_link(group_pol, domain_pol);
1233                 }
1234         }
1235
1236         prs_mem_free(&data   );
1237         prs_mem_free(&rdata  );
1238
1239         return valid_pol;
1240 }
1241
1242 /****************************************************************************
1243 do a SAMR Delete Group Member
1244 ****************************************************************************/
1245 BOOL samr_del_groupmem(  POLICY_HND *group_pol, uint32 rid)
1246 {
1247         prs_struct data;
1248         prs_struct rdata;
1249
1250         SAMR_Q_DEL_GROUPMEM q_o;
1251         BOOL valid_pol = False;
1252
1253         if (group_pol == NULL) return False;
1254
1255         /* create and send a MSRPC command with api SAMR_DEL_GROUPMEM */
1256
1257         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1258         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1259
1260         DEBUG(4,("SAMR Delete Group Member.\n"));
1261
1262         /* store the parameters */
1263         make_samr_q_del_groupmem(&q_o, group_pol, rid);
1264
1265         /* turn parameters into data stream */
1266         samr_io_q_del_groupmem("", &q_o,  &data, 0);
1267
1268         /* send the data on \PIPE\ */
1269         if (rpc_hnd_pipe_req(group_pol, SAMR_DEL_GROUPMEM, &data, &rdata))
1270         {
1271                 SAMR_R_DEL_GROUPMEM r_o;
1272                 BOOL p;
1273
1274                 samr_io_r_del_groupmem("", &r_o, &rdata, 0);
1275                 p = rdata.offset != 0;
1276
1277                 if (p && r_o.status != 0)
1278                 {
1279                         /* report error code */
1280                         DEBUG(4,("SAMR_R_DEL_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
1281                         p = False;
1282                 }
1283
1284                 if (p)
1285                 {
1286                         valid_pol = True;
1287                 }
1288         }
1289
1290         prs_mem_free(&data   );
1291         prs_mem_free(&rdata  );
1292
1293         return valid_pol;
1294 }
1295
1296 /****************************************************************************
1297 do a SAMR Add Group Member
1298 ****************************************************************************/
1299 BOOL samr_add_groupmem(  POLICY_HND *group_pol, uint32 rid)
1300 {
1301         prs_struct data;
1302         prs_struct rdata;
1303
1304         SAMR_Q_ADD_GROUPMEM q_o;
1305         BOOL valid_pol = False;
1306
1307         if (group_pol == NULL) return False;
1308
1309         /* create and send a MSRPC command with api SAMR_ADD_GROUPMEM */
1310
1311         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1312         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1313
1314         DEBUG(4,("SAMR Add Group Member.\n"));
1315
1316         /* store the parameters */
1317         make_samr_q_add_groupmem(&q_o, group_pol, rid);
1318
1319         /* turn parameters into data stream */
1320         samr_io_q_add_groupmem("", &q_o,  &data, 0);
1321
1322         /* send the data on \PIPE\ */
1323         if (rpc_hnd_pipe_req(group_pol, SAMR_ADD_GROUPMEM, &data, &rdata))
1324         {
1325                 SAMR_R_ADD_GROUPMEM r_o;
1326                 BOOL p;
1327
1328                 samr_io_r_add_groupmem("", &r_o, &rdata, 0);
1329                 p = rdata.offset != 0;
1330
1331                 if (p && r_o.status != 0)
1332                 {
1333                         /* report error code */
1334                         DEBUG(4,("SAMR_R_ADD_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
1335                         p = False;
1336                 }
1337
1338                 if (p)
1339                 {
1340                         valid_pol = True;
1341                 }
1342         }
1343
1344         prs_mem_free(&data   );
1345         prs_mem_free(&rdata  );
1346
1347         return valid_pol;
1348 }
1349
1350 /****************************************************************************
1351 do a SAMR Delete Domain Group
1352 ****************************************************************************/
1353 BOOL samr_delete_dom_group(  POLICY_HND *group_pol)
1354 {
1355         prs_struct data;
1356         prs_struct rdata;
1357
1358         SAMR_Q_DELETE_DOM_GROUP q_o;
1359         BOOL valid_pol = False;
1360
1361         if (group_pol == NULL) return False;
1362
1363         /* delete and send a MSRPC command with api SAMR_DELETE_DOM_GROUP */
1364
1365         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1366         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1367
1368         DEBUG(4,("SAMR Delete Domain Group.\n"));
1369
1370         /* store the parameters */
1371         make_samr_q_delete_dom_group(&q_o, group_pol);
1372
1373         /* turn parameters into data stream */
1374         samr_io_q_delete_dom_group("", &q_o,  &data, 0);
1375
1376         /* send the data on \PIPE\ */
1377         if (rpc_hnd_pipe_req(group_pol, SAMR_DELETE_DOM_GROUP, &data, &rdata))
1378         {
1379                 SAMR_R_DELETE_DOM_GROUP r_o;
1380                 BOOL p;
1381
1382                 samr_io_r_delete_dom_group("", &r_o, &rdata, 0);
1383                 p = rdata.offset != 0;
1384
1385                 if (p && r_o.status != 0)
1386                 {
1387                         /* report error code */
1388                         DEBUG(4,("SAMR_R_DELETE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
1389                         p = False;
1390                 }
1391
1392                 if (p)
1393                 {
1394                         valid_pol = True;
1395                 }
1396         }
1397
1398         prs_mem_free(&data   );
1399         prs_mem_free(&rdata  );
1400
1401         return valid_pol;
1402 }
1403
1404 /****************************************************************************
1405 do a SAMR Create Domain Group
1406 ****************************************************************************/
1407 BOOL samr_create_dom_group(  POLICY_HND *domain_pol, const char *acct_name,
1408                                 POLICY_HND *group_pol, uint32 *rid)
1409 {
1410         prs_struct data;
1411         prs_struct rdata;
1412
1413         SAMR_Q_CREATE_DOM_GROUP q_o;
1414         BOOL valid_pol = False;
1415
1416         if (group_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
1417
1418         /* create and send a MSRPC command with api SAMR_CREATE_DOM_GROUP */
1419
1420         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1421         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1422
1423         DEBUG(4,("SAMR Create Domain Group. Name:%s\n", acct_name));
1424
1425         /* store the parameters */
1426         make_samr_q_create_dom_group(&q_o, domain_pol, acct_name);
1427
1428         /* turn parameters into data stream */
1429         samr_io_q_create_dom_group("", &q_o,  &data, 0);
1430
1431         /* send the data on \PIPE\ */
1432         if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_DOM_GROUP, &data, &rdata))
1433         {
1434                 SAMR_R_CREATE_DOM_GROUP r_o;
1435                 BOOL p;
1436
1437                 samr_io_r_create_dom_group("", &r_o, &rdata, 0);
1438                 p = rdata.offset != 0;
1439
1440                 if (p && r_o.status != 0)
1441                 {
1442                         /* report error code */
1443                         DEBUG(4,("SAMR_R_CREATE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
1444                         p = False;
1445                 }
1446
1447                 if (p)
1448                 {
1449                         memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
1450                         *rid = r_o.rid;
1451                         valid_pol = cli_pol_link(group_pol, domain_pol);
1452                 }
1453         }
1454
1455         prs_mem_free(&data   );
1456         prs_mem_free(&rdata  );
1457
1458         return valid_pol;
1459 }
1460
1461 /****************************************************************************
1462 do a SAMR Set Group Info
1463 ****************************************************************************/
1464 BOOL samr_set_groupinfo(  POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
1465 {
1466         prs_struct data;
1467         prs_struct rdata;
1468
1469         SAMR_Q_SET_GROUPINFO q_o;
1470         BOOL valid_pol = False;
1471
1472         if (group_pol == NULL || ctr == NULL) return False;
1473
1474         /* create and send a MSRPC command with api SAMR_SET_GROUPINFO */
1475
1476         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1477         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1478
1479         DEBUG(4,("SAMR Set Group Info\n"));
1480
1481         /* store the parameters */
1482         make_samr_q_set_groupinfo(&q_o, group_pol, ctr);
1483
1484         /* turn parameters into data stream */
1485         samr_io_q_set_groupinfo("", &q_o,  &data, 0);
1486
1487         /* send the data on \PIPE\ */
1488         if (rpc_hnd_pipe_req(group_pol, SAMR_SET_GROUPINFO, &data, &rdata))
1489         {
1490                 SAMR_R_SET_GROUPINFO r_o;
1491                 BOOL p;
1492
1493                 samr_io_r_set_groupinfo("", &r_o, &rdata, 0);
1494                 p = rdata.offset != 0;
1495
1496                 if (p && r_o.status != 0)
1497                 {
1498                         /* report error code */
1499                         DEBUG(4,("SAMR_R_SET_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
1500                         p = False;
1501                 }
1502
1503                 if (p)
1504                 {
1505                         valid_pol = True;
1506                 }
1507         }
1508
1509         prs_mem_free(&data   );
1510         prs_mem_free(&rdata  );
1511
1512         return valid_pol;
1513 }
1514
1515 /****************************************************************************
1516 do a SAMR Open Domain
1517 ****************************************************************************/
1518 BOOL samr_open_domain(  const POLICY_HND *connect_pol,
1519                                 uint32 ace_perms,
1520                                 const DOM_SID *sid,
1521                                 POLICY_HND *domain_pol)
1522 {
1523         pstring sid_str;
1524         prs_struct data;
1525         prs_struct rdata;
1526
1527         SAMR_Q_OPEN_DOMAIN q_o;
1528         BOOL valid_pol = False;
1529
1530         if (DEBUGLEVEL >= 4)
1531         {
1532                 sid_to_string(sid_str, sid);
1533                 DEBUG(4,("SAMR Open Domain.  SID:%s Permissions:%x\n",
1534                                         sid_str, ace_perms));
1535         }
1536
1537         if (connect_pol == NULL || sid == NULL || domain_pol == NULL) return False;
1538
1539         /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
1540
1541         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1542         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1543
1544         /* store the parameters */
1545         make_samr_q_open_domain(&q_o, connect_pol, ace_perms, sid);
1546
1547         /* turn parameters into data stream */
1548         samr_io_q_open_domain("", &q_o,  &data, 0);
1549
1550         /* send the data on \PIPE\ */
1551         if (rpc_hnd_pipe_req(connect_pol, SAMR_OPEN_DOMAIN, &data, &rdata))
1552         {
1553                 SAMR_R_OPEN_DOMAIN r_o;
1554                 BOOL p;
1555
1556                 samr_io_r_open_domain("", &r_o, &rdata, 0);
1557                 p = rdata.offset != 0;
1558
1559                 if (p && r_o.status != 0)
1560                 {
1561                         /* report error code */
1562                         DEBUG(4,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
1563                         p = False;
1564                 }
1565
1566                 if (p)
1567                 {
1568                         memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
1569                         valid_pol = cli_pol_link(domain_pol, connect_pol);
1570                 }
1571         }
1572
1573         prs_mem_free(&data   );
1574         prs_mem_free(&rdata  );
1575
1576         return valid_pol;
1577 }
1578
1579 /****************************************************************************
1580 do a SAMR Query Lookup Domain
1581 ****************************************************************************/
1582 BOOL samr_query_lookup_domain(  POLICY_HND *pol, const char *dom_name,
1583                               DOM_SID *dom_sid)
1584 {
1585         prs_struct data;
1586         prs_struct rdata;
1587
1588         SAMR_Q_LOOKUP_DOMAIN q_o;
1589         BOOL valid_query = False;
1590
1591         if (pol == NULL || dom_name == NULL || dom_sid == NULL) return False;
1592
1593         /* create and send a MSRPC command with api SAMR_LOOKUP_DOMAIN */
1594
1595         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1596         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1597
1598         DEBUG(4,("SAMR Query Lookup Domain.\n"));
1599
1600         /* store the parameters */
1601         make_samr_q_lookup_domain(&q_o, pol, dom_name);
1602
1603         /* turn parameters into data stream */
1604         samr_io_q_lookup_domain("", &q_o, &data, 0);
1605
1606         /* send the data on \PIPE\ */
1607         if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_DOMAIN, &data, &rdata))
1608         {
1609                 SAMR_R_LOOKUP_DOMAIN r_o;
1610                 BOOL p;
1611
1612                 samr_io_r_lookup_domain("", &r_o, &rdata, 0);
1613                 p = rdata.offset != 0;
1614                 
1615                 if (p && r_o.status != 0)
1616                 {
1617                         /* report error code */
1618                         DEBUG(4,("SAMR_R_LOOKUP_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
1619                         p = False;
1620                 }
1621
1622                 if (p && r_o.ptr_sid != 0)
1623                 {
1624                         sid_copy(dom_sid, &r_o.dom_sid.sid);
1625                         valid_query = True;
1626                 }
1627         }
1628
1629         prs_mem_free(&data   );
1630         prs_mem_free(&rdata  );
1631
1632         return valid_query;
1633 }
1634
1635 /****************************************************************************
1636 do a SAMR Query Lookup Names
1637 ****************************************************************************/
1638 BOOL samr_query_lookup_names(  POLICY_HND *pol, uint32 flags,
1639                                 uint32 num_names, char **names,
1640                                 uint32 *num_rids,
1641                                 uint32 rid[MAX_LOOKUP_SIDS],
1642                                 uint32 type[MAX_LOOKUP_SIDS])
1643 {
1644         prs_struct data;
1645         prs_struct rdata;
1646
1647         SAMR_Q_LOOKUP_NAMES q_o;
1648         BOOL valid_query = False;
1649
1650         if (pol == NULL || flags == 0 || num_names == 0 || names == NULL ||
1651             num_rids == NULL || rid == NULL || type == NULL ) return False;
1652
1653         /* create and send a MSRPC command with api SAMR_LOOKUP_NAMES */
1654
1655         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1656         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1657
1658         DEBUG(4,("SAMR Query Lookup NAMES.\n"));
1659
1660         /* store the parameters */
1661         make_samr_q_lookup_names(&q_o, pol, flags, num_names, names);
1662
1663         /* turn parameters into data stream */
1664         samr_io_q_lookup_names("", &q_o, &data, 0);
1665
1666         /* send the data on \PIPE\ */
1667         if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_NAMES, &data, &rdata))
1668         {
1669                 SAMR_R_LOOKUP_NAMES r_o;
1670                 BOOL p;
1671
1672                 samr_io_r_lookup_names("", &r_o, &rdata, 0);
1673                 p = rdata.offset != 0;
1674                 
1675                 if (p && r_o.status != 0)
1676                 {
1677                         /* report error code */
1678                         DEBUG(4,("SAMR_R_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_o.status)));
1679                         p = r_o.status == 0x107;
1680                 }
1681
1682                 if (p)
1683                 {
1684                         if (r_o.ptr_rids != 0 && r_o.ptr_types != 0 &&
1685                             r_o.num_types1 == r_o.num_rids1)
1686                         {
1687                                 uint32 i;
1688
1689                                 valid_query = True;
1690                                 *num_rids = r_o.num_rids1;
1691
1692                                 for (i = 0; i < r_o.num_rids1; i++)
1693                                 {
1694                                         rid[i] = r_o.rid[i];
1695                                 }
1696                                 for (i = 0; i < r_o.num_types1; i++)
1697                                 {
1698                                         type[i] = r_o.type[i];
1699                                 }
1700                         }
1701                         else if (r_o.ptr_rids == 0 && r_o.ptr_types == 0)
1702                         {
1703                                 valid_query = True;
1704                                 *num_rids = 0;
1705                         }
1706                         else
1707                         {
1708                                 p = False;
1709                         }
1710                 }
1711         }
1712
1713         prs_mem_free(&data   );
1714         prs_mem_free(&rdata  );
1715
1716         return valid_query;
1717 }
1718
1719 /****************************************************************************
1720 do a SAMR Query Lookup RIDS
1721 ****************************************************************************/
1722 BOOL samr_query_lookup_rids(  const POLICY_HND *pol, uint32 flags,
1723                                 uint32 num_rids, uint32 *rids,
1724                                 uint32 *num_names,
1725                                 char   ***names,
1726                                 uint32 **type)
1727 {
1728         prs_struct data;
1729         prs_struct rdata;
1730
1731         SAMR_Q_LOOKUP_RIDS q_o;
1732         BOOL valid_query = False;
1733
1734         if (pol == NULL || flags == 0 || num_rids == 0 || rids == NULL ||
1735             num_names == NULL || names == NULL || type == NULL ) return False;
1736
1737         /* create and send a MSRPC command with api SAMR_LOOKUP_RIDS */
1738
1739         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1740         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1741
1742         DEBUG(4,("SAMR Query Lookup RIDs.\n"));
1743
1744         /* store the parameters */
1745         make_samr_q_lookup_rids(&q_o, pol, flags, num_rids, rids);
1746
1747         /* turn parameters into data stream */
1748         samr_io_q_lookup_rids("", &q_o,  &data, 0);
1749
1750         /* send the data on \PIPE\ */
1751         if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_RIDS, &data, &rdata))
1752         {
1753                 SAMR_R_LOOKUP_RIDS r_o;
1754                 BOOL p;
1755                 ZERO_STRUCT(r_o);
1756
1757                 samr_io_r_lookup_rids("", &r_o, &rdata, 0);
1758                 p = rdata.offset != 0;
1759                 
1760                 if (p && r_o.status != 0)
1761                 {
1762                         /* report error code */
1763                         DEBUG(4,("SAMR_R_LOOKUP_RIDS: %s\n", get_nt_error_msg(r_o.status)));
1764                         p = False;
1765                 }
1766
1767                 if (p)
1768                 {
1769                         if (r_o.ptr_names != 0 && r_o.ptr_types != 0 &&
1770                             r_o.num_types1 == r_o.num_names1)
1771                         {
1772                                 uint32 i;
1773                                 valid_query = True;
1774
1775                                 (*num_names) = 0;
1776                                 (*names) = NULL;
1777
1778                                 for (i = 0; i < r_o.num_names1; i++)
1779                                 {
1780                                         fstring tmp;
1781                                         unistr2_to_ascii(tmp, &r_o.uni_name[i], sizeof(tmp)-1);
1782                                         add_chars_to_array(num_names, names, tmp);
1783                                 }
1784
1785                                 if ((*num_names) != 0)
1786                                 {
1787                                         (*type) = (uint32*)malloc((*num_names) * sizeof(**type));
1788                                 }
1789
1790                                 for (i = 0; (*type) != NULL && i < r_o.num_types1; i++)
1791                                 {
1792                                         (*type)[i] = r_o.type[i];
1793                                 }
1794                         }
1795                         else if (r_o.ptr_names == 0 && r_o.ptr_types == 0)
1796                         {
1797                                 valid_query = True;
1798                                 *num_names = 0;
1799                                 *names = NULL;
1800                                 *type = NULL;
1801                         }
1802                         else
1803                         {
1804                                 p = False;
1805                         }
1806                 }
1807
1808                 samr_free_r_lookup_rids(&r_o);
1809         }
1810
1811         prs_mem_free(&data   );
1812         prs_mem_free(&rdata  );
1813
1814         return valid_query;
1815 }
1816
1817 /****************************************************************************
1818 do a SAMR Query Alias Members
1819 ****************************************************************************/
1820 BOOL samr_query_aliasmem(  const POLICY_HND *alias_pol, 
1821                                 uint32 *num_mem, DOM_SID2 *sid)
1822 {
1823         prs_struct data;
1824         prs_struct rdata;
1825
1826         SAMR_Q_QUERY_ALIASMEM q_o;
1827         BOOL valid_query = False;
1828
1829         DEBUG(4,("SAMR Query Alias Members.\n"));
1830
1831         if (alias_pol == NULL || sid == NULL || num_mem == NULL) return False;
1832
1833         /* create and send a MSRPC command with api SAMR_QUERY_ALIASMEM */
1834
1835         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1836         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1837
1838         /* store the parameters */
1839         make_samr_q_query_aliasmem(&q_o, alias_pol);
1840
1841         /* turn parameters into data stream */
1842         samr_io_q_query_aliasmem("", &q_o,  &data, 0);
1843
1844         /* send the data on \PIPE\ */
1845         if (rpc_hnd_pipe_req(alias_pol, SAMR_QUERY_ALIASMEM, &data, &rdata))
1846         {
1847                 SAMR_R_QUERY_ALIASMEM r_o;
1848                 BOOL p;
1849
1850                 /* get user info */
1851                 r_o.sid = sid;
1852
1853                 samr_io_r_query_aliasmem("", &r_o, &rdata, 0);
1854                 p = rdata.offset != 0;
1855                 
1856                 if (p && r_o.status != 0)
1857                 {
1858                         /* report error code */
1859                         DEBUG(4,("SAMR_R_QUERY_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
1860                         p = False;
1861                 }
1862
1863                 if (p && r_o.ptr != 0)
1864                 {
1865                         valid_query = True;
1866                         *num_mem = r_o.num_sids;
1867                 }
1868
1869         }
1870
1871         prs_mem_free(&data   );
1872         prs_mem_free(&rdata  );
1873
1874         return valid_query;
1875 }
1876
1877 /****************************************************************************
1878 do a SAMR Query User Aliases
1879 ****************************************************************************/
1880 BOOL samr_query_useraliases(  const POLICY_HND *pol,
1881                                 uint32 *ptr_sid, DOM_SID2 *sid,
1882                                 uint32 *num_aliases, uint32 **rid)
1883 {
1884         prs_struct data;
1885         prs_struct rdata;
1886
1887         SAMR_Q_QUERY_USERALIASES q_o;
1888         BOOL valid_query = False;
1889         ZERO_STRUCT(q_o);
1890
1891         DEBUG(4,("SAMR Query User Aliases.\n"));
1892
1893         if (pol == NULL || sid == NULL || rid == NULL || num_aliases == 0) return False;
1894
1895         /* create and send a MSRPC command with api SAMR_QUERY_USERALIASES */
1896
1897         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1898         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1899
1900         /* store the parameters */
1901         make_samr_q_query_useraliases(&q_o, pol, ptr_sid, sid);
1902
1903         /* turn parameters into data stream */
1904         samr_io_q_query_useraliases("", &q_o,  &data, 0);
1905
1906         /* send the data on \PIPE\ */
1907         if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERALIASES, &data, &rdata))
1908         {
1909                 SAMR_R_QUERY_USERALIASES r_o;
1910                 BOOL p;
1911
1912                 r_o.rid = NULL;
1913
1914                 samr_io_r_query_useraliases("", &r_o, &rdata, 0);
1915                 *rid = r_o.rid;
1916                 p = rdata.offset != 0;
1917                 
1918                 if (p && r_o.status != 0)
1919                 {
1920                         /* report error code */
1921                         DEBUG(4,("SAMR_R_QUERY_USERALIASES: %s\n", get_nt_error_msg(r_o.status)));
1922                         p = False;
1923                 }
1924
1925                 if (p && r_o.ptr != 0)
1926                 {
1927                         valid_query = True;
1928                         *num_aliases = r_o.num_entries;
1929                 }
1930
1931         }
1932
1933         prs_mem_free(&data   );
1934         prs_mem_free(&rdata  );
1935
1936         return valid_query;
1937 }
1938
1939 /****************************************************************************
1940 do a SAMR Query Group Members
1941 ****************************************************************************/
1942 BOOL samr_query_groupmem(  POLICY_HND *group_pol, 
1943                                 uint32 *num_mem, uint32 **rid, uint32 **attr)
1944 {
1945         prs_struct data;
1946         prs_struct rdata;
1947
1948         SAMR_Q_QUERY_GROUPMEM q_o;
1949         BOOL valid_query = False;
1950
1951         DEBUG(4,("SAMR Query Group Members.\n"));
1952
1953         if (group_pol == NULL || rid == NULL || attr == NULL || num_mem == NULL) return False;
1954
1955         /* create and send a MSRPC command with api SAMR_QUERY_GROUPMEM */
1956
1957         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1958         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1959
1960         /* store the parameters */
1961         make_samr_q_query_groupmem(&q_o, group_pol);
1962
1963         /* turn parameters into data stream */
1964         samr_io_q_query_groupmem("", &q_o,  &data, 0);
1965
1966         /* send the data on \PIPE\ */
1967         if (rpc_hnd_pipe_req(group_pol, SAMR_QUERY_GROUPMEM, &data, &rdata))
1968         {
1969                 SAMR_R_QUERY_GROUPMEM r_o;
1970                 BOOL p;
1971
1972                 r_o.rid  = NULL;
1973                 r_o.attr = NULL;
1974
1975                 samr_io_r_query_groupmem("", &r_o, &rdata, 0);
1976                 *rid  = r_o.rid ;
1977                 *attr = r_o.attr;
1978                 p = rdata.offset != 0;
1979                 
1980                 if (p && r_o.status != 0)
1981                 {
1982                         /* report error code */
1983                         DEBUG(4,("SAMR_R_QUERY_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
1984                         p = False;
1985                 }
1986
1987                 if (p && r_o.ptr != 0 &&
1988                     r_o.ptr_rids != 0 && r_o.ptr_attrs != 0 &&
1989                     r_o.num_rids == r_o.num_attrs)
1990                 {
1991                         valid_query = True;
1992                         *num_mem = r_o.num_rids;
1993                 }
1994
1995         }
1996
1997         prs_mem_free(&data   );
1998         prs_mem_free(&rdata  );
1999
2000         return valid_query;
2001 }
2002
2003 /****************************************************************************
2004 do a SAMR Query User Groups
2005 ****************************************************************************/
2006 BOOL samr_query_usergroups(  POLICY_HND *pol, uint32 *num_groups,
2007                                 DOM_GID **gid)
2008 {
2009         prs_struct data;
2010         prs_struct rdata;
2011
2012         SAMR_Q_QUERY_USERGROUPS q_o;
2013         BOOL valid_query = False;
2014
2015         DEBUG(4,("SAMR Query User Groups.\n"));
2016
2017         if (pol == NULL || gid == NULL || num_groups == 0) return False;
2018
2019         /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
2020
2021         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2022         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2023
2024         /* store the parameters */
2025         make_samr_q_query_usergroups(&q_o, pol);
2026
2027         /* turn parameters into data stream */
2028         samr_io_q_query_usergroups("", &q_o,  &data, 0);
2029
2030         /* send the data on \PIPE\ */
2031         if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERGROUPS, &data, &rdata))
2032         {
2033                 SAMR_R_QUERY_USERGROUPS r_o;
2034                 BOOL p;
2035
2036                 /* get user info */
2037                 r_o.gid = NULL;
2038
2039                 samr_io_r_query_usergroups("", &r_o, &rdata, 0);
2040                 *gid = r_o.gid;
2041                 p = rdata.offset != 0;
2042                 
2043                 if (p && r_o.status != 0)
2044                 {
2045                         /* report error code */
2046                         DEBUG(4,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
2047                         p = False;
2048                 }
2049
2050                 if (p && r_o.ptr_0 != 0)
2051                 {
2052                         valid_query = True;
2053                         *num_groups = r_o.num_entries;
2054                 }
2055
2056         }
2057
2058         prs_mem_free(&data   );
2059         prs_mem_free(&rdata  );
2060
2061         return valid_query;
2062 }
2063
2064 /****************************************************************************
2065 do a SAMR Query Group Info
2066 ****************************************************************************/
2067 BOOL samr_query_groupinfo(  POLICY_HND *pol,
2068                                 uint16 switch_value, GROUP_INFO_CTR* ctr)
2069 {
2070         prs_struct data;
2071         prs_struct rdata;
2072
2073         SAMR_Q_QUERY_GROUPINFO q_o;
2074         BOOL valid_query = False;
2075
2076         DEBUG(4,("SAMR Query Group Info.  level: %d\n", switch_value));
2077
2078         if (pol == NULL || ctr == NULL || switch_value == 0) return False;
2079
2080         /* create and send a MSRPC command with api SAMR_QUERY_GROUPINFO */
2081
2082         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2083         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2084
2085         /* store the parameters */
2086         make_samr_q_query_groupinfo(&q_o, pol, switch_value);
2087
2088         /* turn parameters into data stream */
2089         samr_io_q_query_groupinfo("", &q_o,  &data, 0);
2090
2091         /* send the data on \PIPE\ */
2092         if (rpc_hnd_pipe_req(pol, SAMR_QUERY_GROUPINFO, &data, &rdata))
2093         {
2094                 SAMR_R_QUERY_GROUPINFO r_o;
2095                 BOOL p;
2096
2097                 /* get group info */
2098                 r_o.ctr = ctr;
2099
2100                 samr_io_r_query_groupinfo("", &r_o, &rdata, 0);
2101                 p = rdata.offset != 0;
2102                 
2103                 if (p && r_o.status != 0)
2104                 {
2105                         /* report error code */
2106                         DEBUG(4,("SAMR_R_QUERY_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
2107                         p = False;
2108                 }
2109
2110                 if (p && r_o.ctr->switch_value1 != switch_value)
2111                 {
2112                         DEBUG(4,("SAMR_R_QUERY_GROUPINFO: received incorrect level %d\n",
2113                                   r_o.ctr->switch_value1));
2114                 }
2115
2116                 if (p && r_o.ptr != 0)
2117                 {
2118                         valid_query = True;
2119                 }
2120         }
2121
2122         prs_mem_free(&data   );
2123         prs_mem_free(&rdata  );
2124
2125         return valid_query;
2126 }
2127
2128 /****************************************************************************
2129 do a SAMR Set User Info
2130 ****************************************************************************/
2131 BOOL samr_set_userinfo2(  POLICY_HND *pol, uint16 switch_value,
2132                                 void* usr)
2133 {
2134         prs_struct data;
2135         prs_struct rdata;
2136
2137         SAMR_Q_SET_USERINFO2 q_o;
2138         BOOL valid_query = False;
2139
2140         DEBUG(4,("SAMR Set User Info 2.  level: %d\n", switch_value));
2141
2142         if (pol == NULL || usr == NULL || switch_value == 0) return False;
2143
2144         /* create and send a MSRPC command with api SAMR_SET_USERINFO2 */
2145
2146         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2147         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2148
2149         /* store the parameters */
2150         make_samr_q_set_userinfo2(&q_o, pol, switch_value, usr);
2151
2152         /* turn parameters into data stream */
2153         samr_io_q_set_userinfo2("", &q_o,  &data, 0);
2154
2155         /* send the data on \PIPE\ */
2156         if (rpc_hnd_pipe_req(pol, SAMR_SET_USERINFO2, &data, &rdata))
2157         {
2158                 SAMR_R_SET_USERINFO2 r_o;
2159                 BOOL p;
2160
2161                 samr_io_r_set_userinfo2("", &r_o, &rdata, 0);
2162                 p = rdata.offset != 0;
2163                 
2164                 if (p && r_o.status != 0)
2165                 {
2166                         /* report error code */
2167                         DEBUG(4,("SAMR_R_QUERY_USERINFO2: %s\n", get_nt_error_msg(r_o.status)));
2168                         p = False;
2169                 }
2170
2171                 if (p)
2172                 {
2173                         valid_query = True;
2174                 }
2175         }
2176
2177         prs_mem_free(&data   );
2178         prs_mem_free(&rdata  );
2179
2180         return valid_query;
2181 }
2182
2183 /****************************************************************************
2184 do a SAMR Set User Info
2185 ****************************************************************************/
2186 BOOL samr_set_userinfo(  POLICY_HND *pol, uint16 switch_value, void* usr)
2187 {
2188         prs_struct data;
2189         prs_struct rdata;
2190
2191         SAMR_Q_SET_USERINFO q_o;
2192         BOOL valid_query = False;
2193
2194         DEBUG(4,("SAMR Set User Info.  level: %d\n", switch_value));
2195
2196         if (pol == NULL || usr == NULL || switch_value == 0) return False;
2197
2198         /* create and send a MSRPC command with api SAMR_SET_USERINFO */
2199
2200         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2201         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2202
2203         /* store the parameters */
2204         make_samr_q_set_userinfo(&q_o, pol, switch_value, usr);
2205
2206         /* turn parameters into data stream */
2207         samr_io_q_set_userinfo("", &q_o,  &data, 0);
2208
2209         /* send the data on \PIPE\ */
2210         if (rpc_hnd_pipe_req(pol, SAMR_SET_USERINFO, &data, &rdata))
2211         {
2212                 SAMR_R_SET_USERINFO r_o;
2213                 BOOL p;
2214
2215                 samr_io_r_set_userinfo("", &r_o, &rdata, 0);
2216                 p = rdata.offset != 0;
2217                 
2218                 if (p && r_o.status != 0)
2219                 {
2220                         /* report error code */
2221                         DEBUG(4,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
2222                         p = False;
2223                 }
2224
2225                 if (p)
2226                 {
2227                         valid_query = True;
2228                 }
2229         }
2230
2231         prs_mem_free(&data   );
2232         prs_mem_free(&rdata  );
2233
2234         return valid_query;
2235 }
2236
2237 /****************************************************************************
2238 do a SAMR Query User Info
2239 ****************************************************************************/
2240 BOOL samr_query_userinfo(  POLICY_HND *pol, uint16 switch_value, void* usr)
2241 {
2242         prs_struct data;
2243         prs_struct rdata;
2244
2245         SAMR_Q_QUERY_USERINFO q_o;
2246         BOOL valid_query = False;
2247
2248         DEBUG(4,("SAMR Query User Info.  level: %d\n", switch_value));
2249
2250         if (pol == NULL || usr == NULL || switch_value == 0) return False;
2251
2252         /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
2253
2254         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2255         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2256
2257         /* store the parameters */
2258         make_samr_q_query_userinfo(&q_o, pol, switch_value);
2259
2260         /* turn parameters into data stream */
2261         samr_io_q_query_userinfo("", &q_o,  &data, 0);
2262
2263         /* send the data on \PIPE\ */
2264         if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERINFO, &data, &rdata))
2265         {
2266                 SAMR_R_QUERY_USERINFO r_o;
2267                 BOOL p;
2268
2269                 /* get user info */
2270                 r_o.info.id = usr;
2271
2272                 samr_io_r_query_userinfo("", &r_o, &rdata, 0);
2273                 p = rdata.offset != 0;
2274                 
2275                 if (p && r_o.status != 0)
2276                 {
2277                         /* report error code */
2278                         DEBUG(4,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
2279                         p = False;
2280                 }
2281
2282                 if (p && r_o.switch_value != switch_value)
2283                 {
2284                         DEBUG(4,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
2285                                   r_o.switch_value));
2286                 }
2287
2288                 if (p && r_o.ptr != 0)
2289                 {
2290                         valid_query = True;
2291                 }
2292         }
2293
2294         prs_mem_free(&data   );
2295         prs_mem_free(&rdata  );
2296
2297         return valid_query;
2298 }
2299
2300 /****************************************************************************
2301 do a SAMR Close
2302 ****************************************************************************/
2303 BOOL samr_close(  POLICY_HND *hnd)
2304 {
2305         prs_struct data;
2306         prs_struct rdata;
2307
2308         SAMR_Q_CLOSE_HND q_c;
2309         BOOL valid_close = False;
2310
2311         DEBUG(4,("SAMR Close\n"));
2312
2313         if (hnd == NULL) return False;
2314
2315         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2316         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2317
2318         /* create and send a MSRPC command with api SAMR_CLOSE_HND */
2319
2320         /* store the parameters */
2321         make_samr_q_close_hnd(&q_c, hnd);
2322
2323         /* turn parameters into data stream */
2324         samr_io_q_close_hnd("", &q_c,  &data, 0);
2325
2326         /* send the data on \PIPE\ */
2327         if (rpc_hnd_pipe_req(hnd, SAMR_CLOSE_HND, &data, &rdata))
2328         {
2329                 SAMR_R_CLOSE_HND r_c;
2330                 BOOL p;
2331
2332                 samr_io_r_close_hnd("", &r_c, &rdata, 0);
2333                 p = rdata.offset != 0;
2334
2335                 if (p && r_c.status != 0)
2336                 {
2337                         /* report error code */
2338                         DEBUG(4,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
2339                         p = False;
2340                 }
2341
2342                 if (p)
2343                 {
2344                         /* check that the returned policy handle is all zeros */
2345                         uint32 i;
2346                         valid_close = True;
2347
2348                         for (i = 0; i < sizeof(r_c.pol.data); i++)
2349                         {
2350                                 if (r_c.pol.data[i] != 0)
2351                                 {
2352                                         valid_close = False;
2353                                         break;
2354                                 }
2355                         }       
2356                         if (!valid_close)
2357                         {
2358                                 DEBUG(4,("SAMR_CLOSE_HND: non-zero handle returned\n"));
2359                         }
2360                 }
2361         }
2362
2363         prs_mem_free(&data   );
2364         prs_mem_free(&rdata  );
2365
2366         close_policy_hnd(hnd);
2367
2368         return valid_close;
2369 }
2370
2371 /****************************************************************************
2372 do a SAMR query display info
2373 ****************************************************************************/
2374 BOOL samr_query_dispinfo(  POLICY_HND *pol_domain, uint16 level,
2375                                 uint32 *num_entries,
2376                                 SAM_DISPINFO_CTR *ctr)
2377 {
2378         prs_struct data;
2379         prs_struct rdata;
2380
2381         SAMR_Q_QUERY_DISPINFO q_o;
2382         BOOL valid_query = False;
2383
2384         DEBUG(4,("SAMR Query Display Info.  level: %d\n", level));
2385
2386         if (pol_domain == NULL || num_entries == NULL || ctr == NULL ||
2387             level == 0)
2388         {
2389                 return False;
2390         }
2391
2392         /* create and send a MSRPC command with api SAMR_QUERY_DISPINFO */
2393
2394         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2395         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2396
2397         /* store the parameters */
2398         make_samr_q_query_dispinfo(&q_o, pol_domain, level, 0, 0xffffffff);
2399
2400         /* turn parameters into data stream */
2401         samr_io_q_query_dispinfo("", &q_o,  &data, 0);
2402
2403         /* send the data on \PIPE\ */
2404         if (rpc_hnd_pipe_req(pol_domain, SAMR_QUERY_DISPINFO, &data, &rdata))
2405         {
2406                 SAMR_R_QUERY_DISPINFO r_o;
2407                 BOOL p;
2408
2409                 /* get user info */
2410                 r_o.ctr = ctr;
2411
2412                 samr_io_r_query_dispinfo("", &r_o, &rdata, 0);
2413                 p = rdata.offset != 0;
2414                 
2415                 if (p && r_o.status != 0)
2416                 {
2417                         /* report error code */
2418                         DEBUG(4,("SAMR_R_QUERY_DISPINFO: %s\n", get_nt_error_msg(r_o.status)));
2419                         p = False;
2420                 }
2421
2422                 if (p && r_o.switch_level != level)
2423                 {
2424                         DEBUG(4,("SAMR_R_QUERY_DISPINFO: received incorrect level %d\n",
2425                                   r_o.switch_level));
2426                 }
2427
2428                 if (p && r_o.ptr_entries != 0)
2429                 {
2430                         valid_query = True;
2431                         (*num_entries) = r_o.num_entries;
2432                 }
2433         }
2434
2435         prs_mem_free(&data   );
2436         prs_mem_free(&rdata  );
2437
2438         return valid_query;
2439 }
2440