s3/docs: Fix typo.
[Samba.git] / source / rpcclient / cmd_samr.c
blob5523d2ace2b240741292b07a1980871571c13d57
1 /*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
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 Copyright (C) Guenther Deschner 2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "includes.h"
26 #include "rpcclient.h"
28 extern DOM_SID domain_sid;
30 /****************************************************************************
31 display samr_user_info_7 structure
32 ****************************************************************************/
33 static void display_samr_user_info_7(struct samr_UserInfo7 *r)
35 printf("\tUser Name :\t%s\n", r->account_name.string);
38 /****************************************************************************
39 display samr_user_info_9 structure
40 ****************************************************************************/
41 static void display_samr_user_info_9(struct samr_UserInfo9 *r)
43 printf("\tPrimary group RID :\tox%x\n", r->primary_gid);
46 /****************************************************************************
47 display samr_user_info_16 structure
48 ****************************************************************************/
49 static void display_samr_user_info_16(struct samr_UserInfo16 *r)
51 printf("\tAcct Flags :\tox%x\n", r->acct_flags);
54 /****************************************************************************
55 display samr_user_info_20 structure
56 ****************************************************************************/
57 static void display_samr_user_info_20(struct samr_UserInfo20 *r)
59 printf("\tRemote Dial :\n");
60 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
64 /****************************************************************************
65 display samr_user_info_21 structure
66 ****************************************************************************/
67 static void display_samr_user_info_21(struct samr_UserInfo21 *r)
69 printf("\tUser Name :\t%s\n", r->account_name.string);
70 printf("\tFull Name :\t%s\n", r->full_name.string);
71 printf("\tHome Drive :\t%s\n", r->home_directory.string);
72 printf("\tDir Drive :\t%s\n", r->home_drive.string);
73 printf("\tProfile Path:\t%s\n", r->profile_path.string);
74 printf("\tLogon Script:\t%s\n", r->logon_script.string);
75 printf("\tDescription :\t%s\n", r->description.string);
76 printf("\tWorkstations:\t%s\n", r->workstations.string);
77 printf("\tComment :\t%s\n", r->comment.string);
78 printf("\tRemote Dial :\n");
79 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
81 printf("\tLogon Time :\t%s\n",
82 http_timestring(nt_time_to_unix(r->last_logon)));
83 printf("\tLogoff Time :\t%s\n",
84 http_timestring(nt_time_to_unix(r->last_logoff)));
85 printf("\tKickoff Time :\t%s\n",
86 http_timestring(nt_time_to_unix(r->acct_expiry)));
87 printf("\tPassword last set Time :\t%s\n",
88 http_timestring(nt_time_to_unix(r->last_password_change)));
89 printf("\tPassword can change Time :\t%s\n",
90 http_timestring(nt_time_to_unix(r->allow_password_change)));
91 printf("\tPassword must change Time:\t%s\n",
92 http_timestring(nt_time_to_unix(r->force_password_change)));
94 printf("\tunknown_2[0..31]...\n"); /* user passwords? */
96 printf("\tuser_rid :\t0x%x\n" , r->rid); /* User ID */
97 printf("\tgroup_rid:\t0x%x\n" , r->primary_gid); /* Group ID */
98 printf("\tacb_info :\t0x%08x\n", r->acct_flags); /* Account Control Info */
100 printf("\tfields_present:\t0x%08x\n", r->fields_present); /* 0x00ff ffff */
101 printf("\tlogon_divs:\t%d\n", r->logon_hours.units_per_week); /* 0x0000 00a8 which is 168 which is num hrs in a week */
102 printf("\tbad_password_count:\t0x%08x\n", r->bad_password_count);
103 printf("\tlogon_count:\t0x%08x\n", r->logon_count);
105 printf("\tpadding1[0..7]...\n");
107 if (r->logon_hours.bits) {
108 printf("\tlogon_hrs[0..%d]...\n", r->logon_hours.units_per_week/8);
113 static void display_password_properties(uint32_t password_properties)
115 printf("password_properties: 0x%08x\n", password_properties);
117 if (password_properties & DOMAIN_PASSWORD_COMPLEX)
118 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
120 if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
121 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
123 if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
124 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
126 if (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)
127 printf("\tDOMAIN_PASSWORD_LOCKOUT_ADMINS\n");
129 if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
130 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
132 if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
133 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
136 static void display_sam_dom_info_1(struct samr_DomInfo1 *info1)
138 printf("Minimum password length:\t\t\t%d\n",
139 info1->min_password_length);
140 printf("Password uniqueness (remember x passwords):\t%d\n",
141 info1->password_history_length);
142 display_password_properties(info1->password_properties);
143 printf("password expire in:\t\t\t\t%s\n",
144 display_time(info1->max_password_age));
145 printf("Min password age (allow changing in x days):\t%s\n",
146 display_time(info1->min_password_age));
149 static void display_sam_dom_info_2(struct samr_DomInfo2 *info2)
151 printf("Domain:\t\t%s\n", info2->domain_name.string);
152 printf("Server:\t\t%s\n", info2->primary.string);
153 printf("Comment:\t%s\n", info2->comment.string);
155 printf("Total Users:\t%d\n", info2->num_users);
156 printf("Total Groups:\t%d\n", info2->num_groups);
157 printf("Total Aliases:\t%d\n", info2->num_aliases);
159 printf("Sequence No:\t%llu\n", (unsigned long long)info2->sequence_num);
161 printf("Force Logoff:\t%d\n",
162 (int)nt_time_to_unix_abs(&info2->force_logoff_time));
164 printf("Unknown 2:\t0x%x\n", info2->unknown2);
165 printf("Server Role:\t%s\n", server_role_str(info2->role));
166 printf("Unknown 3:\t0x%x\n", info2->unknown3);
169 static void display_sam_dom_info_3(struct samr_DomInfo3 *info3)
171 printf("Force Logoff:\t%d\n",
172 (int)nt_time_to_unix_abs(&info3->force_logoff_time));
175 static void display_sam_dom_info_4(struct samr_DomInfo4 *info4)
177 printf("Comment:\t%s\n", info4->comment.string);
180 static void display_sam_dom_info_5(struct samr_DomInfo5 *info5)
182 printf("Domain:\t\t%s\n", info5->domain_name.string);
185 static void display_sam_dom_info_6(struct samr_DomInfo6 *info6)
187 printf("Server:\t\t%s\n", info6->primary.string);
190 static void display_sam_dom_info_7(struct samr_DomInfo7 *info7)
192 printf("Server Role:\t%s\n", server_role_str(info7->role));
195 static void display_sam_dom_info_8(struct samr_DomInfo8 *info8)
197 printf("Sequence No:\t%llu\n", (unsigned long long)info8->sequence_num);
198 printf("Domain Create Time:\t%s\n",
199 http_timestring(nt_time_to_unix(info8->domain_create_time)));
202 static void display_sam_dom_info_9(struct samr_DomInfo9 *info9)
204 printf("unknown:\t%d (0x%08x)\n", info9->unknown, info9->unknown);
207 static void display_sam_dom_info_12(struct samr_DomInfo12 *info12)
209 printf("Bad password lockout duration: %s\n",
210 display_time(info12->lockout_duration));
211 printf("Reset Lockout after: %s\n",
212 display_time(info12->lockout_window));
213 printf("Lockout after bad attempts: %d\n",
214 info12->lockout_threshold);
217 static void display_sam_dom_info_13(struct samr_DomInfo13 *info13)
219 printf("Sequence No:\t%llu\n", (unsigned long long)info13->sequence_num);
220 printf("Domain Create Time:\t%s\n",
221 http_timestring(nt_time_to_unix(info13->domain_create_time)));
222 printf("Unknown1:\t%d\n", info13->unknown1);
223 printf("Unknown2:\t%d\n", info13->unknown2);
227 static void display_sam_info_1(struct samr_DispEntryGeneral *r)
229 printf("index: 0x%x ", r->idx);
230 printf("RID: 0x%x ", r->rid);
231 printf("acb: 0x%08x ", r->acct_flags);
232 printf("Account: %s\t", r->account_name.string);
233 printf("Name: %s\t", r->full_name.string);
234 printf("Desc: %s\n", r->description.string);
237 static void display_sam_info_2(struct samr_DispEntryFull *r)
239 printf("index: 0x%x ", r->idx);
240 printf("RID: 0x%x ", r->rid);
241 printf("acb: 0x%08x ", r->acct_flags);
242 printf("Account: %s\t", r->account_name.string);
243 printf("Desc: %s\n", r->description.string);
246 static void display_sam_info_3(struct samr_DispEntryFullGroup *r)
248 printf("index: 0x%x ", r->idx);
249 printf("RID: 0x%x ", r->rid);
250 printf("acb: 0x%08x ", r->acct_flags);
251 printf("Account: %s\t", r->account_name.string);
252 printf("Desc: %s\n", r->description.string);
255 static void display_sam_info_4(struct samr_DispEntryAscii *r)
257 printf("index: 0x%x ", r->idx);
258 printf("Account: %s\n", r->account_name.string);
261 static void display_sam_info_5(struct samr_DispEntryAscii *r)
263 printf("index: 0x%x ", r->idx);
264 printf("Account: %s\n", r->account_name.string);
267 /**********************************************************************
268 * Query user information
270 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
271 TALLOC_CTX *mem_ctx,
272 int argc, const char **argv)
274 POLICY_HND connect_pol, domain_pol, user_pol;
275 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
276 uint32 info_level = 21;
277 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
278 union samr_UserInfo *info = NULL;
279 uint32 user_rid = 0;
281 if ((argc < 2) || (argc > 4)) {
282 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
283 return NT_STATUS_OK;
286 sscanf(argv[1], "%i", &user_rid);
288 if (argc > 2)
289 sscanf(argv[2], "%i", &info_level);
291 if (argc > 3)
292 sscanf(argv[3], "%x", &access_mask);
295 result = rpccli_try_samr_connects(cli, mem_ctx,
296 MAXIMUM_ALLOWED_ACCESS,
297 &connect_pol);
299 if (!NT_STATUS_IS_OK(result))
300 goto done;
302 result = rpccli_samr_OpenDomain(cli, mem_ctx,
303 &connect_pol,
304 MAXIMUM_ALLOWED_ACCESS,
305 &domain_sid,
306 &domain_pol);
307 if (!NT_STATUS_IS_OK(result))
308 goto done;
310 result = rpccli_samr_OpenUser(cli, mem_ctx,
311 &domain_pol,
312 access_mask,
313 user_rid,
314 &user_pol);
316 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
317 (user_rid == 0)) {
319 /* Probably this was a user name, try lookupnames */
320 struct samr_Ids rids, types;
321 struct lsa_String lsa_acct_name;
323 init_lsa_String(&lsa_acct_name, argv[1]);
325 result = rpccli_samr_LookupNames(cli, mem_ctx,
326 &domain_pol,
328 &lsa_acct_name,
329 &rids,
330 &types);
332 if (NT_STATUS_IS_OK(result)) {
333 result = rpccli_samr_OpenUser(cli, mem_ctx,
334 &domain_pol,
335 access_mask,
336 rids.ids[0],
337 &user_pol);
342 if (!NT_STATUS_IS_OK(result))
343 goto done;
345 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
346 &user_pol,
347 info_level,
348 &info);
350 if (!NT_STATUS_IS_OK(result))
351 goto done;
353 switch (info_level) {
354 case 7:
355 display_samr_user_info_7(&info->info7);
356 break;
357 case 9:
358 display_samr_user_info_9(&info->info9);
359 break;
360 case 16:
361 display_samr_user_info_16(&info->info16);
362 break;
363 case 20:
364 display_samr_user_info_20(&info->info20);
365 break;
366 case 21:
367 display_samr_user_info_21(&info->info21);
368 break;
369 default:
370 printf("Unsupported infolevel: %d\n", info_level);
371 break;
374 rpccli_samr_Close(cli, mem_ctx, &user_pol);
375 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
376 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
378 done:
379 return result;
382 /****************************************************************************
383 display group info
384 ****************************************************************************/
385 static void display_group_info1(struct samr_GroupInfoAll *info1)
387 printf("\tGroup Name:\t%s\n", info1->name.string);
388 printf("\tDescription:\t%s\n", info1->description.string);
389 printf("\tGroup Attribute:%d\n", info1->attributes);
390 printf("\tNum Members:%d\n", info1->num_members);
393 /****************************************************************************
394 display group info
395 ****************************************************************************/
396 static void display_group_info2(struct lsa_String *info2)
398 printf("\tGroup Description:%s\n", info2->string);
402 /****************************************************************************
403 display group info
404 ****************************************************************************/
405 static void display_group_info3(struct samr_GroupInfoAttributes *info3)
407 printf("\tGroup Attribute:%d\n", info3->attributes);
411 /****************************************************************************
412 display group info
413 ****************************************************************************/
414 static void display_group_info4(struct lsa_String *info4)
416 printf("\tGroup Description:%s\n", info4->string);
419 /****************************************************************************
420 display group info
421 ****************************************************************************/
422 static void display_group_info5(struct samr_GroupInfoAll *info5)
424 printf("\tGroup Name:\t%s\n", info5->name.string);
425 printf("\tDescription:\t%s\n", info5->description.string);
426 printf("\tGroup Attribute:%d\n", info5->attributes);
427 printf("\tNum Members:%d\n", info5->num_members);
430 /****************************************************************************
431 display sam sync structure
432 ****************************************************************************/
433 static void display_group_info(union samr_GroupInfo *info,
434 enum samr_GroupInfoEnum level)
436 switch (level) {
437 case 1:
438 display_group_info1(&info->all);
439 break;
440 case 2:
441 display_group_info2(&info->name);
442 break;
443 case 3:
444 display_group_info3(&info->attributes);
445 break;
446 case 4:
447 display_group_info4(&info->description);
448 break;
449 case 5:
450 display_group_info5(&info->all2);
451 break;
455 /***********************************************************************
456 * Query group information
458 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
459 TALLOC_CTX *mem_ctx,
460 int argc, const char **argv)
462 POLICY_HND connect_pol, domain_pol, group_pol;
463 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
464 enum samr_GroupInfoEnum info_level = GROUPINFOALL;
465 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
466 union samr_GroupInfo *group_info = NULL;
467 uint32 group_rid;
469 if ((argc < 2) || (argc > 4)) {
470 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
471 return NT_STATUS_OK;
474 sscanf(argv[1], "%i", &group_rid);
476 if (argc > 2)
477 info_level = atoi(argv[2]);
479 if (argc > 3)
480 sscanf(argv[3], "%x", &access_mask);
482 result = rpccli_try_samr_connects(cli, mem_ctx,
483 MAXIMUM_ALLOWED_ACCESS,
484 &connect_pol);
486 if (!NT_STATUS_IS_OK(result))
487 goto done;
489 result = rpccli_samr_OpenDomain(cli, mem_ctx,
490 &connect_pol,
491 MAXIMUM_ALLOWED_ACCESS,
492 &domain_sid,
493 &domain_pol);
495 if (!NT_STATUS_IS_OK(result))
496 goto done;
498 result = rpccli_samr_OpenGroup(cli, mem_ctx,
499 &domain_pol,
500 access_mask,
501 group_rid,
502 &group_pol);
504 if (!NT_STATUS_IS_OK(result))
505 goto done;
507 result = rpccli_samr_QueryGroupInfo(cli, mem_ctx,
508 &group_pol,
509 info_level,
510 &group_info);
511 if (!NT_STATUS_IS_OK(result)) {
512 goto done;
515 display_group_info(group_info, info_level);
517 rpccli_samr_Close(cli, mem_ctx, &group_pol);
518 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
519 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
520 done:
521 return result;
524 /* Query groups a user is a member of */
526 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
527 TALLOC_CTX *mem_ctx,
528 int argc, const char **argv)
530 POLICY_HND connect_pol,
531 domain_pol,
532 user_pol;
533 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
534 uint32 user_rid;
535 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
536 int i;
537 struct samr_RidWithAttributeArray *rid_array = NULL;
539 if ((argc < 2) || (argc > 3)) {
540 printf("Usage: %s rid [access mask]\n", argv[0]);
541 return NT_STATUS_OK;
544 sscanf(argv[1], "%i", &user_rid);
546 if (argc > 2)
547 sscanf(argv[2], "%x", &access_mask);
549 result = rpccli_try_samr_connects(cli, mem_ctx,
550 MAXIMUM_ALLOWED_ACCESS,
551 &connect_pol);
553 if (!NT_STATUS_IS_OK(result))
554 goto done;
556 result = rpccli_samr_OpenDomain(cli, mem_ctx,
557 &connect_pol,
558 MAXIMUM_ALLOWED_ACCESS,
559 &domain_sid, &domain_pol);
561 if (!NT_STATUS_IS_OK(result))
562 goto done;
564 result = rpccli_samr_OpenUser(cli, mem_ctx,
565 &domain_pol,
566 access_mask,
567 user_rid,
568 &user_pol);
570 if (!NT_STATUS_IS_OK(result))
571 goto done;
573 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
574 &user_pol,
575 &rid_array);
577 if (!NT_STATUS_IS_OK(result))
578 goto done;
580 for (i = 0; i < rid_array->count; i++) {
581 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
582 rid_array->rids[i].rid,
583 rid_array->rids[i].attributes);
586 rpccli_samr_Close(cli, mem_ctx, &user_pol);
587 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
588 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
589 done:
590 return result;
593 /* Query aliases a user is a member of */
595 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
596 TALLOC_CTX *mem_ctx,
597 int argc, const char **argv)
599 POLICY_HND connect_pol, domain_pol;
600 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
601 DOM_SID *sids;
602 size_t num_sids;
603 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
604 int i;
605 struct lsa_SidArray sid_array;
606 struct samr_Ids alias_rids;
608 if (argc < 3) {
609 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
610 return NT_STATUS_INVALID_PARAMETER;
613 sids = NULL;
614 num_sids = 0;
616 for (i=2; i<argc; i++) {
617 DOM_SID tmp_sid;
618 if (!string_to_sid(&tmp_sid, argv[i])) {
619 printf("%s is not a legal SID\n", argv[i]);
620 return NT_STATUS_INVALID_PARAMETER;
622 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
623 if (!NT_STATUS_IS_OK(result)) {
624 return result;
628 if (num_sids) {
629 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids);
630 if (sid_array.sids == NULL)
631 return NT_STATUS_NO_MEMORY;
632 } else {
633 sid_array.sids = NULL;
636 for (i=0; i<num_sids; i++) {
637 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[i]);
638 if (!sid_array.sids[i].sid) {
639 return NT_STATUS_NO_MEMORY;
643 sid_array.num_sids = num_sids;
645 result = rpccli_try_samr_connects(cli, mem_ctx,
646 MAXIMUM_ALLOWED_ACCESS,
647 &connect_pol);
649 if (!NT_STATUS_IS_OK(result))
650 goto done;
652 if (StrCaseCmp(argv[1], "domain")==0)
653 result = rpccli_samr_OpenDomain(cli, mem_ctx,
654 &connect_pol,
655 access_mask,
656 &domain_sid, &domain_pol);
657 else if (StrCaseCmp(argv[1], "builtin")==0)
658 result = rpccli_samr_OpenDomain(cli, mem_ctx,
659 &connect_pol,
660 access_mask,
661 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
662 &domain_pol);
663 else {
664 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
665 return NT_STATUS_INVALID_PARAMETER;
668 if (!NT_STATUS_IS_OK(result))
669 goto done;
671 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
672 &domain_pol,
673 &sid_array,
674 &alias_rids);
675 if (!NT_STATUS_IS_OK(result))
676 goto done;
678 for (i = 0; i < alias_rids.count; i++) {
679 printf("\tgroup rid:[0x%x]\n", alias_rids.ids[i]);
682 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
683 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
684 done:
685 return result;
688 /* Query members of a group */
690 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
691 TALLOC_CTX *mem_ctx,
692 int argc, const char **argv)
694 POLICY_HND connect_pol, domain_pol, group_pol;
695 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
696 uint32 group_rid;
697 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
698 int i;
699 unsigned int old_timeout;
700 struct samr_RidTypeArray *rids = NULL;
702 if ((argc < 2) || (argc > 3)) {
703 printf("Usage: %s rid [access mask]\n", argv[0]);
704 return NT_STATUS_OK;
707 sscanf(argv[1], "%i", &group_rid);
709 if (argc > 2)
710 sscanf(argv[2], "%x", &access_mask);
712 result = rpccli_try_samr_connects(cli, mem_ctx,
713 MAXIMUM_ALLOWED_ACCESS,
714 &connect_pol);
716 if (!NT_STATUS_IS_OK(result))
717 goto done;
719 result = rpccli_samr_OpenDomain(cli, mem_ctx,
720 &connect_pol,
721 MAXIMUM_ALLOWED_ACCESS,
722 &domain_sid,
723 &domain_pol);
725 if (!NT_STATUS_IS_OK(result))
726 goto done;
728 result = rpccli_samr_OpenGroup(cli, mem_ctx,
729 &domain_pol,
730 access_mask,
731 group_rid,
732 &group_pol);
734 if (!NT_STATUS_IS_OK(result))
735 goto done;
737 /* Make sure to wait for our DC's reply */
738 old_timeout = cli_set_timeout(cli->cli, MAX(cli->cli->timeout,30000)); /* 30 seconds. */
740 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
741 &group_pol,
742 &rids);
744 cli_set_timeout(cli->cli, old_timeout);
746 if (!NT_STATUS_IS_OK(result))
747 goto done;
749 for (i = 0; i < rids->count; i++) {
750 printf("\trid:[0x%x] attr:[0x%x]\n", rids->rids[i],
751 rids->types[i]);
754 rpccli_samr_Close(cli, mem_ctx, &group_pol);
755 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
756 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
757 done:
758 return result;
761 /* Enumerate domain users */
763 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
764 TALLOC_CTX *mem_ctx,
765 int argc, const char **argv)
767 POLICY_HND connect_pol, domain_pol;
768 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
769 uint32 start_idx, size, num_dom_users, i;
770 struct samr_SamArray *dom_users = NULL;
771 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
772 uint32 acb_mask = ACB_NORMAL;
773 bool got_connect_pol = False, got_domain_pol = False;
775 if ((argc < 1) || (argc > 3)) {
776 printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
777 return NT_STATUS_OK;
780 if (argc > 1)
781 sscanf(argv[1], "%x", &access_mask);
783 if (argc > 2)
784 sscanf(argv[2], "%x", &acb_mask);
786 /* Get sam policy handle */
788 result = rpccli_try_samr_connects(cli, mem_ctx,
789 MAXIMUM_ALLOWED_ACCESS,
790 &connect_pol);
792 if (!NT_STATUS_IS_OK(result))
793 goto done;
795 got_connect_pol = True;
797 /* Get domain policy handle */
799 result = rpccli_samr_OpenDomain(cli, mem_ctx,
800 &connect_pol,
801 access_mask,
802 &domain_sid,
803 &domain_pol);
805 if (!NT_STATUS_IS_OK(result))
806 goto done;
808 got_domain_pol = True;
810 /* Enumerate domain users */
812 start_idx = 0;
813 size = 0xffff;
815 do {
816 result = rpccli_samr_EnumDomainUsers(cli, mem_ctx,
817 &domain_pol,
818 &start_idx,
819 acb_mask,
820 &dom_users,
821 size,
822 &num_dom_users);
824 if (NT_STATUS_IS_OK(result) ||
825 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
827 for (i = 0; i < num_dom_users; i++)
828 printf("user:[%s] rid:[0x%x]\n",
829 dom_users->entries[i].name.string,
830 dom_users->entries[i].idx);
833 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
835 done:
836 if (got_domain_pol)
837 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
839 if (got_connect_pol)
840 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
842 return result;
845 /* Enumerate domain groups */
847 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
848 TALLOC_CTX *mem_ctx,
849 int argc, const char **argv)
851 POLICY_HND connect_pol, domain_pol;
852 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
853 uint32 start_idx, size, num_dom_groups, i;
854 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
855 struct samr_SamArray *dom_groups = NULL;
856 bool got_connect_pol = False, got_domain_pol = False;
858 if ((argc < 1) || (argc > 2)) {
859 printf("Usage: %s [access_mask]\n", argv[0]);
860 return NT_STATUS_OK;
863 if (argc > 1)
864 sscanf(argv[1], "%x", &access_mask);
866 /* Get sam policy handle */
868 result = rpccli_try_samr_connects(cli, mem_ctx,
869 MAXIMUM_ALLOWED_ACCESS,
870 &connect_pol);
872 if (!NT_STATUS_IS_OK(result))
873 goto done;
875 got_connect_pol = True;
877 /* Get domain policy handle */
879 result = rpccli_samr_OpenDomain(cli, mem_ctx,
880 &connect_pol,
881 access_mask,
882 &domain_sid,
883 &domain_pol);
885 if (!NT_STATUS_IS_OK(result))
886 goto done;
888 got_domain_pol = True;
890 /* Enumerate domain groups */
892 start_idx = 0;
893 size = 0xffff;
895 do {
896 result = rpccli_samr_EnumDomainGroups(cli, mem_ctx,
897 &domain_pol,
898 &start_idx,
899 &dom_groups,
900 size,
901 &num_dom_groups);
902 if (NT_STATUS_IS_OK(result) ||
903 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
905 for (i = 0; i < num_dom_groups; i++)
906 printf("group:[%s] rid:[0x%x]\n",
907 dom_groups->entries[i].name.string,
908 dom_groups->entries[i].idx);
911 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
913 done:
914 if (got_domain_pol)
915 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
917 if (got_connect_pol)
918 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
920 return result;
923 /* Enumerate alias groups */
925 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
926 TALLOC_CTX *mem_ctx,
927 int argc, const char **argv)
929 POLICY_HND connect_pol, domain_pol;
930 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
931 uint32 start_idx, size, num_als_groups, i;
932 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
933 struct samr_SamArray *als_groups = NULL;
934 bool got_connect_pol = False, got_domain_pol = False;
936 if ((argc < 2) || (argc > 3)) {
937 printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
938 return NT_STATUS_OK;
941 if (argc > 2)
942 sscanf(argv[2], "%x", &access_mask);
944 /* Get sam policy handle */
946 result = rpccli_try_samr_connects(cli, mem_ctx,
947 MAXIMUM_ALLOWED_ACCESS,
948 &connect_pol);
950 if (!NT_STATUS_IS_OK(result))
951 goto done;
953 got_connect_pol = True;
955 /* Get domain policy handle */
957 if (StrCaseCmp(argv[1], "domain")==0)
958 result = rpccli_samr_OpenDomain(cli, mem_ctx,
959 &connect_pol,
960 access_mask,
961 &domain_sid,
962 &domain_pol);
963 else if (StrCaseCmp(argv[1], "builtin")==0)
964 result = rpccli_samr_OpenDomain(cli, mem_ctx,
965 &connect_pol,
966 access_mask,
967 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
968 &domain_pol);
969 else
970 return NT_STATUS_OK;
972 if (!NT_STATUS_IS_OK(result))
973 goto done;
975 got_domain_pol = True;
977 /* Enumerate alias groups */
979 start_idx = 0;
980 size = 0xffff; /* Number of groups to retrieve */
982 do {
983 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx,
984 &domain_pol,
985 &start_idx,
986 &als_groups,
987 size,
988 &num_als_groups);
990 if (NT_STATUS_IS_OK(result) ||
991 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
993 for (i = 0; i < num_als_groups; i++)
994 printf("group:[%s] rid:[0x%x]\n",
995 als_groups->entries[i].name.string,
996 als_groups->entries[i].idx);
998 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1000 done:
1001 if (got_domain_pol)
1002 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1004 if (got_connect_pol)
1005 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1007 return result;
1010 /* Enumerate domains */
1012 static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
1013 TALLOC_CTX *mem_ctx,
1014 int argc, const char **argv)
1016 POLICY_HND connect_pol;
1017 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1018 uint32 start_idx, size, num_entries, i;
1019 uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1020 bool got_connect_pol = false;
1021 struct samr_SamArray *sam = NULL;
1023 if ((argc < 1) || (argc > 2)) {
1024 printf("Usage: %s [access mask]\n", argv[0]);
1025 return NT_STATUS_OK;
1028 if (argc > 1) {
1029 sscanf(argv[1], "%x", &access_mask);
1032 /* Get sam policy handle */
1034 result = rpccli_try_samr_connects(cli, mem_ctx,
1035 access_mask,
1036 &connect_pol);
1038 if (!NT_STATUS_IS_OK(result)) {
1039 goto done;
1042 got_connect_pol = true;
1044 /* Enumerate alias groups */
1046 start_idx = 0;
1047 size = 0xffff;
1049 do {
1050 result = rpccli_samr_EnumDomains(cli, mem_ctx,
1051 &connect_pol,
1052 &start_idx,
1053 &sam,
1054 size,
1055 &num_entries);
1057 if (NT_STATUS_IS_OK(result) ||
1058 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1060 for (i = 0; i < num_entries; i++)
1061 printf("name:[%s] idx:[0x%x]\n",
1062 sam->entries[i].name.string,
1063 sam->entries[i].idx);
1065 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1067 done:
1068 if (got_connect_pol) {
1069 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1072 return result;
1076 /* Query alias membership */
1078 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1079 TALLOC_CTX *mem_ctx,
1080 int argc, const char **argv)
1082 POLICY_HND connect_pol, domain_pol, alias_pol;
1083 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1084 uint32 alias_rid, i;
1085 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1086 struct lsa_SidArray sid_array;
1088 if ((argc < 3) || (argc > 4)) {
1089 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1090 return NT_STATUS_OK;
1093 sscanf(argv[2], "%i", &alias_rid);
1095 if (argc > 3)
1096 sscanf(argv[3], "%x", &access_mask);
1098 /* Open SAMR handle */
1100 result = rpccli_try_samr_connects(cli, mem_ctx,
1101 MAXIMUM_ALLOWED_ACCESS,
1102 &connect_pol);
1104 if (!NT_STATUS_IS_OK(result))
1105 goto done;
1107 /* Open handle on domain */
1109 if (StrCaseCmp(argv[1], "domain")==0)
1110 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1111 &connect_pol,
1112 MAXIMUM_ALLOWED_ACCESS,
1113 &domain_sid,
1114 &domain_pol);
1115 else if (StrCaseCmp(argv[1], "builtin")==0)
1116 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1117 &connect_pol,
1118 MAXIMUM_ALLOWED_ACCESS,
1119 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1120 &domain_pol);
1121 else
1122 return NT_STATUS_OK;
1124 if (!NT_STATUS_IS_OK(result))
1125 goto done;
1127 /* Open handle on alias */
1129 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1130 &domain_pol,
1131 access_mask,
1132 alias_rid,
1133 &alias_pol);
1134 if (!NT_STATUS_IS_OK(result))
1135 goto done;
1137 result = rpccli_samr_GetMembersInAlias(cli, mem_ctx,
1138 &alias_pol,
1139 &sid_array);
1141 if (!NT_STATUS_IS_OK(result))
1142 goto done;
1144 for (i = 0; i < sid_array.num_sids; i++) {
1145 fstring sid_str;
1147 sid_to_fstring(sid_str, sid_array.sids[i].sid);
1148 printf("\tsid:[%s]\n", sid_str);
1151 rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1152 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1153 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1154 done:
1155 return result;
1158 /* Query alias info */
1160 static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
1161 TALLOC_CTX *mem_ctx,
1162 int argc, const char **argv)
1164 POLICY_HND connect_pol, domain_pol, alias_pol;
1165 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1166 uint32_t alias_rid;
1167 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1168 union samr_AliasInfo *info = NULL;
1169 enum samr_AliasInfoEnum level = ALIASINFOALL;
1171 if ((argc < 3) || (argc > 4)) {
1172 printf("Usage: %s builtin|domain rid [level] [access mask]\n",
1173 argv[0]);
1174 return NT_STATUS_OK;
1177 sscanf(argv[2], "%i", &alias_rid);
1179 if (argc > 2) {
1180 level = atoi(argv[3]);
1183 if (argc > 3) {
1184 sscanf(argv[4], "%x", &access_mask);
1187 /* Open SAMR handle */
1189 result = rpccli_try_samr_connects(cli, mem_ctx,
1190 SEC_FLAG_MAXIMUM_ALLOWED,
1191 &connect_pol);
1193 if (!NT_STATUS_IS_OK(result)) {
1194 goto done;
1197 /* Open handle on domain */
1199 if (strequal(argv[1], "domain")) {
1201 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1202 &connect_pol,
1203 SEC_FLAG_MAXIMUM_ALLOWED,
1204 &domain_sid,
1205 &domain_pol);
1207 } else if (strequal(argv[1], "builtin")) {
1209 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1210 &connect_pol,
1211 SEC_FLAG_MAXIMUM_ALLOWED,
1212 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1213 &domain_pol);
1215 } else {
1216 return NT_STATUS_OK;
1219 if (!NT_STATUS_IS_OK(result)) {
1220 goto done;
1223 /* Open handle on alias */
1225 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1226 &domain_pol,
1227 access_mask,
1228 alias_rid,
1229 &alias_pol);
1230 if (!NT_STATUS_IS_OK(result)) {
1231 goto done;
1234 result = rpccli_samr_QueryAliasInfo(cli, mem_ctx,
1235 &alias_pol,
1236 level,
1237 &info);
1239 if (!NT_STATUS_IS_OK(result)) {
1240 goto done;
1243 switch (level) {
1244 case ALIASINFOALL:
1245 printf("Name: %s\n", info->all.name.string);
1246 printf("Description: %s\n", info->all.description.string);
1247 printf("Num Members: %d\n", info->all.num_members);
1248 break;
1249 case ALIASINFONAME:
1250 printf("Name: %s\n", info->name.string);
1251 break;
1252 case ALIASINFODESCRIPTION:
1253 printf("Description: %s\n", info->description.string);
1254 break;
1255 default:
1256 break;
1259 rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1260 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1261 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1262 done:
1263 return result;
1267 /* Query delete an alias membership */
1269 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1270 TALLOC_CTX *mem_ctx,
1271 int argc, const char **argv)
1273 POLICY_HND connect_pol, domain_pol, alias_pol;
1274 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1275 uint32 alias_rid;
1276 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1278 if (argc != 3) {
1279 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1280 return NT_STATUS_OK;
1283 alias_rid = strtoul(argv[2], NULL, 10);
1285 /* Open SAMR handle */
1287 result = rpccli_try_samr_connects(cli, mem_ctx,
1288 MAXIMUM_ALLOWED_ACCESS,
1289 &connect_pol);
1291 if (!NT_STATUS_IS_OK(result))
1292 goto done;
1294 /* Open handle on domain */
1296 if (StrCaseCmp(argv[1], "domain")==0)
1297 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1298 &connect_pol,
1299 MAXIMUM_ALLOWED_ACCESS,
1300 &domain_sid,
1301 &domain_pol);
1302 else if (StrCaseCmp(argv[1], "builtin")==0)
1303 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1304 &connect_pol,
1305 MAXIMUM_ALLOWED_ACCESS,
1306 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1307 &domain_pol);
1308 else
1309 return NT_STATUS_INVALID_PARAMETER;
1311 if (!NT_STATUS_IS_OK(result))
1312 goto done;
1314 /* Open handle on alias */
1316 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1317 &domain_pol,
1318 access_mask,
1319 alias_rid,
1320 &alias_pol);
1321 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1322 /* Probably this was a user name, try lookupnames */
1323 struct samr_Ids rids, types;
1324 struct lsa_String lsa_acct_name;
1326 init_lsa_String(&lsa_acct_name, argv[2]);
1328 result = rpccli_samr_LookupNames(cli, mem_ctx,
1329 &domain_pol,
1331 &lsa_acct_name,
1332 &rids,
1333 &types);
1335 if (NT_STATUS_IS_OK(result)) {
1336 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1337 &domain_pol,
1338 access_mask,
1339 rids.ids[0],
1340 &alias_pol);
1344 result = rpccli_samr_DeleteDomAlias(cli, mem_ctx,
1345 &alias_pol);
1347 if (!NT_STATUS_IS_OK(result))
1348 goto done;
1350 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1351 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1352 done:
1353 return result;
1356 /* Query display info */
1358 static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli,
1359 TALLOC_CTX *mem_ctx,
1360 int argc, const char **argv,
1361 uint32_t opcode)
1363 POLICY_HND connect_pol, domain_pol;
1364 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1365 uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
1366 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1367 uint32 info_level = 1;
1368 union samr_DispInfo info;
1369 int loop_count = 0;
1370 bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1371 uint32_t total_size, returned_size;
1373 if (argc > 6) {
1374 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1375 return NT_STATUS_OK;
1378 if (argc >= 2)
1379 sscanf(argv[1], "%i", &info_level);
1381 if (argc >= 3)
1382 sscanf(argv[2], "%i", &start_idx);
1384 if (argc >= 4) {
1385 sscanf(argv[3], "%i", &max_entries);
1386 got_params = True;
1389 if (argc >= 5) {
1390 sscanf(argv[4], "%i", &max_size);
1391 got_params = True;
1394 if (argc >= 6)
1395 sscanf(argv[5], "%x", &access_mask);
1397 /* Get sam policy handle */
1399 result = rpccli_try_samr_connects(cli, mem_ctx,
1400 MAXIMUM_ALLOWED_ACCESS,
1401 &connect_pol);
1403 if (!NT_STATUS_IS_OK(result))
1404 goto done;
1406 /* Get domain policy handle */
1408 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1409 &connect_pol,
1410 access_mask,
1411 &domain_sid,
1412 &domain_pol);
1414 if (!NT_STATUS_IS_OK(result))
1415 goto done;
1417 /* Query display info */
1419 do {
1421 if (!got_params)
1422 get_query_dispinfo_params(
1423 loop_count, &max_entries, &max_size);
1425 switch (opcode) {
1426 case NDR_SAMR_QUERYDISPLAYINFO:
1427 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
1428 &domain_pol,
1429 info_level,
1430 start_idx,
1431 max_entries,
1432 max_size,
1433 &total_size,
1434 &returned_size,
1435 &info);
1436 break;
1437 case NDR_SAMR_QUERYDISPLAYINFO2:
1438 result = rpccli_samr_QueryDisplayInfo2(cli, mem_ctx,
1439 &domain_pol,
1440 info_level,
1441 start_idx,
1442 max_entries,
1443 max_size,
1444 &total_size,
1445 &returned_size,
1446 &info);
1448 break;
1449 case NDR_SAMR_QUERYDISPLAYINFO3:
1450 result = rpccli_samr_QueryDisplayInfo3(cli, mem_ctx,
1451 &domain_pol,
1452 info_level,
1453 start_idx,
1454 max_entries,
1455 max_size,
1456 &total_size,
1457 &returned_size,
1458 &info);
1460 break;
1461 default:
1462 return NT_STATUS_INVALID_PARAMETER;
1465 if (!NT_STATUS_IS_OK(result) &&
1466 !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
1467 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1468 break;
1471 loop_count++;
1473 switch (info_level) {
1474 case 1:
1475 num_entries = info.info1.count;
1476 break;
1477 case 2:
1478 num_entries = info.info2.count;
1479 break;
1480 case 3:
1481 num_entries = info.info3.count;
1482 break;
1483 case 4:
1484 num_entries = info.info4.count;
1485 break;
1486 case 5:
1487 num_entries = info.info5.count;
1488 break;
1489 default:
1490 break;
1493 start_idx += num_entries;
1495 if (num_entries == 0)
1496 break;
1498 for (i = 0; i < num_entries; i++) {
1499 switch (info_level) {
1500 case 1:
1501 display_sam_info_1(&info.info1.entries[i]);
1502 break;
1503 case 2:
1504 display_sam_info_2(&info.info2.entries[i]);
1505 break;
1506 case 3:
1507 display_sam_info_3(&info.info3.entries[i]);
1508 break;
1509 case 4:
1510 display_sam_info_4(&info.info4.entries[i]);
1511 break;
1512 case 5:
1513 display_sam_info_5(&info.info5.entries[i]);
1514 break;
1517 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1519 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1520 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1521 done:
1522 return result;
1525 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1526 TALLOC_CTX *mem_ctx,
1527 int argc, const char **argv)
1529 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1530 NDR_SAMR_QUERYDISPLAYINFO);
1533 static NTSTATUS cmd_samr_query_dispinfo2(struct rpc_pipe_client *cli,
1534 TALLOC_CTX *mem_ctx,
1535 int argc, const char **argv)
1537 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1538 NDR_SAMR_QUERYDISPLAYINFO2);
1541 static NTSTATUS cmd_samr_query_dispinfo3(struct rpc_pipe_client *cli,
1542 TALLOC_CTX *mem_ctx,
1543 int argc, const char **argv)
1545 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1546 NDR_SAMR_QUERYDISPLAYINFO3);
1549 /* Query domain info */
1551 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1552 TALLOC_CTX *mem_ctx,
1553 int argc, const char **argv)
1555 POLICY_HND connect_pol, domain_pol;
1556 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1557 uint32 switch_level = 2;
1558 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1559 union samr_DomainInfo *info = NULL;
1561 if (argc > 3) {
1562 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1563 return NT_STATUS_OK;
1566 if (argc > 1)
1567 sscanf(argv[1], "%i", &switch_level);
1569 if (argc > 2)
1570 sscanf(argv[2], "%x", &access_mask);
1572 /* Get sam policy handle */
1574 result = rpccli_try_samr_connects(cli, mem_ctx,
1575 MAXIMUM_ALLOWED_ACCESS,
1576 &connect_pol);
1578 if (!NT_STATUS_IS_OK(result))
1579 goto done;
1581 /* Get domain policy handle */
1583 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1584 &connect_pol,
1585 access_mask,
1586 &domain_sid,
1587 &domain_pol);
1589 if (!NT_STATUS_IS_OK(result))
1590 goto done;
1592 /* Query domain info */
1594 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1595 &domain_pol,
1596 switch_level,
1597 &info);
1599 if (!NT_STATUS_IS_OK(result))
1600 goto done;
1602 /* Display domain info */
1604 switch (switch_level) {
1605 case 1:
1606 display_sam_dom_info_1(&info->info1);
1607 break;
1608 case 2:
1609 display_sam_dom_info_2(&info->info2);
1610 break;
1611 case 3:
1612 display_sam_dom_info_3(&info->info3);
1613 break;
1614 case 4:
1615 display_sam_dom_info_4(&info->info4);
1616 break;
1617 case 5:
1618 display_sam_dom_info_5(&info->info5);
1619 break;
1620 case 6:
1621 display_sam_dom_info_6(&info->info6);
1622 break;
1623 case 7:
1624 display_sam_dom_info_7(&info->info7);
1625 break;
1626 case 8:
1627 display_sam_dom_info_8(&info->info8);
1628 break;
1629 case 9:
1630 display_sam_dom_info_9(&info->info9);
1631 break;
1632 case 12:
1633 display_sam_dom_info_12(&info->info12);
1634 break;
1635 case 13:
1636 display_sam_dom_info_13(&info->info13);
1637 break;
1639 default:
1640 printf("cannot display domain info for switch value %d\n",
1641 switch_level);
1642 break;
1645 done:
1647 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1648 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1649 return result;
1652 /* Create domain user */
1654 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1655 TALLOC_CTX *mem_ctx,
1656 int argc, const char **argv)
1658 POLICY_HND connect_pol, domain_pol, user_pol;
1659 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1660 struct lsa_String acct_name;
1661 uint32 acb_info;
1662 uint32 acct_flags, user_rid;
1663 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1664 uint32_t access_granted = 0;
1666 if ((argc < 2) || (argc > 3)) {
1667 printf("Usage: %s username [access mask]\n", argv[0]);
1668 return NT_STATUS_OK;
1671 init_lsa_String(&acct_name, argv[1]);
1673 if (argc > 2)
1674 sscanf(argv[2], "%x", &access_mask);
1676 /* Get sam policy handle */
1678 result = rpccli_try_samr_connects(cli, mem_ctx,
1679 MAXIMUM_ALLOWED_ACCESS,
1680 &connect_pol);
1682 if (!NT_STATUS_IS_OK(result))
1683 goto done;
1685 /* Get domain policy handle */
1687 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1688 &connect_pol,
1689 access_mask,
1690 &domain_sid,
1691 &domain_pol);
1693 if (!NT_STATUS_IS_OK(result))
1694 goto done;
1696 /* Create domain user */
1698 acb_info = ACB_NORMAL;
1699 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1700 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1701 SAMR_USER_ACCESS_SET_PASSWORD |
1702 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1703 SAMR_USER_ACCESS_SET_ATTRIBUTES;
1705 result = rpccli_samr_CreateUser2(cli, mem_ctx,
1706 &domain_pol,
1707 &acct_name,
1708 acb_info,
1709 acct_flags,
1710 &user_pol,
1711 &access_granted,
1712 &user_rid);
1714 if (!NT_STATUS_IS_OK(result))
1715 goto done;
1717 result = rpccli_samr_Close(cli, mem_ctx, &user_pol);
1718 if (!NT_STATUS_IS_OK(result)) goto done;
1720 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1721 if (!NT_STATUS_IS_OK(result)) goto done;
1723 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1724 if (!NT_STATUS_IS_OK(result)) goto done;
1726 done:
1727 return result;
1730 /* Create domain group */
1732 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1733 TALLOC_CTX *mem_ctx,
1734 int argc, const char **argv)
1736 POLICY_HND connect_pol, domain_pol, group_pol;
1737 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1738 struct lsa_String grp_name;
1739 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1740 uint32_t rid = 0;
1742 if ((argc < 2) || (argc > 3)) {
1743 printf("Usage: %s groupname [access mask]\n", argv[0]);
1744 return NT_STATUS_OK;
1747 init_lsa_String(&grp_name, argv[1]);
1749 if (argc > 2)
1750 sscanf(argv[2], "%x", &access_mask);
1752 /* Get sam policy handle */
1754 result = rpccli_try_samr_connects(cli, mem_ctx,
1755 MAXIMUM_ALLOWED_ACCESS,
1756 &connect_pol);
1758 if (!NT_STATUS_IS_OK(result))
1759 goto done;
1761 /* Get domain policy handle */
1763 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1764 &connect_pol,
1765 access_mask,
1766 &domain_sid,
1767 &domain_pol);
1769 if (!NT_STATUS_IS_OK(result))
1770 goto done;
1772 /* Create domain user */
1773 result = rpccli_samr_CreateDomainGroup(cli, mem_ctx,
1774 &domain_pol,
1775 &grp_name,
1776 MAXIMUM_ALLOWED_ACCESS,
1777 &group_pol,
1778 &rid);
1780 if (!NT_STATUS_IS_OK(result))
1781 goto done;
1783 result = rpccli_samr_Close(cli, mem_ctx, &group_pol);
1784 if (!NT_STATUS_IS_OK(result)) goto done;
1786 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1787 if (!NT_STATUS_IS_OK(result)) goto done;
1789 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1790 if (!NT_STATUS_IS_OK(result)) goto done;
1792 done:
1793 return result;
1796 /* Create domain alias */
1798 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1799 TALLOC_CTX *mem_ctx,
1800 int argc, const char **argv)
1802 POLICY_HND connect_pol, domain_pol, alias_pol;
1803 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1804 struct lsa_String alias_name;
1805 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1806 uint32_t rid = 0;
1808 if ((argc < 2) || (argc > 3)) {
1809 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1810 return NT_STATUS_OK;
1813 init_lsa_String(&alias_name, argv[1]);
1815 if (argc > 2)
1816 sscanf(argv[2], "%x", &access_mask);
1818 /* Get sam policy handle */
1820 result = rpccli_try_samr_connects(cli, mem_ctx,
1821 MAXIMUM_ALLOWED_ACCESS,
1822 &connect_pol);
1824 if (!NT_STATUS_IS_OK(result))
1825 goto done;
1827 /* Get domain policy handle */
1829 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1830 &connect_pol,
1831 access_mask,
1832 &domain_sid,
1833 &domain_pol);
1835 if (!NT_STATUS_IS_OK(result))
1836 goto done;
1838 /* Create domain user */
1840 result = rpccli_samr_CreateDomAlias(cli, mem_ctx,
1841 &domain_pol,
1842 &alias_name,
1843 MAXIMUM_ALLOWED_ACCESS,
1844 &alias_pol,
1845 &rid);
1847 if (!NT_STATUS_IS_OK(result))
1848 goto done;
1850 result = rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1851 if (!NT_STATUS_IS_OK(result)) goto done;
1853 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1854 if (!NT_STATUS_IS_OK(result)) goto done;
1856 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1857 if (!NT_STATUS_IS_OK(result)) goto done;
1859 done:
1860 return result;
1863 /* Lookup sam names */
1865 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
1866 TALLOC_CTX *mem_ctx,
1867 int argc, const char **argv)
1869 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1870 POLICY_HND connect_pol, domain_pol;
1871 uint32 num_names;
1872 struct samr_Ids rids, name_types;
1873 int i;
1874 struct lsa_String *names = NULL;;
1876 if (argc < 3) {
1877 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1878 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1879 printf("or check on the builtin SID: S-1-5-32\n");
1880 return NT_STATUS_OK;
1883 /* Get sam policy and domain handles */
1885 result = rpccli_try_samr_connects(cli, mem_ctx,
1886 MAXIMUM_ALLOWED_ACCESS,
1887 &connect_pol);
1889 if (!NT_STATUS_IS_OK(result))
1890 goto done;
1892 if (StrCaseCmp(argv[1], "domain")==0)
1893 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1894 &connect_pol,
1895 MAXIMUM_ALLOWED_ACCESS,
1896 &domain_sid,
1897 &domain_pol);
1898 else if (StrCaseCmp(argv[1], "builtin")==0)
1899 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1900 &connect_pol,
1901 MAXIMUM_ALLOWED_ACCESS,
1902 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1903 &domain_pol);
1904 else
1905 return NT_STATUS_OK;
1907 if (!NT_STATUS_IS_OK(result))
1908 goto done;
1910 /* Look up names */
1912 num_names = argc - 2;
1914 if ((names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names)) == NULL) {
1915 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1916 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1917 result = NT_STATUS_NO_MEMORY;
1918 goto done;
1921 for (i = 0; i < num_names; i++) {
1922 init_lsa_String(&names[i], argv[i + 2]);
1925 result = rpccli_samr_LookupNames(cli, mem_ctx,
1926 &domain_pol,
1927 num_names,
1928 names,
1929 &rids,
1930 &name_types);
1932 if (!NT_STATUS_IS_OK(result))
1933 goto done;
1935 /* Display results */
1937 for (i = 0; i < num_names; i++)
1938 printf("name %s: 0x%x (%d)\n", names[i].string, rids.ids[i],
1939 name_types.ids[i]);
1941 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1942 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1943 done:
1944 return result;
1947 /* Lookup sam rids */
1949 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
1950 TALLOC_CTX *mem_ctx,
1951 int argc, const char **argv)
1953 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1954 POLICY_HND connect_pol, domain_pol;
1955 uint32_t num_rids, *rids;
1956 struct lsa_Strings names;
1957 struct samr_Ids types;
1959 int i;
1961 if (argc < 3) {
1962 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1963 return NT_STATUS_OK;
1966 /* Get sam policy and domain handles */
1968 result = rpccli_try_samr_connects(cli, mem_ctx,
1969 MAXIMUM_ALLOWED_ACCESS,
1970 &connect_pol);
1972 if (!NT_STATUS_IS_OK(result))
1973 goto done;
1975 if (StrCaseCmp(argv[1], "domain")==0)
1976 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1977 &connect_pol,
1978 MAXIMUM_ALLOWED_ACCESS,
1979 &domain_sid,
1980 &domain_pol);
1981 else if (StrCaseCmp(argv[1], "builtin")==0)
1982 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1983 &connect_pol,
1984 MAXIMUM_ALLOWED_ACCESS,
1985 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1986 &domain_pol);
1987 else
1988 return NT_STATUS_OK;
1990 if (!NT_STATUS_IS_OK(result))
1991 goto done;
1993 /* Look up rids */
1995 num_rids = argc - 2;
1997 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1998 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1999 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2000 result = NT_STATUS_NO_MEMORY;
2001 goto done;
2004 for (i = 0; i < argc - 2; i++)
2005 sscanf(argv[i + 2], "%i", &rids[i]);
2007 result = rpccli_samr_LookupRids(cli, mem_ctx,
2008 &domain_pol,
2009 num_rids,
2010 rids,
2011 &names,
2012 &types);
2014 if (!NT_STATUS_IS_OK(result) &&
2015 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
2016 goto done;
2018 /* Display results */
2020 for (i = 0; i < num_rids; i++) {
2021 printf("rid 0x%x: %s (%d)\n",
2022 rids[i], names.names[i].string, types.ids[i]);
2025 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2026 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2027 done:
2028 return result;
2031 /* Delete domain group */
2033 static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
2034 TALLOC_CTX *mem_ctx,
2035 int argc, const char **argv)
2037 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2038 POLICY_HND connect_pol, domain_pol, group_pol;
2039 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2041 if ((argc < 2) || (argc > 3)) {
2042 printf("Usage: %s groupname\n", argv[0]);
2043 return NT_STATUS_OK;
2046 if (argc > 2)
2047 sscanf(argv[2], "%x", &access_mask);
2049 /* Get sam policy and domain handles */
2051 result = rpccli_try_samr_connects(cli, mem_ctx,
2052 MAXIMUM_ALLOWED_ACCESS,
2053 &connect_pol);
2055 if (!NT_STATUS_IS_OK(result))
2056 goto done;
2058 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2059 &connect_pol,
2060 MAXIMUM_ALLOWED_ACCESS,
2061 &domain_sid,
2062 &domain_pol);
2064 if (!NT_STATUS_IS_OK(result))
2065 goto done;
2067 /* Get handle on group */
2070 struct samr_Ids group_rids, name_types;
2071 struct lsa_String lsa_acct_name;
2073 init_lsa_String(&lsa_acct_name, argv[1]);
2075 result = rpccli_samr_LookupNames(cli, mem_ctx,
2076 &domain_pol,
2078 &lsa_acct_name,
2079 &group_rids,
2080 &name_types);
2081 if (!NT_STATUS_IS_OK(result))
2082 goto done;
2084 result = rpccli_samr_OpenGroup(cli, mem_ctx,
2085 &domain_pol,
2086 access_mask,
2087 group_rids.ids[0],
2088 &group_pol);
2090 if (!NT_STATUS_IS_OK(result))
2091 goto done;
2094 /* Delete group */
2096 result = rpccli_samr_DeleteDomainGroup(cli, mem_ctx,
2097 &group_pol);
2099 if (!NT_STATUS_IS_OK(result))
2100 goto done;
2102 /* Display results */
2104 rpccli_samr_Close(cli, mem_ctx, &group_pol);
2105 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2106 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2108 done:
2109 return result;
2112 /* Delete domain user */
2114 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
2115 TALLOC_CTX *mem_ctx,
2116 int argc, const char **argv)
2118 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2119 POLICY_HND connect_pol, domain_pol, user_pol;
2120 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2122 if ((argc < 2) || (argc > 3)) {
2123 printf("Usage: %s username\n", argv[0]);
2124 return NT_STATUS_OK;
2127 if (argc > 2)
2128 sscanf(argv[2], "%x", &access_mask);
2130 /* Get sam policy and domain handles */
2132 result = rpccli_try_samr_connects(cli, mem_ctx,
2133 MAXIMUM_ALLOWED_ACCESS,
2134 &connect_pol);
2136 if (!NT_STATUS_IS_OK(result))
2137 goto done;
2139 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2140 &connect_pol,
2141 MAXIMUM_ALLOWED_ACCESS,
2142 &domain_sid,
2143 &domain_pol);
2145 if (!NT_STATUS_IS_OK(result))
2146 goto done;
2148 /* Get handle on user */
2151 struct samr_Ids user_rids, name_types;
2152 struct lsa_String lsa_acct_name;
2154 init_lsa_String(&lsa_acct_name, argv[1]);
2156 result = rpccli_samr_LookupNames(cli, mem_ctx,
2157 &domain_pol,
2159 &lsa_acct_name,
2160 &user_rids,
2161 &name_types);
2163 if (!NT_STATUS_IS_OK(result))
2164 goto done;
2166 result = rpccli_samr_OpenUser(cli, mem_ctx,
2167 &domain_pol,
2168 access_mask,
2169 user_rids.ids[0],
2170 &user_pol);
2172 if (!NT_STATUS_IS_OK(result))
2173 goto done;
2176 /* Delete user */
2178 result = rpccli_samr_DeleteUser(cli, mem_ctx,
2179 &user_pol);
2181 if (!NT_STATUS_IS_OK(result))
2182 goto done;
2184 /* Display results */
2186 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2187 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2188 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2190 done:
2191 return result;
2194 /**********************************************************************
2195 * Query user security object
2197 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
2198 TALLOC_CTX *mem_ctx,
2199 int argc, const char **argv)
2201 POLICY_HND connect_pol, domain_pol, user_pol, *pol;
2202 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2203 uint32 sec_info = DACL_SECURITY_INFORMATION;
2204 uint32 user_rid = 0;
2205 TALLOC_CTX *ctx = NULL;
2206 SEC_DESC_BUF *sec_desc_buf=NULL;
2207 bool domain = False;
2209 ctx=talloc_init("cmd_samr_query_sec_obj");
2211 if ((argc < 1) || (argc > 3)) {
2212 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2213 printf("\tSpecify rid for security on user, -d for security on domain\n");
2214 talloc_destroy(ctx);
2215 return NT_STATUS_OK;
2218 if (argc > 1) {
2219 if (strcmp(argv[1], "-d") == 0)
2220 domain = True;
2221 else
2222 sscanf(argv[1], "%i", &user_rid);
2225 if (argc == 3) {
2226 sec_info = atoi(argv[2]);
2229 result = rpccli_try_samr_connects(cli, mem_ctx,
2230 MAXIMUM_ALLOWED_ACCESS,
2231 &connect_pol);
2233 if (!NT_STATUS_IS_OK(result))
2234 goto done;
2236 if (domain || user_rid)
2237 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2238 &connect_pol,
2239 MAXIMUM_ALLOWED_ACCESS,
2240 &domain_sid,
2241 &domain_pol);
2243 if (!NT_STATUS_IS_OK(result))
2244 goto done;
2246 if (user_rid)
2247 result = rpccli_samr_OpenUser(cli, mem_ctx,
2248 &domain_pol,
2249 MAXIMUM_ALLOWED_ACCESS,
2250 user_rid,
2251 &user_pol);
2253 if (!NT_STATUS_IS_OK(result))
2254 goto done;
2256 /* Pick which query pol to use */
2258 pol = &connect_pol;
2260 if (domain)
2261 pol = &domain_pol;
2263 if (user_rid)
2264 pol = &user_pol;
2266 /* Query SAM security object */
2268 result = rpccli_samr_QuerySecurity(cli, mem_ctx,
2269 pol,
2270 sec_info,
2271 &sec_desc_buf);
2273 if (!NT_STATUS_IS_OK(result))
2274 goto done;
2276 display_sec_desc(sec_desc_buf->sd);
2278 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2279 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2280 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2281 done:
2282 talloc_destroy(ctx);
2283 return result;
2286 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
2287 TALLOC_CTX *mem_ctx,
2288 int argc, const char **argv)
2290 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2291 POLICY_HND connect_pol, domain_pol, user_pol;
2292 struct samr_PwInfo info;
2293 uint32_t rid;
2295 if (argc != 2) {
2296 printf("Usage: %s rid\n", argv[0]);
2297 return NT_STATUS_OK;
2300 sscanf(argv[1], "%i", &rid);
2302 result = rpccli_try_samr_connects(cli, mem_ctx,
2303 MAXIMUM_ALLOWED_ACCESS,
2304 &connect_pol);
2306 if (!NT_STATUS_IS_OK(result)) {
2307 goto done;
2310 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2311 &connect_pol,
2312 MAXIMUM_ALLOWED_ACCESS,
2313 &domain_sid,
2314 &domain_pol);
2316 if (!NT_STATUS_IS_OK(result)) {
2317 goto done;
2320 result = rpccli_samr_OpenUser(cli, mem_ctx,
2321 &domain_pol,
2322 MAXIMUM_ALLOWED_ACCESS,
2323 rid,
2324 &user_pol);
2326 if (!NT_STATUS_IS_OK(result)) {
2327 goto done;
2330 result = rpccli_samr_GetUserPwInfo(cli, mem_ctx, &user_pol, &info);
2331 if (NT_STATUS_IS_OK(result)) {
2332 printf("min_password_length: %d\n", info.min_password_length);
2333 printf("%s\n",
2334 NDR_PRINT_STRUCT_STRING(mem_ctx,
2335 samr_PasswordProperties, &info.password_properties));
2338 done:
2339 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2340 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2341 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2343 return result;
2346 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2347 TALLOC_CTX *mem_ctx,
2348 int argc, const char **argv)
2350 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2351 struct lsa_String domain_name;
2352 struct samr_PwInfo info;
2354 if (argc < 1 || argc > 3) {
2355 printf("Usage: %s <domain>\n", argv[0]);
2356 return NT_STATUS_OK;
2359 init_lsa_String(&domain_name, argv[1]);
2361 result = rpccli_samr_GetDomPwInfo(cli, mem_ctx, &domain_name, &info);
2363 if (NT_STATUS_IS_OK(result)) {
2364 printf("min_password_length: %d\n", info.min_password_length);
2365 display_password_properties(info.password_properties);
2368 return result;
2371 /* Look up domain name */
2373 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
2374 TALLOC_CTX *mem_ctx,
2375 int argc, const char **argv)
2377 POLICY_HND connect_pol, domain_pol;
2378 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2379 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2380 fstring sid_string;
2381 struct lsa_String domain_name;
2382 DOM_SID *sid = NULL;
2384 if (argc != 2) {
2385 printf("Usage: %s domain_name\n", argv[0]);
2386 return NT_STATUS_OK;
2389 init_lsa_String(&domain_name, argv[1]);
2391 result = rpccli_try_samr_connects(cli, mem_ctx,
2392 access_mask,
2393 &connect_pol);
2395 if (!NT_STATUS_IS_OK(result))
2396 goto done;
2398 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2399 &connect_pol,
2400 access_mask,
2401 &domain_sid,
2402 &domain_pol);
2404 if (!NT_STATUS_IS_OK(result))
2405 goto done;
2407 result = rpccli_samr_LookupDomain(cli, mem_ctx,
2408 &connect_pol,
2409 &domain_name,
2410 &sid);
2412 if (NT_STATUS_IS_OK(result)) {
2413 sid_to_fstring(sid_string, sid);
2414 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2415 argv[1], sid_string);
2418 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2419 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2420 done:
2421 return result;
2424 /* Change user password */
2426 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2427 TALLOC_CTX *mem_ctx,
2428 int argc, const char **argv)
2430 POLICY_HND connect_pol, domain_pol;
2431 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2432 const char *user, *oldpass, *newpass;
2433 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2435 if (argc < 3) {
2436 printf("Usage: %s username oldpass newpass\n", argv[0]);
2437 return NT_STATUS_INVALID_PARAMETER;
2440 user = argv[1];
2441 oldpass = argv[2];
2442 newpass = argv[3];
2444 /* Get sam policy handle */
2446 result = rpccli_try_samr_connects(cli, mem_ctx,
2447 MAXIMUM_ALLOWED_ACCESS,
2448 &connect_pol);
2450 if (!NT_STATUS_IS_OK(result))
2451 goto done;
2453 /* Get domain policy handle */
2455 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2456 &connect_pol,
2457 access_mask,
2458 &domain_sid,
2459 &domain_pol);
2461 if (!NT_STATUS_IS_OK(result))
2462 goto done;
2464 /* Change user password */
2465 result = rpccli_samr_chgpasswd_user(cli, mem_ctx, user, newpass, oldpass);
2467 if (!NT_STATUS_IS_OK(result))
2468 goto done;
2470 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2471 if (!NT_STATUS_IS_OK(result)) goto done;
2473 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2474 if (!NT_STATUS_IS_OK(result)) goto done;
2476 done:
2477 return result;
2481 /* Change user password */
2483 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
2484 TALLOC_CTX *mem_ctx,
2485 int argc, const char **argv)
2487 POLICY_HND connect_pol, domain_pol;
2488 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2489 const char *user, *oldpass, *newpass;
2490 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2491 struct samr_DomInfo1 *info = NULL;
2492 struct samr_ChangeReject *reject = NULL;
2494 if (argc < 3) {
2495 printf("Usage: %s username oldpass newpass\n", argv[0]);
2496 return NT_STATUS_INVALID_PARAMETER;
2499 user = argv[1];
2500 oldpass = argv[2];
2501 newpass = argv[3];
2503 /* Get sam policy handle */
2505 result = rpccli_try_samr_connects(cli, mem_ctx,
2506 MAXIMUM_ALLOWED_ACCESS,
2507 &connect_pol);
2509 if (!NT_STATUS_IS_OK(result))
2510 goto done;
2512 /* Get domain policy handle */
2514 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2515 &connect_pol,
2516 access_mask,
2517 &domain_sid,
2518 &domain_pol);
2520 if (!NT_STATUS_IS_OK(result))
2521 goto done;
2523 /* Change user password */
2524 result = rpccli_samr_chgpasswd3(cli, mem_ctx,
2525 user,
2526 newpass,
2527 oldpass,
2528 &info,
2529 &reject);
2531 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2533 display_sam_dom_info_1(info);
2535 switch (reject->reason) {
2536 case SAMR_REJECT_TOO_SHORT:
2537 d_printf("SAMR_REJECT_TOO_SHORT\n");
2538 break;
2539 case SAMR_REJECT_IN_HISTORY:
2540 d_printf("SAMR_REJECT_IN_HISTORY\n");
2541 break;
2542 case SAMR_REJECT_COMPLEXITY:
2543 d_printf("SAMR_REJECT_COMPLEXITY\n");
2544 break;
2545 case SAMR_REJECT_OTHER:
2546 d_printf("SAMR_REJECT_OTHER\n");
2547 break;
2548 default:
2549 d_printf("unknown reject reason: %d\n",
2550 reject->reason);
2551 break;
2555 if (!NT_STATUS_IS_OK(result))
2556 goto done;
2558 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2559 if (!NT_STATUS_IS_OK(result)) goto done;
2561 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2562 if (!NT_STATUS_IS_OK(result)) goto done;
2564 done:
2565 return result;
2568 static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
2569 TALLOC_CTX *mem_ctx,
2570 int argc, const char **argv)
2572 NTSTATUS status;
2573 struct policy_handle connect_handle;
2574 struct policy_handle domain_handle;
2575 uint16_t level = 1;
2576 struct lsa_String name;
2577 uint32_t idx = 0;
2579 if (argc < 2 || argc > 3) {
2580 printf("Usage: %s name level\n", argv[0]);
2581 return NT_STATUS_INVALID_PARAMETER;
2584 init_lsa_String(&name, argv[1]);
2586 if (argc == 3) {
2587 level = atoi(argv[2]);
2590 status = rpccli_try_samr_connects(cli, mem_ctx,
2591 SEC_RIGHTS_MAXIMUM_ALLOWED,
2592 &connect_handle);
2594 if (!NT_STATUS_IS_OK(status)) {
2595 goto done;
2598 status = rpccli_samr_OpenDomain(cli, mem_ctx,
2599 &connect_handle,
2600 SEC_RIGHTS_MAXIMUM_ALLOWED,
2601 &domain_sid,
2602 &domain_handle);
2604 if (!NT_STATUS_IS_OK(status))
2605 goto done;
2608 status = rpccli_samr_GetDisplayEnumerationIndex(cli, mem_ctx,
2609 &domain_handle,
2610 level,
2611 &name,
2612 &idx);
2614 if (NT_STATUS_IS_OK(status) ||
2615 NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
2616 printf("idx: %d (0x%08x)\n", idx, idx);
2618 done:
2620 if (is_valid_policy_hnd(&domain_handle)) {
2621 rpccli_samr_Close(cli, mem_ctx, &domain_handle);
2623 if (is_valid_policy_hnd(&connect_handle)) {
2624 rpccli_samr_Close(cli, mem_ctx, &connect_handle);
2627 return status;
2630 /* List of commands exported by this module */
2632 struct cmd_set samr_commands[] = {
2634 { "SAMR" },
2636 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, PI_SAMR, NULL, "Query user info", "" },
2637 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, PI_SAMR, NULL, "Query group info", "" },
2638 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, PI_SAMR, NULL, "Query user groups", "" },
2639 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, PI_SAMR, NULL, "Query user aliases", "" },
2640 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, PI_SAMR, NULL, "Query group membership", "" },
2641 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, PI_SAMR, NULL, "Query alias membership", "" },
2642 { "queryaliasinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasinfo, NULL, PI_SAMR, NULL, "Query alias info", "" },
2643 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, PI_SAMR, NULL, "Delete an alias", "" },
2644 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, PI_SAMR, NULL, "Query display info", "" },
2645 { "querydispinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo2, NULL, PI_SAMR, NULL, "Query display info", "" },
2646 { "querydispinfo3", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo3, NULL, PI_SAMR, NULL, "Query display info", "" },
2647 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, PI_SAMR, NULL, "Query domain info", "" },
2648 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, PI_SAMR, NULL, "Enumerate domain users", "" },
2649 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, PI_SAMR, NULL, "Enumerate domain groups", "" },
2650 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, PI_SAMR, NULL, "Enumerate alias groups", "" },
2651 { "enumdomains", RPC_RTYPE_NTSTATUS, cmd_samr_enum_domains, NULL, PI_SAMR, NULL, "Enumerate domains", "" },
2653 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, PI_SAMR, NULL, "Create domain user", "" },
2654 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, PI_SAMR, NULL, "Create domain group", "" },
2655 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, PI_SAMR, NULL, "Create domain alias", "" },
2656 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, PI_SAMR, NULL, "Look up names", "" },
2657 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, PI_SAMR, NULL, "Look up names", "" },
2658 { "deletedomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group, NULL, PI_SAMR, NULL, "Delete domain group", "" },
2659 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, PI_SAMR, NULL, "Delete domain user", "" },
2660 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, PI_SAMR, NULL, "Query SAMR security object", "" },
2661 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
2662 { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve user domain password info", "" },
2664 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },
2665 { "chgpasswd2", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2, NULL, PI_SAMR, NULL, "Change user password", "" },
2666 { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, PI_SAMR, NULL, "Change user password", "" },
2667 { "getdispinfoidx", RPC_RTYPE_NTSTATUS, cmd_samr_get_dispinfo_idx, NULL, PI_SAMR, NULL, "Get Display Information Index", "" },
2668 { NULL }