ok. got ntlogin command working. argh, it maintains a connection to
[ira/wip.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         /* send the data on \PIPE\ */
64         if (rpc_con_pipe_req(con, SAMR_CHGPASSWD_USER, &data, &rdata))
65         {
66                 SAMR_R_CHGPASSWD_USER r_e;
67                 BOOL p;
68
69                 samr_io_r_chgpasswd_user("", &r_e, &rdata, 0);
70
71                 p = rdata.offset != 0;
72                 if (p && r_e.status != 0)
73                 {
74                         /* report error code */
75                         DEBUG(4,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
76                         p = False;
77                 }
78
79                 if (p)
80                 {
81                         valid_pwc = True;
82                 }
83         }
84
85         prs_mem_free(&data   );
86         prs_mem_free(&rdata  );
87
88         cli_connection_unlink(con);
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 BOOL 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
964         SAMR_Q_CREATE_USER q_o;
965         BOOL valid_pol = False;
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
991                 if (p && r_o.status != 0)
992                 {
993                         /* report error code */
994                         DEBUG(4,("SAMR_R_CREATE_USER: %s\n", get_nt_error_msg(r_o.status)));
995                         p = False;
996                 }
997
998                 if (p)
999                 {
1000                         memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
1001                         *rid = r_o.user_rid;
1002                         valid_pol = cli_pol_link(user_pol, domain_pol);
1003                 }
1004         }
1005
1006         prs_mem_free(&data   );
1007         prs_mem_free(&rdata  );
1008
1009         return valid_pol;
1010 }
1011
1012 /****************************************************************************
1013 do a SAMR Create Domain Alias
1014 ****************************************************************************/
1015 BOOL samr_create_dom_alias(  POLICY_HND *domain_pol, const char *acct_name,
1016                                 POLICY_HND *alias_pol, uint32 *rid)
1017 {
1018         prs_struct data;
1019         prs_struct rdata;
1020
1021         SAMR_Q_CREATE_DOM_ALIAS q_o;
1022         BOOL valid_pol = False;
1023
1024         if (alias_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
1025
1026         /* create and send a MSRPC command with api SAMR_CREATE_DOM_ALIAS */
1027
1028         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1029         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1030
1031         DEBUG(4,("SAMR Create Domain Alias. Name:%s\n", acct_name));
1032
1033         /* store the parameters */
1034         make_samr_q_create_dom_alias(&q_o, domain_pol, acct_name);
1035
1036         /* turn parameters into data stream */
1037         samr_io_q_create_dom_alias("", &q_o,  &data, 0);
1038
1039         /* send the data on \PIPE\ */
1040         if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_DOM_ALIAS, &data, &rdata))
1041         {
1042                 SAMR_R_CREATE_DOM_ALIAS r_o;
1043                 BOOL p;
1044
1045                 samr_io_r_create_dom_alias("", &r_o, &rdata, 0);
1046                 p = rdata.offset != 0;
1047
1048                 if (p && r_o.status != 0)
1049                 {
1050                         /* report error code */
1051                         DEBUG(4,("SAMR_R_CREATE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
1052                         p = False;
1053                 }
1054
1055                 if (p)
1056                 {
1057                         memcpy(alias_pol, &r_o.alias_pol, sizeof(r_o.alias_pol));
1058                         *rid = r_o.rid;
1059                         valid_pol = cli_pol_link(alias_pol, domain_pol);
1060                 }
1061         }
1062
1063         prs_mem_free(&data   );
1064         prs_mem_free(&rdata  );
1065
1066         return valid_pol;
1067 }
1068
1069 /****************************************************************************
1070 do a SAMR Get Alias Info
1071 ****************************************************************************/
1072 BOOL samr_query_aliasinfo(  POLICY_HND *alias_pol, uint16 switch_value,
1073                                 ALIAS_INFO_CTR *ctr)
1074 {
1075         prs_struct data;
1076         prs_struct rdata;
1077
1078         SAMR_Q_QUERY_ALIASINFO q_o;
1079         BOOL valid_pol = False;
1080
1081         if (alias_pol == NULL || ctr == NULL) return False;
1082
1083         /* create and send a MSRPC command with api SAMR_GET_ALIASINFO */
1084
1085         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1086         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1087
1088         DEBUG(4,("SAMR Get Alias Info\n"));
1089
1090         /* store the parameters */
1091         make_samr_q_query_aliasinfo(&q_o, alias_pol, switch_value);
1092
1093         /* turn parameters into data stream */
1094         samr_io_q_query_aliasinfo("", &q_o,  &data, 0);
1095
1096         /* send the data on \PIPE\ */
1097         if (rpc_hnd_pipe_req(alias_pol, SAMR_QUERY_ALIASINFO, &data, &rdata))
1098         {
1099                 SAMR_R_QUERY_ALIASINFO r_o;
1100                 BOOL p;
1101
1102                 /* get alias info */
1103                 r_o.ctr = ctr;
1104
1105                 samr_io_r_query_aliasinfo("", &r_o, &rdata, 0);
1106                 p = rdata.offset != 0;
1107
1108                 if (p && r_o.status != 0)
1109                 {
1110                         /* report error code */
1111                         DEBUG(4,("SAMR_R_QUERY_ALIASINFO: %s\n", get_nt_error_msg(r_o.status)));
1112                         p = False;
1113                 }
1114
1115                 if (p)
1116                 {
1117                         valid_pol = True;
1118                 }
1119         }
1120
1121         prs_mem_free(&data   );
1122         prs_mem_free(&rdata  );
1123
1124         return valid_pol;
1125 }
1126
1127 /****************************************************************************
1128 do a SAMR Set Alias Info
1129 ****************************************************************************/
1130 BOOL samr_set_aliasinfo(  POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
1131 {
1132         prs_struct data;
1133         prs_struct rdata;
1134
1135         SAMR_Q_SET_ALIASINFO q_o;
1136         BOOL valid_pol = False;
1137
1138         if (alias_pol == NULL || ctr == NULL) return False;
1139
1140         /* create and send a MSRPC command with api SAMR_SET_ALIASINFO */
1141
1142         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1143         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1144
1145         DEBUG(4,("SAMR Set Alias Info\n"));
1146
1147         /* store the parameters */
1148         make_samr_q_set_aliasinfo(&q_o, alias_pol, ctr);
1149
1150         /* turn parameters into data stream */
1151         samr_io_q_set_aliasinfo("", &q_o,  &data, 0);
1152
1153         /* send the data on \PIPE\ */
1154         if (rpc_hnd_pipe_req(alias_pol, SAMR_SET_ALIASINFO, &data, &rdata))
1155         {
1156                 SAMR_R_SET_ALIASINFO r_o;
1157                 BOOL p;
1158
1159                 samr_io_r_set_aliasinfo("", &r_o, &rdata, 0);
1160                 p = rdata.offset != 0;
1161
1162                 if (p && r_o.status != 0)
1163                 {
1164                         /* report error code */
1165                         DEBUG(4,("SAMR_R_SET_ALIASINFO: %s\n", get_nt_error_msg(r_o.status)));
1166                         p = False;
1167                 }
1168
1169                 if (p)
1170                 {
1171                         valid_pol = True;
1172                 }
1173         }
1174
1175         prs_mem_free(&data   );
1176         prs_mem_free(&rdata  );
1177
1178         return valid_pol;
1179 }
1180
1181 /****************************************************************************
1182 do a SAMR Open Group
1183 ****************************************************************************/
1184 BOOL samr_open_group(  const POLICY_HND *domain_pol,
1185                                 uint32 flags, uint32 rid,
1186                                 POLICY_HND *group_pol)
1187 {
1188         prs_struct data;
1189         prs_struct rdata;
1190
1191         SAMR_Q_OPEN_GROUP q_o;
1192         BOOL valid_pol = False;
1193
1194         DEBUG(4,("SAMR Open Group. RID:%x\n", rid));
1195
1196         if (group_pol == NULL || domain_pol == NULL) return False;
1197
1198         /* create and send a MSRPC command with api SAMR_OPEN_GROUP */
1199
1200         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1201         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1202
1203         /* store the parameters */
1204         make_samr_q_open_group(&q_o, domain_pol, flags, rid);
1205
1206         /* turn parameters into data stream */
1207         samr_io_q_open_group("", &q_o,  &data, 0);
1208
1209         /* send the data on \PIPE\ */
1210         if (rpc_hnd_pipe_req(domain_pol, SAMR_OPEN_GROUP, &data, &rdata))
1211         {
1212                 SAMR_R_OPEN_GROUP r_o;
1213                 BOOL p;
1214
1215                 samr_io_r_open_group("", &r_o, &rdata, 0);
1216                 p = rdata.offset != 0;
1217
1218                 if (p && r_o.status != 0)
1219                 {
1220                         /* report error code */
1221                         DEBUG(4,("SAMR_R_OPEN_GROUP: %s\n", get_nt_error_msg(r_o.status)));
1222                         p = False;
1223                 }
1224
1225                 if (p)
1226                 {
1227                         memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
1228                         valid_pol = cli_pol_link(group_pol, domain_pol);
1229                 }
1230         }
1231
1232         prs_mem_free(&data   );
1233         prs_mem_free(&rdata  );
1234
1235         return valid_pol;
1236 }
1237
1238 /****************************************************************************
1239 do a SAMR Delete Group Member
1240 ****************************************************************************/
1241 BOOL samr_del_groupmem(  POLICY_HND *group_pol, uint32 rid)
1242 {
1243         prs_struct data;
1244         prs_struct rdata;
1245
1246         SAMR_Q_DEL_GROUPMEM q_o;
1247         BOOL valid_pol = False;
1248
1249         if (group_pol == NULL) return False;
1250
1251         /* create and send a MSRPC command with api SAMR_DEL_GROUPMEM */
1252
1253         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1254         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1255
1256         DEBUG(4,("SAMR Delete Group Member.\n"));
1257
1258         /* store the parameters */
1259         make_samr_q_del_groupmem(&q_o, group_pol, rid);
1260
1261         /* turn parameters into data stream */
1262         samr_io_q_del_groupmem("", &q_o,  &data, 0);
1263
1264         /* send the data on \PIPE\ */
1265         if (rpc_hnd_pipe_req(group_pol, SAMR_DEL_GROUPMEM, &data, &rdata))
1266         {
1267                 SAMR_R_DEL_GROUPMEM r_o;
1268                 BOOL p;
1269
1270                 samr_io_r_del_groupmem("", &r_o, &rdata, 0);
1271                 p = rdata.offset != 0;
1272
1273                 if (p && r_o.status != 0)
1274                 {
1275                         /* report error code */
1276                         DEBUG(4,("SAMR_R_DEL_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
1277                         p = False;
1278                 }
1279
1280                 if (p)
1281                 {
1282                         valid_pol = True;
1283                 }
1284         }
1285
1286         prs_mem_free(&data   );
1287         prs_mem_free(&rdata  );
1288
1289         return valid_pol;
1290 }
1291
1292 /****************************************************************************
1293 do a SAMR Add Group Member
1294 ****************************************************************************/
1295 BOOL samr_add_groupmem(  POLICY_HND *group_pol, uint32 rid)
1296 {
1297         prs_struct data;
1298         prs_struct rdata;
1299
1300         SAMR_Q_ADD_GROUPMEM q_o;
1301         BOOL valid_pol = False;
1302
1303         if (group_pol == NULL) return False;
1304
1305         /* create and send a MSRPC command with api SAMR_ADD_GROUPMEM */
1306
1307         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1308         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1309
1310         DEBUG(4,("SAMR Add Group Member.\n"));
1311
1312         /* store the parameters */
1313         make_samr_q_add_groupmem(&q_o, group_pol, rid);
1314
1315         /* turn parameters into data stream */
1316         samr_io_q_add_groupmem("", &q_o,  &data, 0);
1317
1318         /* send the data on \PIPE\ */
1319         if (rpc_hnd_pipe_req(group_pol, SAMR_ADD_GROUPMEM, &data, &rdata))
1320         {
1321                 SAMR_R_ADD_GROUPMEM r_o;
1322                 BOOL p;
1323
1324                 samr_io_r_add_groupmem("", &r_o, &rdata, 0);
1325                 p = rdata.offset != 0;
1326
1327                 if (p && r_o.status != 0)
1328                 {
1329                         /* report error code */
1330                         DEBUG(4,("SAMR_R_ADD_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
1331                         p = False;
1332                 }
1333
1334                 if (p)
1335                 {
1336                         valid_pol = True;
1337                 }
1338         }
1339
1340         prs_mem_free(&data   );
1341         prs_mem_free(&rdata  );
1342
1343         return valid_pol;
1344 }
1345
1346 /****************************************************************************
1347 do a SAMR Delete Domain Group
1348 ****************************************************************************/
1349 BOOL samr_delete_dom_group(  POLICY_HND *group_pol)
1350 {
1351         prs_struct data;
1352         prs_struct rdata;
1353
1354         SAMR_Q_DELETE_DOM_GROUP q_o;
1355         BOOL valid_pol = False;
1356
1357         if (group_pol == NULL) return False;
1358
1359         /* delete and send a MSRPC command with api SAMR_DELETE_DOM_GROUP */
1360
1361         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1362         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1363
1364         DEBUG(4,("SAMR Delete Domain Group.\n"));
1365
1366         /* store the parameters */
1367         make_samr_q_delete_dom_group(&q_o, group_pol);
1368
1369         /* turn parameters into data stream */
1370         samr_io_q_delete_dom_group("", &q_o,  &data, 0);
1371
1372         /* send the data on \PIPE\ */
1373         if (rpc_hnd_pipe_req(group_pol, SAMR_DELETE_DOM_GROUP, &data, &rdata))
1374         {
1375                 SAMR_R_DELETE_DOM_GROUP r_o;
1376                 BOOL p;
1377
1378                 samr_io_r_delete_dom_group("", &r_o, &rdata, 0);
1379                 p = rdata.offset != 0;
1380
1381                 if (p && r_o.status != 0)
1382                 {
1383                         /* report error code */
1384                         DEBUG(4,("SAMR_R_DELETE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
1385                         p = False;
1386                 }
1387
1388                 if (p)
1389                 {
1390                         valid_pol = True;
1391                 }
1392         }
1393
1394         prs_mem_free(&data   );
1395         prs_mem_free(&rdata  );
1396
1397         return valid_pol;
1398 }
1399
1400 /****************************************************************************
1401 do a SAMR Create Domain Group
1402 ****************************************************************************/
1403 BOOL samr_create_dom_group(  POLICY_HND *domain_pol, const char *acct_name,
1404                                 POLICY_HND *group_pol, uint32 *rid)
1405 {
1406         prs_struct data;
1407         prs_struct rdata;
1408
1409         SAMR_Q_CREATE_DOM_GROUP q_o;
1410         BOOL valid_pol = False;
1411
1412         if (group_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
1413
1414         /* create and send a MSRPC command with api SAMR_CREATE_DOM_GROUP */
1415
1416         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1417         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1418
1419         DEBUG(4,("SAMR Create Domain Group. Name:%s\n", acct_name));
1420
1421         /* store the parameters */
1422         make_samr_q_create_dom_group(&q_o, domain_pol, acct_name);
1423
1424         /* turn parameters into data stream */
1425         samr_io_q_create_dom_group("", &q_o,  &data, 0);
1426
1427         /* send the data on \PIPE\ */
1428         if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_DOM_GROUP, &data, &rdata))
1429         {
1430                 SAMR_R_CREATE_DOM_GROUP r_o;
1431                 BOOL p;
1432
1433                 samr_io_r_create_dom_group("", &r_o, &rdata, 0);
1434                 p = rdata.offset != 0;
1435
1436                 if (p && r_o.status != 0)
1437                 {
1438                         /* report error code */
1439                         DEBUG(4,("SAMR_R_CREATE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
1440                         p = False;
1441                 }
1442
1443                 if (p)
1444                 {
1445                         memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
1446                         *rid = r_o.rid;
1447                         valid_pol = cli_pol_link(group_pol, domain_pol);
1448                 }
1449         }
1450
1451         prs_mem_free(&data   );
1452         prs_mem_free(&rdata  );
1453
1454         return valid_pol;
1455 }
1456
1457 /****************************************************************************
1458 do a SAMR Set Group Info
1459 ****************************************************************************/
1460 BOOL samr_set_groupinfo(  POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
1461 {
1462         prs_struct data;
1463         prs_struct rdata;
1464
1465         SAMR_Q_SET_GROUPINFO q_o;
1466         BOOL valid_pol = False;
1467
1468         if (group_pol == NULL || ctr == NULL) return False;
1469
1470         /* create and send a MSRPC command with api SAMR_SET_GROUPINFO */
1471
1472         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1473         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1474
1475         DEBUG(4,("SAMR Set Group Info\n"));
1476
1477         /* store the parameters */
1478         make_samr_q_set_groupinfo(&q_o, group_pol, ctr);
1479
1480         /* turn parameters into data stream */
1481         samr_io_q_set_groupinfo("", &q_o,  &data, 0);
1482
1483         /* send the data on \PIPE\ */
1484         if (rpc_hnd_pipe_req(group_pol, SAMR_SET_GROUPINFO, &data, &rdata))
1485         {
1486                 SAMR_R_SET_GROUPINFO r_o;
1487                 BOOL p;
1488
1489                 samr_io_r_set_groupinfo("", &r_o, &rdata, 0);
1490                 p = rdata.offset != 0;
1491
1492                 if (p && r_o.status != 0)
1493                 {
1494                         /* report error code */
1495                         DEBUG(4,("SAMR_R_SET_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
1496                         p = False;
1497                 }
1498
1499                 if (p)
1500                 {
1501                         valid_pol = True;
1502                 }
1503         }
1504
1505         prs_mem_free(&data   );
1506         prs_mem_free(&rdata  );
1507
1508         return valid_pol;
1509 }
1510
1511 /****************************************************************************
1512 do a SAMR Open Domain
1513 ****************************************************************************/
1514 BOOL samr_open_domain(  const POLICY_HND *connect_pol,
1515                                 uint32 ace_perms,
1516                                 const DOM_SID *sid,
1517                                 POLICY_HND *domain_pol)
1518 {
1519         pstring sid_str;
1520         prs_struct data;
1521         prs_struct rdata;
1522
1523         SAMR_Q_OPEN_DOMAIN q_o;
1524         BOOL valid_pol = False;
1525
1526         if (DEBUGLEVEL >= 4)
1527         {
1528                 sid_to_string(sid_str, sid);
1529                 DEBUG(4,("SAMR Open Domain.  SID:%s Permissions:%x\n",
1530                                         sid_str, ace_perms));
1531         }
1532
1533         if (connect_pol == NULL || sid == NULL || domain_pol == NULL) return False;
1534
1535         /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
1536
1537         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1538         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1539
1540         /* store the parameters */
1541         make_samr_q_open_domain(&q_o, connect_pol, ace_perms, sid);
1542
1543         /* turn parameters into data stream */
1544         samr_io_q_open_domain("", &q_o,  &data, 0);
1545
1546         /* send the data on \PIPE\ */
1547         if (rpc_hnd_pipe_req(connect_pol, SAMR_OPEN_DOMAIN, &data, &rdata))
1548         {
1549                 SAMR_R_OPEN_DOMAIN r_o;
1550                 BOOL p;
1551
1552                 samr_io_r_open_domain("", &r_o, &rdata, 0);
1553                 p = rdata.offset != 0;
1554
1555                 if (p && r_o.status != 0)
1556                 {
1557                         /* report error code */
1558                         DEBUG(4,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
1559                         p = False;
1560                 }
1561
1562                 if (p)
1563                 {
1564                         memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
1565                         valid_pol = cli_pol_link(domain_pol, connect_pol);
1566                 }
1567         }
1568
1569         prs_mem_free(&data   );
1570         prs_mem_free(&rdata  );
1571
1572         return valid_pol;
1573 }
1574
1575 /****************************************************************************
1576 do a SAMR Query Lookup Domain
1577 ****************************************************************************/
1578 BOOL samr_query_lookup_domain(  POLICY_HND *pol, const char *dom_name,
1579                               DOM_SID *dom_sid)
1580 {
1581         prs_struct data;
1582         prs_struct rdata;
1583
1584         SAMR_Q_LOOKUP_DOMAIN q_o;
1585         BOOL valid_query = False;
1586
1587         if (pol == NULL || dom_name == NULL || dom_sid == NULL) return False;
1588
1589         /* create and send a MSRPC command with api SAMR_LOOKUP_DOMAIN */
1590
1591         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1592         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1593
1594         DEBUG(4,("SAMR Query Lookup Domain.\n"));
1595
1596         /* store the parameters */
1597         make_samr_q_lookup_domain(&q_o, pol, dom_name);
1598
1599         /* turn parameters into data stream */
1600         samr_io_q_lookup_domain("", &q_o, &data, 0);
1601
1602         /* send the data on \PIPE\ */
1603         if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_DOMAIN, &data, &rdata))
1604         {
1605                 SAMR_R_LOOKUP_DOMAIN r_o;
1606                 BOOL p;
1607
1608                 samr_io_r_lookup_domain("", &r_o, &rdata, 0);
1609                 p = rdata.offset != 0;
1610                 
1611                 if (p && r_o.status != 0)
1612                 {
1613                         /* report error code */
1614                         DEBUG(4,("SAMR_R_LOOKUP_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
1615                         p = False;
1616                 }
1617
1618                 if (p && r_o.ptr_sid != 0)
1619                 {
1620                         sid_copy(dom_sid, &r_o.dom_sid.sid);
1621                         valid_query = True;
1622                 }
1623         }
1624
1625         prs_mem_free(&data   );
1626         prs_mem_free(&rdata  );
1627
1628         return valid_query;
1629 }
1630
1631 /****************************************************************************
1632 do a SAMR Query Lookup Names
1633 ****************************************************************************/
1634 BOOL samr_query_lookup_names(  POLICY_HND *pol, uint32 flags,
1635                                 uint32 num_names, char **names,
1636                                 uint32 *num_rids,
1637                                 uint32 rid[MAX_LOOKUP_SIDS],
1638                                 uint32 type[MAX_LOOKUP_SIDS])
1639 {
1640         prs_struct data;
1641         prs_struct rdata;
1642
1643         SAMR_Q_LOOKUP_NAMES q_o;
1644         BOOL valid_query = False;
1645
1646         if (pol == NULL || flags == 0 || num_names == 0 || names == NULL ||
1647             num_rids == NULL || rid == NULL || type == NULL ) return False;
1648
1649         /* create and send a MSRPC command with api SAMR_LOOKUP_NAMES */
1650
1651         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1652         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1653
1654         DEBUG(4,("SAMR Query Lookup NAMES.\n"));
1655
1656         /* store the parameters */
1657         make_samr_q_lookup_names(&q_o, pol, flags, num_names, names);
1658
1659         /* turn parameters into data stream */
1660         samr_io_q_lookup_names("", &q_o, &data, 0);
1661
1662         /* send the data on \PIPE\ */
1663         if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_NAMES, &data, &rdata))
1664         {
1665                 SAMR_R_LOOKUP_NAMES r_o;
1666                 BOOL p;
1667
1668                 samr_io_r_lookup_names("", &r_o, &rdata, 0);
1669                 p = rdata.offset != 0;
1670                 
1671                 if (p && r_o.status != 0)
1672                 {
1673                         /* report error code */
1674                         DEBUG(4,("SAMR_R_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_o.status)));
1675                         p = r_o.status == 0x107;
1676                 }
1677
1678                 if (p)
1679                 {
1680                         if (r_o.ptr_rids != 0 && r_o.ptr_types != 0 &&
1681                             r_o.num_types1 == r_o.num_rids1)
1682                         {
1683                                 uint32 i;
1684
1685                                 valid_query = True;
1686                                 *num_rids = r_o.num_rids1;
1687
1688                                 for (i = 0; i < r_o.num_rids1; i++)
1689                                 {
1690                                         rid[i] = r_o.rid[i];
1691                                 }
1692                                 for (i = 0; i < r_o.num_types1; i++)
1693                                 {
1694                                         type[i] = r_o.type[i];
1695                                 }
1696                         }
1697                         else if (r_o.ptr_rids == 0 && r_o.ptr_types == 0)
1698                         {
1699                                 valid_query = True;
1700                                 *num_rids = 0;
1701                         }
1702                         else
1703                         {
1704                                 p = False;
1705                         }
1706                 }
1707         }
1708
1709         prs_mem_free(&data   );
1710         prs_mem_free(&rdata  );
1711
1712         return valid_query;
1713 }
1714
1715 /****************************************************************************
1716 do a SAMR Query Lookup RIDS
1717 ****************************************************************************/
1718 BOOL samr_query_lookup_rids(  const POLICY_HND *pol, uint32 flags,
1719                                 uint32 num_rids, uint32 *rids,
1720                                 uint32 *num_names,
1721                                 char   ***names,
1722                                 uint32 **type)
1723 {
1724         prs_struct data;
1725         prs_struct rdata;
1726
1727         SAMR_Q_LOOKUP_RIDS q_o;
1728         BOOL valid_query = False;
1729
1730         if (pol == NULL || flags == 0 || num_rids == 0 || rids == NULL ||
1731             num_names == NULL || names == NULL || type == NULL ) return False;
1732
1733         /* create and send a MSRPC command with api SAMR_LOOKUP_RIDS */
1734
1735         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1736         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1737
1738         DEBUG(4,("SAMR Query Lookup RIDs.\n"));
1739
1740         /* store the parameters */
1741         make_samr_q_lookup_rids(&q_o, pol, flags, num_rids, rids);
1742
1743         /* turn parameters into data stream */
1744         samr_io_q_lookup_rids("", &q_o,  &data, 0);
1745
1746         /* send the data on \PIPE\ */
1747         if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_RIDS, &data, &rdata))
1748         {
1749                 SAMR_R_LOOKUP_RIDS r_o;
1750                 BOOL p;
1751                 ZERO_STRUCT(r_o);
1752
1753                 samr_io_r_lookup_rids("", &r_o, &rdata, 0);
1754                 p = rdata.offset != 0;
1755                 
1756                 if (p && r_o.status != 0)
1757                 {
1758                         /* report error code */
1759                         DEBUG(4,("SAMR_R_LOOKUP_RIDS: %s\n", get_nt_error_msg(r_o.status)));
1760                         p = False;
1761                 }
1762
1763                 if (p)
1764                 {
1765                         if (r_o.ptr_names != 0 && r_o.ptr_types != 0 &&
1766                             r_o.num_types1 == r_o.num_names1)
1767                         {
1768                                 uint32 i;
1769                                 valid_query = True;
1770
1771                                 (*num_names) = 0;
1772                                 (*names) = NULL;
1773
1774                                 for (i = 0; i < r_o.num_names1; i++)
1775                                 {
1776                                         fstring tmp;
1777                                         unistr2_to_ascii(tmp, &r_o.uni_name[i], sizeof(tmp)-1);
1778                                         add_chars_to_array(num_names, names, tmp);
1779                                 }
1780
1781                                 if ((*num_names) != 0)
1782                                 {
1783                                         (*type) = (uint32*)malloc((*num_names) * sizeof(**type));
1784                                 }
1785
1786                                 for (i = 0; (*type) != NULL && i < r_o.num_types1; i++)
1787                                 {
1788                                         (*type)[i] = r_o.type[i];
1789                                 }
1790                         }
1791                         else if (r_o.ptr_names == 0 && r_o.ptr_types == 0)
1792                         {
1793                                 valid_query = True;
1794                                 *num_names = 0;
1795                                 *names = NULL;
1796                                 *type = NULL;
1797                         }
1798                         else
1799                         {
1800                                 p = False;
1801                         }
1802                 }
1803
1804                 samr_free_r_lookup_rids(&r_o);
1805         }
1806
1807         prs_mem_free(&data   );
1808         prs_mem_free(&rdata  );
1809
1810         return valid_query;
1811 }
1812
1813 /****************************************************************************
1814 do a SAMR Query Alias Members
1815 ****************************************************************************/
1816 BOOL samr_query_aliasmem(  const POLICY_HND *alias_pol, 
1817                                 uint32 *num_mem, DOM_SID2 *sid)
1818 {
1819         prs_struct data;
1820         prs_struct rdata;
1821
1822         SAMR_Q_QUERY_ALIASMEM q_o;
1823         BOOL valid_query = False;
1824
1825         DEBUG(4,("SAMR Query Alias Members.\n"));
1826
1827         if (alias_pol == NULL || sid == NULL || num_mem == NULL) return False;
1828
1829         /* create and send a MSRPC command with api SAMR_QUERY_ALIASMEM */
1830
1831         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1832         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1833
1834         /* store the parameters */
1835         make_samr_q_query_aliasmem(&q_o, alias_pol);
1836
1837         /* turn parameters into data stream */
1838         samr_io_q_query_aliasmem("", &q_o,  &data, 0);
1839
1840         /* send the data on \PIPE\ */
1841         if (rpc_hnd_pipe_req(alias_pol, SAMR_QUERY_ALIASMEM, &data, &rdata))
1842         {
1843                 SAMR_R_QUERY_ALIASMEM r_o;
1844                 BOOL p;
1845
1846                 /* get user info */
1847                 r_o.sid = sid;
1848
1849                 samr_io_r_query_aliasmem("", &r_o, &rdata, 0);
1850                 p = rdata.offset != 0;
1851                 
1852                 if (p && r_o.status != 0)
1853                 {
1854                         /* report error code */
1855                         DEBUG(4,("SAMR_R_QUERY_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
1856                         p = False;
1857                 }
1858
1859                 if (p && r_o.ptr != 0)
1860                 {
1861                         valid_query = True;
1862                         *num_mem = r_o.num_sids;
1863                 }
1864
1865         }
1866
1867         prs_mem_free(&data   );
1868         prs_mem_free(&rdata  );
1869
1870         return valid_query;
1871 }
1872
1873 /****************************************************************************
1874 do a SAMR Query User Aliases
1875 ****************************************************************************/
1876 BOOL samr_query_useraliases(  const POLICY_HND *pol,
1877                                 uint32 *ptr_sid, DOM_SID2 *sid,
1878                                 uint32 *num_aliases, uint32 **rid)
1879 {
1880         prs_struct data;
1881         prs_struct rdata;
1882
1883         SAMR_Q_QUERY_USERALIASES q_o;
1884         BOOL valid_query = False;
1885         ZERO_STRUCT(q_o);
1886
1887         DEBUG(4,("SAMR Query User Aliases.\n"));
1888
1889         if (pol == NULL || sid == NULL || rid == NULL || num_aliases == 0) return False;
1890
1891         /* create and send a MSRPC command with api SAMR_QUERY_USERALIASES */
1892
1893         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1894         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1895
1896         /* store the parameters */
1897         make_samr_q_query_useraliases(&q_o, pol, ptr_sid, sid);
1898
1899         /* turn parameters into data stream */
1900         samr_io_q_query_useraliases("", &q_o,  &data, 0);
1901
1902         /* send the data on \PIPE\ */
1903         if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERALIASES, &data, &rdata))
1904         {
1905                 SAMR_R_QUERY_USERALIASES r_o;
1906                 BOOL p;
1907
1908                 r_o.rid = NULL;
1909
1910                 samr_io_r_query_useraliases("", &r_o, &rdata, 0);
1911                 *rid = r_o.rid;
1912                 p = rdata.offset != 0;
1913                 
1914                 if (p && r_o.status != 0)
1915                 {
1916                         /* report error code */
1917                         DEBUG(4,("SAMR_R_QUERY_USERALIASES: %s\n", get_nt_error_msg(r_o.status)));
1918                         p = False;
1919                 }
1920
1921                 if (p && r_o.ptr != 0)
1922                 {
1923                         valid_query = True;
1924                         *num_aliases = r_o.num_entries;
1925                 }
1926
1927         }
1928
1929         prs_mem_free(&data   );
1930         prs_mem_free(&rdata  );
1931
1932         return valid_query;
1933 }
1934
1935 /****************************************************************************
1936 do a SAMR Query Group Members
1937 ****************************************************************************/
1938 BOOL samr_query_groupmem(  POLICY_HND *group_pol, 
1939                                 uint32 *num_mem, uint32 **rid, uint32 **attr)
1940 {
1941         prs_struct data;
1942         prs_struct rdata;
1943
1944         SAMR_Q_QUERY_GROUPMEM q_o;
1945         BOOL valid_query = False;
1946
1947         DEBUG(4,("SAMR Query Group Members.\n"));
1948
1949         if (group_pol == NULL || rid == NULL || attr == NULL || num_mem == NULL) return False;
1950
1951         /* create and send a MSRPC command with api SAMR_QUERY_GROUPMEM */
1952
1953         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1954         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1955
1956         /* store the parameters */
1957         make_samr_q_query_groupmem(&q_o, group_pol);
1958
1959         /* turn parameters into data stream */
1960         samr_io_q_query_groupmem("", &q_o,  &data, 0);
1961
1962         /* send the data on \PIPE\ */
1963         if (rpc_hnd_pipe_req(group_pol, SAMR_QUERY_GROUPMEM, &data, &rdata))
1964         {
1965                 SAMR_R_QUERY_GROUPMEM r_o;
1966                 BOOL p;
1967
1968                 r_o.rid  = NULL;
1969                 r_o.attr = NULL;
1970
1971                 samr_io_r_query_groupmem("", &r_o, &rdata, 0);
1972                 *rid  = r_o.rid ;
1973                 *attr = r_o.attr;
1974                 p = rdata.offset != 0;
1975                 
1976                 if (p && r_o.status != 0)
1977                 {
1978                         /* report error code */
1979                         DEBUG(4,("SAMR_R_QUERY_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
1980                         p = False;
1981                 }
1982
1983                 if (p && r_o.ptr != 0 &&
1984                     r_o.ptr_rids != 0 && r_o.ptr_attrs != 0 &&
1985                     r_o.num_rids == r_o.num_attrs)
1986                 {
1987                         valid_query = True;
1988                         *num_mem = r_o.num_rids;
1989                 }
1990
1991         }
1992
1993         prs_mem_free(&data   );
1994         prs_mem_free(&rdata  );
1995
1996         return valid_query;
1997 }
1998
1999 /****************************************************************************
2000 do a SAMR Query User Groups
2001 ****************************************************************************/
2002 BOOL samr_query_usergroups(  POLICY_HND *pol, uint32 *num_groups,
2003                                 DOM_GID **gid)
2004 {
2005         prs_struct data;
2006         prs_struct rdata;
2007
2008         SAMR_Q_QUERY_USERGROUPS q_o;
2009         BOOL valid_query = False;
2010
2011         DEBUG(4,("SAMR Query User Groups.\n"));
2012
2013         if (pol == NULL || gid == NULL || num_groups == 0) return False;
2014
2015         /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
2016
2017         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2018         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2019
2020         /* store the parameters */
2021         make_samr_q_query_usergroups(&q_o, pol);
2022
2023         /* turn parameters into data stream */
2024         samr_io_q_query_usergroups("", &q_o,  &data, 0);
2025
2026         /* send the data on \PIPE\ */
2027         if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERGROUPS, &data, &rdata))
2028         {
2029                 SAMR_R_QUERY_USERGROUPS r_o;
2030                 BOOL p;
2031
2032                 /* get user info */
2033                 r_o.gid = NULL;
2034
2035                 samr_io_r_query_usergroups("", &r_o, &rdata, 0);
2036                 *gid = r_o.gid;
2037                 p = rdata.offset != 0;
2038                 
2039                 if (p && r_o.status != 0)
2040                 {
2041                         /* report error code */
2042                         DEBUG(4,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
2043                         p = False;
2044                 }
2045
2046                 if (p && r_o.ptr_0 != 0)
2047                 {
2048                         valid_query = True;
2049                         *num_groups = r_o.num_entries;
2050                 }
2051
2052         }
2053
2054         prs_mem_free(&data   );
2055         prs_mem_free(&rdata  );
2056
2057         return valid_query;
2058 }
2059
2060 /****************************************************************************
2061 do a SAMR Query Group Info
2062 ****************************************************************************/
2063 BOOL samr_query_groupinfo(  POLICY_HND *pol,
2064                                 uint16 switch_value, GROUP_INFO_CTR* ctr)
2065 {
2066         prs_struct data;
2067         prs_struct rdata;
2068
2069         SAMR_Q_QUERY_GROUPINFO q_o;
2070         BOOL valid_query = False;
2071
2072         DEBUG(4,("SAMR Query Group Info.  level: %d\n", switch_value));
2073
2074         if (pol == NULL || ctr == NULL || switch_value == 0) return False;
2075
2076         /* create and send a MSRPC command with api SAMR_QUERY_GROUPINFO */
2077
2078         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2079         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2080
2081         /* store the parameters */
2082         make_samr_q_query_groupinfo(&q_o, pol, switch_value);
2083
2084         /* turn parameters into data stream */
2085         samr_io_q_query_groupinfo("", &q_o,  &data, 0);
2086
2087         /* send the data on \PIPE\ */
2088         if (rpc_hnd_pipe_req(pol, SAMR_QUERY_GROUPINFO, &data, &rdata))
2089         {
2090                 SAMR_R_QUERY_GROUPINFO r_o;
2091                 BOOL p;
2092
2093                 /* get group info */
2094                 r_o.ctr = ctr;
2095
2096                 samr_io_r_query_groupinfo("", &r_o, &rdata, 0);
2097                 p = rdata.offset != 0;
2098                 
2099                 if (p && r_o.status != 0)
2100                 {
2101                         /* report error code */
2102                         DEBUG(4,("SAMR_R_QUERY_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
2103                         p = False;
2104                 }
2105
2106                 if (p && r_o.ctr->switch_value1 != switch_value)
2107                 {
2108                         DEBUG(4,("SAMR_R_QUERY_GROUPINFO: received incorrect level %d\n",
2109                                   r_o.ctr->switch_value1));
2110                 }
2111
2112                 if (p && r_o.ptr != 0)
2113                 {
2114                         valid_query = True;
2115                 }
2116         }
2117
2118         prs_mem_free(&data   );
2119         prs_mem_free(&rdata  );
2120
2121         return valid_query;
2122 }
2123
2124 /****************************************************************************
2125 do a SAMR Set User Info
2126 ****************************************************************************/
2127 BOOL samr_set_userinfo2(  POLICY_HND *pol, uint16 switch_value,
2128                                 void* usr)
2129 {
2130         prs_struct data;
2131         prs_struct rdata;
2132
2133         SAMR_Q_SET_USERINFO2 q_o;
2134         BOOL valid_query = False;
2135
2136         DEBUG(4,("SAMR Set User Info 2.  level: %d\n", switch_value));
2137
2138         if (pol == NULL || usr == NULL || switch_value == 0) return False;
2139
2140         /* create and send a MSRPC command with api SAMR_SET_USERINFO2 */
2141
2142         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2143         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2144
2145         /* store the parameters */
2146         make_samr_q_set_userinfo2(&q_o, pol, switch_value, usr);
2147
2148         /* turn parameters into data stream */
2149         samr_io_q_set_userinfo2("", &q_o,  &data, 0);
2150
2151         /* send the data on \PIPE\ */
2152         if (rpc_hnd_pipe_req(pol, SAMR_SET_USERINFO2, &data, &rdata))
2153         {
2154                 SAMR_R_SET_USERINFO2 r_o;
2155                 BOOL p;
2156
2157                 samr_io_r_set_userinfo2("", &r_o, &rdata, 0);
2158                 p = rdata.offset != 0;
2159                 
2160                 if (p && r_o.status != 0)
2161                 {
2162                         /* report error code */
2163                         DEBUG(4,("SAMR_R_QUERY_USERINFO2: %s\n", get_nt_error_msg(r_o.status)));
2164                         p = False;
2165                 }
2166
2167                 if (p)
2168                 {
2169                         valid_query = True;
2170                 }
2171         }
2172
2173         prs_mem_free(&data   );
2174         prs_mem_free(&rdata  );
2175
2176         return valid_query;
2177 }
2178
2179 /****************************************************************************
2180 do a SAMR Set User Info
2181 ****************************************************************************/
2182 BOOL samr_set_userinfo(  POLICY_HND *pol, uint16 switch_value, void* usr)
2183 {
2184         prs_struct data;
2185         prs_struct rdata;
2186
2187         SAMR_Q_SET_USERINFO q_o;
2188         BOOL valid_query = False;
2189
2190         DEBUG(4,("SAMR Set User Info.  level: %d\n", switch_value));
2191
2192         if (pol == NULL || usr == NULL || switch_value == 0) return False;
2193
2194         /* create and send a MSRPC command with api SAMR_SET_USERINFO */
2195
2196         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2197         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2198
2199         /* store the parameters */
2200         make_samr_q_set_userinfo(&q_o, pol, switch_value, usr);
2201
2202         /* turn parameters into data stream */
2203         samr_io_q_set_userinfo("", &q_o,  &data, 0);
2204
2205         /* send the data on \PIPE\ */
2206         if (rpc_hnd_pipe_req(pol, SAMR_SET_USERINFO, &data, &rdata))
2207         {
2208                 SAMR_R_SET_USERINFO r_o;
2209                 BOOL p;
2210
2211                 samr_io_r_set_userinfo("", &r_o, &rdata, 0);
2212                 p = rdata.offset != 0;
2213                 
2214                 if (p && r_o.status != 0)
2215                 {
2216                         /* report error code */
2217                         DEBUG(4,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
2218                         p = False;
2219                 }
2220
2221                 if (p)
2222                 {
2223                         valid_query = True;
2224                 }
2225         }
2226
2227         prs_mem_free(&data   );
2228         prs_mem_free(&rdata  );
2229
2230         return valid_query;
2231 }
2232
2233 /****************************************************************************
2234 do a SAMR Query User Info
2235 ****************************************************************************/
2236 BOOL samr_query_userinfo(  POLICY_HND *pol, uint16 switch_value, void* usr)
2237 {
2238         prs_struct data;
2239         prs_struct rdata;
2240
2241         SAMR_Q_QUERY_USERINFO q_o;
2242         BOOL valid_query = False;
2243
2244         DEBUG(4,("SAMR Query User Info.  level: %d\n", switch_value));
2245
2246         if (pol == NULL || usr == NULL || switch_value == 0) return False;
2247
2248         /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
2249
2250         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2251         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2252
2253         /* store the parameters */
2254         make_samr_q_query_userinfo(&q_o, pol, switch_value);
2255
2256         /* turn parameters into data stream */
2257         samr_io_q_query_userinfo("", &q_o,  &data, 0);
2258
2259         /* send the data on \PIPE\ */
2260         if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERINFO, &data, &rdata))
2261         {
2262                 SAMR_R_QUERY_USERINFO r_o;
2263                 BOOL p;
2264
2265                 /* get user info */
2266                 r_o.info.id = usr;
2267
2268                 samr_io_r_query_userinfo("", &r_o, &rdata, 0);
2269                 p = rdata.offset != 0;
2270                 
2271                 if (p && r_o.status != 0)
2272                 {
2273                         /* report error code */
2274                         DEBUG(4,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
2275                         p = False;
2276                 }
2277
2278                 if (p && r_o.switch_value != switch_value)
2279                 {
2280                         DEBUG(4,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
2281                                   r_o.switch_value));
2282                 }
2283
2284                 if (p && r_o.ptr != 0)
2285                 {
2286                         valid_query = True;
2287                 }
2288         }
2289
2290         prs_mem_free(&data   );
2291         prs_mem_free(&rdata  );
2292
2293         return valid_query;
2294 }
2295
2296 /****************************************************************************
2297 do a SAMR Close
2298 ****************************************************************************/
2299 BOOL samr_close(  POLICY_HND *hnd)
2300 {
2301         prs_struct data;
2302         prs_struct rdata;
2303
2304         SAMR_Q_CLOSE_HND q_c;
2305         BOOL valid_close = False;
2306
2307         DEBUG(4,("SAMR Close\n"));
2308
2309         if (hnd == NULL) return False;
2310
2311         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2312         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2313
2314         /* create and send a MSRPC command with api SAMR_CLOSE_HND */
2315
2316         /* store the parameters */
2317         make_samr_q_close_hnd(&q_c, hnd);
2318
2319         /* turn parameters into data stream */
2320         samr_io_q_close_hnd("", &q_c,  &data, 0);
2321
2322         /* send the data on \PIPE\ */
2323         if (rpc_hnd_pipe_req(hnd, SAMR_CLOSE_HND, &data, &rdata))
2324         {
2325                 SAMR_R_CLOSE_HND r_c;
2326                 BOOL p;
2327
2328                 samr_io_r_close_hnd("", &r_c, &rdata, 0);
2329                 p = rdata.offset != 0;
2330
2331                 if (p && r_c.status != 0)
2332                 {
2333                         /* report error code */
2334                         DEBUG(4,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
2335                         p = False;
2336                 }
2337
2338                 if (p)
2339                 {
2340                         /* check that the returned policy handle is all zeros */
2341                         uint32 i;
2342                         valid_close = True;
2343
2344                         for (i = 0; i < sizeof(r_c.pol.data); i++)
2345                         {
2346                                 if (r_c.pol.data[i] != 0)
2347                                 {
2348                                         valid_close = False;
2349                                         break;
2350                                 }
2351                         }       
2352                         if (!valid_close)
2353                         {
2354                                 DEBUG(4,("SAMR_CLOSE_HND: non-zero handle returned\n"));
2355                         }
2356                 }
2357         }
2358
2359         prs_mem_free(&data   );
2360         prs_mem_free(&rdata  );
2361
2362         close_policy_hnd(hnd);
2363
2364         return valid_close;
2365 }
2366
2367 /****************************************************************************
2368 do a SAMR query display info
2369 ****************************************************************************/
2370 BOOL samr_query_dispinfo(  POLICY_HND *pol_domain, uint16 level,
2371                                 uint32 *num_entries,
2372                                 SAM_DISPINFO_CTR *ctr)
2373 {
2374         prs_struct data;
2375         prs_struct rdata;
2376
2377         SAMR_Q_QUERY_DISPINFO q_o;
2378         BOOL valid_query = False;
2379
2380         DEBUG(4,("SAMR Query Display Info.  level: %d\n", level));
2381
2382         if (pol_domain == NULL || num_entries == NULL || ctr == NULL ||
2383             level == 0)
2384         {
2385                 return False;
2386         }
2387
2388         /* create and send a MSRPC command with api SAMR_QUERY_DISPINFO */
2389
2390         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
2391         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
2392
2393         /* store the parameters */
2394         make_samr_q_query_dispinfo(&q_o, pol_domain, level, 0, 0xffffffff);
2395
2396         /* turn parameters into data stream */
2397         samr_io_q_query_dispinfo("", &q_o,  &data, 0);
2398
2399         /* send the data on \PIPE\ */
2400         if (rpc_hnd_pipe_req(pol_domain, SAMR_QUERY_DISPINFO, &data, &rdata))
2401         {
2402                 SAMR_R_QUERY_DISPINFO r_o;
2403                 BOOL p;
2404
2405                 /* get user info */
2406                 r_o.ctr = ctr;
2407
2408                 samr_io_r_query_dispinfo("", &r_o, &rdata, 0);
2409                 p = rdata.offset != 0;
2410                 
2411                 if (p && r_o.status != 0)
2412                 {
2413                         /* report error code */
2414                         DEBUG(4,("SAMR_R_QUERY_DISPINFO: %s\n", get_nt_error_msg(r_o.status)));
2415                         p = False;
2416                 }
2417
2418                 if (p && r_o.switch_level != level)
2419                 {
2420                         DEBUG(4,("SAMR_R_QUERY_DISPINFO: received incorrect level %d\n",
2421                                   r_o.switch_level));
2422                 }
2423
2424                 if (p && r_o.ptr_entries != 0)
2425                 {
2426                         valid_query = True;
2427                         (*num_entries) = r_o.num_entries;
2428                 }
2429         }
2430
2431         prs_mem_free(&data   );
2432         prs_mem_free(&rdata  );
2433
2434         return valid_query;
2435 }
2436