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