Trying to avoid defining new SAMR acct creation flags when we already have them with...
[samba.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 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_open_domain(cli, mem_ctx, &connect_pol,
378                                       MAXIMUM_ALLOWED_ACCESS,
379                                       &domain_sid, &domain_pol);
380
381         if (!NT_STATUS_IS_OK(result))
382                 goto done;
383
384         result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
385                                     access_mask,
386                                     user_rid, &user_pol);
387
388         if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
389             (user_rid == 0)) {
390
391                 /* Probably this was a user name, try lookupnames */
392                 uint32 num_rids;
393                 uint32 *rids, *types;
394                 
395                 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
396                                                   1000, 1, &argv[1],
397                                                   &num_rids, &rids,
398                                                   &types);
399
400                 if (NT_STATUS_IS_OK(result)) {
401                         result = rpccli_samr_open_user(cli, mem_ctx,
402                                                        &domain_pol,
403                                                        access_mask,
404                                                        rids[0], &user_pol);
405                 }
406         }
407
408
409         if (!NT_STATUS_IS_OK(result))
410                 goto done;
411
412         ZERO_STRUCT(user_ctr);
413
414         result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol, 
415                                          info_level, &user_ctr);
416
417         if (!NT_STATUS_IS_OK(result))
418                 goto done;
419
420         switch (user_ctr->switch_value) {
421         case 7:
422                 display_sam_user_info_7(user_ctr->info.id7);
423                 break;
424         case 9:
425                 display_sam_user_info_9(user_ctr->info.id9);
426                 break;
427         case 16:
428                 display_sam_user_info_16(user_ctr->info.id16);
429                 break;
430         case 21:
431                 display_sam_user_info_21(user_ctr->info.id21);
432                 break;
433         default:
434                 printf("Unsupported infolevel: %d\n", info_level);
435                 break;
436         }
437
438         rpccli_samr_close(cli, mem_ctx, &user_pol);
439         rpccli_samr_close(cli, mem_ctx, &domain_pol);
440         rpccli_samr_close(cli, mem_ctx, &connect_pol);
441
442 done:
443         return result;
444 }
445
446 /****************************************************************************
447  display group info
448  ****************************************************************************/
449 static void display_group_info1(GROUP_INFO1 *info1)
450 {
451         fstring temp;
452
453         unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp));
454         printf("\tGroup Name:\t%s\n", temp);
455         unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp));
456         printf("\tDescription:\t%s\n", temp);
457         printf("\tGroup Attribute:%d\n", info1->group_attr);
458         printf("\tNum Members:%d\n", info1->num_members);
459 }
460
461 /****************************************************************************
462  display group info
463  ****************************************************************************/
464 static void display_group_info2(GROUP_INFO2 *info2)
465 {
466         fstring name;
467
468         unistr2_to_ascii(name, &info2->uni_acct_name, sizeof(name));
469         printf("\tGroup Description:%s\n", name);
470 }
471
472
473 /****************************************************************************
474  display group info
475  ****************************************************************************/
476 static void display_group_info3(GROUP_INFO3 *info3)
477 {
478         printf("\tGroup Attribute:%d\n", info3->group_attr);
479 }
480
481
482 /****************************************************************************
483  display group info
484  ****************************************************************************/
485 static void display_group_info4(GROUP_INFO4 *info4)
486 {
487         fstring desc;
488
489         unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc));
490         printf("\tGroup Description:%s\n", desc);
491 }
492
493 /****************************************************************************
494  display group info
495  ****************************************************************************/
496 static void display_group_info5(GROUP_INFO5 *info5)
497 {
498         fstring temp;
499
500         unistr2_to_ascii(temp, &info5->uni_acct_name, sizeof(temp));
501         printf("\tGroup Name:\t%s\n", temp);
502         unistr2_to_ascii(temp, &info5->uni_acct_desc, sizeof(temp));
503         printf("\tDescription:\t%s\n", temp);
504         printf("\tGroup Attribute:%d\n", info5->group_attr);
505         printf("\tNum Members:%d\n", info5->num_members);
506 }
507
508 /****************************************************************************
509  display sam sync structure
510  ****************************************************************************/
511 static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
512 {
513         switch (ctr->switch_value1) {
514                 case 1:
515                         display_group_info1(&ctr->group.info1);
516                         break;
517                 case 2:
518                         display_group_info2(&ctr->group.info2);
519                         break;
520                 case 3:
521                         display_group_info3(&ctr->group.info3);
522                         break;
523                 case 4:
524                         display_group_info4(&ctr->group.info4);
525                         break;
526                 case 5:
527                         display_group_info5(&ctr->group.info5);
528                         break;
529
530         }
531 }
532
533 /***********************************************************************
534  * Query group information 
535  */
536 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli, 
537                                      TALLOC_CTX *mem_ctx,
538                                      int argc, const char **argv) 
539 {
540         POLICY_HND connect_pol, domain_pol, group_pol;
541         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
542         uint32 info_level = 1;
543         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
544         GROUP_INFO_CTR *group_ctr;
545         fstring                 server; 
546         uint32 group_rid;
547         
548         if ((argc < 2) || (argc > 4)) {
549                 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
550                 return NT_STATUS_OK;
551         }
552
553         sscanf(argv[1], "%i", &group_rid);
554         
555         if (argc > 2)
556                 sscanf(argv[2], "%i", &info_level);
557         
558         if (argc > 3)
559                 sscanf(argv[3], "%x", &access_mask);
560
561         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
562         strupper_m(server);
563
564         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
565                                    &connect_pol);
566
567         if (!NT_STATUS_IS_OK(result))
568                 goto done;
569
570         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
571                                       MAXIMUM_ALLOWED_ACCESS,
572                                       &domain_sid, &domain_pol);
573
574         if (!NT_STATUS_IS_OK(result))
575                 goto done;
576
577         result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
578                                      access_mask,
579                                      group_rid, &group_pol);
580
581         if (!NT_STATUS_IS_OK(result))
582                 goto done;
583
584         result = rpccli_samr_query_groupinfo(cli, mem_ctx, &group_pol, 
585                                           info_level, &group_ctr);
586         if (!NT_STATUS_IS_OK(result)) {
587                 goto done;
588         }
589
590         display_group_info_ctr(group_ctr);
591
592         rpccli_samr_close(cli, mem_ctx, &group_pol);
593         rpccli_samr_close(cli, mem_ctx, &domain_pol);
594         rpccli_samr_close(cli, mem_ctx, &connect_pol);
595 done:
596         return result;
597 }
598
599 /* Query groups a user is a member of */
600
601 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli, 
602                                           TALLOC_CTX *mem_ctx,
603                                           int argc, const char **argv) 
604 {
605         POLICY_HND              connect_pol, 
606                                 domain_pol, 
607                                 user_pol;
608         NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
609         uint32                  num_groups, 
610                                 user_rid;
611         uint32                  access_mask = MAXIMUM_ALLOWED_ACCESS;
612         DOM_GID                 *user_gids;
613         int                     i;
614         fstring                 server;
615         
616         if ((argc < 2) || (argc > 3)) {
617                 printf("Usage: %s rid [access mask]\n", argv[0]);
618                 return NT_STATUS_OK;
619         }
620
621         sscanf(argv[1], "%i", &user_rid);
622         
623         if (argc > 2)
624                 sscanf(argv[2], "%x", &access_mask);
625
626         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
627         strupper_m(server);
628                 
629         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
630                                    &connect_pol);
631
632         if (!NT_STATUS_IS_OK(result))
633                 goto done;
634
635         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
636                                       MAXIMUM_ALLOWED_ACCESS,
637                                       &domain_sid, &domain_pol);
638
639         if (!NT_STATUS_IS_OK(result))
640                 goto done;
641
642         result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
643                                     access_mask,
644                                     user_rid, &user_pol);
645
646         if (!NT_STATUS_IS_OK(result))
647                 goto done;
648
649         result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
650                                            &num_groups, &user_gids);
651
652         if (!NT_STATUS_IS_OK(result))
653                 goto done;
654
655         for (i = 0; i < num_groups; i++) {
656                 printf("\tgroup rid:[0x%x] attr:[0x%x]\n", 
657                        user_gids[i].g_rid, user_gids[i].attr);
658         }
659
660         rpccli_samr_close(cli, mem_ctx, &user_pol);
661         rpccli_samr_close(cli, mem_ctx, &domain_pol);
662         rpccli_samr_close(cli, mem_ctx, &connect_pol);
663  done:
664         return result;
665 }
666
667 /* Query aliases a user is a member of */
668
669 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli, 
670                                            TALLOC_CTX *mem_ctx,
671                                            int argc, const char **argv) 
672 {
673         POLICY_HND              connect_pol, domain_pol;
674         NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
675         DOM_SID                *sids;
676         size_t                     num_sids;
677         uint32                  num_aliases, *alias_rids;
678         uint32                  access_mask = MAXIMUM_ALLOWED_ACCESS;
679         int                     i;
680         fstring                 server;
681         DOM_SID2               *sid2;
682
683         if (argc < 3) {
684                 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
685                 return NT_STATUS_INVALID_PARAMETER;
686         }
687
688         sids = NULL;
689         num_sids = 0;
690
691         for (i=2; i<argc; i++) {
692                 DOM_SID tmp_sid;
693                 if (!string_to_sid(&tmp_sid, argv[i])) {
694                         printf("%s is not a legal SID\n", argv[i]);
695                         return NT_STATUS_INVALID_PARAMETER;
696                 }
697                 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
698                 if (!NT_STATUS_IS_OK(result)) {
699                         return result;
700                 }
701         }
702
703         if (num_sids) {
704                 sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
705                 if (sid2 == NULL)
706                         return NT_STATUS_NO_MEMORY;
707         } else {
708                 sid2 = NULL;
709         }
710
711         for (i=0; i<num_sids; i++) {
712                 sid_copy(&sid2[i].sid, &sids[i]);
713                 sid2[i].num_auths = sid2[i].sid.num_auths;
714         }
715
716         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
717         strupper_m(server);
718                 
719         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
720                                    &connect_pol);
721
722         if (!NT_STATUS_IS_OK(result))
723                 goto done;
724
725         if (StrCaseCmp(argv[1], "domain")==0)
726                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
727                                               access_mask,
728                                               &domain_sid, &domain_pol);
729         else if (StrCaseCmp(argv[1], "builtin")==0)
730                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
731                                               access_mask,
732                                               &global_sid_Builtin,
733                                               &domain_pol);
734         else {
735                 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
736                 return NT_STATUS_INVALID_PARAMETER;
737         }
738
739         if (!NT_STATUS_IS_OK(result))
740                 goto done;
741
742         result = rpccli_samr_query_useraliases(cli, mem_ctx, &domain_pol,
743                                             num_sids, sid2,
744                                             &num_aliases, &alias_rids);
745
746         if (!NT_STATUS_IS_OK(result))
747                 goto done;
748
749         for (i = 0; i < num_aliases; i++) {
750                 printf("\tgroup rid:[0x%x]\n", alias_rids[i]);
751         }
752
753         rpccli_samr_close(cli, mem_ctx, &domain_pol);
754         rpccli_samr_close(cli, mem_ctx, &connect_pol);
755  done:
756         return result;
757 }
758
759 /* Query members of a group */
760
761 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli, 
762                                         TALLOC_CTX *mem_ctx,
763                                         int argc, const char **argv) 
764 {
765         POLICY_HND connect_pol, domain_pol, group_pol;
766         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
767         uint32 num_members, *group_rids, *group_attrs, group_rid;
768         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
769         int i;
770         fstring                 server;
771         unsigned int old_timeout;
772         
773         if ((argc < 2) || (argc > 3)) {
774                 printf("Usage: %s rid [access mask]\n", argv[0]);
775                 return NT_STATUS_OK;
776         }
777
778         sscanf(argv[1], "%i", &group_rid);
779         
780         if (argc > 2)
781                 sscanf(argv[2], "%x", &access_mask);
782
783         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
784         strupper_m(server);
785
786         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
787                                    &connect_pol);
788
789         if (!NT_STATUS_IS_OK(result))
790                 goto done;
791
792         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
793                                       MAXIMUM_ALLOWED_ACCESS,
794                                       &domain_sid, &domain_pol);
795
796         if (!NT_STATUS_IS_OK(result))
797                 goto done;
798
799         result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
800                                      access_mask,
801                                      group_rid, &group_pol);
802
803         if (!NT_STATUS_IS_OK(result))
804                 goto done;
805
806         /* Make sure to wait for our DC's reply */
807         old_timeout = cli_set_timeout(cli->cli, MAX(cli->cli->timeout,30000)); /* 30 seconds. */
808
809         result = rpccli_samr_query_groupmem(cli, mem_ctx, &group_pol,
810                                          &num_members, &group_rids,
811                                          &group_attrs);
812
813         cli_set_timeout(cli->cli, old_timeout);
814
815         if (!NT_STATUS_IS_OK(result))
816                 goto done;
817
818         for (i = 0; i < num_members; i++) {
819                 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
820                        group_attrs[i]);
821         }
822
823         rpccli_samr_close(cli, mem_ctx, &group_pol);
824         rpccli_samr_close(cli, mem_ctx, &domain_pol);
825         rpccli_samr_close(cli, mem_ctx, &connect_pol);
826  done:
827         return result;
828 }
829
830 /* Enumerate domain users */
831
832 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, 
833                                         TALLOC_CTX *mem_ctx,
834                                         int argc, const char **argv) 
835 {
836         POLICY_HND connect_pol, domain_pol;
837         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
838         uint32 start_idx, size, num_dom_users, i;
839         char **dom_users;
840         uint32 *dom_rids;
841         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
842         uint32 acb_mask = ACB_NORMAL;
843         bool got_connect_pol = False, got_domain_pol = False;
844
845         if ((argc < 1) || (argc > 3)) {
846                 printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
847                 return NT_STATUS_OK;
848         }
849         
850         if (argc > 1)
851                 sscanf(argv[1], "%x", &access_mask);
852
853         if (argc > 2)
854                 sscanf(argv[2], "%x", &acb_mask);
855
856         /* Get sam policy handle */
857
858         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
859                                    &connect_pol);
860
861         if (!NT_STATUS_IS_OK(result))
862                 goto done;
863
864         got_connect_pol = True;
865
866         /* Get domain policy handle */
867
868         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
869                                       access_mask,
870                                       &domain_sid, &domain_pol);
871
872         if (!NT_STATUS_IS_OK(result))
873                 goto done;
874
875         got_domain_pol = True;
876
877         /* Enumerate domain users */
878
879         start_idx = 0;
880         size = 0xffff;
881
882         do {
883                 result = rpccli_samr_enum_dom_users(
884                         cli, mem_ctx, &domain_pol, &start_idx, acb_mask,
885                         size, &dom_users, &dom_rids, &num_dom_users);
886
887                 if (NT_STATUS_IS_OK(result) ||
888                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
889
890                         for (i = 0; i < num_dom_users; i++)
891                                printf("user:[%s] rid:[0x%x]\n", 
892                                        dom_users[i], dom_rids[i]);
893                 }
894
895         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
896
897  done:
898         if (got_domain_pol)
899                 rpccli_samr_close(cli, mem_ctx, &domain_pol);
900
901         if (got_connect_pol)
902                 rpccli_samr_close(cli, mem_ctx, &connect_pol);
903
904         return result;
905 }
906
907 /* Enumerate domain groups */
908
909 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, 
910                                          TALLOC_CTX *mem_ctx,
911                                          int argc, const char **argv) 
912 {
913         POLICY_HND connect_pol, domain_pol;
914         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
915         uint32 start_idx, size, num_dom_groups, i;
916         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
917         struct acct_info *dom_groups;
918         bool got_connect_pol = False, got_domain_pol = False;
919
920         if ((argc < 1) || (argc > 2)) {
921                 printf("Usage: %s [access_mask]\n", argv[0]);
922                 return NT_STATUS_OK;
923         }
924         
925         if (argc > 1)
926                 sscanf(argv[1], "%x", &access_mask);
927
928         /* Get sam policy handle */
929
930         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
931                                    &connect_pol);
932
933         if (!NT_STATUS_IS_OK(result))
934                 goto done;
935
936         got_connect_pol = True;
937
938         /* Get domain policy handle */
939
940         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
941                                       access_mask,
942                                       &domain_sid, &domain_pol);
943
944         if (!NT_STATUS_IS_OK(result))
945                 goto done;
946
947         got_domain_pol = True;
948
949         /* Enumerate domain groups */
950
951         start_idx = 0;
952         size = 0xffff;
953
954         do {
955                 result = rpccli_samr_enum_dom_groups(
956                         cli, mem_ctx, &domain_pol, &start_idx, size,
957                         &dom_groups, &num_dom_groups);
958
959                 if (NT_STATUS_IS_OK(result) ||
960                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
961
962                         for (i = 0; i < num_dom_groups; i++)
963                                 printf("group:[%s] rid:[0x%x]\n", 
964                                        dom_groups[i].acct_name,
965                                        dom_groups[i].rid);
966                 }
967
968         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
969
970  done:
971         if (got_domain_pol)
972                 rpccli_samr_close(cli, mem_ctx, &domain_pol);
973
974         if (got_connect_pol)
975                 rpccli_samr_close(cli, mem_ctx, &connect_pol);
976
977         return result;
978 }
979
980 /* Enumerate alias groups */
981
982 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, 
983                                          TALLOC_CTX *mem_ctx,
984                                          int argc, const char **argv) 
985 {
986         POLICY_HND connect_pol, domain_pol;
987         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
988         uint32 start_idx, size, num_als_groups, i;
989         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
990         struct acct_info *als_groups;
991         bool got_connect_pol = False, got_domain_pol = False;
992
993         if ((argc < 2) || (argc > 3)) {
994                 printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
995                 return NT_STATUS_OK;
996         }
997         
998         if (argc > 2)
999                 sscanf(argv[2], "%x", &access_mask);
1000
1001         /* Get sam policy handle */
1002
1003         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1004                                    &connect_pol);
1005
1006         if (!NT_STATUS_IS_OK(result))
1007                 goto done;
1008
1009         got_connect_pol = True;
1010
1011         /* Get domain policy handle */
1012
1013         if (StrCaseCmp(argv[1], "domain")==0)
1014                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1015                                               access_mask,
1016                                               &domain_sid, &domain_pol);
1017         else if (StrCaseCmp(argv[1], "builtin")==0)
1018                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1019                                               access_mask,
1020                                               &global_sid_Builtin, &domain_pol);
1021         else
1022                 return NT_STATUS_OK;
1023
1024         if (!NT_STATUS_IS_OK(result))
1025                 goto done;
1026
1027         got_domain_pol = True;
1028
1029         /* Enumerate alias groups */
1030
1031         start_idx = 0;
1032         size = 0xffff;          /* Number of groups to retrieve */
1033
1034         do {
1035                 result = rpccli_samr_enum_als_groups(
1036                         cli, mem_ctx, &domain_pol, &start_idx, size,
1037                         &als_groups, &num_als_groups);
1038
1039                 if (NT_STATUS_IS_OK(result) ||
1040                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1041
1042                         for (i = 0; i < num_als_groups; i++)
1043                                 printf("group:[%s] rid:[0x%x]\n", 
1044                                        als_groups[i].acct_name,
1045                                        als_groups[i].rid);
1046                 }
1047         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1048
1049  done:
1050         if (got_domain_pol)
1051                 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1052         
1053         if (got_connect_pol)
1054                 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1055         
1056         return result;
1057 }
1058
1059 /* Query alias membership */
1060
1061 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli, 
1062                                         TALLOC_CTX *mem_ctx,
1063                                         int argc, const char **argv) 
1064 {
1065         POLICY_HND connect_pol, domain_pol, alias_pol;
1066         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1067         uint32 alias_rid, num_members, i;
1068         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1069         DOM_SID *alias_sids;
1070
1071         if ((argc < 3) || (argc > 4)) {
1072                 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1073                 return NT_STATUS_OK;
1074         }
1075
1076         sscanf(argv[2], "%i", &alias_rid);
1077         
1078         if (argc > 3)
1079                 sscanf(argv[3], "%x", &access_mask);
1080
1081         /* Open SAMR handle */
1082
1083         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1084                                    &connect_pol);
1085
1086         if (!NT_STATUS_IS_OK(result))
1087                 goto done;
1088
1089         /* Open handle on domain */
1090         
1091         if (StrCaseCmp(argv[1], "domain")==0)
1092                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1093                                               MAXIMUM_ALLOWED_ACCESS,
1094                                               &domain_sid, &domain_pol);
1095         else if (StrCaseCmp(argv[1], "builtin")==0)
1096                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1097                                               MAXIMUM_ALLOWED_ACCESS,
1098                                               &global_sid_Builtin, &domain_pol);
1099         else
1100                 return NT_STATUS_OK;
1101
1102         if (!NT_STATUS_IS_OK(result))
1103                 goto done;
1104
1105         /* Open handle on alias */
1106
1107         result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
1108                                      access_mask,
1109                                      alias_rid, &alias_pol);
1110         if (!NT_STATUS_IS_OK(result))
1111                 goto done;
1112
1113         result = rpccli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
1114                                          &num_members, &alias_sids);
1115
1116         if (!NT_STATUS_IS_OK(result))
1117                 goto done;
1118
1119         for (i = 0; i < num_members; i++) {
1120                 fstring sid_str;
1121
1122                 sid_to_fstring(sid_str, &alias_sids[i]);
1123                 printf("\tsid:[%s]\n", sid_str);
1124         }
1125
1126         rpccli_samr_close(cli, mem_ctx, &alias_pol);
1127         rpccli_samr_close(cli, mem_ctx, &domain_pol);
1128         rpccli_samr_close(cli, mem_ctx, &connect_pol);
1129  done:
1130         return result;
1131 }
1132
1133 /* Query delete an alias membership */
1134
1135 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli, 
1136                                       TALLOC_CTX *mem_ctx,
1137                                       int argc, const char **argv) 
1138 {
1139         POLICY_HND connect_pol, domain_pol, alias_pol;
1140         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1141         uint32 alias_rid;
1142         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1143
1144         if (argc != 3) {
1145                 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1146                 return NT_STATUS_OK;
1147         }
1148
1149         alias_rid = strtoul(argv[2], NULL, 10);
1150         
1151         /* Open SAMR handle */
1152
1153         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1154                                    &connect_pol);
1155
1156         if (!NT_STATUS_IS_OK(result))
1157                 goto done;
1158
1159         /* Open handle on domain */
1160         
1161         if (StrCaseCmp(argv[1], "domain")==0)
1162                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1163                                               MAXIMUM_ALLOWED_ACCESS,
1164                                               &domain_sid, &domain_pol);
1165         else if (StrCaseCmp(argv[1], "builtin")==0)
1166                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1167                                               MAXIMUM_ALLOWED_ACCESS,
1168                                               &global_sid_Builtin, &domain_pol);
1169         else
1170                 return NT_STATUS_INVALID_PARAMETER;
1171
1172         if (!NT_STATUS_IS_OK(result))
1173                 goto done;
1174
1175         /* Open handle on alias */
1176
1177         result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
1178                                      access_mask,
1179                                      alias_rid, &alias_pol);
1180         if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1181                 /* Probably this was a user name, try lookupnames */
1182                 uint32 num_rids;
1183                 uint32 *rids, *types;
1184                 
1185                 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1186                                                   1000, 1, &argv[2],
1187                                                   &num_rids, &rids,
1188                                                   &types);
1189
1190                 if (NT_STATUS_IS_OK(result)) {
1191                         result = rpccli_samr_open_alias(cli, mem_ctx,
1192                                                        &domain_pol,
1193                                                        access_mask,
1194                                                        rids[0], &alias_pol);
1195                 }
1196         }
1197
1198         result = rpccli_samr_delete_dom_alias(cli, mem_ctx, &alias_pol);
1199
1200         if (!NT_STATUS_IS_OK(result))
1201                 goto done;
1202
1203         rpccli_samr_close(cli, mem_ctx, &domain_pol);
1204         rpccli_samr_close(cli, mem_ctx, &connect_pol);
1205  done:
1206         return result;
1207 }
1208
1209 /* Query display info */
1210
1211 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli, 
1212                                         TALLOC_CTX *mem_ctx,
1213                                         int argc, const char **argv) 
1214 {
1215         POLICY_HND connect_pol, domain_pol;
1216         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1217         uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries, i;
1218         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1219         uint32 info_level = 1;
1220         SAM_DISPINFO_CTR ctr;
1221         SAM_DISPINFO_1 info1;
1222         SAM_DISPINFO_2 info2;
1223         SAM_DISPINFO_3 info3;
1224         SAM_DISPINFO_4 info4;
1225         SAM_DISPINFO_5 info5;
1226         int loop_count = 0;
1227         bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1228
1229         if (argc > 6) {
1230                 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1231                 return NT_STATUS_OK;
1232         }
1233
1234         if (argc >= 2)
1235                 sscanf(argv[1], "%i", &info_level);
1236         
1237         if (argc >= 3)
1238                 sscanf(argv[2], "%i", &start_idx);
1239         
1240         if (argc >= 4) {
1241                 sscanf(argv[3], "%i", &max_entries);
1242                 got_params = True;
1243         }
1244         
1245         if (argc >= 5) {
1246                 sscanf(argv[4], "%i", &max_size);
1247                 got_params = True;
1248         }
1249         
1250         if (argc >= 6)
1251                 sscanf(argv[5], "%x", &access_mask);
1252
1253         /* Get sam policy handle */
1254
1255         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1256                                    &connect_pol);
1257
1258         if (!NT_STATUS_IS_OK(result))
1259                 goto done;
1260
1261         /* Get domain policy handle */
1262
1263         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1264                                       access_mask, 
1265                                       &domain_sid, &domain_pol);
1266
1267         if (!NT_STATUS_IS_OK(result))
1268                 goto done;
1269
1270         /* Query display info */
1271
1272         ZERO_STRUCT(ctr);
1273         ZERO_STRUCT(info1);
1274         
1275         switch (info_level) {
1276         case 1:
1277                 ZERO_STRUCT(info1);
1278                 ctr.sam.info1 = &info1;
1279                 break;
1280         case 2:
1281                 ZERO_STRUCT(info2);
1282                 ctr.sam.info2 = &info2;
1283                 break;
1284         case 3:
1285                 ZERO_STRUCT(info3);
1286                 ctr.sam.info3 = &info3;
1287                 break;
1288         case 4:
1289                 ZERO_STRUCT(info4);
1290                 ctr.sam.info4 = &info4;
1291                 break;
1292         case 5:
1293                 ZERO_STRUCT(info5);
1294                 ctr.sam.info5 = &info5;
1295                 break;
1296         }
1297
1298
1299         do {
1300
1301                 if (!got_params)
1302                         get_query_dispinfo_params(
1303                                 loop_count, &max_entries, &max_size);
1304                 
1305                 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
1306                                                  &start_idx, info_level,
1307                                                  &num_entries, max_entries, 
1308                                                  max_size, &ctr);
1309
1310                 loop_count++;
1311
1312                 if (NT_STATUS_IS_ERR(result))
1313                         break;
1314
1315                 if (num_entries == 0) 
1316                         break;
1317
1318                 for (i = 0; i < num_entries; i++) {
1319                         switch (info_level) {
1320                         case 1:
1321                                 display_sam_info_1(&ctr.sam.info1->sam[i], &ctr.sam.info1->str[i]);
1322                                 break;
1323                         case 2:
1324                                 display_sam_info_2(&ctr.sam.info2->sam[i], &ctr.sam.info2->str[i]);
1325                                 break;
1326                         case 3:
1327                                 display_sam_info_3(&ctr.sam.info3->sam[i], &ctr.sam.info3->str[i]);
1328                                 break;
1329                         case 4:
1330                                 display_sam_info_4(&ctr.sam.info4->sam[i], &ctr.sam.info4->str[i]);
1331                                 break;
1332                         case 5:
1333                                 display_sam_info_5(&ctr.sam.info5->sam[i], &ctr.sam.info5->str[i]);
1334                                 break;
1335                         }
1336                 }
1337         } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1338
1339         rpccli_samr_close(cli, mem_ctx, &domain_pol);
1340         rpccli_samr_close(cli, mem_ctx, &connect_pol);
1341  done:
1342         return result;
1343 }
1344
1345 /* Query domain info */
1346
1347 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli, 
1348                                        TALLOC_CTX *mem_ctx,
1349                                        int argc, const char **argv) 
1350 {
1351         POLICY_HND connect_pol, domain_pol;
1352         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1353         uint32 switch_level = 2;
1354         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1355         SAM_UNK_CTR ctr;
1356
1357         if (argc > 3) {
1358                 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1359                 return NT_STATUS_OK;
1360         }
1361
1362         if (argc > 1)
1363                 sscanf(argv[1], "%i", &switch_level);
1364         
1365         if (argc > 2)
1366                 sscanf(argv[2], "%x", &access_mask);
1367
1368         /* Get sam policy handle */
1369
1370         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1371                                    &connect_pol);
1372
1373         if (!NT_STATUS_IS_OK(result))
1374                 goto done;
1375
1376         /* Get domain policy handle */
1377
1378         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1379                                       access_mask,
1380                                       &domain_sid, &domain_pol);
1381
1382         if (!NT_STATUS_IS_OK(result))
1383                 goto done;
1384
1385         /* Query domain info */
1386
1387         result = rpccli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
1388                                          switch_level, &ctr);
1389
1390         if (!NT_STATUS_IS_OK(result))
1391                 goto done;
1392
1393         /* Display domain info */
1394
1395         switch (switch_level) {
1396         case 1:
1397                 display_sam_unk_info_1(&ctr.info.inf1);
1398                 break;
1399         case 2:
1400                 display_sam_unk_info_2(&ctr.info.inf2);
1401                 break;
1402         case 3:
1403                 display_sam_unk_info_3(&ctr.info.inf3);
1404                 break;
1405         case 4:
1406                 display_sam_unk_info_4(&ctr.info.inf4);
1407                 break;
1408         case 5:
1409                 display_sam_unk_info_5(&ctr.info.inf5);
1410                 break;
1411         case 6:
1412                 display_sam_unk_info_6(&ctr.info.inf6);
1413                 break;
1414         case 7:
1415                 display_sam_unk_info_7(&ctr.info.inf7);
1416                 break;
1417         case 8:
1418                 display_sam_unk_info_8(&ctr.info.inf8);
1419                 break;
1420         case 9:
1421                 display_sam_unk_info_9(&ctr.info.inf9);
1422                 break;
1423         case 12:
1424                 display_sam_unk_info_12(&ctr.info.inf12);
1425                 break;
1426         case 13:
1427                 display_sam_unk_info_13(&ctr.info.inf13);
1428                 break;
1429
1430         default:
1431                 printf("cannot display domain info for switch value %d\n",
1432                        switch_level);
1433                 break;
1434         }
1435
1436  done:
1437  
1438         rpccli_samr_close(cli, mem_ctx, &domain_pol);
1439         rpccli_samr_close(cli, mem_ctx, &connect_pol);
1440         return result;
1441 }
1442
1443 /* Create domain user */
1444
1445 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli, 
1446                                          TALLOC_CTX *mem_ctx,
1447                                          int argc, const char **argv) 
1448 {
1449         POLICY_HND connect_pol, domain_pol, user_pol;
1450         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1451         const char *acct_name;
1452         uint32 acb_info;
1453         uint32 acct_flags, user_rid;
1454         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1455
1456         if ((argc < 2) || (argc > 3)) {
1457                 printf("Usage: %s username [access mask]\n", argv[0]);
1458                 return NT_STATUS_OK;
1459         }
1460
1461         acct_name = argv[1];
1462
1463         if (argc > 2)
1464                 sscanf(argv[2], "%x", &access_mask);
1465
1466         /* Get sam policy handle */
1467
1468         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1469                                    &connect_pol);
1470
1471         if (!NT_STATUS_IS_OK(result))
1472                 goto done;
1473
1474         /* Get domain policy handle */
1475
1476         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1477                                       access_mask,
1478                                       &domain_sid, &domain_pol);
1479
1480         if (!NT_STATUS_IS_OK(result))
1481                 goto done;
1482
1483         /* Create domain user */
1484
1485         acb_info = ACB_NORMAL;
1486         acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1487                      SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1488                      SAMR_USER_ACCESS_SET_PASSWORD |
1489                      SAMR_USER_ACCESS_GET_ATTRIBUTES |
1490                      SAMR_USER_ACCESS_SET_ATTRIBUTES;
1491
1492         result = rpccli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1493                                           acct_name, acb_info, acct_flags,
1494                                           &user_pol, &user_rid);
1495
1496         if (!NT_STATUS_IS_OK(result))
1497                 goto done;
1498
1499         result = rpccli_samr_close(cli, mem_ctx, &user_pol);
1500         if (!NT_STATUS_IS_OK(result)) goto done;
1501
1502         result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1503         if (!NT_STATUS_IS_OK(result)) goto done;
1504
1505         result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1506         if (!NT_STATUS_IS_OK(result)) goto done;
1507
1508  done:
1509         return result;
1510 }
1511
1512 /* Create domain group */
1513
1514 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli, 
1515                                           TALLOC_CTX *mem_ctx,
1516                                           int argc, const char **argv) 
1517 {
1518         POLICY_HND connect_pol, domain_pol, group_pol;
1519         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1520         const char *grp_name;
1521         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1522
1523         if ((argc < 2) || (argc > 3)) {
1524                 printf("Usage: %s groupname [access mask]\n", argv[0]);
1525                 return NT_STATUS_OK;
1526         }
1527
1528         grp_name = argv[1];
1529         
1530         if (argc > 2)
1531                 sscanf(argv[2], "%x", &access_mask);
1532
1533         /* Get sam policy handle */
1534
1535         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1536                                    &connect_pol);
1537
1538         if (!NT_STATUS_IS_OK(result))
1539                 goto done;
1540
1541         /* Get domain policy handle */
1542
1543         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1544                                       access_mask,
1545                                       &domain_sid, &domain_pol);
1546
1547         if (!NT_STATUS_IS_OK(result))
1548                 goto done;
1549
1550         /* Create domain user */
1551
1552         result = rpccli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
1553                                            grp_name, MAXIMUM_ALLOWED_ACCESS,
1554                                            &group_pol);
1555
1556         if (!NT_STATUS_IS_OK(result))
1557                 goto done;
1558
1559         result = rpccli_samr_close(cli, mem_ctx, &group_pol);
1560         if (!NT_STATUS_IS_OK(result)) goto done;
1561
1562         result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1563         if (!NT_STATUS_IS_OK(result)) goto done;
1564
1565         result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1566         if (!NT_STATUS_IS_OK(result)) goto done;
1567
1568  done:
1569         return result;
1570 }
1571
1572 /* Create domain alias */
1573
1574 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli, 
1575                                           TALLOC_CTX *mem_ctx,
1576                                           int argc, const char **argv) 
1577 {
1578         POLICY_HND connect_pol, domain_pol, alias_pol;
1579         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1580         const char *alias_name;
1581         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1582
1583         if ((argc < 2) || (argc > 3)) {
1584                 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1585                 return NT_STATUS_OK;
1586         }
1587
1588         alias_name = argv[1];
1589         
1590         if (argc > 2)
1591                 sscanf(argv[2], "%x", &access_mask);
1592
1593         /* Get sam policy handle */
1594
1595         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1596                                    &connect_pol);
1597
1598         if (!NT_STATUS_IS_OK(result))
1599                 goto done;
1600
1601         /* Get domain policy handle */
1602
1603         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1604                                          access_mask,
1605                                          &domain_sid, &domain_pol);
1606
1607         if (!NT_STATUS_IS_OK(result))
1608                 goto done;
1609
1610         /* Create domain user */
1611
1612         result = rpccli_samr_create_dom_alias(cli, mem_ctx, &domain_pol,
1613                                               alias_name, &alias_pol);
1614
1615         if (!NT_STATUS_IS_OK(result))
1616                 goto done;
1617
1618         result = rpccli_samr_close(cli, mem_ctx, &alias_pol);
1619         if (!NT_STATUS_IS_OK(result)) goto done;
1620
1621         result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1622         if (!NT_STATUS_IS_OK(result)) goto done;
1623
1624         result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1625         if (!NT_STATUS_IS_OK(result)) goto done;
1626
1627  done:
1628         return result;
1629 }
1630
1631 /* Lookup sam names */
1632
1633 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli, 
1634                                       TALLOC_CTX *mem_ctx,
1635                                       int argc, const char **argv) 
1636 {
1637         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1638         POLICY_HND connect_pol, domain_pol;
1639         uint32 flags = 0x000003e8; /* Unknown */
1640         uint32 num_rids, num_names, *name_types, *rids;
1641         const char **names;
1642         int i;
1643
1644         if (argc < 3) {
1645                 printf("Usage: %s  domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1646                 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1647                 printf("or check on the builtin SID: S-1-5-32\n");
1648                 return NT_STATUS_OK;
1649         }
1650
1651         /* Get sam policy and domain handles */
1652
1653         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1654                                    &connect_pol);
1655
1656         if (!NT_STATUS_IS_OK(result))
1657                 goto done;
1658
1659         if (StrCaseCmp(argv[1], "domain")==0)
1660                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1661                                               MAXIMUM_ALLOWED_ACCESS,
1662                                               &domain_sid, &domain_pol);
1663         else if (StrCaseCmp(argv[1], "builtin")==0)
1664                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1665                                               MAXIMUM_ALLOWED_ACCESS,
1666                                               &global_sid_Builtin, &domain_pol);
1667         else
1668                 return NT_STATUS_OK;
1669
1670         if (!NT_STATUS_IS_OK(result))
1671                 goto done;
1672
1673         /* Look up names */
1674
1675         num_names = argc - 2;
1676
1677         if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) {
1678                 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1679                 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1680                 result = NT_STATUS_NO_MEMORY;
1681                 goto done;
1682         }
1683
1684         for (i = 0; i < num_names; i++)
1685                 names[i] = argv[i + 2];
1686
1687         result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1688                                        flags, num_names, names,
1689                                        &num_rids, &rids, &name_types);
1690
1691         if (!NT_STATUS_IS_OK(result))
1692                 goto done;
1693
1694         /* Display results */
1695
1696         for (i = 0; i < num_names; i++)
1697                 printf("name %s: 0x%x (%d)\n", names[i], rids[i], 
1698                        name_types[i]);
1699
1700         rpccli_samr_close(cli, mem_ctx, &domain_pol);
1701         rpccli_samr_close(cli, mem_ctx, &connect_pol);
1702  done:
1703         return result;
1704 }
1705
1706 /* Lookup sam rids */
1707
1708 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli, 
1709                                      TALLOC_CTX *mem_ctx,
1710                                      int argc, const char **argv) 
1711 {
1712         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1713         POLICY_HND connect_pol, domain_pol;
1714         uint32 num_rids, num_names, *rids, *name_types;
1715         char **names;
1716         int i;
1717
1718         if (argc < 3) {
1719                 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1720                 return NT_STATUS_OK;
1721         }
1722
1723         /* Get sam policy and domain handles */
1724
1725         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1726                                    &connect_pol);
1727
1728         if (!NT_STATUS_IS_OK(result))
1729                 goto done;
1730
1731         if (StrCaseCmp(argv[1], "domain")==0)
1732                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1733                                               MAXIMUM_ALLOWED_ACCESS,
1734                                               &domain_sid, &domain_pol);
1735         else if (StrCaseCmp(argv[1], "builtin")==0)
1736                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1737                                               MAXIMUM_ALLOWED_ACCESS,
1738                                               &global_sid_Builtin, &domain_pol);
1739         else
1740                 return NT_STATUS_OK;
1741
1742         if (!NT_STATUS_IS_OK(result))
1743                 goto done;
1744
1745         /* Look up rids */
1746
1747         num_rids = argc - 2;
1748
1749         if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1750                 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1751                 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1752                 result = NT_STATUS_NO_MEMORY;
1753                 goto done;
1754         }
1755
1756         for (i = 0; i < argc - 2; i++)
1757                 sscanf(argv[i + 2], "%i", &rids[i]);
1758
1759         result = rpccli_samr_lookup_rids(cli, mem_ctx, &domain_pol, num_rids, rids,
1760                                       &num_names, &names, &name_types);
1761
1762         if (!NT_STATUS_IS_OK(result) &&
1763             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1764                 goto done;
1765
1766         /* Display results */
1767
1768         for (i = 0; i < num_names; i++)
1769                 printf("rid 0x%x: %s (%d)\n", rids[i], names[i], name_types[i]);
1770
1771         rpccli_samr_close(cli, mem_ctx, &domain_pol);
1772         rpccli_samr_close(cli, mem_ctx, &connect_pol);
1773  done:
1774         return result;
1775 }
1776
1777 /* Delete domain group */
1778
1779 static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli, 
1780                                          TALLOC_CTX *mem_ctx,
1781                                          int argc, const char **argv) 
1782 {
1783         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1784         POLICY_HND connect_pol, domain_pol, group_pol;
1785         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1786
1787         if ((argc < 2) || (argc > 3)) {
1788                 printf("Usage: %s groupname\n", argv[0]);
1789                 return NT_STATUS_OK;
1790         }
1791         
1792         if (argc > 2)
1793                 sscanf(argv[2], "%x", &access_mask);
1794
1795         /* Get sam policy and domain handles */
1796
1797         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1798                                    &connect_pol);
1799
1800         if (!NT_STATUS_IS_OK(result))
1801                 goto done;
1802
1803         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1804                                       MAXIMUM_ALLOWED_ACCESS,
1805                                       &domain_sid, &domain_pol);
1806
1807         if (!NT_STATUS_IS_OK(result))
1808                 goto done;
1809
1810         /* Get handle on group */
1811
1812         {
1813                 uint32 *group_rids, num_rids, *name_types;
1814                 uint32 flags = 0x000003e8; /* Unknown */
1815
1816                 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1817                                                flags, 1, (const char **)&argv[1],
1818                                                &num_rids, &group_rids,
1819                                                &name_types);
1820
1821                 if (!NT_STATUS_IS_OK(result))
1822                         goto done;
1823
1824                 result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
1825                                                 access_mask,
1826                                                 group_rids[0], &group_pol);
1827
1828                 if (!NT_STATUS_IS_OK(result))
1829                         goto done;
1830         }
1831
1832         /* Delete user */
1833
1834         result = rpccli_samr_delete_dom_group(cli, mem_ctx, &group_pol);
1835
1836         if (!NT_STATUS_IS_OK(result))
1837                 goto done;
1838
1839         /* Display results */
1840
1841         rpccli_samr_close(cli, mem_ctx, &group_pol);
1842         rpccli_samr_close(cli, mem_ctx, &domain_pol);
1843         rpccli_samr_close(cli, mem_ctx, &connect_pol);
1844
1845  done:
1846         return result;
1847 }
1848
1849 /* Delete domain user */
1850
1851 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli, 
1852                                          TALLOC_CTX *mem_ctx,
1853                                          int argc, const char **argv) 
1854 {
1855         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1856         POLICY_HND connect_pol, domain_pol, user_pol;
1857         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1858
1859         if ((argc < 2) || (argc > 3)) {
1860                 printf("Usage: %s username\n", argv[0]);
1861                 return NT_STATUS_OK;
1862         }
1863         
1864         if (argc > 2)
1865                 sscanf(argv[2], "%x", &access_mask);
1866
1867         /* Get sam policy and domain handles */
1868
1869         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
1870                                    &connect_pol);
1871
1872         if (!NT_STATUS_IS_OK(result))
1873                 goto done;
1874
1875         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1876                                       MAXIMUM_ALLOWED_ACCESS,
1877                                       &domain_sid, &domain_pol);
1878
1879         if (!NT_STATUS_IS_OK(result))
1880                 goto done;
1881
1882         /* Get handle on user */
1883
1884         {
1885                 uint32 *user_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, &user_rids,
1891                                                &name_types);
1892
1893                 if (!NT_STATUS_IS_OK(result))
1894                         goto done;
1895
1896                 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1897                                             access_mask,
1898                                             user_rids[0], &user_pol);
1899
1900                 if (!NT_STATUS_IS_OK(result))
1901                         goto done;
1902         }
1903
1904         /* Delete user */
1905
1906         result = rpccli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
1907
1908         if (!NT_STATUS_IS_OK(result))
1909                 goto done;
1910
1911         /* Display results */
1912
1913         rpccli_samr_close(cli, mem_ctx, &user_pol);
1914         rpccli_samr_close(cli, mem_ctx, &domain_pol);
1915         rpccli_samr_close(cli, mem_ctx, &connect_pol);
1916
1917  done:
1918         return result;
1919 }
1920
1921 /**********************************************************************
1922  * Query user security object 
1923  */
1924 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli, 
1925                                     TALLOC_CTX *mem_ctx,
1926                                     int argc, const char **argv) 
1927 {
1928         POLICY_HND connect_pol, domain_pol, user_pol, *pol;
1929         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1930         uint32 sec_info = DACL_SECURITY_INFORMATION;
1931         fstring server;
1932         uint32 user_rid = 0;
1933         TALLOC_CTX *ctx = NULL;
1934         SEC_DESC_BUF *sec_desc_buf=NULL;
1935         bool domain = False;
1936
1937         ctx=talloc_init("cmd_samr_query_sec_obj");
1938         
1939         if ((argc < 1) || (argc > 3)) {
1940                 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
1941                 printf("\tSpecify rid for security on user, -d for security on domain\n");
1942                 talloc_destroy(ctx);
1943                 return NT_STATUS_OK;
1944         }
1945         
1946         if (argc > 1) {
1947                 if (strcmp(argv[1], "-d") == 0)
1948                         domain = True;
1949                 else
1950                         sscanf(argv[1], "%i", &user_rid);
1951         }
1952
1953         if (argc == 3) {
1954                 sec_info = atoi(argv[2]);
1955         }
1956         
1957         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
1958         strupper_m(server);
1959         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1960                                    &connect_pol);
1961
1962         if (!NT_STATUS_IS_OK(result))
1963                 goto done;
1964
1965         if (domain || user_rid)
1966                 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1967                                               MAXIMUM_ALLOWED_ACCESS,
1968                                               &domain_sid, &domain_pol);
1969
1970         if (!NT_STATUS_IS_OK(result))
1971                 goto done;
1972
1973         if (user_rid)
1974                 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1975                                             MAXIMUM_ALLOWED_ACCESS,
1976                                             user_rid, &user_pol);
1977
1978         if (!NT_STATUS_IS_OK(result))
1979                 goto done;
1980
1981         /* Pick which query pol to use */
1982
1983         pol = &connect_pol;
1984
1985         if (domain)
1986                 pol = &domain_pol;
1987
1988         if (user_rid)
1989                 pol = &user_pol;
1990
1991         /* Query SAM security object */
1992
1993         result = rpccli_samr_query_sec_obj(cli, mem_ctx, pol, sec_info, ctx, 
1994                                         &sec_desc_buf);
1995
1996         if (!NT_STATUS_IS_OK(result))
1997                 goto done;
1998
1999         display_sec_desc(sec_desc_buf->sd);
2000
2001         rpccli_samr_close(cli, mem_ctx, &user_pol);
2002         rpccli_samr_close(cli, mem_ctx, &domain_pol);
2003         rpccli_samr_close(cli, mem_ctx, &connect_pol);
2004 done:
2005         talloc_destroy(ctx);
2006         return result;
2007 }
2008
2009 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli, 
2010                                            TALLOC_CTX *mem_ctx,
2011                                            int argc, const char **argv) 
2012 {
2013         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2014         POLICY_HND connect_pol, domain_pol, user_pol;
2015         uint16 min_pwd_length;
2016         uint32 password_properties, unknown1, rid;
2017
2018         if (argc != 2) {
2019                 printf("Usage: %s rid\n", argv[0]);
2020                 return NT_STATUS_OK;
2021         }
2022         
2023         sscanf(argv[1], "%i", &rid);
2024
2025         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
2026                                    &connect_pol);
2027
2028         if (!NT_STATUS_IS_OK(result)) {
2029                 goto done;
2030         }
2031
2032         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
2033                                          MAXIMUM_ALLOWED_ACCESS, &domain_sid, &domain_pol);
2034
2035         if (!NT_STATUS_IS_OK(result)) {
2036                 goto done;
2037         }
2038
2039         result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
2040                                        MAXIMUM_ALLOWED_ACCESS,
2041                                        rid, &user_pol);
2042
2043         if (!NT_STATUS_IS_OK(result)) {
2044                 goto done;
2045         }
2046
2047         result = rpccli_samr_get_usrdom_pwinfo(cli, mem_ctx, &user_pol,
2048                                                &min_pwd_length, &password_properties, 
2049                                                &unknown1) ;
2050
2051         if (NT_STATUS_IS_OK(result)) {
2052                 printf("min_pwd_length: %d\n", min_pwd_length);
2053                 printf("unknown1: %d\n", unknown1);
2054                 display_password_properties(password_properties);
2055         }
2056
2057  done:
2058         rpccli_samr_close(cli, mem_ctx, &user_pol);
2059         rpccli_samr_close(cli, mem_ctx, &domain_pol);
2060         rpccli_samr_close(cli, mem_ctx, &connect_pol);
2061
2062         return result;
2063 }
2064
2065
2066 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli, 
2067                                         TALLOC_CTX *mem_ctx,
2068                                         int argc, const char **argv) 
2069 {
2070         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2071         uint16 min_pwd_length;
2072         uint32 password_properties;
2073
2074         if (argc != 1) {
2075                 printf("Usage: %s\n", argv[0]);
2076                 return NT_STATUS_OK;
2077         }
2078
2079         result = rpccli_samr_get_dom_pwinfo(cli, mem_ctx, &min_pwd_length, &password_properties) ;
2080         
2081         if (NT_STATUS_IS_OK(result)) {
2082                 printf("min_pwd_length: %d\n", min_pwd_length);
2083                 display_password_properties(password_properties);
2084         }
2085
2086         return result;
2087 }
2088
2089 /* Look up domain name */
2090
2091 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli, 
2092                                        TALLOC_CTX *mem_ctx,
2093                                        int argc, const char **argv) 
2094 {
2095         POLICY_HND connect_pol, domain_pol;
2096         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2097         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2098         fstring domain_name,sid_string;
2099         DOM_SID sid;
2100         
2101         if (argc != 2) {
2102                 printf("Usage: %s domain_name\n", argv[0]);
2103                 return NT_STATUS_OK;
2104         }
2105         
2106         sscanf(argv[1], "%s", domain_name);
2107         
2108         result = try_samr_connects(cli, mem_ctx, access_mask, &connect_pol);
2109         
2110         if (!NT_STATUS_IS_OK(result))
2111                 goto done;
2112
2113         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
2114                                       access_mask, &domain_sid, &domain_pol);
2115
2116         if (!NT_STATUS_IS_OK(result))
2117                 goto done;
2118         
2119         result = rpccli_samr_lookup_domain(
2120                 cli, mem_ctx, &connect_pol, domain_name, &sid);
2121
2122         if (NT_STATUS_IS_OK(result)) {
2123                 sid_to_fstring(sid_string,&sid);
2124                 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2125                        domain_name,sid_string);
2126         }
2127
2128         rpccli_samr_close(cli, mem_ctx, &domain_pol);
2129         rpccli_samr_close(cli, mem_ctx, &connect_pol);
2130 done:
2131         return result;
2132 }
2133
2134 /* Change user password */
2135
2136 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli, 
2137                                     TALLOC_CTX *mem_ctx,
2138                                     int argc, const char **argv) 
2139 {
2140         POLICY_HND connect_pol, domain_pol;
2141         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2142         const char *user, *oldpass, *newpass;
2143         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2144
2145         if (argc < 3) {
2146                 printf("Usage: %s username oldpass newpass\n", argv[0]);
2147                 return NT_STATUS_INVALID_PARAMETER;
2148         }
2149
2150         user = argv[1];
2151         oldpass = argv[2];
2152         newpass = argv[3];
2153         
2154         /* Get sam policy handle */
2155
2156         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
2157                                    &connect_pol);
2158
2159         if (!NT_STATUS_IS_OK(result))
2160                 goto done;
2161
2162         /* Get domain policy handle */
2163
2164         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
2165                                       access_mask,
2166                                       &domain_sid, &domain_pol);
2167
2168         if (!NT_STATUS_IS_OK(result))
2169                 goto done;
2170
2171         /* Change user password */
2172         result = rpccli_samr_chgpasswd_user(cli, mem_ctx, user, newpass, oldpass);
2173
2174         if (!NT_STATUS_IS_OK(result))
2175                 goto done;
2176
2177         result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
2178         if (!NT_STATUS_IS_OK(result)) goto done;
2179
2180         result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
2181         if (!NT_STATUS_IS_OK(result)) goto done;
2182
2183  done:
2184         return result;
2185 }
2186
2187
2188 /* Change user password */
2189
2190 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli, 
2191                                     TALLOC_CTX *mem_ctx,
2192                                     int argc, const char **argv) 
2193 {
2194         POLICY_HND connect_pol, domain_pol;
2195         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2196         const char *user, *oldpass, *newpass;
2197         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2198         SAM_UNK_INFO_1 info;
2199         SAMR_CHANGE_REJECT reject;
2200
2201         if (argc < 3) {
2202                 printf("Usage: %s username oldpass newpass\n", argv[0]);
2203                 return NT_STATUS_INVALID_PARAMETER;
2204         }
2205
2206         user = argv[1];
2207         oldpass = argv[2];
2208         newpass = argv[3];
2209         
2210         /* Get sam policy handle */
2211
2212         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
2213                                    &connect_pol);
2214
2215         if (!NT_STATUS_IS_OK(result))
2216                 goto done;
2217
2218         /* Get domain policy handle */
2219
2220         result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
2221                                       access_mask,
2222                                       &domain_sid, &domain_pol);
2223
2224         if (!NT_STATUS_IS_OK(result))
2225                 goto done;
2226
2227         /* Change user password */
2228         result = rpccli_samr_chgpasswd3(cli, mem_ctx, user, newpass, oldpass, &info, &reject);
2229
2230         if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2231         
2232                 display_sam_unk_info_1(&info);
2233
2234                 switch (reject.reject_reason) {
2235                         case SAMR_REJECT_TOO_SHORT:
2236                                 d_printf("SAMR_REJECT_TOO_SHORT\n");
2237                                 break;
2238                         case SAMR_REJECT_IN_HISTORY:
2239                                 d_printf("SAMR_REJECT_IN_HISTORY\n");
2240                                 break;
2241                         case SAMR_REJECT_COMPLEXITY:
2242                                 d_printf("SAMR_REJECT_COMPLEXITY\n");
2243                                 break;
2244                         case SAMR_REJECT_OTHER:
2245                                 d_printf("SAMR_REJECT_OTHER\n");
2246                                 break;
2247                         default:
2248                                 d_printf("unknown reject reason: %d\n", reject.reject_reason);
2249                                 break;
2250                 }
2251         }
2252
2253         if (!NT_STATUS_IS_OK(result))
2254                 goto done;
2255
2256         result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
2257         if (!NT_STATUS_IS_OK(result)) goto done;
2258
2259         result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
2260         if (!NT_STATUS_IS_OK(result)) goto done;
2261
2262  done:
2263         return result;
2264 }
2265
2266 /* List of commands exported by this module */
2267
2268 struct cmd_set samr_commands[] = {
2269
2270         { "SAMR" },
2271
2272         { "queryuser",  RPC_RTYPE_NTSTATUS, cmd_samr_query_user,                NULL, PI_SAMR, NULL,    "Query user info",         "" },
2273         { "querygroup",         RPC_RTYPE_NTSTATUS, cmd_samr_query_group,               NULL, PI_SAMR, NULL,    "Query group info",        "" },
2274         { "queryusergroups",    RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups,  NULL, PI_SAMR, NULL,    "Query user groups",       "" },
2275         { "queryuseraliases",   RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases,         NULL, PI_SAMR, NULL,    "Query user aliases",      "" },
2276         { "querygroupmem",      RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem,    NULL, PI_SAMR, NULL,    "Query group membership",  "" },
2277         { "queryaliasmem",      RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem,    NULL, PI_SAMR, NULL,    "Query alias membership",  "" },
2278         { "deletealias",        RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias,      NULL, PI_SAMR, NULL,    "Delete an alias",  "" },
2279         { "querydispinfo",      RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo,    NULL, PI_SAMR, NULL,    "Query display info",      "" },
2280         { "querydominfo",       RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo,     NULL, PI_SAMR, NULL,    "Query domain info",       "" },
2281         { "enumdomusers",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users,       NULL, PI_SAMR, NULL,  "Enumerate domain users", "" },
2282         { "enumdomgroups",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups,       NULL, PI_SAMR, NULL,        "Enumerate domain groups", "" },
2283         { "enumalsgroups",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups,       NULL, PI_SAMR, NULL,        "Enumerate alias groups",  "" },
2284
2285         { "createdomuser",      RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user,       NULL, PI_SAMR, NULL,        "Create domain user",      "" },
2286         { "createdomgroup",     RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group,      NULL, PI_SAMR, NULL,        "Create domain group",     "" },
2287         { "createdomalias",     RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias,      NULL, PI_SAMR, NULL,        "Create domain alias",     "" },
2288         { "samlookupnames",     RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names,          NULL, PI_SAMR, NULL,        "Look up names",           "" },
2289         { "samlookuprids",      RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids,           NULL, PI_SAMR, NULL,        "Look up names",           "" },
2290         { "deletedomgroup",     RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group,      NULL, PI_SAMR, NULL,        "Delete domain group",     "" },
2291         { "deletedomuser",      RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user,       NULL, PI_SAMR, NULL,        "Delete domain user",      "" },
2292         { "samquerysecobj",     RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj,         NULL, PI_SAMR, NULL, "Query SAMR security object",   "" },
2293         { "getdompwinfo",       RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo,        NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
2294         { "getusrdompwinfo",    RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo,     NULL, PI_SAMR, NULL, "Retrieve user domain password info", "" },
2295
2296         { "lookupdomain",       RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain,         NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },
2297         { "chgpasswd2",         RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2,            NULL, PI_SAMR, NULL, "Change user password", "" },
2298         { "chgpasswd3",         RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3,            NULL, PI_SAMR, NULL, "Change user password", "" },
2299         { NULL }
2300 };