r14194: Coverity bug #35. Fix uninitialized pipe_hnd.
[Samba/bb.git] / source3 / rpcclient / cmd_samr.c
blob5e1f0c37ddbc59e9bae70cde87e56d3990a7407e
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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "includes.h"
26 #include "rpcclient.h"
28 extern DOM_SID domain_sid;
30 /****************************************************************************
31 display sam_user_info_7 structure
32 ****************************************************************************/
33 static void display_sam_user_info_7(SAM_USER_INFO_7 *usr)
35 fstring temp;
37 unistr2_to_ascii(temp, &usr->uni_name, sizeof(temp)-1);
38 printf("\tUser Name :\t%s\n", temp);
41 /****************************************************************************
42 display sam_user_info_9 structure
43 ****************************************************************************/
44 static void display_sam_user_info_9(SAM_USER_INFO_9 *usr)
46 printf("\tPrimary group RID :\tox%x\n", usr->rid_group);
49 /****************************************************************************
50 display sam_user_info_21 structure
51 ****************************************************************************/
52 static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
54 fstring temp;
56 unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp)-1);
57 printf("\tUser Name :\t%s\n", temp);
59 unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp)-1);
60 printf("\tFull Name :\t%s\n", temp);
62 unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp)-1);
63 printf("\tHome Drive :\t%s\n", temp);
65 unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp)-1);
66 printf("\tDir Drive :\t%s\n", temp);
68 unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp)-1);
69 printf("\tProfile Path:\t%s\n", temp);
71 unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp)-1);
72 printf("\tLogon Script:\t%s\n", temp);
74 unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp)-1);
75 printf("\tDescription :\t%s\n", temp);
77 unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp)-1);
78 printf("\tWorkstations:\t%s\n", temp);
80 unistr2_to_ascii(temp, &usr->uni_unknown_str, sizeof(temp)-1);
81 printf("\tUnknown Str :\t%s\n", temp);
83 unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp)-1);
84 printf("\tRemote Dial :\t%s\n", temp);
86 printf("\tLogon Time :\t%s\n",
87 http_timestring(nt_time_to_unix(&usr->logon_time)));
88 printf("\tLogoff Time :\t%s\n",
89 http_timestring(nt_time_to_unix(&usr->logoff_time)));
90 printf("\tKickoff Time :\t%s\n",
91 http_timestring(nt_time_to_unix(&usr->kickoff_time)));
92 printf("\tPassword last set Time :\t%s\n",
93 http_timestring(nt_time_to_unix(&usr->pass_last_set_time)));
94 printf("\tPassword can change Time :\t%s\n",
95 http_timestring(nt_time_to_unix(&usr->pass_can_change_time)));
96 printf("\tPassword must change Time:\t%s\n",
97 http_timestring(nt_time_to_unix(&usr->pass_must_change_time)));
99 printf("\tunknown_2[0..31]...\n"); /* user passwords? */
101 printf("\tuser_rid :\t0x%x\n" , usr->user_rid ); /* User ID */
102 printf("\tgroup_rid:\t0x%x\n" , usr->group_rid); /* Group ID */
103 printf("\tacb_info :\t0x%08x\n", usr->acb_info ); /* Account Control Info */
105 printf("\tfields_present:\t0x%08x\n", usr->fields_present); /* 0x00ff ffff */
106 printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
107 printf("\tbad_password_count:\t0x%08x\n", usr->bad_password_count);
108 printf("\tlogon_count:\t0x%08x\n", usr->logon_count);
110 printf("\tpadding1[0..7]...\n");
112 if (usr->ptr_logon_hrs) {
113 printf("\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len);
117 static const char *display_time(NTTIME nttime)
119 static fstring string;
121 float high;
122 float low;
123 int sec;
124 int days, hours, mins, secs;
126 if (nttime.high==0 && nttime.low==0)
127 return "Now";
129 if (nttime.high==0x80000000 && nttime.low==0)
130 return "Never";
132 high = 65536;
133 high = high/10000;
134 high = high*65536;
135 high = high/1000;
136 high = high * (~nttime.high);
138 low = ~nttime.low;
139 low = low/(1000*1000*10);
141 sec=high+low;
143 days=sec/(60*60*24);
144 hours=(sec - (days*60*60*24)) / (60*60);
145 mins=(sec - (days*60*60*24) - (hours*60*60) ) / 60;
146 secs=sec - (days*60*60*24) - (hours*60*60) - (mins*60);
148 fstr_sprintf(string, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
149 return (string);
152 static void display_password_properties(uint32 password_properties)
154 printf("password_properties: 0x%08x\n", password_properties);
156 if (password_properties & DOMAIN_PASSWORD_COMPLEX)
157 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
159 if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
160 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
162 if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
163 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
165 if (password_properties & DOMAIN_LOCKOUT_ADMINS)
166 printf("\tDOMAIN_LOCKOUT_ADMINS\n");
168 if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
169 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
171 if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
172 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
175 static void display_sam_unk_info_1(SAM_UNK_INFO_1 *info1)
178 printf("Minimum password length:\t\t\t%d\n", info1->min_length_password);
179 printf("Password uniqueness (remember x passwords):\t%d\n", info1->password_history);
180 display_password_properties(info1->password_properties);
181 printf("password expire in:\t\t\t\t%s\n", display_time(info1->expire));
182 printf("Min password age (allow changing in x days):\t%s\n", display_time(info1->min_passwordage));
185 static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
187 fstring name;
189 unistr2_to_ascii(name, &info2->uni_domain, sizeof(name) - 1);
190 printf("Domain:\t\t%s\n", name);
192 unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1);
193 printf("Server:\t\t%s\n", name);
195 unistr2_to_ascii(name, &info2->uni_comment, sizeof(name) - 1);
196 printf("Comment:\t%s\n", name);
198 printf("Total Users:\t%d\n", info2->num_domain_usrs);
199 printf("Total Groups:\t%d\n", info2->num_domain_grps);
200 printf("Total Aliases:\t%d\n", info2->num_local_grps);
202 printf("Sequence No:\t%d\n", info2->seq_num.low);
204 printf("Force Logoff:\t%d\n", (int)nt_time_to_unix_abs(&info2->logout));
206 printf("Unknown 4:\t0x%x\n", info2->unknown_4);
207 printf("Server Role:\t%s\n", server_role_str(info2->server_role));
208 printf("Unknown 6:\t0x%x\n", info2->unknown_6);
211 static void display_sam_unk_info_7(SAM_UNK_INFO_7 *info7)
213 printf("Server Role:\t%s\n", server_role_str(info7->server_role));
216 static void display_sam_unk_info_8(SAM_UNK_INFO_8 *info8)
218 printf("Sequence No:\t%d\n", info8->seq_num.low);
219 printf("Domain Create Time:\t%s\n",
220 http_timestring(nt_time_to_unix(&info8->domain_create_time)));
224 static void display_sam_unk_info_12(SAM_UNK_INFO_12 *info12)
226 printf("Bad password lockout duration: %s\n", display_time(info12->duration));
227 printf("Reset Lockout after: %s\n", display_time(info12->reset_count));
228 printf("Lockout after bad attempts: %d\n", info12->bad_attempt_lockout);
231 static void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
233 fstring tmp;
235 printf("index: 0x%x ", e1->user_idx);
236 printf("RID: 0x%x ", e1->rid_user);
237 printf("acb: 0x%x ", e1->acb_info);
239 unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp)-1);
240 printf("Account: %s\t", tmp);
242 unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp)-1);
243 printf("Name: %s\t", tmp);
245 unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp)-1);
246 printf("Desc: %s\n", tmp);
249 static void display_sam_info_2(SAM_ENTRY2 *e2, SAM_STR2 *s2)
251 fstring tmp;
253 printf("index: 0x%x ", e2->user_idx);
254 printf("RID: 0x%x ", e2->rid_user);
255 printf("acb: 0x%x ", e2->acb_info);
257 unistr2_to_ascii(tmp, &s2->uni_srv_name, sizeof(tmp)-1);
258 printf("Account: %s\t", tmp);
260 unistr2_to_ascii(tmp, &s2->uni_srv_desc, sizeof(tmp)-1);
261 printf("Name: %s\n", tmp);
265 static void display_sam_info_3(SAM_ENTRY3 *e3, SAM_STR3 *s3)
267 fstring tmp;
269 printf("index: 0x%x ", e3->grp_idx);
270 printf("RID: 0x%x ", e3->rid_grp);
271 printf("attr: 0x%x ", e3->attr);
273 unistr2_to_ascii(tmp, &s3->uni_grp_name, sizeof(tmp)-1);
274 printf("Account: %s\t", tmp);
276 unistr2_to_ascii(tmp, &s3->uni_grp_desc, sizeof(tmp)-1);
277 printf("Name: %s\n", tmp);
281 static void display_sam_info_4(SAM_ENTRY4 *e4, SAM_STR4 *s4)
283 int i;
285 printf("index: %d ", e4->user_idx);
287 printf("Account: ");
288 for (i=0; i<s4->acct_name.str_str_len; i++)
289 printf("%c", s4->acct_name.buffer[i]);
290 printf("\n");
294 static void display_sam_info_5(SAM_ENTRY5 *e5, SAM_STR5 *s5)
296 int i;
298 printf("index: 0x%x ", e5->grp_idx);
300 printf("Account: ");
301 for (i=0; i<s5->grp_name.str_str_len; i++)
302 printf("%c", s5->grp_name.buffer[i]);
303 printf("\n");
307 /****************************************************************************
308 Try samr_connect4 first, then samr_conenct if it fails
309 ****************************************************************************/
310 static NTSTATUS try_samr_connects(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
311 uint32 access_mask, POLICY_HND *connect_pol)
313 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
315 result = rpccli_samr_connect4(cli, mem_ctx, access_mask, connect_pol);
316 if (!NT_STATUS_IS_OK(result)) {
317 result = rpccli_samr_connect(cli, mem_ctx, access_mask,
318 connect_pol);
320 return result;
323 /**********************************************************************
324 * Query user information
326 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
327 TALLOC_CTX *mem_ctx,
328 int argc, const char **argv)
330 POLICY_HND connect_pol, domain_pol, user_pol;
331 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
332 uint32 info_level = 21;
333 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
334 SAM_USERINFO_CTR *user_ctr;
335 fstring server;
336 uint32 user_rid;
338 if ((argc < 2) || (argc > 4)) {
339 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
340 return NT_STATUS_OK;
343 user_rid = strtoul(argv[1], NULL, 10);
345 if (argc > 2)
346 sscanf(argv[2], "%i", &info_level);
348 if (argc > 3)
349 sscanf(argv[3], "%x", &access_mask);
352 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
353 strupper_m(server);
355 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
356 &connect_pol);
358 if (!NT_STATUS_IS_OK(result))
359 goto done;
361 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
362 MAXIMUM_ALLOWED_ACCESS,
363 &domain_sid, &domain_pol);
365 if (!NT_STATUS_IS_OK(result))
366 goto done;
368 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
369 access_mask,
370 user_rid, &user_pol);
372 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
373 (user_rid == 0)) {
375 /* Probably this was a user name, try lookupnames */
376 uint32 num_rids;
377 uint32 *rids, *types;
379 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
380 1000, 1, &argv[1],
381 &num_rids, &rids,
382 &types);
384 if (NT_STATUS_IS_OK(result)) {
385 result = rpccli_samr_open_user(cli, mem_ctx,
386 &domain_pol,
387 access_mask,
388 rids[0], &user_pol);
393 if (!NT_STATUS_IS_OK(result))
394 goto done;
396 ZERO_STRUCT(user_ctr);
398 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
399 info_level, &user_ctr);
401 if (!NT_STATUS_IS_OK(result))
402 goto done;
404 switch (user_ctr->switch_value) {
405 case 21:
406 display_sam_user_info_21(user_ctr->info.id21);
407 break;
408 case 7:
409 display_sam_user_info_7(user_ctr->info.id7);
410 break;
411 case 9:
412 display_sam_user_info_9(user_ctr->info.id9);
413 break;
414 default:
415 printf("Unsupported infolevel: %d\n", info_level);
416 break;
419 rpccli_samr_close(cli, mem_ctx, &user_pol);
420 rpccli_samr_close(cli, mem_ctx, &domain_pol);
421 rpccli_samr_close(cli, mem_ctx, &connect_pol);
423 done:
424 return result;
427 /****************************************************************************
428 display group info
429 ****************************************************************************/
430 static void display_group_info1(GROUP_INFO1 *info1)
432 fstring temp;
434 unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
435 printf("\tGroup Name:\t%s\n", temp);
436 unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
437 printf("\tDescription:\t%s\n", temp);
438 printf("\tGroup Attribute:%d\n", info1->group_attr);
439 printf("\tNum Members:%d\n", info1->num_members);
442 /****************************************************************************
443 display group info
444 ****************************************************************************/
445 static void display_group_info3(GROUP_INFO3 *info3)
447 printf("\tGroup Attribute:%d\n", info3->group_attr);
451 /****************************************************************************
452 display group info
453 ****************************************************************************/
454 static void display_group_info4(GROUP_INFO4 *info4)
456 fstring desc;
458 unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
459 printf("\tGroup Description:%s\n", desc);
462 /****************************************************************************
463 display sam sync structure
464 ****************************************************************************/
465 static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
467 switch (ctr->switch_value1) {
468 case 1: {
469 display_group_info1(&ctr->group.info1);
470 break;
472 case 3: {
473 display_group_info3(&ctr->group.info3);
474 break;
476 case 4: {
477 display_group_info4(&ctr->group.info4);
478 break;
483 /***********************************************************************
484 * Query group information
486 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
487 TALLOC_CTX *mem_ctx,
488 int argc, const char **argv)
490 POLICY_HND connect_pol, domain_pol, group_pol;
491 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
492 uint32 info_level = 1;
493 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
494 GROUP_INFO_CTR *group_ctr;
495 fstring server;
496 uint32 group_rid;
498 if ((argc < 2) || (argc > 4)) {
499 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
500 return NT_STATUS_OK;
503 sscanf(argv[1], "%i", &group_rid);
505 if (argc > 2)
506 sscanf(argv[2], "%i", &info_level);
508 if (argc > 3)
509 sscanf(argv[3], "%x", &access_mask);
511 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
512 strupper_m(server);
514 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
515 &connect_pol);
517 if (!NT_STATUS_IS_OK(result))
518 goto done;
520 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
521 MAXIMUM_ALLOWED_ACCESS,
522 &domain_sid, &domain_pol);
524 if (!NT_STATUS_IS_OK(result))
525 goto done;
527 result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
528 access_mask,
529 group_rid, &group_pol);
531 if (!NT_STATUS_IS_OK(result))
532 goto done;
534 result = rpccli_samr_query_groupinfo(cli, mem_ctx, &group_pol,
535 info_level, &group_ctr);
536 if (!NT_STATUS_IS_OK(result)) {
537 goto done;
540 display_group_info_ctr(group_ctr);
542 rpccli_samr_close(cli, mem_ctx, &group_pol);
543 rpccli_samr_close(cli, mem_ctx, &domain_pol);
544 rpccli_samr_close(cli, mem_ctx, &connect_pol);
545 done:
546 return result;
549 /* Query groups a user is a member of */
551 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
552 TALLOC_CTX *mem_ctx,
553 int argc, const char **argv)
555 POLICY_HND connect_pol,
556 domain_pol,
557 user_pol;
558 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
559 uint32 num_groups,
560 user_rid;
561 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
562 DOM_GID *user_gids;
563 int i;
564 fstring server;
566 if ((argc < 2) || (argc > 3)) {
567 printf("Usage: %s rid [access mask]\n", argv[0]);
568 return NT_STATUS_OK;
571 sscanf(argv[1], "%i", &user_rid);
573 if (argc > 2)
574 sscanf(argv[2], "%x", &access_mask);
576 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
577 strupper_m(server);
579 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
580 &connect_pol);
582 if (!NT_STATUS_IS_OK(result))
583 goto done;
585 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
586 MAXIMUM_ALLOWED_ACCESS,
587 &domain_sid, &domain_pol);
589 if (!NT_STATUS_IS_OK(result))
590 goto done;
592 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
593 access_mask,
594 user_rid, &user_pol);
596 if (!NT_STATUS_IS_OK(result))
597 goto done;
599 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
600 &num_groups, &user_gids);
602 if (!NT_STATUS_IS_OK(result))
603 goto done;
605 for (i = 0; i < num_groups; i++) {
606 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
607 user_gids[i].g_rid, user_gids[i].attr);
610 rpccli_samr_close(cli, mem_ctx, &user_pol);
611 rpccli_samr_close(cli, mem_ctx, &domain_pol);
612 rpccli_samr_close(cli, mem_ctx, &connect_pol);
613 done:
614 return result;
617 /* Query aliases a user is a member of */
619 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
620 TALLOC_CTX *mem_ctx,
621 int argc, const char **argv)
623 POLICY_HND connect_pol, domain_pol;
624 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
625 DOM_SID *sids;
626 size_t num_sids;
627 uint32 num_aliases, *alias_rids;
628 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
629 int i;
630 fstring server;
631 DOM_SID2 *sid2;
633 if (argc < 3) {
634 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
635 return NT_STATUS_INVALID_PARAMETER;
638 sids = NULL;
639 num_sids = 0;
641 for (i=2; i<argc; i++) {
642 DOM_SID tmp_sid;
643 if (!string_to_sid(&tmp_sid, argv[i])) {
644 printf("%s is not a legal SID\n", argv[i]);
645 return NT_STATUS_INVALID_PARAMETER;
647 add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
650 sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
651 if (sid2 == NULL)
652 return NT_STATUS_NO_MEMORY;
654 for (i=0; i<num_sids; i++) {
655 sid_copy(&sid2[i].sid, &sids[i]);
656 sid2[i].num_auths = sid2[i].sid.num_auths;
659 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
660 strupper_m(server);
662 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
663 &connect_pol);
665 if (!NT_STATUS_IS_OK(result))
666 goto done;
668 if (StrCaseCmp(argv[1], "domain")==0)
669 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
670 access_mask,
671 &domain_sid, &domain_pol);
672 else if (StrCaseCmp(argv[1], "builtin")==0)
673 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
674 access_mask,
675 &global_sid_Builtin,
676 &domain_pol);
677 else {
678 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
679 return NT_STATUS_INVALID_PARAMETER;
682 if (!NT_STATUS_IS_OK(result))
683 goto done;
685 result = rpccli_samr_query_useraliases(cli, mem_ctx, &domain_pol,
686 num_sids, sid2,
687 &num_aliases, &alias_rids);
689 if (!NT_STATUS_IS_OK(result))
690 goto done;
692 for (i = 0; i < num_aliases; i++) {
693 printf("\tgroup rid:[0x%x]\n", alias_rids[i]);
696 rpccli_samr_close(cli, mem_ctx, &domain_pol);
697 rpccli_samr_close(cli, mem_ctx, &connect_pol);
698 done:
699 return result;
702 /* Query members of a group */
704 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
705 TALLOC_CTX *mem_ctx,
706 int argc, const char **argv)
708 POLICY_HND connect_pol, domain_pol, group_pol;
709 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
710 uint32 num_members, *group_rids, *group_attrs, group_rid;
711 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
712 int i;
713 fstring server;
715 if ((argc < 2) || (argc > 3)) {
716 printf("Usage: %s rid [access mask]\n", argv[0]);
717 return NT_STATUS_OK;
720 sscanf(argv[1], "%i", &group_rid);
722 if (argc > 2)
723 sscanf(argv[2], "%x", &access_mask);
725 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
726 strupper_m(server);
728 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
729 &connect_pol);
731 if (!NT_STATUS_IS_OK(result))
732 goto done;
734 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
735 MAXIMUM_ALLOWED_ACCESS,
736 &domain_sid, &domain_pol);
738 if (!NT_STATUS_IS_OK(result))
739 goto done;
741 result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
742 access_mask,
743 group_rid, &group_pol);
745 if (!NT_STATUS_IS_OK(result))
746 goto done;
748 result = rpccli_samr_query_groupmem(cli, mem_ctx, &group_pol,
749 &num_members, &group_rids,
750 &group_attrs);
752 if (!NT_STATUS_IS_OK(result))
753 goto done;
755 for (i = 0; i < num_members; i++) {
756 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
757 group_attrs[i]);
760 rpccli_samr_close(cli, mem_ctx, &group_pol);
761 rpccli_samr_close(cli, mem_ctx, &domain_pol);
762 rpccli_samr_close(cli, mem_ctx, &connect_pol);
763 done:
764 return result;
767 /* Enumerate domain users */
769 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
770 TALLOC_CTX *mem_ctx,
771 int argc, const char **argv)
773 POLICY_HND connect_pol, domain_pol;
774 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
775 uint32 start_idx, size, num_dom_users, i;
776 char **dom_users;
777 uint32 *dom_rids;
778 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
779 uint32 acb_mask = ACB_NORMAL;
780 BOOL got_connect_pol = False, got_domain_pol = False;
782 if ((argc < 1) || (argc > 3)) {
783 printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
784 return NT_STATUS_OK;
787 if (argc > 1)
788 sscanf(argv[1], "%x", &access_mask);
790 if (argc > 2)
791 sscanf(argv[2], "%x", &acb_mask);
793 /* Get sam policy handle */
795 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
796 &connect_pol);
798 if (!NT_STATUS_IS_OK(result))
799 goto done;
801 got_connect_pol = True;
803 /* Get domain policy handle */
805 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
806 access_mask,
807 &domain_sid, &domain_pol);
809 if (!NT_STATUS_IS_OK(result))
810 goto done;
812 got_domain_pol = True;
814 /* Enumerate domain users */
816 start_idx = 0;
817 size = 0xffff;
819 do {
820 result = rpccli_samr_enum_dom_users(
821 cli, mem_ctx, &domain_pol, &start_idx, acb_mask,
822 size, &dom_users, &dom_rids, &num_dom_users);
824 if (NT_STATUS_IS_OK(result) ||
825 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
827 for (i = 0; i < num_dom_users; i++)
828 printf("user:[%s] rid:[0x%x]\n",
829 dom_users[i], dom_rids[i]);
832 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
834 done:
835 if (got_domain_pol)
836 rpccli_samr_close(cli, mem_ctx, &domain_pol);
838 if (got_connect_pol)
839 rpccli_samr_close(cli, mem_ctx, &connect_pol);
841 return result;
844 /* Enumerate domain groups */
846 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
847 TALLOC_CTX *mem_ctx,
848 int argc, const char **argv)
850 POLICY_HND connect_pol, domain_pol;
851 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
852 uint32 start_idx, size, num_dom_groups, i;
853 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
854 struct acct_info *dom_groups;
855 BOOL got_connect_pol = False, got_domain_pol = False;
857 if ((argc < 1) || (argc > 2)) {
858 printf("Usage: %s [access_mask]\n", argv[0]);
859 return NT_STATUS_OK;
862 if (argc > 1)
863 sscanf(argv[1], "%x", &access_mask);
865 /* Get sam policy handle */
867 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
868 &connect_pol);
870 if (!NT_STATUS_IS_OK(result))
871 goto done;
873 got_connect_pol = True;
875 /* Get domain policy handle */
877 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
878 access_mask,
879 &domain_sid, &domain_pol);
881 if (!NT_STATUS_IS_OK(result))
882 goto done;
884 got_domain_pol = True;
886 /* Enumerate domain groups */
888 start_idx = 0;
889 size = 0xffff;
891 do {
892 result = rpccli_samr_enum_dom_groups(
893 cli, mem_ctx, &domain_pol, &start_idx, size,
894 &dom_groups, &num_dom_groups);
896 if (NT_STATUS_IS_OK(result) ||
897 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
899 for (i = 0; i < num_dom_groups; i++)
900 printf("group:[%s] rid:[0x%x]\n",
901 dom_groups[i].acct_name,
902 dom_groups[i].rid);
905 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
907 done:
908 if (got_domain_pol)
909 rpccli_samr_close(cli, mem_ctx, &domain_pol);
911 if (got_connect_pol)
912 rpccli_samr_close(cli, mem_ctx, &connect_pol);
914 return result;
917 /* Enumerate alias groups */
919 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
920 TALLOC_CTX *mem_ctx,
921 int argc, const char **argv)
923 POLICY_HND connect_pol, domain_pol;
924 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
925 uint32 start_idx, size, num_als_groups, i;
926 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
927 struct acct_info *als_groups;
928 BOOL got_connect_pol = False, got_domain_pol = False;
930 if ((argc < 2) || (argc > 3)) {
931 printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
932 return NT_STATUS_OK;
935 if (argc > 2)
936 sscanf(argv[2], "%x", &access_mask);
938 /* Get sam policy handle */
940 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
941 &connect_pol);
943 if (!NT_STATUS_IS_OK(result))
944 goto done;
946 got_connect_pol = True;
948 /* Get domain policy handle */
950 if (StrCaseCmp(argv[1], "domain")==0)
951 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
952 access_mask,
953 &domain_sid, &domain_pol);
954 else if (StrCaseCmp(argv[1], "builtin")==0)
955 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
956 access_mask,
957 &global_sid_Builtin, &domain_pol);
958 else
959 return NT_STATUS_OK;
961 if (!NT_STATUS_IS_OK(result))
962 goto done;
964 got_domain_pol = True;
966 /* Enumerate alias groups */
968 start_idx = 0;
969 size = 0xffff; /* Number of groups to retrieve */
971 do {
972 result = rpccli_samr_enum_als_groups(
973 cli, mem_ctx, &domain_pol, &start_idx, size,
974 &als_groups, &num_als_groups);
976 if (NT_STATUS_IS_OK(result) ||
977 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
979 for (i = 0; i < num_als_groups; i++)
980 printf("group:[%s] rid:[0x%x]\n",
981 als_groups[i].acct_name,
982 als_groups[i].rid);
984 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
986 done:
987 if (got_domain_pol)
988 rpccli_samr_close(cli, mem_ctx, &domain_pol);
990 if (got_connect_pol)
991 rpccli_samr_close(cli, mem_ctx, &connect_pol);
993 return result;
996 /* Query alias membership */
998 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
999 TALLOC_CTX *mem_ctx,
1000 int argc, const char **argv)
1002 POLICY_HND connect_pol, domain_pol, alias_pol;
1003 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1004 uint32 alias_rid, num_members, i;
1005 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1006 DOM_SID *alias_sids;
1008 if ((argc < 3) || (argc > 4)) {
1009 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1010 return NT_STATUS_OK;
1013 sscanf(argv[2], "%i", &alias_rid);
1015 if (argc > 3)
1016 sscanf(argv[3], "%x", &access_mask);
1018 /* Open SAMR handle */
1020 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1021 &connect_pol);
1023 if (!NT_STATUS_IS_OK(result))
1024 goto done;
1026 /* Open handle on domain */
1028 if (StrCaseCmp(argv[1], "domain")==0)
1029 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1030 MAXIMUM_ALLOWED_ACCESS,
1031 &domain_sid, &domain_pol);
1032 else if (StrCaseCmp(argv[1], "builtin")==0)
1033 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1034 MAXIMUM_ALLOWED_ACCESS,
1035 &global_sid_Builtin, &domain_pol);
1036 else
1037 return NT_STATUS_OK;
1039 if (!NT_STATUS_IS_OK(result))
1040 goto done;
1042 /* Open handle on alias */
1044 result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
1045 access_mask,
1046 alias_rid, &alias_pol);
1047 if (!NT_STATUS_IS_OK(result))
1048 goto done;
1050 result = rpccli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
1051 &num_members, &alias_sids);
1053 if (!NT_STATUS_IS_OK(result))
1054 goto done;
1056 for (i = 0; i < num_members; i++) {
1057 fstring sid_str;
1059 sid_to_string(sid_str, &alias_sids[i]);
1060 printf("\tsid:[%s]\n", sid_str);
1063 rpccli_samr_close(cli, mem_ctx, &alias_pol);
1064 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1065 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1066 done:
1067 return result;
1070 /* Query delete an alias membership */
1072 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1073 TALLOC_CTX *mem_ctx,
1074 int argc, const char **argv)
1076 POLICY_HND connect_pol, domain_pol, alias_pol;
1077 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1078 uint32 alias_rid;
1079 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1081 if (argc != 3) {
1082 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1083 return NT_STATUS_OK;
1086 alias_rid = strtoul(argv[2], NULL, 10);
1088 /* Open SAMR handle */
1090 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1091 &connect_pol);
1093 if (!NT_STATUS_IS_OK(result))
1094 goto done;
1096 /* Open handle on domain */
1098 if (StrCaseCmp(argv[1], "domain")==0)
1099 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1100 MAXIMUM_ALLOWED_ACCESS,
1101 &domain_sid, &domain_pol);
1102 else if (StrCaseCmp(argv[1], "builtin")==0)
1103 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1104 MAXIMUM_ALLOWED_ACCESS,
1105 &global_sid_Builtin, &domain_pol);
1106 else
1107 return NT_STATUS_INVALID_PARAMETER;
1109 if (!NT_STATUS_IS_OK(result))
1110 goto done;
1112 /* Open handle on alias */
1114 result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
1115 access_mask,
1116 alias_rid, &alias_pol);
1117 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1118 /* Probably this was a user name, try lookupnames */
1119 uint32 num_rids;
1120 uint32 *rids, *types;
1122 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1123 1000, 1, &argv[2],
1124 &num_rids, &rids,
1125 &types);
1127 if (NT_STATUS_IS_OK(result)) {
1128 result = rpccli_samr_open_alias(cli, mem_ctx,
1129 &domain_pol,
1130 access_mask,
1131 rids[0], &alias_pol);
1135 result = rpccli_samr_delete_dom_alias(cli, mem_ctx, &alias_pol);
1137 if (!NT_STATUS_IS_OK(result))
1138 goto done;
1140 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1141 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1142 done:
1143 return result;
1146 /* Query display info */
1148 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1149 TALLOC_CTX *mem_ctx,
1150 int argc, const char **argv)
1152 POLICY_HND connect_pol, domain_pol;
1153 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1154 uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries, i;
1155 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1156 uint32 info_level = 1;
1157 SAM_DISPINFO_CTR ctr;
1158 SAM_DISPINFO_1 info1;
1159 SAM_DISPINFO_2 info2;
1160 SAM_DISPINFO_3 info3;
1161 SAM_DISPINFO_4 info4;
1162 SAM_DISPINFO_5 info5;
1163 int loop_count = 0;
1164 BOOL got_params = False; /* Use get_query_dispinfo_params() or not? */
1166 if (argc > 5) {
1167 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1168 return NT_STATUS_OK;
1171 if (argc >= 2)
1172 sscanf(argv[1], "%i", &info_level);
1174 if (argc >= 3)
1175 sscanf(argv[2], "%i", &start_idx);
1177 if (argc >= 4) {
1178 sscanf(argv[3], "%i", &max_entries);
1179 got_params = True;
1182 if (argc >= 5) {
1183 sscanf(argv[4], "%i", &max_size);
1184 got_params = True;
1187 if (argc >= 6)
1188 sscanf(argv[5], "%x", &access_mask);
1190 /* Get sam policy handle */
1192 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1193 &connect_pol);
1195 if (!NT_STATUS_IS_OK(result))
1196 goto done;
1198 /* Get domain policy handle */
1200 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1201 access_mask,
1202 &domain_sid, &domain_pol);
1204 if (!NT_STATUS_IS_OK(result))
1205 goto done;
1207 /* Query display info */
1209 ZERO_STRUCT(ctr);
1210 ZERO_STRUCT(info1);
1212 switch (info_level) {
1213 case 1:
1214 ZERO_STRUCT(info1);
1215 ctr.sam.info1 = &info1;
1216 break;
1217 case 2:
1218 ZERO_STRUCT(info2);
1219 ctr.sam.info2 = &info2;
1220 break;
1221 case 3:
1222 ZERO_STRUCT(info3);
1223 ctr.sam.info3 = &info3;
1224 break;
1225 case 4:
1226 ZERO_STRUCT(info4);
1227 ctr.sam.info4 = &info4;
1228 break;
1229 case 5:
1230 ZERO_STRUCT(info5);
1231 ctr.sam.info5 = &info5;
1232 break;
1236 do {
1238 if (!got_params)
1239 get_query_dispinfo_params(
1240 loop_count, &max_entries, &max_size);
1242 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
1243 &start_idx, info_level,
1244 &num_entries, max_entries,
1245 max_size, &ctr);
1247 loop_count++;
1249 if (NT_STATUS_IS_ERR(result))
1250 break;
1252 if (num_entries == 0)
1253 break;
1255 for (i = 0; i < num_entries; i++) {
1256 switch (info_level) {
1257 case 1:
1258 display_sam_info_1(&ctr.sam.info1->sam[i], &ctr.sam.info1->str[i]);
1259 break;
1260 case 2:
1261 display_sam_info_2(&ctr.sam.info2->sam[i], &ctr.sam.info2->str[i]);
1262 break;
1263 case 3:
1264 display_sam_info_3(&ctr.sam.info3->sam[i], &ctr.sam.info3->str[i]);
1265 break;
1266 case 4:
1267 display_sam_info_4(&ctr.sam.info4->sam[i], &ctr.sam.info4->str[i]);
1268 break;
1269 case 5:
1270 display_sam_info_5(&ctr.sam.info5->sam[i], &ctr.sam.info5->str[i]);
1271 break;
1274 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1276 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1277 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1278 done:
1279 return result;
1282 /* Query domain info */
1284 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1285 TALLOC_CTX *mem_ctx,
1286 int argc, const char **argv)
1288 POLICY_HND connect_pol, domain_pol;
1289 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1290 uint32 switch_level = 2;
1291 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1292 SAM_UNK_CTR ctr;
1294 if (argc > 2) {
1295 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1296 return NT_STATUS_OK;
1299 if (argc > 1)
1300 sscanf(argv[1], "%i", &switch_level);
1302 if (argc > 2)
1303 sscanf(argv[2], "%x", &access_mask);
1305 /* Get sam policy handle */
1307 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1308 &connect_pol);
1310 if (!NT_STATUS_IS_OK(result))
1311 goto done;
1313 /* Get domain policy handle */
1315 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1316 access_mask,
1317 &domain_sid, &domain_pol);
1319 if (!NT_STATUS_IS_OK(result))
1320 goto done;
1322 /* Query domain info */
1324 result = rpccli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
1325 switch_level, &ctr);
1327 if (!NT_STATUS_IS_OK(result))
1328 goto done;
1330 /* Display domain info */
1332 switch (switch_level) {
1333 case 1:
1334 display_sam_unk_info_1(&ctr.info.inf1);
1335 break;
1336 case 2:
1337 display_sam_unk_info_2(&ctr.info.inf2);
1338 break;
1339 case 7:
1340 display_sam_unk_info_7(&ctr.info.inf7);
1341 break;
1342 case 8:
1343 display_sam_unk_info_8(&ctr.info.inf8);
1344 break;
1345 case 12:
1346 display_sam_unk_info_12(&ctr.info.inf12);
1347 break;
1348 default:
1349 printf("cannot display domain info for switch value %d\n",
1350 switch_level);
1351 break;
1354 done:
1356 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1357 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1358 return result;
1361 /* Create domain user */
1363 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1364 TALLOC_CTX *mem_ctx,
1365 int argc, const char **argv)
1367 POLICY_HND connect_pol, domain_pol, user_pol;
1368 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1369 const char *acct_name;
1370 uint32 acb_info;
1371 uint32 unknown, user_rid;
1372 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1374 if ((argc < 2) || (argc > 3)) {
1375 printf("Usage: %s username [access mask]\n", argv[0]);
1376 return NT_STATUS_OK;
1379 acct_name = argv[1];
1381 if (argc > 2)
1382 sscanf(argv[2], "%x", &access_mask);
1384 /* Get sam policy handle */
1386 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1387 &connect_pol);
1389 if (!NT_STATUS_IS_OK(result))
1390 goto done;
1392 /* Get domain policy handle */
1394 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1395 access_mask,
1396 &domain_sid, &domain_pol);
1398 if (!NT_STATUS_IS_OK(result))
1399 goto done;
1401 /* Create domain user */
1403 acb_info = ACB_NORMAL;
1404 unknown = 0xe005000b; /* No idea what this is - a permission mask? */
1406 result = rpccli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1407 acct_name, acb_info, unknown,
1408 &user_pol, &user_rid);
1410 if (!NT_STATUS_IS_OK(result))
1411 goto done;
1413 result = rpccli_samr_close(cli, mem_ctx, &user_pol);
1414 if (!NT_STATUS_IS_OK(result)) goto done;
1416 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1417 if (!NT_STATUS_IS_OK(result)) goto done;
1419 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1420 if (!NT_STATUS_IS_OK(result)) goto done;
1422 done:
1423 return result;
1426 /* Create domain group */
1428 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1429 TALLOC_CTX *mem_ctx,
1430 int argc, const char **argv)
1432 POLICY_HND connect_pol, domain_pol, group_pol;
1433 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1434 const char *grp_name;
1435 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1437 if ((argc < 2) || (argc > 3)) {
1438 printf("Usage: %s groupname [access mask]\n", argv[0]);
1439 return NT_STATUS_OK;
1442 grp_name = argv[1];
1444 if (argc > 2)
1445 sscanf(argv[2], "%x", &access_mask);
1447 /* Get sam policy handle */
1449 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1450 &connect_pol);
1452 if (!NT_STATUS_IS_OK(result))
1453 goto done;
1455 /* Get domain policy handle */
1457 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1458 access_mask,
1459 &domain_sid, &domain_pol);
1461 if (!NT_STATUS_IS_OK(result))
1462 goto done;
1464 /* Create domain user */
1466 result = rpccli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
1467 grp_name, MAXIMUM_ALLOWED_ACCESS,
1468 &group_pol);
1470 if (!NT_STATUS_IS_OK(result))
1471 goto done;
1473 result = rpccli_samr_close(cli, mem_ctx, &group_pol);
1474 if (!NT_STATUS_IS_OK(result)) goto done;
1476 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1477 if (!NT_STATUS_IS_OK(result)) goto done;
1479 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1480 if (!NT_STATUS_IS_OK(result)) goto done;
1482 done:
1483 return result;
1486 /* Create domain alias */
1488 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1489 TALLOC_CTX *mem_ctx,
1490 int argc, const char **argv)
1492 POLICY_HND connect_pol, domain_pol, alias_pol;
1493 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1494 const char *alias_name;
1495 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1497 if ((argc < 2) || (argc > 3)) {
1498 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1499 return NT_STATUS_OK;
1502 alias_name = argv[1];
1504 if (argc > 2)
1505 sscanf(argv[2], "%x", &access_mask);
1507 /* Get sam policy handle */
1509 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1510 &connect_pol);
1512 if (!NT_STATUS_IS_OK(result))
1513 goto done;
1515 /* Get domain policy handle */
1517 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1518 access_mask,
1519 &domain_sid, &domain_pol);
1521 if (!NT_STATUS_IS_OK(result))
1522 goto done;
1524 /* Create domain user */
1526 result = rpccli_samr_create_dom_alias(cli, mem_ctx, &domain_pol,
1527 alias_name, &alias_pol);
1529 if (!NT_STATUS_IS_OK(result))
1530 goto done;
1532 result = rpccli_samr_close(cli, mem_ctx, &alias_pol);
1533 if (!NT_STATUS_IS_OK(result)) goto done;
1535 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
1536 if (!NT_STATUS_IS_OK(result)) goto done;
1538 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
1539 if (!NT_STATUS_IS_OK(result)) goto done;
1541 done:
1542 return result;
1545 /* Lookup sam names */
1547 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
1548 TALLOC_CTX *mem_ctx,
1549 int argc, const char **argv)
1551 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1552 POLICY_HND connect_pol, domain_pol;
1553 uint32 flags = 0x000003e8; /* Unknown */
1554 uint32 num_rids, num_names, *name_types, *rids;
1555 const char **names;
1556 int i;
1558 if (argc < 3) {
1559 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1560 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1561 printf("or check on the builtin SID: S-1-5-32\n");
1562 return NT_STATUS_OK;
1565 /* Get sam policy and domain handles */
1567 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1568 &connect_pol);
1570 if (!NT_STATUS_IS_OK(result))
1571 goto done;
1573 if (StrCaseCmp(argv[1], "domain")==0)
1574 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1575 MAXIMUM_ALLOWED_ACCESS,
1576 &domain_sid, &domain_pol);
1577 else if (StrCaseCmp(argv[1], "builtin")==0)
1578 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1579 MAXIMUM_ALLOWED_ACCESS,
1580 &global_sid_Builtin, &domain_pol);
1581 else
1582 return NT_STATUS_OK;
1584 if (!NT_STATUS_IS_OK(result))
1585 goto done;
1587 /* Look up names */
1589 num_names = argc - 2;
1590 names = TALLOC_ARRAY(mem_ctx, const char *, num_names);
1592 for (i = 0; i < argc - 2; i++)
1593 names[i] = argv[i + 2];
1595 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1596 flags, num_names, names,
1597 &num_rids, &rids, &name_types);
1599 if (!NT_STATUS_IS_OK(result))
1600 goto done;
1602 /* Display results */
1604 for (i = 0; i < num_names; i++)
1605 printf("name %s: 0x%x (%d)\n", names[i], rids[i],
1606 name_types[i]);
1608 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1609 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1610 done:
1611 return result;
1614 /* Lookup sam rids */
1616 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
1617 TALLOC_CTX *mem_ctx,
1618 int argc, const char **argv)
1620 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1621 POLICY_HND connect_pol, domain_pol;
1622 uint32 num_rids, num_names, *rids, *name_types;
1623 char **names;
1624 int i;
1626 if (argc < 3) {
1627 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1628 return NT_STATUS_OK;
1631 /* Get sam policy and domain handles */
1633 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1634 &connect_pol);
1636 if (!NT_STATUS_IS_OK(result))
1637 goto done;
1639 if (StrCaseCmp(argv[1], "domain")==0)
1640 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1641 MAXIMUM_ALLOWED_ACCESS,
1642 &domain_sid, &domain_pol);
1643 else if (StrCaseCmp(argv[1], "builtin")==0)
1644 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1645 MAXIMUM_ALLOWED_ACCESS,
1646 &global_sid_Builtin, &domain_pol);
1647 else
1648 return NT_STATUS_OK;
1650 if (!NT_STATUS_IS_OK(result))
1651 goto done;
1653 /* Look up rids */
1655 num_rids = argc - 2;
1656 rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids);
1658 for (i = 0; i < argc - 2; i++)
1659 sscanf(argv[i + 2], "%i", &rids[i]);
1661 result = rpccli_samr_lookup_rids(cli, mem_ctx, &domain_pol, num_rids, rids,
1662 &num_names, &names, &name_types);
1664 if (!NT_STATUS_IS_OK(result) &&
1665 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1666 goto done;
1668 /* Display results */
1670 for (i = 0; i < num_names; i++)
1671 printf("rid 0x%x: %s (%d)\n", rids[i], names[i], name_types[i]);
1673 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1674 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1675 done:
1676 return result;
1679 /* Delete domain user */
1681 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
1682 TALLOC_CTX *mem_ctx,
1683 int argc, const char **argv)
1685 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1686 POLICY_HND connect_pol, domain_pol, user_pol;
1687 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1689 if ((argc < 2) || (argc > 3)) {
1690 printf("Usage: %s username\n", argv[0]);
1691 return NT_STATUS_OK;
1694 if (argc > 2)
1695 sscanf(argv[2], "%x", &access_mask);
1697 /* Get sam policy and domain handles */
1699 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1700 &connect_pol);
1702 if (!NT_STATUS_IS_OK(result))
1703 goto done;
1705 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1706 MAXIMUM_ALLOWED_ACCESS,
1707 &domain_sid, &domain_pol);
1709 if (!NT_STATUS_IS_OK(result))
1710 goto done;
1712 /* Get handle on user */
1715 uint32 *user_rids, num_rids, *name_types;
1716 uint32 flags = 0x000003e8; /* Unknown */
1718 result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1719 flags, 1, (const char **)&argv[1],
1720 &num_rids, &user_rids,
1721 &name_types);
1723 if (!NT_STATUS_IS_OK(result))
1724 goto done;
1726 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1727 access_mask,
1728 user_rids[0], &user_pol);
1730 if (!NT_STATUS_IS_OK(result))
1731 goto done;
1734 /* Delete user */
1736 result = rpccli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
1738 if (!NT_STATUS_IS_OK(result))
1739 goto done;
1741 /* Display results */
1743 rpccli_samr_close(cli, mem_ctx, &user_pol);
1744 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1745 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1747 done:
1748 return result;
1751 /**********************************************************************
1752 * Query user security object
1754 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
1755 TALLOC_CTX *mem_ctx,
1756 int argc, const char **argv)
1758 POLICY_HND connect_pol, domain_pol, user_pol, *pol;
1759 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1760 uint32 sec_info = DACL_SECURITY_INFORMATION;
1761 fstring server;
1762 uint32 user_rid = 0;
1763 TALLOC_CTX *ctx = NULL;
1764 SEC_DESC_BUF *sec_desc_buf=NULL;
1765 BOOL domain = False;
1767 ctx=talloc_init("cmd_samr_query_sec_obj");
1769 if ((argc < 1) || (argc > 3)) {
1770 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
1771 printf("\tSpecify rid for security on user, -d for security on domain\n");
1772 return NT_STATUS_OK;
1775 if (argc > 1) {
1776 if (strcmp(argv[1], "-d") == 0)
1777 domain = True;
1778 else
1779 sscanf(argv[1], "%i", &user_rid);
1782 if (argc == 3) {
1783 sec_info = atoi(argv[2]);
1786 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
1787 strupper_m(server);
1788 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1789 &connect_pol);
1791 if (!NT_STATUS_IS_OK(result))
1792 goto done;
1794 if (domain || user_rid)
1795 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1796 MAXIMUM_ALLOWED_ACCESS,
1797 &domain_sid, &domain_pol);
1799 if (!NT_STATUS_IS_OK(result))
1800 goto done;
1802 if (user_rid)
1803 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1804 MAXIMUM_ALLOWED_ACCESS,
1805 user_rid, &user_pol);
1807 if (!NT_STATUS_IS_OK(result))
1808 goto done;
1810 /* Pick which query pol to use */
1812 pol = &connect_pol;
1814 if (domain)
1815 pol = &domain_pol;
1817 if (user_rid)
1818 pol = &user_pol;
1820 /* Query SAM security object */
1822 result = rpccli_samr_query_sec_obj(cli, mem_ctx, pol, sec_info, ctx,
1823 &sec_desc_buf);
1825 if (!NT_STATUS_IS_OK(result))
1826 goto done;
1828 display_sec_desc(sec_desc_buf->sec);
1830 rpccli_samr_close(cli, mem_ctx, &user_pol);
1831 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1832 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1833 done:
1834 talloc_destroy(ctx);
1835 return result;
1838 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
1839 TALLOC_CTX *mem_ctx,
1840 int argc, const char **argv)
1842 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1843 POLICY_HND connect_pol, domain_pol, user_pol;
1844 uint16 min_pwd_length;
1845 uint32 password_properties, unknown1, rid;
1847 if (argc != 2) {
1848 printf("Usage: %s rid\n", argv[0]);
1849 return NT_STATUS_OK;
1852 sscanf(argv[1], "%i", &rid);
1854 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1855 &connect_pol);
1857 if (!NT_STATUS_IS_OK(result)) {
1858 goto done;
1861 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1862 MAXIMUM_ALLOWED_ACCESS, &domain_sid, &domain_pol);
1864 if (!NT_STATUS_IS_OK(result)) {
1865 goto done;
1868 result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
1869 MAXIMUM_ALLOWED_ACCESS,
1870 rid, &user_pol);
1872 if (!NT_STATUS_IS_OK(result)) {
1873 goto done;
1876 result = rpccli_samr_get_usrdom_pwinfo(cli, mem_ctx, &user_pol,
1877 &min_pwd_length, &password_properties,
1878 &unknown1) ;
1880 if (NT_STATUS_IS_OK(result)) {
1881 printf("min_pwd_length: %d\n", min_pwd_length);
1882 printf("unknown1: %d\n", unknown1);
1883 display_password_properties(password_properties);
1886 done:
1887 rpccli_samr_close(cli, mem_ctx, &user_pol);
1888 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1889 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1891 return result;
1895 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
1896 TALLOC_CTX *mem_ctx,
1897 int argc, const char **argv)
1899 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1900 uint16 min_pwd_length;
1901 uint32 password_properties;
1903 if (argc != 1) {
1904 printf("Usage: %s\n", argv[0]);
1905 return NT_STATUS_OK;
1908 result = rpccli_samr_get_dom_pwinfo(cli, mem_ctx, &min_pwd_length, &password_properties) ;
1910 if (NT_STATUS_IS_OK(result)) {
1911 printf("min_pwd_length: %d\n", min_pwd_length);
1912 display_password_properties(password_properties);
1915 return result;
1918 /* Look up domain name */
1920 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
1921 TALLOC_CTX *mem_ctx,
1922 int argc, const char **argv)
1924 POLICY_HND connect_pol, domain_pol;
1925 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1926 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1927 fstring domain_name,sid_string;
1928 DOM_SID sid;
1930 if (argc != 2) {
1931 printf("Usage: %s domain_name\n", argv[0]);
1932 return NT_STATUS_OK;
1935 sscanf(argv[1], "%s", domain_name);
1937 result = try_samr_connects(cli, mem_ctx, access_mask, &connect_pol);
1939 if (!NT_STATUS_IS_OK(result))
1940 goto done;
1942 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1943 access_mask, &domain_sid, &domain_pol);
1945 if (!NT_STATUS_IS_OK(result))
1946 goto done;
1948 result = rpccli_samr_lookup_domain(
1949 cli, mem_ctx, &connect_pol, domain_name, &sid);
1951 sid_to_string(sid_string,&sid);
1953 if (NT_STATUS_IS_OK(result))
1954 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
1955 domain_name,sid_string);
1957 rpccli_samr_close(cli, mem_ctx, &domain_pol);
1958 rpccli_samr_close(cli, mem_ctx, &connect_pol);
1959 done:
1960 return result;
1963 /* Change user password */
1965 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
1966 TALLOC_CTX *mem_ctx,
1967 int argc, const char **argv)
1969 POLICY_HND connect_pol, domain_pol;
1970 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1971 const char *user, *oldpass, *newpass;
1972 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1973 SAM_UNK_INFO_1 info;
1974 SAMR_CHANGE_REJECT reject;
1976 if (argc < 3) {
1977 printf("Usage: %s username oldpass newpass\n", argv[0]);
1978 return NT_STATUS_INVALID_PARAMETER;
1981 user = argv[1];
1982 oldpass = argv[2];
1983 newpass = argv[3];
1985 /* Get sam policy handle */
1987 result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1988 &connect_pol);
1990 if (!NT_STATUS_IS_OK(result))
1991 goto done;
1993 /* Get domain policy handle */
1995 result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
1996 access_mask,
1997 &domain_sid, &domain_pol);
1999 if (!NT_STATUS_IS_OK(result))
2000 goto done;
2002 /* Change user password */
2003 result = rpccli_samr_chgpasswd3(cli, mem_ctx, user, newpass, oldpass, &info, &reject);
2005 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2007 display_sam_unk_info_1(&info);
2009 switch (reject.reject_reason) {
2010 case REJECT_REASON_TOO_SHORT:
2011 d_printf("REJECT_REASON_TOO_SHORT\n");
2012 break;
2013 case REJECT_REASON_IN_HISTORY:
2014 d_printf("REJECT_REASON_IN_HISTORY\n");
2015 break;
2016 case REJECT_REASON_NOT_COMPLEX:
2017 d_printf("REJECT_REASON_NOT_COMPLEX\n");
2018 break;
2019 case 0:
2020 break;
2021 default:
2022 d_printf("unknown reject reason: %d\n", reject.reject_reason);
2023 break;
2027 if (!NT_STATUS_IS_OK(result))
2028 goto done;
2030 result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
2031 if (!NT_STATUS_IS_OK(result)) goto done;
2033 result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
2034 if (!NT_STATUS_IS_OK(result)) goto done;
2036 done:
2037 return result;
2040 /* List of commands exported by this module */
2042 struct cmd_set samr_commands[] = {
2044 { "SAMR" },
2046 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, PI_SAMR, NULL, "Query user info", "" },
2047 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, PI_SAMR, NULL, "Query group info", "" },
2048 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, PI_SAMR, NULL, "Query user groups", "" },
2049 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, PI_SAMR, NULL, "Query user aliases", "" },
2050 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, PI_SAMR, NULL, "Query group membership", "" },
2051 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, PI_SAMR, NULL, "Query alias membership", "" },
2052 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, PI_SAMR, NULL, "Delete an alias", "" },
2053 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, PI_SAMR, NULL, "Query display info", "" },
2054 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, PI_SAMR, NULL, "Query domain info", "" },
2055 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, PI_SAMR, NULL, "Enumerate domain users", "" },
2056 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, PI_SAMR, NULL, "Enumerate domain groups", "" },
2057 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, PI_SAMR, NULL, "Enumerate alias groups", "" },
2059 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, PI_SAMR, NULL, "Create domain user", "" },
2060 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, PI_SAMR, NULL, "Create domain group", "" },
2061 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, PI_SAMR, NULL, "Create domain alias", "" },
2062 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, PI_SAMR, NULL, "Look up names", "" },
2063 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, PI_SAMR, NULL, "Look up names", "" },
2064 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, PI_SAMR, NULL, "Delete domain user", "" },
2065 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, PI_SAMR, NULL, "Query SAMR security object", "" },
2066 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
2067 { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve user domain password info", "" },
2069 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },
2070 { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, PI_SAMR, NULL, "Change user password", "" },
2071 { NULL }