s3:client: Fix old-style function definition
[Samba.git] / source3 / rpcclient / cmd_samr.c
blob8106ca90cf221c9fa3ba4453ca9e5b2111757c64
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"
34 #include "lib/util/smb_strtox.h"
36 static struct dom_sid domain_sid;
38 /****************************************************************************
39 display samr_user_info_7 structure
40 ****************************************************************************/
41 static void display_samr_user_info_7(struct samr_UserInfo7 *r)
43 printf("\tUser Name :\t%s\n", r->account_name.string);
46 /****************************************************************************
47 display samr_user_info_9 structure
48 ****************************************************************************/
49 static void display_samr_user_info_9(struct samr_UserInfo9 *r)
51 printf("\tPrimary group RID :\tox%x\n", r->primary_gid);
54 /****************************************************************************
55 display samr_user_info_16 structure
56 ****************************************************************************/
57 static void display_samr_user_info_16(struct samr_UserInfo16 *r)
59 printf("\tAcct Flags :\tox%x\n", r->acct_flags);
62 /****************************************************************************
63 display samr_user_info_20 structure
64 ****************************************************************************/
65 static void display_samr_user_info_20(struct samr_UserInfo20 *r)
67 printf("\tRemote Dial :\n");
68 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
72 /****************************************************************************
73 display samr_user_info_21 structure
74 ****************************************************************************/
75 static void display_samr_user_info_21(struct samr_UserInfo21 *r)
77 printf("\tUser Name :\t%s\n", r->account_name.string);
78 printf("\tFull Name :\t%s\n", r->full_name.string);
79 printf("\tHome Drive :\t%s\n", r->home_directory.string);
80 printf("\tDir Drive :\t%s\n", r->home_drive.string);
81 printf("\tProfile Path:\t%s\n", r->profile_path.string);
82 printf("\tLogon Script:\t%s\n", r->logon_script.string);
83 printf("\tDescription :\t%s\n", r->description.string);
84 printf("\tWorkstations:\t%s\n", r->workstations.string);
85 printf("\tComment :\t%s\n", r->comment.string);
86 printf("\tRemote Dial :\n");
87 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
89 printf("\tLogon Time :\t%s\n",
90 http_timestring(talloc_tos(), nt_time_to_unix(r->last_logon)));
91 printf("\tLogoff Time :\t%s\n",
92 http_timestring(talloc_tos(), nt_time_to_unix(r->last_logoff)));
93 printf("\tKickoff Time :\t%s\n",
94 http_timestring(talloc_tos(), nt_time_to_unix(r->acct_expiry)));
95 printf("\tPassword last set Time :\t%s\n",
96 http_timestring(talloc_tos(), nt_time_to_unix(r->last_password_change)));
97 printf("\tPassword can change Time :\t%s\n",
98 http_timestring(talloc_tos(), nt_time_to_unix(r->allow_password_change)));
99 printf("\tPassword must change Time:\t%s\n",
100 http_timestring(talloc_tos(), nt_time_to_unix(r->force_password_change)));
102 printf("\tunknown_2[0..31]...\n"); /* user passwords? */
104 printf("\tuser_rid :\t0x%x\n" , r->rid); /* User ID */
105 printf("\tgroup_rid:\t0x%x\n" , r->primary_gid); /* Group ID */
106 printf("\tacb_info :\t0x%08x\n", r->acct_flags); /* Account Control Info */
108 printf("\tfields_present:\t0x%08x\n", r->fields_present); /* 0x00ff ffff */
109 printf("\tlogon_divs:\t%d\n", r->logon_hours.units_per_week); /* 0x0000 00a8 which is 168 which is num hrs in a week */
110 printf("\tbad_password_count:\t0x%08x\n", r->bad_password_count);
111 printf("\tlogon_count:\t0x%08x\n", r->logon_count);
113 printf("\tpadding1[0..7]...\n");
115 if (r->logon_hours.bits) {
116 printf("\tlogon_hrs[0..%d]...\n", r->logon_hours.units_per_week/8);
121 static void display_password_properties(uint32_t password_properties)
123 printf("password_properties: 0x%08x\n", password_properties);
125 if (password_properties & DOMAIN_PASSWORD_COMPLEX)
126 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
128 if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
129 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
131 if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
132 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
134 if (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)
135 printf("\tDOMAIN_PASSWORD_LOCKOUT_ADMINS\n");
137 if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
138 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
140 if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
141 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
144 static void display_sam_dom_info_1(struct samr_DomInfo1 *info1)
146 printf("Minimum password length:\t\t\t%d\n",
147 info1->min_password_length);
148 printf("Password uniqueness (remember x passwords):\t%d\n",
149 info1->password_history_length);
150 display_password_properties(info1->password_properties);
151 printf("password expire in:\t\t\t\t%s\n",
152 display_time(info1->max_password_age));
153 printf("Min password age (allow changing in x days):\t%s\n",
154 display_time(info1->min_password_age));
157 static void display_sam_dom_info_2(struct samr_DomGeneralInformation *general)
159 printf("Domain:\t\t%s\n", general->domain_name.string);
160 printf("Server:\t\t%s\n", general->primary.string);
161 printf("Comment:\t%s\n", general->oem_information.string);
163 printf("Total Users:\t%d\n", general->num_users);
164 printf("Total Groups:\t%d\n", general->num_groups);
165 printf("Total Aliases:\t%d\n", general->num_aliases);
167 printf("Sequence No:\t%llu\n", (unsigned long long)general->sequence_num);
169 printf("Force Logoff:\t%d\n",
170 (int)nt_time_to_unix_abs(&general->force_logoff_time));
172 printf("Domain Server State:\t0x%x\n", general->domain_server_state);
173 printf("Server Role:\t%s\n", server_role_str(general->role));
174 printf("Unknown 3:\t0x%x\n", general->unknown3);
177 static void display_sam_dom_info_3(struct samr_DomInfo3 *info3)
179 printf("Force Logoff:\t%d\n",
180 (int)nt_time_to_unix_abs(&info3->force_logoff_time));
183 static void display_sam_dom_info_4(struct samr_DomOEMInformation *oem)
185 printf("Comment:\t%s\n", oem->oem_information.string);
188 static void display_sam_dom_info_5(struct samr_DomInfo5 *info5)
190 printf("Domain:\t\t%s\n", info5->domain_name.string);
193 static void display_sam_dom_info_6(struct samr_DomInfo6 *info6)
195 printf("Server:\t\t%s\n", info6->primary.string);
198 static void display_sam_dom_info_7(struct samr_DomInfo7 *info7)
200 printf("Server Role:\t%s\n", server_role_str(info7->role));
203 static void display_sam_dom_info_8(struct samr_DomInfo8 *info8)
205 printf("Sequence No:\t%llu\n", (unsigned long long)info8->sequence_num);
206 printf("Domain Create Time:\t%s\n",
207 http_timestring(talloc_tos(), nt_time_to_unix(info8->domain_create_time)));
210 static void display_sam_dom_info_9(struct samr_DomInfo9 *info9)
212 printf("Domain Server State:\t0x%x\n", info9->domain_server_state);
215 static void display_sam_dom_info_12(struct samr_DomInfo12 *info12)
217 printf("Bad password lockout duration: %s\n",
218 display_time(info12->lockout_duration));
219 printf("Reset Lockout after: %s\n",
220 display_time(info12->lockout_window));
221 printf("Lockout after bad attempts: %d\n",
222 info12->lockout_threshold);
225 static void display_sam_dom_info_13(struct samr_DomInfo13 *info13)
227 printf("Sequence No:\t%llu\n", (unsigned long long)info13->sequence_num);
228 printf("Domain Create Time:\t%s\n",
229 http_timestring(talloc_tos(), nt_time_to_unix(info13->domain_create_time)));
230 printf("Sequence No at last promotion:\t%llu\n",
231 (unsigned long long)info13->modified_count_at_last_promotion);
234 static void display_sam_info_1(struct samr_DispEntryGeneral *r)
236 printf("index: 0x%x ", r->idx);
237 printf("RID: 0x%x ", r->rid);
238 printf("acb: 0x%08x ", r->acct_flags);
239 printf("Account: %s\t", r->account_name.string);
240 printf("Name: %s\t", r->full_name.string);
241 printf("Desc: %s\n", r->description.string);
244 static void display_sam_info_2(struct samr_DispEntryFull *r)
246 printf("index: 0x%x ", r->idx);
247 printf("RID: 0x%x ", r->rid);
248 printf("acb: 0x%08x ", r->acct_flags);
249 printf("Account: %s\t", r->account_name.string);
250 printf("Desc: %s\n", r->description.string);
253 static void display_sam_info_3(struct samr_DispEntryFullGroup *r)
255 printf("index: 0x%x ", r->idx);
256 printf("RID: 0x%x ", r->rid);
257 printf("acb: 0x%08x ", r->acct_flags);
258 printf("Account: %s\t", r->account_name.string);
259 printf("Desc: %s\n", r->description.string);
262 static void display_sam_info_4(struct samr_DispEntryAscii *r)
264 printf("index: 0x%x ", r->idx);
265 printf("Account: %s\n", r->account_name.string);
268 static void display_sam_info_5(struct samr_DispEntryAscii *r)
270 printf("index: 0x%x ", r->idx);
271 printf("Account: %s\n", r->account_name.string);
274 static NTSTATUS rpccli_try_samr_connects(
275 struct rpc_pipe_client *cli,
276 TALLOC_CTX *mem_ctx,
277 uint32_t access_mask,
278 struct policy_handle *connect_pol)
280 struct dcerpc_binding_handle *b = cli->binding_handle;
281 NTSTATUS status;
282 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
283 uint32_t start_idx = 0;
284 uint32_t i, num_entries;
285 struct samr_SamArray *sam = NULL;
286 struct dom_sid *domsid = NULL;
288 status = dcerpc_try_samr_connects(
290 mem_ctx,
291 cli->srv_name_slash,
292 access_mask,
293 connect_pol,
294 &result);
295 if (!NT_STATUS_IS_OK(status)) {
296 return status;
298 if (!NT_STATUS_IS_OK(result)) {
299 return result;
302 if (!is_null_sid(&domain_sid)) {
303 return NT_STATUS_OK;
307 * Look up the servers domain SID. Just pick the first
308 * non-builtin domain from samr_EnumDomains.
311 status = dcerpc_samr_EnumDomains(
313 mem_ctx,
314 connect_pol,
315 &start_idx,
316 &sam,
317 0xffff,
318 &num_entries,
319 &result);
320 if (!NT_STATUS_IS_OK(status)) {
321 goto fail;
323 if (!NT_STATUS_IS_OK(result)) {
324 status = result;
325 goto fail;
328 for (i=0; i<num_entries; i++) {
329 if (!strequal(sam->entries[i].name.string, "builtin")) {
330 break;
333 if (i == num_entries) {
334 status = NT_STATUS_NOT_FOUND;
335 goto fail;
338 status = dcerpc_samr_LookupDomain(
340 mem_ctx,
341 connect_pol,
342 &sam->entries[i].name,
343 &domsid,
344 &result);
345 if (!NT_STATUS_IS_OK(status)) {
346 goto fail;
348 if (!NT_STATUS_IS_OK(result)) {
349 status = result;
350 goto fail;
353 sid_copy(&domain_sid, domsid);
354 TALLOC_FREE(domsid);
356 return NT_STATUS_OK;
358 fail:
359 dcerpc_samr_Close(b, mem_ctx, connect_pol, &result);
360 return status;
363 /****************************************************************************
364 ****************************************************************************/
366 static NTSTATUS get_domain_handle(struct rpc_pipe_client *cli,
367 TALLOC_CTX *mem_ctx,
368 const char *sam,
369 struct policy_handle *connect_pol,
370 uint32_t access_mask,
371 struct dom_sid *_domain_sid,
372 struct policy_handle *domain_pol)
374 struct dcerpc_binding_handle *b = cli->binding_handle;
375 NTSTATUS status = NT_STATUS_INVALID_PARAMETER, result;
377 if (strcasecmp_m(sam, "domain") == 0) {
378 status = dcerpc_samr_OpenDomain(b, mem_ctx,
379 connect_pol,
380 access_mask,
381 _domain_sid,
382 domain_pol,
383 &result);
384 } else if (strcasecmp_m(sam, "builtin") == 0) {
385 status = dcerpc_samr_OpenDomain(b, mem_ctx,
386 connect_pol,
387 access_mask,
388 discard_const_p(struct dom_sid2, &global_sid_Builtin),
389 domain_pol,
390 &result);
393 if (!NT_STATUS_IS_OK(status)) {
394 return status;
397 return result;
400 /**********************************************************************
401 * Query user information
403 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
404 TALLOC_CTX *mem_ctx,
405 int argc, const char **argv)
407 struct policy_handle connect_pol, domain_pol, user_pol;
408 NTSTATUS status, result;
409 uint32_t info_level = 21;
410 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
411 union samr_UserInfo *info = NULL;
412 uint32_t user_rid = 0;
413 struct dcerpc_binding_handle *b = cli->binding_handle;
415 if ((argc < 2) || (argc > 4)) {
416 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
417 return NT_STATUS_OK;
420 sscanf(argv[1], "%i", &user_rid);
422 if (argc > 2)
423 sscanf(argv[2], "%i", &info_level);
425 if (argc > 3)
426 sscanf(argv[3], "%x", &access_mask);
429 status = rpccli_try_samr_connects(cli, mem_ctx,
430 MAXIMUM_ALLOWED_ACCESS,
431 &connect_pol);
432 if (!NT_STATUS_IS_OK(status)) {
433 goto done;
436 status = dcerpc_samr_OpenDomain(b, mem_ctx,
437 &connect_pol,
438 MAXIMUM_ALLOWED_ACCESS,
439 &domain_sid,
440 &domain_pol,
441 &result);
442 if (!NT_STATUS_IS_OK(status)) {
443 goto done;
445 if (!NT_STATUS_IS_OK(result)) {
446 status = result;
447 goto done;
450 status = dcerpc_samr_OpenUser(b, mem_ctx,
451 &domain_pol,
452 access_mask,
453 user_rid,
454 &user_pol,
455 &result);
456 if (!NT_STATUS_IS_OK(status)) {
457 goto done;
459 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
460 (user_rid == 0)) {
462 /* Probably this was a user name, try lookupnames */
463 struct samr_Ids rids, types;
464 struct lsa_String lsa_acct_name;
466 init_lsa_String(&lsa_acct_name, argv[1]);
468 status = dcerpc_samr_LookupNames(b, mem_ctx,
469 &domain_pol,
471 &lsa_acct_name,
472 &rids,
473 &types,
474 &result);
475 if (!NT_STATUS_IS_OK(status)) {
476 goto done;
479 if (NT_STATUS_IS_OK(result)) {
480 if (rids.count != 1) {
481 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
482 goto done;
484 if (types.count != 1) {
485 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
486 goto done;
489 status = dcerpc_samr_OpenUser(b, mem_ctx,
490 &domain_pol,
491 access_mask,
492 rids.ids[0],
493 &user_pol,
494 &result);
495 if (!NT_STATUS_IS_OK(status)) {
496 goto done;
502 if (!NT_STATUS_IS_OK(result)) {
503 status = result;
504 goto done;
507 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
508 &user_pol,
509 info_level,
510 &info,
511 &result);
512 if (!NT_STATUS_IS_OK(status)) {
513 goto done;
515 if (!NT_STATUS_IS_OK(result)) {
516 status = result;
517 goto done;
520 switch (info_level) {
521 case 7:
522 display_samr_user_info_7(&info->info7);
523 break;
524 case 9:
525 display_samr_user_info_9(&info->info9);
526 break;
527 case 16:
528 display_samr_user_info_16(&info->info16);
529 break;
530 case 20:
531 display_samr_user_info_20(&info->info20);
532 break;
533 case 21:
534 display_samr_user_info_21(&info->info21);
535 break;
536 default:
537 printf("Unsupported infolevel: %d\n", info_level);
538 break;
541 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
542 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
543 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
545 done:
546 return status;
549 /****************************************************************************
550 display group info
551 ****************************************************************************/
552 static void display_group_info1(struct samr_GroupInfoAll *info1)
554 printf("\tGroup Name:\t%s\n", info1->name.string);
555 printf("\tDescription:\t%s\n", info1->description.string);
556 printf("\tGroup Attribute:%d\n", info1->attributes);
557 printf("\tNum Members:%d\n", info1->num_members);
560 /****************************************************************************
561 display group info
562 ****************************************************************************/
563 static void display_group_info2(struct lsa_String *info2)
565 printf("\tGroup Description:%s\n", info2->string);
569 /****************************************************************************
570 display group info
571 ****************************************************************************/
572 static void display_group_info3(struct samr_GroupInfoAttributes *info3)
574 printf("\tGroup Attribute:%d\n", info3->attributes);
578 /****************************************************************************
579 display group info
580 ****************************************************************************/
581 static void display_group_info4(struct lsa_String *info4)
583 printf("\tGroup Description:%s\n", info4->string);
586 /****************************************************************************
587 display group info
588 ****************************************************************************/
589 static void display_group_info5(struct samr_GroupInfoAll *info5)
591 printf("\tGroup Name:\t%s\n", info5->name.string);
592 printf("\tDescription:\t%s\n", info5->description.string);
593 printf("\tGroup Attribute:%d\n", info5->attributes);
594 printf("\tNum Members:%d\n", info5->num_members);
597 /****************************************************************************
598 display sam sync structure
599 ****************************************************************************/
600 static void display_group_info(union samr_GroupInfo *info,
601 enum samr_GroupInfoEnum level)
603 switch (level) {
604 case 1:
605 display_group_info1(&info->all);
606 break;
607 case 2:
608 display_group_info2(&info->name);
609 break;
610 case 3:
611 display_group_info3(&info->attributes);
612 break;
613 case 4:
614 display_group_info4(&info->description);
615 break;
616 case 5:
617 display_group_info5(&info->all2);
618 break;
622 /***********************************************************************
623 * Query group information
625 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
626 TALLOC_CTX *mem_ctx,
627 int argc, const char **argv)
629 struct policy_handle connect_pol, domain_pol, group_pol;
630 NTSTATUS status, result;
631 enum samr_GroupInfoEnum info_level = GROUPINFOALL;
632 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
633 union samr_GroupInfo *group_info = NULL;
634 uint32_t group_rid;
635 struct dcerpc_binding_handle *b = cli->binding_handle;
637 if ((argc < 2) || (argc > 4)) {
638 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
639 return NT_STATUS_OK;
642 sscanf(argv[1], "%i", &group_rid);
644 if (argc > 2)
645 info_level = atoi(argv[2]);
647 if (argc > 3)
648 sscanf(argv[3], "%x", &access_mask);
650 status = rpccli_try_samr_connects(cli, mem_ctx,
651 MAXIMUM_ALLOWED_ACCESS,
652 &connect_pol);
653 if (!NT_STATUS_IS_OK(status)) {
654 goto done;
657 status = dcerpc_samr_OpenDomain(b, mem_ctx,
658 &connect_pol,
659 MAXIMUM_ALLOWED_ACCESS,
660 &domain_sid,
661 &domain_pol,
662 &result);
663 if (!NT_STATUS_IS_OK(status)) {
664 goto done;
666 if (!NT_STATUS_IS_OK(result)) {
667 status = result;
668 goto done;
671 status = dcerpc_samr_OpenGroup(b, mem_ctx,
672 &domain_pol,
673 access_mask,
674 group_rid,
675 &group_pol,
676 &result);
677 if (!NT_STATUS_IS_OK(status)) {
678 goto done;
680 if (!NT_STATUS_IS_OK(result)) {
681 status = result;
682 goto done;
685 status = dcerpc_samr_QueryGroupInfo(b, mem_ctx,
686 &group_pol,
687 info_level,
688 &group_info,
689 &result);
690 if (!NT_STATUS_IS_OK(status)) {
691 goto done;
693 if (!NT_STATUS_IS_OK(result)) {
694 status = result;
695 goto done;
698 display_group_info(group_info, info_level);
700 dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
701 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
702 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
703 done:
704 return status;
707 /* Query groups a user is a member of */
709 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
710 TALLOC_CTX *mem_ctx,
711 int argc, const char **argv)
713 struct policy_handle connect_pol,
714 domain_pol,
715 user_pol;
716 NTSTATUS status, result;
717 uint32_t user_rid;
718 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
719 int i;
720 struct samr_RidWithAttributeArray *rid_array = NULL;
721 struct dcerpc_binding_handle *b = cli->binding_handle;
723 if ((argc < 2) || (argc > 3)) {
724 printf("Usage: %s rid [access mask]\n", argv[0]);
725 return NT_STATUS_OK;
728 sscanf(argv[1], "%i", &user_rid);
730 if (argc > 2)
731 sscanf(argv[2], "%x", &access_mask);
733 status = rpccli_try_samr_connects(cli, mem_ctx,
734 MAXIMUM_ALLOWED_ACCESS,
735 &connect_pol);
736 if (!NT_STATUS_IS_OK(status)) {
737 goto done;
740 status = dcerpc_samr_OpenDomain(b, mem_ctx,
741 &connect_pol,
742 MAXIMUM_ALLOWED_ACCESS,
743 &domain_sid,
744 &domain_pol,
745 &result);
746 if (!NT_STATUS_IS_OK(status)) {
747 goto done;
749 if (!NT_STATUS_IS_OK(result)) {
750 status = result;
751 goto done;
754 status = dcerpc_samr_OpenUser(b, mem_ctx,
755 &domain_pol,
756 access_mask,
757 user_rid,
758 &user_pol,
759 &result);
761 if (!NT_STATUS_IS_OK(status)) {
762 goto done;
764 if (!NT_STATUS_IS_OK(result)) {
765 status = result;
766 goto done;
769 status = dcerpc_samr_GetGroupsForUser(b, mem_ctx,
770 &user_pol,
771 &rid_array,
772 &result);
773 if (!NT_STATUS_IS_OK(status)) {
774 goto done;
776 if (!NT_STATUS_IS_OK(result)) {
777 status = result;
778 goto done;
781 for (i = 0; i < rid_array->count; i++) {
782 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
783 rid_array->rids[i].rid,
784 rid_array->rids[i].attributes);
787 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
788 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
789 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
790 done:
791 return status;
794 /* Query aliases a user is a member of */
796 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
797 TALLOC_CTX *mem_ctx,
798 int argc, const char **argv)
800 struct policy_handle connect_pol, domain_pol;
801 NTSTATUS status, result;
802 struct dom_sid *sids;
803 uint32_t num_sids;
804 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
805 int i;
806 struct lsa_SidArray sid_array;
807 struct samr_Ids alias_rids;
808 struct dcerpc_binding_handle *b = cli->binding_handle;
810 if (argc < 3) {
811 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
812 return NT_STATUS_INVALID_PARAMETER;
815 sids = NULL;
816 num_sids = 0;
818 for (i=2; i<argc; i++) {
819 struct dom_sid tmp_sid;
820 if (!string_to_sid(&tmp_sid, argv[i])) {
821 printf("%s is not a legal SID\n", argv[i]);
822 return NT_STATUS_INVALID_PARAMETER;
824 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
825 if (!NT_STATUS_IS_OK(result)) {
826 return result;
830 if (num_sids) {
831 sid_array.sids = talloc_zero_array(mem_ctx, struct lsa_SidPtr, num_sids);
832 if (sid_array.sids == NULL)
833 return NT_STATUS_NO_MEMORY;
834 } else {
835 sid_array.sids = NULL;
838 for (i=0; i<num_sids; i++) {
839 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]);
840 if (!sid_array.sids[i].sid) {
841 return NT_STATUS_NO_MEMORY;
845 sid_array.num_sids = num_sids;
847 status = rpccli_try_samr_connects(cli, mem_ctx,
848 MAXIMUM_ALLOWED_ACCESS,
849 &connect_pol);
850 if (!NT_STATUS_IS_OK(status)) {
851 goto done;
854 status = get_domain_handle(cli, mem_ctx, argv[1],
855 &connect_pol,
856 access_mask,
857 &domain_sid,
858 &domain_pol);
859 if (!NT_STATUS_IS_OK(status)) {
860 goto done;
863 status = dcerpc_samr_GetAliasMembership(b, mem_ctx,
864 &domain_pol,
865 &sid_array,
866 &alias_rids,
867 &result);
868 if (!NT_STATUS_IS_OK(status)) {
869 goto done;
871 if (!NT_STATUS_IS_OK(result)) {
872 status = result;
873 goto done;
876 for (i = 0; i < alias_rids.count; i++) {
877 printf("\tgroup rid:[0x%x]\n", alias_rids.ids[i]);
880 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
881 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
882 done:
883 return status;
886 /* Query members of a group */
888 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
889 TALLOC_CTX *mem_ctx,
890 int argc, const char **argv)
892 struct policy_handle connect_pol, domain_pol, group_pol;
893 NTSTATUS status, result;
894 uint32_t group_rid;
895 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
896 int i;
897 unsigned int old_timeout;
898 struct samr_RidAttrArray *rids = NULL;
899 struct dcerpc_binding_handle *b = cli->binding_handle;
901 if ((argc < 2) || (argc > 3)) {
902 printf("Usage: %s rid [access mask]\n", argv[0]);
903 return NT_STATUS_OK;
906 sscanf(argv[1], "%i", &group_rid);
908 if (argc > 2)
909 sscanf(argv[2], "%x", &access_mask);
911 status = rpccli_try_samr_connects(cli, mem_ctx,
912 MAXIMUM_ALLOWED_ACCESS,
913 &connect_pol);
914 if (!NT_STATUS_IS_OK(status)) {
915 goto done;
918 status = dcerpc_samr_OpenDomain(b, mem_ctx,
919 &connect_pol,
920 MAXIMUM_ALLOWED_ACCESS,
921 &domain_sid,
922 &domain_pol,
923 &result);
924 if (!NT_STATUS_IS_OK(status)) {
925 goto done;
927 if (!NT_STATUS_IS_OK(result)) {
928 status = result;
929 goto done;
932 status = dcerpc_samr_OpenGroup(b, mem_ctx,
933 &domain_pol,
934 access_mask,
935 group_rid,
936 &group_pol,
937 &result);
938 if (!NT_STATUS_IS_OK(status)) {
939 goto done;
941 if (!NT_STATUS_IS_OK(result)) {
942 status = result;
943 goto done;
946 /* Make sure to wait for our DC's reply */
947 old_timeout = rpccli_set_timeout(cli, 30000); /* 30 seconds. */
948 rpccli_set_timeout(cli, MAX(30000, old_timeout)); /* At least 30 sec */
950 status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
951 &group_pol,
952 &rids,
953 &result);
955 rpccli_set_timeout(cli, old_timeout);
957 if (!NT_STATUS_IS_OK(status)) {
958 goto done;
960 if (!NT_STATUS_IS_OK(result)) {
961 status = result;
962 goto done;
965 for (i = 0; i < rids->count; i++) {
966 printf("\trid:[0x%x] attr:[0x%x]\n", rids->rids[i],
967 rids->attributes[i]);
970 dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
971 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
972 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
973 done:
974 return status;
977 /* Enumerate domain users */
979 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
980 TALLOC_CTX *mem_ctx,
981 int argc, const char **argv)
983 struct policy_handle connect_pol;
984 struct policy_handle domain_pol = { 0, };
985 NTSTATUS status, result;
986 uint32_t start_idx, num_dom_users, i;
987 struct samr_SamArray *dom_users = NULL;
988 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
989 uint32_t acb_mask = ACB_NORMAL;
990 uint32_t size = 0xffff;
991 struct dcerpc_binding_handle *b = cli->binding_handle;
993 if ((argc < 1) || (argc > 4)) {
994 printf("Usage: %s [access_mask] [acb_mask] [size]\n", argv[0]);
995 return NT_STATUS_OK;
998 if (argc > 1) {
999 sscanf(argv[1], "%x", &access_mask);
1002 if (argc > 2) {
1003 sscanf(argv[2], "%x", &acb_mask);
1006 if (argc > 3) {
1007 sscanf(argv[3], "%x", &size);
1010 /* Get sam policy handle */
1012 status = rpccli_try_samr_connects(cli, mem_ctx,
1013 MAXIMUM_ALLOWED_ACCESS,
1014 &connect_pol);
1015 if (!NT_STATUS_IS_OK(status)) {
1016 goto done;
1019 /* Get domain policy handle */
1021 status = get_domain_handle(cli, mem_ctx, "domain",
1022 &connect_pol,
1023 access_mask,
1024 &domain_sid,
1025 &domain_pol);
1026 if (!NT_STATUS_IS_OK(status)) {
1027 goto done;
1030 /* Enumerate domain users */
1032 start_idx = 0;
1034 do {
1035 status = dcerpc_samr_EnumDomainUsers(b, mem_ctx,
1036 &domain_pol,
1037 &start_idx,
1038 acb_mask,
1039 &dom_users,
1040 size,
1041 &num_dom_users,
1042 &result);
1043 if (!NT_STATUS_IS_OK(status)) {
1044 goto done;
1046 if (NT_STATUS_IS_OK(result) ||
1047 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1049 for (i = 0; i < num_dom_users; i++)
1050 printf("user:[%s] rid:[0x%x]\n",
1051 dom_users->entries[i].name.string,
1052 dom_users->entries[i].idx);
1055 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1057 done:
1058 if (is_valid_policy_hnd(&domain_pol))
1059 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1061 if (is_valid_policy_hnd(&connect_pol))
1062 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1064 return status;
1067 /* Enumerate domain groups */
1069 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
1070 TALLOC_CTX *mem_ctx,
1071 int argc, const char **argv)
1073 struct policy_handle connect_pol;
1074 struct policy_handle domain_pol = { 0, };
1075 NTSTATUS status, result;
1076 uint32_t start_idx, num_dom_groups, i;
1077 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1078 struct samr_SamArray *dom_groups = NULL;
1079 uint32_t size = 0xffff;
1080 struct dcerpc_binding_handle *b = cli->binding_handle;
1082 if ((argc < 1) || (argc > 3)) {
1083 printf("Usage: %s [access_mask] [max_size]\n", argv[0]);
1084 return NT_STATUS_OK;
1087 if (argc > 1) {
1088 sscanf(argv[1], "%x", &access_mask);
1091 if (argc > 2) {
1092 sscanf(argv[2], "%x", &size);
1095 /* Get sam policy handle */
1097 status = rpccli_try_samr_connects(cli, mem_ctx,
1098 MAXIMUM_ALLOWED_ACCESS,
1099 &connect_pol);
1100 if (!NT_STATUS_IS_OK(status)) {
1101 goto done;
1104 /* Get domain policy handle */
1106 status = get_domain_handle(cli, mem_ctx, "domain",
1107 &connect_pol,
1108 access_mask,
1109 &domain_sid,
1110 &domain_pol);
1111 if (!NT_STATUS_IS_OK(status)) {
1112 goto done;
1115 /* Enumerate domain groups */
1117 start_idx = 0;
1119 do {
1120 status = dcerpc_samr_EnumDomainGroups(b, mem_ctx,
1121 &domain_pol,
1122 &start_idx,
1123 &dom_groups,
1124 size,
1125 &num_dom_groups,
1126 &result);
1127 if (!NT_STATUS_IS_OK(status)) {
1128 goto done;
1130 if (NT_STATUS_IS_OK(result) ||
1131 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1133 for (i = 0; i < num_dom_groups; i++)
1134 printf("group:[%s] rid:[0x%x]\n",
1135 dom_groups->entries[i].name.string,
1136 dom_groups->entries[i].idx);
1139 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1141 done:
1142 if (is_valid_policy_hnd(&domain_pol))
1143 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1145 if (is_valid_policy_hnd(&connect_pol))
1146 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1148 return status;
1151 /* Enumerate alias groups */
1153 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
1154 TALLOC_CTX *mem_ctx,
1155 int argc, const char **argv)
1157 struct policy_handle connect_pol;
1158 struct policy_handle domain_pol = { 0, };
1159 NTSTATUS status, result;
1160 uint32_t start_idx, num_als_groups, i;
1161 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1162 struct samr_SamArray *als_groups = NULL;
1163 uint32_t size = 0xffff;
1164 struct dcerpc_binding_handle *b = cli->binding_handle;
1166 if ((argc < 2) || (argc > 4)) {
1167 printf("Usage: %s builtin|domain [access mask] [max_size]\n", argv[0]);
1168 return NT_STATUS_OK;
1171 if (argc > 2) {
1172 sscanf(argv[2], "%x", &access_mask);
1175 if (argc > 3) {
1176 sscanf(argv[3], "%x", &size);
1179 /* Get sam policy handle */
1181 status = rpccli_try_samr_connects(cli, mem_ctx,
1182 MAXIMUM_ALLOWED_ACCESS,
1183 &connect_pol);
1184 if (!NT_STATUS_IS_OK(status)) {
1185 goto done;
1188 /* Get domain policy handle */
1190 status = get_domain_handle(cli, mem_ctx, argv[1],
1191 &connect_pol,
1192 access_mask,
1193 &domain_sid,
1194 &domain_pol);
1195 if (!NT_STATUS_IS_OK(status)) {
1196 goto done;
1199 /* Enumerate alias groups */
1201 start_idx = 0;
1203 do {
1204 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
1205 &domain_pol,
1206 &start_idx,
1207 &als_groups,
1208 size,
1209 &num_als_groups,
1210 &result);
1211 if (!NT_STATUS_IS_OK(status)) {
1212 goto done;
1214 if (NT_STATUS_IS_OK(result) ||
1215 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1217 for (i = 0; i < num_als_groups; i++)
1218 printf("group:[%s] rid:[0x%x]\n",
1219 als_groups->entries[i].name.string,
1220 als_groups->entries[i].idx);
1222 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1224 done:
1225 if (is_valid_policy_hnd(&domain_pol))
1226 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1228 if (is_valid_policy_hnd(&connect_pol))
1229 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1231 return status;
1234 /* Enumerate domains */
1236 static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
1237 TALLOC_CTX *mem_ctx,
1238 int argc, const char **argv)
1240 struct policy_handle connect_pol;
1241 NTSTATUS status, result;
1242 uint32_t start_idx, size, num_entries, i;
1243 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1244 struct samr_SamArray *sam = NULL;
1245 struct dcerpc_binding_handle *b = cli->binding_handle;
1247 if ((argc < 1) || (argc > 2)) {
1248 printf("Usage: %s [access mask]\n", argv[0]);
1249 return NT_STATUS_OK;
1252 if (argc > 1) {
1253 sscanf(argv[1], "%x", &access_mask);
1256 /* Get sam policy handle */
1258 status = rpccli_try_samr_connects(cli, mem_ctx,
1259 access_mask,
1260 &connect_pol);
1261 if (!NT_STATUS_IS_OK(status)) {
1262 goto done;
1265 /* Enumerate domains */
1267 start_idx = 0;
1268 size = 0xffff;
1270 do {
1271 status = dcerpc_samr_EnumDomains(b, mem_ctx,
1272 &connect_pol,
1273 &start_idx,
1274 &sam,
1275 size,
1276 &num_entries,
1277 &result);
1278 if (!NT_STATUS_IS_OK(status)) {
1279 goto done;
1281 if (NT_STATUS_IS_OK(result) ||
1282 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1284 for (i = 0; i < num_entries; i++)
1285 printf("name:[%s] idx:[0x%x]\n",
1286 sam->entries[i].name.string,
1287 sam->entries[i].idx);
1289 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1291 done:
1292 if (is_valid_policy_hnd(&connect_pol)) {
1293 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1296 return status;
1300 /* Query alias membership */
1302 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1303 TALLOC_CTX *mem_ctx,
1304 int argc, const char **argv)
1306 struct policy_handle connect_pol, domain_pol, alias_pol;
1307 NTSTATUS status, result;
1308 uint32_t alias_rid, i;
1309 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1310 struct lsa_SidArray sid_array;
1311 struct dcerpc_binding_handle *b = cli->binding_handle;
1313 if ((argc < 3) || (argc > 4)) {
1314 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1315 return NT_STATUS_OK;
1318 sscanf(argv[2], "%i", &alias_rid);
1320 if (argc > 3)
1321 sscanf(argv[3], "%x", &access_mask);
1323 /* Open SAMR handle */
1325 status = rpccli_try_samr_connects(cli, mem_ctx,
1326 MAXIMUM_ALLOWED_ACCESS,
1327 &connect_pol);
1328 if (!NT_STATUS_IS_OK(status)) {
1329 goto done;
1332 /* Open handle on domain */
1334 status = get_domain_handle(cli, mem_ctx, argv[1],
1335 &connect_pol,
1336 MAXIMUM_ALLOWED_ACCESS,
1337 &domain_sid,
1338 &domain_pol);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 goto done;
1343 /* Open handle on alias */
1345 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1346 &domain_pol,
1347 access_mask,
1348 alias_rid,
1349 &alias_pol,
1350 &result);
1351 if (!NT_STATUS_IS_OK(status)) {
1352 goto done;
1354 if (!NT_STATUS_IS_OK(result)) {
1355 status = result;
1356 goto done;
1359 status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
1360 &alias_pol,
1361 &sid_array,
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 for (i = 0; i < sid_array.num_sids; i++) {
1372 struct dom_sid_buf sid_str;
1374 printf("\tsid:[%s]\n",
1375 dom_sid_str_buf(sid_array.sids[i].sid, &sid_str));
1378 dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
1379 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1380 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1381 done:
1382 return status;
1385 /* Query alias info */
1387 static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
1388 TALLOC_CTX *mem_ctx,
1389 int argc, const char **argv)
1391 struct policy_handle connect_pol, domain_pol, alias_pol;
1392 NTSTATUS status, result;
1393 uint32_t alias_rid;
1394 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1395 union samr_AliasInfo *info = NULL;
1396 enum samr_AliasInfoEnum level = ALIASINFOALL;
1397 struct dcerpc_binding_handle *b = cli->binding_handle;
1399 if ((argc < 3) || (argc > 4)) {
1400 printf("Usage: %s builtin|domain rid [level] [access mask]\n",
1401 argv[0]);
1402 return NT_STATUS_OK;
1405 sscanf(argv[2], "%i", &alias_rid);
1407 if (argc > 2) {
1408 level = atoi(argv[3]);
1411 if (argc > 3) {
1412 sscanf(argv[4], "%x", &access_mask);
1415 /* Open SAMR handle */
1417 status = rpccli_try_samr_connects(cli, mem_ctx,
1418 SEC_FLAG_MAXIMUM_ALLOWED,
1419 &connect_pol);
1420 if (!NT_STATUS_IS_OK(status)) {
1421 goto done;
1424 /* Open handle on domain */
1426 status = get_domain_handle(cli, mem_ctx, argv[1],
1427 &connect_pol,
1428 SEC_FLAG_MAXIMUM_ALLOWED,
1429 &domain_sid,
1430 &domain_pol);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 goto done;
1435 /* Open handle on alias */
1437 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1438 &domain_pol,
1439 access_mask,
1440 alias_rid,
1441 &alias_pol,
1442 &result);
1443 if (!NT_STATUS_IS_OK(status)) {
1444 goto done;
1446 if (!NT_STATUS_IS_OK(result)) {
1447 status = result;
1448 goto done;
1451 status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
1452 &alias_pol,
1453 level,
1454 &info,
1455 &result);
1456 if (!NT_STATUS_IS_OK(status)) {
1457 goto done;
1459 if (!NT_STATUS_IS_OK(result)) {
1460 status = result;
1461 goto done;
1464 switch (level) {
1465 case ALIASINFOALL:
1466 printf("Name: %s\n", info->all.name.string);
1467 printf("Description: %s\n", info->all.description.string);
1468 printf("Num Members: %d\n", info->all.num_members);
1469 break;
1470 case ALIASINFONAME:
1471 printf("Name: %s\n", info->name.string);
1472 break;
1473 case ALIASINFODESCRIPTION:
1474 printf("Description: %s\n", info->description.string);
1475 break;
1476 default:
1477 break;
1480 dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
1481 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1482 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1483 done:
1484 return status;
1488 /* Query delete an alias membership */
1490 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1491 TALLOC_CTX *mem_ctx,
1492 int argc, const char **argv)
1494 struct policy_handle connect_pol, domain_pol, alias_pol;
1495 NTSTATUS status, result;
1496 uint32_t alias_rid;
1497 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1498 struct dcerpc_binding_handle *b = cli->binding_handle;
1499 int error = 0;
1501 if (argc != 3) {
1502 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1503 return NT_STATUS_OK;
1506 alias_rid = smb_strtoul(argv[2], NULL, 10, &error, SMB_STR_STANDARD);
1507 if (error != 0) {
1508 return NT_STATUS_INVALID_PARAMETER;
1512 /* Open SAMR handle */
1514 status = rpccli_try_samr_connects(cli, mem_ctx,
1515 MAXIMUM_ALLOWED_ACCESS,
1516 &connect_pol);
1517 if (!NT_STATUS_IS_OK(status)) {
1518 goto done;
1521 /* Open handle on domain */
1523 status = get_domain_handle(cli, mem_ctx, argv[1],
1524 &connect_pol,
1525 MAXIMUM_ALLOWED_ACCESS,
1526 &domain_sid,
1527 &domain_pol);
1528 if (!NT_STATUS_IS_OK(status)) {
1529 goto done;
1532 /* Open handle on alias */
1534 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1535 &domain_pol,
1536 access_mask,
1537 alias_rid,
1538 &alias_pol,
1539 &result);
1540 if (!NT_STATUS_IS_OK(status)) {
1541 goto done;
1543 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1544 /* Probably this was a user name, try lookupnames */
1545 struct samr_Ids rids, types;
1546 struct lsa_String lsa_acct_name;
1548 init_lsa_String(&lsa_acct_name, argv[2]);
1550 status = dcerpc_samr_LookupNames(b, mem_ctx,
1551 &domain_pol,
1553 &lsa_acct_name,
1554 &rids,
1555 &types,
1556 &result);
1557 if (!NT_STATUS_IS_OK(status)) {
1558 goto done;
1560 if (NT_STATUS_IS_OK(result)) {
1561 if (rids.count != 1) {
1562 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1563 goto done;
1565 if (types.count != 1) {
1566 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1567 goto done;
1570 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1571 &domain_pol,
1572 access_mask,
1573 rids.ids[0],
1574 &alias_pol,
1575 &result);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 goto done;
1582 status = dcerpc_samr_DeleteDomAlias(b, mem_ctx,
1583 &alias_pol,
1584 &result);
1585 if (!NT_STATUS_IS_OK(status)) {
1586 goto done;
1588 if (!NT_STATUS_IS_OK(result)) {
1589 status = result;
1590 goto done;
1593 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1594 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1595 done:
1596 return status;
1599 /* Query display info */
1601 static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli,
1602 TALLOC_CTX *mem_ctx,
1603 int argc, const char **argv,
1604 uint32_t opcode)
1606 struct policy_handle connect_pol, domain_pol;
1607 NTSTATUS status, result;
1608 uint32_t start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
1609 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1610 uint32_t info_level = 1;
1611 union samr_DispInfo info;
1612 int loop_count = 0;
1613 bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1614 uint32_t total_size, returned_size;
1615 struct dcerpc_binding_handle *b = cli->binding_handle;
1617 if (argc > 6) {
1618 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1619 return NT_STATUS_OK;
1622 if (argc >= 2)
1623 sscanf(argv[1], "%i", &info_level);
1625 if (argc >= 3)
1626 sscanf(argv[2], "%i", &start_idx);
1628 if (argc >= 4) {
1629 sscanf(argv[3], "%i", &max_entries);
1630 got_params = True;
1633 if (argc >= 5) {
1634 sscanf(argv[4], "%i", &max_size);
1635 got_params = True;
1638 if (argc >= 6)
1639 sscanf(argv[5], "%x", &access_mask);
1641 /* Get sam policy handle */
1643 status = rpccli_try_samr_connects(cli, mem_ctx,
1644 MAXIMUM_ALLOWED_ACCESS,
1645 &connect_pol);
1646 if (!NT_STATUS_IS_OK(status)) {
1647 goto done;
1650 /* Get domain policy handle */
1652 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1653 &connect_pol,
1654 access_mask,
1655 &domain_sid,
1656 &domain_pol,
1657 &result);
1658 if (!NT_STATUS_IS_OK(status)) {
1659 goto done;
1661 if (!NT_STATUS_IS_OK(result)) {
1662 status = result;
1663 goto done;
1666 /* Query display info */
1668 do {
1670 if (!got_params)
1671 dcerpc_get_query_dispinfo_params(
1672 loop_count, &max_entries, &max_size);
1674 switch (opcode) {
1675 case NDR_SAMR_QUERYDISPLAYINFO:
1676 status = dcerpc_samr_QueryDisplayInfo(b, mem_ctx,
1677 &domain_pol,
1678 info_level,
1679 start_idx,
1680 max_entries,
1681 max_size,
1682 &total_size,
1683 &returned_size,
1684 &info,
1685 &result);
1686 break;
1687 case NDR_SAMR_QUERYDISPLAYINFO2:
1688 status = dcerpc_samr_QueryDisplayInfo2(b, mem_ctx,
1689 &domain_pol,
1690 info_level,
1691 start_idx,
1692 max_entries,
1693 max_size,
1694 &total_size,
1695 &returned_size,
1696 &info,
1697 &result);
1699 break;
1700 case NDR_SAMR_QUERYDISPLAYINFO3:
1701 status = dcerpc_samr_QueryDisplayInfo3(b, mem_ctx,
1702 &domain_pol,
1703 info_level,
1704 start_idx,
1705 max_entries,
1706 max_size,
1707 &total_size,
1708 &returned_size,
1709 &info,
1710 &result);
1712 break;
1713 default:
1714 return NT_STATUS_INVALID_PARAMETER;
1717 if (!NT_STATUS_IS_OK(status)) {
1718 break;
1720 status = result;
1721 if (!NT_STATUS_IS_OK(result) &&
1722 !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
1723 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1724 break;
1727 loop_count++;
1729 switch (info_level) {
1730 case 1:
1731 num_entries = info.info1.count;
1732 break;
1733 case 2:
1734 num_entries = info.info2.count;
1735 break;
1736 case 3:
1737 num_entries = info.info3.count;
1738 break;
1739 case 4:
1740 num_entries = info.info4.count;
1741 break;
1742 case 5:
1743 num_entries = info.info5.count;
1744 break;
1745 default:
1746 break;
1749 start_idx += num_entries;
1751 if (num_entries == 0)
1752 break;
1754 for (i = 0; i < num_entries; i++) {
1755 switch (info_level) {
1756 case 1:
1757 display_sam_info_1(&info.info1.entries[i]);
1758 break;
1759 case 2:
1760 display_sam_info_2(&info.info2.entries[i]);
1761 break;
1762 case 3:
1763 display_sam_info_3(&info.info3.entries[i]);
1764 break;
1765 case 4:
1766 display_sam_info_4(&info.info4.entries[i]);
1767 break;
1768 case 5:
1769 display_sam_info_5(&info.info5.entries[i]);
1770 break;
1773 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1775 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1776 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1777 done:
1778 return status;
1781 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1782 TALLOC_CTX *mem_ctx,
1783 int argc, const char **argv)
1785 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1786 NDR_SAMR_QUERYDISPLAYINFO);
1789 static NTSTATUS cmd_samr_query_dispinfo2(struct rpc_pipe_client *cli,
1790 TALLOC_CTX *mem_ctx,
1791 int argc, const char **argv)
1793 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1794 NDR_SAMR_QUERYDISPLAYINFO2);
1797 static NTSTATUS cmd_samr_query_dispinfo3(struct rpc_pipe_client *cli,
1798 TALLOC_CTX *mem_ctx,
1799 int argc, const char **argv)
1801 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1802 NDR_SAMR_QUERYDISPLAYINFO3);
1805 /* Query domain info */
1807 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1808 TALLOC_CTX *mem_ctx,
1809 int argc, const char **argv)
1811 struct policy_handle connect_pol, domain_pol;
1812 NTSTATUS status, result;
1813 uint32_t switch_level = 2;
1814 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1815 union samr_DomainInfo *info = NULL;
1816 struct dcerpc_binding_handle *b = cli->binding_handle;
1818 if (argc > 3) {
1819 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1820 return NT_STATUS_OK;
1823 if (argc > 1)
1824 sscanf(argv[1], "%i", &switch_level);
1826 if (argc > 2)
1827 sscanf(argv[2], "%x", &access_mask);
1829 /* Get sam policy handle */
1831 status = rpccli_try_samr_connects(cli, mem_ctx,
1832 MAXIMUM_ALLOWED_ACCESS,
1833 &connect_pol);
1834 if (!NT_STATUS_IS_OK(status)) {
1835 goto done;
1838 /* Get domain policy handle */
1840 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1841 &connect_pol,
1842 access_mask,
1843 &domain_sid,
1844 &domain_pol,
1845 &result);
1846 if (!NT_STATUS_IS_OK(status)) {
1847 goto done;
1849 if (!NT_STATUS_IS_OK(result)) {
1850 status = result;
1851 goto done;
1854 /* Query domain info */
1856 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
1857 &domain_pol,
1858 switch_level,
1859 &info,
1860 &result);
1861 if (!NT_STATUS_IS_OK(status)) {
1862 goto done;
1864 if (!NT_STATUS_IS_OK(result)) {
1865 status = result;
1866 goto done;
1869 /* Display domain info */
1871 switch (switch_level) {
1872 case 1:
1873 display_sam_dom_info_1(&info->info1);
1874 break;
1875 case 2:
1876 display_sam_dom_info_2(&info->general);
1877 break;
1878 case 3:
1879 display_sam_dom_info_3(&info->info3);
1880 break;
1881 case 4:
1882 display_sam_dom_info_4(&info->oem);
1883 break;
1884 case 5:
1885 display_sam_dom_info_5(&info->info5);
1886 break;
1887 case 6:
1888 display_sam_dom_info_6(&info->info6);
1889 break;
1890 case 7:
1891 display_sam_dom_info_7(&info->info7);
1892 break;
1893 case 8:
1894 display_sam_dom_info_8(&info->info8);
1895 break;
1896 case 9:
1897 display_sam_dom_info_9(&info->info9);
1898 break;
1899 case 12:
1900 display_sam_dom_info_12(&info->info12);
1901 break;
1902 case 13:
1903 display_sam_dom_info_13(&info->info13);
1904 break;
1906 default:
1907 printf("cannot display domain info for switch value %d\n",
1908 switch_level);
1909 break;
1912 done:
1914 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1915 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1916 return status;
1919 /* Create domain user */
1921 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1922 TALLOC_CTX *mem_ctx,
1923 int argc, const char **argv)
1925 struct policy_handle connect_pol, domain_pol, user_pol;
1926 NTSTATUS status, result;
1927 struct lsa_String acct_name;
1928 uint32_t acb_info;
1929 uint32_t acct_flags, user_rid;
1930 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1931 uint32_t access_granted = 0;
1932 struct dcerpc_binding_handle *b = cli->binding_handle;
1934 if ((argc < 2) || (argc > 3)) {
1935 printf("Usage: %s username [access mask]\n", argv[0]);
1936 return NT_STATUS_OK;
1939 init_lsa_String(&acct_name, argv[1]);
1941 if (argc > 2)
1942 sscanf(argv[2], "%x", &access_mask);
1944 /* Get sam policy handle */
1946 status = rpccli_try_samr_connects(cli, mem_ctx,
1947 MAXIMUM_ALLOWED_ACCESS,
1948 &connect_pol);
1949 if (!NT_STATUS_IS_OK(status)) {
1950 goto done;
1953 /* Get domain policy handle */
1955 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1956 &connect_pol,
1957 access_mask,
1958 &domain_sid,
1959 &domain_pol,
1960 &result);
1961 if (!NT_STATUS_IS_OK(status)) {
1962 goto done;
1964 if (!NT_STATUS_IS_OK(result)) {
1965 status = result;
1966 goto done;
1969 /* Create domain user */
1971 acb_info = ACB_NORMAL;
1972 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1973 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1974 SAMR_USER_ACCESS_SET_PASSWORD |
1975 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1976 SAMR_USER_ACCESS_SET_ATTRIBUTES;
1978 status = dcerpc_samr_CreateUser2(b, mem_ctx,
1979 &domain_pol,
1980 &acct_name,
1981 acb_info,
1982 acct_flags,
1983 &user_pol,
1984 &access_granted,
1985 &user_rid,
1986 &result);
1987 if (!NT_STATUS_IS_OK(status)) {
1988 goto done;
1990 if (!NT_STATUS_IS_OK(result)) {
1991 status = result;
1992 goto done;
1995 status = dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1996 if (!NT_STATUS_IS_OK(status)) goto done;
1998 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1999 if (!NT_STATUS_IS_OK(status)) goto done;
2001 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2002 if (!NT_STATUS_IS_OK(status)) goto done;
2004 done:
2005 return status;
2008 /* Create domain group */
2010 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
2011 TALLOC_CTX *mem_ctx,
2012 int argc, const char **argv)
2014 struct policy_handle connect_pol, domain_pol, group_pol;
2015 NTSTATUS status, result;
2016 struct lsa_String grp_name;
2017 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2018 uint32_t rid = 0;
2019 struct dcerpc_binding_handle *b = cli->binding_handle;
2021 if ((argc < 2) || (argc > 3)) {
2022 printf("Usage: %s groupname [access mask]\n", argv[0]);
2023 return NT_STATUS_OK;
2026 init_lsa_String(&grp_name, argv[1]);
2028 if (argc > 2)
2029 sscanf(argv[2], "%x", &access_mask);
2031 /* Get sam policy handle */
2033 status = rpccli_try_samr_connects(cli, mem_ctx,
2034 MAXIMUM_ALLOWED_ACCESS,
2035 &connect_pol);
2036 if (!NT_STATUS_IS_OK(status)) {
2037 goto done;
2040 /* Get domain policy handle */
2042 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2043 &connect_pol,
2044 access_mask,
2045 &domain_sid,
2046 &domain_pol,
2047 &result);
2048 if (!NT_STATUS_IS_OK(status)) {
2049 goto done;
2051 if (!NT_STATUS_IS_OK(result)) {
2052 status = result;
2053 goto done;
2056 /* Create domain user */
2057 status = dcerpc_samr_CreateDomainGroup(b, mem_ctx,
2058 &domain_pol,
2059 &grp_name,
2060 MAXIMUM_ALLOWED_ACCESS,
2061 &group_pol,
2062 &rid,
2063 &result);
2064 if (!NT_STATUS_IS_OK(status)) {
2065 goto done;
2067 if (!NT_STATUS_IS_OK(result)) {
2068 status = result;
2069 goto done;
2072 status = dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
2073 if (!NT_STATUS_IS_OK(status)) goto done;
2075 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2076 if (!NT_STATUS_IS_OK(status)) goto done;
2078 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2079 if (!NT_STATUS_IS_OK(status)) goto done;
2081 done:
2082 return status;
2085 /* Create domain alias */
2087 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
2088 TALLOC_CTX *mem_ctx,
2089 int argc, const char **argv)
2091 struct policy_handle connect_pol, domain_pol, alias_pol;
2092 NTSTATUS status, result;
2093 struct lsa_String alias_name;
2094 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2095 uint32_t rid = 0;
2096 struct dcerpc_binding_handle *b = cli->binding_handle;
2098 if ((argc < 2) || (argc > 3)) {
2099 printf("Usage: %s aliasname [access mask]\n", argv[0]);
2100 return NT_STATUS_OK;
2103 init_lsa_String(&alias_name, argv[1]);
2105 if (argc > 2)
2106 sscanf(argv[2], "%x", &access_mask);
2108 /* Get sam policy handle */
2110 status = rpccli_try_samr_connects(cli, mem_ctx,
2111 MAXIMUM_ALLOWED_ACCESS,
2112 &connect_pol);
2113 if (!NT_STATUS_IS_OK(status)) {
2114 goto done;
2117 /* Get domain policy handle */
2119 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2120 &connect_pol,
2121 access_mask,
2122 &domain_sid,
2123 &domain_pol,
2124 &result);
2125 if (!NT_STATUS_IS_OK(status)) {
2126 goto done;
2128 if (!NT_STATUS_IS_OK(result)) {
2129 status = result;
2130 goto done;
2133 /* Create domain user */
2135 status = dcerpc_samr_CreateDomAlias(b, mem_ctx,
2136 &domain_pol,
2137 &alias_name,
2138 MAXIMUM_ALLOWED_ACCESS,
2139 &alias_pol,
2140 &rid,
2141 &result);
2142 if (!NT_STATUS_IS_OK(status)) {
2143 goto done;
2145 if (!NT_STATUS_IS_OK(result)) {
2146 status = result;
2147 goto done;
2151 status = dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
2152 if (!NT_STATUS_IS_OK(status)) goto done;
2154 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2155 if (!NT_STATUS_IS_OK(status)) goto done;
2157 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2158 if (!NT_STATUS_IS_OK(status)) goto done;
2160 done:
2161 return status;
2164 /* Lookup sam names */
2166 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
2167 TALLOC_CTX *mem_ctx,
2168 int argc, const char **argv)
2170 NTSTATUS status, result;
2171 struct policy_handle connect_pol, domain_pol;
2172 uint32_t num_names;
2173 struct samr_Ids rids, name_types;
2174 int i;
2175 struct lsa_String *names = NULL;
2176 struct dcerpc_binding_handle *b = cli->binding_handle;
2178 if (argc < 3) {
2179 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
2180 printf("check on the domain SID: S-1-5-21-x-y-z\n");
2181 printf("or check on the builtin SID: S-1-5-32\n");
2182 return NT_STATUS_OK;
2185 /* Get sam policy and domain handles */
2187 status = rpccli_try_samr_connects(cli, mem_ctx,
2188 MAXIMUM_ALLOWED_ACCESS,
2189 &connect_pol);
2190 if (!NT_STATUS_IS_OK(status)) {
2191 goto done;
2194 status = get_domain_handle(cli, mem_ctx, argv[1],
2195 &connect_pol,
2196 MAXIMUM_ALLOWED_ACCESS,
2197 &domain_sid,
2198 &domain_pol);
2199 if (!NT_STATUS_IS_OK(status)) {
2200 goto done;
2203 /* Look up names */
2205 num_names = argc - 2;
2207 if ((names = talloc_array(mem_ctx, struct lsa_String, num_names)) == NULL) {
2208 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2209 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2210 status = NT_STATUS_NO_MEMORY;
2211 goto done;
2214 for (i = 0; i < num_names; i++) {
2215 init_lsa_String(&names[i], argv[i + 2]);
2218 status = dcerpc_samr_LookupNames(b, mem_ctx,
2219 &domain_pol,
2220 num_names,
2221 names,
2222 &rids,
2223 &name_types,
2224 &result);
2225 if (!NT_STATUS_IS_OK(status)) {
2226 goto done;
2228 if (!NT_STATUS_IS_OK(result)) {
2229 status = result;
2230 goto done;
2232 if (rids.count != num_names) {
2233 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2234 goto done;
2236 if (name_types.count != num_names) {
2237 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2238 goto done;
2241 /* Display results */
2243 for (i = 0; i < num_names; i++)
2244 printf("name %s: 0x%x (%d)\n", names[i].string, rids.ids[i],
2245 name_types.ids[i]);
2247 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2248 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2249 done:
2250 return status;
2253 /* Lookup sam rids */
2255 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
2256 TALLOC_CTX *mem_ctx,
2257 int argc, const char **argv)
2259 NTSTATUS status, result;
2260 struct policy_handle connect_pol, domain_pol;
2261 uint32_t num_rids, *rids;
2262 struct lsa_Strings names;
2263 struct samr_Ids types;
2264 struct dcerpc_binding_handle *b = cli->binding_handle;
2266 int i;
2268 if (argc < 3) {
2269 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
2270 return NT_STATUS_OK;
2273 /* Get sam policy and domain handles */
2275 status = rpccli_try_samr_connects(cli, mem_ctx,
2276 MAXIMUM_ALLOWED_ACCESS,
2277 &connect_pol);
2278 if (!NT_STATUS_IS_OK(status)) {
2279 goto done;
2282 status = get_domain_handle(cli, mem_ctx, argv[1],
2283 &connect_pol,
2284 MAXIMUM_ALLOWED_ACCESS,
2285 &domain_sid,
2286 &domain_pol);
2287 if (!NT_STATUS_IS_OK(status)) {
2288 goto done;
2291 /* Look up rids */
2293 num_rids = argc - 2;
2295 if ((rids = talloc_array(mem_ctx, uint32_t, num_rids)) == NULL) {
2296 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2297 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2298 status = NT_STATUS_NO_MEMORY;
2299 goto done;
2302 for (i = 0; i < argc - 2; i++)
2303 sscanf(argv[i + 2], "%i", &rids[i]);
2305 status = dcerpc_samr_LookupRids(b, mem_ctx,
2306 &domain_pol,
2307 num_rids,
2308 rids,
2309 &names,
2310 &types,
2311 &result);
2312 if (!NT_STATUS_IS_OK(status)) {
2313 goto done;
2315 status = result;
2316 if (!NT_STATUS_IS_OK(result) &&
2317 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
2318 goto done;
2320 /* Display results */
2321 if (num_rids != names.count) {
2322 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2323 goto done;
2325 if (num_rids != types.count) {
2326 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2327 goto done;
2330 for (i = 0; i < num_rids; i++) {
2331 printf("rid 0x%x: %s (%d)\n",
2332 rids[i], names.names[i].string, types.ids[i]);
2335 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2336 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2337 done:
2338 return status;
2341 /* Delete domain group */
2343 static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
2344 TALLOC_CTX *mem_ctx,
2345 int argc, const char **argv)
2347 NTSTATUS status, result;
2348 struct policy_handle connect_pol, domain_pol, group_pol;
2349 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2350 struct dcerpc_binding_handle *b = cli->binding_handle;
2352 if ((argc < 2) || (argc > 3)) {
2353 printf("Usage: %s groupname\n", argv[0]);
2354 return NT_STATUS_OK;
2357 if (argc > 2)
2358 sscanf(argv[2], "%x", &access_mask);
2360 /* Get sam policy and domain handles */
2362 status = rpccli_try_samr_connects(cli, mem_ctx,
2363 MAXIMUM_ALLOWED_ACCESS,
2364 &connect_pol);
2365 if (!NT_STATUS_IS_OK(status)) {
2366 goto done;
2369 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2370 &connect_pol,
2371 MAXIMUM_ALLOWED_ACCESS,
2372 &domain_sid,
2373 &domain_pol,
2374 &result);
2375 if (!NT_STATUS_IS_OK(status)) {
2376 goto done;
2378 if (!NT_STATUS_IS_OK(result)) {
2379 status = result;
2380 goto done;
2383 /* Get handle on group */
2386 struct samr_Ids group_rids, name_types;
2387 struct lsa_String lsa_acct_name;
2389 init_lsa_String(&lsa_acct_name, argv[1]);
2391 status = dcerpc_samr_LookupNames(b, mem_ctx,
2392 &domain_pol,
2394 &lsa_acct_name,
2395 &group_rids,
2396 &name_types,
2397 &result);
2398 if (!NT_STATUS_IS_OK(status)) {
2399 goto done;
2401 if (!NT_STATUS_IS_OK(result)) {
2402 status = result;
2403 goto done;
2405 if (group_rids.count != 1) {
2406 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2407 goto done;
2409 if (name_types.count != 1) {
2410 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2411 goto done;
2414 status = dcerpc_samr_OpenGroup(b, mem_ctx,
2415 &domain_pol,
2416 access_mask,
2417 group_rids.ids[0],
2418 &group_pol,
2419 &result);
2420 if (!NT_STATUS_IS_OK(status)) {
2421 goto done;
2423 if (!NT_STATUS_IS_OK(result)) {
2424 status = result;
2425 goto done;
2429 /* Delete group */
2431 status = dcerpc_samr_DeleteDomainGroup(b, mem_ctx,
2432 &group_pol,
2433 &result);
2434 if (!NT_STATUS_IS_OK(status)) {
2435 goto done;
2437 if (!NT_STATUS_IS_OK(result)) {
2438 status = result;
2439 goto done;
2442 /* Display results */
2444 dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
2445 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2446 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2448 done:
2449 return status;
2452 /* Delete domain user */
2454 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
2455 TALLOC_CTX *mem_ctx,
2456 int argc, const char **argv)
2458 NTSTATUS status, result;
2459 struct policy_handle connect_pol, domain_pol, user_pol;
2460 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2461 struct dcerpc_binding_handle *b = cli->binding_handle;
2463 if ((argc < 2) || (argc > 3)) {
2464 printf("Usage: %s username\n", argv[0]);
2465 return NT_STATUS_OK;
2468 if (argc > 2)
2469 sscanf(argv[2], "%x", &access_mask);
2471 /* Get sam policy and domain handles */
2473 status = rpccli_try_samr_connects(cli, mem_ctx,
2474 MAXIMUM_ALLOWED_ACCESS,
2475 &connect_pol);
2476 if (!NT_STATUS_IS_OK(status)) {
2477 goto done;
2480 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2481 &connect_pol,
2482 MAXIMUM_ALLOWED_ACCESS,
2483 &domain_sid,
2484 &domain_pol,
2485 &result);
2486 if (!NT_STATUS_IS_OK(status)) {
2487 goto done;
2489 if (!NT_STATUS_IS_OK(result)) {
2490 status = result;
2491 goto done;
2494 /* Get handle on user */
2497 struct samr_Ids user_rids, name_types;
2498 struct lsa_String lsa_acct_name;
2500 init_lsa_String(&lsa_acct_name, argv[1]);
2502 status = dcerpc_samr_LookupNames(b, mem_ctx,
2503 &domain_pol,
2505 &lsa_acct_name,
2506 &user_rids,
2507 &name_types,
2508 &result);
2509 if (!NT_STATUS_IS_OK(status)) {
2510 goto done;
2512 if (!NT_STATUS_IS_OK(result)) {
2513 status = result;
2514 goto done;
2516 if (user_rids.count != 1) {
2517 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2518 goto done;
2520 if (name_types.count != 1) {
2521 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2522 goto done;
2525 status = dcerpc_samr_OpenUser(b, mem_ctx,
2526 &domain_pol,
2527 access_mask,
2528 user_rids.ids[0],
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 /* Delete user */
2542 status = dcerpc_samr_DeleteUser(b, mem_ctx,
2543 &user_pol,
2544 &result);
2545 if (!NT_STATUS_IS_OK(status)) {
2546 goto done;
2548 if (!NT_STATUS_IS_OK(result)) {
2549 status = result;
2550 goto done;
2553 /* Display results */
2555 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2556 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2557 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2559 done:
2560 return status;
2563 /**********************************************************************
2564 * Query user security object
2566 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
2567 TALLOC_CTX *mem_ctx,
2568 int argc, const char **argv)
2570 struct policy_handle connect_pol, domain_pol, user_pol, *pol;
2571 NTSTATUS status, result;
2572 uint32_t sec_info = SECINFO_DACL;
2573 uint32_t user_rid = 0;
2574 TALLOC_CTX *ctx = NULL;
2575 struct sec_desc_buf *sec_desc_buf=NULL;
2576 bool domain = False;
2577 struct dcerpc_binding_handle *b = cli->binding_handle;
2579 ctx=talloc_init("cmd_samr_query_sec_obj");
2581 if ((argc < 1) || (argc > 3)) {
2582 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2583 printf("\tSpecify rid for security on user, -d for security on domain\n");
2584 talloc_destroy(ctx);
2585 return NT_STATUS_OK;
2588 if (argc > 1) {
2589 if (strcmp(argv[1], "-d") == 0)
2590 domain = True;
2591 else
2592 sscanf(argv[1], "%i", &user_rid);
2595 if (argc == 3) {
2596 sec_info = atoi(argv[2]);
2599 status = rpccli_try_samr_connects(cli, mem_ctx,
2600 MAXIMUM_ALLOWED_ACCESS,
2601 &connect_pol);
2602 if (!NT_STATUS_IS_OK(status)) {
2603 goto done;
2606 if (domain || user_rid) {
2607 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2608 &connect_pol,
2609 MAXIMUM_ALLOWED_ACCESS,
2610 &domain_sid,
2611 &domain_pol,
2612 &result);
2613 if (!NT_STATUS_IS_OK(status)) {
2614 goto done;
2616 if (!NT_STATUS_IS_OK(result)) {
2617 status = result;
2618 goto done;
2622 if (user_rid) {
2623 status = dcerpc_samr_OpenUser(b, mem_ctx,
2624 &domain_pol,
2625 MAXIMUM_ALLOWED_ACCESS,
2626 user_rid,
2627 &user_pol,
2628 &result);
2629 if (!NT_STATUS_IS_OK(status)) {
2630 goto done;
2632 if (!NT_STATUS_IS_OK(result)) {
2633 status = result;
2634 goto done;
2638 /* Pick which query pol to use */
2640 pol = &connect_pol;
2642 if (domain)
2643 pol = &domain_pol;
2645 if (user_rid)
2646 pol = &user_pol;
2648 /* Query SAM security object */
2650 status = dcerpc_samr_QuerySecurity(b, mem_ctx,
2651 pol,
2652 sec_info,
2653 &sec_desc_buf,
2654 &result);
2655 if (!NT_STATUS_IS_OK(status)) {
2656 goto done;
2658 if (!NT_STATUS_IS_OK(result)) {
2659 status = result;
2660 goto done;
2663 display_sec_desc(sec_desc_buf->sd);
2665 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2666 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2667 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2668 done:
2669 talloc_destroy(ctx);
2670 return status;
2673 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
2674 TALLOC_CTX *mem_ctx,
2675 int argc, const char **argv)
2677 NTSTATUS status, result;
2678 struct policy_handle connect_pol, domain_pol, user_pol;
2679 struct samr_PwInfo info;
2680 uint32_t rid;
2681 struct dcerpc_binding_handle *b = cli->binding_handle;
2683 if (argc != 2) {
2684 printf("Usage: %s rid\n", argv[0]);
2685 return NT_STATUS_OK;
2688 sscanf(argv[1], "%i", &rid);
2690 status = rpccli_try_samr_connects(cli, mem_ctx,
2691 MAXIMUM_ALLOWED_ACCESS,
2692 &connect_pol);
2693 if (!NT_STATUS_IS_OK(status)) {
2694 goto done;
2697 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2698 &connect_pol,
2699 MAXIMUM_ALLOWED_ACCESS,
2700 &domain_sid,
2701 &domain_pol,
2702 &result);
2703 if (!NT_STATUS_IS_OK(status)) {
2704 goto done;
2706 if (!NT_STATUS_IS_OK(result)) {
2707 status = result;
2708 goto done;
2711 status = dcerpc_samr_OpenUser(b, mem_ctx,
2712 &domain_pol,
2713 MAXIMUM_ALLOWED_ACCESS,
2714 rid,
2715 &user_pol,
2716 &result);
2717 if (!NT_STATUS_IS_OK(status)) {
2718 goto done;
2720 if (!NT_STATUS_IS_OK(result)) {
2721 status = result;
2722 goto done;
2725 status = dcerpc_samr_GetUserPwInfo(b, mem_ctx,
2726 &user_pol,
2727 &info,
2728 &result);
2729 if (!NT_STATUS_IS_OK(status)) {
2730 goto done;
2732 status = result;
2733 if (NT_STATUS_IS_OK(result)) {
2734 printf("%s\n",
2735 NDR_PRINT_STRUCT_STRING(mem_ctx,
2736 samr_PwInfo, &info));
2739 done:
2740 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2741 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2742 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2744 return status;
2747 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2748 TALLOC_CTX *mem_ctx,
2749 int argc, const char **argv)
2751 NTSTATUS status, result;
2752 struct lsa_String domain_name;
2753 struct samr_PwInfo info;
2754 struct dcerpc_binding_handle *b = cli->binding_handle;
2756 if (argc < 1 || argc > 3) {
2757 printf("Usage: %s <domain>\n", argv[0]);
2758 return NT_STATUS_OK;
2761 init_lsa_String(&domain_name, argv[1]);
2763 status = dcerpc_samr_GetDomPwInfo(b, mem_ctx,
2764 &domain_name,
2765 &info,
2766 &result);
2767 if (!NT_STATUS_IS_OK(status)) {
2768 return status;
2770 if (NT_STATUS_IS_OK(result)) {
2771 printf("min_password_length: %d\n", info.min_password_length);
2772 display_password_properties(info.password_properties);
2775 return result;
2778 /* Look up domain name */
2780 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
2781 TALLOC_CTX *mem_ctx,
2782 int argc, const char **argv)
2784 struct policy_handle connect_pol, domain_pol;
2785 NTSTATUS status, result;
2786 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2787 struct lsa_String domain_name;
2788 struct dom_sid *sid = NULL;
2789 struct dcerpc_binding_handle *b = cli->binding_handle;
2791 if (argc != 2) {
2792 printf("Usage: %s domain_name\n", argv[0]);
2793 return NT_STATUS_OK;
2796 init_lsa_String(&domain_name, argv[1]);
2798 status = rpccli_try_samr_connects(cli, mem_ctx,
2799 access_mask,
2800 &connect_pol);
2801 if (!NT_STATUS_IS_OK(status)) {
2802 goto done;
2805 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2806 &connect_pol,
2807 access_mask,
2808 &domain_sid,
2809 &domain_pol,
2810 &result);
2811 if (!NT_STATUS_IS_OK(status)) {
2812 goto done;
2814 if (!NT_STATUS_IS_OK(result)) {
2815 status = result;
2816 goto done;
2819 status = dcerpc_samr_LookupDomain(b, mem_ctx,
2820 &connect_pol,
2821 &domain_name,
2822 &sid,
2823 &result);
2824 if (!NT_STATUS_IS_OK(status)) {
2825 goto done;
2827 if (!NT_STATUS_IS_OK(result)) {
2828 status = result;
2829 goto done;
2832 if (NT_STATUS_IS_OK(result)) {
2833 struct dom_sid_buf sid_str;
2834 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2835 argv[1],
2836 dom_sid_str_buf(sid, &sid_str));
2839 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2840 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2841 done:
2842 return status;
2845 /* Change user password */
2847 static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli,
2848 TALLOC_CTX *mem_ctx,
2849 int argc, const char **argv)
2851 struct policy_handle connect_pol;
2852 struct policy_handle domain_pol = { 0, };
2853 struct policy_handle user_pol = { 0, };
2854 NTSTATUS status, result;
2855 const char *user, *oldpass, *newpass;
2856 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2857 struct samr_Ids rids, types;
2858 struct lsa_String lsa_acct_name;
2859 struct dcerpc_binding_handle *b = cli->binding_handle;
2861 if (argc < 3) {
2862 printf("Usage: %s username oldpass newpass\n", argv[0]);
2863 return NT_STATUS_INVALID_PARAMETER;
2866 user = argv[1];
2867 oldpass = argv[2];
2868 newpass = argv[3];
2870 /* Get sam policy handle */
2872 status = rpccli_try_samr_connects(cli, mem_ctx,
2873 MAXIMUM_ALLOWED_ACCESS,
2874 &connect_pol);
2875 if (!NT_STATUS_IS_OK(status)) {
2876 goto done;
2879 /* Get domain policy handle */
2881 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2882 &connect_pol,
2883 access_mask,
2884 &domain_sid,
2885 &domain_pol,
2886 &result);
2887 if (!NT_STATUS_IS_OK(status)) {
2888 goto done;
2890 if (!NT_STATUS_IS_OK(result)) {
2891 status = result;
2892 goto done;
2895 init_lsa_String(&lsa_acct_name, user);
2897 status = dcerpc_samr_LookupNames(b, mem_ctx,
2898 &domain_pol,
2900 &lsa_acct_name,
2901 &rids,
2902 &types,
2903 &result);
2904 if (!NT_STATUS_IS_OK(status)) {
2905 goto done;
2907 if (!NT_STATUS_IS_OK(result)) {
2908 status = result;
2909 goto done;
2911 if (rids.count != 1) {
2912 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2913 goto done;
2915 if (types.count != 1) {
2916 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2917 goto done;
2920 status = dcerpc_samr_OpenUser(b, mem_ctx,
2921 &domain_pol,
2922 access_mask,
2923 rids.ids[0],
2924 &user_pol,
2925 &result);
2926 if (!NT_STATUS_IS_OK(status)) {
2927 goto done;
2929 if (!NT_STATUS_IS_OK(result)) {
2930 status = result;
2931 goto done;
2934 /* Change user password */
2935 status = rpccli_samr_chgpasswd_user(cli, mem_ctx,
2936 &user_pol,
2937 newpass,
2938 oldpass);
2939 if (!NT_STATUS_IS_OK(status)) {
2940 goto done;
2943 done:
2944 if (is_valid_policy_hnd(&user_pol)) {
2945 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2947 if (is_valid_policy_hnd(&domain_pol)) {
2948 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2950 if (is_valid_policy_hnd(&connect_pol)) {
2951 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2954 return status;
2958 /* Change user password */
2960 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2961 TALLOC_CTX *mem_ctx,
2962 int argc, const char **argv)
2964 struct policy_handle connect_pol, domain_pol;
2965 NTSTATUS status, result;
2966 const char *user, *oldpass, *newpass;
2967 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2968 struct dcerpc_binding_handle *b = cli->binding_handle;
2970 if (argc < 3) {
2971 printf("Usage: %s username oldpass newpass\n", argv[0]);
2972 return NT_STATUS_INVALID_PARAMETER;
2975 user = argv[1];
2976 oldpass = argv[2];
2977 newpass = argv[3];
2979 /* Get sam policy handle */
2981 status = rpccli_try_samr_connects(cli, mem_ctx,
2982 MAXIMUM_ALLOWED_ACCESS,
2983 &connect_pol);
2984 if (!NT_STATUS_IS_OK(status)) {
2985 goto done;
2988 /* Get domain policy handle */
2990 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2991 &connect_pol,
2992 access_mask,
2993 &domain_sid,
2994 &domain_pol,
2995 &result);
2996 if (!NT_STATUS_IS_OK(status)) {
2997 goto done;
2999 if (!NT_STATUS_IS_OK(result)) {
3000 status = result;
3001 goto done;
3004 /* Change user password */
3005 status = rpccli_samr_chgpasswd_user2(cli, mem_ctx, user, newpass, oldpass);
3007 if (!NT_STATUS_IS_OK(status)) {
3008 goto done;
3011 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
3012 if (!NT_STATUS_IS_OK(status)) goto done;
3014 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
3015 if (!NT_STATUS_IS_OK(status)) goto done;
3017 done:
3018 return status;
3022 /* Change user password */
3024 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
3025 TALLOC_CTX *mem_ctx,
3026 int argc, const char **argv)
3028 struct policy_handle connect_pol, domain_pol;
3029 NTSTATUS status, result;
3030 const char *user, *oldpass, *newpass;
3031 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
3032 struct samr_DomInfo1 *info = NULL;
3033 struct userPwdChangeFailureInformation *reject = NULL;
3034 struct dcerpc_binding_handle *b = cli->binding_handle;
3036 if (argc < 4) {
3037 printf("Usage: %s username oldpass newpass\n", argv[0]);
3038 return NT_STATUS_INVALID_PARAMETER;
3041 user = argv[1];
3042 oldpass = argv[2];
3043 newpass = argv[3];
3045 /* Get sam policy handle */
3047 status = rpccli_try_samr_connects(cli, mem_ctx,
3048 MAXIMUM_ALLOWED_ACCESS,
3049 &connect_pol);
3050 if (!NT_STATUS_IS_OK(status)) {
3051 goto done;
3054 /* Get domain policy handle */
3056 status = dcerpc_samr_OpenDomain(b, mem_ctx,
3057 &connect_pol,
3058 access_mask,
3059 &domain_sid,
3060 &domain_pol,
3061 &result);
3062 if (!NT_STATUS_IS_OK(status)) {
3063 goto done;
3065 if (!NT_STATUS_IS_OK(result)) {
3066 status = result;
3067 goto done;
3070 /* Change user password */
3071 status = rpccli_samr_chgpasswd_user3(cli, mem_ctx,
3072 user,
3073 newpass,
3074 oldpass,
3075 &info,
3076 &reject);
3077 if (!NT_STATUS_IS_OK(status)) {
3078 goto done;
3081 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
3083 display_sam_dom_info_1(info);
3085 switch (reject->extendedFailureReason) {
3086 case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT:
3087 d_printf("SAM_PWD_CHANGE_PASSWORD_TOO_SHORT\n");
3088 break;
3089 case SAM_PWD_CHANGE_PWD_IN_HISTORY:
3090 d_printf("SAM_PWD_CHANGE_PWD_IN_HISTORY\n");
3091 break;
3092 case SAM_PWD_CHANGE_NOT_COMPLEX:
3093 d_printf("SAM_PWD_CHANGE_NOT_COMPLEX\n");
3094 break;
3095 default:
3096 d_printf("unknown reject reason: %d\n",
3097 reject->extendedFailureReason);
3098 break;
3102 if (!NT_STATUS_IS_OK(result)) {
3103 status = result;
3104 goto done;
3107 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
3108 if (!NT_STATUS_IS_OK(status)) goto done;
3110 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
3111 if (!NT_STATUS_IS_OK(status)) goto done;
3113 done:
3114 return status;
3117 static NTSTATUS cmd_samr_chgpasswd4(struct rpc_pipe_client *cli,
3118 TALLOC_CTX *mem_ctx,
3119 int argc,
3120 const char **argv)
3122 struct dcerpc_binding_handle *b = cli->binding_handle;
3123 const char *srv_name_slash = cli->srv_name_slash;
3124 const char *user = NULL;
3125 const char *oldpass = NULL;
3126 const char *newpass = NULL;
3127 NTSTATUS status;
3128 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
3130 if (argc < 4) {
3131 printf("Usage: %s username oldpass newpass\n", argv[0]);
3132 return NT_STATUS_INVALID_PARAMETER;
3135 user = argv[1];
3136 oldpass = argv[2];
3137 newpass = argv[3];
3139 /* Change user password */
3140 status = dcerpc_samr_chgpasswd_user4(b,
3141 mem_ctx,
3142 srv_name_slash,
3143 user,
3144 oldpass,
3145 newpass,
3146 &result);
3147 if (!NT_STATUS_IS_OK(status)) {
3148 return status;
3150 if (!NT_STATUS_IS_OK(result)) {
3151 status = result;
3154 return status;
3157 static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli,
3158 TALLOC_CTX *mem_ctx,
3159 int argc, const char **argv,
3160 int opcode)
3162 struct policy_handle connect_pol, domain_pol, user_pol;
3163 NTSTATUS status, result;
3164 const char *user, *param;
3165 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
3166 uint32_t level;
3167 uint32_t user_rid;
3168 union samr_UserInfo info;
3169 struct samr_CryptPassword pwd_buf;
3170 struct samr_CryptPasswordEx pwd_buf_ex;
3171 struct samr_EncryptedPasswordAES pwd_buf_aes;
3172 uint8_t nt_hash[16];
3173 uint8_t lm_hash[16];
3174 DATA_BLOB session_key;
3175 uint8_t salt_data[16];
3176 DATA_BLOB salt = {
3177 .data = salt_data,
3178 .length = sizeof(salt_data),
3180 uint8_t password_expired = 0;
3181 struct dcerpc_binding_handle *b = cli->binding_handle;
3182 TALLOC_CTX *frame = NULL;
3183 int rc;
3185 if (argc < 4) {
3186 printf("Usage: %s username level password [password_expired]\n",
3187 argv[0]);
3188 return NT_STATUS_INVALID_PARAMETER;
3191 frame = talloc_stackframe();
3193 user = argv[1];
3194 level = atoi(argv[2]);
3195 param = argv[3];
3197 if (argc >= 5) {
3198 password_expired = atoi(argv[4]);
3201 status = cli_get_session_key(frame, cli, &session_key);
3202 if (!NT_STATUS_IS_OK(status)) {
3203 goto done;
3206 generate_nonce_buffer(salt.data, salt.length);
3208 switch(level) {
3209 case 18:
3210 case 21:
3211 nt_lm_owf_gen(param, nt_hash, lm_hash);
3212 break;
3213 case 23:
3214 case 24:
3215 status = init_samr_CryptPassword(param, &session_key, &pwd_buf);
3216 if (!NT_STATUS_IS_OK(status)) {
3217 goto done;
3219 break;
3220 case 25:
3221 case 26:
3222 status = init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex);
3223 if (!NT_STATUS_IS_OK(status)) {
3224 goto done;
3226 break;
3227 case 31:
3228 status = init_samr_CryptPasswordAES(frame,
3229 param,
3230 &salt,
3231 &session_key,
3232 &pwd_buf_aes);
3233 if (!NT_STATUS_IS_OK(status)) {
3234 goto done;
3236 break;
3237 default:
3238 break;
3241 switch (level) {
3242 case 18:
3244 DATA_BLOB in,out;
3245 in = data_blob_const(nt_hash, 16);
3246 out = data_blob_talloc_zero(frame, 16);
3247 if (out.data == NULL) {
3248 status = NT_STATUS_NO_MEMORY;
3249 goto done;
3251 rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
3252 if (rc != 0) {
3253 status = gnutls_error_to_ntstatus(rc,
3254 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
3256 memcpy(nt_hash, out.data, out.length);
3259 DATA_BLOB in,out;
3260 in = data_blob_const(lm_hash, 16);
3261 out = data_blob_talloc_zero(frame, 15);
3262 if (out.data == NULL) {
3263 status = NT_STATUS_NO_MEMORY;
3264 goto done;
3266 rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
3267 if (rc != 0) {
3268 status = gnutls_error_to_ntstatus(rc,
3269 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
3271 memcpy(lm_hash, out.data, out.length);
3274 memcpy(info.info18.nt_pwd.hash, nt_hash, 16);
3275 memcpy(info.info18.lm_pwd.hash, lm_hash, 16);
3276 info.info18.nt_pwd_active = true;
3277 info.info18.lm_pwd_active = true;
3278 info.info18.password_expired = password_expired;
3280 break;
3281 case 21:
3282 ZERO_STRUCT(info.info21);
3284 info.info21.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3285 SAMR_FIELD_LM_PASSWORD_PRESENT;
3286 if (argc >= 5) {
3287 info.info21.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3288 info.info21.password_expired = password_expired;
3291 info.info21.lm_password_set = true;
3292 info.info21.lm_owf_password.length = 16;
3293 info.info21.lm_owf_password.size = 16;
3295 info.info21.nt_password_set = true;
3296 info.info21.nt_owf_password.length = 16;
3297 info.info21.nt_owf_password.size = 16;
3300 DATA_BLOB in,out;
3301 in = data_blob_const(nt_hash, 16);
3302 out = data_blob_talloc_zero(frame, 16);
3303 if (out.data == NULL) {
3304 status = NT_STATUS_NO_MEMORY;
3305 goto done;
3307 rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
3308 if (rc != 0) {
3309 status = gnutls_error_to_ntstatus(rc,
3310 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
3312 info.info21.nt_owf_password.array =
3313 (uint16_t *)talloc_memdup(frame, out.data, 16);
3316 DATA_BLOB in,out;
3317 in = data_blob_const(lm_hash, 16);
3318 out = data_blob_talloc_zero(frame, 16);
3319 rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
3320 if (rc != 0) {
3321 status = gnutls_error_to_ntstatus(rc,
3322 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
3324 info.info21.lm_owf_password.array =
3325 (uint16_t *)talloc_memdup(frame, out.data, 16);
3326 if (out.data == NULL) {
3327 status = NT_STATUS_NO_MEMORY;
3328 goto done;
3332 break;
3333 case 23:
3334 ZERO_STRUCT(info.info23);
3336 info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3337 SAMR_FIELD_LM_PASSWORD_PRESENT;
3338 if (argc >= 5) {
3339 info.info23.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3340 info.info23.info.password_expired = password_expired;
3343 info.info23.password = pwd_buf;
3345 break;
3346 case 24:
3347 info.info24.password = pwd_buf;
3348 info.info24.password_expired = password_expired;
3350 break;
3351 case 25:
3352 ZERO_STRUCT(info.info25);
3354 info.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3355 SAMR_FIELD_LM_PASSWORD_PRESENT;
3356 if (argc >= 5) {
3357 info.info25.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3358 info.info25.info.password_expired = password_expired;
3361 info.info25.password = pwd_buf_ex;
3363 break;
3364 case 26:
3365 info.info26.password = pwd_buf_ex;
3366 info.info26.password_expired = password_expired;
3368 break;
3369 case 31:
3370 info.info31.password = pwd_buf_aes;
3371 info.info31.password_expired = password_expired;
3372 break;
3373 default:
3374 status = NT_STATUS_INVALID_INFO_CLASS;
3375 goto done;
3378 /* Get sam policy handle */
3380 status = rpccli_try_samr_connects(cli, frame,
3381 MAXIMUM_ALLOWED_ACCESS,
3382 &connect_pol);
3383 if (!NT_STATUS_IS_OK(status)) {
3384 goto done;
3387 /* Get domain policy handle */
3389 status = dcerpc_samr_OpenDomain(b, frame,
3390 &connect_pol,
3391 access_mask,
3392 &domain_sid,
3393 &domain_pol,
3394 &result);
3396 if (!NT_STATUS_IS_OK(status))
3397 goto done;
3398 if (!NT_STATUS_IS_OK(result)) {
3399 status = result;
3400 goto done;
3403 user_rid = strtol(user, NULL, 0);
3404 if (user_rid) {
3405 status = dcerpc_samr_OpenUser(b, frame,
3406 &domain_pol,
3407 access_mask,
3408 user_rid,
3409 &user_pol,
3410 &result);
3411 if (!NT_STATUS_IS_OK(status)) {
3412 goto done;
3415 status = result;
3418 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) ||
3419 (user_rid == 0)) {
3421 /* Probably this was a user name, try lookupnames */
3422 struct samr_Ids rids, types;
3423 struct lsa_String lsa_acct_name;
3425 init_lsa_String(&lsa_acct_name, user);
3427 status = dcerpc_samr_LookupNames(b, frame,
3428 &domain_pol,
3430 &lsa_acct_name,
3431 &rids,
3432 &types,
3433 &result);
3434 if (!NT_STATUS_IS_OK(status)) {
3435 goto done;
3437 if (!NT_STATUS_IS_OK(result)) {
3438 status = result;
3439 goto done;
3441 if (rids.count != 1) {
3442 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
3443 goto done;
3445 if (types.count != 1) {
3446 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
3447 goto done;
3450 status = dcerpc_samr_OpenUser(b, frame,
3451 &domain_pol,
3452 access_mask,
3453 rids.ids[0],
3454 &user_pol,
3455 &result);
3456 if (!NT_STATUS_IS_OK(status)) {
3457 goto done;
3459 if (!NT_STATUS_IS_OK(result)) {
3460 status = result;
3461 goto done;
3465 switch (opcode) {
3466 case NDR_SAMR_SETUSERINFO:
3467 status = dcerpc_samr_SetUserInfo(b, frame,
3468 &user_pol,
3469 level,
3470 &info,
3471 &result);
3472 break;
3473 case NDR_SAMR_SETUSERINFO2:
3474 status = dcerpc_samr_SetUserInfo2(b, frame,
3475 &user_pol,
3476 level,
3477 &info,
3478 &result);
3479 break;
3480 default:
3481 status = NT_STATUS_INVALID_PARAMETER;
3482 goto done;
3484 if (!NT_STATUS_IS_OK(status)) {
3485 DEBUG(0,("status: %s\n", nt_errstr(status)));
3486 goto done;
3488 if (!NT_STATUS_IS_OK(result)) {
3489 status = result;
3490 DEBUG(0,("result: %s\n", nt_errstr(status)));
3491 goto done;
3494 status = NT_STATUS_OK;
3495 done:
3496 TALLOC_FREE(frame);
3497 return status;
3500 static NTSTATUS cmd_samr_setuserinfo(struct rpc_pipe_client *cli,
3501 TALLOC_CTX *mem_ctx,
3502 int argc, const char **argv)
3504 return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
3505 NDR_SAMR_SETUSERINFO);
3508 static NTSTATUS cmd_samr_setuserinfo2(struct rpc_pipe_client *cli,
3509 TALLOC_CTX *mem_ctx,
3510 int argc, const char **argv)
3512 return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
3513 NDR_SAMR_SETUSERINFO2);
3516 static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
3517 TALLOC_CTX *mem_ctx,
3518 int argc, const char **argv)
3520 NTSTATUS status, result;
3521 struct policy_handle connect_handle;
3522 struct policy_handle domain_handle = { 0, };
3523 uint16_t level = 1;
3524 struct lsa_String name;
3525 uint32_t idx = 0;
3526 struct dcerpc_binding_handle *b = cli->binding_handle;
3528 if (argc < 2 || argc > 3) {
3529 printf("Usage: %s name level\n", argv[0]);
3530 return NT_STATUS_INVALID_PARAMETER;
3533 init_lsa_String(&name, argv[1]);
3535 if (argc == 3) {
3536 level = atoi(argv[2]);
3539 status = rpccli_try_samr_connects(cli, mem_ctx,
3540 SEC_FLAG_MAXIMUM_ALLOWED,
3541 &connect_handle);
3542 if (!NT_STATUS_IS_OK(status)) {
3543 goto done;
3546 status = dcerpc_samr_OpenDomain(b, mem_ctx,
3547 &connect_handle,
3548 SEC_FLAG_MAXIMUM_ALLOWED,
3549 &domain_sid,
3550 &domain_handle,
3551 &result);
3552 if (!NT_STATUS_IS_OK(status)) {
3553 goto done;
3555 if (!NT_STATUS_IS_OK(result)) {
3556 status = result;
3557 goto done;
3560 status = dcerpc_samr_GetDisplayEnumerationIndex(b, mem_ctx,
3561 &domain_handle,
3562 level,
3563 &name,
3564 &idx,
3565 &result);
3566 if (!NT_STATUS_IS_OK(status)) {
3567 goto done;
3570 status = result;
3572 if (NT_STATUS_IS_OK(status) ||
3573 NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
3574 printf("idx: %d (0x%08x)\n", idx, idx);
3576 done:
3578 if (is_valid_policy_hnd(&domain_handle)) {
3579 dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
3581 if (is_valid_policy_hnd(&connect_handle)) {
3582 dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
3585 return status;
3588 /* List of commands exported by this module */
3590 struct cmd_set samr_commands[] = {
3593 .name = "SAMR",
3597 .name = "queryuser",
3598 .returntype = RPC_RTYPE_NTSTATUS,
3599 .ntfn = cmd_samr_query_user,
3600 .wfn = NULL,
3601 .table = &ndr_table_samr,
3602 .rpc_pipe = NULL,
3603 .description = "Query user info",
3604 .usage = "",
3607 .name = "querygroup",
3608 .returntype = RPC_RTYPE_NTSTATUS,
3609 .ntfn = cmd_samr_query_group,
3610 .wfn = NULL,
3611 .table = &ndr_table_samr,
3612 .rpc_pipe = NULL,
3613 .description = "Query group info",
3614 .usage = "",
3617 .name = "queryusergroups",
3618 .returntype = RPC_RTYPE_NTSTATUS,
3619 .ntfn = cmd_samr_query_usergroups,
3620 .wfn = NULL,
3621 .table = &ndr_table_samr,
3622 .rpc_pipe = NULL,
3623 .description = "Query user groups",
3624 .usage = "",
3627 .name = "queryuseraliases",
3628 .returntype = RPC_RTYPE_NTSTATUS,
3629 .ntfn = cmd_samr_query_useraliases,
3630 .wfn = NULL,
3631 .table = &ndr_table_samr,
3632 .rpc_pipe = NULL,
3633 .description = "Query user aliases",
3634 .usage = "",
3637 .name = "querygroupmem",
3638 .returntype = RPC_RTYPE_NTSTATUS,
3639 .ntfn = cmd_samr_query_groupmem,
3640 .wfn = NULL,
3641 .table = &ndr_table_samr,
3642 .rpc_pipe = NULL,
3643 .description = "Query group membership",
3644 .usage = "",
3647 .name = "queryaliasmem",
3648 .returntype = RPC_RTYPE_NTSTATUS,
3649 .ntfn = cmd_samr_query_aliasmem,
3650 .wfn = NULL,
3651 .table = &ndr_table_samr,
3652 .rpc_pipe = NULL,
3653 .description = "Query alias membership",
3654 .usage = "",
3657 .name = "queryaliasinfo",
3658 .returntype = RPC_RTYPE_NTSTATUS,
3659 .ntfn = cmd_samr_query_aliasinfo,
3660 .wfn = NULL,
3661 .table = &ndr_table_samr,
3662 .rpc_pipe = NULL,
3663 .description = "Query alias info",
3664 .usage = "",
3667 .name = "deletealias",
3668 .returntype = RPC_RTYPE_NTSTATUS,
3669 .ntfn = cmd_samr_delete_alias,
3670 .wfn = NULL,
3671 .table = &ndr_table_samr,
3672 .rpc_pipe = NULL,
3673 .description = "Delete an alias",
3674 .usage = "",
3677 .name = "querydispinfo",
3678 .returntype = RPC_RTYPE_NTSTATUS,
3679 .ntfn = cmd_samr_query_dispinfo,
3680 .wfn = NULL,
3681 .table = &ndr_table_samr,
3682 .rpc_pipe = NULL,
3683 .description = "Query display info",
3684 .usage = "",
3687 .name = "querydispinfo2",
3688 .returntype = RPC_RTYPE_NTSTATUS,
3689 .ntfn = cmd_samr_query_dispinfo2,
3690 .wfn = NULL,
3691 .table = &ndr_table_samr,
3692 .rpc_pipe = NULL,
3693 .description = "Query display info",
3694 .usage = "",
3697 .name = "querydispinfo3",
3698 .returntype = RPC_RTYPE_NTSTATUS,
3699 .ntfn = cmd_samr_query_dispinfo3,
3700 .wfn = NULL,
3701 .table = &ndr_table_samr,
3702 .rpc_pipe = NULL,
3703 .description = "Query display info",
3704 .usage = "",
3707 .name = "querydominfo",
3708 .returntype = RPC_RTYPE_NTSTATUS,
3709 .ntfn = cmd_samr_query_dominfo,
3710 .wfn = NULL,
3711 .table = &ndr_table_samr,
3712 .rpc_pipe = NULL,
3713 .description = "Query domain info",
3714 .usage = "",
3717 .name = "enumdomusers",
3718 .returntype = RPC_RTYPE_NTSTATUS,
3719 .ntfn = cmd_samr_enum_dom_users,
3720 .wfn = NULL,
3721 .table = &ndr_table_samr,
3722 .rpc_pipe = NULL,
3723 .description = "Enumerate domain users",
3724 .usage = "",
3727 .name = "enumdomgroups",
3728 .returntype = RPC_RTYPE_NTSTATUS,
3729 .ntfn = cmd_samr_enum_dom_groups,
3730 .wfn = NULL,
3731 .table = &ndr_table_samr,
3732 .rpc_pipe = NULL,
3733 .description = "Enumerate domain groups",
3734 .usage = "",
3737 .name = "enumalsgroups",
3738 .returntype = RPC_RTYPE_NTSTATUS,
3739 .ntfn = cmd_samr_enum_als_groups,
3740 .wfn = NULL,
3741 .table = &ndr_table_samr,
3742 .rpc_pipe = NULL,
3743 .description = "Enumerate alias groups",
3744 .usage = "",
3747 .name = "enumdomains",
3748 .returntype = RPC_RTYPE_NTSTATUS,
3749 .ntfn = cmd_samr_enum_domains,
3750 .wfn = NULL,
3751 .table = &ndr_table_samr,
3752 .rpc_pipe = NULL,
3753 .description = "Enumerate domains",
3754 .usage = "",
3758 .name = "createdomuser",
3759 .returntype = RPC_RTYPE_NTSTATUS,
3760 .ntfn = cmd_samr_create_dom_user,
3761 .wfn = NULL,
3762 .table = &ndr_table_samr,
3763 .rpc_pipe = NULL,
3764 .description = "Create domain user",
3765 .usage = "",
3768 .name = "createdomgroup",
3769 .returntype = RPC_RTYPE_NTSTATUS,
3770 .ntfn = cmd_samr_create_dom_group,
3771 .wfn = NULL,
3772 .table = &ndr_table_samr,
3773 .rpc_pipe = NULL,
3774 .description = "Create domain group",
3775 .usage = "",
3778 .name = "createdomalias",
3779 .returntype = RPC_RTYPE_NTSTATUS,
3780 .ntfn = cmd_samr_create_dom_alias,
3781 .wfn = NULL,
3782 .table = &ndr_table_samr,
3783 .rpc_pipe = NULL,
3784 .description = "Create domain alias",
3785 .usage = "",
3788 .name = "samlookupnames",
3789 .returntype = RPC_RTYPE_NTSTATUS,
3790 .ntfn = cmd_samr_lookup_names,
3791 .wfn = NULL,
3792 .table = &ndr_table_samr,
3793 .rpc_pipe = NULL,
3794 .description = "Look up names",
3795 .usage = "",
3798 .name = "samlookuprids",
3799 .returntype = RPC_RTYPE_NTSTATUS,
3800 .ntfn = cmd_samr_lookup_rids,
3801 .wfn = NULL,
3802 .table = &ndr_table_samr,
3803 .rpc_pipe = NULL,
3804 .description = "Look up names",
3805 .usage = "",
3808 .name = "deletedomgroup",
3809 .returntype = RPC_RTYPE_NTSTATUS,
3810 .ntfn = cmd_samr_delete_dom_group,
3811 .wfn = NULL,
3812 .table = &ndr_table_samr,
3813 .rpc_pipe = NULL,
3814 .description = "Delete domain group",
3815 .usage = "",
3818 .name = "deletedomuser",
3819 .returntype = RPC_RTYPE_NTSTATUS,
3820 .ntfn = cmd_samr_delete_dom_user,
3821 .wfn = NULL,
3822 .table = &ndr_table_samr,
3823 .rpc_pipe = NULL,
3824 .description = "Delete domain user",
3825 .usage = "",
3828 .name = "samquerysecobj",
3829 .returntype = RPC_RTYPE_NTSTATUS,
3830 .ntfn = cmd_samr_query_sec_obj,
3831 .wfn = NULL,
3832 .table = &ndr_table_samr,
3833 .rpc_pipe = NULL,
3834 .description = "Query SAMR security object",
3835 .usage = "",
3838 .name = "getdompwinfo",
3839 .returntype = RPC_RTYPE_NTSTATUS,
3840 .ntfn = cmd_samr_get_dom_pwinfo,
3841 .wfn = NULL,
3842 .table = &ndr_table_samr,
3843 .rpc_pipe = NULL,
3844 .description = "Retrieve domain password info",
3845 .usage = "",
3848 .name = "getusrdompwinfo",
3849 .returntype = RPC_RTYPE_NTSTATUS,
3850 .ntfn = cmd_samr_get_usrdom_pwinfo,
3851 .wfn = NULL,
3852 .table = &ndr_table_samr,
3853 .rpc_pipe = NULL,
3854 .description = "Retrieve user domain password info",
3855 .usage = "",
3859 .name = "lookupdomain",
3860 .returntype = RPC_RTYPE_NTSTATUS,
3861 .ntfn = cmd_samr_lookup_domain,
3862 .wfn = NULL,
3863 .table = &ndr_table_samr,
3864 .rpc_pipe = NULL,
3865 .description = "Lookup Domain Name",
3866 .usage = "",
3869 .name = "chgpasswd",
3870 .returntype = RPC_RTYPE_NTSTATUS,
3871 .ntfn = cmd_samr_chgpasswd,
3872 .wfn = NULL,
3873 .table = &ndr_table_samr,
3874 .rpc_pipe = NULL,
3875 .description = "Change user password",
3876 .usage = "",
3879 .name = "chgpasswd2",
3880 .returntype = RPC_RTYPE_NTSTATUS,
3881 .ntfn = cmd_samr_chgpasswd2,
3882 .wfn = NULL,
3883 .table = &ndr_table_samr,
3884 .rpc_pipe = NULL,
3885 .description = "Change user password",
3886 .usage = "",
3889 .name = "chgpasswd3",
3890 .returntype = RPC_RTYPE_NTSTATUS,
3891 .ntfn = cmd_samr_chgpasswd3,
3892 .wfn = NULL,
3893 .table = &ndr_table_samr,
3894 .rpc_pipe = NULL,
3895 .description = "Change user password",
3896 .usage = "",
3899 .name = "chgpasswd4",
3900 .returntype = RPC_RTYPE_NTSTATUS,
3901 .ntfn = cmd_samr_chgpasswd4,
3902 .wfn = NULL,
3903 .table = &ndr_table_samr,
3904 .rpc_pipe = NULL,
3905 .description = "Change user password",
3906 .usage = "",
3909 .name = "getdispinfoidx",
3910 .returntype = RPC_RTYPE_NTSTATUS,
3911 .ntfn = cmd_samr_get_dispinfo_idx,
3912 .wfn = NULL,
3913 .table = &ndr_table_samr,
3914 .rpc_pipe = NULL,
3915 .description = "Get Display Information Index",
3916 .usage = "",
3919 .name = "setuserinfo",
3920 .returntype = RPC_RTYPE_NTSTATUS,
3921 .ntfn = cmd_samr_setuserinfo,
3922 .wfn = NULL,
3923 .table = &ndr_table_samr,
3924 .rpc_pipe = NULL,
3925 .description = "Set user info",
3926 .usage = "",
3929 .name = "setuserinfo2",
3930 .returntype = RPC_RTYPE_NTSTATUS,
3931 .ntfn = cmd_samr_setuserinfo2,
3932 .wfn = NULL,
3933 .table = &ndr_table_samr,
3934 .rpc_pipe = NULL,
3935 .description = "Set user info2",
3936 .usage = "",
3939 .name = NULL,