s3: use monotonic clock for time deltas in namequery functions
[Samba/gebeck_regimport.git] / source3 / rpcclient / cmd_samr.c
blobea943761c889d309020aef3a0806a901d5444933
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/cli_samr.h"
30 #include "rpc_client/cli_samr.h"
31 #include "rpc_client/init_samr.h"
32 #include "rpc_client/init_lsa.h"
34 extern struct dom_sid domain_sid;
36 /****************************************************************************
37 display samr_user_info_7 structure
38 ****************************************************************************/
39 static void display_samr_user_info_7(struct samr_UserInfo7 *r)
41 printf("\tUser Name :\t%s\n", r->account_name.string);
44 /****************************************************************************
45 display samr_user_info_9 structure
46 ****************************************************************************/
47 static void display_samr_user_info_9(struct samr_UserInfo9 *r)
49 printf("\tPrimary group RID :\tox%x\n", r->primary_gid);
52 /****************************************************************************
53 display samr_user_info_16 structure
54 ****************************************************************************/
55 static void display_samr_user_info_16(struct samr_UserInfo16 *r)
57 printf("\tAcct Flags :\tox%x\n", r->acct_flags);
60 /****************************************************************************
61 display samr_user_info_20 structure
62 ****************************************************************************/
63 static void display_samr_user_info_20(struct samr_UserInfo20 *r)
65 printf("\tRemote Dial :\n");
66 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
70 /****************************************************************************
71 display samr_user_info_21 structure
72 ****************************************************************************/
73 static void display_samr_user_info_21(struct samr_UserInfo21 *r)
75 printf("\tUser Name :\t%s\n", r->account_name.string);
76 printf("\tFull Name :\t%s\n", r->full_name.string);
77 printf("\tHome Drive :\t%s\n", r->home_directory.string);
78 printf("\tDir Drive :\t%s\n", r->home_drive.string);
79 printf("\tProfile Path:\t%s\n", r->profile_path.string);
80 printf("\tLogon Script:\t%s\n", r->logon_script.string);
81 printf("\tDescription :\t%s\n", r->description.string);
82 printf("\tWorkstations:\t%s\n", r->workstations.string);
83 printf("\tComment :\t%s\n", r->comment.string);
84 printf("\tRemote Dial :\n");
85 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
87 printf("\tLogon Time :\t%s\n",
88 http_timestring(talloc_tos(), nt_time_to_unix(r->last_logon)));
89 printf("\tLogoff Time :\t%s\n",
90 http_timestring(talloc_tos(), nt_time_to_unix(r->last_logoff)));
91 printf("\tKickoff Time :\t%s\n",
92 http_timestring(talloc_tos(), nt_time_to_unix(r->acct_expiry)));
93 printf("\tPassword last set Time :\t%s\n",
94 http_timestring(talloc_tos(), nt_time_to_unix(r->last_password_change)));
95 printf("\tPassword can change Time :\t%s\n",
96 http_timestring(talloc_tos(), nt_time_to_unix(r->allow_password_change)));
97 printf("\tPassword must change Time:\t%s\n",
98 http_timestring(talloc_tos(), nt_time_to_unix(r->force_password_change)));
100 printf("\tunknown_2[0..31]...\n"); /* user passwords? */
102 printf("\tuser_rid :\t0x%x\n" , r->rid); /* User ID */
103 printf("\tgroup_rid:\t0x%x\n" , r->primary_gid); /* Group ID */
104 printf("\tacb_info :\t0x%08x\n", r->acct_flags); /* Account Control Info */
106 printf("\tfields_present:\t0x%08x\n", r->fields_present); /* 0x00ff ffff */
107 printf("\tlogon_divs:\t%d\n", r->logon_hours.units_per_week); /* 0x0000 00a8 which is 168 which is num hrs in a week */
108 printf("\tbad_password_count:\t0x%08x\n", r->bad_password_count);
109 printf("\tlogon_count:\t0x%08x\n", r->logon_count);
111 printf("\tpadding1[0..7]...\n");
113 if (r->logon_hours.bits) {
114 printf("\tlogon_hrs[0..%d]...\n", r->logon_hours.units_per_week/8);
119 static void display_password_properties(uint32_t password_properties)
121 printf("password_properties: 0x%08x\n", password_properties);
123 if (password_properties & DOMAIN_PASSWORD_COMPLEX)
124 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
126 if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
127 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
129 if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
130 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
132 if (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)
133 printf("\tDOMAIN_PASSWORD_LOCKOUT_ADMINS\n");
135 if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
136 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
138 if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
139 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
142 static void display_sam_dom_info_1(struct samr_DomInfo1 *info1)
144 printf("Minimum password length:\t\t\t%d\n",
145 info1->min_password_length);
146 printf("Password uniqueness (remember x passwords):\t%d\n",
147 info1->password_history_length);
148 display_password_properties(info1->password_properties);
149 printf("password expire in:\t\t\t\t%s\n",
150 display_time(info1->max_password_age));
151 printf("Min password age (allow changing in x days):\t%s\n",
152 display_time(info1->min_password_age));
155 static void display_sam_dom_info_2(struct samr_DomGeneralInformation *general)
157 printf("Domain:\t\t%s\n", general->domain_name.string);
158 printf("Server:\t\t%s\n", general->primary.string);
159 printf("Comment:\t%s\n", general->oem_information.string);
161 printf("Total Users:\t%d\n", general->num_users);
162 printf("Total Groups:\t%d\n", general->num_groups);
163 printf("Total Aliases:\t%d\n", general->num_aliases);
165 printf("Sequence No:\t%llu\n", (unsigned long long)general->sequence_num);
167 printf("Force Logoff:\t%d\n",
168 (int)nt_time_to_unix_abs(&general->force_logoff_time));
170 printf("Domain Server State:\t0x%x\n", general->domain_server_state);
171 printf("Server Role:\t%s\n", server_role_str(general->role));
172 printf("Unknown 3:\t0x%x\n", general->unknown3);
175 static void display_sam_dom_info_3(struct samr_DomInfo3 *info3)
177 printf("Force Logoff:\t%d\n",
178 (int)nt_time_to_unix_abs(&info3->force_logoff_time));
181 static void display_sam_dom_info_4(struct samr_DomOEMInformation *oem)
183 printf("Comment:\t%s\n", oem->oem_information.string);
186 static void display_sam_dom_info_5(struct samr_DomInfo5 *info5)
188 printf("Domain:\t\t%s\n", info5->domain_name.string);
191 static void display_sam_dom_info_6(struct samr_DomInfo6 *info6)
193 printf("Server:\t\t%s\n", info6->primary.string);
196 static void display_sam_dom_info_7(struct samr_DomInfo7 *info7)
198 printf("Server Role:\t%s\n", server_role_str(info7->role));
201 static void display_sam_dom_info_8(struct samr_DomInfo8 *info8)
203 printf("Sequence No:\t%llu\n", (unsigned long long)info8->sequence_num);
204 printf("Domain Create Time:\t%s\n",
205 http_timestring(talloc_tos(), nt_time_to_unix(info8->domain_create_time)));
208 static void display_sam_dom_info_9(struct samr_DomInfo9 *info9)
210 printf("Domain Server State:\t0x%x\n", info9->domain_server_state);
213 static void display_sam_dom_info_12(struct samr_DomInfo12 *info12)
215 printf("Bad password lockout duration: %s\n",
216 display_time(info12->lockout_duration));
217 printf("Reset Lockout after: %s\n",
218 display_time(info12->lockout_window));
219 printf("Lockout after bad attempts: %d\n",
220 info12->lockout_threshold);
223 static void display_sam_dom_info_13(struct samr_DomInfo13 *info13)
225 printf("Sequence No:\t%llu\n", (unsigned long long)info13->sequence_num);
226 printf("Domain Create Time:\t%s\n",
227 http_timestring(talloc_tos(), nt_time_to_unix(info13->domain_create_time)));
228 printf("Sequence No at last promotion:\t%llu\n",
229 (unsigned long long)info13->modified_count_at_last_promotion);
232 static void display_sam_info_1(struct samr_DispEntryGeneral *r)
234 printf("index: 0x%x ", r->idx);
235 printf("RID: 0x%x ", r->rid);
236 printf("acb: 0x%08x ", r->acct_flags);
237 printf("Account: %s\t", r->account_name.string);
238 printf("Name: %s\t", r->full_name.string);
239 printf("Desc: %s\n", r->description.string);
242 static void display_sam_info_2(struct samr_DispEntryFull *r)
244 printf("index: 0x%x ", r->idx);
245 printf("RID: 0x%x ", r->rid);
246 printf("acb: 0x%08x ", r->acct_flags);
247 printf("Account: %s\t", r->account_name.string);
248 printf("Desc: %s\n", r->description.string);
251 static void display_sam_info_3(struct samr_DispEntryFullGroup *r)
253 printf("index: 0x%x ", r->idx);
254 printf("RID: 0x%x ", r->rid);
255 printf("acb: 0x%08x ", r->acct_flags);
256 printf("Account: %s\t", r->account_name.string);
257 printf("Desc: %s\n", r->description.string);
260 static void display_sam_info_4(struct samr_DispEntryAscii *r)
262 printf("index: 0x%x ", r->idx);
263 printf("Account: %s\n", r->account_name.string);
266 static void display_sam_info_5(struct samr_DispEntryAscii *r)
268 printf("index: 0x%x ", r->idx);
269 printf("Account: %s\n", r->account_name.string);
272 /****************************************************************************
273 ****************************************************************************/
275 static NTSTATUS get_domain_handle(struct rpc_pipe_client *cli,
276 TALLOC_CTX *mem_ctx,
277 const char *sam,
278 struct policy_handle *connect_pol,
279 uint32_t access_mask,
280 struct dom_sid *_domain_sid,
281 struct policy_handle *domain_pol)
284 if (StrCaseCmp(sam, "domain") == 0) {
285 return rpccli_samr_OpenDomain(cli, mem_ctx,
286 connect_pol,
287 access_mask,
288 _domain_sid,
289 domain_pol);
290 } else if (StrCaseCmp(sam, "builtin") == 0) {
291 return rpccli_samr_OpenDomain(cli, mem_ctx,
292 connect_pol,
293 access_mask,
294 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
295 domain_pol);
298 return NT_STATUS_INVALID_PARAMETER;
301 /**********************************************************************
302 * Query user information
304 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
305 TALLOC_CTX *mem_ctx,
306 int argc, const char **argv)
308 struct policy_handle connect_pol, domain_pol, user_pol;
309 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
310 uint32 info_level = 21;
311 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
312 union samr_UserInfo *info = NULL;
313 uint32 user_rid = 0;
315 if ((argc < 2) || (argc > 4)) {
316 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
317 return NT_STATUS_OK;
320 sscanf(argv[1], "%i", &user_rid);
322 if (argc > 2)
323 sscanf(argv[2], "%i", &info_level);
325 if (argc > 3)
326 sscanf(argv[3], "%x", &access_mask);
329 result = rpccli_try_samr_connects(cli, mem_ctx,
330 MAXIMUM_ALLOWED_ACCESS,
331 &connect_pol);
333 if (!NT_STATUS_IS_OK(result))
334 goto done;
336 result = rpccli_samr_OpenDomain(cli, mem_ctx,
337 &connect_pol,
338 MAXIMUM_ALLOWED_ACCESS,
339 &domain_sid,
340 &domain_pol);
341 if (!NT_STATUS_IS_OK(result))
342 goto done;
344 result = rpccli_samr_OpenUser(cli, mem_ctx,
345 &domain_pol,
346 access_mask,
347 user_rid,
348 &user_pol);
350 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
351 (user_rid == 0)) {
353 /* Probably this was a user name, try lookupnames */
354 struct samr_Ids rids, types;
355 struct lsa_String lsa_acct_name;
357 init_lsa_String(&lsa_acct_name, argv[1]);
359 result = rpccli_samr_LookupNames(cli, mem_ctx,
360 &domain_pol,
362 &lsa_acct_name,
363 &rids,
364 &types);
366 if (NT_STATUS_IS_OK(result)) {
367 result = rpccli_samr_OpenUser(cli, mem_ctx,
368 &domain_pol,
369 access_mask,
370 rids.ids[0],
371 &user_pol);
376 if (!NT_STATUS_IS_OK(result))
377 goto done;
379 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
380 &user_pol,
381 info_level,
382 &info);
384 if (!NT_STATUS_IS_OK(result))
385 goto done;
387 switch (info_level) {
388 case 7:
389 display_samr_user_info_7(&info->info7);
390 break;
391 case 9:
392 display_samr_user_info_9(&info->info9);
393 break;
394 case 16:
395 display_samr_user_info_16(&info->info16);
396 break;
397 case 20:
398 display_samr_user_info_20(&info->info20);
399 break;
400 case 21:
401 display_samr_user_info_21(&info->info21);
402 break;
403 default:
404 printf("Unsupported infolevel: %d\n", info_level);
405 break;
408 rpccli_samr_Close(cli, mem_ctx, &user_pol);
409 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
410 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
412 done:
413 return result;
416 /****************************************************************************
417 display group info
418 ****************************************************************************/
419 static void display_group_info1(struct samr_GroupInfoAll *info1)
421 printf("\tGroup Name:\t%s\n", info1->name.string);
422 printf("\tDescription:\t%s\n", info1->description.string);
423 printf("\tGroup Attribute:%d\n", info1->attributes);
424 printf("\tNum Members:%d\n", info1->num_members);
427 /****************************************************************************
428 display group info
429 ****************************************************************************/
430 static void display_group_info2(struct lsa_String *info2)
432 printf("\tGroup Description:%s\n", info2->string);
436 /****************************************************************************
437 display group info
438 ****************************************************************************/
439 static void display_group_info3(struct samr_GroupInfoAttributes *info3)
441 printf("\tGroup Attribute:%d\n", info3->attributes);
445 /****************************************************************************
446 display group info
447 ****************************************************************************/
448 static void display_group_info4(struct lsa_String *info4)
450 printf("\tGroup Description:%s\n", info4->string);
453 /****************************************************************************
454 display group info
455 ****************************************************************************/
456 static void display_group_info5(struct samr_GroupInfoAll *info5)
458 printf("\tGroup Name:\t%s\n", info5->name.string);
459 printf("\tDescription:\t%s\n", info5->description.string);
460 printf("\tGroup Attribute:%d\n", info5->attributes);
461 printf("\tNum Members:%d\n", info5->num_members);
464 /****************************************************************************
465 display sam sync structure
466 ****************************************************************************/
467 static void display_group_info(union samr_GroupInfo *info,
468 enum samr_GroupInfoEnum level)
470 switch (level) {
471 case 1:
472 display_group_info1(&info->all);
473 break;
474 case 2:
475 display_group_info2(&info->name);
476 break;
477 case 3:
478 display_group_info3(&info->attributes);
479 break;
480 case 4:
481 display_group_info4(&info->description);
482 break;
483 case 5:
484 display_group_info5(&info->all2);
485 break;
489 /***********************************************************************
490 * Query group information
492 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
493 TALLOC_CTX *mem_ctx,
494 int argc, const char **argv)
496 struct policy_handle connect_pol, domain_pol, group_pol;
497 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
498 enum samr_GroupInfoEnum info_level = GROUPINFOALL;
499 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
500 union samr_GroupInfo *group_info = NULL;
501 uint32 group_rid;
503 if ((argc < 2) || (argc > 4)) {
504 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
505 return NT_STATUS_OK;
508 sscanf(argv[1], "%i", &group_rid);
510 if (argc > 2)
511 info_level = atoi(argv[2]);
513 if (argc > 3)
514 sscanf(argv[3], "%x", &access_mask);
516 result = rpccli_try_samr_connects(cli, mem_ctx,
517 MAXIMUM_ALLOWED_ACCESS,
518 &connect_pol);
520 if (!NT_STATUS_IS_OK(result))
521 goto done;
523 result = rpccli_samr_OpenDomain(cli, mem_ctx,
524 &connect_pol,
525 MAXIMUM_ALLOWED_ACCESS,
526 &domain_sid,
527 &domain_pol);
529 if (!NT_STATUS_IS_OK(result))
530 goto done;
532 result = rpccli_samr_OpenGroup(cli, mem_ctx,
533 &domain_pol,
534 access_mask,
535 group_rid,
536 &group_pol);
538 if (!NT_STATUS_IS_OK(result))
539 goto done;
541 result = rpccli_samr_QueryGroupInfo(cli, mem_ctx,
542 &group_pol,
543 info_level,
544 &group_info);
545 if (!NT_STATUS_IS_OK(result)) {
546 goto done;
549 display_group_info(group_info, info_level);
551 rpccli_samr_Close(cli, mem_ctx, &group_pol);
552 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
553 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
554 done:
555 return result;
558 /* Query groups a user is a member of */
560 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
561 TALLOC_CTX *mem_ctx,
562 int argc, const char **argv)
564 struct policy_handle connect_pol,
565 domain_pol,
566 user_pol;
567 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
568 uint32 user_rid;
569 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
570 int i;
571 struct samr_RidWithAttributeArray *rid_array = NULL;
573 if ((argc < 2) || (argc > 3)) {
574 printf("Usage: %s rid [access mask]\n", argv[0]);
575 return NT_STATUS_OK;
578 sscanf(argv[1], "%i", &user_rid);
580 if (argc > 2)
581 sscanf(argv[2], "%x", &access_mask);
583 result = rpccli_try_samr_connects(cli, mem_ctx,
584 MAXIMUM_ALLOWED_ACCESS,
585 &connect_pol);
587 if (!NT_STATUS_IS_OK(result))
588 goto done;
590 result = rpccli_samr_OpenDomain(cli, mem_ctx,
591 &connect_pol,
592 MAXIMUM_ALLOWED_ACCESS,
593 &domain_sid, &domain_pol);
595 if (!NT_STATUS_IS_OK(result))
596 goto done;
598 result = rpccli_samr_OpenUser(cli, mem_ctx,
599 &domain_pol,
600 access_mask,
601 user_rid,
602 &user_pol);
604 if (!NT_STATUS_IS_OK(result))
605 goto done;
607 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
608 &user_pol,
609 &rid_array);
611 if (!NT_STATUS_IS_OK(result))
612 goto done;
614 for (i = 0; i < rid_array->count; i++) {
615 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
616 rid_array->rids[i].rid,
617 rid_array->rids[i].attributes);
620 rpccli_samr_Close(cli, mem_ctx, &user_pol);
621 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
622 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
623 done:
624 return result;
627 /* Query aliases a user is a member of */
629 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
630 TALLOC_CTX *mem_ctx,
631 int argc, const char **argv)
633 struct policy_handle connect_pol, domain_pol;
634 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
635 struct dom_sid *sids;
636 size_t num_sids;
637 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
638 int i;
639 struct lsa_SidArray sid_array;
640 struct samr_Ids alias_rids;
642 if (argc < 3) {
643 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
644 return NT_STATUS_INVALID_PARAMETER;
647 sids = NULL;
648 num_sids = 0;
650 for (i=2; i<argc; i++) {
651 struct dom_sid tmp_sid;
652 if (!string_to_sid(&tmp_sid, argv[i])) {
653 printf("%s is not a legal SID\n", argv[i]);
654 return NT_STATUS_INVALID_PARAMETER;
656 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
657 if (!NT_STATUS_IS_OK(result)) {
658 return result;
662 if (num_sids) {
663 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids);
664 if (sid_array.sids == NULL)
665 return NT_STATUS_NO_MEMORY;
666 } else {
667 sid_array.sids = NULL;
670 for (i=0; i<num_sids; i++) {
671 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[i]);
672 if (!sid_array.sids[i].sid) {
673 return NT_STATUS_NO_MEMORY;
677 sid_array.num_sids = num_sids;
679 result = rpccli_try_samr_connects(cli, mem_ctx,
680 MAXIMUM_ALLOWED_ACCESS,
681 &connect_pol);
683 if (!NT_STATUS_IS_OK(result))
684 goto done;
686 result = get_domain_handle(cli, mem_ctx, argv[1],
687 &connect_pol,
688 access_mask,
689 &domain_sid,
690 &domain_pol);
692 if (!NT_STATUS_IS_OK(result))
693 goto done;
695 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
696 &domain_pol,
697 &sid_array,
698 &alias_rids);
699 if (!NT_STATUS_IS_OK(result))
700 goto done;
702 for (i = 0; i < alias_rids.count; i++) {
703 printf("\tgroup rid:[0x%x]\n", alias_rids.ids[i]);
706 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
707 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
708 done:
709 return result;
712 /* Query members of a group */
714 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
715 TALLOC_CTX *mem_ctx,
716 int argc, const char **argv)
718 struct policy_handle connect_pol, domain_pol, group_pol;
719 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
720 uint32 group_rid;
721 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
722 int i;
723 unsigned int old_timeout;
724 struct samr_RidTypeArray *rids = NULL;
726 if ((argc < 2) || (argc > 3)) {
727 printf("Usage: %s rid [access mask]\n", argv[0]);
728 return NT_STATUS_OK;
731 sscanf(argv[1], "%i", &group_rid);
733 if (argc > 2)
734 sscanf(argv[2], "%x", &access_mask);
736 result = rpccli_try_samr_connects(cli, mem_ctx,
737 MAXIMUM_ALLOWED_ACCESS,
738 &connect_pol);
740 if (!NT_STATUS_IS_OK(result))
741 goto done;
743 result = rpccli_samr_OpenDomain(cli, mem_ctx,
744 &connect_pol,
745 MAXIMUM_ALLOWED_ACCESS,
746 &domain_sid,
747 &domain_pol);
749 if (!NT_STATUS_IS_OK(result))
750 goto done;
752 result = rpccli_samr_OpenGroup(cli, mem_ctx,
753 &domain_pol,
754 access_mask,
755 group_rid,
756 &group_pol);
758 if (!NT_STATUS_IS_OK(result))
759 goto done;
761 /* Make sure to wait for our DC's reply */
762 old_timeout = rpccli_set_timeout(cli, 30000); /* 30 seconds. */
763 rpccli_set_timeout(cli, MAX(30000, old_timeout)); /* At least 30 sec */
765 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
766 &group_pol,
767 &rids);
769 rpccli_set_timeout(cli, old_timeout);
771 if (!NT_STATUS_IS_OK(result))
772 goto done;
774 for (i = 0; i < rids->count; i++) {
775 printf("\trid:[0x%x] attr:[0x%x]\n", rids->rids[i],
776 rids->types[i]);
779 rpccli_samr_Close(cli, mem_ctx, &group_pol);
780 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
781 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
782 done:
783 return result;
786 /* Enumerate domain users */
788 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
789 TALLOC_CTX *mem_ctx,
790 int argc, const char **argv)
792 struct policy_handle connect_pol, domain_pol;
793 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
794 uint32 start_idx, num_dom_users, i;
795 struct samr_SamArray *dom_users = NULL;
796 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
797 uint32 acb_mask = ACB_NORMAL;
798 uint32_t size = 0xffff;
800 if ((argc < 1) || (argc > 4)) {
801 printf("Usage: %s [access_mask] [acb_mask] [size]\n", argv[0]);
802 return NT_STATUS_OK;
805 if (argc > 1) {
806 sscanf(argv[1], "%x", &access_mask);
809 if (argc > 2) {
810 sscanf(argv[2], "%x", &acb_mask);
813 if (argc > 3) {
814 sscanf(argv[3], "%x", &size);
817 /* Get sam policy handle */
819 result = rpccli_try_samr_connects(cli, mem_ctx,
820 MAXIMUM_ALLOWED_ACCESS,
821 &connect_pol);
823 if (!NT_STATUS_IS_OK(result))
824 goto done;
826 /* Get domain policy handle */
828 result = get_domain_handle(cli, mem_ctx, "domain",
829 &connect_pol,
830 access_mask,
831 &domain_sid,
832 &domain_pol);
833 if (!NT_STATUS_IS_OK(result))
834 goto done;
836 /* Enumerate domain users */
838 start_idx = 0;
840 do {
841 result = rpccli_samr_EnumDomainUsers(cli, mem_ctx,
842 &domain_pol,
843 &start_idx,
844 acb_mask,
845 &dom_users,
846 size,
847 &num_dom_users);
849 if (NT_STATUS_IS_OK(result) ||
850 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
852 for (i = 0; i < num_dom_users; i++)
853 printf("user:[%s] rid:[0x%x]\n",
854 dom_users->entries[i].name.string,
855 dom_users->entries[i].idx);
858 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
860 done:
861 if (is_valid_policy_hnd(&domain_pol))
862 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
864 if (is_valid_policy_hnd(&connect_pol))
865 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
867 return result;
870 /* Enumerate domain groups */
872 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
873 TALLOC_CTX *mem_ctx,
874 int argc, const char **argv)
876 struct policy_handle connect_pol, domain_pol;
877 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
878 uint32 start_idx, num_dom_groups, i;
879 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
880 struct samr_SamArray *dom_groups = NULL;
881 uint32_t size = 0xffff;
883 if ((argc < 1) || (argc > 3)) {
884 printf("Usage: %s [access_mask] [max_size]\n", argv[0]);
885 return NT_STATUS_OK;
888 if (argc > 1) {
889 sscanf(argv[1], "%x", &access_mask);
892 if (argc > 2) {
893 sscanf(argv[2], "%x", &size);
896 /* Get sam policy handle */
898 result = rpccli_try_samr_connects(cli, mem_ctx,
899 MAXIMUM_ALLOWED_ACCESS,
900 &connect_pol);
902 if (!NT_STATUS_IS_OK(result))
903 goto done;
905 /* Get domain policy handle */
907 result = get_domain_handle(cli, mem_ctx, "domain",
908 &connect_pol,
909 access_mask,
910 &domain_sid,
911 &domain_pol);
912 if (!NT_STATUS_IS_OK(result))
913 goto done;
915 /* Enumerate domain groups */
917 start_idx = 0;
919 do {
920 result = rpccli_samr_EnumDomainGroups(cli, mem_ctx,
921 &domain_pol,
922 &start_idx,
923 &dom_groups,
924 size,
925 &num_dom_groups);
926 if (NT_STATUS_IS_OK(result) ||
927 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
929 for (i = 0; i < num_dom_groups; i++)
930 printf("group:[%s] rid:[0x%x]\n",
931 dom_groups->entries[i].name.string,
932 dom_groups->entries[i].idx);
935 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
937 done:
938 if (is_valid_policy_hnd(&domain_pol))
939 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
941 if (is_valid_policy_hnd(&connect_pol))
942 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
944 return result;
947 /* Enumerate alias groups */
949 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
950 TALLOC_CTX *mem_ctx,
951 int argc, const char **argv)
953 struct policy_handle connect_pol, domain_pol;
954 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
955 uint32 start_idx, num_als_groups, i;
956 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
957 struct samr_SamArray *als_groups = NULL;
958 uint32_t size = 0xffff;
960 if ((argc < 2) || (argc > 4)) {
961 printf("Usage: %s builtin|domain [access mask] [max_size]\n", argv[0]);
962 return NT_STATUS_OK;
965 if (argc > 2) {
966 sscanf(argv[2], "%x", &access_mask);
969 if (argc > 3) {
970 sscanf(argv[3], "%x", &size);
973 /* Get sam policy handle */
975 result = rpccli_try_samr_connects(cli, mem_ctx,
976 MAXIMUM_ALLOWED_ACCESS,
977 &connect_pol);
979 if (!NT_STATUS_IS_OK(result))
980 goto done;
982 /* Get domain policy handle */
984 result = get_domain_handle(cli, mem_ctx, argv[1],
985 &connect_pol,
986 access_mask,
987 &domain_sid,
988 &domain_pol);
990 if (!NT_STATUS_IS_OK(result))
991 goto done;
993 /* Enumerate alias groups */
995 start_idx = 0;
997 do {
998 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx,
999 &domain_pol,
1000 &start_idx,
1001 &als_groups,
1002 size,
1003 &num_als_groups);
1005 if (NT_STATUS_IS_OK(result) ||
1006 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1008 for (i = 0; i < num_als_groups; i++)
1009 printf("group:[%s] rid:[0x%x]\n",
1010 als_groups->entries[i].name.string,
1011 als_groups->entries[i].idx);
1013 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1015 done:
1016 if (is_valid_policy_hnd(&domain_pol))
1017 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1019 if (is_valid_policy_hnd(&connect_pol))
1020 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1022 return result;
1025 /* Enumerate domains */
1027 static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
1028 TALLOC_CTX *mem_ctx,
1029 int argc, const char **argv)
1031 struct policy_handle connect_pol;
1032 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1033 uint32 start_idx, size, num_entries, i;
1034 uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1035 struct samr_SamArray *sam = NULL;
1037 if ((argc < 1) || (argc > 2)) {
1038 printf("Usage: %s [access mask]\n", argv[0]);
1039 return NT_STATUS_OK;
1042 if (argc > 1) {
1043 sscanf(argv[1], "%x", &access_mask);
1046 /* Get sam policy handle */
1048 result = rpccli_try_samr_connects(cli, mem_ctx,
1049 access_mask,
1050 &connect_pol);
1052 if (!NT_STATUS_IS_OK(result)) {
1053 goto done;
1056 /* Enumerate alias groups */
1058 start_idx = 0;
1059 size = 0xffff;
1061 do {
1062 result = rpccli_samr_EnumDomains(cli, mem_ctx,
1063 &connect_pol,
1064 &start_idx,
1065 &sam,
1066 size,
1067 &num_entries);
1069 if (NT_STATUS_IS_OK(result) ||
1070 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1072 for (i = 0; i < num_entries; i++)
1073 printf("name:[%s] idx:[0x%x]\n",
1074 sam->entries[i].name.string,
1075 sam->entries[i].idx);
1077 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1079 done:
1080 if (is_valid_policy_hnd(&connect_pol)) {
1081 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1084 return result;
1088 /* Query alias membership */
1090 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1091 TALLOC_CTX *mem_ctx,
1092 int argc, const char **argv)
1094 struct policy_handle connect_pol, domain_pol, alias_pol;
1095 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1096 uint32 alias_rid, i;
1097 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1098 struct lsa_SidArray sid_array;
1100 if ((argc < 3) || (argc > 4)) {
1101 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1102 return NT_STATUS_OK;
1105 sscanf(argv[2], "%i", &alias_rid);
1107 if (argc > 3)
1108 sscanf(argv[3], "%x", &access_mask);
1110 /* Open SAMR handle */
1112 result = rpccli_try_samr_connects(cli, mem_ctx,
1113 MAXIMUM_ALLOWED_ACCESS,
1114 &connect_pol);
1116 if (!NT_STATUS_IS_OK(result))
1117 goto done;
1119 /* Open handle on domain */
1121 result = get_domain_handle(cli, mem_ctx, argv[1],
1122 &connect_pol,
1123 MAXIMUM_ALLOWED_ACCESS,
1124 &domain_sid,
1125 &domain_pol);
1127 if (!NT_STATUS_IS_OK(result))
1128 goto done;
1130 /* Open handle on alias */
1132 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1133 &domain_pol,
1134 access_mask,
1135 alias_rid,
1136 &alias_pol);
1137 if (!NT_STATUS_IS_OK(result))
1138 goto done;
1140 result = rpccli_samr_GetMembersInAlias(cli, mem_ctx,
1141 &alias_pol,
1142 &sid_array);
1144 if (!NT_STATUS_IS_OK(result))
1145 goto done;
1147 for (i = 0; i < sid_array.num_sids; i++) {
1148 fstring sid_str;
1150 sid_to_fstring(sid_str, sid_array.sids[i].sid);
1151 printf("\tsid:[%s]\n", sid_str);
1154 rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1155 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1156 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1157 done:
1158 return result;
1161 /* Query alias info */
1163 static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
1164 TALLOC_CTX *mem_ctx,
1165 int argc, const char **argv)
1167 struct policy_handle connect_pol, domain_pol, alias_pol;
1168 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1169 uint32_t alias_rid;
1170 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1171 union samr_AliasInfo *info = NULL;
1172 enum samr_AliasInfoEnum level = ALIASINFOALL;
1174 if ((argc < 3) || (argc > 4)) {
1175 printf("Usage: %s builtin|domain rid [level] [access mask]\n",
1176 argv[0]);
1177 return NT_STATUS_OK;
1180 sscanf(argv[2], "%i", &alias_rid);
1182 if (argc > 2) {
1183 level = atoi(argv[3]);
1186 if (argc > 3) {
1187 sscanf(argv[4], "%x", &access_mask);
1190 /* Open SAMR handle */
1192 result = rpccli_try_samr_connects(cli, mem_ctx,
1193 SEC_FLAG_MAXIMUM_ALLOWED,
1194 &connect_pol);
1196 if (!NT_STATUS_IS_OK(result)) {
1197 goto done;
1200 /* Open handle on domain */
1202 result = get_domain_handle(cli, mem_ctx, argv[1],
1203 &connect_pol,
1204 SEC_FLAG_MAXIMUM_ALLOWED,
1205 &domain_sid,
1206 &domain_pol);
1208 if (!NT_STATUS_IS_OK(result)) {
1209 goto done;
1212 /* Open handle on alias */
1214 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1215 &domain_pol,
1216 access_mask,
1217 alias_rid,
1218 &alias_pol);
1219 if (!NT_STATUS_IS_OK(result)) {
1220 goto done;
1223 result = rpccli_samr_QueryAliasInfo(cli, mem_ctx,
1224 &alias_pol,
1225 level,
1226 &info);
1228 if (!NT_STATUS_IS_OK(result)) {
1229 goto done;
1232 switch (level) {
1233 case ALIASINFOALL:
1234 printf("Name: %s\n", info->all.name.string);
1235 printf("Description: %s\n", info->all.description.string);
1236 printf("Num Members: %d\n", info->all.num_members);
1237 break;
1238 case ALIASINFONAME:
1239 printf("Name: %s\n", info->name.string);
1240 break;
1241 case ALIASINFODESCRIPTION:
1242 printf("Description: %s\n", info->description.string);
1243 break;
1244 default:
1245 break;
1248 rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1249 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1250 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1251 done:
1252 return result;
1256 /* Query delete an alias membership */
1258 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1259 TALLOC_CTX *mem_ctx,
1260 int argc, const char **argv)
1262 struct policy_handle connect_pol, domain_pol, alias_pol;
1263 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1264 uint32 alias_rid;
1265 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1267 if (argc != 3) {
1268 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1269 return NT_STATUS_OK;
1272 alias_rid = strtoul(argv[2], NULL, 10);
1274 /* Open SAMR handle */
1276 result = rpccli_try_samr_connects(cli, mem_ctx,
1277 MAXIMUM_ALLOWED_ACCESS,
1278 &connect_pol);
1280 if (!NT_STATUS_IS_OK(result))
1281 goto done;
1283 /* Open handle on domain */
1285 result = get_domain_handle(cli, mem_ctx, argv[1],
1286 &connect_pol,
1287 MAXIMUM_ALLOWED_ACCESS,
1288 &domain_sid,
1289 &domain_pol);
1291 if (!NT_STATUS_IS_OK(result))
1292 goto done;
1294 /* Open handle on alias */
1296 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1297 &domain_pol,
1298 access_mask,
1299 alias_rid,
1300 &alias_pol);
1301 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1302 /* Probably this was a user name, try lookupnames */
1303 struct samr_Ids rids, types;
1304 struct lsa_String lsa_acct_name;
1306 init_lsa_String(&lsa_acct_name, argv[2]);
1308 result = rpccli_samr_LookupNames(cli, mem_ctx,
1309 &domain_pol,
1311 &lsa_acct_name,
1312 &rids,
1313 &types);
1315 if (NT_STATUS_IS_OK(result)) {
1316 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1317 &domain_pol,
1318 access_mask,
1319 rids.ids[0],
1320 &alias_pol);
1324 result = rpccli_samr_DeleteDomAlias(cli, mem_ctx,
1325 &alias_pol);
1327 if (!NT_STATUS_IS_OK(result))
1328 goto done;
1330 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1331 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1332 done:
1333 return result;
1336 /* Query display info */
1338 static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli,
1339 TALLOC_CTX *mem_ctx,
1340 int argc, const char **argv,
1341 uint32_t opcode)
1343 struct policy_handle connect_pol, domain_pol;
1344 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1345 uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
1346 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1347 uint32 info_level = 1;
1348 union samr_DispInfo info;
1349 int loop_count = 0;
1350 bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1351 uint32_t total_size, returned_size;
1353 if (argc > 6) {
1354 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1355 return NT_STATUS_OK;
1358 if (argc >= 2)
1359 sscanf(argv[1], "%i", &info_level);
1361 if (argc >= 3)
1362 sscanf(argv[2], "%i", &start_idx);
1364 if (argc >= 4) {
1365 sscanf(argv[3], "%i", &max_entries);
1366 got_params = True;
1369 if (argc >= 5) {
1370 sscanf(argv[4], "%i", &max_size);
1371 got_params = True;
1374 if (argc >= 6)
1375 sscanf(argv[5], "%x", &access_mask);
1377 /* Get sam policy handle */
1379 result = rpccli_try_samr_connects(cli, mem_ctx,
1380 MAXIMUM_ALLOWED_ACCESS,
1381 &connect_pol);
1383 if (!NT_STATUS_IS_OK(result))
1384 goto done;
1386 /* Get domain policy handle */
1388 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1389 &connect_pol,
1390 access_mask,
1391 &domain_sid,
1392 &domain_pol);
1394 if (!NT_STATUS_IS_OK(result))
1395 goto done;
1397 /* Query display info */
1399 do {
1401 if (!got_params)
1402 get_query_dispinfo_params(
1403 loop_count, &max_entries, &max_size);
1405 switch (opcode) {
1406 case NDR_SAMR_QUERYDISPLAYINFO:
1407 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
1408 &domain_pol,
1409 info_level,
1410 start_idx,
1411 max_entries,
1412 max_size,
1413 &total_size,
1414 &returned_size,
1415 &info);
1416 break;
1417 case NDR_SAMR_QUERYDISPLAYINFO2:
1418 result = rpccli_samr_QueryDisplayInfo2(cli, mem_ctx,
1419 &domain_pol,
1420 info_level,
1421 start_idx,
1422 max_entries,
1423 max_size,
1424 &total_size,
1425 &returned_size,
1426 &info);
1428 break;
1429 case NDR_SAMR_QUERYDISPLAYINFO3:
1430 result = rpccli_samr_QueryDisplayInfo3(cli, mem_ctx,
1431 &domain_pol,
1432 info_level,
1433 start_idx,
1434 max_entries,
1435 max_size,
1436 &total_size,
1437 &returned_size,
1438 &info);
1440 break;
1441 default:
1442 return NT_STATUS_INVALID_PARAMETER;
1445 if (!NT_STATUS_IS_OK(result) &&
1446 !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
1447 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1448 break;
1451 loop_count++;
1453 switch (info_level) {
1454 case 1:
1455 num_entries = info.info1.count;
1456 break;
1457 case 2:
1458 num_entries = info.info2.count;
1459 break;
1460 case 3:
1461 num_entries = info.info3.count;
1462 break;
1463 case 4:
1464 num_entries = info.info4.count;
1465 break;
1466 case 5:
1467 num_entries = info.info5.count;
1468 break;
1469 default:
1470 break;
1473 start_idx += num_entries;
1475 if (num_entries == 0)
1476 break;
1478 for (i = 0; i < num_entries; i++) {
1479 switch (info_level) {
1480 case 1:
1481 display_sam_info_1(&info.info1.entries[i]);
1482 break;
1483 case 2:
1484 display_sam_info_2(&info.info2.entries[i]);
1485 break;
1486 case 3:
1487 display_sam_info_3(&info.info3.entries[i]);
1488 break;
1489 case 4:
1490 display_sam_info_4(&info.info4.entries[i]);
1491 break;
1492 case 5:
1493 display_sam_info_5(&info.info5.entries[i]);
1494 break;
1497 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1499 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1500 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1501 done:
1502 return result;
1505 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1506 TALLOC_CTX *mem_ctx,
1507 int argc, const char **argv)
1509 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1510 NDR_SAMR_QUERYDISPLAYINFO);
1513 static NTSTATUS cmd_samr_query_dispinfo2(struct rpc_pipe_client *cli,
1514 TALLOC_CTX *mem_ctx,
1515 int argc, const char **argv)
1517 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1518 NDR_SAMR_QUERYDISPLAYINFO2);
1521 static NTSTATUS cmd_samr_query_dispinfo3(struct rpc_pipe_client *cli,
1522 TALLOC_CTX *mem_ctx,
1523 int argc, const char **argv)
1525 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1526 NDR_SAMR_QUERYDISPLAYINFO3);
1529 /* Query domain info */
1531 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1532 TALLOC_CTX *mem_ctx,
1533 int argc, const char **argv)
1535 struct policy_handle connect_pol, domain_pol;
1536 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1537 uint32 switch_level = 2;
1538 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1539 union samr_DomainInfo *info = NULL;
1541 if (argc > 3) {
1542 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1543 return NT_STATUS_OK;
1546 if (argc > 1)
1547 sscanf(argv[1], "%i", &switch_level);
1549 if (argc > 2)
1550 sscanf(argv[2], "%x", &access_mask);
1552 /* Get sam policy handle */
1554 result = rpccli_try_samr_connects(cli, mem_ctx,
1555 MAXIMUM_ALLOWED_ACCESS,
1556 &connect_pol);
1558 if (!NT_STATUS_IS_OK(result))
1559 goto done;
1561 /* Get domain policy handle */
1563 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1564 &connect_pol,
1565 access_mask,
1566 &domain_sid,
1567 &domain_pol);
1569 if (!NT_STATUS_IS_OK(result))
1570 goto done;
1572 /* Query domain info */
1574 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1575 &domain_pol,
1576 switch_level,
1577 &info);
1579 if (!NT_STATUS_IS_OK(result))
1580 goto done;
1582 /* Display domain info */
1584 switch (switch_level) {
1585 case 1:
1586 display_sam_dom_info_1(&info->info1);
1587 break;
1588 case 2:
1589 display_sam_dom_info_2(&info->general);
1590 break;
1591 case 3:
1592 display_sam_dom_info_3(&info->info3);
1593 break;
1594 case 4:
1595 display_sam_dom_info_4(&info->oem);
1596 break;
1597 case 5:
1598 display_sam_dom_info_5(&info->info5);
1599 break;
1600 case 6:
1601 display_sam_dom_info_6(&info->info6);
1602 break;
1603 case 7:
1604 display_sam_dom_info_7(&info->info7);
1605 break;
1606 case 8:
1607 display_sam_dom_info_8(&info->info8);
1608 break;
1609 case 9:
1610 display_sam_dom_info_9(&info->info9);
1611 break;
1612 case 12:
1613 display_sam_dom_info_12(&info->info12);
1614 break;
1615 case 13:
1616 display_sam_dom_info_13(&info->info13);
1617 break;
1619 default:
1620 printf("cannot display domain info for switch value %d\n",
1621 switch_level);
1622 break;
1625 done:
1627 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1628 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1629 return result;
1632 /* Create domain user */
1634 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1635 TALLOC_CTX *mem_ctx,
1636 int argc, const char **argv)
1638 struct policy_handle connect_pol, domain_pol, user_pol;
1639 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1640 struct lsa_String acct_name;
1641 uint32 acb_info;
1642 uint32 acct_flags, user_rid;
1643 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1644 uint32_t access_granted = 0;
1646 if ((argc < 2) || (argc > 3)) {
1647 printf("Usage: %s username [access mask]\n", argv[0]);
1648 return NT_STATUS_OK;
1651 init_lsa_String(&acct_name, argv[1]);
1653 if (argc > 2)
1654 sscanf(argv[2], "%x", &access_mask);
1656 /* Get sam policy handle */
1658 result = rpccli_try_samr_connects(cli, mem_ctx,
1659 MAXIMUM_ALLOWED_ACCESS,
1660 &connect_pol);
1662 if (!NT_STATUS_IS_OK(result))
1663 goto done;
1665 /* Get domain policy handle */
1667 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1668 &connect_pol,
1669 access_mask,
1670 &domain_sid,
1671 &domain_pol);
1673 if (!NT_STATUS_IS_OK(result))
1674 goto done;
1676 /* Create domain user */
1678 acb_info = ACB_NORMAL;
1679 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1680 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1681 SAMR_USER_ACCESS_SET_PASSWORD |
1682 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1683 SAMR_USER_ACCESS_SET_ATTRIBUTES;
1685 result = rpccli_samr_CreateUser2(cli, mem_ctx,
1686 &domain_pol,
1687 &acct_name,
1688 acb_info,
1689 acct_flags,
1690 &user_pol,
1691 &access_granted,
1692 &user_rid);
1694 if (!NT_STATUS_IS_OK(result))
1695 goto done;
1697 result = rpccli_samr_Close(cli, mem_ctx, &user_pol);
1698 if (!NT_STATUS_IS_OK(result)) goto done;
1700 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1701 if (!NT_STATUS_IS_OK(result)) goto done;
1703 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1704 if (!NT_STATUS_IS_OK(result)) goto done;
1706 done:
1707 return result;
1710 /* Create domain group */
1712 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1713 TALLOC_CTX *mem_ctx,
1714 int argc, const char **argv)
1716 struct policy_handle connect_pol, domain_pol, group_pol;
1717 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1718 struct lsa_String grp_name;
1719 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1720 uint32_t rid = 0;
1722 if ((argc < 2) || (argc > 3)) {
1723 printf("Usage: %s groupname [access mask]\n", argv[0]);
1724 return NT_STATUS_OK;
1727 init_lsa_String(&grp_name, argv[1]);
1729 if (argc > 2)
1730 sscanf(argv[2], "%x", &access_mask);
1732 /* Get sam policy handle */
1734 result = rpccli_try_samr_connects(cli, mem_ctx,
1735 MAXIMUM_ALLOWED_ACCESS,
1736 &connect_pol);
1738 if (!NT_STATUS_IS_OK(result))
1739 goto done;
1741 /* Get domain policy handle */
1743 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1744 &connect_pol,
1745 access_mask,
1746 &domain_sid,
1747 &domain_pol);
1749 if (!NT_STATUS_IS_OK(result))
1750 goto done;
1752 /* Create domain user */
1753 result = rpccli_samr_CreateDomainGroup(cli, mem_ctx,
1754 &domain_pol,
1755 &grp_name,
1756 MAXIMUM_ALLOWED_ACCESS,
1757 &group_pol,
1758 &rid);
1760 if (!NT_STATUS_IS_OK(result))
1761 goto done;
1763 result = rpccli_samr_Close(cli, mem_ctx, &group_pol);
1764 if (!NT_STATUS_IS_OK(result)) goto done;
1766 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1767 if (!NT_STATUS_IS_OK(result)) goto done;
1769 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1770 if (!NT_STATUS_IS_OK(result)) goto done;
1772 done:
1773 return result;
1776 /* Create domain alias */
1778 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1779 TALLOC_CTX *mem_ctx,
1780 int argc, const char **argv)
1782 struct policy_handle connect_pol, domain_pol, alias_pol;
1783 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1784 struct lsa_String alias_name;
1785 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1786 uint32_t rid = 0;
1788 if ((argc < 2) || (argc > 3)) {
1789 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1790 return NT_STATUS_OK;
1793 init_lsa_String(&alias_name, argv[1]);
1795 if (argc > 2)
1796 sscanf(argv[2], "%x", &access_mask);
1798 /* Get sam policy handle */
1800 result = rpccli_try_samr_connects(cli, mem_ctx,
1801 MAXIMUM_ALLOWED_ACCESS,
1802 &connect_pol);
1804 if (!NT_STATUS_IS_OK(result))
1805 goto done;
1807 /* Get domain policy handle */
1809 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1810 &connect_pol,
1811 access_mask,
1812 &domain_sid,
1813 &domain_pol);
1815 if (!NT_STATUS_IS_OK(result))
1816 goto done;
1818 /* Create domain user */
1820 result = rpccli_samr_CreateDomAlias(cli, mem_ctx,
1821 &domain_pol,
1822 &alias_name,
1823 MAXIMUM_ALLOWED_ACCESS,
1824 &alias_pol,
1825 &rid);
1827 if (!NT_STATUS_IS_OK(result))
1828 goto done;
1830 result = rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1831 if (!NT_STATUS_IS_OK(result)) goto done;
1833 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1834 if (!NT_STATUS_IS_OK(result)) goto done;
1836 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1837 if (!NT_STATUS_IS_OK(result)) goto done;
1839 done:
1840 return result;
1843 /* Lookup sam names */
1845 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
1846 TALLOC_CTX *mem_ctx,
1847 int argc, const char **argv)
1849 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1850 struct policy_handle connect_pol, domain_pol;
1851 uint32 num_names;
1852 struct samr_Ids rids, name_types;
1853 int i;
1854 struct lsa_String *names = NULL;;
1856 if (argc < 3) {
1857 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1858 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1859 printf("or check on the builtin SID: S-1-5-32\n");
1860 return NT_STATUS_OK;
1863 /* Get sam policy and domain handles */
1865 result = rpccli_try_samr_connects(cli, mem_ctx,
1866 MAXIMUM_ALLOWED_ACCESS,
1867 &connect_pol);
1869 if (!NT_STATUS_IS_OK(result))
1870 goto done;
1872 result = get_domain_handle(cli, mem_ctx, argv[1],
1873 &connect_pol,
1874 MAXIMUM_ALLOWED_ACCESS,
1875 &domain_sid,
1876 &domain_pol);
1878 if (!NT_STATUS_IS_OK(result))
1879 goto done;
1881 /* Look up names */
1883 num_names = argc - 2;
1885 if ((names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names)) == NULL) {
1886 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1887 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1888 result = NT_STATUS_NO_MEMORY;
1889 goto done;
1892 for (i = 0; i < num_names; i++) {
1893 init_lsa_String(&names[i], argv[i + 2]);
1896 result = rpccli_samr_LookupNames(cli, mem_ctx,
1897 &domain_pol,
1898 num_names,
1899 names,
1900 &rids,
1901 &name_types);
1903 if (!NT_STATUS_IS_OK(result))
1904 goto done;
1906 /* Display results */
1908 for (i = 0; i < num_names; i++)
1909 printf("name %s: 0x%x (%d)\n", names[i].string, rids.ids[i],
1910 name_types.ids[i]);
1912 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1913 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1914 done:
1915 return result;
1918 /* Lookup sam rids */
1920 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
1921 TALLOC_CTX *mem_ctx,
1922 int argc, const char **argv)
1924 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1925 struct policy_handle connect_pol, domain_pol;
1926 uint32_t num_rids, *rids;
1927 struct lsa_Strings names;
1928 struct samr_Ids types;
1930 int i;
1932 if (argc < 3) {
1933 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1934 return NT_STATUS_OK;
1937 /* Get sam policy and domain handles */
1939 result = rpccli_try_samr_connects(cli, mem_ctx,
1940 MAXIMUM_ALLOWED_ACCESS,
1941 &connect_pol);
1943 if (!NT_STATUS_IS_OK(result))
1944 goto done;
1946 result = get_domain_handle(cli, mem_ctx, argv[1],
1947 &connect_pol,
1948 MAXIMUM_ALLOWED_ACCESS,
1949 &domain_sid,
1950 &domain_pol);
1952 if (!NT_STATUS_IS_OK(result))
1953 goto done;
1955 /* Look up rids */
1957 num_rids = argc - 2;
1959 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1960 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1961 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1962 result = NT_STATUS_NO_MEMORY;
1963 goto done;
1966 for (i = 0; i < argc - 2; i++)
1967 sscanf(argv[i + 2], "%i", &rids[i]);
1969 result = rpccli_samr_LookupRids(cli, mem_ctx,
1970 &domain_pol,
1971 num_rids,
1972 rids,
1973 &names,
1974 &types);
1976 if (!NT_STATUS_IS_OK(result) &&
1977 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1978 goto done;
1980 /* Display results */
1982 for (i = 0; i < num_rids; i++) {
1983 printf("rid 0x%x: %s (%d)\n",
1984 rids[i], names.names[i].string, types.ids[i]);
1987 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1988 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1989 done:
1990 return result;
1993 /* Delete domain group */
1995 static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
1996 TALLOC_CTX *mem_ctx,
1997 int argc, const char **argv)
1999 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2000 struct policy_handle connect_pol, domain_pol, group_pol;
2001 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2003 if ((argc < 2) || (argc > 3)) {
2004 printf("Usage: %s groupname\n", argv[0]);
2005 return NT_STATUS_OK;
2008 if (argc > 2)
2009 sscanf(argv[2], "%x", &access_mask);
2011 /* Get sam policy and domain handles */
2013 result = rpccli_try_samr_connects(cli, mem_ctx,
2014 MAXIMUM_ALLOWED_ACCESS,
2015 &connect_pol);
2017 if (!NT_STATUS_IS_OK(result))
2018 goto done;
2020 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2021 &connect_pol,
2022 MAXIMUM_ALLOWED_ACCESS,
2023 &domain_sid,
2024 &domain_pol);
2026 if (!NT_STATUS_IS_OK(result))
2027 goto done;
2029 /* Get handle on group */
2032 struct samr_Ids group_rids, name_types;
2033 struct lsa_String lsa_acct_name;
2035 init_lsa_String(&lsa_acct_name, argv[1]);
2037 result = rpccli_samr_LookupNames(cli, mem_ctx,
2038 &domain_pol,
2040 &lsa_acct_name,
2041 &group_rids,
2042 &name_types);
2043 if (!NT_STATUS_IS_OK(result))
2044 goto done;
2046 result = rpccli_samr_OpenGroup(cli, mem_ctx,
2047 &domain_pol,
2048 access_mask,
2049 group_rids.ids[0],
2050 &group_pol);
2052 if (!NT_STATUS_IS_OK(result))
2053 goto done;
2056 /* Delete group */
2058 result = rpccli_samr_DeleteDomainGroup(cli, mem_ctx,
2059 &group_pol);
2061 if (!NT_STATUS_IS_OK(result))
2062 goto done;
2064 /* Display results */
2066 rpccli_samr_Close(cli, mem_ctx, &group_pol);
2067 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2068 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2070 done:
2071 return result;
2074 /* Delete domain user */
2076 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
2077 TALLOC_CTX *mem_ctx,
2078 int argc, const char **argv)
2080 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2081 struct policy_handle connect_pol, domain_pol, user_pol;
2082 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2084 if ((argc < 2) || (argc > 3)) {
2085 printf("Usage: %s username\n", argv[0]);
2086 return NT_STATUS_OK;
2089 if (argc > 2)
2090 sscanf(argv[2], "%x", &access_mask);
2092 /* Get sam policy and domain handles */
2094 result = rpccli_try_samr_connects(cli, mem_ctx,
2095 MAXIMUM_ALLOWED_ACCESS,
2096 &connect_pol);
2098 if (!NT_STATUS_IS_OK(result))
2099 goto done;
2101 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2102 &connect_pol,
2103 MAXIMUM_ALLOWED_ACCESS,
2104 &domain_sid,
2105 &domain_pol);
2107 if (!NT_STATUS_IS_OK(result))
2108 goto done;
2110 /* Get handle on user */
2113 struct samr_Ids user_rids, name_types;
2114 struct lsa_String lsa_acct_name;
2116 init_lsa_String(&lsa_acct_name, argv[1]);
2118 result = rpccli_samr_LookupNames(cli, mem_ctx,
2119 &domain_pol,
2121 &lsa_acct_name,
2122 &user_rids,
2123 &name_types);
2125 if (!NT_STATUS_IS_OK(result))
2126 goto done;
2128 result = rpccli_samr_OpenUser(cli, mem_ctx,
2129 &domain_pol,
2130 access_mask,
2131 user_rids.ids[0],
2132 &user_pol);
2134 if (!NT_STATUS_IS_OK(result))
2135 goto done;
2138 /* Delete user */
2140 result = rpccli_samr_DeleteUser(cli, mem_ctx,
2141 &user_pol);
2143 if (!NT_STATUS_IS_OK(result))
2144 goto done;
2146 /* Display results */
2148 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2149 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2150 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2152 done:
2153 return result;
2156 /**********************************************************************
2157 * Query user security object
2159 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
2160 TALLOC_CTX *mem_ctx,
2161 int argc, const char **argv)
2163 struct policy_handle connect_pol, domain_pol, user_pol, *pol;
2164 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2165 uint32 sec_info = SECINFO_DACL;
2166 uint32 user_rid = 0;
2167 TALLOC_CTX *ctx = NULL;
2168 struct sec_desc_buf *sec_desc_buf=NULL;
2169 bool domain = False;
2171 ctx=talloc_init("cmd_samr_query_sec_obj");
2173 if ((argc < 1) || (argc > 3)) {
2174 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2175 printf("\tSpecify rid for security on user, -d for security on domain\n");
2176 talloc_destroy(ctx);
2177 return NT_STATUS_OK;
2180 if (argc > 1) {
2181 if (strcmp(argv[1], "-d") == 0)
2182 domain = True;
2183 else
2184 sscanf(argv[1], "%i", &user_rid);
2187 if (argc == 3) {
2188 sec_info = atoi(argv[2]);
2191 result = rpccli_try_samr_connects(cli, mem_ctx,
2192 MAXIMUM_ALLOWED_ACCESS,
2193 &connect_pol);
2195 if (!NT_STATUS_IS_OK(result))
2196 goto done;
2198 if (domain || user_rid)
2199 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2200 &connect_pol,
2201 MAXIMUM_ALLOWED_ACCESS,
2202 &domain_sid,
2203 &domain_pol);
2205 if (!NT_STATUS_IS_OK(result))
2206 goto done;
2208 if (user_rid)
2209 result = rpccli_samr_OpenUser(cli, mem_ctx,
2210 &domain_pol,
2211 MAXIMUM_ALLOWED_ACCESS,
2212 user_rid,
2213 &user_pol);
2215 if (!NT_STATUS_IS_OK(result))
2216 goto done;
2218 /* Pick which query pol to use */
2220 pol = &connect_pol;
2222 if (domain)
2223 pol = &domain_pol;
2225 if (user_rid)
2226 pol = &user_pol;
2228 /* Query SAM security object */
2230 result = rpccli_samr_QuerySecurity(cli, mem_ctx,
2231 pol,
2232 sec_info,
2233 &sec_desc_buf);
2235 if (!NT_STATUS_IS_OK(result))
2236 goto done;
2238 display_sec_desc(sec_desc_buf->sd);
2240 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2241 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2242 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2243 done:
2244 talloc_destroy(ctx);
2245 return result;
2248 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
2249 TALLOC_CTX *mem_ctx,
2250 int argc, const char **argv)
2252 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2253 struct policy_handle connect_pol, domain_pol, user_pol;
2254 struct samr_PwInfo info;
2255 uint32_t rid;
2257 if (argc != 2) {
2258 printf("Usage: %s rid\n", argv[0]);
2259 return NT_STATUS_OK;
2262 sscanf(argv[1], "%i", &rid);
2264 result = rpccli_try_samr_connects(cli, mem_ctx,
2265 MAXIMUM_ALLOWED_ACCESS,
2266 &connect_pol);
2268 if (!NT_STATUS_IS_OK(result)) {
2269 goto done;
2272 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2273 &connect_pol,
2274 MAXIMUM_ALLOWED_ACCESS,
2275 &domain_sid,
2276 &domain_pol);
2278 if (!NT_STATUS_IS_OK(result)) {
2279 goto done;
2282 result = rpccli_samr_OpenUser(cli, mem_ctx,
2283 &domain_pol,
2284 MAXIMUM_ALLOWED_ACCESS,
2285 rid,
2286 &user_pol);
2288 if (!NT_STATUS_IS_OK(result)) {
2289 goto done;
2292 result = rpccli_samr_GetUserPwInfo(cli, mem_ctx, &user_pol, &info);
2293 if (NT_STATUS_IS_OK(result)) {
2294 printf("min_password_length: %d\n", info.min_password_length);
2295 printf("%s\n",
2296 NDR_PRINT_STRUCT_STRING(mem_ctx,
2297 samr_PasswordProperties, &info.password_properties));
2300 done:
2301 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2302 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2303 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2305 return result;
2308 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2309 TALLOC_CTX *mem_ctx,
2310 int argc, const char **argv)
2312 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2313 struct lsa_String domain_name;
2314 struct samr_PwInfo info;
2316 if (argc < 1 || argc > 3) {
2317 printf("Usage: %s <domain>\n", argv[0]);
2318 return NT_STATUS_OK;
2321 init_lsa_String(&domain_name, argv[1]);
2323 result = rpccli_samr_GetDomPwInfo(cli, mem_ctx, &domain_name, &info);
2325 if (NT_STATUS_IS_OK(result)) {
2326 printf("min_password_length: %d\n", info.min_password_length);
2327 display_password_properties(info.password_properties);
2330 return result;
2333 /* Look up domain name */
2335 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
2336 TALLOC_CTX *mem_ctx,
2337 int argc, const char **argv)
2339 struct policy_handle connect_pol, domain_pol;
2340 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2341 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2342 fstring sid_string;
2343 struct lsa_String domain_name;
2344 struct dom_sid *sid = NULL;
2346 if (argc != 2) {
2347 printf("Usage: %s domain_name\n", argv[0]);
2348 return NT_STATUS_OK;
2351 init_lsa_String(&domain_name, argv[1]);
2353 result = rpccli_try_samr_connects(cli, mem_ctx,
2354 access_mask,
2355 &connect_pol);
2357 if (!NT_STATUS_IS_OK(result))
2358 goto done;
2360 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2361 &connect_pol,
2362 access_mask,
2363 &domain_sid,
2364 &domain_pol);
2366 if (!NT_STATUS_IS_OK(result))
2367 goto done;
2369 result = rpccli_samr_LookupDomain(cli, mem_ctx,
2370 &connect_pol,
2371 &domain_name,
2372 &sid);
2374 if (NT_STATUS_IS_OK(result)) {
2375 sid_to_fstring(sid_string, sid);
2376 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2377 argv[1], sid_string);
2380 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2381 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2382 done:
2383 return result;
2386 /* Change user password */
2388 static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli,
2389 TALLOC_CTX *mem_ctx,
2390 int argc, const char **argv)
2392 struct policy_handle connect_pol, domain_pol, user_pol;
2393 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2394 const char *user, *oldpass, *newpass;
2395 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2396 struct samr_Ids rids, types;
2397 struct lsa_String lsa_acct_name;
2399 if (argc < 3) {
2400 printf("Usage: %s username oldpass newpass\n", argv[0]);
2401 return NT_STATUS_INVALID_PARAMETER;
2404 user = argv[1];
2405 oldpass = argv[2];
2406 newpass = argv[3];
2408 /* Get sam policy handle */
2410 result = rpccli_try_samr_connects(cli, mem_ctx,
2411 MAXIMUM_ALLOWED_ACCESS,
2412 &connect_pol);
2414 if (!NT_STATUS_IS_OK(result)) {
2415 goto done;
2418 /* Get domain policy handle */
2420 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2421 &connect_pol,
2422 access_mask,
2423 &domain_sid,
2424 &domain_pol);
2426 if (!NT_STATUS_IS_OK(result)) {
2427 goto done;
2430 init_lsa_String(&lsa_acct_name, user);
2432 result = rpccli_samr_LookupNames(cli, mem_ctx,
2433 &domain_pol,
2435 &lsa_acct_name,
2436 &rids,
2437 &types);
2439 if (!NT_STATUS_IS_OK(result)) {
2440 goto done;
2443 result = rpccli_samr_OpenUser(cli, mem_ctx,
2444 &domain_pol,
2445 access_mask,
2446 rids.ids[0],
2447 &user_pol);
2449 if (!NT_STATUS_IS_OK(result)) {
2450 goto done;
2453 /* Change user password */
2454 result = rpccli_samr_chgpasswd_user(cli, mem_ctx,
2455 &user_pol,
2456 newpass,
2457 oldpass);
2459 if (!NT_STATUS_IS_OK(result)) {
2460 goto done;
2463 done:
2464 if (is_valid_policy_hnd(&user_pol)) {
2465 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2467 if (is_valid_policy_hnd(&domain_pol)) {
2468 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2470 if (is_valid_policy_hnd(&connect_pol)) {
2471 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2474 return result;
2478 /* Change user password */
2480 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2481 TALLOC_CTX *mem_ctx,
2482 int argc, const char **argv)
2484 struct policy_handle connect_pol, domain_pol;
2485 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2486 const char *user, *oldpass, *newpass;
2487 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2489 if (argc < 3) {
2490 printf("Usage: %s username oldpass newpass\n", argv[0]);
2491 return NT_STATUS_INVALID_PARAMETER;
2494 user = argv[1];
2495 oldpass = argv[2];
2496 newpass = argv[3];
2498 /* Get sam policy handle */
2500 result = rpccli_try_samr_connects(cli, mem_ctx,
2501 MAXIMUM_ALLOWED_ACCESS,
2502 &connect_pol);
2504 if (!NT_STATUS_IS_OK(result))
2505 goto done;
2507 /* Get domain policy handle */
2509 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2510 &connect_pol,
2511 access_mask,
2512 &domain_sid,
2513 &domain_pol);
2515 if (!NT_STATUS_IS_OK(result))
2516 goto done;
2518 /* Change user password */
2519 result = rpccli_samr_chgpasswd_user2(cli, mem_ctx, user, newpass, oldpass);
2521 if (!NT_STATUS_IS_OK(result))
2522 goto done;
2524 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2525 if (!NT_STATUS_IS_OK(result)) goto done;
2527 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2528 if (!NT_STATUS_IS_OK(result)) goto done;
2530 done:
2531 return result;
2535 /* Change user password */
2537 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
2538 TALLOC_CTX *mem_ctx,
2539 int argc, const char **argv)
2541 struct policy_handle connect_pol, domain_pol;
2542 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2543 const char *user, *oldpass, *newpass;
2544 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2545 struct samr_DomInfo1 *info = NULL;
2546 struct userPwdChangeFailureInformation *reject = NULL;
2548 if (argc < 3) {
2549 printf("Usage: %s username oldpass newpass\n", argv[0]);
2550 return NT_STATUS_INVALID_PARAMETER;
2553 user = argv[1];
2554 oldpass = argv[2];
2555 newpass = argv[3];
2557 /* Get sam policy handle */
2559 result = rpccli_try_samr_connects(cli, mem_ctx,
2560 MAXIMUM_ALLOWED_ACCESS,
2561 &connect_pol);
2563 if (!NT_STATUS_IS_OK(result))
2564 goto done;
2566 /* Get domain policy handle */
2568 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2569 &connect_pol,
2570 access_mask,
2571 &domain_sid,
2572 &domain_pol);
2574 if (!NT_STATUS_IS_OK(result))
2575 goto done;
2577 /* Change user password */
2578 result = rpccli_samr_chgpasswd_user3(cli, mem_ctx,
2579 user,
2580 newpass,
2581 oldpass,
2582 &info,
2583 &reject);
2585 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2587 display_sam_dom_info_1(info);
2589 switch (reject->extendedFailureReason) {
2590 case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT:
2591 d_printf("SAM_PWD_CHANGE_PASSWORD_TOO_SHORT\n");
2592 break;
2593 case SAM_PWD_CHANGE_PWD_IN_HISTORY:
2594 d_printf("SAM_PWD_CHANGE_PWD_IN_HISTORY\n");
2595 break;
2596 case SAM_PWD_CHANGE_NOT_COMPLEX:
2597 d_printf("SAM_PWD_CHANGE_NOT_COMPLEX\n");
2598 break;
2599 default:
2600 d_printf("unknown reject reason: %d\n",
2601 reject->extendedFailureReason);
2602 break;
2606 if (!NT_STATUS_IS_OK(result))
2607 goto done;
2609 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2610 if (!NT_STATUS_IS_OK(result)) goto done;
2612 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2613 if (!NT_STATUS_IS_OK(result)) goto done;
2615 done:
2616 return result;
2619 static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli,
2620 TALLOC_CTX *mem_ctx,
2621 int argc, const char **argv,
2622 int opcode)
2624 struct policy_handle connect_pol, domain_pol, user_pol;
2625 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2626 const char *user, *param;
2627 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2628 uint32_t level;
2629 uint32_t user_rid;
2630 union samr_UserInfo info;
2631 struct samr_CryptPassword pwd_buf;
2632 struct samr_CryptPasswordEx pwd_buf_ex;
2633 uint8_t nt_hash[16];
2634 uint8_t lm_hash[16];
2635 DATA_BLOB session_key;
2636 uint8_t password_expired = 0;
2638 if (argc < 4) {
2639 printf("Usage: %s username level password [password_expired]\n",
2640 argv[0]);
2641 return NT_STATUS_INVALID_PARAMETER;
2644 user = argv[1];
2645 level = atoi(argv[2]);
2646 param = argv[3];
2648 if (argc >= 5) {
2649 password_expired = atoi(argv[4]);
2652 status = cli_get_session_key(mem_ctx, cli, &session_key);
2653 if (!NT_STATUS_IS_OK(status)) {
2654 return status;
2657 init_samr_CryptPassword(param, &session_key, &pwd_buf);
2658 init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex);
2659 nt_lm_owf_gen(param, nt_hash, lm_hash);
2661 switch (level) {
2662 case 18:
2664 DATA_BLOB in,out;
2665 in = data_blob_const(nt_hash, 16);
2666 out = data_blob_talloc_zero(mem_ctx, 16);
2667 sess_crypt_blob(&out, &in, &session_key, true);
2668 memcpy(nt_hash, out.data, out.length);
2671 DATA_BLOB in,out;
2672 in = data_blob_const(lm_hash, 16);
2673 out = data_blob_talloc_zero(mem_ctx, 16);
2674 sess_crypt_blob(&out, &in, &session_key, true);
2675 memcpy(lm_hash, out.data, out.length);
2678 memcpy(info.info18.nt_pwd.hash, nt_hash, 16);
2679 memcpy(info.info18.lm_pwd.hash, lm_hash, 16);
2680 info.info18.nt_pwd_active = true;
2681 info.info18.lm_pwd_active = true;
2682 info.info18.password_expired = password_expired;
2684 break;
2685 case 21:
2686 ZERO_STRUCT(info.info21);
2688 info.info21.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
2689 SAMR_FIELD_LM_PASSWORD_PRESENT;
2690 if (argc >= 5) {
2691 info.info21.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
2692 info.info21.password_expired = password_expired;
2695 info.info21.lm_password_set = true;
2696 info.info21.lm_owf_password.length = 16;
2697 info.info21.lm_owf_password.size = 16;
2699 info.info21.nt_password_set = true;
2700 info.info21.nt_owf_password.length = 16;
2701 info.info21.nt_owf_password.size = 16;
2704 DATA_BLOB in,out;
2705 in = data_blob_const(nt_hash, 16);
2706 out = data_blob_talloc_zero(mem_ctx, 16);
2707 sess_crypt_blob(&out, &in, &session_key, true);
2708 info.info21.nt_owf_password.array =
2709 (uint16_t *)talloc_memdup(mem_ctx, out.data, 16);
2712 DATA_BLOB in,out;
2713 in = data_blob_const(lm_hash, 16);
2714 out = data_blob_talloc_zero(mem_ctx, 16);
2715 sess_crypt_blob(&out, &in, &session_key, true);
2716 info.info21.lm_owf_password.array =
2717 (uint16_t *)talloc_memdup(mem_ctx, out.data, 16);
2720 break;
2721 case 23:
2722 ZERO_STRUCT(info.info23);
2724 info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
2725 SAMR_FIELD_LM_PASSWORD_PRESENT;
2726 if (argc >= 5) {
2727 info.info23.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
2728 info.info23.info.password_expired = password_expired;
2731 info.info23.password = pwd_buf;
2733 break;
2734 case 24:
2735 info.info24.password = pwd_buf;
2736 info.info24.password_expired = password_expired;
2738 break;
2739 case 25:
2740 ZERO_STRUCT(info.info25);
2742 info.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
2743 SAMR_FIELD_LM_PASSWORD_PRESENT;
2744 if (argc >= 5) {
2745 info.info25.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
2746 info.info25.info.password_expired = password_expired;
2749 info.info25.password = pwd_buf_ex;
2751 break;
2752 case 26:
2753 info.info26.password = pwd_buf_ex;
2754 info.info26.password_expired = password_expired;
2756 break;
2757 default:
2758 return NT_STATUS_INVALID_INFO_CLASS;
2761 /* Get sam policy handle */
2763 status = rpccli_try_samr_connects(cli, mem_ctx,
2764 MAXIMUM_ALLOWED_ACCESS,
2765 &connect_pol);
2767 if (!NT_STATUS_IS_OK(status))
2768 goto done;
2770 /* Get domain policy handle */
2772 status = rpccli_samr_OpenDomain(cli, mem_ctx,
2773 &connect_pol,
2774 access_mask,
2775 &domain_sid,
2776 &domain_pol);
2778 if (!NT_STATUS_IS_OK(status))
2779 goto done;
2781 user_rid = strtol(user, NULL, 0);
2782 if (user_rid) {
2783 status = rpccli_samr_OpenUser(cli, mem_ctx,
2784 &domain_pol,
2785 access_mask,
2786 user_rid,
2787 &user_pol);
2790 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) ||
2791 (user_rid == 0)) {
2793 /* Probably this was a user name, try lookupnames */
2794 struct samr_Ids rids, types;
2795 struct lsa_String lsa_acct_name;
2797 init_lsa_String(&lsa_acct_name, user);
2799 status = rpccli_samr_LookupNames(cli, mem_ctx,
2800 &domain_pol,
2802 &lsa_acct_name,
2803 &rids,
2804 &types);
2805 if (!NT_STATUS_IS_OK(status)) {
2806 return status;
2809 status = rpccli_samr_OpenUser(cli, mem_ctx,
2810 &domain_pol,
2811 access_mask,
2812 rids.ids[0],
2813 &user_pol);
2814 if (!NT_STATUS_IS_OK(status)) {
2815 return status;
2819 switch (opcode) {
2820 case NDR_SAMR_SETUSERINFO:
2821 status = rpccli_samr_SetUserInfo(cli, mem_ctx,
2822 &user_pol,
2823 level,
2824 &info);
2825 break;
2826 case NDR_SAMR_SETUSERINFO2:
2827 status = rpccli_samr_SetUserInfo2(cli, mem_ctx,
2828 &user_pol,
2829 level,
2830 &info);
2831 break;
2832 default:
2833 return NT_STATUS_INVALID_PARAMETER;
2836 done:
2837 return status;
2840 static NTSTATUS cmd_samr_setuserinfo(struct rpc_pipe_client *cli,
2841 TALLOC_CTX *mem_ctx,
2842 int argc, const char **argv)
2844 return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
2845 NDR_SAMR_SETUSERINFO);
2848 static NTSTATUS cmd_samr_setuserinfo2(struct rpc_pipe_client *cli,
2849 TALLOC_CTX *mem_ctx,
2850 int argc, const char **argv)
2852 return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
2853 NDR_SAMR_SETUSERINFO2);
2856 static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
2857 TALLOC_CTX *mem_ctx,
2858 int argc, const char **argv)
2860 NTSTATUS status;
2861 struct policy_handle connect_handle;
2862 struct policy_handle domain_handle;
2863 uint16_t level = 1;
2864 struct lsa_String name;
2865 uint32_t idx = 0;
2867 if (argc < 2 || argc > 3) {
2868 printf("Usage: %s name level\n", argv[0]);
2869 return NT_STATUS_INVALID_PARAMETER;
2872 init_lsa_String(&name, argv[1]);
2874 if (argc == 3) {
2875 level = atoi(argv[2]);
2878 status = rpccli_try_samr_connects(cli, mem_ctx,
2879 SEC_FLAG_MAXIMUM_ALLOWED,
2880 &connect_handle);
2882 if (!NT_STATUS_IS_OK(status)) {
2883 goto done;
2886 status = rpccli_samr_OpenDomain(cli, mem_ctx,
2887 &connect_handle,
2888 SEC_FLAG_MAXIMUM_ALLOWED,
2889 &domain_sid,
2890 &domain_handle);
2892 if (!NT_STATUS_IS_OK(status))
2893 goto done;
2896 status = rpccli_samr_GetDisplayEnumerationIndex(cli, mem_ctx,
2897 &domain_handle,
2898 level,
2899 &name,
2900 &idx);
2902 if (NT_STATUS_IS_OK(status) ||
2903 NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
2904 printf("idx: %d (0x%08x)\n", idx, idx);
2906 done:
2908 if (is_valid_policy_hnd(&domain_handle)) {
2909 rpccli_samr_Close(cli, mem_ctx, &domain_handle);
2911 if (is_valid_policy_hnd(&connect_handle)) {
2912 rpccli_samr_Close(cli, mem_ctx, &connect_handle);
2915 return status;
2918 /* List of commands exported by this module */
2920 struct cmd_set samr_commands[] = {
2922 { "SAMR" },
2924 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, &ndr_table_samr.syntax_id, NULL, "Query user info", "" },
2925 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, &ndr_table_samr.syntax_id, NULL, "Query group info", "" },
2926 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, &ndr_table_samr.syntax_id, NULL, "Query user groups", "" },
2927 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, &ndr_table_samr.syntax_id, NULL, "Query user aliases", "" },
2928 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, &ndr_table_samr.syntax_id, NULL, "Query group membership", "" },
2929 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, &ndr_table_samr.syntax_id, NULL, "Query alias membership", "" },
2930 { "queryaliasinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query alias info", "" },
2931 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, &ndr_table_samr.syntax_id, NULL, "Delete an alias", "" },
2932 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
2933 { "querydispinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo2, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
2934 { "querydispinfo3", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo3, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
2935 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query domain info", "" },
2936 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domain users", "" },
2937 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domain groups", "" },
2938 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate alias groups", "" },
2939 { "enumdomains", RPC_RTYPE_NTSTATUS, cmd_samr_enum_domains, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domains", "" },
2941 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain user", "" },
2942 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain group", "" },
2943 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain alias", "" },
2944 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, &ndr_table_samr.syntax_id, NULL, "Look up names", "" },
2945 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, &ndr_table_samr.syntax_id, NULL, "Look up names", "" },
2946 { "deletedomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group, NULL, &ndr_table_samr.syntax_id, NULL, "Delete domain group", "" },
2947 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, &ndr_table_samr.syntax_id, NULL, "Delete domain user", "" },
2948 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, &ndr_table_samr.syntax_id, NULL, "Query SAMR security object", "" },
2949 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Retrieve domain password info", "" },
2950 { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Retrieve user domain password info", "" },
2952 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, &ndr_table_samr.syntax_id, NULL, "Lookup Domain Name", "" },
2953 { "chgpasswd", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
2954 { "chgpasswd2", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
2955 { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
2956 { "getdispinfoidx", RPC_RTYPE_NTSTATUS, cmd_samr_get_dispinfo_idx, NULL, &ndr_table_samr.syntax_id, NULL, "Get Display Information Index", "" },
2957 { "setuserinfo", RPC_RTYPE_NTSTATUS, cmd_samr_setuserinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Set user info", "" },
2958 { "setuserinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_setuserinfo2, NULL, &ndr_table_samr.syntax_id, NULL, "Set user info2", "" },
2959 { NULL }