Updated packaging files from 2.0.0 branch - NOTE: Not yet operative.
[samba.git] / source / rpc_client / cli_samr.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NT Domain Authentication SMB / MSRPC client
5    Copyright (C) Andrew Tridgell 1994-1997
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
7    
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
36 /****************************************************************************
37 do a SAMR create domain alias
38 ****************************************************************************/
39 BOOL create_samr_domain_alias(struct cli_state *cli, 
40                                 POLICY_HND *pol_open_domain,
41                                 const char *acct_name, const char *acct_desc,
42                                 uint32 *rid)
43 {
44         POLICY_HND pol_open_alias;
45         ALIAS_INFO_CTR ctr;
46         if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
47
48         /* send create alias */
49         if (!samr_create_dom_alias(cli,
50                                 pol_open_domain,
51                                 acct_name,
52                                 &pol_open_alias, rid))
53         {
54                 return False;
55         }
56
57         DEBUG(5,("create_samr_domain_alias: name: %s rid 0x%x\n",
58                   acct_name, *rid));
59
60         ctr.switch_value1 = 3;
61         make_samr_alias_info3(&ctr.alias.info3, acct_desc);
62
63         /* send set alias info */
64         if (!samr_set_aliasinfo(cli,
65                                 &pol_open_alias,
66                                 &ctr))
67         {
68                 DEBUG(5,("create_samr_domain_alias: error in samr_set_aliasinfo\n"));
69         }
70
71         return samr_close(cli, &pol_open_alias);
72 }
73
74 /****************************************************************************
75 do a SAMR create domain group
76 ****************************************************************************/
77 BOOL create_samr_domain_group(struct cli_state *cli, 
78                                 POLICY_HND *pol_open_domain,
79                                 const char *acct_name, const char *acct_desc,
80                                 uint32 *rid)
81 {
82         POLICY_HND pol_open_group;
83         GROUP_INFO_CTR ctr;
84         if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
85
86         /* send create group*/
87         if (!samr_create_dom_group(cli,
88                                 pol_open_domain,
89                                 acct_name,
90                                 &pol_open_group, rid))
91         {
92                 return False;
93         }
94
95         DEBUG(5,("create_samr_domain_group: name: %s rid 0x%x\n",
96                   acct_name, *rid));
97
98         ctr.switch_value1 = 4;
99         ctr.switch_value2 = 4;
100         make_samr_group_info4(&ctr.group.info4, acct_desc);
101
102         /* send user groups query */
103         if (!samr_set_groupinfo(cli,
104                                 &pol_open_group,
105                                 &ctr))
106         {
107                 DEBUG(5,("create_samr_domain_group: error in samr_set_groupinfo\n"));
108         }
109
110         return samr_close(cli, &pol_open_group);
111 }
112
113 /****************************************************************************
114 do a SAMR query user groups
115 ****************************************************************************/
116 BOOL get_samr_query_usergroups(struct cli_state *cli, 
117                                 POLICY_HND *pol_open_domain, uint32 user_rid,
118                                 uint32 *num_groups, DOM_GID *gid)
119 {
120         POLICY_HND pol_open_user;
121         if (pol_open_domain == NULL || num_groups == NULL || gid == NULL) return False;
122
123         /* send open domain (on user sid) */
124         if (!samr_open_user(cli,
125                                 pol_open_domain,
126                                 0x02011b, user_rid,
127                                 &pol_open_user))
128         {
129                 return False;
130         }
131
132         /* send user groups query */
133         if (!samr_query_usergroups(cli,
134                                 &pol_open_user,
135                                 num_groups, gid))
136         {
137                 DEBUG(5,("samr_query_usergroups: error in query user groups\n"));
138         }
139
140         return samr_close(cli, &pol_open_user);
141 }
142
143 /****************************************************************************
144 do a SAMR query user info
145 ****************************************************************************/
146 BOOL get_samr_query_userinfo(struct cli_state *cli, 
147                                 POLICY_HND *pol_open_domain,
148                                 uint32 info_level,
149                                 uint32 user_rid, SAM_USER_INFO_21 *usr)
150 {
151         POLICY_HND pol_open_user;
152         if (pol_open_domain == NULL || usr == NULL) return False;
153
154         bzero(usr, sizeof(*usr));
155
156         /* send open domain (on user sid) */
157         if (!samr_open_user(cli,
158                                 pol_open_domain,
159                                 0x02011b, user_rid,
160                                 &pol_open_user))
161         {
162                 return False;
163         }
164
165         /* send user info query */
166         if (!samr_query_userinfo(cli,
167                                 &pol_open_user,
168                                 info_level, (void*)usr))
169         {
170                 DEBUG(5,("samr_query_userinfo: error in query user info, level 0x%x\n",
171                           info_level));
172         }
173
174         return samr_close(cli, &pol_open_user);
175 }
176
177 /****************************************************************************
178 do a SAMR change user password command
179 ****************************************************************************/
180 BOOL samr_chgpasswd_user(struct cli_state *cli,
181                 char *srv_name, char *user_name,
182                 char nt_newpass[516], uchar nt_oldhash[16],
183                 char lm_newpass[516], uchar lm_oldhash[16])
184 {
185         prs_struct data;
186         prs_struct rdata;
187
188         SAMR_Q_CHGPASSWD_USER q_e;
189         BOOL valid_pwc = False;
190
191         /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
192
193         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
194         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
195
196         DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
197                 srv_name, user_name));
198
199         make_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
200                                    nt_newpass, nt_oldhash,
201                                    lm_newpass, lm_oldhash);
202
203         /* turn parameters into data stream */
204         samr_io_q_chgpasswd_user("", &q_e, &data, 0);
205
206         /* send the data on \PIPE\ */
207         if (rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &data, &rdata))
208         {
209                 SAMR_R_CHGPASSWD_USER r_e;
210                 BOOL p;
211
212                 samr_io_r_chgpasswd_user("", &r_e, &rdata, 0);
213
214                 p = rdata.offset != 0;
215                 if (p && r_e.status != 0)
216                 {
217                         /* report error code */
218                         DEBUG(0,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
219                         p = False;
220                 }
221
222                 if (p)
223                 {
224                         valid_pwc = True;
225                 }
226         }
227
228         prs_mem_free(&data   );
229         prs_mem_free(&rdata  );
230
231         return valid_pwc;
232 }
233
234 /****************************************************************************
235 do a SAMR unknown 0x38 command
236 ****************************************************************************/
237 BOOL samr_unknown_38(struct cli_state *cli, char *srv_name)
238 {
239         prs_struct data;
240         prs_struct rdata;
241
242         SAMR_Q_UNKNOWN_38 q_e;
243         BOOL valid_un8 = False;
244
245         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
246
247         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
248         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
249
250         DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name));
251
252         make_samr_q_unknown_38(&q_e, srv_name);
253
254         /* turn parameters into data stream */
255         samr_io_q_unknown_38("", &q_e, &data, 0);
256
257         /* send the data on \PIPE\ */
258         if (rpc_api_pipe_req(cli, SAMR_UNKNOWN_38, &data, &rdata))
259         {
260                 SAMR_R_UNKNOWN_38 r_e;
261                 BOOL p;
262
263                 samr_io_r_unknown_38("", &r_e, &rdata, 0);
264
265                 p = rdata.offset != 0;
266 #if 0
267                 if (p && r_e.status != 0)
268                 {
269                         /* report error code */
270                         DEBUG(0,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status)));
271                         p = False;
272                 }
273 #endif
274                 if (p)
275                 {
276                         valid_un8 = True;
277                 }
278         }
279
280         prs_mem_free(&data   );
281         prs_mem_free(&rdata  );
282
283         return valid_un8;
284 }
285
286 /****************************************************************************
287 do a SAMR unknown 0x8 command
288 ****************************************************************************/
289 BOOL samr_query_dom_info(struct cli_state *cli, 
290                                 POLICY_HND *domain_pol, uint16 switch_value)
291 {
292         prs_struct data;
293         prs_struct rdata;
294
295         SAMR_Q_QUERY_DOMAIN_INFO q_e;
296         BOOL valid_un8 = False;
297
298         DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
299
300         if (domain_pol == NULL) return False;
301
302         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
303
304         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
305         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
306
307         /* store the parameters */
308         make_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
309
310         /* turn parameters into data stream */
311         samr_io_q_query_dom_info("", &q_e, &data, 0);
312
313         /* send the data on \PIPE\ */
314         if (rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &data, &rdata))
315         {
316 #if 0
317                 SAMR_R_QUERY_DOMAIN_INFO r_e;
318                 BOOL p;
319
320                 samr_io_r_query_dom_info("", &r_e, &rdata, 0);
321
322                 p = rdata.offset != 0;
323                 if (p && r_e.status != 0)
324                 {
325                         /* report error code */
326                         DEBUG(0,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status)));
327                         p = False;
328                 }
329
330                 if (p)
331                 {
332                         valid_un8 = True;
333                 }
334 #endif
335         }
336
337         prs_mem_free(&data   );
338         prs_mem_free(&rdata  );
339
340         return valid_un8;
341 }
342
343 /****************************************************************************
344 do a SAMR enumerate users
345 ****************************************************************************/
346 BOOL samr_enum_dom_users(struct cli_state *cli, 
347                                 POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
348                                 uint16 acb_mask, uint16 unk_1, uint32 size,
349                                 struct acct_info **sam,
350                                 int *num_sam_users)
351 {
352         prs_struct data;
353         prs_struct rdata;
354
355         SAMR_Q_ENUM_DOM_USERS q_e;
356         BOOL valid_pol = False;
357
358         DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
359
360         if (pol == NULL || num_sam_users == NULL) return False;
361
362         /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
363
364         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
365         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
366
367         /* store the parameters */
368         make_samr_q_enum_dom_users(&q_e, pol,
369                                    num_entries, unk_0,
370                                    acb_mask, unk_1, size);
371
372         /* turn parameters into data stream */
373         samr_io_q_enum_dom_users("", &q_e, &data, 0);
374
375         /* send the data on \PIPE\ */
376         if (rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &data, &rdata))
377         {
378                 SAMR_R_ENUM_DOM_USERS r_e;
379                 BOOL p;
380
381                 samr_io_r_enum_dom_users("", &r_e, &rdata, 0);
382
383                 p = rdata.offset != 0;
384                 if (p && r_e.status != 0)
385                 {
386                         /* report error code */
387                         DEBUG(0,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
388                         p = False;
389                 }
390
391                 if (p)
392                 {
393                         int i;
394                         int name_idx = 0;
395
396                         *num_sam_users = r_e.num_entries2;
397                         if (*num_sam_users > MAX_SAM_ENTRIES)
398                         {
399                                 *num_sam_users = MAX_SAM_ENTRIES;
400                                 DEBUG(2,("samr_enum_dom_users: sam user entries limited to %d\n",
401                                           *num_sam_users));
402                         }
403
404                         *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_users));
405                                     
406                         if ((*sam) == NULL)
407                         {
408                                 *num_sam_users = 0;
409                         }
410
411                         for (i = 0; i < *num_sam_users; i++)
412                         {
413
414                                 (*sam)[i].user_rid = r_e.sam[i].rid;
415                                 if (r_e.sam[i].hdr_name.buffer)
416                                 {
417                                         char *acct_name = unistrn2(r_e.uni_acct_name[name_idx].buffer,
418                                                                    r_e.uni_acct_name[name_idx].uni_str_len);
419                                         fstrcpy((*sam)[i].acct_name, acct_name);
420                                         name_idx++;
421                                 }
422                                 else
423                                 {
424                                         bzero((*sam)[i].acct_name, sizeof((*sam)[i].acct_name));
425                                 }
426                                 DEBUG(5,("samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
427                                           i, (*sam)[i].user_rid, (*sam)[i].acct_name));
428                         }
429                         valid_pol = True;
430                 }
431         }
432
433         prs_mem_free(&data   );
434         prs_mem_free(&rdata  );
435
436         return valid_pol;
437 }
438
439 /****************************************************************************
440 do a SAMR Connect
441 ****************************************************************************/
442 BOOL samr_connect(struct cli_state *cli, 
443                                 char *srv_name, uint32 unknown_0,
444                                 POLICY_HND *connect_pol)
445 {
446         prs_struct data;
447         prs_struct rdata;
448
449         SAMR_Q_CONNECT q_o;
450         BOOL valid_pol = False;
451
452         DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
453                                 srv_name, unknown_0));
454
455         if (srv_name == NULL || connect_pol == NULL) return False;
456
457         /* create and send a MSRPC command with api SAMR_CONNECT */
458
459         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
460         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
461
462         /* store the parameters */
463         make_samr_q_connect(&q_o, srv_name, unknown_0);
464
465         /* turn parameters into data stream */
466         samr_io_q_connect("", &q_o,  &data, 0);
467
468         /* send the data on \PIPE\ */
469         if (rpc_api_pipe_req(cli, SAMR_CONNECT, &data, &rdata))
470         {
471                 SAMR_R_CONNECT r_o;
472                 BOOL p;
473
474                 samr_io_r_connect("", &r_o, &rdata, 0);
475                 p = rdata.offset != 0;
476                 
477                 if (p && r_o.status != 0)
478                 {
479                         /* report error code */
480                         DEBUG(0,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
481                         p = False;
482                 }
483
484                 if (p)
485                 {
486                         memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
487                         valid_pol = True;
488                 }
489         }
490
491         prs_mem_free(&data   );
492         prs_mem_free(&rdata  );
493
494         return valid_pol;
495 }
496
497 /****************************************************************************
498 do a SAMR Open User
499 ****************************************************************************/
500 BOOL samr_open_user(struct cli_state *cli, 
501                                 POLICY_HND *pol, uint32 unk_0, uint32 rid, 
502                                 POLICY_HND *user_pol)
503 {
504         prs_struct data;
505         prs_struct rdata;
506
507         SAMR_Q_OPEN_USER q_o;
508         BOOL valid_pol = False;
509
510         DEBUG(4,("SAMR Open User.  unk_0: %08x RID:%x\n",
511                   unk_0, rid));
512
513         if (pol == NULL || user_pol == NULL) return False;
514
515         /* create and send a MSRPC command with api SAMR_OPEN_USER */
516
517         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
518         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
519
520         /* store the parameters */
521         make_samr_q_open_user(&q_o, pol, unk_0, rid);
522
523         /* turn parameters into data stream */
524         samr_io_q_open_user("", &q_o,  &data, 0);
525
526         /* send the data on \PIPE\ */
527         if (rpc_api_pipe_req(cli, SAMR_OPEN_USER, &data, &rdata))
528         {
529                 SAMR_R_OPEN_USER r_o;
530                 BOOL p;
531
532                 samr_io_r_open_user("", &r_o, &rdata, 0);
533                 p = rdata.offset != 0;
534                 
535                 if (p && r_o.status != 0)
536                 {
537                         /* report error code */
538                         DEBUG(0,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
539                         p = False;
540                 }
541
542                 if (p)
543                 {
544                         memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
545                         valid_pol = True;
546                 }
547         }
548
549         prs_mem_free(&data   );
550         prs_mem_free(&rdata  );
551
552         return valid_pol;
553 }
554
555 /****************************************************************************
556 do a SAMR Open Alias
557 ****************************************************************************/
558 BOOL samr_open_alias(struct cli_state *cli, 
559                                 POLICY_HND *domain_pol, uint32 rid,
560                                 POLICY_HND *alias_pol)
561 {
562         prs_struct data;
563         prs_struct rdata;
564
565         SAMR_Q_OPEN_ALIAS q_o;
566         BOOL valid_pol = False;
567
568         DEBUG(4,("SAMR Open Alias. RID:%x\n", rid));
569
570         if (alias_pol == NULL || domain_pol == NULL) return False;
571
572         /* create and send a MSRPC command with api SAMR_OPEN_ALIAS */
573
574         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
575         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
576
577         /* store the parameters */
578         make_samr_q_open_alias(&q_o, domain_pol, 0x0008, rid);
579
580         /* turn parameters into data stream */
581         samr_io_q_open_alias("", &q_o,  &data, 0);
582
583         /* send the data on \PIPE\ */
584         if (rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &data, &rdata))
585         {
586                 SAMR_R_OPEN_ALIAS r_o;
587                 BOOL p;
588
589                 samr_io_r_open_alias("", &r_o, &rdata, 0);
590                 p = rdata.offset != 0;
591
592                 if (p && r_o.status != 0)
593                 {
594                         /* report error code */
595                         DEBUG(0,("SAMR_R_OPEN_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
596                         p = False;
597                 }
598
599                 if (p)
600                 {
601                         memcpy(alias_pol, &r_o.pol, sizeof(r_o.pol));
602                         valid_pol = True;
603                 }
604         }
605
606         prs_mem_free(&data   );
607         prs_mem_free(&rdata  );
608
609         return valid_pol;
610 }
611
612 /****************************************************************************
613 do a SAMR Create Domain Alias
614 ****************************************************************************/
615 BOOL samr_create_dom_alias(struct cli_state *cli, 
616                                 POLICY_HND *domain_pol, const char *acct_name,
617                                 POLICY_HND *alias_pol, uint32 *rid)
618 {
619         prs_struct data;
620         prs_struct rdata;
621
622         SAMR_Q_CREATE_DOM_ALIAS q_o;
623         BOOL valid_pol = False;
624
625         if (alias_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
626
627         /* create and send a MSRPC command with api SAMR_CREATE_DOM_ALIAS */
628
629         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
630         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
631
632         DEBUG(4,("SAMR Create Domain Alias. Name:%s\n", acct_name));
633
634         /* store the parameters */
635         make_samr_q_create_dom_alias(&q_o, domain_pol, acct_name);
636
637         /* turn parameters into data stream */
638         samr_io_q_create_dom_alias("", &q_o,  &data, 0);
639
640         /* send the data on \PIPE\ */
641         if (rpc_api_pipe_req(cli, SAMR_CREATE_DOM_ALIAS, &data, &rdata))
642         {
643                 SAMR_R_CREATE_DOM_ALIAS r_o;
644                 BOOL p;
645
646                 samr_io_r_create_dom_alias("", &r_o, &rdata, 0);
647                 p = rdata.offset != 0;
648
649                 if (p && r_o.status != 0)
650                 {
651                         /* report error code */
652                         DEBUG(0,("SAMR_R_CREATE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
653                         p = False;
654                 }
655
656                 if (p)
657                 {
658                         memcpy(alias_pol, &r_o.alias_pol, sizeof(r_o.alias_pol));
659                         *rid = r_o.rid;
660                         valid_pol = True;
661                 }
662         }
663
664         prs_mem_free(&data   );
665         prs_mem_free(&rdata  );
666
667         return valid_pol;
668 }
669
670 /****************************************************************************
671 do a SAMR Set Alias Info
672 ****************************************************************************/
673 BOOL samr_set_aliasinfo(struct cli_state *cli, 
674                                 POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
675 {
676         prs_struct data;
677         prs_struct rdata;
678
679         SAMR_Q_SET_ALIASINFO q_o;
680         BOOL valid_pol = False;
681
682         if (alias_pol == NULL || ctr == NULL) return False;
683
684         /* create and send a MSRPC command with api SAMR_SET_ALIASINFO */
685
686         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
687         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
688
689         DEBUG(4,("SAMR Set Alias Info\n"));
690
691         /* store the parameters */
692         make_samr_q_set_aliasinfo(&q_o, alias_pol, ctr);
693
694         /* turn parameters into data stream */
695         samr_io_q_set_aliasinfo("", &q_o,  &data, 0);
696
697         /* send the data on \PIPE\ */
698         if (rpc_api_pipe_req(cli, SAMR_SET_ALIASINFO, &data, &rdata))
699         {
700                 SAMR_R_SET_ALIASINFO r_o;
701                 BOOL p;
702
703                 samr_io_r_set_aliasinfo("", &r_o, &rdata, 0);
704                 p = rdata.offset != 0;
705
706                 if (p && r_o.status != 0)
707                 {
708                         /* report error code */
709                         DEBUG(0,("SAMR_R_SET_ALIASINFO: %s\n", get_nt_error_msg(r_o.status)));
710                         p = False;
711                 }
712
713                 if (p)
714                 {
715                         valid_pol = True;
716                 }
717         }
718
719         prs_mem_free(&data   );
720         prs_mem_free(&rdata  );
721
722         return valid_pol;
723 }
724
725 /****************************************************************************
726 do a SAMR Open Group
727 ****************************************************************************/
728 BOOL samr_open_group(struct cli_state *cli, 
729                                 POLICY_HND *domain_pol, uint32 rid,
730                                 POLICY_HND *group_pol)
731 {
732         prs_struct data;
733         prs_struct rdata;
734
735         SAMR_Q_OPEN_GROUP q_o;
736         BOOL valid_pol = False;
737
738         DEBUG(4,("SAMR Open Group. RID:%x\n", rid));
739
740         if (group_pol == NULL || domain_pol == NULL) return False;
741
742         /* create and send a MSRPC command with api SAMR_OPEN_GROUP */
743
744         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
745         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
746
747         /* store the parameters */
748         make_samr_q_open_group(&q_o, domain_pol, 0x0001, rid);
749
750         /* turn parameters into data stream */
751         samr_io_q_open_group("", &q_o,  &data, 0);
752
753         /* send the data on \PIPE\ */
754         if (rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &data, &rdata))
755         {
756                 SAMR_R_OPEN_GROUP r_o;
757                 BOOL p;
758
759                 samr_io_r_open_group("", &r_o, &rdata, 0);
760                 p = rdata.offset != 0;
761
762                 if (p && r_o.status != 0)
763                 {
764                         /* report error code */
765                         DEBUG(0,("SAMR_R_OPEN_GROUP: %s\n", get_nt_error_msg(r_o.status)));
766                         p = False;
767                 }
768
769                 if (p)
770                 {
771                         memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
772                         valid_pol = True;
773                 }
774         }
775
776         prs_mem_free(&data   );
777         prs_mem_free(&rdata  );
778
779         return valid_pol;
780 }
781
782 /****************************************************************************
783 do a SAMR Create Domain Group
784 ****************************************************************************/
785 BOOL samr_create_dom_group(struct cli_state *cli, 
786                                 POLICY_HND *domain_pol, const char *acct_name,
787                                 POLICY_HND *group_pol, uint32 *rid)
788 {
789         prs_struct data;
790         prs_struct rdata;
791
792         SAMR_Q_CREATE_DOM_GROUP q_o;
793         BOOL valid_pol = False;
794
795         if (group_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
796
797         /* create and send a MSRPC command with api SAMR_CREATE_DOM_GROUP */
798
799         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
800         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
801
802         DEBUG(4,("SAMR Create Domain Group. Name:%s\n", acct_name));
803
804         /* store the parameters */
805         make_samr_q_create_dom_group(&q_o, domain_pol, acct_name);
806
807         /* turn parameters into data stream */
808         samr_io_q_create_dom_group("", &q_o,  &data, 0);
809
810         /* send the data on \PIPE\ */
811         if (rpc_api_pipe_req(cli, SAMR_CREATE_DOM_GROUP, &data, &rdata))
812         {
813                 SAMR_R_CREATE_DOM_GROUP r_o;
814                 BOOL p;
815
816                 samr_io_r_create_dom_group("", &r_o, &rdata, 0);
817                 p = rdata.offset != 0;
818
819                 if (p && r_o.status != 0)
820                 {
821                         /* report error code */
822                         DEBUG(0,("SAMR_R_CREATE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
823                         p = False;
824                 }
825
826                 if (p)
827                 {
828                         memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
829                         *rid = r_o.rid;
830                         valid_pol = True;
831                 }
832         }
833
834         prs_mem_free(&data   );
835         prs_mem_free(&rdata  );
836
837         return valid_pol;
838 }
839
840 /****************************************************************************
841 do a SAMR Set Group Info
842 ****************************************************************************/
843 BOOL samr_set_groupinfo(struct cli_state *cli, 
844                                 POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
845 {
846         prs_struct data;
847         prs_struct rdata;
848
849         SAMR_Q_SET_GROUPINFO q_o;
850         BOOL valid_pol = False;
851
852         if (group_pol == NULL || ctr == NULL) return False;
853
854         /* create and send a MSRPC command with api SAMR_SET_GROUPINFO */
855
856         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
857         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
858
859         DEBUG(4,("SAMR Set Group Info\n"));
860
861         /* store the parameters */
862         make_samr_q_set_groupinfo(&q_o, group_pol, ctr);
863
864         /* turn parameters into data stream */
865         samr_io_q_set_groupinfo("", &q_o,  &data, 0);
866
867         /* send the data on \PIPE\ */
868         if (rpc_api_pipe_req(cli, SAMR_SET_GROUPINFO, &data, &rdata))
869         {
870                 SAMR_R_SET_GROUPINFO r_o;
871                 BOOL p;
872
873                 samr_io_r_set_groupinfo("", &r_o, &rdata, 0);
874                 p = rdata.offset != 0;
875
876                 if (p && r_o.status != 0)
877                 {
878                         /* report error code */
879                         DEBUG(0,("SAMR_R_SET_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
880                         p = False;
881                 }
882
883                 if (p)
884                 {
885                         valid_pol = True;
886                 }
887         }
888
889         prs_mem_free(&data   );
890         prs_mem_free(&rdata  );
891
892         return valid_pol;
893 }
894
895 /****************************************************************************
896 do a SAMR Open Domain
897 ****************************************************************************/
898 BOOL samr_open_domain(struct cli_state *cli, 
899                                 POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
900                                 POLICY_HND *domain_pol)
901 {
902         pstring sid_str;
903         prs_struct data;
904         prs_struct rdata;
905
906         SAMR_Q_OPEN_DOMAIN q_o;
907         BOOL valid_pol = False;
908
909         sid_to_string(sid_str, sid);
910         DEBUG(4,("SAMR Open Domain.  SID:%s RID:%x\n", sid_str, rid));
911
912         if (connect_pol == NULL || sid == NULL || domain_pol == NULL) return False;
913
914         /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
915
916         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
917         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
918
919         /* store the parameters */
920         make_samr_q_open_domain(&q_o, connect_pol, rid, sid);
921
922         /* turn parameters into data stream */
923         samr_io_q_open_domain("", &q_o,  &data, 0);
924
925         /* send the data on \PIPE\ */
926         if (rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &data, &rdata))
927         {
928                 SAMR_R_OPEN_DOMAIN r_o;
929                 BOOL p;
930
931                 samr_io_r_open_domain("", &r_o, &rdata, 0);
932                 p = rdata.offset != 0;
933
934                 if (p && r_o.status != 0)
935                 {
936                         /* report error code */
937                         DEBUG(0,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
938                         p = False;
939                 }
940
941                 if (p)
942                 {
943                         memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
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 Query Unknown 12
956 ****************************************************************************/
957 BOOL samr_query_unknown_12(struct cli_state *cli, 
958                                 POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
959                                 uint32 *num_names,
960                                 fstring names[MAX_LOOKUP_SIDS],
961                                 uint32  type [MAX_LOOKUP_SIDS])
962 {
963         prs_struct data;
964         prs_struct rdata;
965
966         SAMR_Q_UNKNOWN_12 q_o;
967         BOOL valid_query = False;
968
969         if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL ||
970             num_names == NULL || names == NULL || type == NULL ) return False;
971
972         /* create and send a MSRPC command with api SAMR_UNKNOWN_12 */
973
974         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
975         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
976
977         DEBUG(4,("SAMR Query Unknown 12.\n"));
978
979         /* store the parameters */
980         make_samr_q_unknown_12(&q_o, pol, rid, num_gids, gids);
981
982         /* turn parameters into data stream */
983         samr_io_q_unknown_12("", &q_o,  &data, 0);
984
985         /* send the data on \PIPE\ */
986         if (rpc_api_pipe_req(cli, SAMR_UNKNOWN_12, &data, &rdata))
987         {
988                 SAMR_R_UNKNOWN_12 r_o;
989                 BOOL p;
990
991                 samr_io_r_unknown_12("", &r_o, &rdata, 0);
992                 p = rdata.offset != 0;
993                 
994                 if (p && r_o.status != 0)
995                 {
996                         /* report error code */
997                         DEBUG(0,("SAMR_R_UNKNOWN_12: %s\n", get_nt_error_msg(r_o.status)));
998                         p = False;
999                 }
1000
1001                 if (p)
1002                 {
1003                         if (r_o.ptr_names != 0 && r_o.ptr_types != 0 &&
1004                             r_o.num_types1 == r_o.num_names1)
1005                         {
1006                                 int i;
1007
1008                                 valid_query = True;
1009                                 *num_names = r_o.num_names1;
1010
1011                                 for (i = 0; i < r_o.num_names1; i++)
1012                                 {
1013                                         fstrcpy(names[i], unistr2_to_str(&r_o.uni_name[i]));
1014                                 }
1015                                 for (i = 0; i < r_o.num_types1; i++)
1016                                 {
1017                                         type[i] = r_o.type[i];
1018                                 }
1019                         }
1020                         else if (r_o.ptr_names == 0 && r_o.ptr_types == 0)
1021                         {
1022                                 valid_query = True;
1023                                 *num_names = 0;
1024                         }
1025                         else
1026                         {
1027                                 p = False;
1028                         }
1029                 }
1030         }
1031
1032         prs_mem_free(&data   );
1033         prs_mem_free(&rdata  );
1034
1035         return valid_query;
1036 }
1037
1038 /****************************************************************************
1039 do a SAMR Query User Aliases
1040 ****************************************************************************/
1041 BOOL samr_query_useraliases(struct cli_state *cli, 
1042                                 POLICY_HND *pol, DOM_SID *sid,
1043                                 uint32 *num_aliases, uint32 *rid)
1044 {
1045         prs_struct data;
1046         prs_struct rdata;
1047
1048         SAMR_Q_QUERY_USERALIASES q_o;
1049         BOOL valid_query = False;
1050
1051         DEBUG(4,("SAMR Query User Aliases.\n"));
1052
1053         if (pol == NULL || sid == NULL || rid == NULL || num_aliases == 0) return False;
1054
1055         /* create and send a MSRPC command with api SAMR_QUERY_USERALIASES */
1056
1057         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1058         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1059
1060         /* store the parameters */
1061         make_samr_q_query_useraliases(&q_o, pol, sid);
1062
1063         /* turn parameters into data stream */
1064         samr_io_q_query_useraliases("", &q_o,  &data, 0);
1065
1066         /* send the data on \PIPE\ */
1067         if (rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &data, &rdata))
1068         {
1069                 SAMR_R_QUERY_USERALIASES r_o;
1070                 BOOL p;
1071
1072                 /* get user info */
1073                 r_o.rid = rid;
1074
1075                 samr_io_r_query_useraliases("", &r_o, &rdata, 0);
1076                 p = rdata.offset != 0;
1077                 
1078                 if (p && r_o.status != 0)
1079                 {
1080                         /* report error code */
1081                         DEBUG(0,("SAMR_R_QUERY_USERALIASES: %s\n", get_nt_error_msg(r_o.status)));
1082                         p = False;
1083                 }
1084
1085                 if (p && r_o.ptr != 0)
1086                 {
1087                         valid_query = True;
1088                         *num_aliases = r_o.num_entries;
1089                 }
1090
1091         }
1092
1093         prs_mem_free(&data   );
1094         prs_mem_free(&rdata  );
1095
1096         return valid_query;
1097 }
1098
1099 /****************************************************************************
1100 do a SAMR Query User Groups
1101 ****************************************************************************/
1102 BOOL samr_query_usergroups(struct cli_state *cli, 
1103                                 POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid)
1104 {
1105         prs_struct data;
1106         prs_struct rdata;
1107
1108         SAMR_Q_QUERY_USERGROUPS q_o;
1109         BOOL valid_query = False;
1110
1111         DEBUG(4,("SAMR Query User Groups.\n"));
1112
1113         if (pol == NULL || gid == NULL || num_groups == 0) return False;
1114
1115         /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
1116
1117         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1118         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1119
1120         /* store the parameters */
1121         make_samr_q_query_usergroups(&q_o, pol);
1122
1123         /* turn parameters into data stream */
1124         samr_io_q_query_usergroups("", &q_o,  &data, 0);
1125
1126         /* send the data on \PIPE\ */
1127         if (rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &data, &rdata))
1128         {
1129                 SAMR_R_QUERY_USERGROUPS r_o;
1130                 BOOL p;
1131
1132                 /* get user info */
1133                 r_o.gid = gid;
1134
1135                 samr_io_r_query_usergroups("", &r_o, &rdata, 0);
1136                 p = rdata.offset != 0;
1137                 
1138                 if (p && r_o.status != 0)
1139                 {
1140                         /* report error code */
1141                         DEBUG(0,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
1142                         p = False;
1143                 }
1144
1145                 if (p && r_o.ptr_0 != 0)
1146                 {
1147                         valid_query = True;
1148                         *num_groups = r_o.num_entries;
1149                 }
1150
1151         }
1152
1153         prs_mem_free(&data   );
1154         prs_mem_free(&rdata  );
1155
1156         return valid_query;
1157 }
1158
1159 /****************************************************************************
1160 do a SAMR Query User Info
1161 ****************************************************************************/
1162 BOOL samr_query_userinfo(struct cli_state *cli, 
1163                                 POLICY_HND *pol, uint16 switch_value, void* usr)
1164 {
1165         prs_struct data;
1166         prs_struct rdata;
1167
1168         SAMR_Q_QUERY_USERINFO q_o;
1169         BOOL valid_query = False;
1170
1171         DEBUG(4,("SAMR Query User Info.  level: %d\n", switch_value));
1172
1173         if (pol == NULL || usr == NULL || switch_value == 0) return False;
1174
1175         /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
1176
1177         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1178         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1179
1180         /* store the parameters */
1181         make_samr_q_query_userinfo(&q_o, pol, switch_value);
1182
1183         /* turn parameters into data stream */
1184         samr_io_q_query_userinfo("", &q_o,  &data, 0);
1185
1186         /* send the data on \PIPE\ */
1187         if (rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &data, &rdata))
1188         {
1189                 SAMR_R_QUERY_USERINFO r_o;
1190                 BOOL p;
1191
1192                 /* get user info */
1193                 r_o.info.id = usr;
1194
1195                 samr_io_r_query_userinfo("", &r_o, &rdata, 0);
1196                 p = rdata.offset != 0;
1197                 
1198                 if (p && r_o.status != 0)
1199                 {
1200                         /* report error code */
1201                         DEBUG(0,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
1202                         p = False;
1203                 }
1204
1205                 if (p && r_o.switch_value != switch_value)
1206                 {
1207                         DEBUG(0,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
1208                                   r_o.switch_value));
1209                 }
1210
1211                 if (p && r_o.ptr != 0)
1212                 {
1213                         valid_query = True;
1214                 }
1215         }
1216
1217         prs_mem_free(&data   );
1218         prs_mem_free(&rdata  );
1219
1220         return valid_query;
1221 }
1222
1223 /****************************************************************************
1224 do a SAMR Close
1225 ****************************************************************************/
1226 BOOL samr_close(struct cli_state *cli, POLICY_HND *hnd)
1227 {
1228         prs_struct data;
1229         prs_struct rdata;
1230
1231         SAMR_Q_CLOSE_HND q_c;
1232         BOOL valid_close = False;
1233
1234         DEBUG(4,("SAMR Close\n"));
1235
1236         if (hnd == NULL) return False;
1237
1238         prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
1239         prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
1240
1241         /* create and send a MSRPC command with api SAMR_CLOSE_HND */
1242
1243         /* store the parameters */
1244         make_samr_q_close_hnd(&q_c, hnd);
1245
1246         /* turn parameters into data stream */
1247         samr_io_q_close_hnd("", &q_c,  &data, 0);
1248
1249         /* send the data on \PIPE\ */
1250         if (rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &data, &rdata))
1251         {
1252                 SAMR_R_CLOSE_HND r_c;
1253                 BOOL p;
1254
1255                 samr_io_r_close_hnd("", &r_c, &rdata, 0);
1256                 p = rdata.offset != 0;
1257
1258                 if (p && r_c.status != 0)
1259                 {
1260                         /* report error code */
1261                         DEBUG(0,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
1262                         p = False;
1263                 }
1264
1265                 if (p)
1266                 {
1267                         /* check that the returned policy handle is all zeros */
1268                         int i;
1269                         valid_close = True;
1270
1271                         for (i = 0; i < sizeof(r_c.pol.data); i++)
1272                         {
1273                                 if (r_c.pol.data[i] != 0)
1274                                 {
1275                                         valid_close = False;
1276                                         break;
1277                                 }
1278                         }       
1279                         if (!valid_close)
1280                         {
1281                                 DEBUG(0,("SAMR_CLOSE_HND: non-zero handle returned\n"));
1282                         }
1283                 }
1284         }
1285
1286         prs_mem_free(&data   );
1287         prs_mem_free(&rdata  );
1288
1289         return valid_close;
1290 }
1291