source: branches/samba-3.2.x/source/rpcclient/cmd_samr.c

Last change on this file was 136, checked in by Paul Smedley, 17 years ago

Update trunk to 3.2.0rc1

File size: 69.9 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
4
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
10
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.
15
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.
20
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/>.
23*/
24
25#include "includes.h"
26#include "rpcclient.h"
27
28extern DOM_SID domain_sid;
29
30/****************************************************************************
31 display samr_user_info_7 structure
32 ****************************************************************************/
33static void display_samr_user_info_7(struct samr_UserInfo7 *r)
34{
35 printf("\tUser Name :\t%s\n", r->account_name.string);
36}
37
38/****************************************************************************
39 display samr_user_info_9 structure
40 ****************************************************************************/
41static void display_samr_user_info_9(struct samr_UserInfo9 *r)
42{
43 printf("\tPrimary group RID :\tox%x\n", r->primary_gid);
44}
45
46/****************************************************************************
47 display samr_user_info_16 structure
48 ****************************************************************************/
49static void display_samr_user_info_16(struct samr_UserInfo16 *r)
50{
51 printf("\tAcct Flags :\tox%x\n", r->acct_flags);
52}
53
54/****************************************************************************
55 display samr_user_info_20 structure
56 ****************************************************************************/
57static void display_samr_user_info_20(struct samr_UserInfo20 *r)
58{
59 printf("\tRemote Dial :\n");
60 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
61}
62
63
64/****************************************************************************
65 display samr_user_info_21 structure
66 ****************************************************************************/
67static void display_samr_user_info_21(struct samr_UserInfo21 *r)
68{
69 printf("\tUser Name :\t%s\n", r->account_name.string);
70 printf("\tFull Name :\t%s\n", r->full_name.string);
71 printf("\tHome Drive :\t%s\n", r->home_directory.string);
72 printf("\tDir Drive :\t%s\n", r->home_drive.string);
73 printf("\tProfile Path:\t%s\n", r->profile_path.string);
74 printf("\tLogon Script:\t%s\n", r->logon_script.string);
75 printf("\tDescription :\t%s\n", r->description.string);
76 printf("\tWorkstations:\t%s\n", r->workstations.string);
77 printf("\tComment :\t%s\n", r->comment.string);
78 printf("\tRemote Dial :\n");
79 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
80
81 printf("\tLogon Time :\t%s\n",
82 http_timestring(nt_time_to_unix(r->last_logon)));
83 printf("\tLogoff Time :\t%s\n",
84 http_timestring(nt_time_to_unix(r->last_logoff)));
85 printf("\tKickoff Time :\t%s\n",
86 http_timestring(nt_time_to_unix(r->acct_expiry)));
87 printf("\tPassword last set Time :\t%s\n",
88 http_timestring(nt_time_to_unix(r->last_password_change)));
89 printf("\tPassword can change Time :\t%s\n",
90 http_timestring(nt_time_to_unix(r->allow_password_change)));
91 printf("\tPassword must change Time:\t%s\n",
92 http_timestring(nt_time_to_unix(r->force_password_change)));
93
94 printf("\tunknown_2[0..31]...\n"); /* user passwords? */
95
96 printf("\tuser_rid :\t0x%x\n" , r->rid); /* User ID */
97 printf("\tgroup_rid:\t0x%x\n" , r->primary_gid); /* Group ID */
98 printf("\tacb_info :\t0x%08x\n", r->acct_flags); /* Account Control Info */
99
100 printf("\tfields_present:\t0x%08x\n", r->fields_present); /* 0x00ff ffff */
101 printf("\tlogon_divs:\t%d\n", r->logon_hours.units_per_week); /* 0x0000 00a8 which is 168 which is num hrs in a week */
102 printf("\tbad_password_count:\t0x%08x\n", r->bad_password_count);
103 printf("\tlogon_count:\t0x%08x\n", r->logon_count);
104
105 printf("\tpadding1[0..7]...\n");
106
107 if (r->logon_hours.bits) {
108 printf("\tlogon_hrs[0..%d]...\n", r->logon_hours.units_per_week/8);
109 }
110}
111
112
113static void display_password_properties(uint32_t password_properties)
114{
115 printf("password_properties: 0x%08x\n", password_properties);
116
117 if (password_properties & DOMAIN_PASSWORD_COMPLEX)
118 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
119
120 if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
121 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
122
123 if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
124 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
125
126 if (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)
127 printf("\tDOMAIN_PASSWORD_LOCKOUT_ADMINS\n");
128
129 if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
130 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
131
132 if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
133 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
134}
135
136static void display_sam_dom_info_1(struct samr_DomInfo1 *info1)
137{
138 printf("Minimum password length:\t\t\t%d\n",
139 info1->min_password_length);
140 printf("Password uniqueness (remember x passwords):\t%d\n",
141 info1->password_history_length);
142 display_password_properties(info1->password_properties);
143 printf("password expire in:\t\t\t\t%s\n",
144 display_time(info1->max_password_age));
145 printf("Min password age (allow changing in x days):\t%s\n",
146 display_time(info1->min_password_age));
147}
148
149static void display_sam_dom_info_2(struct samr_DomInfo2 *info2)
150{
151 printf("Domain:\t\t%s\n", info2->domain_name.string);
152 printf("Server:\t\t%s\n", info2->primary.string);
153 printf("Comment:\t%s\n", info2->comment.string);
154
155 printf("Total Users:\t%d\n", info2->num_users);
156 printf("Total Groups:\t%d\n", info2->num_groups);
157 printf("Total Aliases:\t%d\n", info2->num_aliases);
158
159 printf("Sequence No:\t%llu\n", (unsigned long long)info2->sequence_num);
160
161 printf("Force Logoff:\t%d\n",
162 (int)nt_time_to_unix_abs(&info2->force_logoff_time));
163
164 printf("Unknown 2:\t0x%x\n", info2->unknown2);
165 printf("Server Role:\t%s\n", server_role_str(info2->role));
166 printf("Unknown 3:\t0x%x\n", info2->unknown3);
167}
168
169static void display_sam_dom_info_3(struct samr_DomInfo3 *info3)
170{
171 printf("Force Logoff:\t%d\n",
172 (int)nt_time_to_unix_abs(&info3->force_logoff_time));
173}
174
175static void display_sam_dom_info_4(struct samr_DomInfo4 *info4)
176{
177 printf("Comment:\t%s\n", info4->comment.string);
178}
179
180static void display_sam_dom_info_5(struct samr_DomInfo5 *info5)
181{
182 printf("Domain:\t\t%s\n", info5->domain_name.string);
183}
184
185static void display_sam_dom_info_6(struct samr_DomInfo6 *info6)
186{
187 printf("Server:\t\t%s\n", info6->primary.string);
188}
189
190static void display_sam_dom_info_7(struct samr_DomInfo7 *info7)
191{
192 printf("Server Role:\t%s\n", server_role_str(info7->role));
193}
194
195static void display_sam_dom_info_8(struct samr_DomInfo8 *info8)
196{
197 printf("Sequence No:\t%llu\n", (unsigned long long)info8->sequence_num);
198 printf("Domain Create Time:\t%s\n",
199 http_timestring(nt_time_to_unix(info8->domain_create_time)));
200}
201
202static void display_sam_dom_info_9(struct samr_DomInfo9 *info9)
203{
204 printf("unknown:\t%d (0x%08x)\n", info9->unknown, info9->unknown);
205}
206
207static void display_sam_dom_info_12(struct samr_DomInfo12 *info12)
208{
209 printf("Bad password lockout duration: %s\n",
210 display_time(info12->lockout_duration));
211 printf("Reset Lockout after: %s\n",
212 display_time(info12->lockout_window));
213 printf("Lockout after bad attempts: %d\n",
214 info12->lockout_threshold);
215}
216
217static void display_sam_dom_info_13(struct samr_DomInfo13 *info13)
218{
219 printf("Sequence No:\t%llu\n", (unsigned long long)info13->sequence_num);
220 printf("Domain Create Time:\t%s\n",
221 http_timestring(nt_time_to_unix(info13->domain_create_time)));
222 printf("Unknown1:\t%d\n", info13->unknown1);
223 printf("Unknown2:\t%d\n", info13->unknown2);
224
225}
226
227static void display_sam_info_1(struct samr_DispEntryGeneral *r)
228{
229 printf("index: 0x%x ", r->idx);
230 printf("RID: 0x%x ", r->rid);
231 printf("acb: 0x%08x ", r->acct_flags);
232 printf("Account: %s\t", r->account_name.string);
233 printf("Name: %s\t", r->full_name.string);
234 printf("Desc: %s\n", r->description.string);
235}
236
237static void display_sam_info_2(struct samr_DispEntryFull *r)
238{
239 printf("index: 0x%x ", r->idx);
240 printf("RID: 0x%x ", r->rid);
241 printf("acb: 0x%08x ", r->acct_flags);
242 printf("Account: %s\t", r->account_name.string);
243 printf("Desc: %s\n", r->description.string);
244}
245
246static void display_sam_info_3(struct samr_DispEntryFullGroup *r)
247{
248 printf("index: 0x%x ", r->idx);
249 printf("RID: 0x%x ", r->rid);
250 printf("acb: 0x%08x ", r->acct_flags);
251 printf("Account: %s\t", r->account_name.string);
252 printf("Desc: %s\n", r->description.string);
253}
254
255static void display_sam_info_4(struct samr_DispEntryAscii *r)
256{
257 printf("index: 0x%x ", r->idx);
258 printf("Account: %s\n", r->account_name.string);
259}
260
261static void display_sam_info_5(struct samr_DispEntryAscii *r)
262{
263 printf("index: 0x%x ", r->idx);
264 printf("Account: %s\n", r->account_name.string);
265}
266
267/**********************************************************************
268 * Query user information
269 */
270static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
271 TALLOC_CTX *mem_ctx,
272 int argc, const char **argv)
273{
274 POLICY_HND connect_pol, domain_pol, user_pol;
275 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
276 uint32 info_level = 21;
277 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
278 union samr_UserInfo *info = NULL;
279 uint32 user_rid = 0;
280
281 if ((argc < 2) || (argc > 4)) {
282 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
283 return NT_STATUS_OK;
284 }
285
286 sscanf(argv[1], "%i", &user_rid);
287
288 if (argc > 2)
289 sscanf(argv[2], "%i", &info_level);
290
291 if (argc > 3)
292 sscanf(argv[3], "%x", &access_mask);
293
294
295 result = rpccli_try_samr_connects(cli, mem_ctx,
296 MAXIMUM_ALLOWED_ACCESS,
297 &connect_pol);
298
299 if (!NT_STATUS_IS_OK(result))
300 goto done;
301
302 result = rpccli_samr_OpenDomain(cli, mem_ctx,
303 &connect_pol,
304 MAXIMUM_ALLOWED_ACCESS,
305 &domain_sid,
306 &domain_pol);
307 if (!NT_STATUS_IS_OK(result))
308 goto done;
309
310 result = rpccli_samr_OpenUser(cli, mem_ctx,
311 &domain_pol,
312 access_mask,
313 user_rid,
314 &user_pol);
315
316 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
317 (user_rid == 0)) {
318
319 /* Probably this was a user name, try lookupnames */
320 struct samr_Ids rids, types;
321 struct lsa_String lsa_acct_name;
322
323 init_lsa_String(&lsa_acct_name, argv[1]);
324
325 result = rpccli_samr_LookupNames(cli, mem_ctx,
326 &domain_pol,
327 1,
328 &lsa_acct_name,
329 &rids,
330 &types);
331
332 if (NT_STATUS_IS_OK(result)) {
333 result = rpccli_samr_OpenUser(cli, mem_ctx,
334 &domain_pol,
335 access_mask,
336 rids.ids[0],
337 &user_pol);
338 }
339 }
340
341
342 if (!NT_STATUS_IS_OK(result))
343 goto done;
344
345 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
346 &user_pol,
347 info_level,
348 &info);
349
350 if (!NT_STATUS_IS_OK(result))
351 goto done;
352
353 switch (info_level) {
354 case 7:
355 display_samr_user_info_7(&info->info7);
356 break;
357 case 9:
358 display_samr_user_info_9(&info->info9);
359 break;
360 case 16:
361 display_samr_user_info_16(&info->info16);
362 break;
363 case 20:
364 display_samr_user_info_20(&info->info20);
365 break;
366 case 21:
367 display_samr_user_info_21(&info->info21);
368 break;
369 default:
370 printf("Unsupported infolevel: %d\n", info_level);
371 break;
372 }
373
374 rpccli_samr_Close(cli, mem_ctx, &user_pol);
375 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
376 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
377
378done:
379 return result;
380}
381
382/****************************************************************************
383 display group info
384 ****************************************************************************/
385static void display_group_info1(struct samr_GroupInfoAll *info1)
386{
387 printf("\tGroup Name:\t%s\n", info1->name.string);
388 printf("\tDescription:\t%s\n", info1->description.string);
389 printf("\tGroup Attribute:%d\n", info1->attributes);
390 printf("\tNum Members:%d\n", info1->num_members);
391}
392
393/****************************************************************************
394 display group info
395 ****************************************************************************/
396static void display_group_info2(struct lsa_String *info2)
397{
398 printf("\tGroup Description:%s\n", info2->string);
399}
400
401
402/****************************************************************************
403 display group info
404 ****************************************************************************/
405static void display_group_info3(struct samr_GroupInfoAttributes *info3)
406{
407 printf("\tGroup Attribute:%d\n", info3->attributes);
408}
409
410
411/****************************************************************************
412 display group info
413 ****************************************************************************/
414static void display_group_info4(struct lsa_String *info4)
415{
416 printf("\tGroup Description:%s\n", info4->string);
417}
418
419/****************************************************************************
420 display group info
421 ****************************************************************************/
422static void display_group_info5(struct samr_GroupInfoAll *info5)
423{
424 printf("\tGroup Name:\t%s\n", info5->name.string);
425 printf("\tDescription:\t%s\n", info5->description.string);
426 printf("\tGroup Attribute:%d\n", info5->attributes);
427 printf("\tNum Members:%d\n", info5->num_members);
428}
429
430/****************************************************************************
431 display sam sync structure
432 ****************************************************************************/
433static void display_group_info(union samr_GroupInfo *info,
434 enum samr_GroupInfoEnum level)
435{
436 switch (level) {
437 case 1:
438 display_group_info1(&info->all);
439 break;
440 case 2:
441 display_group_info2(&info->name);
442 break;
443 case 3:
444 display_group_info3(&info->attributes);
445 break;
446 case 4:
447 display_group_info4(&info->description);
448 break;
449 case 5:
450 display_group_info5(&info->all2);
451 break;
452 }
453}
454
455/***********************************************************************
456 * Query group information
457 */
458static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
459 TALLOC_CTX *mem_ctx,
460 int argc, const char **argv)
461{
462 POLICY_HND connect_pol, domain_pol, group_pol;
463 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
464 enum samr_GroupInfoEnum info_level = GROUPINFOALL;
465 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
466 union samr_GroupInfo *group_info = NULL;
467 uint32 group_rid;
468
469 if ((argc < 2) || (argc > 4)) {
470 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
471 return NT_STATUS_OK;
472 }
473
474 sscanf(argv[1], "%i", &group_rid);
475
476 if (argc > 2)
477 info_level = atoi(argv[2]);
478
479 if (argc > 3)
480 sscanf(argv[3], "%x", &access_mask);
481
482 result = rpccli_try_samr_connects(cli, mem_ctx,
483 MAXIMUM_ALLOWED_ACCESS,
484 &connect_pol);
485
486 if (!NT_STATUS_IS_OK(result))
487 goto done;
488
489 result = rpccli_samr_OpenDomain(cli, mem_ctx,
490 &connect_pol,
491 MAXIMUM_ALLOWED_ACCESS,
492 &domain_sid,
493 &domain_pol);
494
495 if (!NT_STATUS_IS_OK(result))
496 goto done;
497
498 result = rpccli_samr_OpenGroup(cli, mem_ctx,
499 &domain_pol,
500 access_mask,
501 group_rid,
502 &group_pol);
503
504 if (!NT_STATUS_IS_OK(result))
505 goto done;
506
507 result = rpccli_samr_QueryGroupInfo(cli, mem_ctx,
508 &group_pol,
509 info_level,
510 &group_info);
511 if (!NT_STATUS_IS_OK(result)) {
512 goto done;
513 }
514
515 display_group_info(group_info, info_level);
516
517 rpccli_samr_Close(cli, mem_ctx, &group_pol);
518 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
519 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
520done:
521 return result;
522}
523
524/* Query groups a user is a member of */
525
526static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
527 TALLOC_CTX *mem_ctx,
528 int argc, const char **argv)
529{
530 POLICY_HND connect_pol,
531 domain_pol,
532 user_pol;
533 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
534 uint32 user_rid;
535 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
536 int i;
537 struct samr_RidWithAttributeArray *rid_array = NULL;
538
539 if ((argc < 2) || (argc > 3)) {
540 printf("Usage: %s rid [access mask]\n", argv[0]);
541 return NT_STATUS_OK;
542 }
543
544 sscanf(argv[1], "%i", &user_rid);
545
546 if (argc > 2)
547 sscanf(argv[2], "%x", &access_mask);
548
549 result = rpccli_try_samr_connects(cli, mem_ctx,
550 MAXIMUM_ALLOWED_ACCESS,
551 &connect_pol);
552
553 if (!NT_STATUS_IS_OK(result))
554 goto done;
555
556 result = rpccli_samr_OpenDomain(cli, mem_ctx,
557 &connect_pol,
558 MAXIMUM_ALLOWED_ACCESS,
559 &domain_sid, &domain_pol);
560
561 if (!NT_STATUS_IS_OK(result))
562 goto done;
563
564 result = rpccli_samr_OpenUser(cli, mem_ctx,
565 &domain_pol,
566 access_mask,
567 user_rid,
568 &user_pol);
569
570 if (!NT_STATUS_IS_OK(result))
571 goto done;
572
573 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
574 &user_pol,
575 &rid_array);
576
577 if (!NT_STATUS_IS_OK(result))
578 goto done;
579
580 for (i = 0; i < rid_array->count; i++) {
581 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
582 rid_array->rids[i].rid,
583 rid_array->rids[i].attributes);
584 }
585
586 rpccli_samr_Close(cli, mem_ctx, &user_pol);
587 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
588 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
589 done:
590 return result;
591}
592
593/* Query aliases a user is a member of */
594
595static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
596 TALLOC_CTX *mem_ctx,
597 int argc, const char **argv)
598{
599 POLICY_HND connect_pol, domain_pol;
600 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
601 DOM_SID *sids;
602 size_t num_sids;
603 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
604 int i;
605 struct lsa_SidArray sid_array;
606 struct samr_Ids alias_rids;
607
608 if (argc < 3) {
609 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
610 return NT_STATUS_INVALID_PARAMETER;
611 }
612
613 sids = NULL;
614 num_sids = 0;
615
616 for (i=2; i<argc; i++) {
617 DOM_SID tmp_sid;
618 if (!string_to_sid(&tmp_sid, argv[i])) {
619 printf("%s is not a legal SID\n", argv[i]);
620 return NT_STATUS_INVALID_PARAMETER;
621 }
622 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
623 if (!NT_STATUS_IS_OK(result)) {
624 return result;
625 }
626 }
627
628 if (num_sids) {
629 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids);
630 if (sid_array.sids == NULL)
631 return NT_STATUS_NO_MEMORY;
632 } else {
633 sid_array.sids = NULL;
634 }
635
636 for (i=0; i<num_sids; i++) {
637 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[i]);
638 if (!sid_array.sids[i].sid) {
639 return NT_STATUS_NO_MEMORY;
640 }
641 }
642
643 sid_array.num_sids = num_sids;
644
645 result = rpccli_try_samr_connects(cli, mem_ctx,
646 MAXIMUM_ALLOWED_ACCESS,
647 &connect_pol);
648
649 if (!NT_STATUS_IS_OK(result))
650 goto done;
651
652 if (StrCaseCmp(argv[1], "domain")==0)
653 result = rpccli_samr_OpenDomain(cli, mem_ctx,
654 &connect_pol,
655 access_mask,
656 &domain_sid, &domain_pol);
657 else if (StrCaseCmp(argv[1], "builtin")==0)
658 result = rpccli_samr_OpenDomain(cli, mem_ctx,
659 &connect_pol,
660 access_mask,
661 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
662 &domain_pol);
663 else {
664 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
665 return NT_STATUS_INVALID_PARAMETER;
666 }
667
668 if (!NT_STATUS_IS_OK(result))
669 goto done;
670
671 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
672 &domain_pol,
673 &sid_array,
674 &alias_rids);
675 if (!NT_STATUS_IS_OK(result))
676 goto done;
677
678 for (i = 0; i < alias_rids.count; i++) {
679 printf("\tgroup rid:[0x%x]\n", alias_rids.ids[i]);
680 }
681
682 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
683 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
684 done:
685 return result;
686}
687
688/* Query members of a group */
689
690static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
691 TALLOC_CTX *mem_ctx,
692 int argc, const char **argv)
693{
694 POLICY_HND connect_pol, domain_pol, group_pol;
695 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
696 uint32 group_rid;
697 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
698 int i;
699 unsigned int old_timeout;
700 struct samr_RidTypeArray *rids = NULL;
701
702 if ((argc < 2) || (argc > 3)) {
703 printf("Usage: %s rid [access mask]\n", argv[0]);
704 return NT_STATUS_OK;
705 }
706
707 sscanf(argv[1], "%i", &group_rid);
708
709 if (argc > 2)
710 sscanf(argv[2], "%x", &access_mask);
711
712 result = rpccli_try_samr_connects(cli, mem_ctx,
713 MAXIMUM_ALLOWED_ACCESS,
714 &connect_pol);
715
716 if (!NT_STATUS_IS_OK(result))
717 goto done;
718
719 result = rpccli_samr_OpenDomain(cli, mem_ctx,
720 &connect_pol,
721 MAXIMUM_ALLOWED_ACCESS,
722 &domain_sid,
723 &domain_pol);
724
725 if (!NT_STATUS_IS_OK(result))
726 goto done;
727
728 result = rpccli_samr_OpenGroup(cli, mem_ctx,
729 &domain_pol,
730 access_mask,
731 group_rid,
732 &group_pol);
733
734 if (!NT_STATUS_IS_OK(result))
735 goto done;
736
737 /* Make sure to wait for our DC's reply */
738 old_timeout = cli_set_timeout(cli->cli, MAX(cli->cli->timeout,30000)); /* 30 seconds. */
739
740 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
741 &group_pol,
742 &rids);
743
744 cli_set_timeout(cli->cli, old_timeout);
745
746 if (!NT_STATUS_IS_OK(result))
747 goto done;
748
749 for (i = 0; i < rids->count; i++) {
750 printf("\trid:[0x%x] attr:[0x%x]\n", rids->rids[i],
751 rids->types[i]);
752 }
753
754 rpccli_samr_Close(cli, mem_ctx, &group_pol);
755 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
756 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
757 done:
758 return result;
759}
760
761/* Enumerate domain users */
762
763static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
764 TALLOC_CTX *mem_ctx,
765 int argc, const char **argv)
766{
767 POLICY_HND connect_pol, domain_pol;
768 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
769 uint32 start_idx, size, num_dom_users, i;
770 struct samr_SamArray *dom_users = NULL;
771 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
772 uint32 acb_mask = ACB_NORMAL;
773 bool got_connect_pol = False, got_domain_pol = False;
774
775 if ((argc < 1) || (argc > 3)) {
776 printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
777 return NT_STATUS_OK;
778 }
779
780 if (argc > 1)
781 sscanf(argv[1], "%x", &access_mask);
782
783 if (argc > 2)
784 sscanf(argv[2], "%x", &acb_mask);
785
786 /* Get sam policy handle */
787
788 result = rpccli_try_samr_connects(cli, mem_ctx,
789 MAXIMUM_ALLOWED_ACCESS,
790 &connect_pol);
791
792 if (!NT_STATUS_IS_OK(result))
793 goto done;
794
795 got_connect_pol = True;
796
797 /* Get domain policy handle */
798
799 result = rpccli_samr_OpenDomain(cli, mem_ctx,
800 &connect_pol,
801 access_mask,
802 &domain_sid,
803 &domain_pol);
804
805 if (!NT_STATUS_IS_OK(result))
806 goto done;
807
808 got_domain_pol = True;
809
810 /* Enumerate domain users */
811
812 start_idx = 0;
813 size = 0xffff;
814
815 do {
816 result = rpccli_samr_EnumDomainUsers(cli, mem_ctx,
817 &domain_pol,
818 &start_idx,
819 acb_mask,
820 &dom_users,
821 size,
822 &num_dom_users);
823
824 if (NT_STATUS_IS_OK(result) ||
825 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
826
827 for (i = 0; i < num_dom_users; i++)
828 printf("user:[%s] rid:[0x%x]\n",
829 dom_users->entries[i].name.string,
830 dom_users->entries[i].idx);
831 }
832
833 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
834
835 done:
836 if (got_domain_pol)
837 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
838
839 if (got_connect_pol)
840 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
841
842 return result;
843}
844
845/* Enumerate domain groups */
846
847static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
848 TALLOC_CTX *mem_ctx,
849 int argc, const char **argv)
850{
851 POLICY_HND connect_pol, domain_pol;
852 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
853 uint32 start_idx, size, num_dom_groups, i;
854 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
855 struct samr_SamArray *dom_groups = NULL;
856 bool got_connect_pol = False, got_domain_pol = False;
857
858 if ((argc < 1) || (argc > 2)) {
859 printf("Usage: %s [access_mask]\n", argv[0]);
860 return NT_STATUS_OK;
861 }
862
863 if (argc > 1)
864 sscanf(argv[1], "%x", &access_mask);
865
866 /* Get sam policy handle */
867
868 result = rpccli_try_samr_connects(cli, mem_ctx,
869 MAXIMUM_ALLOWED_ACCESS,
870 &connect_pol);
871
872 if (!NT_STATUS_IS_OK(result))
873 goto done;
874
875 got_connect_pol = True;
876
877 /* Get domain policy handle */
878
879 result = rpccli_samr_OpenDomain(cli, mem_ctx,
880 &connect_pol,
881 access_mask,
882 &domain_sid,
883 &domain_pol);
884
885 if (!NT_STATUS_IS_OK(result))
886 goto done;
887
888 got_domain_pol = True;
889
890 /* Enumerate domain groups */
891
892 start_idx = 0;
893 size = 0xffff;
894
895 do {
896 result = rpccli_samr_EnumDomainGroups(cli, mem_ctx,
897 &domain_pol,
898 &start_idx,
899 &dom_groups,
900 size,
901 &num_dom_groups);
902 if (NT_STATUS_IS_OK(result) ||
903 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
904
905 for (i = 0; i < num_dom_groups; i++)
906 printf("group:[%s] rid:[0x%x]\n",
907 dom_groups->entries[i].name.string,
908 dom_groups->entries[i].idx);
909 }
910
911 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
912
913 done:
914 if (got_domain_pol)
915 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
916
917 if (got_connect_pol)
918 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
919
920 return result;
921}
922
923/* Enumerate alias groups */
924
925static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
926 TALLOC_CTX *mem_ctx,
927 int argc, const char **argv)
928{
929 POLICY_HND connect_pol, domain_pol;
930 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
931 uint32 start_idx, size, num_als_groups, i;
932 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
933 struct samr_SamArray *als_groups = NULL;
934 bool got_connect_pol = False, got_domain_pol = False;
935
936 if ((argc < 2) || (argc > 3)) {
937 printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
938 return NT_STATUS_OK;
939 }
940
941 if (argc > 2)
942 sscanf(argv[2], "%x", &access_mask);
943
944 /* Get sam policy handle */
945
946 result = rpccli_try_samr_connects(cli, mem_ctx,
947 MAXIMUM_ALLOWED_ACCESS,
948 &connect_pol);
949
950 if (!NT_STATUS_IS_OK(result))
951 goto done;
952
953 got_connect_pol = True;
954
955 /* Get domain policy handle */
956
957 if (StrCaseCmp(argv[1], "domain")==0)
958 result = rpccli_samr_OpenDomain(cli, mem_ctx,
959 &connect_pol,
960 access_mask,
961 &domain_sid,
962 &domain_pol);
963 else if (StrCaseCmp(argv[1], "builtin")==0)
964 result = rpccli_samr_OpenDomain(cli, mem_ctx,
965 &connect_pol,
966 access_mask,
967 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
968 &domain_pol);
969 else
970 return NT_STATUS_OK;
971
972 if (!NT_STATUS_IS_OK(result))
973 goto done;
974
975 got_domain_pol = True;
976
977 /* Enumerate alias groups */
978
979 start_idx = 0;
980 size = 0xffff; /* Number of groups to retrieve */
981
982 do {
983 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx,
984 &domain_pol,
985 &start_idx,
986 &als_groups,
987 size,
988 &num_als_groups);
989
990 if (NT_STATUS_IS_OK(result) ||
991 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
992
993 for (i = 0; i < num_als_groups; i++)
994 printf("group:[%s] rid:[0x%x]\n",
995 als_groups->entries[i].name.string,
996 als_groups->entries[i].idx);
997 }
998 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
999
1000 done:
1001 if (got_domain_pol)
1002 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1003
1004 if (got_connect_pol)
1005 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1006
1007 return result;
1008}
1009
1010/* Enumerate domains */
1011
1012static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
1013 TALLOC_CTX *mem_ctx,
1014 int argc, const char **argv)
1015{
1016 POLICY_HND connect_pol;
1017 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1018 uint32 start_idx, size, num_entries, i;
1019 uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1020 bool got_connect_pol = false;
1021 struct samr_SamArray *sam = NULL;
1022
1023 if ((argc < 1) || (argc > 2)) {
1024 printf("Usage: %s [access mask]\n", argv[0]);
1025 return NT_STATUS_OK;
1026 }
1027
1028 if (argc > 1) {
1029 sscanf(argv[1], "%x", &access_mask);
1030 }
1031
1032 /* Get sam policy handle */
1033
1034 result = rpccli_try_samr_connects(cli, mem_ctx,
1035 access_mask,
1036 &connect_pol);
1037
1038 if (!NT_STATUS_IS_OK(result)) {
1039 goto done;
1040 }
1041
1042 got_connect_pol = true;
1043
1044 /* Enumerate alias groups */
1045
1046 start_idx = 0;
1047 size = 0xffff;
1048
1049 do {
1050 result = rpccli_samr_EnumDomains(cli, mem_ctx,
1051 &connect_pol,
1052 &start_idx,
1053 &sam,
1054 size,
1055 &num_entries);
1056
1057 if (NT_STATUS_IS_OK(result) ||
1058 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1059
1060 for (i = 0; i < num_entries; i++)
1061 printf("name:[%s] idx:[0x%x]\n",
1062 sam->entries[i].name.string,
1063 sam->entries[i].idx);
1064 }
1065 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1066
1067 done:
1068 if (got_connect_pol) {
1069 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1070 }
1071
1072 return result;
1073}
1074
1075
1076/* Query alias membership */
1077
1078static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1079 TALLOC_CTX *mem_ctx,
1080 int argc, const char **argv)
1081{
1082 POLICY_HND connect_pol, domain_pol, alias_pol;
1083 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1084 uint32 alias_rid, i;
1085 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1086 struct lsa_SidArray sid_array;
1087
1088 if ((argc < 3) || (argc > 4)) {
1089 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1090 return NT_STATUS_OK;
1091 }
1092
1093 sscanf(argv[2], "%i", &alias_rid);
1094
1095 if (argc > 3)
1096 sscanf(argv[3], "%x", &access_mask);
1097
1098 /* Open SAMR handle */
1099
1100 result = rpccli_try_samr_connects(cli, mem_ctx,
1101 MAXIMUM_ALLOWED_ACCESS,
1102 &connect_pol);
1103
1104 if (!NT_STATUS_IS_OK(result))
1105 goto done;
1106
1107 /* Open handle on domain */
1108
1109 if (StrCaseCmp(argv[1], "domain")==0)
1110 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1111 &connect_pol,
1112 MAXIMUM_ALLOWED_ACCESS,
1113 &domain_sid,
1114 &domain_pol);
1115 else if (StrCaseCmp(argv[1], "builtin")==0)
1116 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1117 &connect_pol,
1118 MAXIMUM_ALLOWED_ACCESS,
1119 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1120 &domain_pol);
1121 else
1122 return NT_STATUS_OK;
1123
1124 if (!NT_STATUS_IS_OK(result))
1125 goto done;
1126
1127 /* Open handle on alias */
1128
1129 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1130 &domain_pol,
1131 access_mask,
1132 alias_rid,
1133 &alias_pol);
1134 if (!NT_STATUS_IS_OK(result))
1135 goto done;
1136
1137 result = rpccli_samr_GetMembersInAlias(cli, mem_ctx,
1138 &alias_pol,
1139 &sid_array);
1140
1141 if (!NT_STATUS_IS_OK(result))
1142 goto done;
1143
1144 for (i = 0; i < sid_array.num_sids; i++) {
1145 fstring sid_str;
1146
1147 sid_to_fstring(sid_str, sid_array.sids[i].sid);
1148 printf("\tsid:[%s]\n", sid_str);
1149 }
1150
1151 rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1152 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1153 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1154 done:
1155 return result;
1156}
1157
1158/* Query alias info */
1159
1160static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
1161 TALLOC_CTX *mem_ctx,
1162 int argc, const char **argv)
1163{
1164 POLICY_HND connect_pol, domain_pol, alias_pol;
1165 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1166 uint32_t alias_rid;
1167 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1168 union samr_AliasInfo *info = NULL;
1169 enum samr_AliasInfoEnum level = ALIASINFOALL;
1170
1171 if ((argc < 3) || (argc > 4)) {
1172 printf("Usage: %s builtin|domain rid [level] [access mask]\n",
1173 argv[0]);
1174 return NT_STATUS_OK;
1175 }
1176
1177 sscanf(argv[2], "%i", &alias_rid);
1178
1179 if (argc > 2) {
1180 level = atoi(argv[3]);
1181 }
1182
1183 if (argc > 3) {
1184 sscanf(argv[4], "%x", &access_mask);
1185 }
1186
1187 /* Open SAMR handle */
1188
1189 result = rpccli_try_samr_connects(cli, mem_ctx,
1190 SEC_FLAG_MAXIMUM_ALLOWED,
1191 &connect_pol);
1192
1193 if (!NT_STATUS_IS_OK(result)) {
1194 goto done;
1195 }
1196
1197 /* Open handle on domain */
1198
1199 if (strequal(argv[1], "domain")) {
1200
1201 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1202 &connect_pol,
1203 SEC_FLAG_MAXIMUM_ALLOWED,
1204 &domain_sid,
1205 &domain_pol);
1206
1207 } else if (strequal(argv[1], "builtin")) {
1208
1209 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1210 &connect_pol,
1211 SEC_FLAG_MAXIMUM_ALLOWED,
1212 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1213 &domain_pol);
1214
1215 } else {
1216 return NT_STATUS_OK;
1217 }
1218
1219 if (!NT_STATUS_IS_OK(result)) {
1220 goto done;
1221 }
1222
1223 /* Open handle on alias */
1224
1225 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1226 &domain_pol,
1227 access_mask,
1228 alias_rid,
1229 &alias_pol);
1230 if (!NT_STATUS_IS_OK(result)) {
1231 goto done;
1232 }
1233
1234 result = rpccli_samr_QueryAliasInfo(cli, mem_ctx,
1235 &alias_pol,
1236 level,
1237 &info);
1238
1239 if (!NT_STATUS_IS_OK(result)) {
1240 goto done;
1241 }
1242
1243 switch (level) {
1244 case ALIASINFOALL:
1245 printf("Name: %s\n", info->all.name.string);
1246 printf("Description: %s\n", info->all.description.string);
1247 printf("Num Members: %d\n", info->all.num_members);
1248 break;
1249 case ALIASINFONAME:
1250 printf("Name: %s\n", info->name.string);
1251 break;
1252 case ALIASINFODESCRIPTION:
1253 printf("Description: %s\n", info->description.string);
1254 break;
1255 default:
1256 break;
1257 }
1258
1259 rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1260 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1261 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1262 done:
1263 return result;
1264}
1265
1266
1267/* Query delete an alias membership */
1268
1269static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1270 TALLOC_CTX *mem_ctx,
1271 int argc, const char **argv)
1272{
1273 POLICY_HND connect_pol, domain_pol, alias_pol;
1274 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1275 uint32 alias_rid;
1276 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1277
1278 if (argc != 3) {
1279 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1280 return NT_STATUS_OK;
1281 }
1282
1283 alias_rid = strtoul(argv[2], NULL, 10);
1284
1285 /* Open SAMR handle */
1286
1287 result = rpccli_try_samr_connects(cli, mem_ctx,
1288 MAXIMUM_ALLOWED_ACCESS,
1289 &connect_pol);
1290
1291 if (!NT_STATUS_IS_OK(result))
1292 goto done;
1293
1294 /* Open handle on domain */
1295
1296 if (StrCaseCmp(argv[1], "domain")==0)
1297 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1298 &connect_pol,
1299 MAXIMUM_ALLOWED_ACCESS,
1300 &domain_sid,
1301 &domain_pol);
1302 else if (StrCaseCmp(argv[1], "builtin")==0)
1303 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1304 &connect_pol,
1305 MAXIMUM_ALLOWED_ACCESS,
1306 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1307 &domain_pol);
1308 else
1309 return NT_STATUS_INVALID_PARAMETER;
1310
1311 if (!NT_STATUS_IS_OK(result))
1312 goto done;
1313
1314 /* Open handle on alias */
1315
1316 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1317 &domain_pol,
1318 access_mask,
1319 alias_rid,
1320 &alias_pol);
1321 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1322 /* Probably this was a user name, try lookupnames */
1323 struct samr_Ids rids, types;
1324 struct lsa_String lsa_acct_name;
1325
1326 init_lsa_String(&lsa_acct_name, argv[2]);
1327
1328 result = rpccli_samr_LookupNames(cli, mem_ctx,
1329 &domain_pol,
1330 1,
1331 &lsa_acct_name,
1332 &rids,
1333 &types);
1334
1335 if (NT_STATUS_IS_OK(result)) {
1336 result = rpccli_samr_OpenAlias(cli, mem_ctx,
1337 &domain_pol,
1338 access_mask,
1339 rids.ids[0],
1340 &alias_pol);
1341 }
1342 }
1343
1344 result = rpccli_samr_DeleteDomAlias(cli, mem_ctx,
1345 &alias_pol);
1346
1347 if (!NT_STATUS_IS_OK(result))
1348 goto done;
1349
1350 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1351 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1352 done:
1353 return result;
1354}
1355
1356/* Query display info */
1357
1358static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli,
1359 TALLOC_CTX *mem_ctx,
1360 int argc, const char **argv,
1361 uint32_t opcode)
1362{
1363 POLICY_HND connect_pol, domain_pol;
1364 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1365 uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
1366 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1367 uint32 info_level = 1;
1368 union samr_DispInfo info;
1369 int loop_count = 0;
1370 bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1371 uint32_t total_size, returned_size;
1372
1373 if (argc > 6) {
1374 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1375 return NT_STATUS_OK;
1376 }
1377
1378 if (argc >= 2)
1379 sscanf(argv[1], "%i", &info_level);
1380
1381 if (argc >= 3)
1382 sscanf(argv[2], "%i", &start_idx);
1383
1384 if (argc >= 4) {
1385 sscanf(argv[3], "%i", &max_entries);
1386 got_params = True;
1387 }
1388
1389 if (argc >= 5) {
1390 sscanf(argv[4], "%i", &max_size);
1391 got_params = True;
1392 }
1393
1394 if (argc >= 6)
1395 sscanf(argv[5], "%x", &access_mask);
1396
1397 /* Get sam policy handle */
1398
1399 result = rpccli_try_samr_connects(cli, mem_ctx,
1400 MAXIMUM_ALLOWED_ACCESS,
1401 &connect_pol);
1402
1403 if (!NT_STATUS_IS_OK(result))
1404 goto done;
1405
1406 /* Get domain policy handle */
1407
1408 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1409 &connect_pol,
1410 access_mask,
1411 &domain_sid,
1412 &domain_pol);
1413
1414 if (!NT_STATUS_IS_OK(result))
1415 goto done;
1416
1417 /* Query display info */
1418
1419 do {
1420
1421 if (!got_params)
1422 get_query_dispinfo_params(
1423 loop_count, &max_entries, &max_size);
1424
1425 switch (opcode) {
1426 case NDR_SAMR_QUERYDISPLAYINFO:
1427 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
1428 &domain_pol,
1429 info_level,
1430 start_idx,
1431 max_entries,
1432 max_size,
1433 &total_size,
1434 &returned_size,
1435 &info);
1436 break;
1437 case NDR_SAMR_QUERYDISPLAYINFO2:
1438 result = rpccli_samr_QueryDisplayInfo2(cli, mem_ctx,
1439 &domain_pol,
1440 info_level,
1441 start_idx,
1442 max_entries,
1443 max_size,
1444 &total_size,
1445 &returned_size,
1446 &info);
1447
1448 break;
1449 case NDR_SAMR_QUERYDISPLAYINFO3:
1450 result = rpccli_samr_QueryDisplayInfo3(cli, mem_ctx,
1451 &domain_pol,
1452 info_level,
1453 start_idx,
1454 max_entries,
1455 max_size,
1456 &total_size,
1457 &returned_size,
1458 &info);
1459
1460 break;
1461 default:
1462 return NT_STATUS_INVALID_PARAMETER;
1463 }
1464
1465 if (!NT_STATUS_IS_OK(result) &&
1466 !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
1467 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1468 break;
1469 }
1470
1471 loop_count++;
1472
1473 switch (info_level) {
1474 case 1:
1475 num_entries = info.info1.count;
1476 break;
1477 case 2:
1478 num_entries = info.info2.count;
1479 break;
1480 case 3:
1481 num_entries = info.info3.count;
1482 break;
1483 case 4:
1484 num_entries = info.info4.count;
1485 break;
1486 case 5:
1487 num_entries = info.info5.count;
1488 break;
1489 default:
1490 break;
1491 }
1492
1493 start_idx += num_entries;
1494
1495 if (num_entries == 0)
1496 break;
1497
1498 for (i = 0; i < num_entries; i++) {
1499 switch (info_level) {
1500 case 1:
1501 display_sam_info_1(&info.info1.entries[i]);
1502 break;
1503 case 2:
1504 display_sam_info_2(&info.info2.entries[i]);
1505 break;
1506 case 3:
1507 display_sam_info_3(&info.info3.entries[i]);
1508 break;
1509 case 4:
1510 display_sam_info_4(&info.info4.entries[i]);
1511 break;
1512 case 5:
1513 display_sam_info_5(&info.info5.entries[i]);
1514 break;
1515 }
1516 }
1517 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1518
1519 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1520 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1521 done:
1522 return result;
1523}
1524
1525static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1526 TALLOC_CTX *mem_ctx,
1527 int argc, const char **argv)
1528{
1529 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1530 NDR_SAMR_QUERYDISPLAYINFO);
1531}
1532
1533static NTSTATUS cmd_samr_query_dispinfo2(struct rpc_pipe_client *cli,
1534 TALLOC_CTX *mem_ctx,
1535 int argc, const char **argv)
1536{
1537 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1538 NDR_SAMR_QUERYDISPLAYINFO2);
1539}
1540
1541static NTSTATUS cmd_samr_query_dispinfo3(struct rpc_pipe_client *cli,
1542 TALLOC_CTX *mem_ctx,
1543 int argc, const char **argv)
1544{
1545 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1546 NDR_SAMR_QUERYDISPLAYINFO3);
1547}
1548
1549/* Query domain info */
1550
1551static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1552 TALLOC_CTX *mem_ctx,
1553 int argc, const char **argv)
1554{
1555 POLICY_HND connect_pol, domain_pol;
1556 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1557 uint32 switch_level = 2;
1558 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1559 union samr_DomainInfo *info = NULL;
1560
1561 if (argc > 3) {
1562 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1563 return NT_STATUS_OK;
1564 }
1565
1566 if (argc > 1)
1567 sscanf(argv[1], "%i", &switch_level);
1568
1569 if (argc > 2)
1570 sscanf(argv[2], "%x", &access_mask);
1571
1572 /* Get sam policy handle */
1573
1574 result = rpccli_try_samr_connects(cli, mem_ctx,
1575 MAXIMUM_ALLOWED_ACCESS,
1576 &connect_pol);
1577
1578 if (!NT_STATUS_IS_OK(result))
1579 goto done;
1580
1581 /* Get domain policy handle */
1582
1583 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1584 &connect_pol,
1585 access_mask,
1586 &domain_sid,
1587 &domain_pol);
1588
1589 if (!NT_STATUS_IS_OK(result))
1590 goto done;
1591
1592 /* Query domain info */
1593
1594 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1595 &domain_pol,
1596 switch_level,
1597 &info);
1598
1599 if (!NT_STATUS_IS_OK(result))
1600 goto done;
1601
1602 /* Display domain info */
1603
1604 switch (switch_level) {
1605 case 1:
1606 display_sam_dom_info_1(&info->info1);
1607 break;
1608 case 2:
1609 display_sam_dom_info_2(&info->info2);
1610 break;
1611 case 3:
1612 display_sam_dom_info_3(&info->info3);
1613 break;
1614 case 4:
1615 display_sam_dom_info_4(&info->info4);
1616 break;
1617 case 5:
1618 display_sam_dom_info_5(&info->info5);
1619 break;
1620 case 6:
1621 display_sam_dom_info_6(&info->info6);
1622 break;
1623 case 7:
1624 display_sam_dom_info_7(&info->info7);
1625 break;
1626 case 8:
1627 display_sam_dom_info_8(&info->info8);
1628 break;
1629 case 9:
1630 display_sam_dom_info_9(&info->info9);
1631 break;
1632 case 12:
1633 display_sam_dom_info_12(&info->info12);
1634 break;
1635 case 13:
1636 display_sam_dom_info_13(&info->info13);
1637 break;
1638
1639 default:
1640 printf("cannot display domain info for switch value %d\n",
1641 switch_level);
1642 break;
1643 }
1644
1645 done:
1646
1647 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1648 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1649 return result;
1650}
1651
1652/* Create domain user */
1653
1654static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1655 TALLOC_CTX *mem_ctx,
1656 int argc, const char **argv)
1657{
1658 POLICY_HND connect_pol, domain_pol, user_pol;
1659 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1660 struct lsa_String acct_name;
1661 uint32 acb_info;
1662 uint32 acct_flags, user_rid;
1663 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1664 uint32_t access_granted = 0;
1665
1666 if ((argc < 2) || (argc > 3)) {
1667 printf("Usage: %s username [access mask]\n", argv[0]);
1668 return NT_STATUS_OK;
1669 }
1670
1671 init_lsa_String(&acct_name, argv[1]);
1672
1673 if (argc > 2)
1674 sscanf(argv[2], "%x", &access_mask);
1675
1676 /* Get sam policy handle */
1677
1678 result = rpccli_try_samr_connects(cli, mem_ctx,
1679 MAXIMUM_ALLOWED_ACCESS,
1680 &connect_pol);
1681
1682 if (!NT_STATUS_IS_OK(result))
1683 goto done;
1684
1685 /* Get domain policy handle */
1686
1687 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1688 &connect_pol,
1689 access_mask,
1690 &domain_sid,
1691 &domain_pol);
1692
1693 if (!NT_STATUS_IS_OK(result))
1694 goto done;
1695
1696 /* Create domain user */
1697
1698 acb_info = ACB_NORMAL;
1699 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1700 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1701 SAMR_USER_ACCESS_SET_PASSWORD |
1702 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1703 SAMR_USER_ACCESS_SET_ATTRIBUTES;
1704
1705 result = rpccli_samr_CreateUser2(cli, mem_ctx,
1706 &domain_pol,
1707 &acct_name,
1708 acb_info,
1709 acct_flags,
1710 &user_pol,
1711 &access_granted,
1712 &user_rid);
1713
1714 if (!NT_STATUS_IS_OK(result))
1715 goto done;
1716
1717 result = rpccli_samr_Close(cli, mem_ctx, &user_pol);
1718 if (!NT_STATUS_IS_OK(result)) goto done;
1719
1720 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1721 if (!NT_STATUS_IS_OK(result)) goto done;
1722
1723 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1724 if (!NT_STATUS_IS_OK(result)) goto done;
1725
1726 done:
1727 return result;
1728}
1729
1730/* Create domain group */
1731
1732static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1733 TALLOC_CTX *mem_ctx,
1734 int argc, const char **argv)
1735{
1736 POLICY_HND connect_pol, domain_pol, group_pol;
1737 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1738 struct lsa_String grp_name;
1739 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1740 uint32_t rid = 0;
1741
1742 if ((argc < 2) || (argc > 3)) {
1743 printf("Usage: %s groupname [access mask]\n", argv[0]);
1744 return NT_STATUS_OK;
1745 }
1746
1747 init_lsa_String(&grp_name, argv[1]);
1748
1749 if (argc > 2)
1750 sscanf(argv[2], "%x", &access_mask);
1751
1752 /* Get sam policy handle */
1753
1754 result = rpccli_try_samr_connects(cli, mem_ctx,
1755 MAXIMUM_ALLOWED_ACCESS,
1756 &connect_pol);
1757
1758 if (!NT_STATUS_IS_OK(result))
1759 goto done;
1760
1761 /* Get domain policy handle */
1762
1763 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1764 &connect_pol,
1765 access_mask,
1766 &domain_sid,
1767 &domain_pol);
1768
1769 if (!NT_STATUS_IS_OK(result))
1770 goto done;
1771
1772 /* Create domain user */
1773 result = rpccli_samr_CreateDomainGroup(cli, mem_ctx,
1774 &domain_pol,
1775 &grp_name,
1776 MAXIMUM_ALLOWED_ACCESS,
1777 &group_pol,
1778 &rid);
1779
1780 if (!NT_STATUS_IS_OK(result))
1781 goto done;
1782
1783 result = rpccli_samr_Close(cli, mem_ctx, &group_pol);
1784 if (!NT_STATUS_IS_OK(result)) goto done;
1785
1786 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1787 if (!NT_STATUS_IS_OK(result)) goto done;
1788
1789 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1790 if (!NT_STATUS_IS_OK(result)) goto done;
1791
1792 done:
1793 return result;
1794}
1795
1796/* Create domain alias */
1797
1798static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1799 TALLOC_CTX *mem_ctx,
1800 int argc, const char **argv)
1801{
1802 POLICY_HND connect_pol, domain_pol, alias_pol;
1803 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1804 struct lsa_String alias_name;
1805 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1806 uint32_t rid = 0;
1807
1808 if ((argc < 2) || (argc > 3)) {
1809 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1810 return NT_STATUS_OK;
1811 }
1812
1813 init_lsa_String(&alias_name, argv[1]);
1814
1815 if (argc > 2)
1816 sscanf(argv[2], "%x", &access_mask);
1817
1818 /* Get sam policy handle */
1819
1820 result = rpccli_try_samr_connects(cli, mem_ctx,
1821 MAXIMUM_ALLOWED_ACCESS,
1822 &connect_pol);
1823
1824 if (!NT_STATUS_IS_OK(result))
1825 goto done;
1826
1827 /* Get domain policy handle */
1828
1829 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1830 &connect_pol,
1831 access_mask,
1832 &domain_sid,
1833 &domain_pol);
1834
1835 if (!NT_STATUS_IS_OK(result))
1836 goto done;
1837
1838 /* Create domain user */
1839
1840 result = rpccli_samr_CreateDomAlias(cli, mem_ctx,
1841 &domain_pol,
1842 &alias_name,
1843 MAXIMUM_ALLOWED_ACCESS,
1844 &alias_pol,
1845 &rid);
1846
1847 if (!NT_STATUS_IS_OK(result))
1848 goto done;
1849
1850 result = rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1851 if (!NT_STATUS_IS_OK(result)) goto done;
1852
1853 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1854 if (!NT_STATUS_IS_OK(result)) goto done;
1855
1856 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1857 if (!NT_STATUS_IS_OK(result)) goto done;
1858
1859 done:
1860 return result;
1861}
1862
1863/* Lookup sam names */
1864
1865static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
1866 TALLOC_CTX *mem_ctx,
1867 int argc, const char **argv)
1868{
1869 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1870 POLICY_HND connect_pol, domain_pol;
1871 uint32 num_names;
1872 struct samr_Ids rids, name_types;
1873 int i;
1874 struct lsa_String *names = NULL;;
1875
1876 if (argc < 3) {
1877 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1878 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1879 printf("or check on the builtin SID: S-1-5-32\n");
1880 return NT_STATUS_OK;
1881 }
1882
1883 /* Get sam policy and domain handles */
1884
1885 result = rpccli_try_samr_connects(cli, mem_ctx,
1886 MAXIMUM_ALLOWED_ACCESS,
1887 &connect_pol);
1888
1889 if (!NT_STATUS_IS_OK(result))
1890 goto done;
1891
1892 if (StrCaseCmp(argv[1], "domain")==0)
1893 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1894 &connect_pol,
1895 MAXIMUM_ALLOWED_ACCESS,
1896 &domain_sid,
1897 &domain_pol);
1898 else if (StrCaseCmp(argv[1], "builtin")==0)
1899 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1900 &connect_pol,
1901 MAXIMUM_ALLOWED_ACCESS,
1902 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1903 &domain_pol);
1904 else
1905 return NT_STATUS_OK;
1906
1907 if (!NT_STATUS_IS_OK(result))
1908 goto done;
1909
1910 /* Look up names */
1911
1912 num_names = argc - 2;
1913
1914 if ((names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names)) == NULL) {
1915 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1916 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1917 result = NT_STATUS_NO_MEMORY;
1918 goto done;
1919 }
1920
1921 for (i = 0; i < num_names; i++) {
1922 init_lsa_String(&names[i], argv[i + 2]);
1923 }
1924
1925 result = rpccli_samr_LookupNames(cli, mem_ctx,
1926 &domain_pol,
1927 num_names,
1928 names,
1929 &rids,
1930 &name_types);
1931
1932 if (!NT_STATUS_IS_OK(result))
1933 goto done;
1934
1935 /* Display results */
1936
1937 for (i = 0; i < num_names; i++)
1938 printf("name %s: 0x%x (%d)\n", names[i].string, rids.ids[i],
1939 name_types.ids[i]);
1940
1941 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1942 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1943 done:
1944 return result;
1945}
1946
1947/* Lookup sam rids */
1948
1949static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
1950 TALLOC_CTX *mem_ctx,
1951 int argc, const char **argv)
1952{
1953 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1954 POLICY_HND connect_pol, domain_pol;
1955 uint32_t num_rids, *rids;
1956 struct lsa_Strings names;
1957 struct samr_Ids types;
1958
1959 int i;
1960
1961 if (argc < 3) {
1962 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1963 return NT_STATUS_OK;
1964 }
1965
1966 /* Get sam policy and domain handles */
1967
1968 result = rpccli_try_samr_connects(cli, mem_ctx,
1969 MAXIMUM_ALLOWED_ACCESS,
1970 &connect_pol);
1971
1972 if (!NT_STATUS_IS_OK(result))
1973 goto done;
1974
1975 if (StrCaseCmp(argv[1], "domain")==0)
1976 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1977 &connect_pol,
1978 MAXIMUM_ALLOWED_ACCESS,
1979 &domain_sid,
1980 &domain_pol);
1981 else if (StrCaseCmp(argv[1], "builtin")==0)
1982 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1983 &connect_pol,
1984 MAXIMUM_ALLOWED_ACCESS,
1985 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1986 &domain_pol);
1987 else
1988 return NT_STATUS_OK;
1989
1990 if (!NT_STATUS_IS_OK(result))
1991 goto done;
1992
1993 /* Look up rids */
1994
1995 num_rids = argc - 2;
1996
1997 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1998 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1999 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2000 result = NT_STATUS_NO_MEMORY;
2001 goto done;
2002 }
2003
2004 for (i = 0; i < argc - 2; i++)
2005 sscanf(argv[i + 2], "%i", &rids[i]);
2006
2007 result = rpccli_samr_LookupRids(cli, mem_ctx,
2008 &domain_pol,
2009 num_rids,
2010 rids,
2011 &names,
2012 &types);
2013
2014 if (!NT_STATUS_IS_OK(result) &&
2015 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
2016 goto done;
2017
2018 /* Display results */
2019
2020 for (i = 0; i < num_rids; i++) {
2021 printf("rid 0x%x: %s (%d)\n",
2022 rids[i], names.names[i].string, types.ids[i]);
2023 }
2024
2025 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2026 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2027 done:
2028 return result;
2029}
2030
2031/* Delete domain group */
2032
2033static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
2034 TALLOC_CTX *mem_ctx,
2035 int argc, const char **argv)
2036{
2037 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2038 POLICY_HND connect_pol, domain_pol, group_pol;
2039 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2040
2041 if ((argc < 2) || (argc > 3)) {
2042 printf("Usage: %s groupname\n", argv[0]);
2043 return NT_STATUS_OK;
2044 }
2045
2046 if (argc > 2)
2047 sscanf(argv[2], "%x", &access_mask);
2048
2049 /* Get sam policy and domain handles */
2050
2051 result = rpccli_try_samr_connects(cli, mem_ctx,
2052 MAXIMUM_ALLOWED_ACCESS,
2053 &connect_pol);
2054
2055 if (!NT_STATUS_IS_OK(result))
2056 goto done;
2057
2058 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2059 &connect_pol,
2060 MAXIMUM_ALLOWED_ACCESS,
2061 &domain_sid,
2062 &domain_pol);
2063
2064 if (!NT_STATUS_IS_OK(result))
2065 goto done;
2066
2067 /* Get handle on group */
2068
2069 {
2070 struct samr_Ids group_rids, name_types;
2071 struct lsa_String lsa_acct_name;
2072
2073 init_lsa_String(&lsa_acct_name, argv[1]);
2074
2075 result = rpccli_samr_LookupNames(cli, mem_ctx,
2076 &domain_pol,
2077 1,
2078 &lsa_acct_name,
2079 &group_rids,
2080 &name_types);
2081 if (!NT_STATUS_IS_OK(result))
2082 goto done;
2083
2084 result = rpccli_samr_OpenGroup(cli, mem_ctx,
2085 &domain_pol,
2086 access_mask,
2087 group_rids.ids[0],
2088 &group_pol);
2089
2090 if (!NT_STATUS_IS_OK(result))
2091 goto done;
2092 }
2093
2094 /* Delete group */
2095
2096 result = rpccli_samr_DeleteDomainGroup(cli, mem_ctx,
2097 &group_pol);
2098
2099 if (!NT_STATUS_IS_OK(result))
2100 goto done;
2101
2102 /* Display results */
2103
2104 rpccli_samr_Close(cli, mem_ctx, &group_pol);
2105 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2106 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2107
2108 done:
2109 return result;
2110}
2111
2112/* Delete domain user */
2113
2114static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
2115 TALLOC_CTX *mem_ctx,
2116 int argc, const char **argv)
2117{
2118 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2119 POLICY_HND connect_pol, domain_pol, user_pol;
2120 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2121
2122 if ((argc < 2) || (argc > 3)) {
2123 printf("Usage: %s username\n", argv[0]);
2124 return NT_STATUS_OK;
2125 }
2126
2127 if (argc > 2)
2128 sscanf(argv[2], "%x", &access_mask);
2129
2130 /* Get sam policy and domain handles */
2131
2132 result = rpccli_try_samr_connects(cli, mem_ctx,
2133 MAXIMUM_ALLOWED_ACCESS,
2134 &connect_pol);
2135
2136 if (!NT_STATUS_IS_OK(result))
2137 goto done;
2138
2139 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2140 &connect_pol,
2141 MAXIMUM_ALLOWED_ACCESS,
2142 &domain_sid,
2143 &domain_pol);
2144
2145 if (!NT_STATUS_IS_OK(result))
2146 goto done;
2147
2148 /* Get handle on user */
2149
2150 {
2151 struct samr_Ids user_rids, name_types;
2152 struct lsa_String lsa_acct_name;
2153
2154 init_lsa_String(&lsa_acct_name, argv[1]);
2155
2156 result = rpccli_samr_LookupNames(cli, mem_ctx,
2157 &domain_pol,
2158 1,
2159 &lsa_acct_name,
2160 &user_rids,
2161 &name_types);
2162
2163 if (!NT_STATUS_IS_OK(result))
2164 goto done;
2165
2166 result = rpccli_samr_OpenUser(cli, mem_ctx,
2167 &domain_pol,
2168 access_mask,
2169 user_rids.ids[0],
2170 &user_pol);
2171
2172 if (!NT_STATUS_IS_OK(result))
2173 goto done;
2174 }
2175
2176 /* Delete user */
2177
2178 result = rpccli_samr_DeleteUser(cli, mem_ctx,
2179 &user_pol);
2180
2181 if (!NT_STATUS_IS_OK(result))
2182 goto done;
2183
2184 /* Display results */
2185
2186 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2187 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2188 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2189
2190 done:
2191 return result;
2192}
2193
2194/**********************************************************************
2195 * Query user security object
2196 */
2197static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
2198 TALLOC_CTX *mem_ctx,
2199 int argc, const char **argv)
2200{
2201 POLICY_HND connect_pol, domain_pol, user_pol, *pol;
2202 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2203 uint32 sec_info = DACL_SECURITY_INFORMATION;
2204 uint32 user_rid = 0;
2205 TALLOC_CTX *ctx = NULL;
2206 SEC_DESC_BUF *sec_desc_buf=NULL;
2207 bool domain = False;
2208
2209 ctx=talloc_init("cmd_samr_query_sec_obj");
2210
2211 if ((argc < 1) || (argc > 3)) {
2212 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2213 printf("\tSpecify rid for security on user, -d for security on domain\n");
2214 talloc_destroy(ctx);
2215 return NT_STATUS_OK;
2216 }
2217
2218 if (argc > 1) {
2219 if (strcmp(argv[1], "-d") == 0)
2220 domain = True;
2221 else
2222 sscanf(argv[1], "%i", &user_rid);
2223 }
2224
2225 if (argc == 3) {
2226 sec_info = atoi(argv[2]);
2227 }
2228
2229 result = rpccli_try_samr_connects(cli, mem_ctx,
2230 MAXIMUM_ALLOWED_ACCESS,
2231 &connect_pol);
2232
2233 if (!NT_STATUS_IS_OK(result))
2234 goto done;
2235
2236 if (domain || user_rid)
2237 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2238 &connect_pol,
2239 MAXIMUM_ALLOWED_ACCESS,
2240 &domain_sid,
2241 &domain_pol);
2242
2243 if (!NT_STATUS_IS_OK(result))
2244 goto done;
2245
2246 if (user_rid)
2247 result = rpccli_samr_OpenUser(cli, mem_ctx,
2248 &domain_pol,
2249 MAXIMUM_ALLOWED_ACCESS,
2250 user_rid,
2251 &user_pol);
2252
2253 if (!NT_STATUS_IS_OK(result))
2254 goto done;
2255
2256 /* Pick which query pol to use */
2257
2258 pol = &connect_pol;
2259
2260 if (domain)
2261 pol = &domain_pol;
2262
2263 if (user_rid)
2264 pol = &user_pol;
2265
2266 /* Query SAM security object */
2267
2268 result = rpccli_samr_QuerySecurity(cli, mem_ctx,
2269 pol,
2270 sec_info,
2271 &sec_desc_buf);
2272
2273 if (!NT_STATUS_IS_OK(result))
2274 goto done;
2275
2276 display_sec_desc(sec_desc_buf->sd);
2277
2278 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2279 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2280 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2281done:
2282 talloc_destroy(ctx);
2283 return result;
2284}
2285
2286static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
2287 TALLOC_CTX *mem_ctx,
2288 int argc, const char **argv)
2289{
2290 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2291 POLICY_HND connect_pol, domain_pol, user_pol;
2292 struct samr_PwInfo info;
2293 uint32_t rid;
2294
2295 if (argc != 2) {
2296 printf("Usage: %s rid\n", argv[0]);
2297 return NT_STATUS_OK;
2298 }
2299
2300 sscanf(argv[1], "%i", &rid);
2301
2302 result = rpccli_try_samr_connects(cli, mem_ctx,
2303 MAXIMUM_ALLOWED_ACCESS,
2304 &connect_pol);
2305
2306 if (!NT_STATUS_IS_OK(result)) {
2307 goto done;
2308 }
2309
2310 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2311 &connect_pol,
2312 MAXIMUM_ALLOWED_ACCESS,
2313 &domain_sid,
2314 &domain_pol);
2315
2316 if (!NT_STATUS_IS_OK(result)) {
2317 goto done;
2318 }
2319
2320 result = rpccli_samr_OpenUser(cli, mem_ctx,
2321 &domain_pol,
2322 MAXIMUM_ALLOWED_ACCESS,
2323 rid,
2324 &user_pol);
2325
2326 if (!NT_STATUS_IS_OK(result)) {
2327 goto done;
2328 }
2329
2330 result = rpccli_samr_GetUserPwInfo(cli, mem_ctx, &user_pol, &info);
2331 if (NT_STATUS_IS_OK(result)) {
2332 printf("min_password_length: %d\n", info.min_password_length);
2333 printf("%s\n",
2334 NDR_PRINT_STRUCT_STRING(mem_ctx,
2335 samr_PasswordProperties, &info.password_properties));
2336 }
2337
2338 done:
2339 rpccli_samr_Close(cli, mem_ctx, &user_pol);
2340 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2341 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2342
2343 return result;
2344}
2345
2346static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2347 TALLOC_CTX *mem_ctx,
2348 int argc, const char **argv)
2349{
2350 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2351 struct lsa_String domain_name;
2352 struct samr_PwInfo info;
2353
2354 if (argc < 1 || argc > 3) {
2355 printf("Usage: %s <domain>\n", argv[0]);
2356 return NT_STATUS_OK;
2357 }
2358
2359 init_lsa_String(&domain_name, argv[1]);
2360
2361 result = rpccli_samr_GetDomPwInfo(cli, mem_ctx, &domain_name, &info);
2362
2363 if (NT_STATUS_IS_OK(result)) {
2364 printf("min_password_length: %d\n", info.min_password_length);
2365 display_password_properties(info.password_properties);
2366 }
2367
2368 return result;
2369}
2370
2371/* Look up domain name */
2372
2373static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
2374 TALLOC_CTX *mem_ctx,
2375 int argc, const char **argv)
2376{
2377 POLICY_HND connect_pol, domain_pol;
2378 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2379 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2380 fstring sid_string;
2381 struct lsa_String domain_name;
2382 DOM_SID *sid = NULL;
2383
2384 if (argc != 2) {
2385 printf("Usage: %s domain_name\n", argv[0]);
2386 return NT_STATUS_OK;
2387 }
2388
2389 init_lsa_String(&domain_name, argv[1]);
2390
2391 result = rpccli_try_samr_connects(cli, mem_ctx,
2392 access_mask,
2393 &connect_pol);
2394
2395 if (!NT_STATUS_IS_OK(result))
2396 goto done;
2397
2398 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2399 &connect_pol,
2400 access_mask,
2401 &domain_sid,
2402 &domain_pol);
2403
2404 if (!NT_STATUS_IS_OK(result))
2405 goto done;
2406
2407 result = rpccli_samr_LookupDomain(cli, mem_ctx,
2408 &connect_pol,
2409 &domain_name,
2410 &sid);
2411
2412 if (NT_STATUS_IS_OK(result)) {
2413 sid_to_fstring(sid_string, sid);
2414 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2415 argv[1], sid_string);
2416 }
2417
2418 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2419 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2420done:
2421 return result;
2422}
2423
2424/* Change user password */
2425
2426static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2427 TALLOC_CTX *mem_ctx,
2428 int argc, const char **argv)
2429{
2430 POLICY_HND connect_pol, domain_pol;
2431 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2432 const char *user, *oldpass, *newpass;
2433 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2434
2435 if (argc < 3) {
2436 printf("Usage: %s username oldpass newpass\n", argv[0]);
2437 return NT_STATUS_INVALID_PARAMETER;
2438 }
2439
2440 user = argv[1];
2441 oldpass = argv[2];
2442 newpass = argv[3];
2443
2444 /* Get sam policy handle */
2445
2446 result = rpccli_try_samr_connects(cli, mem_ctx,
2447 MAXIMUM_ALLOWED_ACCESS,
2448 &connect_pol);
2449
2450 if (!NT_STATUS_IS_OK(result))
2451 goto done;
2452
2453 /* Get domain policy handle */
2454
2455 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2456 &connect_pol,
2457 access_mask,
2458 &domain_sid,
2459 &domain_pol);
2460
2461 if (!NT_STATUS_IS_OK(result))
2462 goto done;
2463
2464 /* Change user password */
2465 result = rpccli_samr_chgpasswd_user(cli, mem_ctx, user, newpass, oldpass);
2466
2467 if (!NT_STATUS_IS_OK(result))
2468 goto done;
2469
2470 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2471 if (!NT_STATUS_IS_OK(result)) goto done;
2472
2473 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2474 if (!NT_STATUS_IS_OK(result)) goto done;
2475
2476 done:
2477 return result;
2478}
2479
2480
2481/* Change user password */
2482
2483static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
2484 TALLOC_CTX *mem_ctx,
2485 int argc, const char **argv)
2486{
2487 POLICY_HND connect_pol, domain_pol;
2488 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2489 const char *user, *oldpass, *newpass;
2490 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2491 struct samr_DomInfo1 *info = NULL;
2492 struct samr_ChangeReject *reject = NULL;
2493
2494 if (argc < 3) {
2495 printf("Usage: %s username oldpass newpass\n", argv[0]);
2496 return NT_STATUS_INVALID_PARAMETER;
2497 }
2498
2499 user = argv[1];
2500 oldpass = argv[2];
2501 newpass = argv[3];
2502
2503 /* Get sam policy handle */
2504
2505 result = rpccli_try_samr_connects(cli, mem_ctx,
2506 MAXIMUM_ALLOWED_ACCESS,
2507 &connect_pol);
2508
2509 if (!NT_STATUS_IS_OK(result))
2510 goto done;
2511
2512 /* Get domain policy handle */
2513
2514 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2515 &connect_pol,
2516 access_mask,
2517 &domain_sid,
2518 &domain_pol);
2519
2520 if (!NT_STATUS_IS_OK(result))
2521 goto done;
2522
2523 /* Change user password */
2524 result = rpccli_samr_chgpasswd3(cli, mem_ctx,
2525 user,
2526 newpass,
2527 oldpass,
2528 &info,
2529 &reject);
2530
2531 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2532
2533 display_sam_dom_info_1(info);
2534
2535 switch (reject->reason) {
2536 case SAMR_REJECT_TOO_SHORT:
2537 d_printf("SAMR_REJECT_TOO_SHORT\n");
2538 break;
2539 case SAMR_REJECT_IN_HISTORY:
2540 d_printf("SAMR_REJECT_IN_HISTORY\n");
2541 break;
2542 case SAMR_REJECT_COMPLEXITY:
2543 d_printf("SAMR_REJECT_COMPLEXITY\n");
2544 break;
2545 case SAMR_REJECT_OTHER:
2546 d_printf("SAMR_REJECT_OTHER\n");
2547 break;
2548 default:
2549 d_printf("unknown reject reason: %d\n",
2550 reject->reason);
2551 break;
2552 }
2553 }
2554
2555 if (!NT_STATUS_IS_OK(result))
2556 goto done;
2557
2558 result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2559 if (!NT_STATUS_IS_OK(result)) goto done;
2560
2561 result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2562 if (!NT_STATUS_IS_OK(result)) goto done;
2563
2564 done:
2565 return result;
2566}
2567
2568static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
2569 TALLOC_CTX *mem_ctx,
2570 int argc, const char **argv)
2571{
2572 NTSTATUS status;
2573 struct policy_handle connect_handle;
2574 struct policy_handle domain_handle;
2575 uint16_t level = 1;
2576 struct lsa_String name;
2577 uint32_t idx = 0;
2578
2579 if (argc < 2 || argc > 3) {
2580 printf("Usage: %s name level\n", argv[0]);
2581 return NT_STATUS_INVALID_PARAMETER;
2582 }
2583
2584 init_lsa_String(&name, argv[1]);
2585
2586 if (argc == 3) {
2587 level = atoi(argv[2]);
2588 }
2589
2590 status = rpccli_try_samr_connects(cli, mem_ctx,
2591 SEC_RIGHTS_MAXIMUM_ALLOWED,
2592 &connect_handle);
2593
2594 if (!NT_STATUS_IS_OK(status)) {
2595 goto done;
2596 }
2597
2598 status = rpccli_samr_OpenDomain(cli, mem_ctx,
2599 &connect_handle,
2600 SEC_RIGHTS_MAXIMUM_ALLOWED,
2601 &domain_sid,
2602 &domain_handle);
2603
2604 if (!NT_STATUS_IS_OK(status))
2605 goto done;
2606
2607
2608 status = rpccli_samr_GetDisplayEnumerationIndex(cli, mem_ctx,
2609 &domain_handle,
2610 level,
2611 &name,
2612 &idx);
2613
2614 if (NT_STATUS_IS_OK(status) ||
2615 NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
2616 printf("idx: %d (0x%08x)\n", idx, idx);
2617 }
2618 done:
2619
2620 if (is_valid_policy_hnd(&domain_handle)) {
2621 rpccli_samr_Close(cli, mem_ctx, &domain_handle);
2622 }
2623 if (is_valid_policy_hnd(&connect_handle)) {
2624 rpccli_samr_Close(cli, mem_ctx, &connect_handle);
2625 }
2626
2627 return status;
2628
2629}
2630/* List of commands exported by this module */
2631
2632struct cmd_set samr_commands[] = {
2633
2634 { "SAMR" },
2635
2636 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, PI_SAMR, NULL, "Query user info", "" },
2637 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, PI_SAMR, NULL, "Query group info", "" },
2638 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, PI_SAMR, NULL, "Query user groups", "" },
2639 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, PI_SAMR, NULL, "Query user aliases", "" },
2640 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, PI_SAMR, NULL, "Query group membership", "" },
2641 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, PI_SAMR, NULL, "Query alias membership", "" },
2642 { "queryaliasinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasinfo, NULL, PI_SAMR, NULL, "Query alias info", "" },
2643 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, PI_SAMR, NULL, "Delete an alias", "" },
2644 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, PI_SAMR, NULL, "Query display info", "" },
2645 { "querydispinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo2, NULL, PI_SAMR, NULL, "Query display info", "" },
2646 { "querydispinfo3", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo3, NULL, PI_SAMR, NULL, "Query display info", "" },
2647 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, PI_SAMR, NULL, "Query domain info", "" },
2648 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, PI_SAMR, NULL, "Enumerate domain users", "" },
2649 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, PI_SAMR, NULL, "Enumerate domain groups", "" },
2650 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, PI_SAMR, NULL, "Enumerate alias groups", "" },
2651 { "enumdomains", RPC_RTYPE_NTSTATUS, cmd_samr_enum_domains, NULL, PI_SAMR, NULL, "Enumerate domains", "" },
2652
2653 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, PI_SAMR, NULL, "Create domain user", "" },
2654 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, PI_SAMR, NULL, "Create domain group", "" },
2655 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, PI_SAMR, NULL, "Create domain alias", "" },
2656 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, PI_SAMR, NULL, "Look up names", "" },
2657 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, PI_SAMR, NULL, "Look up names", "" },
2658 { "deletedomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group, NULL, PI_SAMR, NULL, "Delete domain group", "" },
2659 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, PI_SAMR, NULL, "Delete domain user", "" },
2660 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, PI_SAMR, NULL, "Query SAMR security object", "" },
2661 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
2662 { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve user domain password info", "" },
2663
2664 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },
2665 { "chgpasswd2", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2, NULL, PI_SAMR, NULL, "Change user password", "" },
2666 { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, PI_SAMR, NULL, "Change user password", "" },
2667 { "getdispinfoidx", RPC_RTYPE_NTSTATUS, cmd_samr_get_dispinfo_idx, NULL, PI_SAMR, NULL, "Get Display Information Index", "" },
2668 { NULL }
2669};
Note: See TracBrowser for help on using the repository browser.