source: trunk/server/source3/rpcclient/cmd_samr.c

Last change on this file was 862, checked in by Silvan Scherrer, 11 years ago

Samba Server: update trunk to 3.6.23

File size: 84.6 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#include "../libcli/auth/libcli_auth.h"
28#include "../librpc/gen_ndr/ndr_samr.h"
29#include "../librpc/gen_ndr/ndr_samr_c.h"
30#include "rpc_client/cli_samr.h"
31#include "rpc_client/init_samr.h"
32#include "rpc_client/init_lsa.h"
33#include "../libcli/security/security.h"
34
35extern struct dom_sid domain_sid;
36
37/****************************************************************************
38 display samr_user_info_7 structure
39 ****************************************************************************/
40static void display_samr_user_info_7(struct samr_UserInfo7 *r)
41{
42 printf("\tUser Name :\t%s\n", r->account_name.string);
43}
44
45/****************************************************************************
46 display samr_user_info_9 structure
47 ****************************************************************************/
48static void display_samr_user_info_9(struct samr_UserInfo9 *r)
49{
50 printf("\tPrimary group RID :\tox%x\n", r->primary_gid);
51}
52
53/****************************************************************************
54 display samr_user_info_16 structure
55 ****************************************************************************/
56static void display_samr_user_info_16(struct samr_UserInfo16 *r)
57{
58 printf("\tAcct Flags :\tox%x\n", r->acct_flags);
59}
60
61/****************************************************************************
62 display samr_user_info_20 structure
63 ****************************************************************************/
64static void display_samr_user_info_20(struct samr_UserInfo20 *r)
65{
66 printf("\tRemote Dial :\n");
67 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
68}
69
70
71/****************************************************************************
72 display samr_user_info_21 structure
73 ****************************************************************************/
74static void display_samr_user_info_21(struct samr_UserInfo21 *r)
75{
76 printf("\tUser Name :\t%s\n", r->account_name.string);
77 printf("\tFull Name :\t%s\n", r->full_name.string);
78 printf("\tHome Drive :\t%s\n", r->home_directory.string);
79 printf("\tDir Drive :\t%s\n", r->home_drive.string);
80 printf("\tProfile Path:\t%s\n", r->profile_path.string);
81 printf("\tLogon Script:\t%s\n", r->logon_script.string);
82 printf("\tDescription :\t%s\n", r->description.string);
83 printf("\tWorkstations:\t%s\n", r->workstations.string);
84 printf("\tComment :\t%s\n", r->comment.string);
85 printf("\tRemote Dial :\n");
86 dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
87
88 printf("\tLogon Time :\t%s\n",
89 http_timestring(talloc_tos(), nt_time_to_unix(r->last_logon)));
90 printf("\tLogoff Time :\t%s\n",
91 http_timestring(talloc_tos(), nt_time_to_unix(r->last_logoff)));
92 printf("\tKickoff Time :\t%s\n",
93 http_timestring(talloc_tos(), nt_time_to_unix(r->acct_expiry)));
94 printf("\tPassword last set Time :\t%s\n",
95 http_timestring(talloc_tos(), nt_time_to_unix(r->last_password_change)));
96 printf("\tPassword can change Time :\t%s\n",
97 http_timestring(talloc_tos(), nt_time_to_unix(r->allow_password_change)));
98 printf("\tPassword must change Time:\t%s\n",
99 http_timestring(talloc_tos(), nt_time_to_unix(r->force_password_change)));
100
101 printf("\tunknown_2[0..31]...\n"); /* user passwords? */
102
103 printf("\tuser_rid :\t0x%x\n" , r->rid); /* User ID */
104 printf("\tgroup_rid:\t0x%x\n" , r->primary_gid); /* Group ID */
105 printf("\tacb_info :\t0x%08x\n", r->acct_flags); /* Account Control Info */
106
107 printf("\tfields_present:\t0x%08x\n", r->fields_present); /* 0x00ff ffff */
108 printf("\tlogon_divs:\t%d\n", r->logon_hours.units_per_week); /* 0x0000 00a8 which is 168 which is num hrs in a week */
109 printf("\tbad_password_count:\t0x%08x\n", r->bad_password_count);
110 printf("\tlogon_count:\t0x%08x\n", r->logon_count);
111
112 printf("\tpadding1[0..7]...\n");
113
114 if (r->logon_hours.bits) {
115 printf("\tlogon_hrs[0..%d]...\n", r->logon_hours.units_per_week/8);
116 }
117}
118
119
120static void display_password_properties(uint32_t password_properties)
121{
122 printf("password_properties: 0x%08x\n", password_properties);
123
124 if (password_properties & DOMAIN_PASSWORD_COMPLEX)
125 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
126
127 if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
128 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
129
130 if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
131 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
132
133 if (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)
134 printf("\tDOMAIN_PASSWORD_LOCKOUT_ADMINS\n");
135
136 if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
137 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
138
139 if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
140 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
141}
142
143static void display_sam_dom_info_1(struct samr_DomInfo1 *info1)
144{
145 printf("Minimum password length:\t\t\t%d\n",
146 info1->min_password_length);
147 printf("Password uniqueness (remember x passwords):\t%d\n",
148 info1->password_history_length);
149 display_password_properties(info1->password_properties);
150 printf("password expire in:\t\t\t\t%s\n",
151 display_time(info1->max_password_age));
152 printf("Min password age (allow changing in x days):\t%s\n",
153 display_time(info1->min_password_age));
154}
155
156static void display_sam_dom_info_2(struct samr_DomGeneralInformation *general)
157{
158 printf("Domain:\t\t%s\n", general->domain_name.string);
159 printf("Server:\t\t%s\n", general->primary.string);
160 printf("Comment:\t%s\n", general->oem_information.string);
161
162 printf("Total Users:\t%d\n", general->num_users);
163 printf("Total Groups:\t%d\n", general->num_groups);
164 printf("Total Aliases:\t%d\n", general->num_aliases);
165
166 printf("Sequence No:\t%llu\n", (unsigned long long)general->sequence_num);
167
168 printf("Force Logoff:\t%d\n",
169 (int)nt_time_to_unix_abs(&general->force_logoff_time));
170
171 printf("Domain Server State:\t0x%x\n", general->domain_server_state);
172 printf("Server Role:\t%s\n", server_role_str(general->role));
173 printf("Unknown 3:\t0x%x\n", general->unknown3);
174}
175
176static void display_sam_dom_info_3(struct samr_DomInfo3 *info3)
177{
178 printf("Force Logoff:\t%d\n",
179 (int)nt_time_to_unix_abs(&info3->force_logoff_time));
180}
181
182static void display_sam_dom_info_4(struct samr_DomOEMInformation *oem)
183{
184 printf("Comment:\t%s\n", oem->oem_information.string);
185}
186
187static void display_sam_dom_info_5(struct samr_DomInfo5 *info5)
188{
189 printf("Domain:\t\t%s\n", info5->domain_name.string);
190}
191
192static void display_sam_dom_info_6(struct samr_DomInfo6 *info6)
193{
194 printf("Server:\t\t%s\n", info6->primary.string);
195}
196
197static void display_sam_dom_info_7(struct samr_DomInfo7 *info7)
198{
199 printf("Server Role:\t%s\n", server_role_str(info7->role));
200}
201
202static void display_sam_dom_info_8(struct samr_DomInfo8 *info8)
203{
204 printf("Sequence No:\t%llu\n", (unsigned long long)info8->sequence_num);
205 printf("Domain Create Time:\t%s\n",
206 http_timestring(talloc_tos(), nt_time_to_unix(info8->domain_create_time)));
207}
208
209static void display_sam_dom_info_9(struct samr_DomInfo9 *info9)
210{
211 printf("Domain Server State:\t0x%x\n", info9->domain_server_state);
212}
213
214static void display_sam_dom_info_12(struct samr_DomInfo12 *info12)
215{
216 printf("Bad password lockout duration: %s\n",
217 display_time(info12->lockout_duration));
218 printf("Reset Lockout after: %s\n",
219 display_time(info12->lockout_window));
220 printf("Lockout after bad attempts: %d\n",
221 info12->lockout_threshold);
222}
223
224static void display_sam_dom_info_13(struct samr_DomInfo13 *info13)
225{
226 printf("Sequence No:\t%llu\n", (unsigned long long)info13->sequence_num);
227 printf("Domain Create Time:\t%s\n",
228 http_timestring(talloc_tos(), nt_time_to_unix(info13->domain_create_time)));
229 printf("Sequence No at last promotion:\t%llu\n",
230 (unsigned long long)info13->modified_count_at_last_promotion);
231}
232
233static void display_sam_info_1(struct samr_DispEntryGeneral *r)
234{
235 printf("index: 0x%x ", r->idx);
236 printf("RID: 0x%x ", r->rid);
237 printf("acb: 0x%08x ", r->acct_flags);
238 printf("Account: %s\t", r->account_name.string);
239 printf("Name: %s\t", r->full_name.string);
240 printf("Desc: %s\n", r->description.string);
241}
242
243static void display_sam_info_2(struct samr_DispEntryFull *r)
244{
245 printf("index: 0x%x ", r->idx);
246 printf("RID: 0x%x ", r->rid);
247 printf("acb: 0x%08x ", r->acct_flags);
248 printf("Account: %s\t", r->account_name.string);
249 printf("Desc: %s\n", r->description.string);
250}
251
252static void display_sam_info_3(struct samr_DispEntryFullGroup *r)
253{
254 printf("index: 0x%x ", r->idx);
255 printf("RID: 0x%x ", r->rid);
256 printf("acb: 0x%08x ", r->acct_flags);
257 printf("Account: %s\t", r->account_name.string);
258 printf("Desc: %s\n", r->description.string);
259}
260
261static void display_sam_info_4(struct samr_DispEntryAscii *r)
262{
263 printf("index: 0x%x ", r->idx);
264 printf("Account: %s\n", r->account_name.string);
265}
266
267static void display_sam_info_5(struct samr_DispEntryAscii *r)
268{
269 printf("index: 0x%x ", r->idx);
270 printf("Account: %s\n", r->account_name.string);
271}
272
273/****************************************************************************
274 ****************************************************************************/
275
276static NTSTATUS get_domain_handle(struct rpc_pipe_client *cli,
277 TALLOC_CTX *mem_ctx,
278 const char *sam,
279 struct policy_handle *connect_pol,
280 uint32_t access_mask,
281 struct dom_sid *_domain_sid,
282 struct policy_handle *domain_pol)
283{
284 struct dcerpc_binding_handle *b = cli->binding_handle;
285 NTSTATUS status = NT_STATUS_INVALID_PARAMETER, result;
286
287 if (StrCaseCmp(sam, "domain") == 0) {
288 status = dcerpc_samr_OpenDomain(b, mem_ctx,
289 connect_pol,
290 access_mask,
291 _domain_sid,
292 domain_pol,
293 &result);
294 } else if (StrCaseCmp(sam, "builtin") == 0) {
295 status = dcerpc_samr_OpenDomain(b, mem_ctx,
296 connect_pol,
297 access_mask,
298 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
299 domain_pol,
300 &result);
301 }
302
303 if (!NT_STATUS_IS_OK(status)) {
304 return status;
305 }
306
307 return result;
308}
309
310/**********************************************************************
311 * Query user information
312 */
313static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
314 TALLOC_CTX *mem_ctx,
315 int argc, const char **argv)
316{
317 struct policy_handle connect_pol, domain_pol, user_pol;
318 NTSTATUS status, result;
319 uint32 info_level = 21;
320 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
321 union samr_UserInfo *info = NULL;
322 uint32 user_rid = 0;
323 struct dcerpc_binding_handle *b = cli->binding_handle;
324
325 if ((argc < 2) || (argc > 4)) {
326 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
327 return NT_STATUS_OK;
328 }
329
330 sscanf(argv[1], "%i", &user_rid);
331
332 if (argc > 2)
333 sscanf(argv[2], "%i", &info_level);
334
335 if (argc > 3)
336 sscanf(argv[3], "%x", &access_mask);
337
338
339 status = rpccli_try_samr_connects(cli, mem_ctx,
340 MAXIMUM_ALLOWED_ACCESS,
341 &connect_pol);
342 if (!NT_STATUS_IS_OK(status)) {
343 goto done;
344 }
345
346 status = dcerpc_samr_OpenDomain(b, mem_ctx,
347 &connect_pol,
348 MAXIMUM_ALLOWED_ACCESS,
349 &domain_sid,
350 &domain_pol,
351 &result);
352 if (!NT_STATUS_IS_OK(status)) {
353 goto done;
354 }
355 if (!NT_STATUS_IS_OK(result)) {
356 status = result;
357 goto done;
358 }
359
360 status = dcerpc_samr_OpenUser(b, mem_ctx,
361 &domain_pol,
362 access_mask,
363 user_rid,
364 &user_pol,
365 &result);
366 if (!NT_STATUS_IS_OK(status)) {
367 goto done;
368 }
369 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
370 (user_rid == 0)) {
371
372 /* Probably this was a user name, try lookupnames */
373 struct samr_Ids rids, types;
374 struct lsa_String lsa_acct_name;
375
376 init_lsa_String(&lsa_acct_name, argv[1]);
377
378 status = dcerpc_samr_LookupNames(b, mem_ctx,
379 &domain_pol,
380 1,
381 &lsa_acct_name,
382 &rids,
383 &types,
384 &result);
385 if (!NT_STATUS_IS_OK(status)) {
386 goto done;
387 }
388
389 if (NT_STATUS_IS_OK(result)) {
390 if (rids.count != 1) {
391 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
392 goto done;
393 }
394 if (types.count != 1) {
395 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
396 goto done;
397 }
398
399 status = dcerpc_samr_OpenUser(b, mem_ctx,
400 &domain_pol,
401 access_mask,
402 rids.ids[0],
403 &user_pol,
404 &result);
405 if (!NT_STATUS_IS_OK(status)) {
406 goto done;
407 }
408 }
409 }
410
411
412 if (!NT_STATUS_IS_OK(result)) {
413 status = result;
414 goto done;
415 }
416
417 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
418 &user_pol,
419 info_level,
420 &info,
421 &result);
422 if (!NT_STATUS_IS_OK(status)) {
423 goto done;
424 }
425 if (!NT_STATUS_IS_OK(result)) {
426 status = result;
427 goto done;
428 }
429
430 switch (info_level) {
431 case 7:
432 display_samr_user_info_7(&info->info7);
433 break;
434 case 9:
435 display_samr_user_info_9(&info->info9);
436 break;
437 case 16:
438 display_samr_user_info_16(&info->info16);
439 break;
440 case 20:
441 display_samr_user_info_20(&info->info20);
442 break;
443 case 21:
444 display_samr_user_info_21(&info->info21);
445 break;
446 default:
447 printf("Unsupported infolevel: %d\n", info_level);
448 break;
449 }
450
451 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
452 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
453 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
454
455done:
456 return status;
457}
458
459/****************************************************************************
460 display group info
461 ****************************************************************************/
462static void display_group_info1(struct samr_GroupInfoAll *info1)
463{
464 printf("\tGroup Name:\t%s\n", info1->name.string);
465 printf("\tDescription:\t%s\n", info1->description.string);
466 printf("\tGroup Attribute:%d\n", info1->attributes);
467 printf("\tNum Members:%d\n", info1->num_members);
468}
469
470/****************************************************************************
471 display group info
472 ****************************************************************************/
473static void display_group_info2(struct lsa_String *info2)
474{
475 printf("\tGroup Description:%s\n", info2->string);
476}
477
478
479/****************************************************************************
480 display group info
481 ****************************************************************************/
482static void display_group_info3(struct samr_GroupInfoAttributes *info3)
483{
484 printf("\tGroup Attribute:%d\n", info3->attributes);
485}
486
487
488/****************************************************************************
489 display group info
490 ****************************************************************************/
491static void display_group_info4(struct lsa_String *info4)
492{
493 printf("\tGroup Description:%s\n", info4->string);
494}
495
496/****************************************************************************
497 display group info
498 ****************************************************************************/
499static void display_group_info5(struct samr_GroupInfoAll *info5)
500{
501 printf("\tGroup Name:\t%s\n", info5->name.string);
502 printf("\tDescription:\t%s\n", info5->description.string);
503 printf("\tGroup Attribute:%d\n", info5->attributes);
504 printf("\tNum Members:%d\n", info5->num_members);
505}
506
507/****************************************************************************
508 display sam sync structure
509 ****************************************************************************/
510static void display_group_info(union samr_GroupInfo *info,
511 enum samr_GroupInfoEnum level)
512{
513 switch (level) {
514 case 1:
515 display_group_info1(&info->all);
516 break;
517 case 2:
518 display_group_info2(&info->name);
519 break;
520 case 3:
521 display_group_info3(&info->attributes);
522 break;
523 case 4:
524 display_group_info4(&info->description);
525 break;
526 case 5:
527 display_group_info5(&info->all2);
528 break;
529 }
530}
531
532/***********************************************************************
533 * Query group information
534 */
535static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
536 TALLOC_CTX *mem_ctx,
537 int argc, const char **argv)
538{
539 struct policy_handle connect_pol, domain_pol, group_pol;
540 NTSTATUS status, result;
541 enum samr_GroupInfoEnum info_level = GROUPINFOALL;
542 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
543 union samr_GroupInfo *group_info = NULL;
544 uint32 group_rid;
545 struct dcerpc_binding_handle *b = cli->binding_handle;
546
547 if ((argc < 2) || (argc > 4)) {
548 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
549 return NT_STATUS_OK;
550 }
551
552 sscanf(argv[1], "%i", &group_rid);
553
554 if (argc > 2)
555 info_level = atoi(argv[2]);
556
557 if (argc > 3)
558 sscanf(argv[3], "%x", &access_mask);
559
560 status = rpccli_try_samr_connects(cli, mem_ctx,
561 MAXIMUM_ALLOWED_ACCESS,
562 &connect_pol);
563 if (!NT_STATUS_IS_OK(status)) {
564 goto done;
565 }
566
567 status = dcerpc_samr_OpenDomain(b, mem_ctx,
568 &connect_pol,
569 MAXIMUM_ALLOWED_ACCESS,
570 &domain_sid,
571 &domain_pol,
572 &result);
573 if (!NT_STATUS_IS_OK(status)) {
574 goto done;
575 }
576 if (!NT_STATUS_IS_OK(result)) {
577 status = result;
578 goto done;
579 }
580
581 status = dcerpc_samr_OpenGroup(b, mem_ctx,
582 &domain_pol,
583 access_mask,
584 group_rid,
585 &group_pol,
586 &result);
587 if (!NT_STATUS_IS_OK(status)) {
588 goto done;
589 }
590 if (!NT_STATUS_IS_OK(result)) {
591 status = result;
592 goto done;
593 }
594
595 status = dcerpc_samr_QueryGroupInfo(b, mem_ctx,
596 &group_pol,
597 info_level,
598 &group_info,
599 &result);
600 if (!NT_STATUS_IS_OK(status)) {
601 goto done;
602 }
603 if (!NT_STATUS_IS_OK(result)) {
604 status = result;
605 goto done;
606 }
607
608 display_group_info(group_info, info_level);
609
610 dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
611 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
612 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
613done:
614 return status;
615}
616
617/* Query groups a user is a member of */
618
619static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
620 TALLOC_CTX *mem_ctx,
621 int argc, const char **argv)
622{
623 struct policy_handle connect_pol,
624 domain_pol,
625 user_pol;
626 NTSTATUS status, result;
627 uint32 user_rid;
628 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
629 int i;
630 struct samr_RidWithAttributeArray *rid_array = NULL;
631 struct dcerpc_binding_handle *b = cli->binding_handle;
632
633 if ((argc < 2) || (argc > 3)) {
634 printf("Usage: %s rid [access mask]\n", argv[0]);
635 return NT_STATUS_OK;
636 }
637
638 sscanf(argv[1], "%i", &user_rid);
639
640 if (argc > 2)
641 sscanf(argv[2], "%x", &access_mask);
642
643 status = rpccli_try_samr_connects(cli, mem_ctx,
644 MAXIMUM_ALLOWED_ACCESS,
645 &connect_pol);
646 if (!NT_STATUS_IS_OK(status)) {
647 goto done;
648 }
649
650 status = dcerpc_samr_OpenDomain(b, mem_ctx,
651 &connect_pol,
652 MAXIMUM_ALLOWED_ACCESS,
653 &domain_sid,
654 &domain_pol,
655 &result);
656 if (!NT_STATUS_IS_OK(status)) {
657 goto done;
658 }
659 if (!NT_STATUS_IS_OK(result)) {
660 status = result;
661 goto done;
662 }
663
664 status = dcerpc_samr_OpenUser(b, mem_ctx,
665 &domain_pol,
666 access_mask,
667 user_rid,
668 &user_pol,
669 &result);
670
671 if (!NT_STATUS_IS_OK(status)) {
672 goto done;
673 }
674 if (!NT_STATUS_IS_OK(result)) {
675 status = result;
676 goto done;
677 }
678
679 status = dcerpc_samr_GetGroupsForUser(b, mem_ctx,
680 &user_pol,
681 &rid_array,
682 &result);
683 if (!NT_STATUS_IS_OK(status)) {
684 goto done;
685 }
686 if (!NT_STATUS_IS_OK(result)) {
687 status = result;
688 goto done;
689 }
690
691 for (i = 0; i < rid_array->count; i++) {
692 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
693 rid_array->rids[i].rid,
694 rid_array->rids[i].attributes);
695 }
696
697 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
698 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
699 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
700 done:
701 return status;
702}
703
704/* Query aliases a user is a member of */
705
706static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
707 TALLOC_CTX *mem_ctx,
708 int argc, const char **argv)
709{
710 struct policy_handle connect_pol, domain_pol;
711 NTSTATUS status, result;
712 struct dom_sid *sids;
713 uint32_t num_sids;
714 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
715 int i;
716 struct lsa_SidArray sid_array;
717 struct samr_Ids alias_rids;
718 struct dcerpc_binding_handle *b = cli->binding_handle;
719
720 if (argc < 3) {
721 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
722 return NT_STATUS_INVALID_PARAMETER;
723 }
724
725 sids = NULL;
726 num_sids = 0;
727
728 for (i=2; i<argc; i++) {
729 struct dom_sid tmp_sid;
730 if (!string_to_sid(&tmp_sid, argv[i])) {
731 printf("%s is not a legal SID\n", argv[i]);
732 return NT_STATUS_INVALID_PARAMETER;
733 }
734 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
735 if (!NT_STATUS_IS_OK(result)) {
736 return result;
737 }
738 }
739
740 if (num_sids) {
741 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids);
742 if (sid_array.sids == NULL)
743 return NT_STATUS_NO_MEMORY;
744 } else {
745 sid_array.sids = NULL;
746 }
747
748 for (i=0; i<num_sids; i++) {
749 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]);
750 if (!sid_array.sids[i].sid) {
751 return NT_STATUS_NO_MEMORY;
752 }
753 }
754
755 sid_array.num_sids = num_sids;
756
757 status = rpccli_try_samr_connects(cli, mem_ctx,
758 MAXIMUM_ALLOWED_ACCESS,
759 &connect_pol);
760 if (!NT_STATUS_IS_OK(status)) {
761 goto done;
762 }
763
764 status = get_domain_handle(cli, mem_ctx, argv[1],
765 &connect_pol,
766 access_mask,
767 &domain_sid,
768 &domain_pol);
769 if (!NT_STATUS_IS_OK(status)) {
770 goto done;
771 }
772
773 status = dcerpc_samr_GetAliasMembership(b, mem_ctx,
774 &domain_pol,
775 &sid_array,
776 &alias_rids,
777 &result);
778 if (!NT_STATUS_IS_OK(status)) {
779 goto done;
780 }
781 if (!NT_STATUS_IS_OK(result)) {
782 status = result;
783 goto done;
784 }
785
786 for (i = 0; i < alias_rids.count; i++) {
787 printf("\tgroup rid:[0x%x]\n", alias_rids.ids[i]);
788 }
789
790 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
791 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
792 done:
793 return status;
794}
795
796/* Query members of a group */
797
798static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
799 TALLOC_CTX *mem_ctx,
800 int argc, const char **argv)
801{
802 struct policy_handle connect_pol, domain_pol, group_pol;
803 NTSTATUS status, result;
804 uint32 group_rid;
805 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
806 int i;
807 unsigned int old_timeout;
808 struct samr_RidAttrArray *rids = NULL;
809 struct dcerpc_binding_handle *b = cli->binding_handle;
810
811 if ((argc < 2) || (argc > 3)) {
812 printf("Usage: %s rid [access mask]\n", argv[0]);
813 return NT_STATUS_OK;
814 }
815
816 sscanf(argv[1], "%i", &group_rid);
817
818 if (argc > 2)
819 sscanf(argv[2], "%x", &access_mask);
820
821 status = rpccli_try_samr_connects(cli, mem_ctx,
822 MAXIMUM_ALLOWED_ACCESS,
823 &connect_pol);
824 if (!NT_STATUS_IS_OK(status)) {
825 goto done;
826 }
827
828 status = dcerpc_samr_OpenDomain(b, mem_ctx,
829 &connect_pol,
830 MAXIMUM_ALLOWED_ACCESS,
831 &domain_sid,
832 &domain_pol,
833 &result);
834 if (!NT_STATUS_IS_OK(status)) {
835 goto done;
836 }
837 if (!NT_STATUS_IS_OK(result)) {
838 status = result;
839 goto done;
840 }
841
842 status = dcerpc_samr_OpenGroup(b, mem_ctx,
843 &domain_pol,
844 access_mask,
845 group_rid,
846 &group_pol,
847 &result);
848 if (!NT_STATUS_IS_OK(status)) {
849 goto done;
850 }
851 if (!NT_STATUS_IS_OK(result)) {
852 status = result;
853 goto done;
854 }
855
856 /* Make sure to wait for our DC's reply */
857 old_timeout = rpccli_set_timeout(cli, 30000); /* 30 seconds. */
858 rpccli_set_timeout(cli, MAX(30000, old_timeout)); /* At least 30 sec */
859
860 status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
861 &group_pol,
862 &rids,
863 &result);
864
865 rpccli_set_timeout(cli, old_timeout);
866
867 if (!NT_STATUS_IS_OK(status)) {
868 goto done;
869 }
870 if (!NT_STATUS_IS_OK(result)) {
871 status = result;
872 goto done;
873 }
874
875 for (i = 0; i < rids->count; i++) {
876 printf("\trid:[0x%x] attr:[0x%x]\n", rids->rids[i],
877 rids->attributes[i]);
878 }
879
880 dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
881 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
882 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
883 done:
884 return status;
885}
886
887/* Enumerate domain users */
888
889static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
890 TALLOC_CTX *mem_ctx,
891 int argc, const char **argv)
892{
893 struct policy_handle connect_pol, domain_pol;
894 NTSTATUS status, result;
895 uint32 start_idx, num_dom_users, i;
896 struct samr_SamArray *dom_users = NULL;
897 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
898 uint32 acb_mask = ACB_NORMAL;
899 uint32_t size = 0xffff;
900 struct dcerpc_binding_handle *b = cli->binding_handle;
901
902 if ((argc < 1) || (argc > 4)) {
903 printf("Usage: %s [access_mask] [acb_mask] [size]\n", argv[0]);
904 return NT_STATUS_OK;
905 }
906
907 if (argc > 1) {
908 sscanf(argv[1], "%x", &access_mask);
909 }
910
911 if (argc > 2) {
912 sscanf(argv[2], "%x", &acb_mask);
913 }
914
915 if (argc > 3) {
916 sscanf(argv[3], "%x", &size);
917 }
918
919 /* Get sam policy handle */
920
921 status = rpccli_try_samr_connects(cli, mem_ctx,
922 MAXIMUM_ALLOWED_ACCESS,
923 &connect_pol);
924 if (!NT_STATUS_IS_OK(status)) {
925 goto done;
926 }
927
928 /* Get domain policy handle */
929
930 status = get_domain_handle(cli, mem_ctx, "domain",
931 &connect_pol,
932 access_mask,
933 &domain_sid,
934 &domain_pol);
935 if (!NT_STATUS_IS_OK(status)) {
936 goto done;
937 }
938
939 /* Enumerate domain users */
940
941 start_idx = 0;
942
943 do {
944 status = dcerpc_samr_EnumDomainUsers(b, mem_ctx,
945 &domain_pol,
946 &start_idx,
947 acb_mask,
948 &dom_users,
949 size,
950 &num_dom_users,
951 &result);
952 if (!NT_STATUS_IS_OK(status)) {
953 goto done;
954 }
955 if (NT_STATUS_IS_OK(result) ||
956 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
957
958 for (i = 0; i < num_dom_users; i++)
959 printf("user:[%s] rid:[0x%x]\n",
960 dom_users->entries[i].name.string,
961 dom_users->entries[i].idx);
962 }
963
964 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
965
966 done:
967 if (is_valid_policy_hnd(&domain_pol))
968 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
969
970 if (is_valid_policy_hnd(&connect_pol))
971 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
972
973 return status;
974}
975
976/* Enumerate domain groups */
977
978static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
979 TALLOC_CTX *mem_ctx,
980 int argc, const char **argv)
981{
982 struct policy_handle connect_pol, domain_pol;
983 NTSTATUS status, result;
984 uint32 start_idx, num_dom_groups, i;
985 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
986 struct samr_SamArray *dom_groups = NULL;
987 uint32_t size = 0xffff;
988 struct dcerpc_binding_handle *b = cli->binding_handle;
989
990 if ((argc < 1) || (argc > 3)) {
991 printf("Usage: %s [access_mask] [max_size]\n", argv[0]);
992 return NT_STATUS_OK;
993 }
994
995 if (argc > 1) {
996 sscanf(argv[1], "%x", &access_mask);
997 }
998
999 if (argc > 2) {
1000 sscanf(argv[2], "%x", &size);
1001 }
1002
1003 /* Get sam policy handle */
1004
1005 status = rpccli_try_samr_connects(cli, mem_ctx,
1006 MAXIMUM_ALLOWED_ACCESS,
1007 &connect_pol);
1008 if (!NT_STATUS_IS_OK(status)) {
1009 goto done;
1010 }
1011
1012 /* Get domain policy handle */
1013
1014 status = get_domain_handle(cli, mem_ctx, "domain",
1015 &connect_pol,
1016 access_mask,
1017 &domain_sid,
1018 &domain_pol);
1019 if (!NT_STATUS_IS_OK(status)) {
1020 goto done;
1021 }
1022
1023 /* Enumerate domain groups */
1024
1025 start_idx = 0;
1026
1027 do {
1028 status = dcerpc_samr_EnumDomainGroups(b, mem_ctx,
1029 &domain_pol,
1030 &start_idx,
1031 &dom_groups,
1032 size,
1033 &num_dom_groups,
1034 &result);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 goto done;
1037 }
1038 if (NT_STATUS_IS_OK(result) ||
1039 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1040
1041 for (i = 0; i < num_dom_groups; i++)
1042 printf("group:[%s] rid:[0x%x]\n",
1043 dom_groups->entries[i].name.string,
1044 dom_groups->entries[i].idx);
1045 }
1046
1047 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1048
1049 done:
1050 if (is_valid_policy_hnd(&domain_pol))
1051 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1052
1053 if (is_valid_policy_hnd(&connect_pol))
1054 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1055
1056 return status;
1057}
1058
1059/* Enumerate alias groups */
1060
1061static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
1062 TALLOC_CTX *mem_ctx,
1063 int argc, const char **argv)
1064{
1065 struct policy_handle connect_pol, domain_pol;
1066 NTSTATUS status, result;
1067 uint32 start_idx, num_als_groups, i;
1068 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1069 struct samr_SamArray *als_groups = NULL;
1070 uint32_t size = 0xffff;
1071 struct dcerpc_binding_handle *b = cli->binding_handle;
1072
1073 if ((argc < 2) || (argc > 4)) {
1074 printf("Usage: %s builtin|domain [access mask] [max_size]\n", argv[0]);
1075 return NT_STATUS_OK;
1076 }
1077
1078 if (argc > 2) {
1079 sscanf(argv[2], "%x", &access_mask);
1080 }
1081
1082 if (argc > 3) {
1083 sscanf(argv[3], "%x", &size);
1084 }
1085
1086 /* Get sam policy handle */
1087
1088 status = rpccli_try_samr_connects(cli, mem_ctx,
1089 MAXIMUM_ALLOWED_ACCESS,
1090 &connect_pol);
1091 if (!NT_STATUS_IS_OK(status)) {
1092 goto done;
1093 }
1094
1095 /* Get domain policy handle */
1096
1097 status = get_domain_handle(cli, mem_ctx, argv[1],
1098 &connect_pol,
1099 access_mask,
1100 &domain_sid,
1101 &domain_pol);
1102 if (!NT_STATUS_IS_OK(status)) {
1103 goto done;
1104 }
1105
1106 /* Enumerate alias groups */
1107
1108 start_idx = 0;
1109
1110 do {
1111 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
1112 &domain_pol,
1113 &start_idx,
1114 &als_groups,
1115 size,
1116 &num_als_groups,
1117 &result);
1118 if (!NT_STATUS_IS_OK(status)) {
1119 goto done;
1120 }
1121 if (NT_STATUS_IS_OK(result) ||
1122 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1123
1124 for (i = 0; i < num_als_groups; i++)
1125 printf("group:[%s] rid:[0x%x]\n",
1126 als_groups->entries[i].name.string,
1127 als_groups->entries[i].idx);
1128 }
1129 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1130
1131 done:
1132 if (is_valid_policy_hnd(&domain_pol))
1133 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1134
1135 if (is_valid_policy_hnd(&connect_pol))
1136 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1137
1138 return status;
1139}
1140
1141/* Enumerate domains */
1142
1143static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
1144 TALLOC_CTX *mem_ctx,
1145 int argc, const char **argv)
1146{
1147 struct policy_handle connect_pol;
1148 NTSTATUS status, result;
1149 uint32 start_idx, size, num_entries, i;
1150 uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1151 struct samr_SamArray *sam = NULL;
1152 struct dcerpc_binding_handle *b = cli->binding_handle;
1153
1154 if ((argc < 1) || (argc > 2)) {
1155 printf("Usage: %s [access mask]\n", argv[0]);
1156 return NT_STATUS_OK;
1157 }
1158
1159 if (argc > 1) {
1160 sscanf(argv[1], "%x", &access_mask);
1161 }
1162
1163 /* Get sam policy handle */
1164
1165 status = rpccli_try_samr_connects(cli, mem_ctx,
1166 access_mask,
1167 &connect_pol);
1168 if (!NT_STATUS_IS_OK(status)) {
1169 goto done;
1170 }
1171
1172 /* Enumerate alias groups */
1173
1174 start_idx = 0;
1175 size = 0xffff;
1176
1177 do {
1178 status = dcerpc_samr_EnumDomains(b, mem_ctx,
1179 &connect_pol,
1180 &start_idx,
1181 &sam,
1182 size,
1183 &num_entries,
1184 &result);
1185 if (!NT_STATUS_IS_OK(status)) {
1186 goto done;
1187 }
1188 if (NT_STATUS_IS_OK(result) ||
1189 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1190
1191 for (i = 0; i < num_entries; i++)
1192 printf("name:[%s] idx:[0x%x]\n",
1193 sam->entries[i].name.string,
1194 sam->entries[i].idx);
1195 }
1196 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1197
1198 done:
1199 if (is_valid_policy_hnd(&connect_pol)) {
1200 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1201 }
1202
1203 return status;
1204}
1205
1206
1207/* Query alias membership */
1208
1209static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1210 TALLOC_CTX *mem_ctx,
1211 int argc, const char **argv)
1212{
1213 struct policy_handle connect_pol, domain_pol, alias_pol;
1214 NTSTATUS status, result;
1215 uint32 alias_rid, i;
1216 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1217 struct lsa_SidArray sid_array;
1218 struct dcerpc_binding_handle *b = cli->binding_handle;
1219
1220 if ((argc < 3) || (argc > 4)) {
1221 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1222 return NT_STATUS_OK;
1223 }
1224
1225 sscanf(argv[2], "%i", &alias_rid);
1226
1227 if (argc > 3)
1228 sscanf(argv[3], "%x", &access_mask);
1229
1230 /* Open SAMR handle */
1231
1232 status = rpccli_try_samr_connects(cli, mem_ctx,
1233 MAXIMUM_ALLOWED_ACCESS,
1234 &connect_pol);
1235 if (!NT_STATUS_IS_OK(status)) {
1236 goto done;
1237 }
1238
1239 /* Open handle on domain */
1240
1241 status = get_domain_handle(cli, mem_ctx, argv[1],
1242 &connect_pol,
1243 MAXIMUM_ALLOWED_ACCESS,
1244 &domain_sid,
1245 &domain_pol);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 goto done;
1248 }
1249
1250 /* Open handle on alias */
1251
1252 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1253 &domain_pol,
1254 access_mask,
1255 alias_rid,
1256 &alias_pol,
1257 &result);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 goto done;
1260 }
1261 if (!NT_STATUS_IS_OK(result)) {
1262 status = result;
1263 goto done;
1264 }
1265
1266 status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
1267 &alias_pol,
1268 &sid_array,
1269 &result);
1270 if (!NT_STATUS_IS_OK(status)) {
1271 goto done;
1272 }
1273 if (!NT_STATUS_IS_OK(result)) {
1274 status = result;
1275 goto done;
1276 }
1277
1278 for (i = 0; i < sid_array.num_sids; i++) {
1279 fstring sid_str;
1280
1281 sid_to_fstring(sid_str, sid_array.sids[i].sid);
1282 printf("\tsid:[%s]\n", sid_str);
1283 }
1284
1285 dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
1286 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1287 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1288 done:
1289 return status;
1290}
1291
1292/* Query alias info */
1293
1294static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
1295 TALLOC_CTX *mem_ctx,
1296 int argc, const char **argv)
1297{
1298 struct policy_handle connect_pol, domain_pol, alias_pol;
1299 NTSTATUS status, result;
1300 uint32_t alias_rid;
1301 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1302 union samr_AliasInfo *info = NULL;
1303 enum samr_AliasInfoEnum level = ALIASINFOALL;
1304 struct dcerpc_binding_handle *b = cli->binding_handle;
1305
1306 if ((argc < 3) || (argc > 4)) {
1307 printf("Usage: %s builtin|domain rid [level] [access mask]\n",
1308 argv[0]);
1309 return NT_STATUS_OK;
1310 }
1311
1312 sscanf(argv[2], "%i", &alias_rid);
1313
1314 if (argc > 2) {
1315 level = atoi(argv[3]);
1316 }
1317
1318 if (argc > 3) {
1319 sscanf(argv[4], "%x", &access_mask);
1320 }
1321
1322 /* Open SAMR handle */
1323
1324 status = rpccli_try_samr_connects(cli, mem_ctx,
1325 SEC_FLAG_MAXIMUM_ALLOWED,
1326 &connect_pol);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 goto done;
1329 }
1330
1331 /* Open handle on domain */
1332
1333 status = get_domain_handle(cli, mem_ctx, argv[1],
1334 &connect_pol,
1335 SEC_FLAG_MAXIMUM_ALLOWED,
1336 &domain_sid,
1337 &domain_pol);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 goto done;
1340 }
1341
1342 /* Open handle on alias */
1343
1344 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1345 &domain_pol,
1346 access_mask,
1347 alias_rid,
1348 &alias_pol,
1349 &result);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 goto done;
1352 }
1353 if (!NT_STATUS_IS_OK(result)) {
1354 status = result;
1355 goto done;
1356 }
1357
1358 status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
1359 &alias_pol,
1360 level,
1361 &info,
1362 &result);
1363 if (!NT_STATUS_IS_OK(status)) {
1364 goto done;
1365 }
1366 if (!NT_STATUS_IS_OK(result)) {
1367 status = result;
1368 goto done;
1369 }
1370
1371 switch (level) {
1372 case ALIASINFOALL:
1373 printf("Name: %s\n", info->all.name.string);
1374 printf("Description: %s\n", info->all.description.string);
1375 printf("Num Members: %d\n", info->all.num_members);
1376 break;
1377 case ALIASINFONAME:
1378 printf("Name: %s\n", info->name.string);
1379 break;
1380 case ALIASINFODESCRIPTION:
1381 printf("Description: %s\n", info->description.string);
1382 break;
1383 default:
1384 break;
1385 }
1386
1387 dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
1388 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1389 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1390 done:
1391 return status;
1392}
1393
1394
1395/* Query delete an alias membership */
1396
1397static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1398 TALLOC_CTX *mem_ctx,
1399 int argc, const char **argv)
1400{
1401 struct policy_handle connect_pol, domain_pol, alias_pol;
1402 NTSTATUS status, result;
1403 uint32 alias_rid;
1404 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1405 struct dcerpc_binding_handle *b = cli->binding_handle;
1406
1407 if (argc != 3) {
1408 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1409 return NT_STATUS_OK;
1410 }
1411
1412 alias_rid = strtoul(argv[2], NULL, 10);
1413
1414 /* Open SAMR handle */
1415
1416 status = rpccli_try_samr_connects(cli, mem_ctx,
1417 MAXIMUM_ALLOWED_ACCESS,
1418 &connect_pol);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 goto done;
1421 }
1422
1423 /* Open handle on domain */
1424
1425 status = get_domain_handle(cli, mem_ctx, argv[1],
1426 &connect_pol,
1427 MAXIMUM_ALLOWED_ACCESS,
1428 &domain_sid,
1429 &domain_pol);
1430 if (!NT_STATUS_IS_OK(status)) {
1431 goto done;
1432 }
1433
1434 /* Open handle on alias */
1435
1436 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1437 &domain_pol,
1438 access_mask,
1439 alias_rid,
1440 &alias_pol,
1441 &result);
1442 if (!NT_STATUS_IS_OK(status)) {
1443 goto done;
1444 }
1445 if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1446 /* Probably this was a user name, try lookupnames */
1447 struct samr_Ids rids, types;
1448 struct lsa_String lsa_acct_name;
1449
1450 init_lsa_String(&lsa_acct_name, argv[2]);
1451
1452 status = dcerpc_samr_LookupNames(b, mem_ctx,
1453 &domain_pol,
1454 1,
1455 &lsa_acct_name,
1456 &rids,
1457 &types,
1458 &result);
1459 if (!NT_STATUS_IS_OK(status)) {
1460 goto done;
1461 }
1462 if (NT_STATUS_IS_OK(result)) {
1463 if (rids.count != 1) {
1464 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1465 goto done;
1466 }
1467 if (types.count != 1) {
1468 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1469 goto done;
1470 }
1471
1472 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1473 &domain_pol,
1474 access_mask,
1475 rids.ids[0],
1476 &alias_pol,
1477 &result);
1478 if (!NT_STATUS_IS_OK(status)) {
1479 goto done;
1480 }
1481 }
1482 }
1483
1484 status = dcerpc_samr_DeleteDomAlias(b, mem_ctx,
1485 &alias_pol,
1486 &result);
1487 if (!NT_STATUS_IS_OK(status)) {
1488 goto done;
1489 }
1490 if (!NT_STATUS_IS_OK(result)) {
1491 status = result;
1492 goto done;
1493 }
1494
1495 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1496 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1497 done:
1498 return status;
1499}
1500
1501/* Query display info */
1502
1503static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli,
1504 TALLOC_CTX *mem_ctx,
1505 int argc, const char **argv,
1506 uint32_t opcode)
1507{
1508 struct policy_handle connect_pol, domain_pol;
1509 NTSTATUS status, result;
1510 uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
1511 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1512 uint32 info_level = 1;
1513 union samr_DispInfo info;
1514 int loop_count = 0;
1515 bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1516 uint32_t total_size, returned_size;
1517 struct dcerpc_binding_handle *b = cli->binding_handle;
1518
1519 if (argc > 6) {
1520 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1521 return NT_STATUS_OK;
1522 }
1523
1524 if (argc >= 2)
1525 sscanf(argv[1], "%i", &info_level);
1526
1527 if (argc >= 3)
1528 sscanf(argv[2], "%i", &start_idx);
1529
1530 if (argc >= 4) {
1531 sscanf(argv[3], "%i", &max_entries);
1532 got_params = True;
1533 }
1534
1535 if (argc >= 5) {
1536 sscanf(argv[4], "%i", &max_size);
1537 got_params = True;
1538 }
1539
1540 if (argc >= 6)
1541 sscanf(argv[5], "%x", &access_mask);
1542
1543 /* Get sam policy handle */
1544
1545 status = rpccli_try_samr_connects(cli, mem_ctx,
1546 MAXIMUM_ALLOWED_ACCESS,
1547 &connect_pol);
1548 if (!NT_STATUS_IS_OK(status)) {
1549 goto done;
1550 }
1551
1552 /* Get domain policy handle */
1553
1554 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1555 &connect_pol,
1556 access_mask,
1557 &domain_sid,
1558 &domain_pol,
1559 &result);
1560 if (!NT_STATUS_IS_OK(status)) {
1561 goto done;
1562 }
1563 if (!NT_STATUS_IS_OK(result)) {
1564 status = result;
1565 goto done;
1566 }
1567
1568 /* Query display info */
1569
1570 do {
1571
1572 if (!got_params)
1573 dcerpc_get_query_dispinfo_params(
1574 loop_count, &max_entries, &max_size);
1575
1576 switch (opcode) {
1577 case NDR_SAMR_QUERYDISPLAYINFO:
1578 status = dcerpc_samr_QueryDisplayInfo(b, mem_ctx,
1579 &domain_pol,
1580 info_level,
1581 start_idx,
1582 max_entries,
1583 max_size,
1584 &total_size,
1585 &returned_size,
1586 &info,
1587 &result);
1588 break;
1589 case NDR_SAMR_QUERYDISPLAYINFO2:
1590 status = dcerpc_samr_QueryDisplayInfo2(b, mem_ctx,
1591 &domain_pol,
1592 info_level,
1593 start_idx,
1594 max_entries,
1595 max_size,
1596 &total_size,
1597 &returned_size,
1598 &info,
1599 &result);
1600
1601 break;
1602 case NDR_SAMR_QUERYDISPLAYINFO3:
1603 status = dcerpc_samr_QueryDisplayInfo3(b, mem_ctx,
1604 &domain_pol,
1605 info_level,
1606 start_idx,
1607 max_entries,
1608 max_size,
1609 &total_size,
1610 &returned_size,
1611 &info,
1612 &result);
1613
1614 break;
1615 default:
1616 return NT_STATUS_INVALID_PARAMETER;
1617 }
1618
1619 if (!NT_STATUS_IS_OK(status)) {
1620 break;
1621 }
1622 status = result;
1623 if (!NT_STATUS_IS_OK(result) &&
1624 !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
1625 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1626 break;
1627 }
1628
1629 loop_count++;
1630
1631 switch (info_level) {
1632 case 1:
1633 num_entries = info.info1.count;
1634 break;
1635 case 2:
1636 num_entries = info.info2.count;
1637 break;
1638 case 3:
1639 num_entries = info.info3.count;
1640 break;
1641 case 4:
1642 num_entries = info.info4.count;
1643 break;
1644 case 5:
1645 num_entries = info.info5.count;
1646 break;
1647 default:
1648 break;
1649 }
1650
1651 start_idx += num_entries;
1652
1653 if (num_entries == 0)
1654 break;
1655
1656 for (i = 0; i < num_entries; i++) {
1657 switch (info_level) {
1658 case 1:
1659 display_sam_info_1(&info.info1.entries[i]);
1660 break;
1661 case 2:
1662 display_sam_info_2(&info.info2.entries[i]);
1663 break;
1664 case 3:
1665 display_sam_info_3(&info.info3.entries[i]);
1666 break;
1667 case 4:
1668 display_sam_info_4(&info.info4.entries[i]);
1669 break;
1670 case 5:
1671 display_sam_info_5(&info.info5.entries[i]);
1672 break;
1673 }
1674 }
1675 } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1676
1677 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1678 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1679 done:
1680 return status;
1681}
1682
1683static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1684 TALLOC_CTX *mem_ctx,
1685 int argc, const char **argv)
1686{
1687 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1688 NDR_SAMR_QUERYDISPLAYINFO);
1689}
1690
1691static NTSTATUS cmd_samr_query_dispinfo2(struct rpc_pipe_client *cli,
1692 TALLOC_CTX *mem_ctx,
1693 int argc, const char **argv)
1694{
1695 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1696 NDR_SAMR_QUERYDISPLAYINFO2);
1697}
1698
1699static NTSTATUS cmd_samr_query_dispinfo3(struct rpc_pipe_client *cli,
1700 TALLOC_CTX *mem_ctx,
1701 int argc, const char **argv)
1702{
1703 return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1704 NDR_SAMR_QUERYDISPLAYINFO3);
1705}
1706
1707/* Query domain info */
1708
1709static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1710 TALLOC_CTX *mem_ctx,
1711 int argc, const char **argv)
1712{
1713 struct policy_handle connect_pol, domain_pol;
1714 NTSTATUS status, result;
1715 uint32 switch_level = 2;
1716 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1717 union samr_DomainInfo *info = NULL;
1718 struct dcerpc_binding_handle *b = cli->binding_handle;
1719
1720 if (argc > 3) {
1721 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1722 return NT_STATUS_OK;
1723 }
1724
1725 if (argc > 1)
1726 sscanf(argv[1], "%i", &switch_level);
1727
1728 if (argc > 2)
1729 sscanf(argv[2], "%x", &access_mask);
1730
1731 /* Get sam policy handle */
1732
1733 status = rpccli_try_samr_connects(cli, mem_ctx,
1734 MAXIMUM_ALLOWED_ACCESS,
1735 &connect_pol);
1736 if (!NT_STATUS_IS_OK(status)) {
1737 goto done;
1738 }
1739
1740 /* Get domain policy handle */
1741
1742 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1743 &connect_pol,
1744 access_mask,
1745 &domain_sid,
1746 &domain_pol,
1747 &result);
1748 if (!NT_STATUS_IS_OK(status)) {
1749 goto done;
1750 }
1751 if (!NT_STATUS_IS_OK(result)) {
1752 status = result;
1753 goto done;
1754 }
1755
1756 /* Query domain info */
1757
1758 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
1759 &domain_pol,
1760 switch_level,
1761 &info,
1762 &result);
1763 if (!NT_STATUS_IS_OK(status)) {
1764 goto done;
1765 }
1766 if (!NT_STATUS_IS_OK(result)) {
1767 status = result;
1768 goto done;
1769 }
1770
1771 /* Display domain info */
1772
1773 switch (switch_level) {
1774 case 1:
1775 display_sam_dom_info_1(&info->info1);
1776 break;
1777 case 2:
1778 display_sam_dom_info_2(&info->general);
1779 break;
1780 case 3:
1781 display_sam_dom_info_3(&info->info3);
1782 break;
1783 case 4:
1784 display_sam_dom_info_4(&info->oem);
1785 break;
1786 case 5:
1787 display_sam_dom_info_5(&info->info5);
1788 break;
1789 case 6:
1790 display_sam_dom_info_6(&info->info6);
1791 break;
1792 case 7:
1793 display_sam_dom_info_7(&info->info7);
1794 break;
1795 case 8:
1796 display_sam_dom_info_8(&info->info8);
1797 break;
1798 case 9:
1799 display_sam_dom_info_9(&info->info9);
1800 break;
1801 case 12:
1802 display_sam_dom_info_12(&info->info12);
1803 break;
1804 case 13:
1805 display_sam_dom_info_13(&info->info13);
1806 break;
1807
1808 default:
1809 printf("cannot display domain info for switch value %d\n",
1810 switch_level);
1811 break;
1812 }
1813
1814 done:
1815
1816 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1817 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1818 return status;
1819}
1820
1821/* Create domain user */
1822
1823static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1824 TALLOC_CTX *mem_ctx,
1825 int argc, const char **argv)
1826{
1827 struct policy_handle connect_pol, domain_pol, user_pol;
1828 NTSTATUS status, result;
1829 struct lsa_String acct_name;
1830 uint32 acb_info;
1831 uint32 acct_flags, user_rid;
1832 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1833 uint32_t access_granted = 0;
1834 struct dcerpc_binding_handle *b = cli->binding_handle;
1835
1836 if ((argc < 2) || (argc > 3)) {
1837 printf("Usage: %s username [access mask]\n", argv[0]);
1838 return NT_STATUS_OK;
1839 }
1840
1841 init_lsa_String(&acct_name, argv[1]);
1842
1843 if (argc > 2)
1844 sscanf(argv[2], "%x", &access_mask);
1845
1846 /* Get sam policy handle */
1847
1848 status = rpccli_try_samr_connects(cli, mem_ctx,
1849 MAXIMUM_ALLOWED_ACCESS,
1850 &connect_pol);
1851 if (!NT_STATUS_IS_OK(status)) {
1852 goto done;
1853 }
1854
1855 /* Get domain policy handle */
1856
1857 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1858 &connect_pol,
1859 access_mask,
1860 &domain_sid,
1861 &domain_pol,
1862 &result);
1863 if (!NT_STATUS_IS_OK(status)) {
1864 goto done;
1865 }
1866 if (!NT_STATUS_IS_OK(result)) {
1867 status = result;
1868 goto done;
1869 }
1870
1871 /* Create domain user */
1872
1873 acb_info = ACB_NORMAL;
1874 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1875 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1876 SAMR_USER_ACCESS_SET_PASSWORD |
1877 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1878 SAMR_USER_ACCESS_SET_ATTRIBUTES;
1879
1880 status = dcerpc_samr_CreateUser2(b, mem_ctx,
1881 &domain_pol,
1882 &acct_name,
1883 acb_info,
1884 acct_flags,
1885 &user_pol,
1886 &access_granted,
1887 &user_rid,
1888 &result);
1889 if (!NT_STATUS_IS_OK(status)) {
1890 goto done;
1891 }
1892 if (!NT_STATUS_IS_OK(result)) {
1893 status = result;
1894 goto done;
1895 }
1896
1897 status = dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1898 if (!NT_STATUS_IS_OK(status)) goto done;
1899
1900 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1901 if (!NT_STATUS_IS_OK(status)) goto done;
1902
1903 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1904 if (!NT_STATUS_IS_OK(status)) goto done;
1905
1906 done:
1907 return status;
1908}
1909
1910/* Create domain group */
1911
1912static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1913 TALLOC_CTX *mem_ctx,
1914 int argc, const char **argv)
1915{
1916 struct policy_handle connect_pol, domain_pol, group_pol;
1917 NTSTATUS status, result;
1918 struct lsa_String grp_name;
1919 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1920 uint32_t rid = 0;
1921 struct dcerpc_binding_handle *b = cli->binding_handle;
1922
1923 if ((argc < 2) || (argc > 3)) {
1924 printf("Usage: %s groupname [access mask]\n", argv[0]);
1925 return NT_STATUS_OK;
1926 }
1927
1928 init_lsa_String(&grp_name, argv[1]);
1929
1930 if (argc > 2)
1931 sscanf(argv[2], "%x", &access_mask);
1932
1933 /* Get sam policy handle */
1934
1935 status = rpccli_try_samr_connects(cli, mem_ctx,
1936 MAXIMUM_ALLOWED_ACCESS,
1937 &connect_pol);
1938 if (!NT_STATUS_IS_OK(status)) {
1939 goto done;
1940 }
1941
1942 /* Get domain policy handle */
1943
1944 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1945 &connect_pol,
1946 access_mask,
1947 &domain_sid,
1948 &domain_pol,
1949 &result);
1950 if (!NT_STATUS_IS_OK(status)) {
1951 goto done;
1952 }
1953 if (!NT_STATUS_IS_OK(result)) {
1954 status = result;
1955 goto done;
1956 }
1957
1958 /* Create domain user */
1959 status = dcerpc_samr_CreateDomainGroup(b, mem_ctx,
1960 &domain_pol,
1961 &grp_name,
1962 MAXIMUM_ALLOWED_ACCESS,
1963 &group_pol,
1964 &rid,
1965 &result);
1966 if (!NT_STATUS_IS_OK(status)) {
1967 goto done;
1968 }
1969 if (!NT_STATUS_IS_OK(result)) {
1970 status = result;
1971 goto done;
1972 }
1973
1974 status = dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
1975 if (!NT_STATUS_IS_OK(status)) goto done;
1976
1977 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1978 if (!NT_STATUS_IS_OK(status)) goto done;
1979
1980 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1981 if (!NT_STATUS_IS_OK(status)) goto done;
1982
1983 done:
1984 return status;
1985}
1986
1987/* Create domain alias */
1988
1989static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1990 TALLOC_CTX *mem_ctx,
1991 int argc, const char **argv)
1992{
1993 struct policy_handle connect_pol, domain_pol, alias_pol;
1994 NTSTATUS status, result;
1995 struct lsa_String alias_name;
1996 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1997 uint32_t rid = 0;
1998 struct dcerpc_binding_handle *b = cli->binding_handle;
1999
2000 if ((argc < 2) || (argc > 3)) {
2001 printf("Usage: %s aliasname [access mask]\n", argv[0]);
2002 return NT_STATUS_OK;
2003 }
2004
2005 init_lsa_String(&alias_name, argv[1]);
2006
2007 if (argc > 2)
2008 sscanf(argv[2], "%x", &access_mask);
2009
2010 /* Get sam policy handle */
2011
2012 status = rpccli_try_samr_connects(cli, mem_ctx,
2013 MAXIMUM_ALLOWED_ACCESS,
2014 &connect_pol);
2015 if (!NT_STATUS_IS_OK(status)) {
2016 goto done;
2017 }
2018
2019 /* Get domain policy handle */
2020
2021 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2022 &connect_pol,
2023 access_mask,
2024 &domain_sid,
2025 &domain_pol,
2026 &result);
2027 if (!NT_STATUS_IS_OK(status)) {
2028 goto done;
2029 }
2030 if (!NT_STATUS_IS_OK(result)) {
2031 status = result;
2032 goto done;
2033 }
2034
2035 /* Create domain user */
2036
2037 status = dcerpc_samr_CreateDomAlias(b, mem_ctx,
2038 &domain_pol,
2039 &alias_name,
2040 MAXIMUM_ALLOWED_ACCESS,
2041 &alias_pol,
2042 &rid,
2043 &result);
2044 if (!NT_STATUS_IS_OK(status)) {
2045 goto done;
2046 }
2047 if (!NT_STATUS_IS_OK(result)) {
2048 status = result;
2049 goto done;
2050 }
2051
2052
2053 status = dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
2054 if (!NT_STATUS_IS_OK(status)) goto done;
2055
2056 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2057 if (!NT_STATUS_IS_OK(status)) goto done;
2058
2059 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2060 if (!NT_STATUS_IS_OK(status)) goto done;
2061
2062 done:
2063 return status;
2064}
2065
2066/* Lookup sam names */
2067
2068static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
2069 TALLOC_CTX *mem_ctx,
2070 int argc, const char **argv)
2071{
2072 NTSTATUS status, result;
2073 struct policy_handle connect_pol, domain_pol;
2074 uint32 num_names;
2075 struct samr_Ids rids, name_types;
2076 int i;
2077 struct lsa_String *names = NULL;
2078 struct dcerpc_binding_handle *b = cli->binding_handle;
2079
2080 if (argc < 3) {
2081 printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
2082 printf("check on the domain SID: S-1-5-21-x-y-z\n");
2083 printf("or check on the builtin SID: S-1-5-32\n");
2084 return NT_STATUS_OK;
2085 }
2086
2087 /* Get sam policy and domain handles */
2088
2089 status = rpccli_try_samr_connects(cli, mem_ctx,
2090 MAXIMUM_ALLOWED_ACCESS,
2091 &connect_pol);
2092 if (!NT_STATUS_IS_OK(status)) {
2093 goto done;
2094 }
2095
2096 status = get_domain_handle(cli, mem_ctx, argv[1],
2097 &connect_pol,
2098 MAXIMUM_ALLOWED_ACCESS,
2099 &domain_sid,
2100 &domain_pol);
2101 if (!NT_STATUS_IS_OK(status)) {
2102 goto done;
2103 }
2104
2105 /* Look up names */
2106
2107 num_names = argc - 2;
2108
2109 if ((names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names)) == NULL) {
2110 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2111 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2112 status = NT_STATUS_NO_MEMORY;
2113 goto done;
2114 }
2115
2116 for (i = 0; i < num_names; i++) {
2117 init_lsa_String(&names[i], argv[i + 2]);
2118 }
2119
2120 status = dcerpc_samr_LookupNames(b, mem_ctx,
2121 &domain_pol,
2122 num_names,
2123 names,
2124 &rids,
2125 &name_types,
2126 &result);
2127 if (!NT_STATUS_IS_OK(status)) {
2128 goto done;
2129 }
2130 if (!NT_STATUS_IS_OK(result)) {
2131 status = result;
2132 goto done;
2133 }
2134 if (rids.count != num_names) {
2135 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2136 goto done;
2137 }
2138 if (name_types.count != num_names) {
2139 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2140 goto done;
2141 }
2142
2143 /* Display results */
2144
2145 for (i = 0; i < num_names; i++)
2146 printf("name %s: 0x%x (%d)\n", names[i].string, rids.ids[i],
2147 name_types.ids[i]);
2148
2149 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2150 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2151 done:
2152 return status;
2153}
2154
2155/* Lookup sam rids */
2156
2157static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
2158 TALLOC_CTX *mem_ctx,
2159 int argc, const char **argv)
2160{
2161 NTSTATUS status, result;
2162 struct policy_handle connect_pol, domain_pol;
2163 uint32_t num_rids, *rids;
2164 struct lsa_Strings names;
2165 struct samr_Ids types;
2166 struct dcerpc_binding_handle *b = cli->binding_handle;
2167
2168 int i;
2169
2170 if (argc < 3) {
2171 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
2172 return NT_STATUS_OK;
2173 }
2174
2175 /* Get sam policy and domain handles */
2176
2177 status = rpccli_try_samr_connects(cli, mem_ctx,
2178 MAXIMUM_ALLOWED_ACCESS,
2179 &connect_pol);
2180 if (!NT_STATUS_IS_OK(status)) {
2181 goto done;
2182 }
2183
2184 status = get_domain_handle(cli, mem_ctx, argv[1],
2185 &connect_pol,
2186 MAXIMUM_ALLOWED_ACCESS,
2187 &domain_sid,
2188 &domain_pol);
2189 if (!NT_STATUS_IS_OK(status)) {
2190 goto done;
2191 }
2192
2193 /* Look up rids */
2194
2195 num_rids = argc - 2;
2196
2197 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
2198 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2199 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2200 status = NT_STATUS_NO_MEMORY;
2201 goto done;
2202 }
2203
2204 for (i = 0; i < argc - 2; i++)
2205 sscanf(argv[i + 2], "%i", &rids[i]);
2206
2207 status = dcerpc_samr_LookupRids(b, mem_ctx,
2208 &domain_pol,
2209 num_rids,
2210 rids,
2211 &names,
2212 &types,
2213 &result);
2214 if (!NT_STATUS_IS_OK(status)) {
2215 goto done;
2216 }
2217 status = result;
2218 if (!NT_STATUS_IS_OK(result) &&
2219 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
2220 goto done;
2221
2222 /* Display results */
2223 if (num_rids != names.count) {
2224 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2225 goto done;
2226 }
2227 if (num_rids != types.count) {
2228 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2229 goto done;
2230 }
2231
2232 for (i = 0; i < num_rids; i++) {
2233 printf("rid 0x%x: %s (%d)\n",
2234 rids[i], names.names[i].string, types.ids[i]);
2235 }
2236
2237 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2238 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2239 done:
2240 return status;
2241}
2242
2243/* Delete domain group */
2244
2245static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
2246 TALLOC_CTX *mem_ctx,
2247 int argc, const char **argv)
2248{
2249 NTSTATUS status, result;
2250 struct policy_handle connect_pol, domain_pol, group_pol;
2251 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2252 struct dcerpc_binding_handle *b = cli->binding_handle;
2253
2254 if ((argc < 2) || (argc > 3)) {
2255 printf("Usage: %s groupname\n", argv[0]);
2256 return NT_STATUS_OK;
2257 }
2258
2259 if (argc > 2)
2260 sscanf(argv[2], "%x", &access_mask);
2261
2262 /* Get sam policy and domain handles */
2263
2264 status = rpccli_try_samr_connects(cli, mem_ctx,
2265 MAXIMUM_ALLOWED_ACCESS,
2266 &connect_pol);
2267 if (!NT_STATUS_IS_OK(status)) {
2268 goto done;
2269 }
2270
2271 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2272 &connect_pol,
2273 MAXIMUM_ALLOWED_ACCESS,
2274 &domain_sid,
2275 &domain_pol,
2276 &result);
2277 if (!NT_STATUS_IS_OK(status)) {
2278 goto done;
2279 }
2280 if (!NT_STATUS_IS_OK(result)) {
2281 status = result;
2282 goto done;
2283 }
2284
2285 /* Get handle on group */
2286
2287 {
2288 struct samr_Ids group_rids, name_types;
2289 struct lsa_String lsa_acct_name;
2290
2291 init_lsa_String(&lsa_acct_name, argv[1]);
2292
2293 status = dcerpc_samr_LookupNames(b, mem_ctx,
2294 &domain_pol,
2295 1,
2296 &lsa_acct_name,
2297 &group_rids,
2298 &name_types,
2299 &result);
2300 if (!NT_STATUS_IS_OK(status)) {
2301 goto done;
2302 }
2303 if (!NT_STATUS_IS_OK(result)) {
2304 status = result;
2305 goto done;
2306 }
2307 if (group_rids.count != 1) {
2308 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2309 goto done;
2310 }
2311 if (name_types.count != 1) {
2312 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2313 goto done;
2314 }
2315
2316 status = dcerpc_samr_OpenGroup(b, mem_ctx,
2317 &domain_pol,
2318 access_mask,
2319 group_rids.ids[0],
2320 &group_pol,
2321 &result);
2322 if (!NT_STATUS_IS_OK(status)) {
2323 goto done;
2324 }
2325 if (!NT_STATUS_IS_OK(result)) {
2326 status = result;
2327 goto done;
2328 }
2329 }
2330
2331 /* Delete group */
2332
2333 status = dcerpc_samr_DeleteDomainGroup(b, mem_ctx,
2334 &group_pol,
2335 &result);
2336 if (!NT_STATUS_IS_OK(status)) {
2337 goto done;
2338 }
2339 if (!NT_STATUS_IS_OK(result)) {
2340 status = result;
2341 goto done;
2342 }
2343
2344 /* Display results */
2345
2346 dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
2347 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2348 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2349
2350 done:
2351 return status;
2352}
2353
2354/* Delete domain user */
2355
2356static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
2357 TALLOC_CTX *mem_ctx,
2358 int argc, const char **argv)
2359{
2360 NTSTATUS status, result;
2361 struct policy_handle connect_pol, domain_pol, user_pol;
2362 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2363 struct dcerpc_binding_handle *b = cli->binding_handle;
2364
2365 if ((argc < 2) || (argc > 3)) {
2366 printf("Usage: %s username\n", argv[0]);
2367 return NT_STATUS_OK;
2368 }
2369
2370 if (argc > 2)
2371 sscanf(argv[2], "%x", &access_mask);
2372
2373 /* Get sam policy and domain handles */
2374
2375 status = rpccli_try_samr_connects(cli, mem_ctx,
2376 MAXIMUM_ALLOWED_ACCESS,
2377 &connect_pol);
2378 if (!NT_STATUS_IS_OK(status)) {
2379 goto done;
2380 }
2381
2382 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2383 &connect_pol,
2384 MAXIMUM_ALLOWED_ACCESS,
2385 &domain_sid,
2386 &domain_pol,
2387 &result);
2388 if (!NT_STATUS_IS_OK(status)) {
2389 goto done;
2390 }
2391 if (!NT_STATUS_IS_OK(result)) {
2392 status = result;
2393 goto done;
2394 }
2395
2396 /* Get handle on user */
2397
2398 {
2399 struct samr_Ids user_rids, name_types;
2400 struct lsa_String lsa_acct_name;
2401
2402 init_lsa_String(&lsa_acct_name, argv[1]);
2403
2404 status = dcerpc_samr_LookupNames(b, mem_ctx,
2405 &domain_pol,
2406 1,
2407 &lsa_acct_name,
2408 &user_rids,
2409 &name_types,
2410 &result);
2411 if (!NT_STATUS_IS_OK(status)) {
2412 goto done;
2413 }
2414 if (!NT_STATUS_IS_OK(result)) {
2415 status = result;
2416 goto done;
2417 }
2418 if (user_rids.count != 1) {
2419 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2420 goto done;
2421 }
2422 if (name_types.count != 1) {
2423 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2424 goto done;
2425 }
2426
2427 status = dcerpc_samr_OpenUser(b, mem_ctx,
2428 &domain_pol,
2429 access_mask,
2430 user_rids.ids[0],
2431 &user_pol,
2432 &result);
2433 if (!NT_STATUS_IS_OK(status)) {
2434 goto done;
2435 }
2436 if (!NT_STATUS_IS_OK(result)) {
2437 status = result;
2438 goto done;
2439 }
2440 }
2441
2442 /* Delete user */
2443
2444 status = dcerpc_samr_DeleteUser(b, mem_ctx,
2445 &user_pol,
2446 &result);
2447 if (!NT_STATUS_IS_OK(status)) {
2448 goto done;
2449 }
2450 if (!NT_STATUS_IS_OK(result)) {
2451 status = result;
2452 goto done;
2453 }
2454
2455 /* Display results */
2456
2457 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2458 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2459 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2460
2461 done:
2462 return status;
2463}
2464
2465/**********************************************************************
2466 * Query user security object
2467 */
2468static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
2469 TALLOC_CTX *mem_ctx,
2470 int argc, const char **argv)
2471{
2472 struct policy_handle connect_pol, domain_pol, user_pol, *pol;
2473 NTSTATUS status, result;
2474 uint32 sec_info = SECINFO_DACL;
2475 uint32 user_rid = 0;
2476 TALLOC_CTX *ctx = NULL;
2477 struct sec_desc_buf *sec_desc_buf=NULL;
2478 bool domain = False;
2479 struct dcerpc_binding_handle *b = cli->binding_handle;
2480
2481 ctx=talloc_init("cmd_samr_query_sec_obj");
2482
2483 if ((argc < 1) || (argc > 3)) {
2484 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2485 printf("\tSpecify rid for security on user, -d for security on domain\n");
2486 talloc_destroy(ctx);
2487 return NT_STATUS_OK;
2488 }
2489
2490 if (argc > 1) {
2491 if (strcmp(argv[1], "-d") == 0)
2492 domain = True;
2493 else
2494 sscanf(argv[1], "%i", &user_rid);
2495 }
2496
2497 if (argc == 3) {
2498 sec_info = atoi(argv[2]);
2499 }
2500
2501 status = rpccli_try_samr_connects(cli, mem_ctx,
2502 MAXIMUM_ALLOWED_ACCESS,
2503 &connect_pol);
2504 if (!NT_STATUS_IS_OK(status)) {
2505 goto done;
2506 }
2507
2508 if (domain || user_rid) {
2509 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2510 &connect_pol,
2511 MAXIMUM_ALLOWED_ACCESS,
2512 &domain_sid,
2513 &domain_pol,
2514 &result);
2515 if (!NT_STATUS_IS_OK(status)) {
2516 goto done;
2517 }
2518 if (!NT_STATUS_IS_OK(result)) {
2519 status = result;
2520 goto done;
2521 }
2522 }
2523
2524 if (user_rid) {
2525 status = dcerpc_samr_OpenUser(b, mem_ctx,
2526 &domain_pol,
2527 MAXIMUM_ALLOWED_ACCESS,
2528 user_rid,
2529 &user_pol,
2530 &result);
2531 if (!NT_STATUS_IS_OK(status)) {
2532 goto done;
2533 }
2534 if (!NT_STATUS_IS_OK(result)) {
2535 status = result;
2536 goto done;
2537 }
2538 }
2539
2540 /* Pick which query pol to use */
2541
2542 pol = &connect_pol;
2543
2544 if (domain)
2545 pol = &domain_pol;
2546
2547 if (user_rid)
2548 pol = &user_pol;
2549
2550 /* Query SAM security object */
2551
2552 status = dcerpc_samr_QuerySecurity(b, mem_ctx,
2553 pol,
2554 sec_info,
2555 &sec_desc_buf,
2556 &result);
2557 if (!NT_STATUS_IS_OK(status)) {
2558 goto done;
2559 }
2560 if (!NT_STATUS_IS_OK(result)) {
2561 status = result;
2562 goto done;
2563 }
2564
2565 display_sec_desc(sec_desc_buf->sd);
2566
2567 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2568 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2569 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2570done:
2571 talloc_destroy(ctx);
2572 return status;
2573}
2574
2575static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
2576 TALLOC_CTX *mem_ctx,
2577 int argc, const char **argv)
2578{
2579 NTSTATUS status, result;
2580 struct policy_handle connect_pol, domain_pol, user_pol;
2581 struct samr_PwInfo info;
2582 uint32_t rid;
2583 struct dcerpc_binding_handle *b = cli->binding_handle;
2584
2585 if (argc != 2) {
2586 printf("Usage: %s rid\n", argv[0]);
2587 return NT_STATUS_OK;
2588 }
2589
2590 sscanf(argv[1], "%i", &rid);
2591
2592 status = rpccli_try_samr_connects(cli, mem_ctx,
2593 MAXIMUM_ALLOWED_ACCESS,
2594 &connect_pol);
2595 if (!NT_STATUS_IS_OK(status)) {
2596 goto done;
2597 }
2598
2599 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2600 &connect_pol,
2601 MAXIMUM_ALLOWED_ACCESS,
2602 &domain_sid,
2603 &domain_pol,
2604 &result);
2605 if (!NT_STATUS_IS_OK(status)) {
2606 goto done;
2607 }
2608 if (!NT_STATUS_IS_OK(result)) {
2609 status = result;
2610 goto done;
2611 }
2612
2613 status = dcerpc_samr_OpenUser(b, mem_ctx,
2614 &domain_pol,
2615 MAXIMUM_ALLOWED_ACCESS,
2616 rid,
2617 &user_pol,
2618 &result);
2619 if (!NT_STATUS_IS_OK(status)) {
2620 goto done;
2621 }
2622 if (!NT_STATUS_IS_OK(result)) {
2623 status = result;
2624 goto done;
2625 }
2626
2627 status = dcerpc_samr_GetUserPwInfo(b, mem_ctx,
2628 &user_pol,
2629 &info,
2630 &result);
2631 if (!NT_STATUS_IS_OK(status)) {
2632 goto done;
2633 }
2634 status = result;
2635 if (NT_STATUS_IS_OK(result)) {
2636 printf("min_password_length: %d\n", info.min_password_length);
2637 printf("%s\n",
2638 NDR_PRINT_STRUCT_STRING(mem_ctx,
2639 samr_PasswordProperties, &info.password_properties));
2640 }
2641
2642 done:
2643 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2644 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2645 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2646
2647 return status;
2648}
2649
2650static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2651 TALLOC_CTX *mem_ctx,
2652 int argc, const char **argv)
2653{
2654 NTSTATUS status, result;
2655 struct lsa_String domain_name;
2656 struct samr_PwInfo info;
2657 struct dcerpc_binding_handle *b = cli->binding_handle;
2658
2659 if (argc < 1 || argc > 3) {
2660 printf("Usage: %s <domain>\n", argv[0]);
2661 return NT_STATUS_OK;
2662 }
2663
2664 init_lsa_String(&domain_name, argv[1]);
2665
2666 status = dcerpc_samr_GetDomPwInfo(b, mem_ctx,
2667 &domain_name,
2668 &info,
2669 &result);
2670 if (!NT_STATUS_IS_OK(status)) {
2671 return status;
2672 }
2673 if (NT_STATUS_IS_OK(result)) {
2674 printf("min_password_length: %d\n", info.min_password_length);
2675 display_password_properties(info.password_properties);
2676 }
2677
2678 return result;
2679}
2680
2681/* Look up domain name */
2682
2683static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
2684 TALLOC_CTX *mem_ctx,
2685 int argc, const char **argv)
2686{
2687 struct policy_handle connect_pol, domain_pol;
2688 NTSTATUS status, result;
2689 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2690 fstring sid_string;
2691 struct lsa_String domain_name;
2692 struct dom_sid *sid = NULL;
2693 struct dcerpc_binding_handle *b = cli->binding_handle;
2694
2695 if (argc != 2) {
2696 printf("Usage: %s domain_name\n", argv[0]);
2697 return NT_STATUS_OK;
2698 }
2699
2700 init_lsa_String(&domain_name, argv[1]);
2701
2702 status = rpccli_try_samr_connects(cli, mem_ctx,
2703 access_mask,
2704 &connect_pol);
2705 if (!NT_STATUS_IS_OK(status)) {
2706 goto done;
2707 }
2708
2709 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2710 &connect_pol,
2711 access_mask,
2712 &domain_sid,
2713 &domain_pol,
2714 &result);
2715 if (!NT_STATUS_IS_OK(status)) {
2716 goto done;
2717 }
2718 if (!NT_STATUS_IS_OK(result)) {
2719 status = result;
2720 goto done;
2721 }
2722
2723 status = dcerpc_samr_LookupDomain(b, mem_ctx,
2724 &connect_pol,
2725 &domain_name,
2726 &sid,
2727 &result);
2728 if (!NT_STATUS_IS_OK(status)) {
2729 goto done;
2730 }
2731 if (!NT_STATUS_IS_OK(result)) {
2732 status = result;
2733 goto done;
2734 }
2735
2736 if (NT_STATUS_IS_OK(result)) {
2737 sid_to_fstring(sid_string, sid);
2738 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2739 argv[1], sid_string);
2740 }
2741
2742 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2743 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2744done:
2745 return status;
2746}
2747
2748/* Change user password */
2749
2750static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli,
2751 TALLOC_CTX *mem_ctx,
2752 int argc, const char **argv)
2753{
2754 struct policy_handle connect_pol, domain_pol, user_pol;
2755 NTSTATUS status, result;
2756 const char *user, *oldpass, *newpass;
2757 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2758 struct samr_Ids rids, types;
2759 struct lsa_String lsa_acct_name;
2760 struct dcerpc_binding_handle *b = cli->binding_handle;
2761
2762 if (argc < 3) {
2763 printf("Usage: %s username oldpass newpass\n", argv[0]);
2764 return NT_STATUS_INVALID_PARAMETER;
2765 }
2766
2767 user = argv[1];
2768 oldpass = argv[2];
2769 newpass = argv[3];
2770
2771 /* Get sam policy handle */
2772
2773 status = rpccli_try_samr_connects(cli, mem_ctx,
2774 MAXIMUM_ALLOWED_ACCESS,
2775 &connect_pol);
2776 if (!NT_STATUS_IS_OK(status)) {
2777 goto done;
2778 }
2779
2780 /* Get domain policy handle */
2781
2782 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2783 &connect_pol,
2784 access_mask,
2785 &domain_sid,
2786 &domain_pol,
2787 &result);
2788 if (!NT_STATUS_IS_OK(status)) {
2789 goto done;
2790 }
2791 if (!NT_STATUS_IS_OK(result)) {
2792 status = result;
2793 goto done;
2794 }
2795
2796 init_lsa_String(&lsa_acct_name, user);
2797
2798 status = dcerpc_samr_LookupNames(b, mem_ctx,
2799 &domain_pol,
2800 1,
2801 &lsa_acct_name,
2802 &rids,
2803 &types,
2804 &result);
2805 if (!NT_STATUS_IS_OK(status)) {
2806 goto done;
2807 }
2808 if (!NT_STATUS_IS_OK(result)) {
2809 status = result;
2810 goto done;
2811 }
2812 if (rids.count != 1) {
2813 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2814 goto done;
2815 }
2816 if (types.count != 1) {
2817 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2818 goto done;
2819 }
2820
2821 status = dcerpc_samr_OpenUser(b, mem_ctx,
2822 &domain_pol,
2823 access_mask,
2824 rids.ids[0],
2825 &user_pol,
2826 &result);
2827 if (!NT_STATUS_IS_OK(status)) {
2828 goto done;
2829 }
2830 if (!NT_STATUS_IS_OK(result)) {
2831 status = result;
2832 goto done;
2833 }
2834
2835 /* Change user password */
2836 status = rpccli_samr_chgpasswd_user(cli, mem_ctx,
2837 &user_pol,
2838 newpass,
2839 oldpass);
2840 if (!NT_STATUS_IS_OK(status)) {
2841 goto done;
2842 }
2843
2844 done:
2845 if (is_valid_policy_hnd(&user_pol)) {
2846 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2847 }
2848 if (is_valid_policy_hnd(&domain_pol)) {
2849 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2850 }
2851 if (is_valid_policy_hnd(&connect_pol)) {
2852 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2853 }
2854
2855 return status;
2856}
2857
2858
2859/* Change user password */
2860
2861static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2862 TALLOC_CTX *mem_ctx,
2863 int argc, const char **argv)
2864{
2865 struct policy_handle connect_pol, domain_pol;
2866 NTSTATUS status, result;
2867 const char *user, *oldpass, *newpass;
2868 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2869 struct dcerpc_binding_handle *b = cli->binding_handle;
2870
2871 if (argc < 3) {
2872 printf("Usage: %s username oldpass newpass\n", argv[0]);
2873 return NT_STATUS_INVALID_PARAMETER;
2874 }
2875
2876 user = argv[1];
2877 oldpass = argv[2];
2878 newpass = argv[3];
2879
2880 /* Get sam policy handle */
2881
2882 status = rpccli_try_samr_connects(cli, mem_ctx,
2883 MAXIMUM_ALLOWED_ACCESS,
2884 &connect_pol);
2885 if (!NT_STATUS_IS_OK(status)) {
2886 goto done;
2887 }
2888
2889 /* Get domain policy handle */
2890
2891 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2892 &connect_pol,
2893 access_mask,
2894 &domain_sid,
2895 &domain_pol,
2896 &result);
2897 if (!NT_STATUS_IS_OK(status)) {
2898 goto done;
2899 }
2900 if (!NT_STATUS_IS_OK(result)) {
2901 status = result;
2902 goto done;
2903 }
2904
2905 /* Change user password */
2906 status = rpccli_samr_chgpasswd_user2(cli, mem_ctx, user, newpass, oldpass);
2907
2908 if (!NT_STATUS_IS_OK(status)) {
2909 goto done;
2910 }
2911
2912 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2913 if (!NT_STATUS_IS_OK(status)) goto done;
2914
2915 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2916 if (!NT_STATUS_IS_OK(status)) goto done;
2917
2918 done:
2919 return status;
2920}
2921
2922
2923/* Change user password */
2924
2925static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
2926 TALLOC_CTX *mem_ctx,
2927 int argc, const char **argv)
2928{
2929 struct policy_handle connect_pol, domain_pol;
2930 NTSTATUS status, result;
2931 const char *user, *oldpass, *newpass;
2932 uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2933 struct samr_DomInfo1 *info = NULL;
2934 struct userPwdChangeFailureInformation *reject = NULL;
2935 struct dcerpc_binding_handle *b = cli->binding_handle;
2936
2937 if (argc < 3) {
2938 printf("Usage: %s username oldpass newpass\n", argv[0]);
2939 return NT_STATUS_INVALID_PARAMETER;
2940 }
2941
2942 user = argv[1];
2943 oldpass = argv[2];
2944 newpass = argv[3];
2945
2946 /* Get sam policy handle */
2947
2948 status = rpccli_try_samr_connects(cli, mem_ctx,
2949 MAXIMUM_ALLOWED_ACCESS,
2950 &connect_pol);
2951 if (!NT_STATUS_IS_OK(status)) {
2952 goto done;
2953 }
2954
2955 /* Get domain policy handle */
2956
2957 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2958 &connect_pol,
2959 access_mask,
2960 &domain_sid,
2961 &domain_pol,
2962 &result);
2963 if (!NT_STATUS_IS_OK(status)) {
2964 goto done;
2965 }
2966 if (!NT_STATUS_IS_OK(result)) {
2967 status = result;
2968 goto done;
2969 }
2970
2971 /* Change user password */
2972 status = rpccli_samr_chgpasswd_user3(cli, mem_ctx,
2973 user,
2974 newpass,
2975 oldpass,
2976 &info,
2977 &reject);
2978 if (!NT_STATUS_IS_OK(status)) {
2979 goto done;
2980 }
2981
2982 if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2983
2984 display_sam_dom_info_1(info);
2985
2986 switch (reject->extendedFailureReason) {
2987 case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT:
2988 d_printf("SAM_PWD_CHANGE_PASSWORD_TOO_SHORT\n");
2989 break;
2990 case SAM_PWD_CHANGE_PWD_IN_HISTORY:
2991 d_printf("SAM_PWD_CHANGE_PWD_IN_HISTORY\n");
2992 break;
2993 case SAM_PWD_CHANGE_NOT_COMPLEX:
2994 d_printf("SAM_PWD_CHANGE_NOT_COMPLEX\n");
2995 break;
2996 default:
2997 d_printf("unknown reject reason: %d\n",
2998 reject->extendedFailureReason);
2999 break;
3000 }
3001 }
3002
3003 if (!NT_STATUS_IS_OK(result)) {
3004 status = result;
3005 goto done;
3006 }
3007
3008 status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
3009 if (!NT_STATUS_IS_OK(status)) goto done;
3010
3011 status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
3012 if (!NT_STATUS_IS_OK(status)) goto done;
3013
3014 done:
3015 return status;
3016}
3017
3018static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli,
3019 TALLOC_CTX *mem_ctx,
3020 int argc, const char **argv,
3021 int opcode)
3022{
3023 struct policy_handle connect_pol, domain_pol, user_pol;
3024 NTSTATUS status, result;
3025 const char *user, *param;
3026 uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
3027 uint32_t level;
3028 uint32_t user_rid;
3029 union samr_UserInfo info;
3030 struct samr_CryptPassword pwd_buf;
3031 struct samr_CryptPasswordEx pwd_buf_ex;
3032 uint8_t nt_hash[16];
3033 uint8_t lm_hash[16];
3034 DATA_BLOB session_key;
3035 uint8_t password_expired = 0;
3036 struct dcerpc_binding_handle *b = cli->binding_handle;
3037
3038 if (argc < 4) {
3039 printf("Usage: %s username level password [password_expired]\n",
3040 argv[0]);
3041 return NT_STATUS_INVALID_PARAMETER;
3042 }
3043
3044 user = argv[1];
3045 level = atoi(argv[2]);
3046 param = argv[3];
3047
3048 if (argc >= 5) {
3049 password_expired = atoi(argv[4]);
3050 }
3051
3052 status = cli_get_session_key(mem_ctx, cli, &session_key);
3053 if (!NT_STATUS_IS_OK(status)) {
3054 return status;
3055 }
3056
3057 init_samr_CryptPassword(param, &session_key, &pwd_buf);
3058 init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex);
3059 nt_lm_owf_gen(param, nt_hash, lm_hash);
3060
3061 switch (level) {
3062 case 18:
3063 {
3064 DATA_BLOB in,out;
3065 in = data_blob_const(nt_hash, 16);
3066 out = data_blob_talloc_zero(mem_ctx, 16);
3067 sess_crypt_blob(&out, &in, &session_key, true);
3068 memcpy(nt_hash, out.data, out.length);
3069 }
3070 {
3071 DATA_BLOB in,out;
3072 in = data_blob_const(lm_hash, 16);
3073 out = data_blob_talloc_zero(mem_ctx, 16);
3074 sess_crypt_blob(&out, &in, &session_key, true);
3075 memcpy(lm_hash, out.data, out.length);
3076 }
3077
3078 memcpy(info.info18.nt_pwd.hash, nt_hash, 16);
3079 memcpy(info.info18.lm_pwd.hash, lm_hash, 16);
3080 info.info18.nt_pwd_active = true;
3081 info.info18.lm_pwd_active = true;
3082 info.info18.password_expired = password_expired;
3083
3084 break;
3085 case 21:
3086 ZERO_STRUCT(info.info21);
3087
3088 info.info21.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3089 SAMR_FIELD_LM_PASSWORD_PRESENT;
3090 if (argc >= 5) {
3091 info.info21.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3092 info.info21.password_expired = password_expired;
3093 }
3094
3095 info.info21.lm_password_set = true;
3096 info.info21.lm_owf_password.length = 16;
3097 info.info21.lm_owf_password.size = 16;
3098
3099 info.info21.nt_password_set = true;
3100 info.info21.nt_owf_password.length = 16;
3101 info.info21.nt_owf_password.size = 16;
3102
3103 {
3104 DATA_BLOB in,out;
3105 in = data_blob_const(nt_hash, 16);
3106 out = data_blob_talloc_zero(mem_ctx, 16);
3107 sess_crypt_blob(&out, &in, &session_key, true);
3108 info.info21.nt_owf_password.array =
3109 (uint16_t *)talloc_memdup(mem_ctx, out.data, 16);
3110 }
3111 {
3112 DATA_BLOB in,out;
3113 in = data_blob_const(lm_hash, 16);
3114 out = data_blob_talloc_zero(mem_ctx, 16);
3115 sess_crypt_blob(&out, &in, &session_key, true);
3116 info.info21.lm_owf_password.array =
3117 (uint16_t *)talloc_memdup(mem_ctx, out.data, 16);
3118 }
3119
3120 break;
3121 case 23:
3122 ZERO_STRUCT(info.info23);
3123
3124 info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3125 SAMR_FIELD_LM_PASSWORD_PRESENT;
3126 if (argc >= 5) {
3127 info.info23.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3128 info.info23.info.password_expired = password_expired;
3129 }
3130
3131 info.info23.password = pwd_buf;
3132
3133 break;
3134 case 24:
3135 info.info24.password = pwd_buf;
3136 info.info24.password_expired = password_expired;
3137
3138 break;
3139 case 25:
3140 ZERO_STRUCT(info.info25);
3141
3142 info.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3143 SAMR_FIELD_LM_PASSWORD_PRESENT;
3144 if (argc >= 5) {
3145 info.info25.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3146 info.info25.info.password_expired = password_expired;
3147 }
3148
3149 info.info25.password = pwd_buf_ex;
3150
3151 break;
3152 case 26:
3153 info.info26.password = pwd_buf_ex;
3154 info.info26.password_expired = password_expired;
3155
3156 break;
3157 default:
3158 return NT_STATUS_INVALID_INFO_CLASS;
3159 }
3160
3161 /* Get sam policy handle */
3162
3163 status = rpccli_try_samr_connects(cli, mem_ctx,
3164 MAXIMUM_ALLOWED_ACCESS,
3165 &connect_pol);
3166 if (!NT_STATUS_IS_OK(status)) {
3167 goto done;
3168 }
3169
3170 /* Get domain policy handle */
3171
3172 status = dcerpc_samr_OpenDomain(b, mem_ctx,
3173 &connect_pol,
3174 access_mask,
3175 &domain_sid,
3176 &domain_pol,
3177 &result);
3178
3179 if (!NT_STATUS_IS_OK(status))
3180 goto done;
3181 if (!NT_STATUS_IS_OK(result)) {
3182 status = result;
3183 goto done;
3184 }
3185
3186 user_rid = strtol(user, NULL, 0);
3187 if (user_rid) {
3188 status = dcerpc_samr_OpenUser(b, mem_ctx,
3189 &domain_pol,
3190 access_mask,
3191 user_rid,
3192 &user_pol,
3193 &result);
3194 if (!NT_STATUS_IS_OK(status)) {
3195 goto done;
3196 }
3197
3198 status = result;
3199 }
3200
3201 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) ||
3202 (user_rid == 0)) {
3203
3204 /* Probably this was a user name, try lookupnames */
3205 struct samr_Ids rids, types;
3206 struct lsa_String lsa_acct_name;
3207
3208 init_lsa_String(&lsa_acct_name, user);
3209
3210 status = dcerpc_samr_LookupNames(b, mem_ctx,
3211 &domain_pol,
3212 1,
3213 &lsa_acct_name,
3214 &rids,
3215 &types,
3216 &result);
3217 if (!NT_STATUS_IS_OK(status)) {
3218 return status;
3219 }
3220 if (!NT_STATUS_IS_OK(result)) {
3221 return result;
3222 }
3223 if (rids.count != 1) {
3224 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3225 }
3226 if (types.count != 1) {
3227 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3228 }
3229
3230 status = dcerpc_samr_OpenUser(b, mem_ctx,
3231 &domain_pol,
3232 access_mask,
3233 rids.ids[0],
3234 &user_pol,
3235 &result);
3236 if (!NT_STATUS_IS_OK(status)) {
3237 return status;
3238 }
3239 if (!NT_STATUS_IS_OK(result)) {
3240 return result;
3241 }
3242 }
3243
3244 switch (opcode) {
3245 case NDR_SAMR_SETUSERINFO:
3246 status = dcerpc_samr_SetUserInfo(b, mem_ctx,
3247 &user_pol,
3248 level,
3249 &info,
3250 &result);
3251 break;
3252 case NDR_SAMR_SETUSERINFO2:
3253 status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
3254 &user_pol,
3255 level,
3256 &info,
3257 &result);
3258 break;
3259 default:
3260 return NT_STATUS_INVALID_PARAMETER;
3261 }
3262 if (!NT_STATUS_IS_OK(status)) {
3263 DEBUG(0,("status: %s\n", nt_errstr(status)));
3264 goto done;
3265 }
3266 if (!NT_STATUS_IS_OK(result)) {
3267 status = result;
3268 DEBUG(0,("result: %s\n", nt_errstr(status)));
3269 goto done;
3270 }
3271 done:
3272 return status;
3273}
3274
3275static NTSTATUS cmd_samr_setuserinfo(struct rpc_pipe_client *cli,
3276 TALLOC_CTX *mem_ctx,
3277 int argc, const char **argv)
3278{
3279 return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
3280 NDR_SAMR_SETUSERINFO);
3281}
3282
3283static NTSTATUS cmd_samr_setuserinfo2(struct rpc_pipe_client *cli,
3284 TALLOC_CTX *mem_ctx,
3285 int argc, const char **argv)
3286{
3287 return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
3288 NDR_SAMR_SETUSERINFO2);
3289}
3290
3291static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
3292 TALLOC_CTX *mem_ctx,
3293 int argc, const char **argv)
3294{
3295 NTSTATUS status, result;
3296 struct policy_handle connect_handle;
3297 struct policy_handle domain_handle;
3298 uint16_t level = 1;
3299 struct lsa_String name;
3300 uint32_t idx = 0;
3301 struct dcerpc_binding_handle *b = cli->binding_handle;
3302
3303 if (argc < 2 || argc > 3) {
3304 printf("Usage: %s name level\n", argv[0]);
3305 return NT_STATUS_INVALID_PARAMETER;
3306 }
3307
3308 init_lsa_String(&name, argv[1]);
3309
3310 if (argc == 3) {
3311 level = atoi(argv[2]);
3312 }
3313
3314 status = rpccli_try_samr_connects(cli, mem_ctx,
3315 SEC_FLAG_MAXIMUM_ALLOWED,
3316 &connect_handle);
3317 if (!NT_STATUS_IS_OK(status)) {
3318 goto done;
3319 }
3320
3321 status = dcerpc_samr_OpenDomain(b, mem_ctx,
3322 &connect_handle,
3323 SEC_FLAG_MAXIMUM_ALLOWED,
3324 &domain_sid,
3325 &domain_handle,
3326 &result);
3327 if (!NT_STATUS_IS_OK(status)) {
3328 goto done;
3329 }
3330 if (!NT_STATUS_IS_OK(result)) {
3331 status = result;
3332 goto done;
3333 }
3334
3335 status = dcerpc_samr_GetDisplayEnumerationIndex(b, mem_ctx,
3336 &domain_handle,
3337 level,
3338 &name,
3339 &idx,
3340 &result);
3341 if (!NT_STATUS_IS_OK(status)) {
3342 goto done;
3343 }
3344
3345 status = result;
3346
3347 if (NT_STATUS_IS_OK(status) ||
3348 NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
3349 printf("idx: %d (0x%08x)\n", idx, idx);
3350 }
3351 done:
3352
3353 if (is_valid_policy_hnd(&domain_handle)) {
3354 dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
3355 }
3356 if (is_valid_policy_hnd(&connect_handle)) {
3357 dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
3358 }
3359
3360 return status;
3361
3362}
3363/* List of commands exported by this module */
3364
3365struct cmd_set samr_commands[] = {
3366
3367 { "SAMR" },
3368
3369 { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, &ndr_table_samr.syntax_id, NULL, "Query user info", "" },
3370 { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, &ndr_table_samr.syntax_id, NULL, "Query group info", "" },
3371 { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, &ndr_table_samr.syntax_id, NULL, "Query user groups", "" },
3372 { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, &ndr_table_samr.syntax_id, NULL, "Query user aliases", "" },
3373 { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, &ndr_table_samr.syntax_id, NULL, "Query group membership", "" },
3374 { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, &ndr_table_samr.syntax_id, NULL, "Query alias membership", "" },
3375 { "queryaliasinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query alias info", "" },
3376 { "deletealias", RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias, NULL, &ndr_table_samr.syntax_id, NULL, "Delete an alias", "" },
3377 { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
3378 { "querydispinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo2, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
3379 { "querydispinfo3", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo3, NULL, &ndr_table_samr.syntax_id, NULL, "Query display info", "" },
3380 { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, &ndr_table_samr.syntax_id, NULL, "Query domain info", "" },
3381 { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domain users", "" },
3382 { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domain groups", "" },
3383 { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate alias groups", "" },
3384 { "enumdomains", RPC_RTYPE_NTSTATUS, cmd_samr_enum_domains, NULL, &ndr_table_samr.syntax_id, NULL, "Enumerate domains", "" },
3385
3386 { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain user", "" },
3387 { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain group", "" },
3388 { "createdomalias", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias, NULL, &ndr_table_samr.syntax_id, NULL, "Create domain alias", "" },
3389 { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, &ndr_table_samr.syntax_id, NULL, "Look up names", "" },
3390 { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, &ndr_table_samr.syntax_id, NULL, "Look up names", "" },
3391 { "deletedomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group, NULL, &ndr_table_samr.syntax_id, NULL, "Delete domain group", "" },
3392 { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, &ndr_table_samr.syntax_id, NULL, "Delete domain user", "" },
3393 { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, &ndr_table_samr.syntax_id, NULL, "Query SAMR security object", "" },
3394 { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Retrieve domain password info", "" },
3395 { "getusrdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Retrieve user domain password info", "" },
3396
3397 { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, &ndr_table_samr.syntax_id, NULL, "Lookup Domain Name", "" },
3398 { "chgpasswd", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
3399 { "chgpasswd2", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
3400 { "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
3401 { "getdispinfoidx", RPC_RTYPE_NTSTATUS, cmd_samr_get_dispinfo_idx, NULL, &ndr_table_samr.syntax_id, NULL, "Get Display Information Index", "" },
3402 { "setuserinfo", RPC_RTYPE_NTSTATUS, cmd_samr_setuserinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Set user info", "" },
3403 { "setuserinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_setuserinfo2, NULL, &ndr_table_samr.syntax_id, NULL, "Set user info2", "" },
3404 { NULL }
3405};
Note: See TracBrowser for help on using the repository browser.