WHATSNEW: Add release notes for Samba 3.6.23.
[Samba.git] / source3 / rpcclient / cmd_samr.c
blobf252acce4fffb009fe9b9c34ca536a1d0bd18cce
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"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../librpc/gen_ndr/ndr_samr.h"
29 #include "../librpc/gen_ndr/ndr_samr_c.h"
30 #include "rpc_client/cli_samr.h"
31 #include "rpc_client/init_samr.h"
32 #include "rpc_client/init_lsa.h"
33 #include "../libcli/security/security.h"
35 extern struct dom_sid domain_sid;
37 /****************************************************************************
38 display samr_user_info_7 structure
39 ****************************************************************************/
40 static void display_samr_user_info_7(struct samr_UserInfo7 *r)
42 printf("\tUser Name :\t%s\n", r->account_name.string);
45 /****************************************************************************
46 display samr_user_info_9 structure
47 ****************************************************************************/
48 static void display_samr_user_info_9(struct samr_UserInfo9 *r)
50 printf("\tPrimary group RID :\tox%x\n", r->primary_gid);
53 /****************************************************************************
54 display samr_user_info_16 structure
55 ****************************************************************************/
56 static void display_samr_user_info_16(struct samr_UserInfo16 *r)
58 printf("\tAcct Flags :\tox%x\n", r->acct_flags);
61 /****************************************************************************
62 display samr_user_info_20 structure
63 ****************************************************************************/
64 static void display_samr_user_info_20(struct samr_UserInfo20 *r)
66 printf("\tRemote Dial :\n");
67 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
71 /****************************************************************************
72 display samr_user_info_21 structure
73 ****************************************************************************/
74 static void display_samr_user_info_21(struct samr_UserInfo21 *r)
76 printf("\tUser Name :\t%s\n", r->account_name.string);
77 printf("\tFull Name :\t%s\n", r->full_name.string);
78 printf("\tHome Drive :\t%s\n", r->home_directory.string);
79 printf("\tDir Drive :\t%s\n", r->home_drive.string);
80 printf("\tProfile Path:\t%s\n", r->profile_path.string);
81 printf("\tLogon Script:\t%s\n", r->logon_script.string);
82 printf("\tDescription :\t%s\n", r->description.string);
83 printf("\tWorkstations:\t%s\n", r->workstations.string);
84 printf("\tComment :\t%s\n", r->comment.string);
85 printf("\tRemote Dial :\n");
86 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
88 printf("\tLogon Time :\t%s\n",
89 http_timestring(talloc_tos(), nt_time_to_unix(r->last_logon)));
90 printf("\tLogoff Time :\t%s\n",
91 http_timestring(talloc_tos(), nt_time_to_unix(r->last_logoff)));
92 printf("\tKickoff Time :\t%s\n",
93 http_timestring(talloc_tos(), nt_time_to_unix(r->acct_expiry)));
94 printf("\tPassword last set Time :\t%s\n",
95 http_timestring(talloc_tos(), nt_time_to_unix(r->last_password_change)));
96 printf("\tPassword can change Time :\t%s\n",
97 http_timestring(talloc_tos(), nt_time_to_unix(r->allow_password_change)));
98 printf("\tPassword must change Time:\t%s\n",
99 http_timestring(talloc_tos(), nt_time_to_unix(r->force_password_change)));
101 printf("\tunknown_2[0..31]...\n"); /* user passwords? */
103 printf("\tuser_rid :\t0x%x\n" , r->rid); /* User ID */
104 printf("\tgroup_rid:\t0x%x\n" , r->primary_gid); /* Group ID */
105 printf("\tacb_info :\t0x%08x\n", r->acct_flags); /* Account Control Info */
107 printf("\tfields_present:\t0x%08x\n", r->fields_present); /* 0x00ff ffff */
108 printf("\tlogon_divs:\t%d\n", r->logon_hours.units_per_week); /* 0x0000 00a8 which is 168 which is num hrs in a week */
109 printf("\tbad_password_count:\t0x%08x\n", r->bad_password_count);
110 printf("\tlogon_count:\t0x%08x\n", r->logon_count);
112 printf("\tpadding1[0..7]...\n");
114 if (r->logon_hours.bits) {
115 printf("\tlogon_hrs[0..%d]...\n", r->logon_hours.units_per_week/8);
120 static void display_password_properties(uint32_t password_properties)
122 printf("password_properties: 0x%08x\n", password_properties);
124 if (password_properties & DOMAIN_PASSWORD_COMPLEX)
125 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
127 if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
128 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
130 if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
131 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
133 if (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)
134 printf("\tDOMAIN_PASSWORD_LOCKOUT_ADMINS\n");
136 if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
137 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
139 if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
140 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
143 static void display_sam_dom_info_1(struct samr_DomInfo1 *info1)
145 printf("Minimum password length:\t\t\t%d\n",
146 info1->min_password_length);
147 printf("Password uniqueness (remember x passwords):\t%d\n",
148 info1->password_history_length);
149 display_password_properties(info1->password_properties);
150 printf("password expire in:\t\t\t\t%s\n",
151 display_time(info1->max_password_age));
152 printf("Min password age (allow changing in x days):\t%s\n",
153 display_time(info1->min_password_age));
156 static void display_sam_dom_info_2(struct samr_DomGeneralInformation *general)
158 printf("Domain:\t\t%s\n", general->domain_name.string);
159 printf("Server:\t\t%s\n", general->primary.string);
160 printf("Comment:\t%s\n", general->oem_information.string);
162 printf("Total Users:\t%d\n", general->num_users);
163 printf("Total Groups:\t%d\n", general->num_groups);
164 printf("Total Aliases:\t%d\n", general->num_aliases);
166 printf("Sequence No:\t%llu\n", (unsigned long long)general->sequence_num);
168 printf("Force Logoff:\t%d\n",
169 (int)nt_time_to_unix_abs(&general->force_logoff_time));
171 printf("Domain Server State:\t0x%x\n", general->domain_server_state);
172 printf("Server Role:\t%s\n", server_role_str(general->role));
173 printf("Unknown 3:\t0x%x\n", general->unknown3);
176 static void display_sam_dom_info_3(struct samr_DomInfo3 *info3)
178 printf("Force Logoff:\t%d\n",
179 (int)nt_time_to_unix_abs(&info3->force_logoff_time));
182 static void display_sam_dom_info_4(struct samr_DomOEMInformation *oem)
184 printf("Comment:\t%s\n", oem->oem_information.string);
187 static void display_sam_dom_info_5(struct samr_DomInfo5 *info5)
189 printf("Domain:\t\t%s\n", info5->domain_name.string);
192 static void display_sam_dom_info_6(struct samr_DomInfo6 *info6)
194 printf("Server:\t\t%s\n", info6->primary.string);
197 static void display_sam_dom_info_7(struct samr_DomInfo7 *info7)
199 printf("Server Role:\t%s\n", server_role_str(info7->role));
202 static void display_sam_dom_info_8(struct samr_DomInfo8 *info8)
204 printf("Sequence No:\t%llu\n", (unsigned long long)info8->sequence_num);
205 printf("Domain Create Time:\t%s\n",
206 http_timestring(talloc_tos(), nt_time_to_unix(info8->domain_create_time)));
209 static void display_sam_dom_info_9(struct samr_DomInfo9 *info9)
211 printf("Domain Server State:\t0x%x\n", info9->domain_server_state);
214 static void display_sam_dom_info_12(struct samr_DomInfo12 *info12)
216 printf("Bad password lockout duration: %s\n",
217 display_time(info12->lockout_duration));
218 printf("Reset Lockout after: %s\n",
219 display_time(info12->lockout_window));
220 printf("Lockout after bad attempts: %d\n",
221 info12->lockout_threshold);
224 static void display_sam_dom_info_13(struct samr_DomInfo13 *info13)
226 printf("Sequence No:\t%llu\n", (unsigned long long)info13->sequence_num);
227 printf("Domain Create Time:\t%s\n",
228 http_timestring(talloc_tos(), nt_time_to_unix(info13->domain_create_time)));
229 printf("Sequence No at last promotion:\t%llu\n",
230 (unsigned long long)info13->modified_count_at_last_promotion);
233 static void display_sam_info_1(struct samr_DispEntryGeneral *r)
235 printf("index: 0x%x ", r->idx);
236 printf("RID: 0x%x ", r->rid);
237 printf("acb: 0x%08x ", r->acct_flags);
238 printf("Account: %s\t", r->account_name.string);
239 printf("Name: %s\t", r->full_name.string);
240 printf("Desc: %s\n", r->description.string);
243 static void display_sam_info_2(struct samr_DispEntryFull *r)
245 printf("index: 0x%x ", r->idx);
246 printf("RID: 0x%x ", r->rid);
247 printf("acb: 0x%08x ", r->acct_flags);
248 printf("Account: %s\t", r->account_name.string);
249 printf("Desc: %s\n", r->description.string);
252 static void display_sam_info_3(struct samr_DispEntryFullGroup *r)
254 printf("index: 0x%x ", r->idx);
255 printf("RID: 0x%x ", r->rid);
256 printf("acb: 0x%08x ", r->acct_flags);
257 printf("Account: %s\t", r->account_name.string);
258 printf("Desc: %s\n", r->description.string);
261 static void display_sam_info_4(struct samr_DispEntryAscii *r)
263 printf("index: 0x%x ", r->idx);
264 printf("Account: %s\n", r->account_name.string);
267 static void display_sam_info_5(struct samr_DispEntryAscii *r)
269 printf("index: 0x%x ", r->idx);
270 printf("Account: %s\n", r->account_name.string);
273 /****************************************************************************
274 ****************************************************************************/
276 static NTSTATUS get_domain_handle(struct rpc_pipe_client *cli,
277 TALLOC_CTX *mem_ctx,
278 const char *sam,
279 struct policy_handle *connect_pol,
280 uint32_t access_mask,
281 struct dom_sid *_domain_sid,
282 struct policy_handle *domain_pol)
284 struct dcerpc_binding_handle *b = cli->binding_handle;
285 NTSTATUS status = NT_STATUS_INVALID_PARAMETER, result;
287 if (StrCaseCmp(sam, "domain") == 0) {
288 status = dcerpc_samr_OpenDomain(b, mem_ctx,
289 connect_pol,
290 access_mask,
291 _domain_sid,
292 domain_pol,
293 &result);
294 } else if (StrCaseCmp(sam, "builtin") == 0) {
295 status = dcerpc_samr_OpenDomain(b, mem_ctx,
296 connect_pol,
297 access_mask,
298 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
299 domain_pol,
300 &result);
303 if (!NT_STATUS_IS_OK(status)) {
304 return status;
307 return result;
310 /**********************************************************************
311 * Query user information
313 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
314 TALLOC_CTX *mem_ctx,
315 int argc, const char **argv)
317 struct policy_handle connect_pol, domain_pol, user_pol;
318 NTSTATUS status, result;
319 uint32 info_level = 21;
320 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
321 union samr_UserInfo *info = NULL;
322 uint32 user_rid = 0;
323 struct dcerpc_binding_handle *b = cli->binding_handle;
325 if ((argc < 2) || (argc > 4)) {
326 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
327 return NT_STATUS_OK;
330 sscanf(argv[1], "%i", &user_rid);
332 if (argc > 2)
333 sscanf(argv[2], "%i", &info_level);
335 if (argc > 3)
336 sscanf(argv[3], "%x", &access_mask);
339 status = rpccli_try_samr_connects(cli, mem_ctx,
340 MAXIMUM_ALLOWED_ACCESS,
341 &connect_pol);
342 if (!NT_STATUS_IS_OK(status)) {
343 goto done;
346 status = dcerpc_samr_OpenDomain(b, mem_ctx,
347 &connect_pol,
348 MAXIMUM_ALLOWED_ACCESS,
349 &domain_sid,
350 &domain_pol,
351 &result);
352 if (!NT_STATUS_IS_OK(status)) {
353 goto done;
355 if (!NT_STATUS_IS_OK(result)) {
356 status = result;
357 goto done;
360 status = dcerpc_samr_OpenUser(b, mem_ctx,
361 &domain_pol,
362 access_mask,
363 user_rid,
364 &user_pol,
365 &result);
366 if (!NT_STATUS_IS_OK(status)) {
367 goto done;
369 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
370 (user_rid == 0)) {
372 /* Probably this was a user name, try lookupnames */
373 struct samr_Ids rids, types;
374 struct lsa_String lsa_acct_name;
376 init_lsa_String(&lsa_acct_name, argv[1]);
378 status = dcerpc_samr_LookupNames(b, mem_ctx,
379 &domain_pol,
381 &lsa_acct_name,
382 &rids,
383 &types,
384 &result);
385 if (!NT_STATUS_IS_OK(status)) {
386 goto done;
389 if (NT_STATUS_IS_OK(result)) {
390 if (rids.count != 1) {
391 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
392 goto done;
394 if (types.count != 1) {
395 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
396 goto done;
399 status = dcerpc_samr_OpenUser(b, mem_ctx,
400 &domain_pol,
401 access_mask,
402 rids.ids[0],
403 &user_pol,
404 &result);
405 if (!NT_STATUS_IS_OK(status)) {
406 goto done;
412 if (!NT_STATUS_IS_OK(result)) {
413 status = result;
414 goto done;
417 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
418 &user_pol,
419 info_level,
420 &info,
421 &result);
422 if (!NT_STATUS_IS_OK(status)) {
423 goto done;
425 if (!NT_STATUS_IS_OK(result)) {
426 status = result;
427 goto done;
430 switch (info_level) {
431 case 7:
432 display_samr_user_info_7(&info->info7);
433 break;
434 case 9:
435 display_samr_user_info_9(&info->info9);
436 break;
437 case 16:
438 display_samr_user_info_16(&info->info16);
439 break;
440 case 20:
441 display_samr_user_info_20(&info->info20);
442 break;
443 case 21:
444 display_samr_user_info_21(&info->info21);
445 break;
446 default:
447 printf("Unsupported infolevel: %d\n", info_level);
448 break;
451 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
452 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
453 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
455 done:
456 return status;
459 /****************************************************************************
460 display group info
461 ****************************************************************************/
462 static void display_group_info1(struct samr_GroupInfoAll *info1)
464 printf("\tGroup Name:\t%s\n", info1->name.string);
465 printf("\tDescription:\t%s\n", info1->description.string);
466 printf("\tGroup Attribute:%d\n", info1->attributes);
467 printf("\tNum Members:%d\n", info1->num_members);
470 /****************************************************************************
471 display group info
472 ****************************************************************************/
473 static void display_group_info2(struct lsa_String *info2)
475 printf("\tGroup Description:%s\n", info2->string);
479 /****************************************************************************
480 display group info
481 ****************************************************************************/
482 static void display_group_info3(struct samr_GroupInfoAttributes *info3)
484 printf("\tGroup Attribute:%d\n", info3->attributes);
488 /****************************************************************************
489 display group info
490 ****************************************************************************/
491 static void display_group_info4(struct lsa_String *info4)
493 printf("\tGroup Description:%s\n", info4->string);
496 /****************************************************************************
497 display group info
498 ****************************************************************************/
499 static void display_group_info5(struct samr_GroupInfoAll *info5)
501 printf("\tGroup Name:\t%s\n", info5->name.string);
502 printf("\tDescription:\t%s\n", info5->description.string);
503 printf("\tGroup Attribute:%d\n", info5->attributes);
504 printf("\tNum Members:%d\n", info5->num_members);
507 /****************************************************************************
508 display sam sync structure
509 ****************************************************************************/
510 static void display_group_info(union samr_GroupInfo *info,
511 enum samr_GroupInfoEnum level)
513 switch (level) {
514 case 1:
515 display_group_info1(&info->all);
516 break;
517 case 2:
518 display_group_info2(&info->name);
519 break;
520 case 3:
521 display_group_info3(&info->attributes);
522 break;
523 case 4:
524 display_group_info4(&info->description);
525 break;
526 case 5:
527 display_group_info5(&info->all2);
528 break;
532 /***********************************************************************
533 * Query group information
535 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
536 TALLOC_CTX *mem_ctx,
537 int argc, const char **argv)
539 struct policy_handle connect_pol, domain_pol, group_pol;
540 NTSTATUS status, result;
541 enum samr_GroupInfoEnum info_level = GROUPINFOALL;
542 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
543 union samr_GroupInfo *group_info = NULL;
544 uint32 group_rid;
545 struct dcerpc_binding_handle *b = cli->binding_handle;
547 if ((argc < 2) || (argc > 4)) {
548 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
549 return NT_STATUS_OK;
552 sscanf(argv[1], "%i", &group_rid);
554 if (argc > 2)
555 info_level = atoi(argv[2]);
557 if (argc > 3)
558 sscanf(argv[3], "%x", &access_mask);
560 status = rpccli_try_samr_connects(cli, mem_ctx,
561 MAXIMUM_ALLOWED_ACCESS,
562 &connect_pol);
563 if (!NT_STATUS_IS_OK(status)) {
564 goto done;
567 status = dcerpc_samr_OpenDomain(b, mem_ctx,
568 &connect_pol,
569 MAXIMUM_ALLOWED_ACCESS,
570 &domain_sid,
571 &domain_pol,
572 &result);
573 if (!NT_STATUS_IS_OK(status)) {
574 goto done;
576 if (!NT_STATUS_IS_OK(result)) {
577 status = result;
578 goto done;
581 status = dcerpc_samr_OpenGroup(b, mem_ctx,
582 &domain_pol,
583 access_mask,
584 group_rid,
585 &group_pol,
586 &result);
587 if (!NT_STATUS_IS_OK(status)) {
588 goto done;
590 if (!NT_STATUS_IS_OK(result)) {
591 status = result;
592 goto done;
595 status = dcerpc_samr_QueryGroupInfo(b, mem_ctx,
596 &group_pol,
597 info_level,
598 &group_info,
599 &result);
600 if (!NT_STATUS_IS_OK(status)) {
601 goto done;
603 if (!NT_STATUS_IS_OK(result)) {
604 status = result;
605 goto done;
608 display_group_info(group_info, info_level);
610 dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
611 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
612 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
613 done:
614 return status;
617 /* Query groups a user is a member of */
619 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
620 TALLOC_CTX *mem_ctx,
621 int argc, const char **argv)
623 struct policy_handle connect_pol,
624 domain_pol,
625 user_pol;
626 NTSTATUS status, result;
627 uint32 user_rid;
628 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
629 int i;
630 struct samr_RidWithAttributeArray *rid_array = NULL;
631 struct dcerpc_binding_handle *b = cli->binding_handle;
633 if ((argc < 2) || (argc > 3)) {
634 printf("Usage: %s rid [access mask]\n", argv[0]);
635 return NT_STATUS_OK;
638 sscanf(argv[1], "%i", &user_rid);
640 if (argc > 2)
641 sscanf(argv[2], "%x", &access_mask);
643 status = rpccli_try_samr_connects(cli, mem_ctx,
644 MAXIMUM_ALLOWED_ACCESS,
645 &connect_pol);
646 if (!NT_STATUS_IS_OK(status)) {
647 goto done;
650 status = dcerpc_samr_OpenDomain(b, mem_ctx,
651 &connect_pol,
652 MAXIMUM_ALLOWED_ACCESS,
653 &domain_sid,
654 &domain_pol,
655 &result);
656 if (!NT_STATUS_IS_OK(status)) {
657 goto done;
659 if (!NT_STATUS_IS_OK(result)) {
660 status = result;
661 goto done;
664 status = dcerpc_samr_OpenUser(b, mem_ctx,
665 &domain_pol,
666 access_mask,
667 user_rid,
668 &user_pol,
669 &result);
671 if (!NT_STATUS_IS_OK(status)) {
672 goto done;
674 if (!NT_STATUS_IS_OK(result)) {
675 status = result;
676 goto done;
679 status = dcerpc_samr_GetGroupsForUser(b, mem_ctx,
680 &user_pol,
681 &rid_array,
682 &result);
683 if (!NT_STATUS_IS_OK(status)) {
684 goto done;
686 if (!NT_STATUS_IS_OK(result)) {
687 status = result;
688 goto done;
691 for (i = 0; i < rid_array->count; i++) {
692 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
693 rid_array->rids[i].rid,
694 rid_array->rids[i].attributes);
697 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
698 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
699 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
700 done:
701 return status;
704 /* Query aliases a user is a member of */
706 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
707 TALLOC_CTX *mem_ctx,
708 int argc, const char **argv)
710 struct policy_handle connect_pol, domain_pol;
711 NTSTATUS status, result;
712 struct dom_sid *sids;
713 uint32_t num_sids;
714 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
715 int i;
716 struct lsa_SidArray sid_array;
717 struct samr_Ids alias_rids;
718 struct dcerpc_binding_handle *b = cli->binding_handle;
720 if (argc < 3) {
721 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
722 return NT_STATUS_INVALID_PARAMETER;
725 sids = NULL;
726 num_sids = 0;
728 for (i=2; i<argc; i++) {
729 struct dom_sid tmp_sid;
730 if (!string_to_sid(&tmp_sid, argv[i])) {
731 printf("%s is not a legal SID\n", argv[i]);
732 return NT_STATUS_INVALID_PARAMETER;
734 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
735 if (!NT_STATUS_IS_OK(result)) {
736 return result;
740 if (num_sids) {
741 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids);
742 if (sid_array.sids == NULL)
743 return NT_STATUS_NO_MEMORY;
744 } else {
745 sid_array.sids = NULL;
748 for (i=0; i<num_sids; i++) {
749 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]);
750 if (!sid_array.sids[i].sid) {
751 return NT_STATUS_NO_MEMORY;
755 sid_array.num_sids = num_sids;
757 status = rpccli_try_samr_connects(cli, mem_ctx,
758 MAXIMUM_ALLOWED_ACCESS,
759 &connect_pol);
760 if (!NT_STATUS_IS_OK(status)) {
761 goto done;
764 status = get_domain_handle(cli, mem_ctx, argv[1],
765 &connect_pol,
766 access_mask,
767 &domain_sid,
768 &domain_pol);
769 if (!NT_STATUS_IS_OK(status)) {
770 goto done;
773 status = dcerpc_samr_GetAliasMembership(b, mem_ctx,
774 &domain_pol,
775 &sid_array,
776 &alias_rids,
777 &result);
778 if (!NT_STATUS_IS_OK(status)) {
779 goto done;
781 if (!NT_STATUS_IS_OK(result)) {
782 status = result;
783 goto done;
786 for (i = 0; i < alias_rids.count; i++) {
787 printf("\tgroup rid:[0x%x]\n", alias_rids.ids[i]);
790 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
791 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
792 done:
793 return status;
796 /* Query members of a group */
798 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
799 TALLOC_CTX *mem_ctx,
800 int argc, const char **argv)
802 struct policy_handle connect_pol, domain_pol, group_pol;
803 NTSTATUS status, result;
804 uint32 group_rid;
805 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
806 int i;
807 unsigned int old_timeout;
808 struct samr_RidAttrArray *rids = NULL;
809 struct dcerpc_binding_handle *b = cli->binding_handle;
811 if ((argc < 2) || (argc > 3)) {
812 printf("Usage: %s rid [access mask]\n", argv[0]);
813 return NT_STATUS_OK;
816 sscanf(argv[1], "%i", &group_rid);
818 if (argc > 2)
819 sscanf(argv[2], "%x", &access_mask);
821 status = rpccli_try_samr_connects(cli, mem_ctx,
822 MAXIMUM_ALLOWED_ACCESS,
823 &connect_pol);
824 if (!NT_STATUS_IS_OK(status)) {
825 goto done;
828 status = dcerpc_samr_OpenDomain(b, mem_ctx,
829 &connect_pol,
830 MAXIMUM_ALLOWED_ACCESS,
831 &domain_sid,
832 &domain_pol,
833 &result);
834 if (!NT_STATUS_IS_OK(status)) {
835 goto done;
837 if (!NT_STATUS_IS_OK(result)) {
838 status = result;
839 goto done;
842 status = dcerpc_samr_OpenGroup(b, mem_ctx,
843 &domain_pol,
844 access_mask,
845 group_rid,
846 &group_pol,
847 &result);
848 if (!NT_STATUS_IS_OK(status)) {
849 goto done;
851 if (!NT_STATUS_IS_OK(result)) {
852 status = result;
853 goto done;
856 /* Make sure to wait for our DC's reply */
857 old_timeout = rpccli_set_timeout(cli, 30000); /* 30 seconds. */
858 rpccli_set_timeout(cli, MAX(30000, old_timeout)); /* At least 30 sec */
860 status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
861 &group_pol,
862 &rids,
863 &result);
865 rpccli_set_timeout(cli, old_timeout);
867 if (!NT_STATUS_IS_OK(status)) {
868 goto done;
870 if (!NT_STATUS_IS_OK(result)) {
871 status = result;
872 goto done;
875 for (i = 0; i < rids->count; i++) {
876 printf("\trid:[0x%x] attr:[0x%x]\n", rids->rids[i],
877 rids->attributes[i]);
880 dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
881 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
882 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
883 done:
884 return status;
887 /* Enumerate domain users */
889 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
890 TALLOC_CTX *mem_ctx,
891 int argc, const char **argv)
893 struct policy_handle connect_pol, domain_pol;
894 NTSTATUS status, result;
895 uint32 start_idx, num_dom_users, i;
896 struct samr_SamArray *dom_users = NULL;
897 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
898 uint32 acb_mask = ACB_NORMAL;
899 uint32_t size = 0xffff;
900 struct dcerpc_binding_handle *b = cli->binding_handle;
902 if ((argc < 1) || (argc > 4)) {
903 printf("Usage: %s [access_mask] [acb_mask] [size]\n", argv[0]);
904 return NT_STATUS_OK;
907 if (argc > 1) {
908 sscanf(argv[1], "%x", &access_mask);
911 if (argc > 2) {
912 sscanf(argv[2], "%x", &acb_mask);
915 if (argc > 3) {
916 sscanf(argv[3], "%x", &size);
919 /* Get sam policy handle */
921 status = rpccli_try_samr_connects(cli, mem_ctx,
922 MAXIMUM_ALLOWED_ACCESS,
923 &connect_pol);
924 if (!NT_STATUS_IS_OK(status)) {
925 goto done;
928 /* Get domain policy handle */
930 status = get_domain_handle(cli, mem_ctx, "domain",
931 &connect_pol,
932 access_mask,
933 &domain_sid,
934 &domain_pol);
935 if (!NT_STATUS_IS_OK(status)) {
936 goto done;
939 /* Enumerate domain users */
941 start_idx = 0;
943 do {
944 status = dcerpc_samr_EnumDomainUsers(b, mem_ctx,
945 &domain_pol,
946 &start_idx,
947 acb_mask,
948 &dom_users,
949 size,
950 &num_dom_users,
951 &result);
952 if (!NT_STATUS_IS_OK(status)) {
953 goto done;
955 if (NT_STATUS_IS_OK(result) ||
956 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
958 for (i = 0; i < num_dom_users; i++)
959 printf("user:[%s] rid:[0x%x]\n",
960 dom_users->entries[i].name.string,
961 dom_users->entries[i].idx);
964 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
966 done:
967 if (is_valid_policy_hnd(&domain_pol))
968 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
970 if (is_valid_policy_hnd(&connect_pol))
971 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
973 return status;
976 /* Enumerate domain groups */
978 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
979 TALLOC_CTX *mem_ctx,
980 int argc, const char **argv)
982 struct policy_handle connect_pol, domain_pol;
983 NTSTATUS status, result;
984 uint32 start_idx, num_dom_groups, i;
985 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
986 struct samr_SamArray *dom_groups = NULL;
987 uint32_t size = 0xffff;
988 struct dcerpc_binding_handle *b = cli->binding_handle;
990 if ((argc < 1) || (argc > 3)) {
991 printf("Usage: %s [access_mask] [max_size]\n", argv[0]);
992 return NT_STATUS_OK;
995 if (argc > 1) {
996 sscanf(argv[1], "%x", &access_mask);
999 if (argc > 2) {
1000 sscanf(argv[2], "%x", &size);
1003 /* Get sam policy handle */
1005 status = rpccli_try_samr_connects(cli, mem_ctx,
1006 MAXIMUM_ALLOWED_ACCESS,
1007 &connect_pol);
1008 if (!NT_STATUS_IS_OK(status)) {
1009 goto done;
1012 /* Get domain policy handle */
1014 status = get_domain_handle(cli, mem_ctx, "domain",
1015 &connect_pol,
1016 access_mask,
1017 &domain_sid,
1018 &domain_pol);
1019 if (!NT_STATUS_IS_OK(status)) {
1020 goto done;
1023 /* Enumerate domain groups */
1025 start_idx = 0;
1027 do {
1028 status = dcerpc_samr_EnumDomainGroups(b, mem_ctx,
1029 &domain_pol,
1030 &start_idx,
1031 &dom_groups,
1032 size,
1033 &num_dom_groups,
1034 &result);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 goto done;
1038 if (NT_STATUS_IS_OK(result) ||
1039 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1041 for (i = 0; i < num_dom_groups; i++)
1042 printf("group:[%s] rid:[0x%x]\n",
1043 dom_groups->entries[i].name.string,
1044 dom_groups->entries[i].idx);
1047 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1049 done:
1050 if (is_valid_policy_hnd(&domain_pol))
1051 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1053 if (is_valid_policy_hnd(&connect_pol))
1054 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1056 return status;
1059 /* Enumerate alias groups */
1061 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
1062 TALLOC_CTX *mem_ctx,
1063 int argc, const char **argv)
1065 struct policy_handle connect_pol, domain_pol;
1066 NTSTATUS status, result;
1067 uint32 start_idx, num_als_groups, i;
1068 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1069 struct samr_SamArray *als_groups = NULL;
1070 uint32_t size = 0xffff;
1071 struct dcerpc_binding_handle *b = cli->binding_handle;
1073 if ((argc < 2) || (argc > 4)) {
1074 printf("Usage: %s builtin|domain [access mask] [max_size]\n", argv[0]);
1075 return NT_STATUS_OK;
1078 if (argc > 2) {
1079 sscanf(argv[2], "%x", &access_mask);
1082 if (argc > 3) {
1083 sscanf(argv[3], "%x", &size);
1086 /* Get sam policy handle */
1088 status = rpccli_try_samr_connects(cli, mem_ctx,
1089 MAXIMUM_ALLOWED_ACCESS,
1090 &connect_pol);
1091 if (!NT_STATUS_IS_OK(status)) {
1092 goto done;
1095 /* Get domain policy handle */
1097 status = get_domain_handle(cli, mem_ctx, argv[1],
1098 &connect_pol,
1099 access_mask,
1100 &domain_sid,
1101 &domain_pol);
1102 if (!NT_STATUS_IS_OK(status)) {
1103 goto done;
1106 /* Enumerate alias groups */
1108 start_idx = 0;
1110 do {
1111 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
1112 &domain_pol,
1113 &start_idx,
1114 &als_groups,
1115 size,
1116 &num_als_groups,
1117 &result);
1118 if (!NT_STATUS_IS_OK(status)) {
1119 goto done;
1121 if (NT_STATUS_IS_OK(result) ||
1122 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1124 for (i = 0; i < num_als_groups; i++)
1125 printf("group:[%s] rid:[0x%x]\n",
1126 als_groups->entries[i].name.string,
1127 als_groups->entries[i].idx);
1129 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1131 done:
1132 if (is_valid_policy_hnd(&domain_pol))
1133 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1135 if (is_valid_policy_hnd(&connect_pol))
1136 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1138 return status;
1141 /* Enumerate domains */
1143 static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
1144 TALLOC_CTX *mem_ctx,
1145 int argc, const char **argv)
1147 struct policy_handle connect_pol;
1148 NTSTATUS status, result;
1149 uint32 start_idx, size, num_entries, i;
1150 uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1151 struct samr_SamArray *sam = NULL;
1152 struct dcerpc_binding_handle *b = cli->binding_handle;
1154 if ((argc < 1) || (argc > 2)) {
1155 printf("Usage: %s [access mask]\n", argv[0]);
1156 return NT_STATUS_OK;
1159 if (argc > 1) {
1160 sscanf(argv[1], "%x", &access_mask);
1163 /* Get sam policy handle */
1165 status = rpccli_try_samr_connects(cli, mem_ctx,
1166 access_mask,
1167 &connect_pol);
1168 if (!NT_STATUS_IS_OK(status)) {
1169 goto done;
1172 /* Enumerate alias groups */
1174 start_idx = 0;
1175 size = 0xffff;
1177 do {
1178 status = dcerpc_samr_EnumDomains(b, mem_ctx,
1179 &connect_pol,
1180 &start_idx,
1181 &sam,
1182 size,
1183 &num_entries,
1184 &result);
1185 if (!NT_STATUS_IS_OK(status)) {
1186 goto done;
1188 if (NT_STATUS_IS_OK(result) ||
1189 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1191 for (i = 0; i < num_entries; i++)
1192 printf("name:[%s] idx:[0x%x]\n",
1193 sam->entries[i].name.string,
1194 sam->entries[i].idx);
1196 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1198 done:
1199 if (is_valid_policy_hnd(&connect_pol)) {
1200 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1203 return status;
1207 /* Query alias membership */
1209 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1210 TALLOC_CTX *mem_ctx,
1211 int argc, const char **argv)
1213 struct policy_handle connect_pol, domain_pol, alias_pol;
1214 NTSTATUS status, result;
1215 uint32 alias_rid, i;
1216 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1217 struct lsa_SidArray sid_array;
1218 struct dcerpc_binding_handle *b = cli->binding_handle;
1220 if ((argc < 3) || (argc > 4)) {
1221 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1222 return NT_STATUS_OK;
1225 sscanf(argv[2], "%i", &alias_rid);
1227 if (argc > 3)
1228 sscanf(argv[3], "%x", &access_mask);
1230 /* Open SAMR handle */
1232 status = rpccli_try_samr_connects(cli, mem_ctx,
1233 MAXIMUM_ALLOWED_ACCESS,
1234 &connect_pol);
1235 if (!NT_STATUS_IS_OK(status)) {
1236 goto done;
1239 /* Open handle on domain */
1241 status = get_domain_handle(cli, mem_ctx, argv[1],
1242 &connect_pol,
1243 MAXIMUM_ALLOWED_ACCESS,
1244 &domain_sid,
1245 &domain_pol);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 goto done;
1250 /* Open handle on alias */
1252 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1253 &domain_pol,
1254 access_mask,
1255 alias_rid,
1256 &alias_pol,
1257 &result);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 goto done;
1261 if (!NT_STATUS_IS_OK(result)) {
1262 status = result;
1263 goto done;
1266 status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
1267 &alias_pol,
1268 &sid_array,
1269 &result);
1270 if (!NT_STATUS_IS_OK(status)) {
1271 goto done;
1273 if (!NT_STATUS_IS_OK(result)) {
1274 status = result;
1275 goto done;
1278 for (i = 0; i < sid_array.num_sids; i++) {
1279 fstring sid_str;
1281 sid_to_fstring(sid_str, sid_array.sids[i].sid);
1282 printf("\tsid:[%s]\n", sid_str);
1285 dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
1286 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1287 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1288 done:
1289 return status;
1292 /* Query alias info */
1294 static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
1295 TALLOC_CTX *mem_ctx,
1296 int argc, const char **argv)
1298 struct policy_handle connect_pol, domain_pol, alias_pol;
1299 NTSTATUS status, result;
1300 uint32_t alias_rid;
1301 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1302 union samr_AliasInfo *info = NULL;
1303 enum samr_AliasInfoEnum level = ALIASINFOALL;
1304 struct dcerpc_binding_handle *b = cli->binding_handle;
1306 if ((argc < 3) || (argc > 4)) {
1307 printf("Usage: %s builtin|domain rid [level] [access mask]\n",
1308 argv[0]);
1309 return NT_STATUS_OK;
1312 sscanf(argv[2], "%i", &alias_rid);
1314 if (argc > 2) {
1315 level = atoi(argv[3]);
1318 if (argc > 3) {
1319 sscanf(argv[4], "%x", &access_mask);
1322 /* Open SAMR handle */
1324 status = rpccli_try_samr_connects(cli, mem_ctx,
1325 SEC_FLAG_MAXIMUM_ALLOWED,
1326 &connect_pol);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 goto done;
1331 /* Open handle on domain */
1333 status = get_domain_handle(cli, mem_ctx, argv[1],
1334 &connect_pol,
1335 SEC_FLAG_MAXIMUM_ALLOWED,
1336 &domain_sid,
1337 &domain_pol);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 goto done;
1342 /* Open handle on alias */
1344 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1345 &domain_pol,
1346 access_mask,
1347 alias_rid,
1348 &alias_pol,
1349 &result);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 goto done;
1353 if (!NT_STATUS_IS_OK(result)) {
1354 status = result;
1355 goto done;
1358 status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
1359 &alias_pol,
1360 level,
1361 &info,
1362 &result);
1363 if (!NT_STATUS_IS_OK(status)) {
1364 goto done;
1366 if (!NT_STATUS_IS_OK(result)) {
1367 status = result;
1368 goto done;
1371 switch (level) {
1372 case ALIASINFOALL:
1373 printf("Name: %s\n", info->all.name.string);
1374 printf("Description: %s\n", info->all.description.string);
1375 printf("Num Members: %d\n", info->all.num_members);
1376 break;
1377 case ALIASINFONAME:
1378 printf("Name: %s\n", info->name.string);
1379 break;
1380 case ALIASINFODESCRIPTION:
1381 printf("Description: %s\n", info->description.string);
1382 break;
1383 default:
1384 break;
1387 dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
1388 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1389 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1390 done:
1391 return status;
1395 /* Query delete an alias membership */
1397 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1398 TALLOC_CTX *mem_ctx,
1399 int argc, const char **argv)
1401 struct policy_handle connect_pol, domain_pol, alias_pol;
1402 NTSTATUS status, result;
1403 uint32 alias_rid;
1404 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1405 struct dcerpc_binding_handle *b = cli->binding_handle;
1407 if (argc != 3) {
1408 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1409 return NT_STATUS_OK;
1412 alias_rid = strtoul(argv[2], NULL, 10);
1414 /* Open SAMR handle */
1416 status = rpccli_try_samr_connects(cli, mem_ctx,
1417 MAXIMUM_ALLOWED_ACCESS,
1418 &connect_pol);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 goto done;
1423 /* Open handle on domain */
1425 status = get_domain_handle(cli, mem_ctx, argv[1],
1426 &connect_pol,
1427 MAXIMUM_ALLOWED_ACCESS,
1428 &domain_sid,
1429 &domain_pol);
1430 if (!NT_STATUS_IS_OK(status)) {
1431 goto done;
1434 /* Open handle on alias */
1436 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1437 &domain_pol,
1438 access_mask,
1439 alias_rid,
1440 &alias_pol,
1441 &result);
1442 if (!NT_STATUS_IS_OK(status)) {
1443 goto done;
1445 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1446 /* Probably this was a user name, try lookupnames */
1447 struct samr_Ids rids, types;
1448 struct lsa_String lsa_acct_name;
1450 init_lsa_String(&lsa_acct_name, argv[2]);
1452 status = dcerpc_samr_LookupNames(b, mem_ctx,
1453 &domain_pol,
1455 &lsa_acct_name,
1456 &rids,
1457 &types,
1458 &result);
1459 if (!NT_STATUS_IS_OK(status)) {
1460 goto done;
1462 if (NT_STATUS_IS_OK(result)) {
1463 if (rids.count != 1) {
1464 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1465 goto done;
1467 if (types.count != 1) {
1468 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1469 goto done;
1472 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1473 &domain_pol,
1474 access_mask,
1475 rids.ids[0],
1476 &alias_pol,
1477 &result);
1478 if (!NT_STATUS_IS_OK(status)) {
1479 goto done;
1484 status = dcerpc_samr_DeleteDomAlias(b, mem_ctx,
1485 &alias_pol,
1486 &result);
1487 if (!NT_STATUS_IS_OK(status)) {
1488 goto done;
1490 if (!NT_STATUS_IS_OK(result)) {
1491 status = result;
1492 goto done;
1495 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1496 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1497 done:
1498 return status;
1501 /* Query display info */
1503 static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli,
1504 TALLOC_CTX *mem_ctx,
1505 int argc, const char **argv,
1506 uint32_t opcode)
1508 struct policy_handle connect_pol, domain_pol;
1509 NTSTATUS status, result;
1510 uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
1511 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1512 uint32 info_level = 1;
1513 union samr_DispInfo info;
1514 int loop_count = 0;
1515 bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1516 uint32_t total_size, returned_size;
1517 struct dcerpc_binding_handle *b = cli->binding_handle;
1519 if (argc > 6) {
1520 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1521 return NT_STATUS_OK;
1524 if (argc >= 2)
1525 sscanf(argv[1], "%i", &info_level);
1527 if (argc >= 3)
1528 sscanf(argv[2], "%i", &start_idx);
1530 if (argc >= 4) {
1531 sscanf(argv[3], "%i", &max_entries);
1532 got_params = True;
1535 if (argc >= 5) {
1536 sscanf(argv[4], "%i", &max_size);
1537 got_params = True;
1540 if (argc >= 6)
1541 sscanf(argv[5], "%x", &access_mask);
1543 /* Get sam policy handle */
1545 status = rpccli_try_samr_connects(cli, mem_ctx,
1546 MAXIMUM_ALLOWED_ACCESS,
1547 &connect_pol);
1548 if (!NT_STATUS_IS_OK(status)) {
1549 goto done;
1552 /* Get domain policy handle */
1554 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1555 &connect_pol,
1556 access_mask,
1557 &domain_sid,
1558 &domain_pol,
1559 &result);
1560 if (!NT_STATUS_IS_OK(status)) {
1561 goto done;
1563 if (!NT_STATUS_IS_OK(result)) {
1564 status = result;
1565 goto done;
1568 /* Query display info */
1570 do {
1572 if (!got_params)
1573 dcerpc_get_query_dispinfo_params(
1574 loop_count, &max_entries, &max_size);
1576 switch (opcode) {
1577 case NDR_SAMR_QUERYDISPLAYINFO:
1578 status = dcerpc_samr_QueryDisplayInfo(b, mem_ctx,
1579 &domain_pol,
1580 info_level,
1581 start_idx,
1582 max_entries,
1583 max_size,
1584 &total_size,
1585 &returned_size,
1586 &info,
1587 &result);
1588 break;
1589 case NDR_SAMR_QUERYDISPLAYINFO2:
1590 status = dcerpc_samr_QueryDisplayInfo2(b, mem_ctx,
1591 &domain_pol,
1592 info_level,
1593 start_idx,
1594 max_entries,
1595 max_size,
1596 &total_size,
1597 &returned_size,
1598 &info,
1599 &result);
1601 break;
1602 case NDR_SAMR_QUERYDISPLAYINFO3:
1603 status = dcerpc_samr_QueryDisplayInfo3(b, mem_ctx,
1604 &domain_pol,
1605 info_level,
1606 start_idx,
1607 max_entries,
1608 max_size,
1609 &total_size,
1610 &returned_size,
1611 &info,
1612 &result);
1614 break;
1615 default:
1616 return NT_STATUS_INVALID_PARAMETER;
1619 if (!NT_STATUS_IS_OK(status)) {
1620 break;
1622 status = result;
1623 if (!NT_STATUS_IS_OK(result) &&
1624 !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
1625 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1626 break;
1629 loop_count++;
1631 switch (info_level) {
1632 case 1:
1633 num_entries = info.info1.count;
1634 break;
1635 case 2:
1636 num_entries = info.info2.count;
1637 break;
1638 case 3:
1639 num_entries = info.info3.count;
1640 break;
1641 case 4:
1642 num_entries = info.info4.count;
1643 break;
1644 case 5:
1645 num_entries = info.info5.count;
1646 break;
1647 default:
1648 break;
1651 start_idx += num_entries;
1653 if (num_entries == 0)
1654 break;
1656 for (i = 0; i < num_entries; i++) {
1657 switch (info_level) {
1658 case 1:
1659 display_sam_info_1(&info.info1.entries[i]);
1660 break;
1661 case 2:
1662 display_sam_info_2(&info.info2.entries[i]);
1663 break;
1664 case 3:
1665 display_sam_info_3(&info.info3.entries[i]);
1666 break;
1667 case 4:
1668 display_sam_info_4(&info.info4.entries[i]);
1669 break;
1670 case 5:
1671 display_sam_info_5(&info.info5.entries[i]);
1672 break;
1675 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1677 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1678 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1679 done:
1680 return status;
1683 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1684 TALLOC_CTX *mem_ctx,
1685 int argc, const char **argv)
1687 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1688 NDR_SAMR_QUERYDISPLAYINFO);
1691 static NTSTATUS cmd_samr_query_dispinfo2(struct rpc_pipe_client *cli,
1692 TALLOC_CTX *mem_ctx,
1693 int argc, const char **argv)
1695 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1696 NDR_SAMR_QUERYDISPLAYINFO2);
1699 static NTSTATUS cmd_samr_query_dispinfo3(struct rpc_pipe_client *cli,
1700 TALLOC_CTX *mem_ctx,
1701 int argc, const char **argv)
1703 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1704 NDR_SAMR_QUERYDISPLAYINFO3);
1707 /* Query domain info */
1709 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1710 TALLOC_CTX *mem_ctx,
1711 int argc, const char **argv)
1713 struct policy_handle connect_pol, domain_pol;
1714 NTSTATUS status, result;
1715 uint32 switch_level = 2;
1716 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1717 union samr_DomainInfo *info = NULL;
1718 struct dcerpc_binding_handle *b = cli->binding_handle;
1720 if (argc > 3) {
1721 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1722 return NT_STATUS_OK;
1725 if (argc > 1)
1726 sscanf(argv[1], "%i", &switch_level);
1728 if (argc > 2)
1729 sscanf(argv[2], "%x", &access_mask);
1731 /* Get sam policy handle */
1733 status = rpccli_try_samr_connects(cli, mem_ctx,
1734 MAXIMUM_ALLOWED_ACCESS,
1735 &connect_pol);
1736 if (!NT_STATUS_IS_OK(status)) {
1737 goto done;
1740 /* Get domain policy handle */
1742 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1743 &connect_pol,
1744 access_mask,
1745 &domain_sid,
1746 &domain_pol,
1747 &result);
1748 if (!NT_STATUS_IS_OK(status)) {
1749 goto done;
1751 if (!NT_STATUS_IS_OK(result)) {
1752 status = result;
1753 goto done;
1756 /* Query domain info */
1758 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
1759 &domain_pol,
1760 switch_level,
1761 &info,
1762 &result);
1763 if (!NT_STATUS_IS_OK(status)) {
1764 goto done;
1766 if (!NT_STATUS_IS_OK(result)) {
1767 status = result;
1768 goto done;
1771 /* Display domain info */
1773 switch (switch_level) {
1774 case 1:
1775 display_sam_dom_info_1(&info->info1);
1776 break;
1777 case 2:
1778 display_sam_dom_info_2(&info->general);
1779 break;
1780 case 3:
1781 display_sam_dom_info_3(&info->info3);
1782 break;
1783 case 4:
1784 display_sam_dom_info_4(&info->oem);
1785 break;
1786 case 5:
1787 display_sam_dom_info_5(&info->info5);
1788 break;
1789 case 6:
1790 display_sam_dom_info_6(&info->info6);
1791 break;
1792 case 7:
1793 display_sam_dom_info_7(&info->info7);
1794 break;
1795 case 8:
1796 display_sam_dom_info_8(&info->info8);
1797 break;
1798 case 9:
1799 display_sam_dom_info_9(&info->info9);
1800 break;
1801 case 12:
1802 display_sam_dom_info_12(&info->info12);
1803 break;
1804 case 13:
1805 display_sam_dom_info_13(&info->info13);
1806 break;
1808 default:
1809 printf("cannot display domain info for switch value %d\n",
1810 switch_level);
1811 break;
1814 done:
1816 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1817 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1818 return status;
1821 /* Create domain user */
1823 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1824 TALLOC_CTX *mem_ctx,
1825 int argc, const char **argv)
1827 struct policy_handle connect_pol, domain_pol, user_pol;
1828 NTSTATUS status, result;
1829 struct lsa_String acct_name;
1830 uint32 acb_info;
1831 uint32 acct_flags, user_rid;
1832 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1833 uint32_t access_granted = 0;
1834 struct dcerpc_binding_handle *b = cli->binding_handle;
1836 if ((argc < 2) || (argc > 3)) {
1837 printf("Usage: %s username [access mask]\n", argv[0]);
1838 return NT_STATUS_OK;
1841 init_lsa_String(&acct_name, argv[1]);
1843 if (argc > 2)
1844 sscanf(argv[2], "%x", &access_mask);
1846 /* Get sam policy handle */
1848 status = rpccli_try_samr_connects(cli, mem_ctx,
1849 MAXIMUM_ALLOWED_ACCESS,
1850 &connect_pol);
1851 if (!NT_STATUS_IS_OK(status)) {
1852 goto done;
1855 /* Get domain policy handle */
1857 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1858 &connect_pol,
1859 access_mask,
1860 &domain_sid,
1861 &domain_pol,
1862 &result);
1863 if (!NT_STATUS_IS_OK(status)) {
1864 goto done;
1866 if (!NT_STATUS_IS_OK(result)) {
1867 status = result;
1868 goto done;
1871 /* Create domain user */
1873 acb_info = ACB_NORMAL;
1874 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1875 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1876 SAMR_USER_ACCESS_SET_PASSWORD |
1877 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1878 SAMR_USER_ACCESS_SET_ATTRIBUTES;
1880 status = dcerpc_samr_CreateUser2(b, mem_ctx,
1881 &domain_pol,
1882 &acct_name,
1883 acb_info,
1884 acct_flags,
1885 &user_pol,
1886 &access_granted,
1887 &user_rid,
1888 &result);
1889 if (!NT_STATUS_IS_OK(status)) {
1890 goto done;
1892 if (!NT_STATUS_IS_OK(result)) {
1893 status = result;
1894 goto done;
1897 status = dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1898 if (!NT_STATUS_IS_OK(status)) goto done;
1900 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1901 if (!NT_STATUS_IS_OK(status)) goto done;
1903 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1904 if (!NT_STATUS_IS_OK(status)) goto done;
1906 done:
1907 return status;
1910 /* Create domain group */
1912 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1913 TALLOC_CTX *mem_ctx,
1914 int argc, const char **argv)
1916 struct policy_handle connect_pol, domain_pol, group_pol;
1917 NTSTATUS status, result;
1918 struct lsa_String grp_name;
1919 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1920 uint32_t rid = 0;
1921 struct dcerpc_binding_handle *b = cli->binding_handle;
1923 if ((argc < 2) || (argc > 3)) {
1924 printf("Usage: %s groupname [access mask]\n", argv[0]);
1925 return NT_STATUS_OK;
1928 init_lsa_String(&grp_name, argv[1]);
1930 if (argc > 2)
1931 sscanf(argv[2], "%x", &access_mask);
1933 /* Get sam policy handle */
1935 status = rpccli_try_samr_connects(cli, mem_ctx,
1936 MAXIMUM_ALLOWED_ACCESS,
1937 &connect_pol);
1938 if (!NT_STATUS_IS_OK(status)) {
1939 goto done;
1942 /* Get domain policy handle */
1944 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1945 &connect_pol,
1946 access_mask,
1947 &domain_sid,
1948 &domain_pol,
1949 &result);
1950 if (!NT_STATUS_IS_OK(status)) {
1951 goto done;
1953 if (!NT_STATUS_IS_OK(result)) {
1954 status = result;
1955 goto done;
1958 /* Create domain user */
1959 status = dcerpc_samr_CreateDomainGroup(b, mem_ctx,
1960 &domain_pol,
1961 &grp_name,
1962 MAXIMUM_ALLOWED_ACCESS,
1963 &group_pol,
1964 &rid,
1965 &result);
1966 if (!NT_STATUS_IS_OK(status)) {
1967 goto done;
1969 if (!NT_STATUS_IS_OK(result)) {
1970 status = result;
1971 goto done;
1974 status = dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
1975 if (!NT_STATUS_IS_OK(status)) goto done;
1977 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1978 if (!NT_STATUS_IS_OK(status)) goto done;
1980 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1981 if (!NT_STATUS_IS_OK(status)) goto done;
1983 done:
1984 return status;
1987 /* Create domain alias */
1989 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1990 TALLOC_CTX *mem_ctx,
1991 int argc, const char **argv)
1993 struct policy_handle connect_pol, domain_pol, alias_pol;
1994 NTSTATUS status, result;
1995 struct lsa_String alias_name;
1996 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1997 uint32_t rid = 0;
1998 struct dcerpc_binding_handle *b = cli->binding_handle;
2000 if ((argc < 2) || (argc > 3)) {
2001 printf("Usage: %s aliasname [access mask]\n", argv[0]);
2002 return NT_STATUS_OK;
2005 init_lsa_String(&alias_name, argv[1]);
2007 if (argc > 2)
2008 sscanf(argv[2], "%x", &access_mask);
2010 /* Get sam policy handle */
2012 status = rpccli_try_samr_connects(cli, mem_ctx,
2013 MAXIMUM_ALLOWED_ACCESS,
2014 &connect_pol);
2015 if (!NT_STATUS_IS_OK(status)) {
2016 goto done;
2019 /* Get domain policy handle */
2021 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2022 &connect_pol,
2023 access_mask,
2024 &domain_sid,
2025 &domain_pol,
2026 &result);
2027 if (!NT_STATUS_IS_OK(status)) {
2028 goto done;
2030 if (!NT_STATUS_IS_OK(result)) {
2031 status = result;
2032 goto done;
2035 /* Create domain user */
2037 status = dcerpc_samr_CreateDomAlias(b, mem_ctx,
2038 &domain_pol,
2039 &alias_name,
2040 MAXIMUM_ALLOWED_ACCESS,
2041 &alias_pol,
2042 &rid,
2043 &result);
2044 if (!NT_STATUS_IS_OK(status)) {
2045 goto done;
2047 if (!NT_STATUS_IS_OK(result)) {
2048 status = result;
2049 goto done;
2053 status = dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
2054 if (!NT_STATUS_IS_OK(status)) goto done;
2056 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2057 if (!NT_STATUS_IS_OK(status)) goto done;
2059 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2060 if (!NT_STATUS_IS_OK(status)) goto done;
2062 done:
2063 return status;
2066 /* Lookup sam names */
2068 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
2069 TALLOC_CTX *mem_ctx,
2070 int argc, const char **argv)
2072 NTSTATUS status, result;
2073 struct policy_handle connect_pol, domain_pol;
2074 uint32 num_names;
2075 struct samr_Ids rids, name_types;
2076 int i;
2077 struct lsa_String *names = NULL;
2078 struct dcerpc_binding_handle *b = cli->binding_handle;
2080 if (argc < 3) {
2081 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
2082 printf("check on the domain SID: S-1-5-21-x-y-z\n");
2083 printf("or check on the builtin SID: S-1-5-32\n");
2084 return NT_STATUS_OK;
2087 /* Get sam policy and domain handles */
2089 status = rpccli_try_samr_connects(cli, mem_ctx,
2090 MAXIMUM_ALLOWED_ACCESS,
2091 &connect_pol);
2092 if (!NT_STATUS_IS_OK(status)) {
2093 goto done;
2096 status = get_domain_handle(cli, mem_ctx, argv[1],
2097 &connect_pol,
2098 MAXIMUM_ALLOWED_ACCESS,
2099 &domain_sid,
2100 &domain_pol);
2101 if (!NT_STATUS_IS_OK(status)) {
2102 goto done;
2105 /* Look up names */
2107 num_names = argc - 2;
2109 if ((names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names)) == NULL) {
2110 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2111 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2112 status = NT_STATUS_NO_MEMORY;
2113 goto done;
2116 for (i = 0; i < num_names; i++) {
2117 init_lsa_String(&names[i], argv[i + 2]);
2120 status = dcerpc_samr_LookupNames(b, mem_ctx,
2121 &domain_pol,
2122 num_names,
2123 names,
2124 &rids,
2125 &name_types,
2126 &result);
2127 if (!NT_STATUS_IS_OK(status)) {
2128 goto done;
2130 if (!NT_STATUS_IS_OK(result)) {
2131 status = result;
2132 goto done;
2134 if (rids.count != num_names) {
2135 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2136 goto done;
2138 if (name_types.count != num_names) {
2139 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2140 goto done;
2143 /* Display results */
2145 for (i = 0; i < num_names; i++)
2146 printf("name %s: 0x%x (%d)\n", names[i].string, rids.ids[i],
2147 name_types.ids[i]);
2149 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2150 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2151 done:
2152 return status;
2155 /* Lookup sam rids */
2157 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
2158 TALLOC_CTX *mem_ctx,
2159 int argc, const char **argv)
2161 NTSTATUS status, result;
2162 struct policy_handle connect_pol, domain_pol;
2163 uint32_t num_rids, *rids;
2164 struct lsa_Strings names;
2165 struct samr_Ids types;
2166 struct dcerpc_binding_handle *b = cli->binding_handle;
2168 int i;
2170 if (argc < 3) {
2171 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
2172 return NT_STATUS_OK;
2175 /* Get sam policy and domain handles */
2177 status = rpccli_try_samr_connects(cli, mem_ctx,
2178 MAXIMUM_ALLOWED_ACCESS,
2179 &connect_pol);
2180 if (!NT_STATUS_IS_OK(status)) {
2181 goto done;
2184 status = get_domain_handle(cli, mem_ctx, argv[1],
2185 &connect_pol,
2186 MAXIMUM_ALLOWED_ACCESS,
2187 &domain_sid,
2188 &domain_pol);
2189 if (!NT_STATUS_IS_OK(status)) {
2190 goto done;
2193 /* Look up rids */
2195 num_rids = argc - 2;
2197 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
2198 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2199 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2200 status = NT_STATUS_NO_MEMORY;
2201 goto done;
2204 for (i = 0; i < argc - 2; i++)
2205 sscanf(argv[i + 2], "%i", &rids[i]);
2207 status = dcerpc_samr_LookupRids(b, mem_ctx,
2208 &domain_pol,
2209 num_rids,
2210 rids,
2211 &names,
2212 &types,
2213 &result);
2214 if (!NT_STATUS_IS_OK(status)) {
2215 goto done;
2217 status = result;
2218 if (!NT_STATUS_IS_OK(result) &&
2219 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
2220 goto done;
2222 /* Display results */
2223 if (num_rids != names.count) {
2224 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2225 goto done;
2227 if (num_rids != types.count) {
2228 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2229 goto done;
2232 for (i = 0; i < num_rids; i++) {
2233 printf("rid 0x%x: %s (%d)\n",
2234 rids[i], names.names[i].string, types.ids[i]);
2237 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2238 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2239 done:
2240 return status;
2243 /* Delete domain group */
2245 static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
2246 TALLOC_CTX *mem_ctx,
2247 int argc, const char **argv)
2249 NTSTATUS status, result;
2250 struct policy_handle connect_pol, domain_pol, group_pol;
2251 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2252 struct dcerpc_binding_handle *b = cli->binding_handle;
2254 if ((argc < 2) || (argc > 3)) {
2255 printf("Usage: %s groupname\n", argv[0]);
2256 return NT_STATUS_OK;
2259 if (argc > 2)
2260 sscanf(argv[2], "%x", &access_mask);
2262 /* Get sam policy and domain handles */
2264 status = rpccli_try_samr_connects(cli, mem_ctx,
2265 MAXIMUM_ALLOWED_ACCESS,
2266 &connect_pol);
2267 if (!NT_STATUS_IS_OK(status)) {
2268 goto done;
2271 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2272 &connect_pol,
2273 MAXIMUM_ALLOWED_ACCESS,
2274 &domain_sid,
2275 &domain_pol,
2276 &result);
2277 if (!NT_STATUS_IS_OK(status)) {
2278 goto done;
2280 if (!NT_STATUS_IS_OK(result)) {
2281 status = result;
2282 goto done;
2285 /* Get handle on group */
2288 struct samr_Ids group_rids, name_types;
2289 struct lsa_String lsa_acct_name;
2291 init_lsa_String(&lsa_acct_name, argv[1]);
2293 status = dcerpc_samr_LookupNames(b, mem_ctx,
2294 &domain_pol,
2296 &lsa_acct_name,
2297 &group_rids,
2298 &name_types,
2299 &result);
2300 if (!NT_STATUS_IS_OK(status)) {
2301 goto done;
2303 if (!NT_STATUS_IS_OK(result)) {
2304 status = result;
2305 goto done;
2307 if (group_rids.count != 1) {
2308 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2309 goto done;
2311 if (name_types.count != 1) {
2312 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2313 goto done;
2316 status = dcerpc_samr_OpenGroup(b, mem_ctx,
2317 &domain_pol,
2318 access_mask,
2319 group_rids.ids[0],
2320 &group_pol,
2321 &result);
2322 if (!NT_STATUS_IS_OK(status)) {
2323 goto done;
2325 if (!NT_STATUS_IS_OK(result)) {
2326 status = result;
2327 goto done;
2331 /* Delete group */
2333 status = dcerpc_samr_DeleteDomainGroup(b, mem_ctx,
2334 &group_pol,
2335 &result);
2336 if (!NT_STATUS_IS_OK(status)) {
2337 goto done;
2339 if (!NT_STATUS_IS_OK(result)) {
2340 status = result;
2341 goto done;
2344 /* Display results */
2346 dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
2347 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2348 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2350 done:
2351 return status;
2354 /* Delete domain user */
2356 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
2357 TALLOC_CTX *mem_ctx,
2358 int argc, const char **argv)
2360 NTSTATUS status, result;
2361 struct policy_handle connect_pol, domain_pol, user_pol;
2362 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2363 struct dcerpc_binding_handle *b = cli->binding_handle;
2365 if ((argc < 2) || (argc > 3)) {
2366 printf("Usage: %s username\n", argv[0]);
2367 return NT_STATUS_OK;
2370 if (argc > 2)
2371 sscanf(argv[2], "%x", &access_mask);
2373 /* Get sam policy and domain handles */
2375 status = rpccli_try_samr_connects(cli, mem_ctx,
2376 MAXIMUM_ALLOWED_ACCESS,
2377 &connect_pol);
2378 if (!NT_STATUS_IS_OK(status)) {
2379 goto done;
2382 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2383 &connect_pol,
2384 MAXIMUM_ALLOWED_ACCESS,
2385 &domain_sid,
2386 &domain_pol,
2387 &result);
2388 if (!NT_STATUS_IS_OK(status)) {
2389 goto done;
2391 if (!NT_STATUS_IS_OK(result)) {
2392 status = result;
2393 goto done;
2396 /* Get handle on user */
2399 struct samr_Ids user_rids, name_types;
2400 struct lsa_String lsa_acct_name;
2402 init_lsa_String(&lsa_acct_name, argv[1]);
2404 status = dcerpc_samr_LookupNames(b, mem_ctx,
2405 &domain_pol,
2407 &lsa_acct_name,
2408 &user_rids,
2409 &name_types,
2410 &result);
2411 if (!NT_STATUS_IS_OK(status)) {
2412 goto done;
2414 if (!NT_STATUS_IS_OK(result)) {
2415 status = result;
2416 goto done;
2418 if (user_rids.count != 1) {
2419 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2420 goto done;
2422 if (name_types.count != 1) {
2423 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2424 goto done;
2427 status = dcerpc_samr_OpenUser(b, mem_ctx,
2428 &domain_pol,
2429 access_mask,
2430 user_rids.ids[0],
2431 &user_pol,
2432 &result);
2433 if (!NT_STATUS_IS_OK(status)) {
2434 goto done;
2436 if (!NT_STATUS_IS_OK(result)) {
2437 status = result;
2438 goto done;
2442 /* Delete user */
2444 status = dcerpc_samr_DeleteUser(b, mem_ctx,
2445 &user_pol,
2446 &result);
2447 if (!NT_STATUS_IS_OK(status)) {
2448 goto done;
2450 if (!NT_STATUS_IS_OK(result)) {
2451 status = result;
2452 goto done;
2455 /* Display results */
2457 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2458 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2459 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2461 done:
2462 return status;
2465 /**********************************************************************
2466 * Query user security object
2468 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
2469 TALLOC_CTX *mem_ctx,
2470 int argc, const char **argv)
2472 struct policy_handle connect_pol, domain_pol, user_pol, *pol;
2473 NTSTATUS status, result;
2474 uint32 sec_info = SECINFO_DACL;
2475 uint32 user_rid = 0;
2476 TALLOC_CTX *ctx = NULL;
2477 struct sec_desc_buf *sec_desc_buf=NULL;
2478 bool domain = False;
2479 struct dcerpc_binding_handle *b = cli->binding_handle;
2481 ctx=talloc_init("cmd_samr_query_sec_obj");
2483 if ((argc < 1) || (argc > 3)) {
2484 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2485 printf("\tSpecify rid for security on user, -d for security on domain\n");
2486 talloc_destroy(ctx);
2487 return NT_STATUS_OK;
2490 if (argc > 1) {
2491 if (strcmp(argv[1], "-d") == 0)
2492 domain = True;
2493 else
2494 sscanf(argv[1], "%i", &user_rid);
2497 if (argc == 3) {
2498 sec_info = atoi(argv[2]);
2501 status = rpccli_try_samr_connects(cli, mem_ctx,
2502 MAXIMUM_ALLOWED_ACCESS,
2503 &connect_pol);
2504 if (!NT_STATUS_IS_OK(status)) {
2505 goto done;
2508 if (domain || user_rid) {
2509 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2510 &connect_pol,
2511 MAXIMUM_ALLOWED_ACCESS,
2512 &domain_sid,
2513 &domain_pol,
2514 &result);
2515 if (!NT_STATUS_IS_OK(status)) {
2516 goto done;
2518 if (!NT_STATUS_IS_OK(result)) {
2519 status = result;
2520 goto done;
2524 if (user_rid) {
2525 status = dcerpc_samr_OpenUser(b, mem_ctx,
2526 &domain_pol,
2527 MAXIMUM_ALLOWED_ACCESS,
2528 user_rid,
2529 &user_pol,
2530 &result);
2531 if (!NT_STATUS_IS_OK(status)) {
2532 goto done;
2534 if (!NT_STATUS_IS_OK(result)) {
2535 status = result;
2536 goto done;
2540 /* Pick which query pol to use */
2542 pol = &connect_pol;
2544 if (domain)
2545 pol = &domain_pol;
2547 if (user_rid)
2548 pol = &user_pol;
2550 /* Query SAM security object */
2552 status = dcerpc_samr_QuerySecurity(b, mem_ctx,
2553 pol,
2554 sec_info,
2555 &sec_desc_buf,
2556 &result);
2557 if (!NT_STATUS_IS_OK(status)) {
2558 goto done;
2560 if (!NT_STATUS_IS_OK(result)) {
2561 status = result;
2562 goto done;
2565 display_sec_desc(sec_desc_buf->sd);
2567 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2568 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2569 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2570 done:
2571 talloc_destroy(ctx);
2572 return status;
2575 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
2576 TALLOC_CTX *mem_ctx,
2577 int argc, const char **argv)
2579 NTSTATUS status, result;
2580 struct policy_handle connect_pol, domain_pol, user_pol;
2581 struct samr_PwInfo info;
2582 uint32_t rid;
2583 struct dcerpc_binding_handle *b = cli->binding_handle;
2585 if (argc != 2) {
2586 printf("Usage: %s rid\n", argv[0]);
2587 return NT_STATUS_OK;
2590 sscanf(argv[1], "%i", &rid);
2592 status = rpccli_try_samr_connects(cli, mem_ctx,
2593 MAXIMUM_ALLOWED_ACCESS,
2594 &connect_pol);
2595 if (!NT_STATUS_IS_OK(status)) {
2596 goto done;
2599 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2600 &connect_pol,
2601 MAXIMUM_ALLOWED_ACCESS,
2602 &domain_sid,
2603 &domain_pol,
2604 &result);
2605 if (!NT_STATUS_IS_OK(status)) {
2606 goto done;
2608 if (!NT_STATUS_IS_OK(result)) {
2609 status = result;
2610 goto done;
2613 status = dcerpc_samr_OpenUser(b, mem_ctx,
2614 &domain_pol,
2615 MAXIMUM_ALLOWED_ACCESS,
2616 rid,
2617 &user_pol,
2618 &result);
2619 if (!NT_STATUS_IS_OK(status)) {
2620 goto done;
2622 if (!NT_STATUS_IS_OK(result)) {
2623 status = result;
2624 goto done;
2627 status = dcerpc_samr_GetUserPwInfo(b, mem_ctx,
2628 &user_pol,
2629 &info,
2630 &result);
2631 if (!NT_STATUS_IS_OK(status)) {
2632 goto done;
2634 status = result;
2635 if (NT_STATUS_IS_OK(result)) {
2636 printf("min_password_length: %d\n", info.min_password_length);
2637 printf("%s\n",
2638 NDR_PRINT_STRUCT_STRING(mem_ctx,
2639 samr_PasswordProperties, &info.password_properties));
2642 done:
2643 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2644 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2645 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2647 return status;
2650 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2651 TALLOC_CTX *mem_ctx,
2652 int argc, const char **argv)
2654 NTSTATUS status, result;
2655 struct lsa_String domain_name;
2656 struct samr_PwInfo info;
2657 struct dcerpc_binding_handle *b = cli->binding_handle;
2659 if (argc < 1 || argc > 3) {
2660 printf("Usage: %s <domain>\n", argv[0]);
2661 return NT_STATUS_OK;
2664 init_lsa_String(&domain_name, argv[1]);
2666 status = dcerpc_samr_GetDomPwInfo(b, mem_ctx,
2667 &domain_name,
2668 &info,
2669 &result);
2670 if (!NT_STATUS_IS_OK(status)) {
2671 return status;
2673 if (NT_STATUS_IS_OK(result)) {
2674 printf("min_password_length: %d\n", info.min_password_length);
2675 display_password_properties(info.password_properties);
2678 return result;
2681 /* Look up domain name */
2683 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
2684 TALLOC_CTX *mem_ctx,
2685 int argc, const char **argv)
2687 struct policy_handle connect_pol, domain_pol;
2688 NTSTATUS status, result;
2689 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2690 fstring sid_string;
2691 struct lsa_String domain_name;
2692 struct dom_sid *sid = NULL;
2693 struct dcerpc_binding_handle *b = cli->binding_handle;
2695 if (argc != 2) {
2696 printf("Usage: %s domain_name\n", argv[0]);
2697 return NT_STATUS_OK;
2700 init_lsa_String(&domain_name, argv[1]);
2702 status = rpccli_try_samr_connects(cli, mem_ctx,
2703 access_mask,
2704 &connect_pol);
2705 if (!NT_STATUS_IS_OK(status)) {
2706 goto done;
2709 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2710 &connect_pol,
2711 access_mask,
2712 &domain_sid,
2713 &domain_pol,
2714 &result);
2715 if (!NT_STATUS_IS_OK(status)) {
2716 goto done;
2718 if (!NT_STATUS_IS_OK(result)) {
2719 status = result;
2720 goto done;
2723 status = dcerpc_samr_LookupDomain(b, mem_ctx,
2724 &connect_pol,
2725 &domain_name,
2726 &sid,
2727 &result);
2728 if (!NT_STATUS_IS_OK(status)) {
2729 goto done;
2731 if (!NT_STATUS_IS_OK(result)) {
2732 status = result;
2733 goto done;
2736 if (NT_STATUS_IS_OK(result)) {
2737 sid_to_fstring(sid_string, sid);
2738 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2739 argv[1], sid_string);
2742 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2743 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2744 done:
2745 return status;
2748 /* Change user password */
2750 static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli,
2751 TALLOC_CTX *mem_ctx,
2752 int argc, const char **argv)
2754 struct policy_handle connect_pol, domain_pol, user_pol;
2755 NTSTATUS status, result;
2756 const char *user, *oldpass, *newpass;
2757 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2758 struct samr_Ids rids, types;
2759 struct lsa_String lsa_acct_name;
2760 struct dcerpc_binding_handle *b = cli->binding_handle;
2762 if (argc < 3) {
2763 printf("Usage: %s username oldpass newpass\n", argv[0]);
2764 return NT_STATUS_INVALID_PARAMETER;
2767 user = argv[1];
2768 oldpass = argv[2];
2769 newpass = argv[3];
2771 /* Get sam policy handle */
2773 status = rpccli_try_samr_connects(cli, mem_ctx,
2774 MAXIMUM_ALLOWED_ACCESS,
2775 &connect_pol);
2776 if (!NT_STATUS_IS_OK(status)) {
2777 goto done;
2780 /* Get domain policy handle */
2782 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2783 &connect_pol,
2784 access_mask,
2785 &domain_sid,
2786 &domain_pol,
2787 &result);
2788 if (!NT_STATUS_IS_OK(status)) {
2789 goto done;
2791 if (!NT_STATUS_IS_OK(result)) {
2792 status = result;
2793 goto done;
2796 init_lsa_String(&lsa_acct_name, user);
2798 status = dcerpc_samr_LookupNames(b, mem_ctx,
2799 &domain_pol,
2801 &lsa_acct_name,
2802 &rids,
2803 &types,
2804 &result);
2805 if (!NT_STATUS_IS_OK(status)) {
2806 goto done;
2808 if (!NT_STATUS_IS_OK(result)) {
2809 status = result;
2810 goto done;
2812 if (rids.count != 1) {
2813 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2814 goto done;
2816 if (types.count != 1) {
2817 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2818 goto done;
2821 status = dcerpc_samr_OpenUser(b, mem_ctx,
2822 &domain_pol,
2823 access_mask,
2824 rids.ids[0],
2825 &user_pol,
2826 &result);
2827 if (!NT_STATUS_IS_OK(status)) {
2828 goto done;
2830 if (!NT_STATUS_IS_OK(result)) {
2831 status = result;
2832 goto done;
2835 /* Change user password */
2836 status = rpccli_samr_chgpasswd_user(cli, mem_ctx,
2837 &user_pol,
2838 newpass,
2839 oldpass);
2840 if (!NT_STATUS_IS_OK(status)) {
2841 goto done;
2844 done:
2845 if (is_valid_policy_hnd(&user_pol)) {
2846 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2848 if (is_valid_policy_hnd(&domain_pol)) {
2849 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2851 if (is_valid_policy_hnd(&connect_pol)) {
2852 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2855 return status;
2859 /* Change user password */
2861 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2862 TALLOC_CTX *mem_ctx,
2863 int argc, const char **argv)
2865 struct policy_handle connect_pol, domain_pol;
2866 NTSTATUS status, result;
2867 const char *user, *oldpass, *newpass;
2868 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2869 struct dcerpc_binding_handle *b = cli->binding_handle;
2871 if (argc < 3) {
2872 printf("Usage: %s username oldpass newpass\n", argv[0]);
2873 return NT_STATUS_INVALID_PARAMETER;
2876 user = argv[1];
2877 oldpass = argv[2];
2878 newpass = argv[3];
2880 /* Get sam policy handle */
2882 status = rpccli_try_samr_connects(cli, mem_ctx,
2883 MAXIMUM_ALLOWED_ACCESS,
2884 &connect_pol);
2885 if (!NT_STATUS_IS_OK(status)) {
2886 goto done;
2889 /* Get domain policy handle */
2891 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2892 &connect_pol,
2893 access_mask,
2894 &domain_sid,
2895 &domain_pol,
2896 &result);
2897 if (!NT_STATUS_IS_OK(status)) {
2898 goto done;
2900 if (!NT_STATUS_IS_OK(result)) {
2901 status = result;
2902 goto done;
2905 /* Change user password */
2906 status = rpccli_samr_chgpasswd_user2(cli, mem_ctx, user, newpass, oldpass);
2908 if (!NT_STATUS_IS_OK(status)) {
2909 goto done;
2912 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2913 if (!NT_STATUS_IS_OK(status)) goto done;
2915 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2916 if (!NT_STATUS_IS_OK(status)) goto done;
2918 done:
2919 return status;
2923 /* Change user password */
2925 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
2926 TALLOC_CTX *mem_ctx,
2927 int argc, const char **argv)
2929 struct policy_handle connect_pol, domain_pol;
2930 NTSTATUS status, result;
2931 const char *user, *oldpass, *newpass;
2932 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2933 struct samr_DomInfo1 *info = NULL;
2934 struct userPwdChangeFailureInformation *reject = NULL;
2935 struct dcerpc_binding_handle *b = cli->binding_handle;
2937 if (argc < 3) {
2938 printf("Usage: %s username oldpass newpass\n", argv[0]);
2939 return NT_STATUS_INVALID_PARAMETER;
2942 user = argv[1];
2943 oldpass = argv[2];
2944 newpass = argv[3];
2946 /* Get sam policy handle */
2948 status = rpccli_try_samr_connects(cli, mem_ctx,
2949 MAXIMUM_ALLOWED_ACCESS,
2950 &connect_pol);
2951 if (!NT_STATUS_IS_OK(status)) {
2952 goto done;
2955 /* Get domain policy handle */
2957 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2958 &connect_pol,
2959 access_mask,
2960 &domain_sid,
2961 &domain_pol,
2962 &result);
2963 if (!NT_STATUS_IS_OK(status)) {
2964 goto done;
2966 if (!NT_STATUS_IS_OK(result)) {
2967 status = result;
2968 goto done;
2971 /* Change user password */
2972 status = rpccli_samr_chgpasswd_user3(cli, mem_ctx,
2973 user,
2974 newpass,
2975 oldpass,
2976 &info,
2977 &reject);
2978 if (!NT_STATUS_IS_OK(status)) {
2979 goto done;
2982 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2984 display_sam_dom_info_1(info);
2986 switch (reject->extendedFailureReason) {
2987 case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT:
2988 d_printf("SAM_PWD_CHANGE_PASSWORD_TOO_SHORT\n");
2989 break;
2990 case SAM_PWD_CHANGE_PWD_IN_HISTORY:
2991 d_printf("SAM_PWD_CHANGE_PWD_IN_HISTORY\n");
2992 break;
2993 case SAM_PWD_CHANGE_NOT_COMPLEX:
2994 d_printf("SAM_PWD_CHANGE_NOT_COMPLEX\n");
2995 break;
2996 default:
2997 d_printf("unknown reject reason: %d\n",
2998 reject->extendedFailureReason);
2999 break;
3003 if (!NT_STATUS_IS_OK(result)) {
3004 status = result;
3005 goto done;
3008 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
3009 if (!NT_STATUS_IS_OK(status)) goto done;
3011 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
3012 if (!NT_STATUS_IS_OK(status)) goto done;
3014 done:
3015 return status;
3018 static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli,
3019 TALLOC_CTX *mem_ctx,
3020 int argc, const char **argv,
3021 int opcode)
3023 struct policy_handle connect_pol, domain_pol, user_pol;
3024 NTSTATUS status, result;
3025 const char *user, *param;
3026 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
3027 uint32_t level;
3028 uint32_t user_rid;
3029 union samr_UserInfo info;
3030 struct samr_CryptPassword pwd_buf;
3031 struct samr_CryptPasswordEx pwd_buf_ex;
3032 uint8_t nt_hash[16];
3033 uint8_t lm_hash[16];
3034 DATA_BLOB session_key;
3035 uint8_t password_expired = 0;
3036 struct dcerpc_binding_handle *b = cli->binding_handle;
3038 if (argc < 4) {
3039 printf("Usage: %s username level password [password_expired]\n",
3040 argv[0]);
3041 return NT_STATUS_INVALID_PARAMETER;
3044 user = argv[1];
3045 level = atoi(argv[2]);
3046 param = argv[3];
3048 if (argc >= 5) {
3049 password_expired = atoi(argv[4]);
3052 status = cli_get_session_key(mem_ctx, cli, &session_key);
3053 if (!NT_STATUS_IS_OK(status)) {
3054 return status;
3057 init_samr_CryptPassword(param, &session_key, &pwd_buf);
3058 init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex);
3059 nt_lm_owf_gen(param, nt_hash, lm_hash);
3061 switch (level) {
3062 case 18:
3064 DATA_BLOB in,out;
3065 in = data_blob_const(nt_hash, 16);
3066 out = data_blob_talloc_zero(mem_ctx, 16);
3067 sess_crypt_blob(&out, &in, &session_key, true);
3068 memcpy(nt_hash, out.data, out.length);
3071 DATA_BLOB in,out;
3072 in = data_blob_const(lm_hash, 16);
3073 out = data_blob_talloc_zero(mem_ctx, 16);
3074 sess_crypt_blob(&out, &in, &session_key, true);
3075 memcpy(lm_hash, out.data, out.length);
3078 memcpy(info.info18.nt_pwd.hash, nt_hash, 16);
3079 memcpy(info.info18.lm_pwd.hash, lm_hash, 16);
3080 info.info18.nt_pwd_active = true;
3081 info.info18.lm_pwd_active = true;
3082 info.info18.password_expired = password_expired;
3084 break;
3085 case 21:
3086 ZERO_STRUCT(info.info21);
3088 info.info21.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3089 SAMR_FIELD_LM_PASSWORD_PRESENT;
3090 if (argc >= 5) {
3091 info.info21.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3092 info.info21.password_expired = password_expired;
3095 info.info21.lm_password_set = true;
3096 info.info21.lm_owf_password.length = 16;
3097 info.info21.lm_owf_password.size = 16;
3099 info.info21.nt_password_set = true;
3100 info.info21.nt_owf_password.length = 16;
3101 info.info21.nt_owf_password.size = 16;
3104 DATA_BLOB in,out;
3105 in = data_blob_const(nt_hash, 16);
3106 out = data_blob_talloc_zero(mem_ctx, 16);
3107 sess_crypt_blob(&out, &in, &session_key, true);
3108 info.info21.nt_owf_password.array =
3109 (uint16_t *)talloc_memdup(mem_ctx, out.data, 16);
3112 DATA_BLOB in,out;
3113 in = data_blob_const(lm_hash, 16);
3114 out = data_blob_talloc_zero(mem_ctx, 16);
3115 sess_crypt_blob(&out, &in, &session_key, true);
3116 info.info21.lm_owf_password.array =
3117 (uint16_t *)talloc_memdup(mem_ctx, out.data, 16);
3120 break;
3121 case 23:
3122 ZERO_STRUCT(info.info23);
3124 info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3125 SAMR_FIELD_LM_PASSWORD_PRESENT;
3126 if (argc >= 5) {
3127 info.info23.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3128 info.info23.info.password_expired = password_expired;
3131 info.info23.password = pwd_buf;
3133 break;
3134 case 24:
3135 info.info24.password = pwd_buf;
3136 info.info24.password_expired = password_expired;
3138 break;
3139 case 25:
3140 ZERO_STRUCT(info.info25);
3142 info.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3143 SAMR_FIELD_LM_PASSWORD_PRESENT;
3144 if (argc >= 5) {
3145 info.info25.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3146 info.info25.info.password_expired = password_expired;
3149 info.info25.password = pwd_buf_ex;
3151 break;
3152 case 26:
3153 info.info26.password = pwd_buf_ex;
3154 info.info26.password_expired = password_expired;
3156 break;
3157 default:
3158 return NT_STATUS_INVALID_INFO_CLASS;
3161 /* Get sam policy handle */
3163 status = rpccli_try_samr_connects(cli, mem_ctx,
3164 MAXIMUM_ALLOWED_ACCESS,
3165 &connect_pol);
3166 if (!NT_STATUS_IS_OK(status)) {
3167 goto done;
3170 /* Get domain policy handle */
3172 status = dcerpc_samr_OpenDomain(b, mem_ctx,
3173 &connect_pol,
3174 access_mask,
3175 &domain_sid,
3176 &domain_pol,
3177 &result);
3179 if (!NT_STATUS_IS_OK(status))
3180 goto done;
3181 if (!NT_STATUS_IS_OK(result)) {
3182 status = result;
3183 goto done;
3186 user_rid = strtol(user, NULL, 0);
3187 if (user_rid) {
3188 status = dcerpc_samr_OpenUser(b, mem_ctx,
3189 &domain_pol,
3190 access_mask,
3191 user_rid,
3192 &user_pol,
3193 &result);
3194 if (!NT_STATUS_IS_OK(status)) {
3195 goto done;
3198 status = result;
3201 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) ||
3202 (user_rid == 0)) {
3204 /* Probably this was a user name, try lookupnames */
3205 struct samr_Ids rids, types;
3206 struct lsa_String lsa_acct_name;
3208 init_lsa_String(&lsa_acct_name, user);
3210 status = dcerpc_samr_LookupNames(b, mem_ctx,
3211 &domain_pol,
3213 &lsa_acct_name,
3214 &rids,
3215 &types,
3216 &result);
3217 if (!NT_STATUS_IS_OK(status)) {
3218 return status;
3220 if (!NT_STATUS_IS_OK(result)) {
3221 return result;
3223 if (rids.count != 1) {
3224 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3226 if (types.count != 1) {
3227 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3230 status = dcerpc_samr_OpenUser(b, mem_ctx,
3231 &domain_pol,
3232 access_mask,
3233 rids.ids[0],
3234 &user_pol,
3235 &result);
3236 if (!NT_STATUS_IS_OK(status)) {
3237 return status;
3239 if (!NT_STATUS_IS_OK(result)) {
3240 return result;
3244 switch (opcode) {
3245 case NDR_SAMR_SETUSERINFO:
3246 status = dcerpc_samr_SetUserInfo(b, mem_ctx,
3247 &user_pol,
3248 level,
3249 &info,
3250 &result);
3251 break;
3252 case NDR_SAMR_SETUSERINFO2:
3253 status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
3254 &user_pol,
3255 level,
3256 &info,
3257 &result);
3258 break;
3259 default:
3260 return NT_STATUS_INVALID_PARAMETER;
3262 if (!NT_STATUS_IS_OK(status)) {
3263 DEBUG(0,("status: %s\n", nt_errstr(status)));
3264 goto done;
3266 if (!NT_STATUS_IS_OK(result)) {
3267 status = result;
3268 DEBUG(0,("result: %s\n", nt_errstr(status)));
3269 goto done;
3271 done:
3272 return status;
3275 static NTSTATUS cmd_samr_setuserinfo(struct rpc_pipe_client *cli,
3276 TALLOC_CTX *mem_ctx,
3277 int argc, const char **argv)
3279 return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
3280 NDR_SAMR_SETUSERINFO);
3283 static NTSTATUS cmd_samr_setuserinfo2(struct rpc_pipe_client *cli,
3284 TALLOC_CTX *mem_ctx,
3285 int argc, const char **argv)
3287 return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
3288 NDR_SAMR_SETUSERINFO2);
3291 static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
3292 TALLOC_CTX *mem_ctx,
3293 int argc, const char **argv)
3295 NTSTATUS status, result;
3296 struct policy_handle connect_handle;
3297 struct policy_handle domain_handle;
3298 uint16_t level = 1;
3299 struct lsa_String name;
3300 uint32_t idx = 0;
3301 struct dcerpc_binding_handle *b = cli->binding_handle;
3303 if (argc < 2 || argc > 3) {
3304 printf("Usage: %s name level\n", argv[0]);
3305 return NT_STATUS_INVALID_PARAMETER;
3308 init_lsa_String(&name, argv[1]);
3310 if (argc == 3) {
3311 level = atoi(argv[2]);
3314 status = rpccli_try_samr_connects(cli, mem_ctx,
3315 SEC_FLAG_MAXIMUM_ALLOWED,
3316 &connect_handle);
3317 if (!NT_STATUS_IS_OK(status)) {
3318 goto done;
3321 status = dcerpc_samr_OpenDomain(b, mem_ctx,
3322 &connect_handle,
3323 SEC_FLAG_MAXIMUM_ALLOWED,
3324 &domain_sid,
3325 &domain_handle,
3326 &result);
3327 if (!NT_STATUS_IS_OK(status)) {
3328 goto done;
3330 if (!NT_STATUS_IS_OK(result)) {
3331 status = result;
3332 goto done;
3335 status = dcerpc_samr_GetDisplayEnumerationIndex(b, mem_ctx,
3336 &domain_handle,
3337 level,
3338 &name,
3339 &idx,
3340 &result);
3341 if (!NT_STATUS_IS_OK(status)) {
3342 goto done;
3345 status = result;
3347 if (NT_STATUS_IS_OK(status) ||
3348 NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
3349 printf("idx: %d (0x%08x)\n", idx, idx);
3351 done:
3353 if (is_valid_policy_hnd(&domain_handle)) {
3354 dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
3356 if (is_valid_policy_hnd(&connect_handle)) {
3357 dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
3360 return status;
3363 /* List of commands exported by this module */
3365 struct cmd_set samr_commands[] = {
3367 { "SAMR" },
3369 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, &ndr_table_samr.syntax_id, NULL, "Query user info", "" },
3370 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, &ndr_table_samr.syntax_id, NULL, "Query group info", "" },
3371 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, &ndr_table_samr.syntax_id, NULL, "Query user groups", "" },
3372 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, &ndr_table_samr.syntax_id, NULL, "Query user aliases", "" },
3373 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, &ndr_table_samr.syntax_id, NULL, "Query group membership", "" },
3374 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, &ndr_table_samr.syntax_id, NULL, "Query alias membership", "" },
3375 { "queryaliasinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query alias info", "" },
3376 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, &ndr_table_samr.syntax_id, NULL, "Delete an alias", "" },
3377 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
3378 { "querydispinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo2, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
3379 { "querydispinfo3", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo3, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
3380 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query domain info", "" },
3381 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domain users", "" },
3382 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domain groups", "" },
3383 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate alias groups", "" },
3384 { "enumdomains", RPC_RTYPE_NTSTATUS, cmd_samr_enum_domains, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domains", "" },
3386 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain user", "" },
3387 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain group", "" },
3388 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain alias", "" },
3389 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, &ndr_table_samr.syntax_id, NULL, "Look up names", "" },
3390 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, &ndr_table_samr.syntax_id, NULL, "Look up names", "" },
3391 { "deletedomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group, NULL, &ndr_table_samr.syntax_id, NULL, "Delete domain group", "" },
3392 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, &ndr_table_samr.syntax_id, NULL, "Delete domain user", "" },
3393 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, &ndr_table_samr.syntax_id, NULL, "Query SAMR security object", "" },
3394 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Retrieve domain password info", "" },
3395 { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Retrieve user domain password info", "" },
3397 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, &ndr_table_samr.syntax_id, NULL, "Lookup Domain Name", "" },
3398 { "chgpasswd", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
3399 { "chgpasswd2", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
3400 { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
3401 { "getdispinfoidx", RPC_RTYPE_NTSTATUS, cmd_samr_get_dispinfo_idx, NULL, &ndr_table_samr.syntax_id, NULL, "Get Display Information Index", "" },
3402 { "setuserinfo", RPC_RTYPE_NTSTATUS, cmd_samr_setuserinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Set user info", "" },
3403 { "setuserinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_setuserinfo2, NULL, &ndr_table_samr.syntax_id, NULL, "Set user info2", "" },
3404 { NULL }