netapi: fix NetGetJoinableOUs_l.
[Samba.git] / source / rpcclient / cmd_samr.c
blobfa1e0fda4d0a414368ddc7134a7e383ecae05764
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 = rpccli_set_timeout(cli, 30000); /* 30 seconds. */
739 rpccli_set_timeout(cli, MAX(30000, old_timeout)); /* At least 30 sec */
741 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
742 &group_pol,
743 &rids);
745 rpccli_set_timeout(cli, old_timeout);
747 if (!NT_STATUS_IS_OK(result))
748 goto done;
750 for (i = 0; i < rids->count; i++) {
751 printf("\trid:[0x%x] attr:[0x%x]\n", rids->rids[i],
752 rids->types[i]);
755 rpccli_samr_Close(cli, mem_ctx, &group_pol);
756 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
757 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
758 done:
759 return result;
762 /* Enumerate domain users */
764 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
765 TALLOC_CTX *mem_ctx,
766 int argc, const char **argv)
768 POLICY_HND connect_pol, domain_pol;
769 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
770 uint32 start_idx, size, num_dom_users, i;
771 struct samr_SamArray *dom_users = NULL;
772 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
773 uint32 acb_mask = ACB_NORMAL;
774 bool got_connect_pol = False, got_domain_pol = False;
776 if ((argc < 1) || (argc > 3)) {
777 printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
778 return NT_STATUS_OK;
781 if (argc > 1)
782 sscanf(argv[1], "%x", &access_mask);
784 if (argc > 2)
785 sscanf(argv[2], "%x", &acb_mask);
787 /* Get sam policy handle */
789 result = rpccli_try_samr_connects(cli, mem_ctx,
790 MAXIMUM_ALLOWED_ACCESS,
791 &connect_pol);
793 if (!NT_STATUS_IS_OK(result))
794 goto done;
796 got_connect_pol = True;
798 /* Get domain policy handle */
800 result = rpccli_samr_OpenDomain(cli, mem_ctx,
801 &connect_pol,
802 access_mask,
803 &domain_sid,
804 &domain_pol);
806 if (!NT_STATUS_IS_OK(result))
807 goto done;
809 got_domain_pol = True;
811 /* Enumerate domain users */
813 start_idx = 0;
814 size = 0xffff;
816 do {
817 result = rpccli_samr_EnumDomainUsers(cli, mem_ctx,
818 &domain_pol,
819 &start_idx,
820 acb_mask,
821 &dom_users,
822 size,
823 &num_dom_users);
825 if (NT_STATUS_IS_OK(result) ||
826 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
828 for (i = 0; i < num_dom_users; i++)
829 printf("user:[%s] rid:[0x%x]\n",
830 dom_users->entries[i].name.string,
831 dom_users->entries[i].idx);
834 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
836 done:
837 if (got_domain_pol)
838 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
840 if (got_connect_pol)
841 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
843 return result;
846 /* Enumerate domain groups */
848 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
849 TALLOC_CTX *mem_ctx,
850 int argc, const char **argv)
852 POLICY_HND connect_pol, domain_pol;
853 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
854 uint32 start_idx, size, num_dom_groups, i;
855 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
856 struct samr_SamArray *dom_groups = NULL;
857 bool got_connect_pol = False, got_domain_pol = False;
859 if ((argc < 1) || (argc > 2)) {
860 printf("Usage: %s [access_mask]\n", argv[0]);
861 return NT_STATUS_OK;
864 if (argc > 1)
865 sscanf(argv[1], "%x", &access_mask);
867 /* Get sam policy handle */
869 result = rpccli_try_samr_connects(cli, mem_ctx,
870 MAXIMUM_ALLOWED_ACCESS,
871 &connect_pol);
873 if (!NT_STATUS_IS_OK(result))
874 goto done;
876 got_connect_pol = True;
878 /* Get domain policy handle */
880 result = rpccli_samr_OpenDomain(cli, mem_ctx,
881 &connect_pol,
882 access_mask,
883 &domain_sid,
884 &domain_pol);
886 if (!NT_STATUS_IS_OK(result))
887 goto done;
889 got_domain_pol = True;
891 /* Enumerate domain groups */
893 start_idx = 0;
894 size = 0xffff;
896 do {
897 result = rpccli_samr_EnumDomainGroups(cli, mem_ctx,
898 &domain_pol,
899 &start_idx,
900 &dom_groups,
901 size,
902 &num_dom_groups);
903 if (NT_STATUS_IS_OK(result) ||
904 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
906 for (i = 0; i < num_dom_groups; i++)
907 printf("group:[%s] rid:[0x%x]\n",
908 dom_groups->entries[i].name.string,
909 dom_groups->entries[i].idx);
912 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
914 done:
915 if (got_domain_pol)
916 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
918 if (got_connect_pol)
919 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
921 return result;
924 /* Enumerate alias groups */
926 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
927 TALLOC_CTX *mem_ctx,
928 int argc, const char **argv)
930 POLICY_HND connect_pol, domain_pol;
931 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
932 uint32 start_idx, size, num_als_groups, i;
933 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
934 struct samr_SamArray *als_groups = NULL;
935 bool got_connect_pol = False, got_domain_pol = False;
937 if ((argc < 2) || (argc > 3)) {
938 printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
939 return NT_STATUS_OK;
942 if (argc > 2)
943 sscanf(argv[2], "%x", &access_mask);
945 /* Get sam policy handle */
947 result = rpccli_try_samr_connects(cli, mem_ctx,
948 MAXIMUM_ALLOWED_ACCESS,
949 &connect_pol);
951 if (!NT_STATUS_IS_OK(result))
952 goto done;
954 got_connect_pol = True;
956 /* Get domain policy handle */
958 if (StrCaseCmp(argv[1], "domain")==0)
959 result = rpccli_samr_OpenDomain(cli, mem_ctx,
960 &connect_pol,
961 access_mask,
962 &domain_sid,
963 &domain_pol);
964 else if (StrCaseCmp(argv[1], "builtin")==0)
965 result = rpccli_samr_OpenDomain(cli, mem_ctx,
966 &connect_pol,
967 access_mask,
968 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
969 &domain_pol);
970 else
971 return NT_STATUS_OK;
973 if (!NT_STATUS_IS_OK(result))
974 goto done;
976 got_domain_pol = True;
978 /* Enumerate alias groups */
980 start_idx = 0;
981 size = 0xffff; /* Number of groups to retrieve */
983 do {
984 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx,
985 &domain_pol,
986 &start_idx,
987 &als_groups,
988 size,
989 &num_als_groups);
991 if (NT_STATUS_IS_OK(result) ||
992 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
994 for (i = 0; i < num_als_groups; i++)
995 printf("group:[%s] rid:[0x%x]\n",
996 als_groups->entries[i].name.string,
997 als_groups->entries[i].idx);
999 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1001 done:
1002 if (got_domain_pol)
1003 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1005 if (got_connect_pol)
1006 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1008 return result;
1011 /* Enumerate domains */
1013 static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
1014 TALLOC_CTX *mem_ctx,
1015 int argc, const char **argv)
1017 POLICY_HND connect_pol;
1018 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1019 uint32 start_idx, size, num_entries, i;
1020 uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1021 bool got_connect_pol = false;
1022 struct samr_SamArray *sam = NULL;
1024 if ((argc < 1) || (argc > 2)) {
1025 printf("Usage: %s [access mask]\n", argv[0]);
1026 return NT_STATUS_OK;
1029 if (argc > 1) {
1030 sscanf(argv[1], "%x", &access_mask);
1033 /* Get sam policy handle */
1035 result = rpccli_try_samr_connects(cli, mem_ctx,
1036 access_mask,
1037 &connect_pol);
1039 if (!NT_STATUS_IS_OK(result)) {
1040 goto done;
1043 got_connect_pol = true;
1045 /* Enumerate alias groups */
1047 start_idx = 0;
1048 size = 0xffff;
1050 do {
1051 result = rpccli_samr_EnumDomains(cli, mem_ctx,
1052 &connect_pol,
1053 &start_idx,
1054 &sam,
1055 size,
1056 &num_entries);
1058 if (NT_STATUS_IS_OK(result) ||
1059 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1061 for (i = 0; i < num_entries; i++)
1062 printf("name:[%s] idx:[0x%x]\n",
1063 sam->entries[i].name.string,
1064 sam->entries[i].idx);
1066 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1068 done:
1069 if (got_connect_pol) {
1070 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1073 return result;
1077 /* Query alias membership */
1079 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1080 TALLOC_CTX *mem_ctx,
1081 int argc, const char **argv)
1083 POLICY_HND connect_pol, domain_pol, alias_pol;
1084 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1085 uint32 alias_rid, i;
1086 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1087 struct lsa_SidArray sid_array;
1089 if ((argc < 3) || (argc > 4)) {
1090 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1091 return NT_STATUS_OK;
1094 sscanf(argv[2], "%i", &alias_rid);
1096 if (argc > 3)
1097 sscanf(argv[3], "%x", &access_mask);
1099 /* Open SAMR handle */
1101 result = rpccli_try_samr_connects(cli, mem_ctx,
1102 MAXIMUM_ALLOWED_ACCESS,
1103 &connect_pol);
1105 if (!NT_STATUS_IS_OK(result))
1106 goto done;
1108 /* Open handle on domain */
1110 if (StrCaseCmp(argv[1], "domain")==0)
1111 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1112 &connect_pol,
1113 MAXIMUM_ALLOWED_ACCESS,
1114 &domain_sid,
1115 &domain_pol);
1116 else if (StrCaseCmp(argv[1], "builtin")==0)
1117 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1118 &connect_pol,
1119 MAXIMUM_ALLOWED_ACCESS,
1120 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1121 &domain_pol);
1122 else
1123 return NT_STATUS_OK;
1125 if (!NT_STATUS_IS_OK(result))
1126 goto done;
1128 /* Open handle on alias */
1130 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1131 &domain_pol,
1132 access_mask,
1133 alias_rid,
1134 &alias_pol);
1135 if (!NT_STATUS_IS_OK(result))
1136 goto done;
1138 result = rpccli_samr_GetMembersInAlias(cli, mem_ctx,
1139 &alias_pol,
1140 &sid_array);
1142 if (!NT_STATUS_IS_OK(result))
1143 goto done;
1145 for (i = 0; i < sid_array.num_sids; i++) {
1146 fstring sid_str;
1148 sid_to_fstring(sid_str, sid_array.sids[i].sid);
1149 printf("\tsid:[%s]\n", sid_str);
1152 rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1153 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1154 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1155 done:
1156 return result;
1159 /* Query alias info */
1161 static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
1162 TALLOC_CTX *mem_ctx,
1163 int argc, const char **argv)
1165 POLICY_HND connect_pol, domain_pol, alias_pol;
1166 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1167 uint32_t alias_rid;
1168 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1169 union samr_AliasInfo *info = NULL;
1170 enum samr_AliasInfoEnum level = ALIASINFOALL;
1172 if ((argc < 3) || (argc > 4)) {
1173 printf("Usage: %s builtin|domain rid [level] [access mask]\n",
1174 argv[0]);
1175 return NT_STATUS_OK;
1178 sscanf(argv[2], "%i", &alias_rid);
1180 if (argc > 2) {
1181 level = atoi(argv[3]);
1184 if (argc > 3) {
1185 sscanf(argv[4], "%x", &access_mask);
1188 /* Open SAMR handle */
1190 result = rpccli_try_samr_connects(cli, mem_ctx,
1191 SEC_FLAG_MAXIMUM_ALLOWED,
1192 &connect_pol);
1194 if (!NT_STATUS_IS_OK(result)) {
1195 goto done;
1198 /* Open handle on domain */
1200 if (strequal(argv[1], "domain")) {
1202 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1203 &connect_pol,
1204 SEC_FLAG_MAXIMUM_ALLOWED,
1205 &domain_sid,
1206 &domain_pol);
1208 } else if (strequal(argv[1], "builtin")) {
1210 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1211 &connect_pol,
1212 SEC_FLAG_MAXIMUM_ALLOWED,
1213 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1214 &domain_pol);
1216 } else {
1217 return NT_STATUS_OK;
1220 if (!NT_STATUS_IS_OK(result)) {
1221 goto done;
1224 /* Open handle on alias */
1226 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1227 &domain_pol,
1228 access_mask,
1229 alias_rid,
1230 &alias_pol);
1231 if (!NT_STATUS_IS_OK(result)) {
1232 goto done;
1235 result = rpccli_samr_QueryAliasInfo(cli, mem_ctx,
1236 &alias_pol,
1237 level,
1238 &info);
1240 if (!NT_STATUS_IS_OK(result)) {
1241 goto done;
1244 switch (level) {
1245 case ALIASINFOALL:
1246 printf("Name: %s\n", info->all.name.string);
1247 printf("Description: %s\n", info->all.description.string);
1248 printf("Num Members: %d\n", info->all.num_members);
1249 break;
1250 case ALIASINFONAME:
1251 printf("Name: %s\n", info->name.string);
1252 break;
1253 case ALIASINFODESCRIPTION:
1254 printf("Description: %s\n", info->description.string);
1255 break;
1256 default:
1257 break;
1260 rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1261 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1262 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1263 done:
1264 return result;
1268 /* Query delete an alias membership */
1270 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1271 TALLOC_CTX *mem_ctx,
1272 int argc, const char **argv)
1274 POLICY_HND connect_pol, domain_pol, alias_pol;
1275 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1276 uint32 alias_rid;
1277 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1279 if (argc != 3) {
1280 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1281 return NT_STATUS_OK;
1284 alias_rid = strtoul(argv[2], NULL, 10);
1286 /* Open SAMR handle */
1288 result = rpccli_try_samr_connects(cli, mem_ctx,
1289 MAXIMUM_ALLOWED_ACCESS,
1290 &connect_pol);
1292 if (!NT_STATUS_IS_OK(result))
1293 goto done;
1295 /* Open handle on domain */
1297 if (StrCaseCmp(argv[1], "domain")==0)
1298 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1299 &connect_pol,
1300 MAXIMUM_ALLOWED_ACCESS,
1301 &domain_sid,
1302 &domain_pol);
1303 else if (StrCaseCmp(argv[1], "builtin")==0)
1304 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1305 &connect_pol,
1306 MAXIMUM_ALLOWED_ACCESS,
1307 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1308 &domain_pol);
1309 else
1310 return NT_STATUS_INVALID_PARAMETER;
1312 if (!NT_STATUS_IS_OK(result))
1313 goto done;
1315 /* Open handle on alias */
1317 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1318 &domain_pol,
1319 access_mask,
1320 alias_rid,
1321 &alias_pol);
1322 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1323 /* Probably this was a user name, try lookupnames */
1324 struct samr_Ids rids, types;
1325 struct lsa_String lsa_acct_name;
1327 init_lsa_String(&lsa_acct_name, argv[2]);
1329 result = rpccli_samr_LookupNames(cli, mem_ctx,
1330 &domain_pol,
1332 &lsa_acct_name,
1333 &rids,
1334 &types);
1336 if (NT_STATUS_IS_OK(result)) {
1337 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1338 &domain_pol,
1339 access_mask,
1340 rids.ids[0],
1341 &alias_pol);
1345 result = rpccli_samr_DeleteDomAlias(cli, mem_ctx,
1346 &alias_pol);
1348 if (!NT_STATUS_IS_OK(result))
1349 goto done;
1351 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1352 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1353 done:
1354 return result;
1357 /* Query display info */
1359 static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli,
1360 TALLOC_CTX *mem_ctx,
1361 int argc, const char **argv,
1362 uint32_t opcode)
1364 POLICY_HND connect_pol, domain_pol;
1365 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1366 uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
1367 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1368 uint32 info_level = 1;
1369 union samr_DispInfo info;
1370 int loop_count = 0;
1371 bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1372 uint32_t total_size, returned_size;
1374 if (argc > 6) {
1375 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1376 return NT_STATUS_OK;
1379 if (argc >= 2)
1380 sscanf(argv[1], "%i", &info_level);
1382 if (argc >= 3)
1383 sscanf(argv[2], "%i", &start_idx);
1385 if (argc >= 4) {
1386 sscanf(argv[3], "%i", &max_entries);
1387 got_params = True;
1390 if (argc >= 5) {
1391 sscanf(argv[4], "%i", &max_size);
1392 got_params = True;
1395 if (argc >= 6)
1396 sscanf(argv[5], "%x", &access_mask);
1398 /* Get sam policy handle */
1400 result = rpccli_try_samr_connects(cli, mem_ctx,
1401 MAXIMUM_ALLOWED_ACCESS,
1402 &connect_pol);
1404 if (!NT_STATUS_IS_OK(result))
1405 goto done;
1407 /* Get domain policy handle */
1409 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1410 &connect_pol,
1411 access_mask,
1412 &domain_sid,
1413 &domain_pol);
1415 if (!NT_STATUS_IS_OK(result))
1416 goto done;
1418 /* Query display info */
1420 do {
1422 if (!got_params)
1423 get_query_dispinfo_params(
1424 loop_count, &max_entries, &max_size);
1426 switch (opcode) {
1427 case NDR_SAMR_QUERYDISPLAYINFO:
1428 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
1429 &domain_pol,
1430 info_level,
1431 start_idx,
1432 max_entries,
1433 max_size,
1434 &total_size,
1435 &returned_size,
1436 &info);
1437 break;
1438 case NDR_SAMR_QUERYDISPLAYINFO2:
1439 result = rpccli_samr_QueryDisplayInfo2(cli, mem_ctx,
1440 &domain_pol,
1441 info_level,
1442 start_idx,
1443 max_entries,
1444 max_size,
1445 &total_size,
1446 &returned_size,
1447 &info);
1449 break;
1450 case NDR_SAMR_QUERYDISPLAYINFO3:
1451 result = rpccli_samr_QueryDisplayInfo3(cli, mem_ctx,
1452 &domain_pol,
1453 info_level,
1454 start_idx,
1455 max_entries,
1456 max_size,
1457 &total_size,
1458 &returned_size,
1459 &info);
1461 break;
1462 default:
1463 return NT_STATUS_INVALID_PARAMETER;
1466 if (!NT_STATUS_IS_OK(result) &&
1467 !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
1468 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1469 break;
1472 loop_count++;
1474 switch (info_level) {
1475 case 1:
1476 num_entries = info.info1.count;
1477 break;
1478 case 2:
1479 num_entries = info.info2.count;
1480 break;
1481 case 3:
1482 num_entries = info.info3.count;
1483 break;
1484 case 4:
1485 num_entries = info.info4.count;
1486 break;
1487 case 5:
1488 num_entries = info.info5.count;
1489 break;
1490 default:
1491 break;
1494 start_idx += num_entries;
1496 if (num_entries == 0)
1497 break;
1499 for (i = 0; i < num_entries; i++) {
1500 switch (info_level) {
1501 case 1:
1502 display_sam_info_1(&info.info1.entries[i]);
1503 break;
1504 case 2:
1505 display_sam_info_2(&info.info2.entries[i]);
1506 break;
1507 case 3:
1508 display_sam_info_3(&info.info3.entries[i]);
1509 break;
1510 case 4:
1511 display_sam_info_4(&info.info4.entries[i]);
1512 break;
1513 case 5:
1514 display_sam_info_5(&info.info5.entries[i]);
1515 break;
1518 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1520 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1521 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1522 done:
1523 return result;
1526 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1527 TALLOC_CTX *mem_ctx,
1528 int argc, const char **argv)
1530 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1531 NDR_SAMR_QUERYDISPLAYINFO);
1534 static NTSTATUS cmd_samr_query_dispinfo2(struct rpc_pipe_client *cli,
1535 TALLOC_CTX *mem_ctx,
1536 int argc, const char **argv)
1538 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1539 NDR_SAMR_QUERYDISPLAYINFO2);
1542 static NTSTATUS cmd_samr_query_dispinfo3(struct rpc_pipe_client *cli,
1543 TALLOC_CTX *mem_ctx,
1544 int argc, const char **argv)
1546 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1547 NDR_SAMR_QUERYDISPLAYINFO3);
1550 /* Query domain info */
1552 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1553 TALLOC_CTX *mem_ctx,
1554 int argc, const char **argv)
1556 POLICY_HND connect_pol, domain_pol;
1557 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1558 uint32 switch_level = 2;
1559 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1560 union samr_DomainInfo *info = NULL;
1562 if (argc > 3) {
1563 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1564 return NT_STATUS_OK;
1567 if (argc > 1)
1568 sscanf(argv[1], "%i", &switch_level);
1570 if (argc > 2)
1571 sscanf(argv[2], "%x", &access_mask);
1573 /* Get sam policy handle */
1575 result = rpccli_try_samr_connects(cli, mem_ctx,
1576 MAXIMUM_ALLOWED_ACCESS,
1577 &connect_pol);
1579 if (!NT_STATUS_IS_OK(result))
1580 goto done;
1582 /* Get domain policy handle */
1584 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1585 &connect_pol,
1586 access_mask,
1587 &domain_sid,
1588 &domain_pol);
1590 if (!NT_STATUS_IS_OK(result))
1591 goto done;
1593 /* Query domain info */
1595 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1596 &domain_pol,
1597 switch_level,
1598 &info);
1600 if (!NT_STATUS_IS_OK(result))
1601 goto done;
1603 /* Display domain info */
1605 switch (switch_level) {
1606 case 1:
1607 display_sam_dom_info_1(&info->info1);
1608 break;
1609 case 2:
1610 display_sam_dom_info_2(&info->info2);
1611 break;
1612 case 3:
1613 display_sam_dom_info_3(&info->info3);
1614 break;
1615 case 4:
1616 display_sam_dom_info_4(&info->info4);
1617 break;
1618 case 5:
1619 display_sam_dom_info_5(&info->info5);
1620 break;
1621 case 6:
1622 display_sam_dom_info_6(&info->info6);
1623 break;
1624 case 7:
1625 display_sam_dom_info_7(&info->info7);
1626 break;
1627 case 8:
1628 display_sam_dom_info_8(&info->info8);
1629 break;
1630 case 9:
1631 display_sam_dom_info_9(&info->info9);
1632 break;
1633 case 12:
1634 display_sam_dom_info_12(&info->info12);
1635 break;
1636 case 13:
1637 display_sam_dom_info_13(&info->info13);
1638 break;
1640 default:
1641 printf("cannot display domain info for switch value %d\n",
1642 switch_level);
1643 break;
1646 done:
1648 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1649 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1650 return result;
1653 /* Create domain user */
1655 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1656 TALLOC_CTX *mem_ctx,
1657 int argc, const char **argv)
1659 POLICY_HND connect_pol, domain_pol, user_pol;
1660 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1661 struct lsa_String acct_name;
1662 uint32 acb_info;
1663 uint32 acct_flags, user_rid;
1664 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1665 uint32_t access_granted = 0;
1667 if ((argc < 2) || (argc > 3)) {
1668 printf("Usage: %s username [access mask]\n", argv[0]);
1669 return NT_STATUS_OK;
1672 init_lsa_String(&acct_name, argv[1]);
1674 if (argc > 2)
1675 sscanf(argv[2], "%x", &access_mask);
1677 /* Get sam policy handle */
1679 result = rpccli_try_samr_connects(cli, mem_ctx,
1680 MAXIMUM_ALLOWED_ACCESS,
1681 &connect_pol);
1683 if (!NT_STATUS_IS_OK(result))
1684 goto done;
1686 /* Get domain policy handle */
1688 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1689 &connect_pol,
1690 access_mask,
1691 &domain_sid,
1692 &domain_pol);
1694 if (!NT_STATUS_IS_OK(result))
1695 goto done;
1697 /* Create domain user */
1699 acb_info = ACB_NORMAL;
1700 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1701 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1702 SAMR_USER_ACCESS_SET_PASSWORD |
1703 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1704 SAMR_USER_ACCESS_SET_ATTRIBUTES;
1706 result = rpccli_samr_CreateUser2(cli, mem_ctx,
1707 &domain_pol,
1708 &acct_name,
1709 acb_info,
1710 acct_flags,
1711 &user_pol,
1712 &access_granted,
1713 &user_rid);
1715 if (!NT_STATUS_IS_OK(result))
1716 goto done;
1718 result = rpccli_samr_Close(cli, mem_ctx, &user_pol);
1719 if (!NT_STATUS_IS_OK(result)) goto done;
1721 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1722 if (!NT_STATUS_IS_OK(result)) goto done;
1724 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1725 if (!NT_STATUS_IS_OK(result)) goto done;
1727 done:
1728 return result;
1731 /* Create domain group */
1733 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1734 TALLOC_CTX *mem_ctx,
1735 int argc, const char **argv)
1737 POLICY_HND connect_pol, domain_pol, group_pol;
1738 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1739 struct lsa_String grp_name;
1740 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1741 uint32_t rid = 0;
1743 if ((argc < 2) || (argc > 3)) {
1744 printf("Usage: %s groupname [access mask]\n", argv[0]);
1745 return NT_STATUS_OK;
1748 init_lsa_String(&grp_name, argv[1]);
1750 if (argc > 2)
1751 sscanf(argv[2], "%x", &access_mask);
1753 /* Get sam policy handle */
1755 result = rpccli_try_samr_connects(cli, mem_ctx,
1756 MAXIMUM_ALLOWED_ACCESS,
1757 &connect_pol);
1759 if (!NT_STATUS_IS_OK(result))
1760 goto done;
1762 /* Get domain policy handle */
1764 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1765 &connect_pol,
1766 access_mask,
1767 &domain_sid,
1768 &domain_pol);
1770 if (!NT_STATUS_IS_OK(result))
1771 goto done;
1773 /* Create domain user */
1774 result = rpccli_samr_CreateDomainGroup(cli, mem_ctx,
1775 &domain_pol,
1776 &grp_name,
1777 MAXIMUM_ALLOWED_ACCESS,
1778 &group_pol,
1779 &rid);
1781 if (!NT_STATUS_IS_OK(result))
1782 goto done;
1784 result = rpccli_samr_Close(cli, mem_ctx, &group_pol);
1785 if (!NT_STATUS_IS_OK(result)) goto done;
1787 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1788 if (!NT_STATUS_IS_OK(result)) goto done;
1790 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1791 if (!NT_STATUS_IS_OK(result)) goto done;
1793 done:
1794 return result;
1797 /* Create domain alias */
1799 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1800 TALLOC_CTX *mem_ctx,
1801 int argc, const char **argv)
1803 POLICY_HND connect_pol, domain_pol, alias_pol;
1804 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1805 struct lsa_String alias_name;
1806 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1807 uint32_t rid = 0;
1809 if ((argc < 2) || (argc > 3)) {
1810 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1811 return NT_STATUS_OK;
1814 init_lsa_String(&alias_name, argv[1]);
1816 if (argc > 2)
1817 sscanf(argv[2], "%x", &access_mask);
1819 /* Get sam policy handle */
1821 result = rpccli_try_samr_connects(cli, mem_ctx,
1822 MAXIMUM_ALLOWED_ACCESS,
1823 &connect_pol);
1825 if (!NT_STATUS_IS_OK(result))
1826 goto done;
1828 /* Get domain policy handle */
1830 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1831 &connect_pol,
1832 access_mask,
1833 &domain_sid,
1834 &domain_pol);
1836 if (!NT_STATUS_IS_OK(result))
1837 goto done;
1839 /* Create domain user */
1841 result = rpccli_samr_CreateDomAlias(cli, mem_ctx,
1842 &domain_pol,
1843 &alias_name,
1844 MAXIMUM_ALLOWED_ACCESS,
1845 &alias_pol,
1846 &rid);
1848 if (!NT_STATUS_IS_OK(result))
1849 goto done;
1851 result = rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1852 if (!NT_STATUS_IS_OK(result)) goto done;
1854 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1855 if (!NT_STATUS_IS_OK(result)) goto done;
1857 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1858 if (!NT_STATUS_IS_OK(result)) goto done;
1860 done:
1861 return result;
1864 /* Lookup sam names */
1866 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
1867 TALLOC_CTX *mem_ctx,
1868 int argc, const char **argv)
1870 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1871 POLICY_HND connect_pol, domain_pol;
1872 uint32 num_names;
1873 struct samr_Ids rids, name_types;
1874 int i;
1875 struct lsa_String *names = NULL;;
1877 if (argc < 3) {
1878 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1879 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1880 printf("or check on the builtin SID: S-1-5-32\n");
1881 return NT_STATUS_OK;
1884 /* Get sam policy and domain handles */
1886 result = rpccli_try_samr_connects(cli, mem_ctx,
1887 MAXIMUM_ALLOWED_ACCESS,
1888 &connect_pol);
1890 if (!NT_STATUS_IS_OK(result))
1891 goto done;
1893 if (StrCaseCmp(argv[1], "domain")==0)
1894 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1895 &connect_pol,
1896 MAXIMUM_ALLOWED_ACCESS,
1897 &domain_sid,
1898 &domain_pol);
1899 else if (StrCaseCmp(argv[1], "builtin")==0)
1900 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1901 &connect_pol,
1902 MAXIMUM_ALLOWED_ACCESS,
1903 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1904 &domain_pol);
1905 else
1906 return NT_STATUS_OK;
1908 if (!NT_STATUS_IS_OK(result))
1909 goto done;
1911 /* Look up names */
1913 num_names = argc - 2;
1915 if ((names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names)) == NULL) {
1916 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1917 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1918 result = NT_STATUS_NO_MEMORY;
1919 goto done;
1922 for (i = 0; i < num_names; i++) {
1923 init_lsa_String(&names[i], argv[i + 2]);
1926 result = rpccli_samr_LookupNames(cli, mem_ctx,
1927 &domain_pol,
1928 num_names,
1929 names,
1930 &rids,
1931 &name_types);
1933 if (!NT_STATUS_IS_OK(result))
1934 goto done;
1936 /* Display results */
1938 for (i = 0; i < num_names; i++)
1939 printf("name %s: 0x%x (%d)\n", names[i].string, rids.ids[i],
1940 name_types.ids[i]);
1942 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1943 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1944 done:
1945 return result;
1948 /* Lookup sam rids */
1950 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
1951 TALLOC_CTX *mem_ctx,
1952 int argc, const char **argv)
1954 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1955 POLICY_HND connect_pol, domain_pol;
1956 uint32_t num_rids, *rids;
1957 struct lsa_Strings names;
1958 struct samr_Ids types;
1960 int i;
1962 if (argc < 3) {
1963 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1964 return NT_STATUS_OK;
1967 /* Get sam policy and domain handles */
1969 result = rpccli_try_samr_connects(cli, mem_ctx,
1970 MAXIMUM_ALLOWED_ACCESS,
1971 &connect_pol);
1973 if (!NT_STATUS_IS_OK(result))
1974 goto done;
1976 if (StrCaseCmp(argv[1], "domain")==0)
1977 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1978 &connect_pol,
1979 MAXIMUM_ALLOWED_ACCESS,
1980 &domain_sid,
1981 &domain_pol);
1982 else if (StrCaseCmp(argv[1], "builtin")==0)
1983 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1984 &connect_pol,
1985 MAXIMUM_ALLOWED_ACCESS,
1986 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1987 &domain_pol);
1988 else
1989 return NT_STATUS_OK;
1991 if (!NT_STATUS_IS_OK(result))
1992 goto done;
1994 /* Look up rids */
1996 num_rids = argc - 2;
1998 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1999 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2000 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2001 result = NT_STATUS_NO_MEMORY;
2002 goto done;
2005 for (i = 0; i < argc - 2; i++)
2006 sscanf(argv[i + 2], "%i", &rids[i]);
2008 result = rpccli_samr_LookupRids(cli, mem_ctx,
2009 &domain_pol,
2010 num_rids,
2011 rids,
2012 &names,
2013 &types);
2015 if (!NT_STATUS_IS_OK(result) &&
2016 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
2017 goto done;
2019 /* Display results */
2021 for (i = 0; i < num_rids; i++) {
2022 printf("rid 0x%x: %s (%d)\n",
2023 rids[i], names.names[i].string, types.ids[i]);
2026 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2027 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2028 done:
2029 return result;
2032 /* Delete domain group */
2034 static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
2035 TALLOC_CTX *mem_ctx,
2036 int argc, const char **argv)
2038 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2039 POLICY_HND connect_pol, domain_pol, group_pol;
2040 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2042 if ((argc < 2) || (argc > 3)) {
2043 printf("Usage: %s groupname\n", argv[0]);
2044 return NT_STATUS_OK;
2047 if (argc > 2)
2048 sscanf(argv[2], "%x", &access_mask);
2050 /* Get sam policy and domain handles */
2052 result = rpccli_try_samr_connects(cli, mem_ctx,
2053 MAXIMUM_ALLOWED_ACCESS,
2054 &connect_pol);
2056 if (!NT_STATUS_IS_OK(result))
2057 goto done;
2059 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2060 &connect_pol,
2061 MAXIMUM_ALLOWED_ACCESS,
2062 &domain_sid,
2063 &domain_pol);
2065 if (!NT_STATUS_IS_OK(result))
2066 goto done;
2068 /* Get handle on group */
2071 struct samr_Ids group_rids, name_types;
2072 struct lsa_String lsa_acct_name;
2074 init_lsa_String(&lsa_acct_name, argv[1]);
2076 result = rpccli_samr_LookupNames(cli, mem_ctx,
2077 &domain_pol,
2079 &lsa_acct_name,
2080 &group_rids,
2081 &name_types);
2082 if (!NT_STATUS_IS_OK(result))
2083 goto done;
2085 result = rpccli_samr_OpenGroup(cli, mem_ctx,
2086 &domain_pol,
2087 access_mask,
2088 group_rids.ids[0],
2089 &group_pol);
2091 if (!NT_STATUS_IS_OK(result))
2092 goto done;
2095 /* Delete group */
2097 result = rpccli_samr_DeleteDomainGroup(cli, mem_ctx,
2098 &group_pol);
2100 if (!NT_STATUS_IS_OK(result))
2101 goto done;
2103 /* Display results */
2105 rpccli_samr_Close(cli, mem_ctx, &group_pol);
2106 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2107 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2109 done:
2110 return result;
2113 /* Delete domain user */
2115 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
2116 TALLOC_CTX *mem_ctx,
2117 int argc, const char **argv)
2119 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2120 POLICY_HND connect_pol, domain_pol, user_pol;
2121 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2123 if ((argc < 2) || (argc > 3)) {
2124 printf("Usage: %s username\n", argv[0]);
2125 return NT_STATUS_OK;
2128 if (argc > 2)
2129 sscanf(argv[2], "%x", &access_mask);
2131 /* Get sam policy and domain handles */
2133 result = rpccli_try_samr_connects(cli, mem_ctx,
2134 MAXIMUM_ALLOWED_ACCESS,
2135 &connect_pol);
2137 if (!NT_STATUS_IS_OK(result))
2138 goto done;
2140 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2141 &connect_pol,
2142 MAXIMUM_ALLOWED_ACCESS,
2143 &domain_sid,
2144 &domain_pol);
2146 if (!NT_STATUS_IS_OK(result))
2147 goto done;
2149 /* Get handle on user */
2152 struct samr_Ids user_rids, name_types;
2153 struct lsa_String lsa_acct_name;
2155 init_lsa_String(&lsa_acct_name, argv[1]);
2157 result = rpccli_samr_LookupNames(cli, mem_ctx,
2158 &domain_pol,
2160 &lsa_acct_name,
2161 &user_rids,
2162 &name_types);
2164 if (!NT_STATUS_IS_OK(result))
2165 goto done;
2167 result = rpccli_samr_OpenUser(cli, mem_ctx,
2168 &domain_pol,
2169 access_mask,
2170 user_rids.ids[0],
2171 &user_pol);
2173 if (!NT_STATUS_IS_OK(result))
2174 goto done;
2177 /* Delete user */
2179 result = rpccli_samr_DeleteUser(cli, mem_ctx,
2180 &user_pol);
2182 if (!NT_STATUS_IS_OK(result))
2183 goto done;
2185 /* Display results */
2187 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2188 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2189 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2191 done:
2192 return result;
2195 /**********************************************************************
2196 * Query user security object
2198 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
2199 TALLOC_CTX *mem_ctx,
2200 int argc, const char **argv)
2202 POLICY_HND connect_pol, domain_pol, user_pol, *pol;
2203 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2204 uint32 sec_info = DACL_SECURITY_INFORMATION;
2205 uint32 user_rid = 0;
2206 TALLOC_CTX *ctx = NULL;
2207 SEC_DESC_BUF *sec_desc_buf=NULL;
2208 bool domain = False;
2210 ctx=talloc_init("cmd_samr_query_sec_obj");
2212 if ((argc < 1) || (argc > 3)) {
2213 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2214 printf("\tSpecify rid for security on user, -d for security on domain\n");
2215 talloc_destroy(ctx);
2216 return NT_STATUS_OK;
2219 if (argc > 1) {
2220 if (strcmp(argv[1], "-d") == 0)
2221 domain = True;
2222 else
2223 sscanf(argv[1], "%i", &user_rid);
2226 if (argc == 3) {
2227 sec_info = atoi(argv[2]);
2230 result = rpccli_try_samr_connects(cli, mem_ctx,
2231 MAXIMUM_ALLOWED_ACCESS,
2232 &connect_pol);
2234 if (!NT_STATUS_IS_OK(result))
2235 goto done;
2237 if (domain || user_rid)
2238 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2239 &connect_pol,
2240 MAXIMUM_ALLOWED_ACCESS,
2241 &domain_sid,
2242 &domain_pol);
2244 if (!NT_STATUS_IS_OK(result))
2245 goto done;
2247 if (user_rid)
2248 result = rpccli_samr_OpenUser(cli, mem_ctx,
2249 &domain_pol,
2250 MAXIMUM_ALLOWED_ACCESS,
2251 user_rid,
2252 &user_pol);
2254 if (!NT_STATUS_IS_OK(result))
2255 goto done;
2257 /* Pick which query pol to use */
2259 pol = &connect_pol;
2261 if (domain)
2262 pol = &domain_pol;
2264 if (user_rid)
2265 pol = &user_pol;
2267 /* Query SAM security object */
2269 result = rpccli_samr_QuerySecurity(cli, mem_ctx,
2270 pol,
2271 sec_info,
2272 &sec_desc_buf);
2274 if (!NT_STATUS_IS_OK(result))
2275 goto done;
2277 display_sec_desc(sec_desc_buf->sd);
2279 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2280 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2281 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2282 done:
2283 talloc_destroy(ctx);
2284 return result;
2287 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
2288 TALLOC_CTX *mem_ctx,
2289 int argc, const char **argv)
2291 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2292 POLICY_HND connect_pol, domain_pol, user_pol;
2293 struct samr_PwInfo info;
2294 uint32_t rid;
2296 if (argc != 2) {
2297 printf("Usage: %s rid\n", argv[0]);
2298 return NT_STATUS_OK;
2301 sscanf(argv[1], "%i", &rid);
2303 result = rpccli_try_samr_connects(cli, mem_ctx,
2304 MAXIMUM_ALLOWED_ACCESS,
2305 &connect_pol);
2307 if (!NT_STATUS_IS_OK(result)) {
2308 goto done;
2311 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2312 &connect_pol,
2313 MAXIMUM_ALLOWED_ACCESS,
2314 &domain_sid,
2315 &domain_pol);
2317 if (!NT_STATUS_IS_OK(result)) {
2318 goto done;
2321 result = rpccli_samr_OpenUser(cli, mem_ctx,
2322 &domain_pol,
2323 MAXIMUM_ALLOWED_ACCESS,
2324 rid,
2325 &user_pol);
2327 if (!NT_STATUS_IS_OK(result)) {
2328 goto done;
2331 result = rpccli_samr_GetUserPwInfo(cli, mem_ctx, &user_pol, &info);
2332 if (NT_STATUS_IS_OK(result)) {
2333 printf("min_password_length: %d\n", info.min_password_length);
2334 printf("%s\n",
2335 NDR_PRINT_STRUCT_STRING(mem_ctx,
2336 samr_PasswordProperties, &info.password_properties));
2339 done:
2340 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2341 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2342 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2344 return result;
2347 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2348 TALLOC_CTX *mem_ctx,
2349 int argc, const char **argv)
2351 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2352 struct lsa_String domain_name;
2353 struct samr_PwInfo info;
2355 if (argc < 1 || argc > 3) {
2356 printf("Usage: %s <domain>\n", argv[0]);
2357 return NT_STATUS_OK;
2360 init_lsa_String(&domain_name, argv[1]);
2362 result = rpccli_samr_GetDomPwInfo(cli, mem_ctx, &domain_name, &info);
2364 if (NT_STATUS_IS_OK(result)) {
2365 printf("min_password_length: %d\n", info.min_password_length);
2366 display_password_properties(info.password_properties);
2369 return result;
2372 /* Look up domain name */
2374 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
2375 TALLOC_CTX *mem_ctx,
2376 int argc, const char **argv)
2378 POLICY_HND connect_pol, domain_pol;
2379 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2380 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2381 fstring sid_string;
2382 struct lsa_String domain_name;
2383 DOM_SID *sid = NULL;
2385 if (argc != 2) {
2386 printf("Usage: %s domain_name\n", argv[0]);
2387 return NT_STATUS_OK;
2390 init_lsa_String(&domain_name, argv[1]);
2392 result = rpccli_try_samr_connects(cli, mem_ctx,
2393 access_mask,
2394 &connect_pol);
2396 if (!NT_STATUS_IS_OK(result))
2397 goto done;
2399 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2400 &connect_pol,
2401 access_mask,
2402 &domain_sid,
2403 &domain_pol);
2405 if (!NT_STATUS_IS_OK(result))
2406 goto done;
2408 result = rpccli_samr_LookupDomain(cli, mem_ctx,
2409 &connect_pol,
2410 &domain_name,
2411 &sid);
2413 if (NT_STATUS_IS_OK(result)) {
2414 sid_to_fstring(sid_string, sid);
2415 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2416 argv[1], sid_string);
2419 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2420 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2421 done:
2422 return result;
2425 /* Change user password */
2427 static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli,
2428 TALLOC_CTX *mem_ctx,
2429 int argc, const char **argv)
2431 POLICY_HND connect_pol, domain_pol, user_pol;
2432 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2433 const char *user, *oldpass, *newpass;
2434 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2435 struct samr_Ids rids, types;
2436 struct lsa_String lsa_acct_name;
2438 if (argc < 3) {
2439 printf("Usage: %s username oldpass newpass\n", argv[0]);
2440 return NT_STATUS_INVALID_PARAMETER;
2443 user = argv[1];
2444 oldpass = argv[2];
2445 newpass = argv[3];
2447 /* Get sam policy handle */
2449 result = rpccli_try_samr_connects(cli, mem_ctx,
2450 MAXIMUM_ALLOWED_ACCESS,
2451 &connect_pol);
2453 if (!NT_STATUS_IS_OK(result)) {
2454 goto done;
2457 /* Get domain policy handle */
2459 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2460 &connect_pol,
2461 access_mask,
2462 &domain_sid,
2463 &domain_pol);
2465 if (!NT_STATUS_IS_OK(result)) {
2466 goto done;
2469 init_lsa_String(&lsa_acct_name, user);
2471 result = rpccli_samr_LookupNames(cli, mem_ctx,
2472 &domain_pol,
2474 &lsa_acct_name,
2475 &rids,
2476 &types);
2478 if (!NT_STATUS_IS_OK(result)) {
2479 goto done;
2482 result = rpccli_samr_OpenUser(cli, mem_ctx,
2483 &domain_pol,
2484 access_mask,
2485 rids.ids[0],
2486 &user_pol);
2488 if (!NT_STATUS_IS_OK(result)) {
2489 goto done;
2492 /* Change user password */
2493 result = rpccli_samr_chgpasswd_user(cli, mem_ctx,
2494 &user_pol,
2495 newpass,
2496 oldpass);
2498 if (!NT_STATUS_IS_OK(result)) {
2499 goto done;
2502 done:
2503 if (is_valid_policy_hnd(&user_pol)) {
2504 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2506 if (is_valid_policy_hnd(&domain_pol)) {
2507 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2509 if (is_valid_policy_hnd(&connect_pol)) {
2510 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2513 return result;
2517 /* Change user password */
2519 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2520 TALLOC_CTX *mem_ctx,
2521 int argc, const char **argv)
2523 POLICY_HND connect_pol, domain_pol;
2524 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2525 const char *user, *oldpass, *newpass;
2526 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2528 if (argc < 3) {
2529 printf("Usage: %s username oldpass newpass\n", argv[0]);
2530 return NT_STATUS_INVALID_PARAMETER;
2533 user = argv[1];
2534 oldpass = argv[2];
2535 newpass = argv[3];
2537 /* Get sam policy handle */
2539 result = rpccli_try_samr_connects(cli, mem_ctx,
2540 MAXIMUM_ALLOWED_ACCESS,
2541 &connect_pol);
2543 if (!NT_STATUS_IS_OK(result))
2544 goto done;
2546 /* Get domain policy handle */
2548 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2549 &connect_pol,
2550 access_mask,
2551 &domain_sid,
2552 &domain_pol);
2554 if (!NT_STATUS_IS_OK(result))
2555 goto done;
2557 /* Change user password */
2558 result = rpccli_samr_chgpasswd_user2(cli, mem_ctx, user, newpass, oldpass);
2560 if (!NT_STATUS_IS_OK(result))
2561 goto done;
2563 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2564 if (!NT_STATUS_IS_OK(result)) goto done;
2566 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2567 if (!NT_STATUS_IS_OK(result)) goto done;
2569 done:
2570 return result;
2574 /* Change user password */
2576 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
2577 TALLOC_CTX *mem_ctx,
2578 int argc, const char **argv)
2580 POLICY_HND connect_pol, domain_pol;
2581 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2582 const char *user, *oldpass, *newpass;
2583 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2584 struct samr_DomInfo1 *info = NULL;
2585 struct samr_ChangeReject *reject = NULL;
2587 if (argc < 3) {
2588 printf("Usage: %s username oldpass newpass\n", argv[0]);
2589 return NT_STATUS_INVALID_PARAMETER;
2592 user = argv[1];
2593 oldpass = argv[2];
2594 newpass = argv[3];
2596 /* Get sam policy handle */
2598 result = rpccli_try_samr_connects(cli, mem_ctx,
2599 MAXIMUM_ALLOWED_ACCESS,
2600 &connect_pol);
2602 if (!NT_STATUS_IS_OK(result))
2603 goto done;
2605 /* Get domain policy handle */
2607 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2608 &connect_pol,
2609 access_mask,
2610 &domain_sid,
2611 &domain_pol);
2613 if (!NT_STATUS_IS_OK(result))
2614 goto done;
2616 /* Change user password */
2617 result = rpccli_samr_chgpasswd_user3(cli, mem_ctx,
2618 user,
2619 newpass,
2620 oldpass,
2621 &info,
2622 &reject);
2624 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2626 display_sam_dom_info_1(info);
2628 switch (reject->reason) {
2629 case SAMR_REJECT_TOO_SHORT:
2630 d_printf("SAMR_REJECT_TOO_SHORT\n");
2631 break;
2632 case SAMR_REJECT_IN_HISTORY:
2633 d_printf("SAMR_REJECT_IN_HISTORY\n");
2634 break;
2635 case SAMR_REJECT_COMPLEXITY:
2636 d_printf("SAMR_REJECT_COMPLEXITY\n");
2637 break;
2638 case SAMR_REJECT_OTHER:
2639 d_printf("SAMR_REJECT_OTHER\n");
2640 break;
2641 default:
2642 d_printf("unknown reject reason: %d\n",
2643 reject->reason);
2644 break;
2648 if (!NT_STATUS_IS_OK(result))
2649 goto done;
2651 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2652 if (!NT_STATUS_IS_OK(result)) goto done;
2654 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2655 if (!NT_STATUS_IS_OK(result)) goto done;
2657 done:
2658 return result;
2661 static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
2662 TALLOC_CTX *mem_ctx,
2663 int argc, const char **argv)
2665 NTSTATUS status;
2666 struct policy_handle connect_handle;
2667 struct policy_handle domain_handle;
2668 uint16_t level = 1;
2669 struct lsa_String name;
2670 uint32_t idx = 0;
2672 if (argc < 2 || argc > 3) {
2673 printf("Usage: %s name level\n", argv[0]);
2674 return NT_STATUS_INVALID_PARAMETER;
2677 init_lsa_String(&name, argv[1]);
2679 if (argc == 3) {
2680 level = atoi(argv[2]);
2683 status = rpccli_try_samr_connects(cli, mem_ctx,
2684 SEC_RIGHTS_MAXIMUM_ALLOWED,
2685 &connect_handle);
2687 if (!NT_STATUS_IS_OK(status)) {
2688 goto done;
2691 status = rpccli_samr_OpenDomain(cli, mem_ctx,
2692 &connect_handle,
2693 SEC_RIGHTS_MAXIMUM_ALLOWED,
2694 &domain_sid,
2695 &domain_handle);
2697 if (!NT_STATUS_IS_OK(status))
2698 goto done;
2701 status = rpccli_samr_GetDisplayEnumerationIndex(cli, mem_ctx,
2702 &domain_handle,
2703 level,
2704 &name,
2705 &idx);
2707 if (NT_STATUS_IS_OK(status) ||
2708 NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
2709 printf("idx: %d (0x%08x)\n", idx, idx);
2711 done:
2713 if (is_valid_policy_hnd(&domain_handle)) {
2714 rpccli_samr_Close(cli, mem_ctx, &domain_handle);
2716 if (is_valid_policy_hnd(&connect_handle)) {
2717 rpccli_samr_Close(cli, mem_ctx, &connect_handle);
2720 return status;
2723 /* List of commands exported by this module */
2725 struct cmd_set samr_commands[] = {
2727 { "SAMR" },
2729 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, &ndr_table_samr.syntax_id, NULL, "Query user info", "" },
2730 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, &ndr_table_samr.syntax_id, NULL, "Query group info", "" },
2731 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, &ndr_table_samr.syntax_id, NULL, "Query user groups", "" },
2732 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, &ndr_table_samr.syntax_id, NULL, "Query user aliases", "" },
2733 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, &ndr_table_samr.syntax_id, NULL, "Query group membership", "" },
2734 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, &ndr_table_samr.syntax_id, NULL, "Query alias membership", "" },
2735 { "queryaliasinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query alias info", "" },
2736 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, &ndr_table_samr.syntax_id, NULL, "Delete an alias", "" },
2737 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
2738 { "querydispinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo2, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
2739 { "querydispinfo3", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo3, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
2740 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query domain info", "" },
2741 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domain users", "" },
2742 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domain groups", "" },
2743 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate alias groups", "" },
2744 { "enumdomains", RPC_RTYPE_NTSTATUS, cmd_samr_enum_domains, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domains", "" },
2746 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain user", "" },
2747 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain group", "" },
2748 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain alias", "" },
2749 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, &ndr_table_samr.syntax_id, NULL, "Look up names", "" },
2750 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, &ndr_table_samr.syntax_id, NULL, "Look up names", "" },
2751 { "deletedomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group, NULL, &ndr_table_samr.syntax_id, NULL, "Delete domain group", "" },
2752 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, &ndr_table_samr.syntax_id, NULL, "Delete domain user", "" },
2753 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, &ndr_table_samr.syntax_id, NULL, "Query SAMR security object", "" },
2754 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Retrieve domain password info", "" },
2755 { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Retrieve user domain password info", "" },
2757 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, &ndr_table_samr.syntax_id, NULL, "Lookup Domain Name", "" },
2758 { "chgpasswd", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
2759 { "chgpasswd2", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
2760 { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
2761 { "getdispinfoidx", RPC_RTYPE_NTSTATUS, cmd_samr_get_dispinfo_idx, NULL, &ndr_table_samr.syntax_id, NULL, "Get Display Information Index", "" },
2762 { NULL }