Use rpccli_samr_CreateDomainGroup() in net and rpcclient.
[ira/wip.git] / source3 / rpcclient / cmd_samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) Andrew Tridgell              1992-2000,
6    Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7    Copyright (C) Elrond                            2000,
8    Copyright (C) Tim Potter                        2000
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "rpcclient.h"
26
27 extern DOM_SID domain_sid;
28
29 /****************************************************************************
30  display sam_user_info_7 structure
31  ****************************************************************************/
32 static void display_sam_user_info_7(SAM_USER_INFO_7 *usr)
33 {
34         fstring temp;
35
36         unistr2_to_ascii(temp, &usr->uni_name, sizeof(temp));
37         printf("\tUser Name   :\t%s\n", temp);
38 }
39
40 /****************************************************************************
41  display sam_user_info_9 structure
42  ****************************************************************************/
43 static void display_sam_user_info_9(SAM_USER_INFO_9 *usr)
44 {
45         printf("\tPrimary group RID   :\tox%x\n", usr->rid_group);
46 }
47
48 /****************************************************************************
49  display sam_user_info_16 structure
50  ****************************************************************************/
51 static void display_sam_user_info_16(SAM_USER_INFO_16 *usr)
52 {
53         printf("\tAcct Flags   :\tox%x\n", usr->acb_info);
54 }
55
56 /****************************************************************************
57  display sam_user_info_21 structure
58  ****************************************************************************/
59 static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
60 {
61         fstring temp;
62
63         unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp));
64         printf("\tUser Name   :\t%s\n", temp);
65         
66         unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp));
67         printf("\tFull Name   :\t%s\n", temp);
68         
69         unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp));
70         printf("\tHome Drive  :\t%s\n", temp);
71         
72         unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp));
73         printf("\tDir Drive   :\t%s\n", temp);
74         
75         unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp));
76         printf("\tProfile Path:\t%s\n", temp);
77         
78         unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp));
79         printf("\tLogon Script:\t%s\n", temp);
80         
81         unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp));
82         printf("\tDescription :\t%s\n", temp);
83         
84         unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp));
85         printf("\tWorkstations:\t%s\n", temp);
86         
87         unistr2_to_ascii(temp, &usr->uni_comment, sizeof(temp));
88         printf("\tUnknown Str :\t%s\n", temp);
89         
90         unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp));
91         printf("\tRemote Dial :\t%s\n", temp);
92         
93         printf("\tLogon Time               :\t%s\n", 
94                http_timestring(nt_time_to_unix(usr->logon_time)));
95         printf("\tLogoff Time              :\t%s\n", 
96                http_timestring(nt_time_to_unix(usr->logoff_time)));
97         printf("\tKickoff Time             :\t%s\n", 
98                http_timestring(nt_time_to_unix(usr->kickoff_time)));
99         printf("\tPassword last set Time   :\t%s\n", 
100                http_timestring(nt_time_to_unix(usr->pass_last_set_time)));
101         printf("\tPassword can change Time :\t%s\n", 
102                http_timestring(nt_time_to_unix(usr->pass_can_change_time)));
103         printf("\tPassword must change Time:\t%s\n", 
104                http_timestring(nt_time_to_unix(usr->pass_must_change_time)));
105         
106         printf("\tunknown_2[0..31]...\n"); /* user passwords? */
107         
108         printf("\tuser_rid :\t0x%x\n"  , usr->user_rid ); /* User ID */
109         printf("\tgroup_rid:\t0x%x\n"  , usr->group_rid); /* Group ID */
110         printf("\tacb_info :\t0x%08x\n", usr->acb_info ); /* Account Control Info */
111         
112         printf("\tfields_present:\t0x%08x\n", usr->fields_present); /* 0x00ff ffff */
113         printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
114         printf("\tbad_password_count:\t0x%08x\n", usr->bad_password_count);
115         printf("\tlogon_count:\t0x%08x\n", usr->logon_count);
116         
117         printf("\tpadding1[0..7]...\n");
118         
119         if (usr->ptr_logon_hrs) {
120                 printf("\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len);
121         }
122 }
123
124
125 static void display_password_properties(uint32_t password_properties)
126 {
127         printf("password_properties: 0x%08x\n", password_properties);
128                 
129         if (password_properties & DOMAIN_PASSWORD_COMPLEX)
130                 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
131                         
132         if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
133                 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
134                         
135         if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
136                 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
137                         
138         if (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)
139                 printf("\tDOMAIN_PASSWORD_LOCKOUT_ADMINS\n");
140                         
141         if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
142                 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
143                         
144         if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
145                 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
146 }
147
148 static void display_sam_unk_info_1(SAM_UNK_INFO_1 *info1)
149 {
150         
151         printf("Minimum password length:\t\t\t%d\n", info1->min_length_password);
152         printf("Password uniqueness (remember x passwords):\t%d\n", info1->password_history);
153         display_password_properties(info1->password_properties);
154         printf("password expire in:\t\t\t\t%s\n", display_time(info1->expire));
155         printf("Min password age (allow changing in x days):\t%s\n", display_time(info1->min_passwordage));
156 }
157
158 static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
159 {
160         fstring name;
161
162         unistr2_to_ascii(name, &info2->uni_domain, sizeof(name));
163         printf("Domain:\t\t%s\n", name);
164
165         unistr2_to_ascii(name, &info2->uni_server, sizeof(name));
166         printf("Server:\t\t%s\n", name);
167
168         unistr2_to_ascii(name, &info2->uni_comment, sizeof(name));
169         printf("Comment:\t%s\n", name);
170
171         printf("Total Users:\t%d\n", info2->num_domain_usrs);
172         printf("Total Groups:\t%d\n", info2->num_domain_grps);
173         printf("Total Aliases:\t%d\n", info2->num_local_grps);
174         
175         printf("Sequence No:\t%llu\n", (unsigned long long)info2->seq_num);
176
177         printf("Force Logoff:\t%d\n", (int)nt_time_to_unix_abs(&info2->logout));
178
179         printf("Unknown 4:\t0x%x\n", info2->unknown_4);
180         printf("Server Role:\t%s\n", server_role_str(info2->server_role));
181         printf("Unknown 6:\t0x%x\n", info2->unknown_6);
182 }
183
184 static void display_sam_unk_info_3(SAM_UNK_INFO_3 *info3)
185 {
186         printf("Force Logoff:\t%d\n", (int)nt_time_to_unix_abs(&info3->logout));
187 }
188
189 static void display_sam_unk_info_4(SAM_UNK_INFO_4 *info4)
190 {
191         fstring name;
192
193         unistr2_to_ascii(name, &info4->uni_comment, sizeof(name));
194         printf("Comment:\t%s\n", name);
195 }
196
197 static void display_sam_unk_info_5(SAM_UNK_INFO_5 *info5)
198 {
199         fstring name;
200
201         unistr2_to_ascii(name, &info5->uni_domain, sizeof(name));
202         printf("Domain:\t\t%s\n", name);
203 }
204
205 static void display_sam_unk_info_6(SAM_UNK_INFO_6 *info6)
206 {
207         fstring name;
208
209         unistr2_to_ascii(name, &info6->uni_server, sizeof(name));
210         printf("Server:\t\t%s\n", name);
211 }
212
213 static void display_sam_unk_info_7(SAM_UNK_INFO_7 *info7)
214 {
215         printf("Server Role:\t%s\n", server_role_str(info7->server_role));
216 }
217
218 static void display_sam_unk_info_8(SAM_UNK_INFO_8 *info8)
219 {
220         printf("Sequence No:\t%llu\n", (unsigned long long)info8->seq_num);
221         printf("Domain Create Time:\t%s\n", 
222                 http_timestring(nt_time_to_unix(info8->domain_create_time)));
223 }
224
225 static void display_sam_unk_info_9(SAM_UNK_INFO_9 *info9)
226 {
227         printf("unknown:\t%d (0x%08x)\n", info9->unknown, info9->unknown);
228 }
229
230 static void display_sam_unk_info_12(SAM_UNK_INFO_12 *info12)
231 {
232         printf("Bad password lockout duration:               %s\n", display_time(info12->duration));
233         printf("Reset Lockout after:                         %s\n", display_time(info12->reset_count));
234         printf("Lockout after bad attempts:                  %d\n", info12->bad_attempt_lockout);
235 }
236
237 static void display_sam_unk_info_13(SAM_UNK_INFO_13 *info13)
238 {
239         printf("Sequence No:\t%llu\n", (unsigned long long)info13->seq_num);
240         printf("Domain Create Time:\t%s\n", 
241                 http_timestring(nt_time_to_unix(info13->domain_create_time)));
242         printf("Unknown1:\t%d\n", info13->unknown1);
243         printf("Unknown2:\t%d\n", info13->unknown2);
244
245 }
246
247 static void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
248 {
249         fstring tmp;
250
251         printf("index: 0x%x ", e1->user_idx);
252         printf("RID: 0x%x ", e1->rid_user);
253         printf("acb: 0x%x ", e1->acb_info);
254
255         unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp));
256         printf("Account: %s\t", tmp);
257
258         unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp));
259         printf("Name: %s\t", tmp);
260
261         unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp));
262         printf("Desc: %s\n", tmp);
263 }
264
265 static void display_sam_info_2(SAM_ENTRY2 *e2, SAM_STR2 *s2)
266 {
267         fstring tmp;
268
269         printf("index: 0x%x ", e2->user_idx);
270         printf("RID: 0x%x ", e2->rid_user);
271         printf("acb: 0x%x ", e2->acb_info);
272         
273         unistr2_to_ascii(tmp, &s2->uni_srv_name, sizeof(tmp));
274         printf("Account: %s\t", tmp);
275
276         unistr2_to_ascii(tmp, &s2->uni_srv_desc, sizeof(tmp));
277         printf("Name: %s\n", tmp);
278
279 }
280
281 static void display_sam_info_3(SAM_ENTRY3 *e3, SAM_STR3 *s3)
282 {
283         fstring tmp;
284
285         printf("index: 0x%x ", e3->grp_idx);
286         printf("RID: 0x%x ", e3->rid_grp);
287         printf("attr: 0x%x ", e3->attr);
288         
289         unistr2_to_ascii(tmp, &s3->uni_grp_name, sizeof(tmp));
290         printf("Account: %s\t", tmp);
291
292         unistr2_to_ascii(tmp, &s3->uni_grp_desc, sizeof(tmp));
293         printf("Name: %s\n", tmp);
294
295 }
296
297 static void display_sam_info_4(SAM_ENTRY4 *e4, SAM_STR4 *s4)
298 {
299         int i;
300
301         printf("index: %d ", e4->user_idx);
302         
303         printf("Account: ");
304         for (i=0; i<s4->acct_name.str_str_len; i++)
305                 printf("%c", s4->acct_name.buffer[i]);
306         printf("\n");
307
308 }
309
310 static void display_sam_info_5(SAM_ENTRY5 *e5, SAM_STR5 *s5)
311 {
312         int i;
313
314         printf("index: 0x%x ", e5->grp_idx);
315         
316         printf("Account: ");
317         for (i=0; i<s5->grp_name.str_str_len; i++)
318                 printf("%c", s5->grp_name.buffer[i]);
319         printf("\n");
320
321 }
322
323 /****************************************************************************
324  Try samr_connect4 first, then samr_conenct if it fails
325  ****************************************************************************/
326 static NTSTATUS try_samr_connects(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
327                                   uint32 access_mask, POLICY_HND *connect_pol)
328 {
329         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
330         
331         result = rpccli_samr_connect4(cli, mem_ctx, access_mask, connect_pol);
332         if (!NT_STATUS_IS_OK(result)) {
333                 result = rpccli_samr_connect(cli, mem_ctx, access_mask,
334                                           connect_pol);
335         }
336         return result;
337 }
338
339 /**********************************************************************
340  * Query user information 
341  */
342 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli, 
343                                     TALLOC_CTX *mem_ctx,
344                                     int argc, const char **argv) 
345 {
346         POLICY_HND connect_pol, domain_pol, user_pol;
347         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
348         uint32 info_level = 21;
349         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
350         SAM_USERINFO_CTR *user_ctr;
351         fstring server;
352         uint32 user_rid = 0;
353         
354         if ((argc < 2) || (argc > 4)) {
355                 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
356                 return NT_STATUS_OK;
357         }
358         
359         sscanf(argv[1], "%i", &user_rid);
360         
361         if (argc > 2)
362                 sscanf(argv[2], "%i", &info_level);
363                 
364         if (argc > 3)
365                 sscanf(argv[3], "%x", &access_mask);
366         
367
368         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
369         strupper_m(server);
370         
371         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
372                                    &connect_pol);
373
374         if (!NT_STATUS_IS_OK(result))
375                 goto done;
376
377         result = rpccli_samr_OpenDomain(cli, mem_ctx,
378                                         &connect_pol,
379                                         MAXIMUM_ALLOWED_ACCESS,
380                                         &domain_sid,
381                                         &domain_pol);
382         if (!NT_STATUS_IS_OK(result))
383                 goto done;
384
385         result = rpccli_samr_OpenUser(cli, mem_ctx,
386                                       &domain_pol,
387                                       access_mask,
388                                       user_rid,
389                                       &user_pol);
390
391         if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
392             (user_rid == 0)) {
393
394                 /* Probably this was a user name, try lookupnames */
395                 uint32 num_rids;
396                 uint32 *rids, *types;
397                 
398                 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
399                                                   1000, 1, &argv[1],
400                                                   &num_rids, &rids,
401                                                   &types);
402
403                 if (NT_STATUS_IS_OK(result)) {
404                         result = rpccli_samr_OpenUser(cli, mem_ctx,
405                                                       &domain_pol,
406                                                       access_mask,
407                                                       rids[0],
408                                                       &user_pol);
409                 }
410         }
411
412
413         if (!NT_STATUS_IS_OK(result))
414                 goto done;
415
416         ZERO_STRUCT(user_ctr);
417
418         result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol, 
419                                          info_level, &user_ctr);
420
421         if (!NT_STATUS_IS_OK(result))
422                 goto done;
423
424         switch (user_ctr->switch_value) {
425         case 7:
426                 display_sam_user_info_7(user_ctr->info.id7);
427                 break;
428         case 9:
429                 display_sam_user_info_9(user_ctr->info.id9);
430                 break;
431         case 16:
432                 display_sam_user_info_16(user_ctr->info.id16);
433                 break;
434         case 21:
435                 display_sam_user_info_21(user_ctr->info.id21);
436                 break;
437         default:
438                 printf("Unsupported infolevel: %d\n", info_level);
439                 break;
440         }
441
442         rpccli_samr_Close(cli, mem_ctx, &user_pol);
443         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
444         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
445
446 done:
447         return result;
448 }
449
450 /****************************************************************************
451  display group info
452  ****************************************************************************/
453 static void display_group_info1(GROUP_INFO1 *info1)
454 {
455         fstring temp;
456
457         unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp));
458         printf("\tGroup Name:\t%s\n", temp);
459         unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp));
460         printf("\tDescription:\t%s\n", temp);
461         printf("\tGroup Attribute:%d\n", info1->group_attr);
462         printf("\tNum Members:%d\n", info1->num_members);
463 }
464
465 /****************************************************************************
466  display group info
467  ****************************************************************************/
468 static void display_group_info2(GROUP_INFO2 *info2)
469 {
470         fstring name;
471
472         unistr2_to_ascii(name, &info2->uni_acct_name, sizeof(name));
473         printf("\tGroup Description:%s\n", name);
474 }
475
476
477 /****************************************************************************
478  display group info
479  ****************************************************************************/
480 static void display_group_info3(GROUP_INFO3 *info3)
481 {
482         printf("\tGroup Attribute:%d\n", info3->group_attr);
483 }
484
485
486 /****************************************************************************
487  display group info
488  ****************************************************************************/
489 static void display_group_info4(GROUP_INFO4 *info4)
490 {
491         fstring desc;
492
493         unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc));
494         printf("\tGroup Description:%s\n", desc);
495 }
496
497 /****************************************************************************
498  display group info
499  ****************************************************************************/
500 static void display_group_info5(GROUP_INFO5 *info5)
501 {
502         fstring temp;
503
504         unistr2_to_ascii(temp, &info5->uni_acct_name, sizeof(temp));
505         printf("\tGroup Name:\t%s\n", temp);
506         unistr2_to_ascii(temp, &info5->uni_acct_desc, sizeof(temp));
507         printf("\tDescription:\t%s\n", temp);
508         printf("\tGroup Attribute:%d\n", info5->group_attr);
509         printf("\tNum Members:%d\n", info5->num_members);
510 }
511
512 /****************************************************************************
513  display sam sync structure
514  ****************************************************************************/
515 static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
516 {
517         switch (ctr->switch_value1) {
518                 case 1:
519                         display_group_info1(&ctr->group.info1);
520                         break;
521                 case 2:
522                         display_group_info2(&ctr->group.info2);
523                         break;
524                 case 3:
525                         display_group_info3(&ctr->group.info3);
526                         break;
527                 case 4:
528                         display_group_info4(&ctr->group.info4);
529                         break;
530                 case 5:
531                         display_group_info5(&ctr->group.info5);
532                         break;
533
534         }
535 }
536
537 /***********************************************************************
538  * Query group information 
539  */
540 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli, 
541                                      TALLOC_CTX *mem_ctx,
542                                      int argc, const char **argv) 
543 {
544         POLICY_HND connect_pol, domain_pol, group_pol;
545         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
546         uint32 info_level = 1;
547         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
548         GROUP_INFO_CTR *group_ctr;
549         fstring                 server; 
550         uint32 group_rid;
551         
552         if ((argc < 2) || (argc > 4)) {
553                 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
554                 return NT_STATUS_OK;
555         }
556
557         sscanf(argv[1], "%i", &group_rid);
558         
559         if (argc > 2)
560                 sscanf(argv[2], "%i", &info_level);
561         
562         if (argc > 3)
563                 sscanf(argv[3], "%x", &access_mask);
564
565         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
566         strupper_m(server);
567
568         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
569                                    &connect_pol);
570
571         if (!NT_STATUS_IS_OK(result))
572                 goto done;
573
574         result = rpccli_samr_OpenDomain(cli, mem_ctx,
575                                         &connect_pol,
576                                         MAXIMUM_ALLOWED_ACCESS,
577                                         &domain_sid,
578                                         &domain_pol);
579
580         if (!NT_STATUS_IS_OK(result))
581                 goto done;
582
583         result = rpccli_samr_OpenGroup(cli, mem_ctx,
584                                        &domain_pol,
585                                        access_mask,
586                                        group_rid,
587                                        &group_pol);
588
589         if (!NT_STATUS_IS_OK(result))
590                 goto done;
591
592         result = rpccli_samr_query_groupinfo(cli, mem_ctx, &group_pol, 
593                                           info_level, &group_ctr);
594         if (!NT_STATUS_IS_OK(result)) {
595                 goto done;
596         }
597
598         display_group_info_ctr(group_ctr);
599
600         rpccli_samr_Close(cli, mem_ctx, &group_pol);
601         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
602         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
603 done:
604         return result;
605 }
606
607 /* Query groups a user is a member of */
608
609 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli, 
610                                           TALLOC_CTX *mem_ctx,
611                                           int argc, const char **argv) 
612 {
613         POLICY_HND              connect_pol, 
614                                 domain_pol, 
615                                 user_pol;
616         NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
617         uint32                  num_groups, 
618                                 user_rid;
619         uint32                  access_mask = MAXIMUM_ALLOWED_ACCESS;
620         DOM_GID                 *user_gids;
621         int                     i;
622         fstring                 server;
623         
624         if ((argc < 2) || (argc > 3)) {
625                 printf("Usage: %s rid [access mask]\n", argv[0]);
626                 return NT_STATUS_OK;
627         }
628
629         sscanf(argv[1], "%i", &user_rid);
630         
631         if (argc > 2)
632                 sscanf(argv[2], "%x", &access_mask);
633
634         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
635         strupper_m(server);
636                 
637         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
638                                    &connect_pol);
639
640         if (!NT_STATUS_IS_OK(result))
641                 goto done;
642
643         result = rpccli_samr_OpenDomain(cli, mem_ctx,
644                                         &connect_pol,
645                                         MAXIMUM_ALLOWED_ACCESS,
646                                         &domain_sid, &domain_pol);
647
648         if (!NT_STATUS_IS_OK(result))
649                 goto done;
650
651         result = rpccli_samr_OpenUser(cli, mem_ctx,
652                                       &domain_pol,
653                                       access_mask,
654                                       user_rid,
655                                       &user_pol);
656
657         if (!NT_STATUS_IS_OK(result))
658                 goto done;
659
660         result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
661                                            &num_groups, &user_gids);
662
663         if (!NT_STATUS_IS_OK(result))
664                 goto done;
665
666         for (i = 0; i < num_groups; i++) {
667                 printf("\tgroup rid:[0x%x] attr:[0x%x]\n", 
668                        user_gids[i].g_rid, user_gids[i].attr);
669         }
670
671         rpccli_samr_Close(cli, mem_ctx, &user_pol);
672         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
673         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
674  done:
675         return result;
676 }
677
678 /* Query aliases a user is a member of */
679
680 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli, 
681                                            TALLOC_CTX *mem_ctx,
682                                            int argc, const char **argv) 
683 {
684         POLICY_HND              connect_pol, domain_pol;
685         NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
686         DOM_SID                *sids;
687         size_t                     num_sids;
688         uint32                  num_aliases, *alias_rids;
689         uint32                  access_mask = MAXIMUM_ALLOWED_ACCESS;
690         int                     i;
691         fstring                 server;
692         DOM_SID2               *sid2;
693
694         if (argc < 3) {
695                 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
696                 return NT_STATUS_INVALID_PARAMETER;
697         }
698
699         sids = NULL;
700         num_sids = 0;
701
702         for (i=2; i<argc; i++) {
703                 DOM_SID tmp_sid;
704                 if (!string_to_sid(&tmp_sid, argv[i])) {
705                         printf("%s is not a legal SID\n", argv[i]);
706                         return NT_STATUS_INVALID_PARAMETER;
707                 }
708                 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
709                 if (!NT_STATUS_IS_OK(result)) {
710                         return result;
711                 }
712         }
713
714         if (num_sids) {
715                 sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
716                 if (sid2 == NULL)
717                         return NT_STATUS_NO_MEMORY;
718         } else {
719                 sid2 = NULL;
720         }
721
722         for (i=0; i<num_sids; i++) {
723                 sid_copy(&sid2[i].sid, &sids[i]);
724                 sid2[i].num_auths = sid2[i].sid.num_auths;
725         }
726
727         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
728         strupper_m(server);
729                 
730         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
731                                    &connect_pol);
732
733         if (!NT_STATUS_IS_OK(result))
734                 goto done;
735
736         if (StrCaseCmp(argv[1], "domain")==0)
737                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
738                                                 &connect_pol,
739                                                 access_mask,
740                                                 &domain_sid, &domain_pol);
741         else if (StrCaseCmp(argv[1], "builtin")==0)
742                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
743                                                 &connect_pol,
744                                                 access_mask,
745                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
746                                                 &domain_pol);
747         else {
748                 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
749                 return NT_STATUS_INVALID_PARAMETER;
750         }
751
752         if (!NT_STATUS_IS_OK(result))
753                 goto done;
754
755         result = rpccli_samr_query_useraliases(cli, mem_ctx, &domain_pol,
756                                             num_sids, sid2,
757                                             &num_aliases, &alias_rids);
758
759         if (!NT_STATUS_IS_OK(result))
760                 goto done;
761
762         for (i = 0; i < num_aliases; i++) {
763                 printf("\tgroup rid:[0x%x]\n", alias_rids[i]);
764         }
765
766         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
767         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
768  done:
769         return result;
770 }
771
772 /* Query members of a group */
773
774 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli, 
775                                         TALLOC_CTX *mem_ctx,
776                                         int argc, const char **argv) 
777 {
778         POLICY_HND connect_pol, domain_pol, group_pol;
779         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
780         uint32 num_members, *group_rids, *group_attrs, group_rid;
781         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
782         int i;
783         fstring                 server;
784         unsigned int old_timeout;
785         
786         if ((argc < 2) || (argc > 3)) {
787                 printf("Usage: %s rid [access mask]\n", argv[0]);
788                 return NT_STATUS_OK;
789         }
790
791         sscanf(argv[1], "%i", &group_rid);
792         
793         if (argc > 2)
794                 sscanf(argv[2], "%x", &access_mask);
795
796         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
797         strupper_m(server);
798
799         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
800                                    &connect_pol);
801
802         if (!NT_STATUS_IS_OK(result))
803                 goto done;
804
805         result = rpccli_samr_OpenDomain(cli, mem_ctx,
806                                         &connect_pol,
807                                         MAXIMUM_ALLOWED_ACCESS,
808                                         &domain_sid,
809                                         &domain_pol);
810
811         if (!NT_STATUS_IS_OK(result))
812                 goto done;
813
814         result = rpccli_samr_OpenGroup(cli, mem_ctx,
815                                        &domain_pol,
816                                        access_mask,
817                                        group_rid,
818                                        &group_pol);
819
820         if (!NT_STATUS_IS_OK(result))
821                 goto done;
822
823         /* Make sure to wait for our DC's reply */
824         old_timeout = cli_set_timeout(cli->cli, MAX(cli->cli->timeout,30000)); /* 30 seconds. */
825
826         result = rpccli_samr_query_groupmem(cli, mem_ctx, &group_pol,
827                                          &num_members, &group_rids,
828                                          &group_attrs);
829
830         cli_set_timeout(cli->cli, old_timeout);
831
832         if (!NT_STATUS_IS_OK(result))
833                 goto done;
834
835         for (i = 0; i < num_members; i++) {
836                 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
837                        group_attrs[i]);
838         }
839
840         rpccli_samr_Close(cli, mem_ctx, &group_pol);
841         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
842         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
843  done:
844         return result;
845 }
846
847 /* Enumerate domain users */
848
849 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, 
850                                         TALLOC_CTX *mem_ctx,
851                                         int argc, const char **argv) 
852 {
853         POLICY_HND connect_pol, domain_pol;
854         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
855         uint32 start_idx, size, num_dom_users, i;
856         char **dom_users;
857         uint32 *dom_rids;
858         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
859         uint32 acb_mask = ACB_NORMAL;
860         bool got_connect_pol = False, got_domain_pol = False;
861
862         if ((argc < 1) || (argc > 3)) {
863                 printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
864                 return NT_STATUS_OK;
865         }
866         
867         if (argc > 1)
868                 sscanf(argv[1], "%x", &access_mask);
869
870         if (argc > 2)
871                 sscanf(argv[2], "%x", &acb_mask);
872
873         /* Get sam policy handle */
874
875         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
876                                    &connect_pol);
877
878         if (!NT_STATUS_IS_OK(result))
879                 goto done;
880
881         got_connect_pol = True;
882
883         /* Get domain policy handle */
884
885         result = rpccli_samr_OpenDomain(cli, mem_ctx,
886                                         &connect_pol,
887                                         access_mask,
888                                         &domain_sid,
889                                         &domain_pol);
890
891         if (!NT_STATUS_IS_OK(result))
892                 goto done;
893
894         got_domain_pol = True;
895
896         /* Enumerate domain users */
897
898         start_idx = 0;
899         size = 0xffff;
900
901         do {
902                 result = rpccli_samr_enum_dom_users(
903                         cli, mem_ctx, &domain_pol, &start_idx, acb_mask,
904                         size, &dom_users, &dom_rids, &num_dom_users);
905
906                 if (NT_STATUS_IS_OK(result) ||
907                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
908
909                         for (i = 0; i < num_dom_users; i++)
910                                printf("user:[%s] rid:[0x%x]\n", 
911                                        dom_users[i], dom_rids[i]);
912                 }
913
914         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
915
916  done:
917         if (got_domain_pol)
918                 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
919
920         if (got_connect_pol)
921                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
922
923         return result;
924 }
925
926 /* Enumerate domain groups */
927
928 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, 
929                                          TALLOC_CTX *mem_ctx,
930                                          int argc, const char **argv) 
931 {
932         POLICY_HND connect_pol, domain_pol;
933         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
934         uint32 start_idx, size, num_dom_groups, i;
935         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
936         struct acct_info *dom_groups;
937         bool got_connect_pol = False, got_domain_pol = False;
938
939         if ((argc < 1) || (argc > 2)) {
940                 printf("Usage: %s [access_mask]\n", argv[0]);
941                 return NT_STATUS_OK;
942         }
943         
944         if (argc > 1)
945                 sscanf(argv[1], "%x", &access_mask);
946
947         /* Get sam policy handle */
948
949         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
950                                    &connect_pol);
951
952         if (!NT_STATUS_IS_OK(result))
953                 goto done;
954
955         got_connect_pol = True;
956
957         /* Get domain policy handle */
958
959         result = rpccli_samr_OpenDomain(cli, mem_ctx,
960                                         &connect_pol,
961                                         access_mask,
962                                         &domain_sid,
963                                         &domain_pol);
964
965         if (!NT_STATUS_IS_OK(result))
966                 goto done;
967
968         got_domain_pol = True;
969
970         /* Enumerate domain groups */
971
972         start_idx = 0;
973         size = 0xffff;
974
975         do {
976                 result = rpccli_samr_enum_dom_groups(
977                         cli, mem_ctx, &domain_pol, &start_idx, size,
978                         &dom_groups, &num_dom_groups);
979
980                 if (NT_STATUS_IS_OK(result) ||
981                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
982
983                         for (i = 0; i < num_dom_groups; i++)
984                                 printf("group:[%s] rid:[0x%x]\n", 
985                                        dom_groups[i].acct_name,
986                                        dom_groups[i].rid);
987                 }
988
989         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
990
991  done:
992         if (got_domain_pol)
993                 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
994
995         if (got_connect_pol)
996                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
997
998         return result;
999 }
1000
1001 /* Enumerate alias groups */
1002
1003 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, 
1004                                          TALLOC_CTX *mem_ctx,
1005                                          int argc, const char **argv) 
1006 {
1007         POLICY_HND connect_pol, domain_pol;
1008         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1009         uint32 start_idx, size, num_als_groups, i;
1010         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1011         struct acct_info *als_groups;
1012         bool got_connect_pol = False, got_domain_pol = False;
1013
1014         if ((argc < 2) || (argc > 3)) {
1015                 printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
1016                 return NT_STATUS_OK;
1017         }
1018         
1019         if (argc > 2)
1020                 sscanf(argv[2], "%x", &access_mask);
1021
1022         /* Get sam policy handle */
1023
1024         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1025                                    &connect_pol);
1026
1027         if (!NT_STATUS_IS_OK(result))
1028                 goto done;
1029
1030         got_connect_pol = True;
1031
1032         /* Get domain policy handle */
1033
1034         if (StrCaseCmp(argv[1], "domain")==0)
1035                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1036                                                 &connect_pol,
1037                                                 access_mask,
1038                                                 &domain_sid,
1039                                                 &domain_pol);
1040         else if (StrCaseCmp(argv[1], "builtin")==0)
1041                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1042                                                 &connect_pol,
1043                                                 access_mask,
1044                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1045                                                 &domain_pol);
1046         else
1047                 return NT_STATUS_OK;
1048
1049         if (!NT_STATUS_IS_OK(result))
1050                 goto done;
1051
1052         got_domain_pol = True;
1053
1054         /* Enumerate alias groups */
1055
1056         start_idx = 0;
1057         size = 0xffff;          /* Number of groups to retrieve */
1058
1059         do {
1060                 result = rpccli_samr_enum_als_groups(
1061                         cli, mem_ctx, &domain_pol, &start_idx, size,
1062                         &als_groups, &num_als_groups);
1063
1064                 if (NT_STATUS_IS_OK(result) ||
1065                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1066
1067                         for (i = 0; i < num_als_groups; i++)
1068                                 printf("group:[%s] rid:[0x%x]\n", 
1069                                        als_groups[i].acct_name,
1070                                        als_groups[i].rid);
1071                 }
1072         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1073
1074  done:
1075         if (got_domain_pol)
1076                 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1077         
1078         if (got_connect_pol)
1079                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1080         
1081         return result;
1082 }
1083
1084 /* Query alias membership */
1085
1086 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli, 
1087                                         TALLOC_CTX *mem_ctx,
1088                                         int argc, const char **argv) 
1089 {
1090         POLICY_HND connect_pol, domain_pol, alias_pol;
1091         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1092         uint32 alias_rid, num_members, i;
1093         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1094         DOM_SID *alias_sids;
1095
1096         if ((argc < 3) || (argc > 4)) {
1097                 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1098                 return NT_STATUS_OK;
1099         }
1100
1101         sscanf(argv[2], "%i", &alias_rid);
1102         
1103         if (argc > 3)
1104                 sscanf(argv[3], "%x", &access_mask);
1105
1106         /* Open SAMR handle */
1107
1108         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1109                                    &connect_pol);
1110
1111         if (!NT_STATUS_IS_OK(result))
1112                 goto done;
1113
1114         /* Open handle on domain */
1115         
1116         if (StrCaseCmp(argv[1], "domain")==0)
1117                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1118                                                 &connect_pol,
1119                                                 MAXIMUM_ALLOWED_ACCESS,
1120                                                 &domain_sid,
1121                                                 &domain_pol);
1122         else if (StrCaseCmp(argv[1], "builtin")==0)
1123                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1124                                                 &connect_pol,
1125                                                 MAXIMUM_ALLOWED_ACCESS,
1126                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1127                                                 &domain_pol);
1128         else
1129                 return NT_STATUS_OK;
1130
1131         if (!NT_STATUS_IS_OK(result))
1132                 goto done;
1133
1134         /* Open handle on alias */
1135
1136         result = rpccli_samr_OpenAlias(cli, mem_ctx,
1137                                        &domain_pol,
1138                                        access_mask,
1139                                        alias_rid,
1140                                        &alias_pol);
1141         if (!NT_STATUS_IS_OK(result))
1142                 goto done;
1143
1144         result = rpccli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
1145                                          &num_members, &alias_sids);
1146
1147         if (!NT_STATUS_IS_OK(result))
1148                 goto done;
1149
1150         for (i = 0; i < num_members; i++) {
1151                 fstring sid_str;
1152
1153                 sid_to_fstring(sid_str, &alias_sids[i]);
1154                 printf("\tsid:[%s]\n", sid_str);
1155         }
1156
1157         rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1158         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1159         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1160  done:
1161         return result;
1162 }
1163
1164 /* Query delete an alias membership */
1165
1166 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli, 
1167                                       TALLOC_CTX *mem_ctx,
1168                                       int argc, const char **argv) 
1169 {
1170         POLICY_HND connect_pol, domain_pol, alias_pol;
1171         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1172         uint32 alias_rid;
1173         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1174
1175         if (argc != 3) {
1176                 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1177                 return NT_STATUS_OK;
1178         }
1179
1180         alias_rid = strtoul(argv[2], NULL, 10);
1181         
1182         /* Open SAMR handle */
1183
1184         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1185                                    &connect_pol);
1186
1187         if (!NT_STATUS_IS_OK(result))
1188                 goto done;
1189
1190         /* Open handle on domain */
1191         
1192         if (StrCaseCmp(argv[1], "domain")==0)
1193                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1194                                                 &connect_pol,
1195                                                 MAXIMUM_ALLOWED_ACCESS,
1196                                                 &domain_sid,
1197                                                 &domain_pol);
1198         else if (StrCaseCmp(argv[1], "builtin")==0)
1199                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1200                                                 &connect_pol,
1201                                                 MAXIMUM_ALLOWED_ACCESS,
1202                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1203                                                 &domain_pol);
1204         else
1205                 return NT_STATUS_INVALID_PARAMETER;
1206
1207         if (!NT_STATUS_IS_OK(result))
1208                 goto done;
1209
1210         /* Open handle on alias */
1211
1212         result = rpccli_samr_OpenAlias(cli, mem_ctx,
1213                                        &domain_pol,
1214                                        access_mask,
1215                                        alias_rid,
1216                                        &alias_pol);
1217         if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1218                 /* Probably this was a user name, try lookupnames */
1219                 uint32 num_rids;
1220                 uint32 *rids, *types;
1221                 
1222                 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1223                                                   1000, 1, &argv[2],
1224                                                   &num_rids, &rids,
1225                                                   &types);
1226
1227                 if (NT_STATUS_IS_OK(result)) {
1228                         result = rpccli_samr_OpenAlias(cli, mem_ctx,
1229                                                        &domain_pol,
1230                                                        access_mask,
1231                                                        rids[0],
1232                                                        &alias_pol);
1233                 }
1234         }
1235
1236         result = rpccli_samr_DeleteDomAlias(cli, mem_ctx,
1237                                             &alias_pol);
1238
1239         if (!NT_STATUS_IS_OK(result))
1240                 goto done;
1241
1242         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1243         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1244  done:
1245         return result;
1246 }
1247
1248 /* Query display info */
1249
1250 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli, 
1251                                         TALLOC_CTX *mem_ctx,
1252                                         int argc, const char **argv) 
1253 {
1254         POLICY_HND connect_pol, domain_pol;
1255         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1256         uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries, i;
1257         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1258         uint32 info_level = 1;
1259         SAM_DISPINFO_CTR ctr;
1260         SAM_DISPINFO_1 info1;
1261         SAM_DISPINFO_2 info2;
1262         SAM_DISPINFO_3 info3;
1263         SAM_DISPINFO_4 info4;
1264         SAM_DISPINFO_5 info5;
1265         int loop_count = 0;
1266         bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1267
1268         if (argc > 6) {
1269                 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1270                 return NT_STATUS_OK;
1271         }
1272
1273         if (argc >= 2)
1274                 sscanf(argv[1], "%i", &info_level);
1275         
1276         if (argc >= 3)
1277                 sscanf(argv[2], "%i", &start_idx);
1278         
1279         if (argc >= 4) {
1280                 sscanf(argv[3], "%i", &max_entries);
1281                 got_params = True;
1282         }
1283         
1284         if (argc >= 5) {
1285                 sscanf(argv[4], "%i", &max_size);
1286                 got_params = True;
1287         }
1288         
1289         if (argc >= 6)
1290                 sscanf(argv[5], "%x", &access_mask);
1291
1292         /* Get sam policy handle */
1293
1294         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1295                                    &connect_pol);
1296
1297         if (!NT_STATUS_IS_OK(result))
1298                 goto done;
1299
1300         /* Get domain policy handle */
1301
1302         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1303                                         &connect_pol,
1304                                         access_mask,
1305                                         &domain_sid,
1306                                         &domain_pol);
1307
1308         if (!NT_STATUS_IS_OK(result))
1309                 goto done;
1310
1311         /* Query display info */
1312
1313         ZERO_STRUCT(ctr);
1314         ZERO_STRUCT(info1);
1315         
1316         switch (info_level) {
1317         case 1:
1318                 ZERO_STRUCT(info1);
1319                 ctr.sam.info1 = &info1;
1320                 break;
1321         case 2:
1322                 ZERO_STRUCT(info2);
1323                 ctr.sam.info2 = &info2;
1324                 break;
1325         case 3:
1326                 ZERO_STRUCT(info3);
1327                 ctr.sam.info3 = &info3;
1328                 break;
1329         case 4:
1330                 ZERO_STRUCT(info4);
1331                 ctr.sam.info4 = &info4;
1332                 break;
1333         case 5:
1334                 ZERO_STRUCT(info5);
1335                 ctr.sam.info5 = &info5;
1336                 break;
1337         }
1338
1339
1340         do {
1341
1342                 if (!got_params)
1343                         get_query_dispinfo_params(
1344                                 loop_count, &max_entries, &max_size);
1345                 
1346                 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
1347                                                  &start_idx, info_level,
1348                                                  &num_entries, max_entries, 
1349                                                  max_size, &ctr);
1350
1351                 loop_count++;
1352
1353                 if (NT_STATUS_IS_ERR(result))
1354                         break;
1355
1356                 if (num_entries == 0) 
1357                         break;
1358
1359                 for (i = 0; i < num_entries; i++) {
1360                         switch (info_level) {
1361                         case 1:
1362                                 display_sam_info_1(&ctr.sam.info1->sam[i], &ctr.sam.info1->str[i]);
1363                                 break;
1364                         case 2:
1365                                 display_sam_info_2(&ctr.sam.info2->sam[i], &ctr.sam.info2->str[i]);
1366                                 break;
1367                         case 3:
1368                                 display_sam_info_3(&ctr.sam.info3->sam[i], &ctr.sam.info3->str[i]);
1369                                 break;
1370                         case 4:
1371                                 display_sam_info_4(&ctr.sam.info4->sam[i], &ctr.sam.info4->str[i]);
1372                                 break;
1373                         case 5:
1374                                 display_sam_info_5(&ctr.sam.info5->sam[i], &ctr.sam.info5->str[i]);
1375                                 break;
1376                         }
1377                 }
1378         } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1379
1380         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1381         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1382  done:
1383         return result;
1384 }
1385
1386 /* Query domain info */
1387
1388 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli, 
1389                                        TALLOC_CTX *mem_ctx,
1390                                        int argc, const char **argv) 
1391 {
1392         POLICY_HND connect_pol, domain_pol;
1393         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1394         uint32 switch_level = 2;
1395         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1396         SAM_UNK_CTR ctr;
1397
1398         if (argc > 3) {
1399                 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1400                 return NT_STATUS_OK;
1401         }
1402
1403         if (argc > 1)
1404                 sscanf(argv[1], "%i", &switch_level);
1405         
1406         if (argc > 2)
1407                 sscanf(argv[2], "%x", &access_mask);
1408
1409         /* Get sam policy handle */
1410
1411         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1412                                    &connect_pol);
1413
1414         if (!NT_STATUS_IS_OK(result))
1415                 goto done;
1416
1417         /* Get domain policy handle */
1418
1419         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1420                                         &connect_pol,
1421                                         access_mask,
1422                                         &domain_sid,
1423                                         &domain_pol);
1424
1425         if (!NT_STATUS_IS_OK(result))
1426                 goto done;
1427
1428         /* Query domain info */
1429
1430         result = rpccli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
1431                                          switch_level, &ctr);
1432
1433         if (!NT_STATUS_IS_OK(result))
1434                 goto done;
1435
1436         /* Display domain info */
1437
1438         switch (switch_level) {
1439         case 1:
1440                 display_sam_unk_info_1(&ctr.info.inf1);
1441                 break;
1442         case 2:
1443                 display_sam_unk_info_2(&ctr.info.inf2);
1444                 break;
1445         case 3:
1446                 display_sam_unk_info_3(&ctr.info.inf3);
1447                 break;
1448         case 4:
1449                 display_sam_unk_info_4(&ctr.info.inf4);
1450                 break;
1451         case 5:
1452                 display_sam_unk_info_5(&ctr.info.inf5);
1453                 break;
1454         case 6:
1455                 display_sam_unk_info_6(&ctr.info.inf6);
1456                 break;
1457         case 7:
1458                 display_sam_unk_info_7(&ctr.info.inf7);
1459                 break;
1460         case 8:
1461                 display_sam_unk_info_8(&ctr.info.inf8);
1462                 break;
1463         case 9:
1464                 display_sam_unk_info_9(&ctr.info.inf9);
1465                 break;
1466         case 12:
1467                 display_sam_unk_info_12(&ctr.info.inf12);
1468                 break;
1469         case 13:
1470                 display_sam_unk_info_13(&ctr.info.inf13);
1471                 break;
1472
1473         default:
1474                 printf("cannot display domain info for switch value %d\n",
1475                        switch_level);
1476                 break;
1477         }
1478
1479  done:
1480
1481         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1482         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1483         return result;
1484 }
1485
1486 /* Create domain user */
1487
1488 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli, 
1489                                          TALLOC_CTX *mem_ctx,
1490                                          int argc, const char **argv) 
1491 {
1492         POLICY_HND connect_pol, domain_pol, user_pol;
1493         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1494         const char *acct_name;
1495         uint32 acb_info;
1496         uint32 acct_flags, user_rid;
1497         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1498
1499         if ((argc < 2) || (argc > 3)) {
1500                 printf("Usage: %s username [access mask]\n", argv[0]);
1501                 return NT_STATUS_OK;
1502         }
1503
1504         acct_name = argv[1];
1505
1506         if (argc > 2)
1507                 sscanf(argv[2], "%x", &access_mask);
1508
1509         /* Get sam policy handle */
1510
1511         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1512                                    &connect_pol);
1513
1514         if (!NT_STATUS_IS_OK(result))
1515                 goto done;
1516
1517         /* Get domain policy handle */
1518
1519         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1520                                         &connect_pol,
1521                                         access_mask,
1522                                         &domain_sid,
1523                                         &domain_pol);
1524
1525         if (!NT_STATUS_IS_OK(result))
1526                 goto done;
1527
1528         /* Create domain user */
1529
1530         acb_info = ACB_NORMAL;
1531         acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1532                      SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1533                      SAMR_USER_ACCESS_SET_PASSWORD |
1534                      SAMR_USER_ACCESS_GET_ATTRIBUTES |
1535                      SAMR_USER_ACCESS_SET_ATTRIBUTES;
1536
1537         result = rpccli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1538                                           acct_name, acb_info, acct_flags,
1539                                           &user_pol, &user_rid);
1540
1541         if (!NT_STATUS_IS_OK(result))
1542                 goto done;
1543
1544         result = rpccli_samr_Close(cli, mem_ctx, &user_pol);
1545         if (!NT_STATUS_IS_OK(result)) goto done;
1546
1547         result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1548         if (!NT_STATUS_IS_OK(result)) goto done;
1549
1550         result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1551         if (!NT_STATUS_IS_OK(result)) goto done;
1552
1553  done:
1554         return result;
1555 }
1556
1557 static void init_lsa_String(struct lsa_String *name, const char *s)
1558 {
1559         name->string = s;
1560 }
1561
1562 /* Create domain group */
1563
1564 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli, 
1565                                           TALLOC_CTX *mem_ctx,
1566                                           int argc, const char **argv) 
1567 {
1568         POLICY_HND connect_pol, domain_pol, group_pol;
1569         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1570         struct lsa_String grp_name;
1571         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1572         uint32_t rid = 0;
1573
1574         if ((argc < 2) || (argc > 3)) {
1575                 printf("Usage: %s groupname [access mask]\n", argv[0]);
1576                 return NT_STATUS_OK;
1577         }
1578
1579         init_lsa_String(&grp_name, argv[1]);
1580
1581         if (argc > 2)
1582                 sscanf(argv[2], "%x", &access_mask);
1583
1584         /* Get sam policy handle */
1585
1586         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1587                                    &connect_pol);
1588
1589         if (!NT_STATUS_IS_OK(result))
1590                 goto done;
1591
1592         /* Get domain policy handle */
1593
1594         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1595                                         &connect_pol,
1596                                         access_mask,
1597                                         &domain_sid,
1598                                         &domain_pol);
1599
1600         if (!NT_STATUS_IS_OK(result))
1601                 goto done;
1602
1603         /* Create domain user */
1604         result = rpccli_samr_CreateDomainGroup(cli, mem_ctx,
1605                                                &domain_pol,
1606                                                &grp_name,
1607                                                MAXIMUM_ALLOWED_ACCESS,
1608                                                &group_pol,
1609                                                &rid);
1610
1611         if (!NT_STATUS_IS_OK(result))
1612                 goto done;
1613
1614         result = rpccli_samr_Close(cli, mem_ctx, &group_pol);
1615         if (!NT_STATUS_IS_OK(result)) goto done;
1616
1617         result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1618         if (!NT_STATUS_IS_OK(result)) goto done;
1619
1620         result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1621         if (!NT_STATUS_IS_OK(result)) goto done;
1622
1623  done:
1624         return result;
1625 }
1626
1627 /* Create domain alias */
1628
1629 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli, 
1630                                           TALLOC_CTX *mem_ctx,
1631                                           int argc, const char **argv) 
1632 {
1633         POLICY_HND connect_pol, domain_pol, alias_pol;
1634         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1635         struct lsa_String alias_name;
1636         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1637         uint32_t rid = 0;
1638
1639         if ((argc < 2) || (argc > 3)) {
1640                 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1641                 return NT_STATUS_OK;
1642         }
1643
1644         init_lsa_String(&alias_name, argv[1]);
1645
1646         if (argc > 2)
1647                 sscanf(argv[2], "%x", &access_mask);
1648
1649         /* Get sam policy handle */
1650
1651         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1652                                    &connect_pol);
1653
1654         if (!NT_STATUS_IS_OK(result))
1655                 goto done;
1656
1657         /* Get domain policy handle */
1658
1659         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1660                                         &connect_pol,
1661                                         access_mask,
1662                                         &domain_sid,
1663                                         &domain_pol);
1664
1665         if (!NT_STATUS_IS_OK(result))
1666                 goto done;
1667
1668         /* Create domain user */
1669
1670         result = rpccli_samr_CreateDomAlias(cli, mem_ctx,
1671                                             &domain_pol,
1672                                             &alias_name,
1673                                             MAXIMUM_ALLOWED_ACCESS,
1674                                             &alias_pol,
1675                                             &rid);
1676
1677         if (!NT_STATUS_IS_OK(result))
1678                 goto done;
1679
1680         result = rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1681         if (!NT_STATUS_IS_OK(result)) goto done;
1682
1683         result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1684         if (!NT_STATUS_IS_OK(result)) goto done;
1685
1686         result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1687         if (!NT_STATUS_IS_OK(result)) goto done;
1688
1689  done:
1690         return result;
1691 }
1692
1693 /* Lookup sam names */
1694
1695 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli, 
1696                                       TALLOC_CTX *mem_ctx,
1697                                       int argc, const char **argv) 
1698 {
1699         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1700         POLICY_HND connect_pol, domain_pol;
1701         uint32 flags = 0x000003e8; /* Unknown */
1702         uint32 num_rids, num_names, *name_types, *rids;
1703         const char **names;
1704         int i;
1705
1706         if (argc < 3) {
1707                 printf("Usage: %s  domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1708                 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1709                 printf("or check on the builtin SID: S-1-5-32\n");
1710                 return NT_STATUS_OK;
1711         }
1712
1713         /* Get sam policy and domain handles */
1714
1715         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1716                                    &connect_pol);
1717
1718         if (!NT_STATUS_IS_OK(result))
1719                 goto done;
1720
1721         if (StrCaseCmp(argv[1], "domain")==0)
1722                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1723                                                 &connect_pol,
1724                                                 MAXIMUM_ALLOWED_ACCESS,
1725                                                 &domain_sid,
1726                                                 &domain_pol);
1727         else if (StrCaseCmp(argv[1], "builtin")==0)
1728                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1729                                                 &connect_pol,
1730                                                 MAXIMUM_ALLOWED_ACCESS,
1731                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1732                                                 &domain_pol);
1733         else
1734                 return NT_STATUS_OK;
1735
1736         if (!NT_STATUS_IS_OK(result))
1737                 goto done;
1738
1739         /* Look up names */
1740
1741         num_names = argc - 2;
1742
1743         if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) {
1744                 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1745                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1746                 result = NT_STATUS_NO_MEMORY;
1747                 goto done;
1748         }
1749
1750         for (i = 0; i < num_names; i++)
1751                 names[i] = argv[i + 2];
1752
1753         result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1754                                        flags, num_names, names,
1755                                        &num_rids, &rids, &name_types);
1756
1757         if (!NT_STATUS_IS_OK(result))
1758                 goto done;
1759
1760         /* Display results */
1761
1762         for (i = 0; i < num_names; i++)
1763                 printf("name %s: 0x%x (%d)\n", names[i], rids[i], 
1764                        name_types[i]);
1765
1766         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1767         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1768  done:
1769         return result;
1770 }
1771
1772 /* Lookup sam rids */
1773
1774 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli, 
1775                                      TALLOC_CTX *mem_ctx,
1776                                      int argc, const char **argv) 
1777 {
1778         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1779         POLICY_HND connect_pol, domain_pol;
1780         uint32 num_rids, num_names, *rids, *name_types;
1781         char **names;
1782         int i;
1783
1784         if (argc < 3) {
1785                 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1786                 return NT_STATUS_OK;
1787         }
1788
1789         /* Get sam policy and domain handles */
1790
1791         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1792                                    &connect_pol);
1793
1794         if (!NT_STATUS_IS_OK(result))
1795                 goto done;
1796
1797         if (StrCaseCmp(argv[1], "domain")==0)
1798                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1799                                                 &connect_pol,
1800                                                 MAXIMUM_ALLOWED_ACCESS,
1801                                                 &domain_sid,
1802                                                 &domain_pol);
1803         else if (StrCaseCmp(argv[1], "builtin")==0)
1804                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1805                                                 &connect_pol,
1806                                                 MAXIMUM_ALLOWED_ACCESS,
1807                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1808                                                 &domain_pol);
1809         else
1810                 return NT_STATUS_OK;
1811
1812         if (!NT_STATUS_IS_OK(result))
1813                 goto done;
1814
1815         /* Look up rids */
1816
1817         num_rids = argc - 2;
1818
1819         if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1820                 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1821                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1822                 result = NT_STATUS_NO_MEMORY;
1823                 goto done;
1824         }
1825
1826         for (i = 0; i < argc - 2; i++)
1827                 sscanf(argv[i + 2], "%i", &rids[i]);
1828
1829         result = rpccli_samr_lookup_rids(cli, mem_ctx, &domain_pol, num_rids, rids,
1830                                       &num_names, &names, &name_types);
1831
1832         if (!NT_STATUS_IS_OK(result) &&
1833             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1834                 goto done;
1835
1836         /* Display results */
1837
1838         for (i = 0; i < num_names; i++)
1839                 printf("rid 0x%x: %s (%d)\n", rids[i], names[i], name_types[i]);
1840
1841         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1842         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1843  done:
1844         return result;
1845 }
1846
1847 /* Delete domain group */
1848
1849 static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli, 
1850                                          TALLOC_CTX *mem_ctx,
1851                                          int argc, const char **argv) 
1852 {
1853         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1854         POLICY_HND connect_pol, domain_pol, group_pol;
1855         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1856
1857         if ((argc < 2) || (argc > 3)) {
1858                 printf("Usage: %s groupname\n", argv[0]);
1859                 return NT_STATUS_OK;
1860         }
1861         
1862         if (argc > 2)
1863                 sscanf(argv[2], "%x", &access_mask);
1864
1865         /* Get sam policy and domain handles */
1866
1867         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1868                                    &connect_pol);
1869
1870         if (!NT_STATUS_IS_OK(result))
1871                 goto done;
1872
1873         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1874                                         &connect_pol,
1875                                         MAXIMUM_ALLOWED_ACCESS,
1876                                         &domain_sid,
1877                                         &domain_pol);
1878
1879         if (!NT_STATUS_IS_OK(result))
1880                 goto done;
1881
1882         /* Get handle on group */
1883
1884         {
1885                 uint32 *group_rids, num_rids, *name_types;
1886                 uint32 flags = 0x000003e8; /* Unknown */
1887
1888                 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1889                                                flags, 1, (const char **)&argv[1],
1890                                                &num_rids, &group_rids,
1891                                                &name_types);
1892
1893                 if (!NT_STATUS_IS_OK(result))
1894                         goto done;
1895
1896                 result = rpccli_samr_OpenGroup(cli, mem_ctx,
1897                                                &domain_pol,
1898                                                access_mask,
1899                                                group_rids[0],
1900                                                &group_pol);
1901
1902                 if (!NT_STATUS_IS_OK(result))
1903                         goto done;
1904         }
1905
1906         /* Delete group */
1907
1908         result = rpccli_samr_DeleteDomainGroup(cli, mem_ctx,
1909                                                &group_pol);
1910
1911         if (!NT_STATUS_IS_OK(result))
1912                 goto done;
1913
1914         /* Display results */
1915
1916         rpccli_samr_Close(cli, mem_ctx, &group_pol);
1917         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1918         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1919
1920  done:
1921         return result;
1922 }
1923
1924 /* Delete domain user */
1925
1926 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli, 
1927                                          TALLOC_CTX *mem_ctx,
1928                                          int argc, const char **argv) 
1929 {
1930         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1931         POLICY_HND connect_pol, domain_pol, user_pol;
1932         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1933
1934         if ((argc < 2) || (argc > 3)) {
1935                 printf("Usage: %s username\n", argv[0]);
1936                 return NT_STATUS_OK;
1937         }
1938         
1939         if (argc > 2)
1940                 sscanf(argv[2], "%x", &access_mask);
1941
1942         /* Get sam policy and domain handles */
1943
1944         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1945                                    &connect_pol);
1946
1947         if (!NT_STATUS_IS_OK(result))
1948                 goto done;
1949
1950         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1951                                         &connect_pol,
1952                                         MAXIMUM_ALLOWED_ACCESS,
1953                                         &domain_sid,
1954                                         &domain_pol);
1955
1956         if (!NT_STATUS_IS_OK(result))
1957                 goto done;
1958
1959         /* Get handle on user */
1960
1961         {
1962                 uint32 *user_rids, num_rids, *name_types;
1963                 uint32 flags = 0x000003e8; /* Unknown */
1964
1965                 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1966                                                flags, 1, (const char **)&argv[1],
1967                                                &num_rids, &user_rids,
1968                                                &name_types);
1969
1970                 if (!NT_STATUS_IS_OK(result))
1971                         goto done;
1972
1973                 result = rpccli_samr_OpenUser(cli, mem_ctx,
1974                                               &domain_pol,
1975                                               access_mask,
1976                                               user_rids[0],
1977                                               &user_pol);
1978
1979                 if (!NT_STATUS_IS_OK(result))
1980                         goto done;
1981         }
1982
1983         /* Delete user */
1984
1985         result = rpccli_samr_DeleteUser(cli, mem_ctx,
1986                                         &user_pol);
1987
1988         if (!NT_STATUS_IS_OK(result))
1989                 goto done;
1990
1991         /* Display results */
1992
1993         rpccli_samr_Close(cli, mem_ctx, &user_pol);
1994         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1995         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1996
1997  done:
1998         return result;
1999 }
2000
2001 /**********************************************************************
2002  * Query user security object 
2003  */
2004 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli, 
2005                                     TALLOC_CTX *mem_ctx,
2006                                     int argc, const char **argv) 
2007 {
2008         POLICY_HND connect_pol, domain_pol, user_pol, *pol;
2009         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2010         uint32 sec_info = DACL_SECURITY_INFORMATION;
2011         fstring server;
2012         uint32 user_rid = 0;
2013         TALLOC_CTX *ctx = NULL;
2014         SEC_DESC_BUF *sec_desc_buf=NULL;
2015         bool domain = False;
2016
2017         ctx=talloc_init("cmd_samr_query_sec_obj");
2018         
2019         if ((argc < 1) || (argc > 3)) {
2020                 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2021                 printf("\tSpecify rid for security on user, -d for security on domain\n");
2022                 talloc_destroy(ctx);
2023                 return NT_STATUS_OK;
2024         }
2025         
2026         if (argc > 1) {
2027                 if (strcmp(argv[1], "-d") == 0)
2028                         domain = True;
2029                 else
2030                         sscanf(argv[1], "%i", &user_rid);
2031         }
2032
2033         if (argc == 3) {
2034                 sec_info = atoi(argv[2]);
2035         }
2036         
2037         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
2038         strupper_m(server);
2039         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2040                                    &connect_pol);
2041
2042         if (!NT_STATUS_IS_OK(result))
2043                 goto done;
2044
2045         if (domain || user_rid)
2046                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2047                                                 &connect_pol,
2048                                                 MAXIMUM_ALLOWED_ACCESS,
2049                                                 &domain_sid,
2050                                                 &domain_pol);
2051
2052         if (!NT_STATUS_IS_OK(result))
2053                 goto done;
2054
2055         if (user_rid)
2056                 result = rpccli_samr_OpenUser(cli, mem_ctx,
2057                                               &domain_pol,
2058                                               MAXIMUM_ALLOWED_ACCESS,
2059                                               user_rid,
2060                                               &user_pol);
2061
2062         if (!NT_STATUS_IS_OK(result))
2063                 goto done;
2064
2065         /* Pick which query pol to use */
2066
2067         pol = &connect_pol;
2068
2069         if (domain)
2070                 pol = &domain_pol;
2071
2072         if (user_rid)
2073                 pol = &user_pol;
2074
2075         /* Query SAM security object */
2076
2077         result = rpccli_samr_query_sec_obj(cli, mem_ctx, pol, sec_info, ctx, 
2078                                         &sec_desc_buf);
2079
2080         if (!NT_STATUS_IS_OK(result))
2081                 goto done;
2082
2083         display_sec_desc(sec_desc_buf->sd);
2084
2085         rpccli_samr_Close(cli, mem_ctx, &user_pol);
2086         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2087         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2088 done:
2089         talloc_destroy(ctx);
2090         return result;
2091 }
2092
2093 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli, 
2094                                            TALLOC_CTX *mem_ctx,
2095                                            int argc, const char **argv) 
2096 {
2097         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2098         POLICY_HND connect_pol, domain_pol, user_pol;
2099         struct samr_PwInfo info;
2100         uint32_t rid;
2101
2102         if (argc != 2) {
2103                 printf("Usage: %s rid\n", argv[0]);
2104                 return NT_STATUS_OK;
2105         }
2106
2107         sscanf(argv[1], "%i", &rid);
2108
2109         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
2110                                    &connect_pol);
2111
2112         if (!NT_STATUS_IS_OK(result)) {
2113                 goto done;
2114         }
2115
2116         result = rpccli_samr_OpenDomain(cli, mem_ctx,
2117                                         &connect_pol,
2118                                         MAXIMUM_ALLOWED_ACCESS,
2119                                         &domain_sid,
2120                                         &domain_pol);
2121
2122         if (!NT_STATUS_IS_OK(result)) {
2123                 goto done;
2124         }
2125
2126         result = rpccli_samr_OpenUser(cli, mem_ctx,
2127                                       &domain_pol,
2128                                       MAXIMUM_ALLOWED_ACCESS,
2129                                       rid,
2130                                       &user_pol);
2131
2132         if (!NT_STATUS_IS_OK(result)) {
2133                 goto done;
2134         }
2135
2136         result = rpccli_samr_GetUserPwInfo(cli, mem_ctx, &user_pol, &info);
2137         if (NT_STATUS_IS_OK(result)) {
2138                 printf("min_password_length: %d\n", info.min_password_length);
2139                 printf("%s\n",
2140                         NDR_PRINT_STRUCT_STRING(mem_ctx,
2141                                 samr_PasswordProperties, &info.password_properties));
2142         }
2143
2144  done:
2145         rpccli_samr_Close(cli, mem_ctx, &user_pol);
2146         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2147         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2148
2149         return result;
2150 }
2151
2152 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2153                                         TALLOC_CTX *mem_ctx,
2154                                         int argc, const char **argv)
2155 {
2156         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2157         struct lsa_String domain_name;
2158         struct samr_PwInfo info;
2159
2160         if (argc < 1 || argc > 3) {
2161                 printf("Usage: %s <domain>\n", argv[0]);
2162                 return NT_STATUS_OK;
2163         }
2164
2165         init_lsa_String(&domain_name, argv[1]);
2166
2167         result = rpccli_samr_GetDomPwInfo(cli, mem_ctx, &domain_name, &info);
2168
2169         if (NT_STATUS_IS_OK(result)) {
2170                 printf("min_password_length: %d\n", info.min_password_length);
2171                 display_password_properties(info.password_properties);
2172         }
2173
2174         return result;
2175 }
2176
2177 /* Look up domain name */
2178
2179 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli, 
2180                                        TALLOC_CTX *mem_ctx,
2181                                        int argc, const char **argv) 
2182 {
2183         POLICY_HND connect_pol, domain_pol;
2184         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2185         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2186         fstring domain_name,sid_string;
2187         DOM_SID sid;
2188         
2189         if (argc != 2) {
2190                 printf("Usage: %s domain_name\n", argv[0]);
2191                 return NT_STATUS_OK;
2192         }
2193         
2194         sscanf(argv[1], "%s", domain_name);
2195         
2196         result = try_samr_connects(cli, mem_ctx, access_mask, &connect_pol);
2197         
2198         if (!NT_STATUS_IS_OK(result))
2199                 goto done;
2200
2201         result = rpccli_samr_OpenDomain(cli, mem_ctx,
2202                                         &connect_pol,
2203                                         access_mask,
2204                                         &domain_sid,
2205                                         &domain_pol);
2206
2207         if (!NT_STATUS_IS_OK(result))
2208                 goto done;
2209         
2210         result = rpccli_samr_lookup_domain(
2211                 cli, mem_ctx, &connect_pol, domain_name, &sid);
2212
2213         if (NT_STATUS_IS_OK(result)) {
2214                 sid_to_fstring(sid_string,&sid);
2215                 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2216                        domain_name,sid_string);
2217         }
2218
2219         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2220         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2221 done:
2222         return result;
2223 }
2224
2225 /* Change user password */
2226
2227 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli, 
2228                                     TALLOC_CTX *mem_ctx,
2229                                     int argc, const char **argv) 
2230 {
2231         POLICY_HND connect_pol, domain_pol;
2232         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2233         const char *user, *oldpass, *newpass;
2234         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2235
2236         if (argc < 3) {
2237                 printf("Usage: %s username oldpass newpass\n", argv[0]);
2238                 return NT_STATUS_INVALID_PARAMETER;
2239         }
2240
2241         user = argv[1];
2242         oldpass = argv[2];
2243         newpass = argv[3];
2244         
2245         /* Get sam policy handle */
2246
2247         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
2248                                    &connect_pol);
2249
2250         if (!NT_STATUS_IS_OK(result))
2251                 goto done;
2252
2253         /* Get domain policy handle */
2254
2255         result = rpccli_samr_OpenDomain(cli, mem_ctx,
2256                                         &connect_pol,
2257                                         access_mask,
2258                                         &domain_sid,
2259                                         &domain_pol);
2260
2261         if (!NT_STATUS_IS_OK(result))
2262                 goto done;
2263
2264         /* Change user password */
2265         result = rpccli_samr_chgpasswd_user(cli, mem_ctx, user, newpass, oldpass);
2266
2267         if (!NT_STATUS_IS_OK(result))
2268                 goto done;
2269
2270         result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2271         if (!NT_STATUS_IS_OK(result)) goto done;
2272
2273         result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2274         if (!NT_STATUS_IS_OK(result)) goto done;
2275
2276  done:
2277         return result;
2278 }
2279
2280
2281 /* Change user password */
2282
2283 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli, 
2284                                     TALLOC_CTX *mem_ctx,
2285                                     int argc, const char **argv) 
2286 {
2287         POLICY_HND connect_pol, domain_pol;
2288         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2289         const char *user, *oldpass, *newpass;
2290         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2291         SAM_UNK_INFO_1 info;
2292         SAMR_CHANGE_REJECT reject;
2293
2294         if (argc < 3) {
2295                 printf("Usage: %s username oldpass newpass\n", argv[0]);
2296                 return NT_STATUS_INVALID_PARAMETER;
2297         }
2298
2299         user = argv[1];
2300         oldpass = argv[2];
2301         newpass = argv[3];
2302         
2303         /* Get sam policy handle */
2304
2305         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
2306                                    &connect_pol);
2307
2308         if (!NT_STATUS_IS_OK(result))
2309                 goto done;
2310
2311         /* Get domain policy handle */
2312
2313         result = rpccli_samr_OpenDomain(cli, mem_ctx,
2314                                         &connect_pol,
2315                                         access_mask,
2316                                         &domain_sid,
2317                                         &domain_pol);
2318
2319         if (!NT_STATUS_IS_OK(result))
2320                 goto done;
2321
2322         /* Change user password */
2323         result = rpccli_samr_chgpasswd3(cli, mem_ctx, user, newpass, oldpass, &info, &reject);
2324
2325         if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2326         
2327                 display_sam_unk_info_1(&info);
2328
2329                 switch (reject.reject_reason) {
2330                         case SAMR_REJECT_TOO_SHORT:
2331                                 d_printf("SAMR_REJECT_TOO_SHORT\n");
2332                                 break;
2333                         case SAMR_REJECT_IN_HISTORY:
2334                                 d_printf("SAMR_REJECT_IN_HISTORY\n");
2335                                 break;
2336                         case SAMR_REJECT_COMPLEXITY:
2337                                 d_printf("SAMR_REJECT_COMPLEXITY\n");
2338                                 break;
2339                         case SAMR_REJECT_OTHER:
2340                                 d_printf("SAMR_REJECT_OTHER\n");
2341                                 break;
2342                         default:
2343                                 d_printf("unknown reject reason: %d\n", reject.reject_reason);
2344                                 break;
2345                 }
2346         }
2347
2348         if (!NT_STATUS_IS_OK(result))
2349                 goto done;
2350
2351         result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2352         if (!NT_STATUS_IS_OK(result)) goto done;
2353
2354         result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2355         if (!NT_STATUS_IS_OK(result)) goto done;
2356
2357  done:
2358         return result;
2359 }
2360
2361 /* List of commands exported by this module */
2362
2363 struct cmd_set samr_commands[] = {
2364
2365         { "SAMR" },
2366
2367         { "queryuser",  RPC_RTYPE_NTSTATUS, cmd_samr_query_user,                NULL, PI_SAMR, NULL,    "Query user info",         "" },
2368         { "querygroup",         RPC_RTYPE_NTSTATUS, cmd_samr_query_group,               NULL, PI_SAMR, NULL,    "Query group info",        "" },
2369         { "queryusergroups",    RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups,  NULL, PI_SAMR, NULL,    "Query user groups",       "" },
2370         { "queryuseraliases",   RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases,         NULL, PI_SAMR, NULL,    "Query user aliases",      "" },
2371         { "querygroupmem",      RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem,    NULL, PI_SAMR, NULL,    "Query group membership",  "" },
2372         { "queryaliasmem",      RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem,    NULL, PI_SAMR, NULL,    "Query alias membership",  "" },
2373         { "deletealias",        RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias,      NULL, PI_SAMR, NULL,    "Delete an alias",  "" },
2374         { "querydispinfo",      RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo,    NULL, PI_SAMR, NULL,    "Query display info",      "" },
2375         { "querydominfo",       RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo,     NULL, PI_SAMR, NULL,    "Query domain info",       "" },
2376         { "enumdomusers",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users,       NULL, PI_SAMR, NULL,  "Enumerate domain users", "" },
2377         { "enumdomgroups",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups,       NULL, PI_SAMR, NULL,        "Enumerate domain groups", "" },
2378         { "enumalsgroups",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups,       NULL, PI_SAMR, NULL,        "Enumerate alias groups",  "" },
2379
2380         { "createdomuser",      RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user,       NULL, PI_SAMR, NULL,        "Create domain user",      "" },
2381         { "createdomgroup",     RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group,      NULL, PI_SAMR, NULL,        "Create domain group",     "" },
2382         { "createdomalias",     RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias,      NULL, PI_SAMR, NULL,        "Create domain alias",     "" },
2383         { "samlookupnames",     RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names,          NULL, PI_SAMR, NULL,        "Look up names",           "" },
2384         { "samlookuprids",      RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids,           NULL, PI_SAMR, NULL,        "Look up names",           "" },
2385         { "deletedomgroup",     RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group,      NULL, PI_SAMR, NULL,        "Delete domain group",     "" },
2386         { "deletedomuser",      RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user,       NULL, PI_SAMR, NULL,        "Delete domain user",      "" },
2387         { "samquerysecobj",     RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj,         NULL, PI_SAMR, NULL, "Query SAMR security object",   "" },
2388         { "getdompwinfo",       RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo,        NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
2389         { "getusrdompwinfo",    RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo,     NULL, PI_SAMR, NULL, "Retrieve user domain password info", "" },
2390
2391         { "lookupdomain",       RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain,         NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },
2392         { "chgpasswd2",         RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2,            NULL, PI_SAMR, NULL, "Change user password", "" },
2393         { "chgpasswd3",         RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3,            NULL, PI_SAMR, NULL, "Change user password", "" },
2394         { NULL }
2395 };