For some unknown reason ldbrename was not being built in samba3.
[Samba.git] / source / rpcclient / cmd_samr.c
blob91968dd3c450b340317a9d5277dea5d03ea68ddc
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("Sequence No at last promotion:\t%llu\n",
223 (unsigned long long)info13->modified_count_at_last_promotion);
226 static void display_sam_info_1(struct samr_DispEntryGeneral *r)
228 printf("index: 0x%x ", r->idx);
229 printf("RID: 0x%x ", r->rid);
230 printf("acb: 0x%08x ", r->acct_flags);
231 printf("Account: %s\t", r->account_name.string);
232 printf("Name: %s\t", r->full_name.string);
233 printf("Desc: %s\n", r->description.string);
236 static void display_sam_info_2(struct samr_DispEntryFull *r)
238 printf("index: 0x%x ", r->idx);
239 printf("RID: 0x%x ", r->rid);
240 printf("acb: 0x%08x ", r->acct_flags);
241 printf("Account: %s\t", r->account_name.string);
242 printf("Desc: %s\n", r->description.string);
245 static void display_sam_info_3(struct samr_DispEntryFullGroup *r)
247 printf("index: 0x%x ", r->idx);
248 printf("RID: 0x%x ", r->rid);
249 printf("acb: 0x%08x ", r->acct_flags);
250 printf("Account: %s\t", r->account_name.string);
251 printf("Desc: %s\n", r->description.string);
254 static void display_sam_info_4(struct samr_DispEntryAscii *r)
256 printf("index: 0x%x ", r->idx);
257 printf("Account: %s\n", r->account_name.string);
260 static void display_sam_info_5(struct samr_DispEntryAscii *r)
262 printf("index: 0x%x ", r->idx);
263 printf("Account: %s\n", r->account_name.string);
266 /**********************************************************************
267 * Query user information
269 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
270 TALLOC_CTX *mem_ctx,
271 int argc, const char **argv)
273 POLICY_HND connect_pol, domain_pol, user_pol;
274 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
275 uint32 info_level = 21;
276 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
277 union samr_UserInfo *info = NULL;
278 uint32 user_rid = 0;
280 if ((argc < 2) || (argc > 4)) {
281 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
282 return NT_STATUS_OK;
285 sscanf(argv[1], "%i", &user_rid);
287 if (argc > 2)
288 sscanf(argv[2], "%i", &info_level);
290 if (argc > 3)
291 sscanf(argv[3], "%x", &access_mask);
294 result = rpccli_try_samr_connects(cli, mem_ctx,
295 MAXIMUM_ALLOWED_ACCESS,
296 &connect_pol);
298 if (!NT_STATUS_IS_OK(result))
299 goto done;
301 result = rpccli_samr_OpenDomain(cli, mem_ctx,
302 &connect_pol,
303 MAXIMUM_ALLOWED_ACCESS,
304 &domain_sid,
305 &domain_pol);
306 if (!NT_STATUS_IS_OK(result))
307 goto done;
309 result = rpccli_samr_OpenUser(cli, mem_ctx,
310 &domain_pol,
311 access_mask,
312 user_rid,
313 &user_pol);
315 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
316 (user_rid == 0)) {
318 /* Probably this was a user name, try lookupnames */
319 struct samr_Ids rids, types;
320 struct lsa_String lsa_acct_name;
322 init_lsa_String(&lsa_acct_name, argv[1]);
324 result = rpccli_samr_LookupNames(cli, mem_ctx,
325 &domain_pol,
327 &lsa_acct_name,
328 &rids,
329 &types);
331 if (NT_STATUS_IS_OK(result)) {
332 result = rpccli_samr_OpenUser(cli, mem_ctx,
333 &domain_pol,
334 access_mask,
335 rids.ids[0],
336 &user_pol);
341 if (!NT_STATUS_IS_OK(result))
342 goto done;
344 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
345 &user_pol,
346 info_level,
347 &info);
349 if (!NT_STATUS_IS_OK(result))
350 goto done;
352 switch (info_level) {
353 case 7:
354 display_samr_user_info_7(&info->info7);
355 break;
356 case 9:
357 display_samr_user_info_9(&info->info9);
358 break;
359 case 16:
360 display_samr_user_info_16(&info->info16);
361 break;
362 case 20:
363 display_samr_user_info_20(&info->info20);
364 break;
365 case 21:
366 display_samr_user_info_21(&info->info21);
367 break;
368 default:
369 printf("Unsupported infolevel: %d\n", info_level);
370 break;
373 rpccli_samr_Close(cli, mem_ctx, &user_pol);
374 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
375 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
377 done:
378 return result;
381 /****************************************************************************
382 display group info
383 ****************************************************************************/
384 static void display_group_info1(struct samr_GroupInfoAll *info1)
386 printf("\tGroup Name:\t%s\n", info1->name.string);
387 printf("\tDescription:\t%s\n", info1->description.string);
388 printf("\tGroup Attribute:%d\n", info1->attributes);
389 printf("\tNum Members:%d\n", info1->num_members);
392 /****************************************************************************
393 display group info
394 ****************************************************************************/
395 static void display_group_info2(struct lsa_String *info2)
397 printf("\tGroup Description:%s\n", info2->string);
401 /****************************************************************************
402 display group info
403 ****************************************************************************/
404 static void display_group_info3(struct samr_GroupInfoAttributes *info3)
406 printf("\tGroup Attribute:%d\n", info3->attributes);
410 /****************************************************************************
411 display group info
412 ****************************************************************************/
413 static void display_group_info4(struct lsa_String *info4)
415 printf("\tGroup Description:%s\n", info4->string);
418 /****************************************************************************
419 display group info
420 ****************************************************************************/
421 static void display_group_info5(struct samr_GroupInfoAll *info5)
423 printf("\tGroup Name:\t%s\n", info5->name.string);
424 printf("\tDescription:\t%s\n", info5->description.string);
425 printf("\tGroup Attribute:%d\n", info5->attributes);
426 printf("\tNum Members:%d\n", info5->num_members);
429 /****************************************************************************
430 display sam sync structure
431 ****************************************************************************/
432 static void display_group_info(union samr_GroupInfo *info,
433 enum samr_GroupInfoEnum level)
435 switch (level) {
436 case 1:
437 display_group_info1(&info->all);
438 break;
439 case 2:
440 display_group_info2(&info->name);
441 break;
442 case 3:
443 display_group_info3(&info->attributes);
444 break;
445 case 4:
446 display_group_info4(&info->description);
447 break;
448 case 5:
449 display_group_info5(&info->all2);
450 break;
454 /***********************************************************************
455 * Query group information
457 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
458 TALLOC_CTX *mem_ctx,
459 int argc, const char **argv)
461 POLICY_HND connect_pol, domain_pol, group_pol;
462 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
463 enum samr_GroupInfoEnum info_level = GROUPINFOALL;
464 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
465 union samr_GroupInfo *group_info = NULL;
466 uint32 group_rid;
468 if ((argc < 2) || (argc > 4)) {
469 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
470 return NT_STATUS_OK;
473 sscanf(argv[1], "%i", &group_rid);
475 if (argc > 2)
476 info_level = atoi(argv[2]);
478 if (argc > 3)
479 sscanf(argv[3], "%x", &access_mask);
481 result = rpccli_try_samr_connects(cli, mem_ctx,
482 MAXIMUM_ALLOWED_ACCESS,
483 &connect_pol);
485 if (!NT_STATUS_IS_OK(result))
486 goto done;
488 result = rpccli_samr_OpenDomain(cli, mem_ctx,
489 &connect_pol,
490 MAXIMUM_ALLOWED_ACCESS,
491 &domain_sid,
492 &domain_pol);
494 if (!NT_STATUS_IS_OK(result))
495 goto done;
497 result = rpccli_samr_OpenGroup(cli, mem_ctx,
498 &domain_pol,
499 access_mask,
500 group_rid,
501 &group_pol);
503 if (!NT_STATUS_IS_OK(result))
504 goto done;
506 result = rpccli_samr_QueryGroupInfo(cli, mem_ctx,
507 &group_pol,
508 info_level,
509 &group_info);
510 if (!NT_STATUS_IS_OK(result)) {
511 goto done;
514 display_group_info(group_info, info_level);
516 rpccli_samr_Close(cli, mem_ctx, &group_pol);
517 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
518 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
519 done:
520 return result;
523 /* Query groups a user is a member of */
525 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
526 TALLOC_CTX *mem_ctx,
527 int argc, const char **argv)
529 POLICY_HND connect_pol,
530 domain_pol,
531 user_pol;
532 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
533 uint32 user_rid;
534 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
535 int i;
536 struct samr_RidWithAttributeArray *rid_array = NULL;
538 if ((argc < 2) || (argc > 3)) {
539 printf("Usage: %s rid [access mask]\n", argv[0]);
540 return NT_STATUS_OK;
543 sscanf(argv[1], "%i", &user_rid);
545 if (argc > 2)
546 sscanf(argv[2], "%x", &access_mask);
548 result = rpccli_try_samr_connects(cli, mem_ctx,
549 MAXIMUM_ALLOWED_ACCESS,
550 &connect_pol);
552 if (!NT_STATUS_IS_OK(result))
553 goto done;
555 result = rpccli_samr_OpenDomain(cli, mem_ctx,
556 &connect_pol,
557 MAXIMUM_ALLOWED_ACCESS,
558 &domain_sid, &domain_pol);
560 if (!NT_STATUS_IS_OK(result))
561 goto done;
563 result = rpccli_samr_OpenUser(cli, mem_ctx,
564 &domain_pol,
565 access_mask,
566 user_rid,
567 &user_pol);
569 if (!NT_STATUS_IS_OK(result))
570 goto done;
572 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
573 &user_pol,
574 &rid_array);
576 if (!NT_STATUS_IS_OK(result))
577 goto done;
579 for (i = 0; i < rid_array->count; i++) {
580 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
581 rid_array->rids[i].rid,
582 rid_array->rids[i].attributes);
585 rpccli_samr_Close(cli, mem_ctx, &user_pol);
586 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
587 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
588 done:
589 return result;
592 /* Query aliases a user is a member of */
594 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
595 TALLOC_CTX *mem_ctx,
596 int argc, const char **argv)
598 POLICY_HND connect_pol, domain_pol;
599 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
600 DOM_SID *sids;
601 size_t num_sids;
602 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
603 int i;
604 struct lsa_SidArray sid_array;
605 struct samr_Ids alias_rids;
607 if (argc < 3) {
608 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
609 return NT_STATUS_INVALID_PARAMETER;
612 sids = NULL;
613 num_sids = 0;
615 for (i=2; i<argc; i++) {
616 DOM_SID tmp_sid;
617 if (!string_to_sid(&tmp_sid, argv[i])) {
618 printf("%s is not a legal SID\n", argv[i]);
619 return NT_STATUS_INVALID_PARAMETER;
621 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
622 if (!NT_STATUS_IS_OK(result)) {
623 return result;
627 if (num_sids) {
628 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids);
629 if (sid_array.sids == NULL)
630 return NT_STATUS_NO_MEMORY;
631 } else {
632 sid_array.sids = NULL;
635 for (i=0; i<num_sids; i++) {
636 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[i]);
637 if (!sid_array.sids[i].sid) {
638 return NT_STATUS_NO_MEMORY;
642 sid_array.num_sids = num_sids;
644 result = rpccli_try_samr_connects(cli, mem_ctx,
645 MAXIMUM_ALLOWED_ACCESS,
646 &connect_pol);
648 if (!NT_STATUS_IS_OK(result))
649 goto done;
651 if (StrCaseCmp(argv[1], "domain")==0)
652 result = rpccli_samr_OpenDomain(cli, mem_ctx,
653 &connect_pol,
654 access_mask,
655 &domain_sid, &domain_pol);
656 else if (StrCaseCmp(argv[1], "builtin")==0)
657 result = rpccli_samr_OpenDomain(cli, mem_ctx,
658 &connect_pol,
659 access_mask,
660 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
661 &domain_pol);
662 else {
663 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
664 return NT_STATUS_INVALID_PARAMETER;
667 if (!NT_STATUS_IS_OK(result))
668 goto done;
670 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
671 &domain_pol,
672 &sid_array,
673 &alias_rids);
674 if (!NT_STATUS_IS_OK(result))
675 goto done;
677 for (i = 0; i < alias_rids.count; i++) {
678 printf("\tgroup rid:[0x%x]\n", alias_rids.ids[i]);
681 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
682 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
683 done:
684 return result;
687 /* Query members of a group */
689 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
690 TALLOC_CTX *mem_ctx,
691 int argc, const char **argv)
693 POLICY_HND connect_pol, domain_pol, group_pol;
694 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
695 uint32 group_rid;
696 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
697 int i;
698 unsigned int old_timeout;
699 struct samr_RidTypeArray *rids = NULL;
701 if ((argc < 2) || (argc > 3)) {
702 printf("Usage: %s rid [access mask]\n", argv[0]);
703 return NT_STATUS_OK;
706 sscanf(argv[1], "%i", &group_rid);
708 if (argc > 2)
709 sscanf(argv[2], "%x", &access_mask);
711 result = rpccli_try_samr_connects(cli, mem_ctx,
712 MAXIMUM_ALLOWED_ACCESS,
713 &connect_pol);
715 if (!NT_STATUS_IS_OK(result))
716 goto done;
718 result = rpccli_samr_OpenDomain(cli, mem_ctx,
719 &connect_pol,
720 MAXIMUM_ALLOWED_ACCESS,
721 &domain_sid,
722 &domain_pol);
724 if (!NT_STATUS_IS_OK(result))
725 goto done;
727 result = rpccli_samr_OpenGroup(cli, mem_ctx,
728 &domain_pol,
729 access_mask,
730 group_rid,
731 &group_pol);
733 if (!NT_STATUS_IS_OK(result))
734 goto done;
736 /* Make sure to wait for our DC's reply */
737 old_timeout = rpccli_set_timeout(cli, 30000); /* 30 seconds. */
738 rpccli_set_timeout(cli, MAX(30000, old_timeout)); /* At least 30 sec */
740 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
741 &group_pol,
742 &rids);
744 rpccli_set_timeout(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_chgpasswd(struct rpc_pipe_client *cli,
2427 TALLOC_CTX *mem_ctx,
2428 int argc, const char **argv)
2430 POLICY_HND connect_pol, domain_pol, user_pol;
2431 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2432 const char *user, *oldpass, *newpass;
2433 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2434 struct samr_Ids rids, types;
2435 struct lsa_String lsa_acct_name;
2437 if (argc < 3) {
2438 printf("Usage: %s username oldpass newpass\n", argv[0]);
2439 return NT_STATUS_INVALID_PARAMETER;
2442 user = argv[1];
2443 oldpass = argv[2];
2444 newpass = argv[3];
2446 /* Get sam policy handle */
2448 result = rpccli_try_samr_connects(cli, mem_ctx,
2449 MAXIMUM_ALLOWED_ACCESS,
2450 &connect_pol);
2452 if (!NT_STATUS_IS_OK(result)) {
2453 goto done;
2456 /* Get domain policy handle */
2458 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2459 &connect_pol,
2460 access_mask,
2461 &domain_sid,
2462 &domain_pol);
2464 if (!NT_STATUS_IS_OK(result)) {
2465 goto done;
2468 init_lsa_String(&lsa_acct_name, user);
2470 result = rpccli_samr_LookupNames(cli, mem_ctx,
2471 &domain_pol,
2473 &lsa_acct_name,
2474 &rids,
2475 &types);
2477 if (!NT_STATUS_IS_OK(result)) {
2478 goto done;
2481 result = rpccli_samr_OpenUser(cli, mem_ctx,
2482 &domain_pol,
2483 access_mask,
2484 rids.ids[0],
2485 &user_pol);
2487 if (!NT_STATUS_IS_OK(result)) {
2488 goto done;
2491 /* Change user password */
2492 result = rpccli_samr_chgpasswd_user(cli, mem_ctx,
2493 &user_pol,
2494 newpass,
2495 oldpass);
2497 if (!NT_STATUS_IS_OK(result)) {
2498 goto done;
2501 done:
2502 if (is_valid_policy_hnd(&user_pol)) {
2503 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2505 if (is_valid_policy_hnd(&domain_pol)) {
2506 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2508 if (is_valid_policy_hnd(&connect_pol)) {
2509 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2512 return result;
2516 /* Change user password */
2518 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2519 TALLOC_CTX *mem_ctx,
2520 int argc, const char **argv)
2522 POLICY_HND connect_pol, domain_pol;
2523 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2524 const char *user, *oldpass, *newpass;
2525 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2527 if (argc < 3) {
2528 printf("Usage: %s username oldpass newpass\n", argv[0]);
2529 return NT_STATUS_INVALID_PARAMETER;
2532 user = argv[1];
2533 oldpass = argv[2];
2534 newpass = argv[3];
2536 /* Get sam policy handle */
2538 result = rpccli_try_samr_connects(cli, mem_ctx,
2539 MAXIMUM_ALLOWED_ACCESS,
2540 &connect_pol);
2542 if (!NT_STATUS_IS_OK(result))
2543 goto done;
2545 /* Get domain policy handle */
2547 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2548 &connect_pol,
2549 access_mask,
2550 &domain_sid,
2551 &domain_pol);
2553 if (!NT_STATUS_IS_OK(result))
2554 goto done;
2556 /* Change user password */
2557 result = rpccli_samr_chgpasswd_user2(cli, mem_ctx, user, newpass, oldpass);
2559 if (!NT_STATUS_IS_OK(result))
2560 goto done;
2562 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2563 if (!NT_STATUS_IS_OK(result)) goto done;
2565 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2566 if (!NT_STATUS_IS_OK(result)) goto done;
2568 done:
2569 return result;
2573 /* Change user password */
2575 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
2576 TALLOC_CTX *mem_ctx,
2577 int argc, const char **argv)
2579 POLICY_HND connect_pol, domain_pol;
2580 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2581 const char *user, *oldpass, *newpass;
2582 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2583 struct samr_DomInfo1 *info = NULL;
2584 struct samr_ChangeReject *reject = NULL;
2586 if (argc < 3) {
2587 printf("Usage: %s username oldpass newpass\n", argv[0]);
2588 return NT_STATUS_INVALID_PARAMETER;
2591 user = argv[1];
2592 oldpass = argv[2];
2593 newpass = argv[3];
2595 /* Get sam policy handle */
2597 result = rpccli_try_samr_connects(cli, mem_ctx,
2598 MAXIMUM_ALLOWED_ACCESS,
2599 &connect_pol);
2601 if (!NT_STATUS_IS_OK(result))
2602 goto done;
2604 /* Get domain policy handle */
2606 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2607 &connect_pol,
2608 access_mask,
2609 &domain_sid,
2610 &domain_pol);
2612 if (!NT_STATUS_IS_OK(result))
2613 goto done;
2615 /* Change user password */
2616 result = rpccli_samr_chgpasswd_user3(cli, mem_ctx,
2617 user,
2618 newpass,
2619 oldpass,
2620 &info,
2621 &reject);
2623 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2625 display_sam_dom_info_1(info);
2627 switch (reject->reason) {
2628 case SAMR_REJECT_TOO_SHORT:
2629 d_printf("SAMR_REJECT_TOO_SHORT\n");
2630 break;
2631 case SAMR_REJECT_IN_HISTORY:
2632 d_printf("SAMR_REJECT_IN_HISTORY\n");
2633 break;
2634 case SAMR_REJECT_COMPLEXITY:
2635 d_printf("SAMR_REJECT_COMPLEXITY\n");
2636 break;
2637 case SAMR_REJECT_OTHER:
2638 d_printf("SAMR_REJECT_OTHER\n");
2639 break;
2640 default:
2641 d_printf("unknown reject reason: %d\n",
2642 reject->reason);
2643 break;
2647 if (!NT_STATUS_IS_OK(result))
2648 goto done;
2650 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2651 if (!NT_STATUS_IS_OK(result)) goto done;
2653 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2654 if (!NT_STATUS_IS_OK(result)) goto done;
2656 done:
2657 return result;
2660 static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
2661 TALLOC_CTX *mem_ctx,
2662 int argc, const char **argv)
2664 NTSTATUS status;
2665 struct policy_handle connect_handle;
2666 struct policy_handle domain_handle;
2667 uint16_t level = 1;
2668 struct lsa_String name;
2669 uint32_t idx = 0;
2671 if (argc < 2 || argc > 3) {
2672 printf("Usage: %s name level\n", argv[0]);
2673 return NT_STATUS_INVALID_PARAMETER;
2676 init_lsa_String(&name, argv[1]);
2678 if (argc == 3) {
2679 level = atoi(argv[2]);
2682 status = rpccli_try_samr_connects(cli, mem_ctx,
2683 SEC_RIGHTS_MAXIMUM_ALLOWED,
2684 &connect_handle);
2686 if (!NT_STATUS_IS_OK(status)) {
2687 goto done;
2690 status = rpccli_samr_OpenDomain(cli, mem_ctx,
2691 &connect_handle,
2692 SEC_RIGHTS_MAXIMUM_ALLOWED,
2693 &domain_sid,
2694 &domain_handle);
2696 if (!NT_STATUS_IS_OK(status))
2697 goto done;
2700 status = rpccli_samr_GetDisplayEnumerationIndex(cli, mem_ctx,
2701 &domain_handle,
2702 level,
2703 &name,
2704 &idx);
2706 if (NT_STATUS_IS_OK(status) ||
2707 NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
2708 printf("idx: %d (0x%08x)\n", idx, idx);
2710 done:
2712 if (is_valid_policy_hnd(&domain_handle)) {
2713 rpccli_samr_Close(cli, mem_ctx, &domain_handle);
2715 if (is_valid_policy_hnd(&connect_handle)) {
2716 rpccli_samr_Close(cli, mem_ctx, &connect_handle);
2719 return status;
2722 /* List of commands exported by this module */
2724 struct cmd_set samr_commands[] = {
2726 { "SAMR" },
2728 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, &ndr_table_samr.syntax_id, NULL, "Query user info", "" },
2729 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, &ndr_table_samr.syntax_id, NULL, "Query group info", "" },
2730 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, &ndr_table_samr.syntax_id, NULL, "Query user groups", "" },
2731 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, &ndr_table_samr.syntax_id, NULL, "Query user aliases", "" },
2732 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, &ndr_table_samr.syntax_id, NULL, "Query group membership", "" },
2733 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, &ndr_table_samr.syntax_id, NULL, "Query alias membership", "" },
2734 { "queryaliasinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query alias info", "" },
2735 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, &ndr_table_samr.syntax_id, NULL, "Delete an alias", "" },
2736 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
2737 { "querydispinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo2, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
2738 { "querydispinfo3", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo3, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
2739 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query domain info", "" },
2740 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domain users", "" },
2741 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domain groups", "" },
2742 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate alias groups", "" },
2743 { "enumdomains", RPC_RTYPE_NTSTATUS, cmd_samr_enum_domains, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domains", "" },
2745 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain user", "" },
2746 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain group", "" },
2747 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain alias", "" },
2748 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, &ndr_table_samr.syntax_id, NULL, "Look up names", "" },
2749 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, &ndr_table_samr.syntax_id, NULL, "Look up names", "" },
2750 { "deletedomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group, NULL, &ndr_table_samr.syntax_id, NULL, "Delete domain group", "" },
2751 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, &ndr_table_samr.syntax_id, NULL, "Delete domain user", "" },
2752 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, &ndr_table_samr.syntax_id, NULL, "Query SAMR security object", "" },
2753 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Retrieve domain password info", "" },
2754 { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Retrieve user domain password info", "" },
2756 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, &ndr_table_samr.syntax_id, NULL, "Lookup Domain Name", "" },
2757 { "chgpasswd", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
2758 { "chgpasswd2", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
2759 { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
2760 { "getdispinfoidx", RPC_RTYPE_NTSTATUS, cmd_samr_get_dispinfo_idx, NULL, &ndr_table_samr.syntax_id, NULL, "Get Display Information Index", "" },
2761 { NULL }