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 
35 static struct dom_sid domain_sid;
36 
37 /****************************************************************************
38  display samr_user_info_7 structure
39  ****************************************************************************/
display_samr_user_info_7(struct samr_UserInfo7 * r)40 static 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  ****************************************************************************/
display_samr_user_info_9(struct samr_UserInfo9 * r)48 static 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  ****************************************************************************/
display_samr_user_info_16(struct samr_UserInfo16 * r)56 static 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  ****************************************************************************/
display_samr_user_info_20(struct samr_UserInfo20 * r)64 static 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  ****************************************************************************/
display_samr_user_info_21(struct samr_UserInfo21 * r)74 static 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 
display_password_properties(uint32_t password_properties)120 static 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 
display_sam_dom_info_1(struct samr_DomInfo1 * info1)143 static 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 
display_sam_dom_info_2(struct samr_DomGeneralInformation * general)156 static 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 
display_sam_dom_info_3(struct samr_DomInfo3 * info3)176 static 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 
display_sam_dom_info_4(struct samr_DomOEMInformation * oem)182 static void display_sam_dom_info_4(struct samr_DomOEMInformation *oem)
183 {
184 	printf("Comment:\t%s\n", oem->oem_information.string);
185 }
186 
display_sam_dom_info_5(struct samr_DomInfo5 * info5)187 static void display_sam_dom_info_5(struct samr_DomInfo5 *info5)
188 {
189 	printf("Domain:\t\t%s\n", info5->domain_name.string);
190 }
191 
display_sam_dom_info_6(struct samr_DomInfo6 * info6)192 static void display_sam_dom_info_6(struct samr_DomInfo6 *info6)
193 {
194 	printf("Server:\t\t%s\n", info6->primary.string);
195 }
196 
display_sam_dom_info_7(struct samr_DomInfo7 * info7)197 static 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 
display_sam_dom_info_8(struct samr_DomInfo8 * info8)202 static 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 
display_sam_dom_info_9(struct samr_DomInfo9 * info9)209 static 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 
display_sam_dom_info_12(struct samr_DomInfo12 * info12)214 static 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 
display_sam_dom_info_13(struct samr_DomInfo13 * info13)224 static 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 
display_sam_info_1(struct samr_DispEntryGeneral * r)233 static 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 
display_sam_info_2(struct samr_DispEntryFull * r)243 static 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 
display_sam_info_3(struct samr_DispEntryFullGroup * r)252 static 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 
display_sam_info_4(struct samr_DispEntryAscii * r)261 static 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 
display_sam_info_5(struct samr_DispEntryAscii * r)267 static 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 
rpccli_try_samr_connects(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,uint32_t access_mask,struct policy_handle * connect_pol)273 static NTSTATUS rpccli_try_samr_connects(
274 	struct rpc_pipe_client *cli,
275 	TALLOC_CTX *mem_ctx,
276 	uint32_t access_mask,
277 	struct policy_handle *connect_pol)
278 {
279 	struct dcerpc_binding_handle *b = cli->binding_handle;
280 	NTSTATUS status;
281 	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
282 	uint32_t start_idx = 0;
283 	uint32_t i, num_entries;
284 	struct samr_SamArray *sam = NULL;
285 	struct dom_sid *domsid = NULL;
286 
287 	status = dcerpc_try_samr_connects(
288 		b,
289 		mem_ctx,
290 		cli->srv_name_slash,
291 		access_mask,
292 		connect_pol,
293 		&result);
294 	if (!NT_STATUS_IS_OK(status)) {
295 		return status;
296 	}
297 	if (!NT_STATUS_IS_OK(result)) {
298 		return result;
299 	}
300 
301 	if (!is_null_sid(&domain_sid)) {
302 		return NT_STATUS_OK;
303 	}
304 
305 	/*
306 	 * Look up the servers domain SID. Just pick the first
307 	 * non-builtin domain from samr_EnumDomains.
308 	 */
309 
310 	status = dcerpc_samr_EnumDomains(
311 		b,
312 		mem_ctx,
313 		connect_pol,
314 		&start_idx,
315 		&sam,
316 		0xffff,
317 		&num_entries,
318 		&result);
319 	if (!NT_STATUS_IS_OK(status)) {
320 		goto fail;
321 	}
322 	if (!NT_STATUS_IS_OK(result)) {
323 		status = result;
324 		goto fail;
325 	}
326 
327 	for (i=0; i<num_entries; i++) {
328 		if (!strequal(sam->entries[i].name.string, "builtin")) {
329 			break;
330 		}
331 	}
332 	if (i == num_entries) {
333 		status = NT_STATUS_NOT_FOUND;
334 		goto fail;
335 	}
336 
337 	status = dcerpc_samr_LookupDomain(
338 		b,
339 		mem_ctx,
340 		connect_pol,
341 		&sam->entries[i].name,
342 		&domsid,
343 		&result);
344 	if (!NT_STATUS_IS_OK(status)) {
345 		goto fail;
346 	}
347 	if (!NT_STATUS_IS_OK(result)) {
348 		status = result;
349 		goto fail;
350 	}
351 
352 	sid_copy(&domain_sid, domsid);
353 	TALLOC_FREE(domsid);
354 
355 	return NT_STATUS_OK;
356 
357 fail:
358 	dcerpc_samr_Close(b, mem_ctx, connect_pol, &result);
359 	return status;
360 }
361 
362 /****************************************************************************
363  ****************************************************************************/
364 
get_domain_handle(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,const char * sam,struct policy_handle * connect_pol,uint32_t access_mask,struct dom_sid * _domain_sid,struct policy_handle * domain_pol)365 static NTSTATUS get_domain_handle(struct rpc_pipe_client *cli,
366 				  TALLOC_CTX *mem_ctx,
367 				  const char *sam,
368 				  struct policy_handle *connect_pol,
369 				  uint32_t access_mask,
370 				  struct dom_sid *_domain_sid,
371 				  struct policy_handle *domain_pol)
372 {
373 	struct dcerpc_binding_handle *b = cli->binding_handle;
374 	NTSTATUS status = NT_STATUS_INVALID_PARAMETER, result;
375 
376 	if (strcasecmp_m(sam, "domain") == 0) {
377 		status = dcerpc_samr_OpenDomain(b, mem_ctx,
378 					      connect_pol,
379 					      access_mask,
380 					      _domain_sid,
381 					      domain_pol,
382 					      &result);
383 	} else if (strcasecmp_m(sam, "builtin") == 0) {
384 		status = dcerpc_samr_OpenDomain(b, mem_ctx,
385 					      connect_pol,
386 					      access_mask,
387 					      discard_const_p(struct dom_sid2, &global_sid_Builtin),
388 					      domain_pol,
389 					      &result);
390 	}
391 
392 	if (!NT_STATUS_IS_OK(status)) {
393 		return status;
394 	}
395 
396 	return result;
397 }
398 
399 /**********************************************************************
400  * Query user information
401  */
cmd_samr_query_user(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)402 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
403                                     TALLOC_CTX *mem_ctx,
404                                     int argc, const char **argv)
405 {
406 	struct policy_handle connect_pol, domain_pol, user_pol;
407 	NTSTATUS status, result;
408 	uint32_t info_level = 21;
409 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
410 	union samr_UserInfo *info = NULL;
411 	uint32_t user_rid = 0;
412 	struct dcerpc_binding_handle *b = cli->binding_handle;
413 
414 	if ((argc < 2) || (argc > 4)) {
415 		printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
416 		return NT_STATUS_OK;
417 	}
418 
419 	sscanf(argv[1], "%i", &user_rid);
420 
421 	if (argc > 2)
422 		sscanf(argv[2], "%i", &info_level);
423 
424 	if (argc > 3)
425 		sscanf(argv[3], "%x", &access_mask);
426 
427 
428 	status = rpccli_try_samr_connects(cli, mem_ctx,
429 					  MAXIMUM_ALLOWED_ACCESS,
430 					  &connect_pol);
431 	if (!NT_STATUS_IS_OK(status)) {
432 		goto done;
433 	}
434 
435 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
436 					&connect_pol,
437 					MAXIMUM_ALLOWED_ACCESS,
438 					&domain_sid,
439 					&domain_pol,
440 					&result);
441 	if (!NT_STATUS_IS_OK(status)) {
442 		goto done;
443 	}
444 	if (!NT_STATUS_IS_OK(result)) {
445 		status = result;
446 		goto done;
447 	}
448 
449 	status = dcerpc_samr_OpenUser(b, mem_ctx,
450 				      &domain_pol,
451 				      access_mask,
452 				      user_rid,
453 				      &user_pol,
454 				      &result);
455 	if (!NT_STATUS_IS_OK(status)) {
456 		goto done;
457 	}
458 	if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
459 	    (user_rid == 0)) {
460 
461 		/* Probably this was a user name, try lookupnames */
462 		struct samr_Ids rids, types;
463 		struct lsa_String lsa_acct_name;
464 
465 		init_lsa_String(&lsa_acct_name, argv[1]);
466 
467 		status = dcerpc_samr_LookupNames(b, mem_ctx,
468 						 &domain_pol,
469 						 1,
470 						 &lsa_acct_name,
471 						 &rids,
472 						 &types,
473 						 &result);
474 		if (!NT_STATUS_IS_OK(status)) {
475 			goto done;
476 		}
477 
478 		if (NT_STATUS_IS_OK(result)) {
479 			if (rids.count != 1) {
480 				status = NT_STATUS_INVALID_NETWORK_RESPONSE;
481 				goto done;
482 			}
483 			if (types.count != 1) {
484 				status = NT_STATUS_INVALID_NETWORK_RESPONSE;
485 				goto done;
486 			}
487 
488 			status = dcerpc_samr_OpenUser(b, mem_ctx,
489 						      &domain_pol,
490 						      access_mask,
491 						      rids.ids[0],
492 						      &user_pol,
493 						      &result);
494 			if (!NT_STATUS_IS_OK(status)) {
495 				goto done;
496 			}
497 		}
498 	}
499 
500 
501 	if (!NT_STATUS_IS_OK(result)) {
502 		status = result;
503 		goto done;
504 	}
505 
506 	status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
507 					   &user_pol,
508 					   info_level,
509 					   &info,
510 					   &result);
511 	if (!NT_STATUS_IS_OK(status)) {
512 		goto done;
513 	}
514 	if (!NT_STATUS_IS_OK(result)) {
515 		status = result;
516 		goto done;
517 	}
518 
519 	switch (info_level) {
520 	case 7:
521 		display_samr_user_info_7(&info->info7);
522 		break;
523 	case 9:
524 		display_samr_user_info_9(&info->info9);
525 		break;
526 	case 16:
527 		display_samr_user_info_16(&info->info16);
528 		break;
529 	case 20:
530 		display_samr_user_info_20(&info->info20);
531 		break;
532 	case 21:
533 		display_samr_user_info_21(&info->info21);
534 		break;
535 	default:
536 		printf("Unsupported infolevel: %d\n", info_level);
537 		break;
538 	}
539 
540 	dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
541 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
542 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
543 
544 done:
545 	return status;
546 }
547 
548 /****************************************************************************
549  display group info
550  ****************************************************************************/
display_group_info1(struct samr_GroupInfoAll * info1)551 static void display_group_info1(struct samr_GroupInfoAll *info1)
552 {
553 	printf("\tGroup Name:\t%s\n", info1->name.string);
554 	printf("\tDescription:\t%s\n", info1->description.string);
555 	printf("\tGroup Attribute:%d\n", info1->attributes);
556 	printf("\tNum Members:%d\n", info1->num_members);
557 }
558 
559 /****************************************************************************
560  display group info
561  ****************************************************************************/
display_group_info2(struct lsa_String * info2)562 static void display_group_info2(struct lsa_String *info2)
563 {
564 	printf("\tGroup Description:%s\n", info2->string);
565 }
566 
567 
568 /****************************************************************************
569  display group info
570  ****************************************************************************/
display_group_info3(struct samr_GroupInfoAttributes * info3)571 static void display_group_info3(struct samr_GroupInfoAttributes *info3)
572 {
573 	printf("\tGroup Attribute:%d\n", info3->attributes);
574 }
575 
576 
577 /****************************************************************************
578  display group info
579  ****************************************************************************/
display_group_info4(struct lsa_String * info4)580 static void display_group_info4(struct lsa_String *info4)
581 {
582 	printf("\tGroup Description:%s\n", info4->string);
583 }
584 
585 /****************************************************************************
586  display group info
587  ****************************************************************************/
display_group_info5(struct samr_GroupInfoAll * info5)588 static void display_group_info5(struct samr_GroupInfoAll *info5)
589 {
590 	printf("\tGroup Name:\t%s\n", info5->name.string);
591 	printf("\tDescription:\t%s\n", info5->description.string);
592 	printf("\tGroup Attribute:%d\n", info5->attributes);
593 	printf("\tNum Members:%d\n", info5->num_members);
594 }
595 
596 /****************************************************************************
597  display sam sync structure
598  ****************************************************************************/
display_group_info(union samr_GroupInfo * info,enum samr_GroupInfoEnum level)599 static void display_group_info(union samr_GroupInfo *info,
600 			       enum samr_GroupInfoEnum level)
601 {
602 	switch (level) {
603 		case 1:
604 			display_group_info1(&info->all);
605 			break;
606 		case 2:
607 			display_group_info2(&info->name);
608 			break;
609 		case 3:
610 			display_group_info3(&info->attributes);
611 			break;
612 		case 4:
613 			display_group_info4(&info->description);
614 			break;
615 		case 5:
616 			display_group_info5(&info->all2);
617 			break;
618 	}
619 }
620 
621 /***********************************************************************
622  * Query group information
623  */
cmd_samr_query_group(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)624 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
625                                      TALLOC_CTX *mem_ctx,
626                                      int argc, const char **argv)
627 {
628 	struct policy_handle connect_pol, domain_pol, group_pol;
629 	NTSTATUS status, result;
630 	enum samr_GroupInfoEnum info_level = GROUPINFOALL;
631 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
632 	union samr_GroupInfo *group_info = NULL;
633 	uint32_t group_rid;
634 	struct dcerpc_binding_handle *b = cli->binding_handle;
635 
636 	if ((argc < 2) || (argc > 4)) {
637 		printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
638 		return NT_STATUS_OK;
639 	}
640 
641         sscanf(argv[1], "%i", &group_rid);
642 
643 	if (argc > 2)
644 		info_level = atoi(argv[2]);
645 
646 	if (argc > 3)
647 		sscanf(argv[3], "%x", &access_mask);
648 
649 	status = rpccli_try_samr_connects(cli, mem_ctx,
650 					  MAXIMUM_ALLOWED_ACCESS,
651 					  &connect_pol);
652 	if (!NT_STATUS_IS_OK(status)) {
653 		goto done;
654 	}
655 
656 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
657 					&connect_pol,
658 					MAXIMUM_ALLOWED_ACCESS,
659 					&domain_sid,
660 					&domain_pol,
661 					&result);
662 	if (!NT_STATUS_IS_OK(status)) {
663 		goto done;
664 	}
665 	if (!NT_STATUS_IS_OK(result)) {
666 		status = result;
667 		goto done;
668 	}
669 
670 	status = dcerpc_samr_OpenGroup(b, mem_ctx,
671 				       &domain_pol,
672 				       access_mask,
673 				       group_rid,
674 				       &group_pol,
675 				       &result);
676 	if (!NT_STATUS_IS_OK(status)) {
677 		goto done;
678 	}
679 	if (!NT_STATUS_IS_OK(result)) {
680 		status = result;
681 		goto done;
682 	}
683 
684 	status = dcerpc_samr_QueryGroupInfo(b, mem_ctx,
685 					    &group_pol,
686 					    info_level,
687 					    &group_info,
688 					    &result);
689 	if (!NT_STATUS_IS_OK(status)) {
690 		goto done;
691 	}
692 	if (!NT_STATUS_IS_OK(result)) {
693 		status = result;
694 		goto done;
695 	}
696 
697 	display_group_info(group_info, info_level);
698 
699 	dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
700 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
701 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
702 done:
703 	return status;
704 }
705 
706 /* Query groups a user is a member of */
707 
cmd_samr_query_usergroups(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)708 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
709                                           TALLOC_CTX *mem_ctx,
710                                           int argc, const char **argv)
711 {
712 	struct policy_handle 		connect_pol,
713 				domain_pol,
714 				user_pol;
715 	NTSTATUS status, result;
716 	uint32_t 		user_rid;
717 	uint32_t		access_mask = MAXIMUM_ALLOWED_ACCESS;
718 	int 			i;
719 	struct samr_RidWithAttributeArray *rid_array = NULL;
720 	struct dcerpc_binding_handle *b = cli->binding_handle;
721 
722 	if ((argc < 2) || (argc > 3)) {
723 		printf("Usage: %s rid [access mask]\n", argv[0]);
724 		return NT_STATUS_OK;
725 	}
726 
727 	sscanf(argv[1], "%i", &user_rid);
728 
729 	if (argc > 2)
730 		sscanf(argv[2], "%x", &access_mask);
731 
732 	status = rpccli_try_samr_connects(cli, mem_ctx,
733 					  MAXIMUM_ALLOWED_ACCESS,
734 					  &connect_pol);
735 	if (!NT_STATUS_IS_OK(status)) {
736 		goto done;
737 	}
738 
739 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
740 					&connect_pol,
741 					MAXIMUM_ALLOWED_ACCESS,
742 					&domain_sid,
743 					&domain_pol,
744 					&result);
745 	if (!NT_STATUS_IS_OK(status)) {
746 		goto done;
747 	}
748 	if (!NT_STATUS_IS_OK(result)) {
749 		status = result;
750 		goto done;
751 	}
752 
753 	status = dcerpc_samr_OpenUser(b, mem_ctx,
754 				      &domain_pol,
755 				      access_mask,
756 				      user_rid,
757 				      &user_pol,
758 				      &result);
759 
760 	if (!NT_STATUS_IS_OK(status)) {
761 		goto done;
762 	}
763 	if (!NT_STATUS_IS_OK(result)) {
764 		status = result;
765 		goto done;
766 	}
767 
768 	status = dcerpc_samr_GetGroupsForUser(b, mem_ctx,
769 					      &user_pol,
770 					      &rid_array,
771 					      &result);
772 	if (!NT_STATUS_IS_OK(status)) {
773 		goto done;
774 	}
775 	if (!NT_STATUS_IS_OK(result)) {
776 		status = result;
777 		goto done;
778 	}
779 
780 	for (i = 0; i < rid_array->count; i++) {
781 		printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
782 		       rid_array->rids[i].rid,
783 		       rid_array->rids[i].attributes);
784 	}
785 
786 	dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
787 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
788 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
789  done:
790 	return status;
791 }
792 
793 /* Query aliases a user is a member of */
794 
cmd_samr_query_useraliases(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)795 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
796 					   TALLOC_CTX *mem_ctx,
797 					   int argc, const char **argv)
798 {
799 	struct policy_handle 		connect_pol, domain_pol;
800 	NTSTATUS status, result;
801 	struct dom_sid                *sids;
802 	uint32_t                num_sids;
803 	uint32_t		access_mask = MAXIMUM_ALLOWED_ACCESS;
804 	int 			i;
805 	struct lsa_SidArray sid_array;
806 	struct samr_Ids alias_rids;
807 	struct dcerpc_binding_handle *b = cli->binding_handle;
808 
809 	if (argc < 3) {
810 		printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
811 		return NT_STATUS_INVALID_PARAMETER;
812 	}
813 
814 	sids = NULL;
815 	num_sids = 0;
816 
817 	for (i=2; i<argc; i++) {
818 		struct dom_sid tmp_sid;
819 		if (!string_to_sid(&tmp_sid, argv[i])) {
820 			printf("%s is not a legal SID\n", argv[i]);
821 			return NT_STATUS_INVALID_PARAMETER;
822 		}
823 		result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
824 		if (!NT_STATUS_IS_OK(result)) {
825 			return result;
826 		}
827 	}
828 
829 	if (num_sids) {
830 		sid_array.sids = talloc_zero_array(mem_ctx, struct lsa_SidPtr, num_sids);
831 		if (sid_array.sids == NULL)
832 			return NT_STATUS_NO_MEMORY;
833 	} else {
834 		sid_array.sids = NULL;
835 	}
836 
837 	for (i=0; i<num_sids; i++) {
838 		sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]);
839 		if (!sid_array.sids[i].sid) {
840 			return NT_STATUS_NO_MEMORY;
841 		}
842 	}
843 
844 	sid_array.num_sids = num_sids;
845 
846 	status = rpccli_try_samr_connects(cli, mem_ctx,
847 					  MAXIMUM_ALLOWED_ACCESS,
848 					  &connect_pol);
849 	if (!NT_STATUS_IS_OK(status)) {
850 		goto done;
851 	}
852 
853 	status = get_domain_handle(cli, mem_ctx, argv[1],
854 				   &connect_pol,
855 				   access_mask,
856 				   &domain_sid,
857 				   &domain_pol);
858 	if (!NT_STATUS_IS_OK(status)) {
859 		goto done;
860 	}
861 
862 	status = dcerpc_samr_GetAliasMembership(b, mem_ctx,
863 						&domain_pol,
864 						&sid_array,
865 						&alias_rids,
866 						&result);
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 < alias_rids.count; i++) {
876 		printf("\tgroup rid:[0x%x]\n", alias_rids.ids[i]);
877 	}
878 
879 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
880 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
881  done:
882 	return status;
883 }
884 
885 /* Query members of a group */
886 
cmd_samr_query_groupmem(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)887 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
888                                         TALLOC_CTX *mem_ctx,
889                                         int argc, const char **argv)
890 {
891 	struct policy_handle connect_pol, domain_pol, group_pol;
892 	NTSTATUS status, result;
893 	uint32_t group_rid;
894 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
895 	int i;
896 	unsigned int old_timeout;
897 	struct samr_RidAttrArray *rids = NULL;
898 	struct dcerpc_binding_handle *b = cli->binding_handle;
899 
900 	if ((argc < 2) || (argc > 3)) {
901 		printf("Usage: %s rid [access mask]\n", argv[0]);
902 		return NT_STATUS_OK;
903 	}
904 
905 	sscanf(argv[1], "%i", &group_rid);
906 
907 	if (argc > 2)
908 		sscanf(argv[2], "%x", &access_mask);
909 
910 	status = rpccli_try_samr_connects(cli, mem_ctx,
911 					  MAXIMUM_ALLOWED_ACCESS,
912 					  &connect_pol);
913 	if (!NT_STATUS_IS_OK(status)) {
914 		goto done;
915 	}
916 
917 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
918 					&connect_pol,
919 					MAXIMUM_ALLOWED_ACCESS,
920 					&domain_sid,
921 					&domain_pol,
922 					&result);
923 	if (!NT_STATUS_IS_OK(status)) {
924 		goto done;
925 	}
926 	if (!NT_STATUS_IS_OK(result)) {
927 		status = result;
928 		goto done;
929 	}
930 
931 	status = dcerpc_samr_OpenGroup(b, mem_ctx,
932 				       &domain_pol,
933 				       access_mask,
934 				       group_rid,
935 				       &group_pol,
936 				       &result);
937 	if (!NT_STATUS_IS_OK(status)) {
938 		goto done;
939 	}
940 	if (!NT_STATUS_IS_OK(result)) {
941 		status = result;
942 		goto done;
943 	}
944 
945 	/* Make sure to wait for our DC's reply */
946 	old_timeout = rpccli_set_timeout(cli, 30000); /* 30 seconds. */
947 	rpccli_set_timeout(cli, MAX(30000, old_timeout)); /* At least 30 sec */
948 
949 	status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
950 					      &group_pol,
951 					      &rids,
952 					      &result);
953 
954 	rpccli_set_timeout(cli, old_timeout);
955 
956 	if (!NT_STATUS_IS_OK(status)) {
957 		goto done;
958 	}
959 	if (!NT_STATUS_IS_OK(result)) {
960 		status = result;
961 		goto done;
962 	}
963 
964 	for (i = 0; i < rids->count; i++) {
965 		printf("\trid:[0x%x] attr:[0x%x]\n", rids->rids[i],
966 		       rids->attributes[i]);
967 	}
968 
969 	dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
970 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
971 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
972  done:
973 	return status;
974 }
975 
976 /* Enumerate domain users */
977 
cmd_samr_enum_dom_users(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)978 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
979 					TALLOC_CTX *mem_ctx,
980 					int argc, const char **argv)
981 {
982 	struct policy_handle connect_pol;
983 	struct policy_handle domain_pol = { 0, };
984 	NTSTATUS status, result;
985 	uint32_t start_idx, num_dom_users, i;
986 	struct samr_SamArray *dom_users = NULL;
987 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
988 	uint32_t acb_mask = ACB_NORMAL;
989 	uint32_t size = 0xffff;
990 	struct dcerpc_binding_handle *b = cli->binding_handle;
991 
992 	if ((argc < 1) || (argc > 4)) {
993 		printf("Usage: %s [access_mask] [acb_mask] [size]\n", argv[0]);
994 		return NT_STATUS_OK;
995 	}
996 
997 	if (argc > 1) {
998 		sscanf(argv[1], "%x", &access_mask);
999 	}
1000 
1001 	if (argc > 2) {
1002 		sscanf(argv[2], "%x", &acb_mask);
1003 	}
1004 
1005 	if (argc > 3) {
1006 		sscanf(argv[3], "%x", &size);
1007 	}
1008 
1009 	/* Get sam policy handle */
1010 
1011 	status = rpccli_try_samr_connects(cli, mem_ctx,
1012 					  MAXIMUM_ALLOWED_ACCESS,
1013 					  &connect_pol);
1014 	if (!NT_STATUS_IS_OK(status)) {
1015 		goto done;
1016 	}
1017 
1018 	/* Get domain policy handle */
1019 
1020 	status = get_domain_handle(cli, mem_ctx, "domain",
1021 				   &connect_pol,
1022 				   access_mask,
1023 				   &domain_sid,
1024 				   &domain_pol);
1025 	if (!NT_STATUS_IS_OK(status)) {
1026 		goto done;
1027 	}
1028 
1029 	/* Enumerate domain users */
1030 
1031 	start_idx = 0;
1032 
1033 	do {
1034 		status = dcerpc_samr_EnumDomainUsers(b, mem_ctx,
1035 						     &domain_pol,
1036 						     &start_idx,
1037 						     acb_mask,
1038 						     &dom_users,
1039 						     size,
1040 						     &num_dom_users,
1041 						     &result);
1042 		if (!NT_STATUS_IS_OK(status)) {
1043 			goto done;
1044 		}
1045 		if (NT_STATUS_IS_OK(result) ||
1046 		    NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1047 
1048 			for (i = 0; i < num_dom_users; i++)
1049                                printf("user:[%s] rid:[0x%x]\n",
1050 				       dom_users->entries[i].name.string,
1051 				       dom_users->entries[i].idx);
1052 		}
1053 
1054 	} while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1055 
1056  done:
1057 	if (is_valid_policy_hnd(&domain_pol))
1058 		dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1059 
1060 	if (is_valid_policy_hnd(&connect_pol))
1061 		dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1062 
1063 	return status;
1064 }
1065 
1066 /* Enumerate domain groups */
1067 
cmd_samr_enum_dom_groups(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1068 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
1069                                          TALLOC_CTX *mem_ctx,
1070                                          int argc, const char **argv)
1071 {
1072 	struct policy_handle connect_pol;
1073 	struct policy_handle domain_pol = { 0, };
1074 	NTSTATUS status, result;
1075 	uint32_t start_idx, num_dom_groups, i;
1076 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1077 	struct samr_SamArray *dom_groups = NULL;
1078 	uint32_t size = 0xffff;
1079 	struct dcerpc_binding_handle *b = cli->binding_handle;
1080 
1081 	if ((argc < 1) || (argc > 3)) {
1082 		printf("Usage: %s [access_mask] [max_size]\n", argv[0]);
1083 		return NT_STATUS_OK;
1084 	}
1085 
1086 	if (argc > 1) {
1087 		sscanf(argv[1], "%x", &access_mask);
1088 	}
1089 
1090 	if (argc > 2) {
1091 		sscanf(argv[2], "%x", &size);
1092 	}
1093 
1094 	/* Get sam policy handle */
1095 
1096 	status = rpccli_try_samr_connects(cli, mem_ctx,
1097 					  MAXIMUM_ALLOWED_ACCESS,
1098 					  &connect_pol);
1099 	if (!NT_STATUS_IS_OK(status)) {
1100 		goto done;
1101 	}
1102 
1103 	/* Get domain policy handle */
1104 
1105 	status = get_domain_handle(cli, mem_ctx, "domain",
1106 				   &connect_pol,
1107 				   access_mask,
1108 				   &domain_sid,
1109 				   &domain_pol);
1110 	if (!NT_STATUS_IS_OK(status)) {
1111 		goto done;
1112 	}
1113 
1114 	/* Enumerate domain groups */
1115 
1116 	start_idx = 0;
1117 
1118 	do {
1119 		status = dcerpc_samr_EnumDomainGroups(b, mem_ctx,
1120 						      &domain_pol,
1121 						      &start_idx,
1122 						      &dom_groups,
1123 						      size,
1124 						      &num_dom_groups,
1125 						      &result);
1126 		if (!NT_STATUS_IS_OK(status)) {
1127 			goto done;
1128 		}
1129 		if (NT_STATUS_IS_OK(result) ||
1130 		    NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1131 
1132 			for (i = 0; i < num_dom_groups; i++)
1133 				printf("group:[%s] rid:[0x%x]\n",
1134 				       dom_groups->entries[i].name.string,
1135 				       dom_groups->entries[i].idx);
1136 		}
1137 
1138 	} while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1139 
1140  done:
1141 	if (is_valid_policy_hnd(&domain_pol))
1142 		dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1143 
1144 	if (is_valid_policy_hnd(&connect_pol))
1145 		dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1146 
1147 	return status;
1148 }
1149 
1150 /* Enumerate alias groups */
1151 
cmd_samr_enum_als_groups(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1152 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
1153                                          TALLOC_CTX *mem_ctx,
1154                                          int argc, const char **argv)
1155 {
1156 	struct policy_handle connect_pol;
1157 	struct policy_handle domain_pol = { 0, };
1158 	NTSTATUS status, result;
1159 	uint32_t start_idx, num_als_groups, i;
1160 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1161 	struct samr_SamArray *als_groups = NULL;
1162 	uint32_t size = 0xffff;
1163 	struct dcerpc_binding_handle *b = cli->binding_handle;
1164 
1165 	if ((argc < 2) || (argc > 4)) {
1166 		printf("Usage: %s builtin|domain [access mask] [max_size]\n", argv[0]);
1167 		return NT_STATUS_OK;
1168 	}
1169 
1170 	if (argc > 2) {
1171 		sscanf(argv[2], "%x", &access_mask);
1172 	}
1173 
1174 	if (argc > 3) {
1175 		sscanf(argv[3], "%x", &size);
1176 	}
1177 
1178 	/* Get sam policy handle */
1179 
1180 	status = rpccli_try_samr_connects(cli, mem_ctx,
1181 					  MAXIMUM_ALLOWED_ACCESS,
1182 					  &connect_pol);
1183 	if (!NT_STATUS_IS_OK(status)) {
1184 		goto done;
1185 	}
1186 
1187 	/* Get domain policy handle */
1188 
1189 	status = get_domain_handle(cli, mem_ctx, argv[1],
1190 				   &connect_pol,
1191 				   access_mask,
1192 				   &domain_sid,
1193 				   &domain_pol);
1194 	if (!NT_STATUS_IS_OK(status)) {
1195 		goto done;
1196 	}
1197 
1198 	/* Enumerate alias groups */
1199 
1200 	start_idx = 0;
1201 
1202 	do {
1203 		status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
1204 						       &domain_pol,
1205 						       &start_idx,
1206 						       &als_groups,
1207 						       size,
1208 						       &num_als_groups,
1209 						       &result);
1210 		if (!NT_STATUS_IS_OK(status)) {
1211 			goto done;
1212 		}
1213 		if (NT_STATUS_IS_OK(result) ||
1214 		    NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1215 
1216 			for (i = 0; i < num_als_groups; i++)
1217 				printf("group:[%s] rid:[0x%x]\n",
1218 				       als_groups->entries[i].name.string,
1219 				       als_groups->entries[i].idx);
1220 		}
1221 	} while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1222 
1223  done:
1224 	if (is_valid_policy_hnd(&domain_pol))
1225 		dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1226 
1227 	if (is_valid_policy_hnd(&connect_pol))
1228 		dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1229 
1230 	return status;
1231 }
1232 
1233 /* Enumerate domains */
1234 
cmd_samr_enum_domains(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1235 static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
1236 				      TALLOC_CTX *mem_ctx,
1237 				      int argc, const char **argv)
1238 {
1239 	struct policy_handle connect_pol;
1240 	NTSTATUS status, result;
1241 	uint32_t start_idx, size, num_entries, i;
1242 	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1243 	struct samr_SamArray *sam = NULL;
1244 	struct dcerpc_binding_handle *b = cli->binding_handle;
1245 
1246 	if ((argc < 1) || (argc > 2)) {
1247 		printf("Usage: %s [access mask]\n", argv[0]);
1248 		return NT_STATUS_OK;
1249 	}
1250 
1251 	if (argc > 1) {
1252 		sscanf(argv[1], "%x", &access_mask);
1253 	}
1254 
1255 	/* Get sam policy handle */
1256 
1257 	status = rpccli_try_samr_connects(cli, mem_ctx,
1258 					  access_mask,
1259 					  &connect_pol);
1260 	if (!NT_STATUS_IS_OK(status)) {
1261 		goto done;
1262 	}
1263 
1264 	/* Enumerate domains */
1265 
1266 	start_idx = 0;
1267 	size = 0xffff;
1268 
1269 	do {
1270 		status = dcerpc_samr_EnumDomains(b, mem_ctx,
1271 						 &connect_pol,
1272 						 &start_idx,
1273 						 &sam,
1274 						 size,
1275 						 &num_entries,
1276 						 &result);
1277 		if (!NT_STATUS_IS_OK(status)) {
1278 			goto done;
1279 		}
1280 		if (NT_STATUS_IS_OK(result) ||
1281 		    NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1282 
1283 			for (i = 0; i < num_entries; i++)
1284 				printf("name:[%s] idx:[0x%x]\n",
1285 				       sam->entries[i].name.string,
1286 				       sam->entries[i].idx);
1287 		}
1288 	} while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1289 
1290  done:
1291 	if (is_valid_policy_hnd(&connect_pol)) {
1292 		dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1293 	}
1294 
1295 	return status;
1296 }
1297 
1298 
1299 /* Query alias membership */
1300 
cmd_samr_query_aliasmem(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1301 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1302                                         TALLOC_CTX *mem_ctx,
1303                                         int argc, const char **argv)
1304 {
1305 	struct policy_handle connect_pol, domain_pol, alias_pol;
1306 	NTSTATUS status, result;
1307 	uint32_t alias_rid, i;
1308 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1309 	struct lsa_SidArray sid_array;
1310 	struct dcerpc_binding_handle *b = cli->binding_handle;
1311 
1312 	if ((argc < 3) || (argc > 4)) {
1313 		printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1314 		return NT_STATUS_OK;
1315 	}
1316 
1317 	sscanf(argv[2], "%i", &alias_rid);
1318 
1319 	if (argc > 3)
1320 		sscanf(argv[3], "%x", &access_mask);
1321 
1322 	/* Open SAMR handle */
1323 
1324 	status = rpccli_try_samr_connects(cli, mem_ctx,
1325 					  MAXIMUM_ALLOWED_ACCESS,
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 				   MAXIMUM_ALLOWED_ACCESS,
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_GetMembersInAlias(b, mem_ctx,
1359 					       &alias_pol,
1360 					       &sid_array,
1361 					       &result);
1362 	if (!NT_STATUS_IS_OK(status)) {
1363 		goto done;
1364 	}
1365 	if (!NT_STATUS_IS_OK(result)) {
1366 		status = result;
1367 		goto done;
1368 	}
1369 
1370 	for (i = 0; i < sid_array.num_sids; i++) {
1371 		struct dom_sid_buf sid_str;
1372 
1373 		printf("\tsid:[%s]\n",
1374 		       dom_sid_str_buf(sid_array.sids[i].sid, &sid_str));
1375 	}
1376 
1377 	dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
1378 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1379 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1380  done:
1381 	return status;
1382 }
1383 
1384 /* Query alias info */
1385 
cmd_samr_query_aliasinfo(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1386 static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
1387 					 TALLOC_CTX *mem_ctx,
1388 					 int argc, const char **argv)
1389 {
1390 	struct policy_handle connect_pol, domain_pol, alias_pol;
1391 	NTSTATUS status, result;
1392 	uint32_t alias_rid;
1393 	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1394 	union samr_AliasInfo *info = NULL;
1395 	enum samr_AliasInfoEnum level = ALIASINFOALL;
1396 	struct dcerpc_binding_handle *b = cli->binding_handle;
1397 
1398 	if ((argc < 3) || (argc > 4)) {
1399 		printf("Usage: %s builtin|domain rid [level] [access mask]\n",
1400 			argv[0]);
1401 		return NT_STATUS_OK;
1402 	}
1403 
1404 	sscanf(argv[2], "%i", &alias_rid);
1405 
1406 	if (argc > 2) {
1407 		level = atoi(argv[3]);
1408 	}
1409 
1410 	if (argc > 3) {
1411 		sscanf(argv[4], "%x", &access_mask);
1412 	}
1413 
1414 	/* Open SAMR handle */
1415 
1416 	status = rpccli_try_samr_connects(cli, mem_ctx,
1417 					  SEC_FLAG_MAXIMUM_ALLOWED,
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 				   SEC_FLAG_MAXIMUM_ALLOWED,
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)) {
1446 		status = result;
1447 		goto done;
1448 	}
1449 
1450 	status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
1451 					    &alias_pol,
1452 					    level,
1453 					    &info,
1454 					    &result);
1455 	if (!NT_STATUS_IS_OK(status)) {
1456 		goto done;
1457 	}
1458 	if (!NT_STATUS_IS_OK(result)) {
1459 		status = result;
1460 		goto done;
1461 	}
1462 
1463 	switch (level) {
1464 		case ALIASINFOALL:
1465 			printf("Name: %s\n", info->all.name.string);
1466 			printf("Description: %s\n", info->all.description.string);
1467 			printf("Num Members: %d\n", info->all.num_members);
1468 			break;
1469 		case ALIASINFONAME:
1470 			printf("Name: %s\n", info->name.string);
1471 			break;
1472 		case ALIASINFODESCRIPTION:
1473 			printf("Description: %s\n", info->description.string);
1474 			break;
1475 		default:
1476 			break;
1477 	}
1478 
1479 	dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
1480 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1481 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1482  done:
1483 	return status;
1484 }
1485 
1486 
1487 /* Query delete an alias membership */
1488 
cmd_samr_delete_alias(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1489 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1490 				      TALLOC_CTX *mem_ctx,
1491 				      int argc, const char **argv)
1492 {
1493 	struct policy_handle connect_pol, domain_pol, alias_pol;
1494 	NTSTATUS status, result;
1495 	uint32_t alias_rid;
1496 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1497 	struct dcerpc_binding_handle *b = cli->binding_handle;
1498 	int error = 0;
1499 
1500 	if (argc != 3) {
1501 		printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1502 		return NT_STATUS_OK;
1503 	}
1504 
1505 	alias_rid = smb_strtoul(argv[2], NULL, 10, &error, SMB_STR_STANDARD);
1506 	if (error != 0) {
1507 		return NT_STATUS_INVALID_PARAMETER;
1508 	}
1509 
1510 
1511 	/* Open SAMR handle */
1512 
1513 	status = rpccli_try_samr_connects(cli, mem_ctx,
1514 					  MAXIMUM_ALLOWED_ACCESS,
1515 					  &connect_pol);
1516 	if (!NT_STATUS_IS_OK(status)) {
1517 		goto done;
1518 	}
1519 
1520 	/* Open handle on domain */
1521 
1522 	status = get_domain_handle(cli, mem_ctx, argv[1],
1523 				   &connect_pol,
1524 				   MAXIMUM_ALLOWED_ACCESS,
1525 				   &domain_sid,
1526 				   &domain_pol);
1527 	if (!NT_STATUS_IS_OK(status)) {
1528 		goto done;
1529 	}
1530 
1531 	/* Open handle on alias */
1532 
1533 	status = dcerpc_samr_OpenAlias(b, mem_ctx,
1534 				       &domain_pol,
1535 				       access_mask,
1536 				       alias_rid,
1537 				       &alias_pol,
1538 				       &result);
1539 	if (!NT_STATUS_IS_OK(status)) {
1540 		goto done;
1541 	}
1542 	if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1543 		/* Probably this was a user name, try lookupnames */
1544 		struct samr_Ids rids, types;
1545 		struct lsa_String lsa_acct_name;
1546 
1547 		init_lsa_String(&lsa_acct_name, argv[2]);
1548 
1549 		status = dcerpc_samr_LookupNames(b, mem_ctx,
1550 						 &domain_pol,
1551 						 1,
1552 						 &lsa_acct_name,
1553 						 &rids,
1554 						 &types,
1555 						 &result);
1556 		if (!NT_STATUS_IS_OK(status)) {
1557 			goto done;
1558 		}
1559 		if (NT_STATUS_IS_OK(result)) {
1560 			if (rids.count != 1) {
1561 				status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1562 				goto done;
1563 			}
1564 			if (types.count != 1) {
1565 				status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1566 				goto done;
1567 			}
1568 
1569 			status = dcerpc_samr_OpenAlias(b, mem_ctx,
1570 						       &domain_pol,
1571 						       access_mask,
1572 						       rids.ids[0],
1573 						       &alias_pol,
1574 						       &result);
1575 			if (!NT_STATUS_IS_OK(status)) {
1576 				goto done;
1577 			}
1578 		}
1579 	}
1580 
1581 	status = dcerpc_samr_DeleteDomAlias(b, mem_ctx,
1582 					    &alias_pol,
1583 					    &result);
1584 	if (!NT_STATUS_IS_OK(status)) {
1585 		goto done;
1586 	}
1587 	if (!NT_STATUS_IS_OK(result)) {
1588 		status = result;
1589 		goto done;
1590 	}
1591 
1592 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1593 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1594  done:
1595 	return status;
1596 }
1597 
1598 /* Query display info */
1599 
cmd_samr_query_dispinfo_internal(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv,uint32_t opcode)1600 static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli,
1601 						 TALLOC_CTX *mem_ctx,
1602 						 int argc, const char **argv,
1603 						 uint32_t opcode)
1604 {
1605 	struct policy_handle connect_pol, domain_pol;
1606 	NTSTATUS status, result;
1607 	uint32_t start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
1608 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1609 	uint32_t info_level = 1;
1610 	union samr_DispInfo info;
1611 	int loop_count = 0;
1612 	bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1613 	uint32_t total_size, returned_size;
1614 	struct dcerpc_binding_handle *b = cli->binding_handle;
1615 
1616 	if (argc > 6) {
1617 		printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1618 		return NT_STATUS_OK;
1619 	}
1620 
1621 	if (argc >= 2)
1622                 sscanf(argv[1], "%i", &info_level);
1623 
1624 	if (argc >= 3)
1625                 sscanf(argv[2], "%i", &start_idx);
1626 
1627 	if (argc >= 4) {
1628                 sscanf(argv[3], "%i", &max_entries);
1629 		got_params = True;
1630 	}
1631 
1632 	if (argc >= 5) {
1633                 sscanf(argv[4], "%i", &max_size);
1634 		got_params = True;
1635 	}
1636 
1637 	if (argc >= 6)
1638                 sscanf(argv[5], "%x", &access_mask);
1639 
1640 	/* Get sam policy handle */
1641 
1642 	status = rpccli_try_samr_connects(cli, mem_ctx,
1643 					  MAXIMUM_ALLOWED_ACCESS,
1644 					  &connect_pol);
1645 	if (!NT_STATUS_IS_OK(status)) {
1646 		goto done;
1647 	}
1648 
1649 	/* Get domain policy handle */
1650 
1651 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
1652 					&connect_pol,
1653 					access_mask,
1654 					&domain_sid,
1655 					&domain_pol,
1656 					&result);
1657 	if (!NT_STATUS_IS_OK(status)) {
1658 		goto done;
1659 	}
1660 	if (!NT_STATUS_IS_OK(result)) {
1661 		status = result;
1662 		goto done;
1663 	}
1664 
1665 	/* Query display info */
1666 
1667 	do {
1668 
1669 		if (!got_params)
1670 			dcerpc_get_query_dispinfo_params(
1671 				loop_count, &max_entries, &max_size);
1672 
1673 		switch (opcode) {
1674 		case NDR_SAMR_QUERYDISPLAYINFO:
1675 			status = dcerpc_samr_QueryDisplayInfo(b, mem_ctx,
1676 							      &domain_pol,
1677 							      info_level,
1678 							      start_idx,
1679 							      max_entries,
1680 							      max_size,
1681 							      &total_size,
1682 							      &returned_size,
1683 							      &info,
1684 							      &result);
1685 			break;
1686 		case NDR_SAMR_QUERYDISPLAYINFO2:
1687 			status = dcerpc_samr_QueryDisplayInfo2(b, mem_ctx,
1688 							       &domain_pol,
1689 							       info_level,
1690 							       start_idx,
1691 							       max_entries,
1692 							       max_size,
1693 							       &total_size,
1694 							       &returned_size,
1695 							       &info,
1696 							       &result);
1697 
1698 			break;
1699 		case NDR_SAMR_QUERYDISPLAYINFO3:
1700 			status = dcerpc_samr_QueryDisplayInfo3(b, mem_ctx,
1701 							       &domain_pol,
1702 							       info_level,
1703 							       start_idx,
1704 							       max_entries,
1705 							       max_size,
1706 							       &total_size,
1707 							       &returned_size,
1708 							       &info,
1709 							       &result);
1710 
1711 			break;
1712 		default:
1713 			return NT_STATUS_INVALID_PARAMETER;
1714 		}
1715 
1716 		if (!NT_STATUS_IS_OK(status)) {
1717 			break;
1718 		}
1719 		status = result;
1720 		if (!NT_STATUS_IS_OK(result) &&
1721 		    !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
1722 		    !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1723 			break;
1724 		}
1725 
1726 		loop_count++;
1727 
1728 		switch (info_level) {
1729 			case 1:
1730 				num_entries = info.info1.count;
1731 				break;
1732 			case 2:
1733 				num_entries = info.info2.count;
1734 				break;
1735 			case 3:
1736 				num_entries = info.info3.count;
1737 				break;
1738 			case 4:
1739 				num_entries = info.info4.count;
1740 				break;
1741 			case 5:
1742 				num_entries = info.info5.count;
1743 				break;
1744 			default:
1745 				break;
1746 		}
1747 
1748 		start_idx += num_entries;
1749 
1750 		if (num_entries == 0)
1751 			break;
1752 
1753 		for (i = 0; i < num_entries; i++) {
1754 			switch (info_level) {
1755 			case 1:
1756 				display_sam_info_1(&info.info1.entries[i]);
1757 				break;
1758 			case 2:
1759 				display_sam_info_2(&info.info2.entries[i]);
1760 				break;
1761 			case 3:
1762 				display_sam_info_3(&info.info3.entries[i]);
1763 				break;
1764 			case 4:
1765 				display_sam_info_4(&info.info4.entries[i]);
1766 				break;
1767 			case 5:
1768 				display_sam_info_5(&info.info5.entries[i]);
1769 				break;
1770 			}
1771 		}
1772 	} while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1773 
1774 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1775 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1776  done:
1777 	return status;
1778 }
1779 
cmd_samr_query_dispinfo(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1780 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1781 					TALLOC_CTX *mem_ctx,
1782 					int argc, const char **argv)
1783 {
1784 	return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1785 						NDR_SAMR_QUERYDISPLAYINFO);
1786 }
1787 
cmd_samr_query_dispinfo2(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1788 static NTSTATUS cmd_samr_query_dispinfo2(struct rpc_pipe_client *cli,
1789 					 TALLOC_CTX *mem_ctx,
1790 					 int argc, const char **argv)
1791 {
1792 	return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1793 						NDR_SAMR_QUERYDISPLAYINFO2);
1794 }
1795 
cmd_samr_query_dispinfo3(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1796 static NTSTATUS cmd_samr_query_dispinfo3(struct rpc_pipe_client *cli,
1797 					 TALLOC_CTX *mem_ctx,
1798 					 int argc, const char **argv)
1799 {
1800 	return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1801 						NDR_SAMR_QUERYDISPLAYINFO3);
1802 }
1803 
1804 /* Query domain info */
1805 
cmd_samr_query_dominfo(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1806 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1807                                        TALLOC_CTX *mem_ctx,
1808                                        int argc, const char **argv)
1809 {
1810 	struct policy_handle connect_pol, domain_pol;
1811 	NTSTATUS status, result;
1812 	uint32_t switch_level = 2;
1813 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1814 	union samr_DomainInfo *info = NULL;
1815 	struct dcerpc_binding_handle *b = cli->binding_handle;
1816 
1817 	if (argc > 3) {
1818 		printf("Usage: %s [info level] [access mask]\n", argv[0]);
1819 		return NT_STATUS_OK;
1820 	}
1821 
1822 	if (argc > 1)
1823                 sscanf(argv[1], "%i", &switch_level);
1824 
1825 	if (argc > 2)
1826                 sscanf(argv[2], "%x", &access_mask);
1827 
1828 	/* Get sam policy handle */
1829 
1830 	status = rpccli_try_samr_connects(cli, mem_ctx,
1831 					  MAXIMUM_ALLOWED_ACCESS,
1832 					  &connect_pol);
1833 	if (!NT_STATUS_IS_OK(status)) {
1834 		goto done;
1835 	}
1836 
1837 	/* Get domain policy handle */
1838 
1839 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
1840 					&connect_pol,
1841 					access_mask,
1842 					&domain_sid,
1843 					&domain_pol,
1844 					&result);
1845 	if (!NT_STATUS_IS_OK(status)) {
1846 		goto done;
1847 	}
1848 	if (!NT_STATUS_IS_OK(result)) {
1849 		status = result;
1850 		goto done;
1851 	}
1852 
1853 	/* Query domain info */
1854 
1855 	status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
1856 					     &domain_pol,
1857 					     switch_level,
1858 					     &info,
1859 					     &result);
1860 	if (!NT_STATUS_IS_OK(status)) {
1861 		goto done;
1862 	}
1863 	if (!NT_STATUS_IS_OK(result)) {
1864 		status = result;
1865 		goto done;
1866 	}
1867 
1868 	/* Display domain info */
1869 
1870 	switch (switch_level) {
1871 	case 1:
1872 		display_sam_dom_info_1(&info->info1);
1873 		break;
1874 	case 2:
1875 		display_sam_dom_info_2(&info->general);
1876 		break;
1877 	case 3:
1878 		display_sam_dom_info_3(&info->info3);
1879 		break;
1880 	case 4:
1881 		display_sam_dom_info_4(&info->oem);
1882 		break;
1883 	case 5:
1884 		display_sam_dom_info_5(&info->info5);
1885 		break;
1886 	case 6:
1887 		display_sam_dom_info_6(&info->info6);
1888 		break;
1889 	case 7:
1890 		display_sam_dom_info_7(&info->info7);
1891 		break;
1892 	case 8:
1893 		display_sam_dom_info_8(&info->info8);
1894 		break;
1895 	case 9:
1896 		display_sam_dom_info_9(&info->info9);
1897 		break;
1898 	case 12:
1899 		display_sam_dom_info_12(&info->info12);
1900 		break;
1901 	case 13:
1902 		display_sam_dom_info_13(&info->info13);
1903 		break;
1904 
1905 	default:
1906 		printf("cannot display domain info for switch value %d\n",
1907 		       switch_level);
1908 		break;
1909 	}
1910 
1911  done:
1912 
1913 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1914 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1915 	return status;
1916 }
1917 
1918 /* Create domain user */
1919 
cmd_samr_create_dom_user(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)1920 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1921                                          TALLOC_CTX *mem_ctx,
1922                                          int argc, const char **argv)
1923 {
1924 	struct policy_handle connect_pol, domain_pol, user_pol;
1925 	NTSTATUS status, result;
1926 	struct lsa_String acct_name;
1927 	uint32_t acb_info;
1928 	uint32_t acct_flags, user_rid;
1929 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
1930 	uint32_t access_granted = 0;
1931 	struct dcerpc_binding_handle *b = cli->binding_handle;
1932 
1933 	if ((argc < 2) || (argc > 3)) {
1934 		printf("Usage: %s username [access mask]\n", argv[0]);
1935 		return NT_STATUS_OK;
1936 	}
1937 
1938 	init_lsa_String(&acct_name, argv[1]);
1939 
1940 	if (argc > 2)
1941                 sscanf(argv[2], "%x", &access_mask);
1942 
1943 	/* Get sam policy handle */
1944 
1945 	status = rpccli_try_samr_connects(cli, mem_ctx,
1946 					  MAXIMUM_ALLOWED_ACCESS,
1947 					  &connect_pol);
1948 	if (!NT_STATUS_IS_OK(status)) {
1949 		goto done;
1950 	}
1951 
1952 	/* Get domain policy handle */
1953 
1954 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
1955 					&connect_pol,
1956 					access_mask,
1957 					&domain_sid,
1958 					&domain_pol,
1959 					&result);
1960 	if (!NT_STATUS_IS_OK(status)) {
1961 		goto done;
1962 	}
1963 	if (!NT_STATUS_IS_OK(result)) {
1964 		status = result;
1965 		goto done;
1966 	}
1967 
1968 	/* Create domain user */
1969 
1970 	acb_info = ACB_NORMAL;
1971 	acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1972 		     SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1973 		     SAMR_USER_ACCESS_SET_PASSWORD |
1974 		     SAMR_USER_ACCESS_GET_ATTRIBUTES |
1975 		     SAMR_USER_ACCESS_SET_ATTRIBUTES;
1976 
1977 	status = dcerpc_samr_CreateUser2(b, mem_ctx,
1978 					 &domain_pol,
1979 					 &acct_name,
1980 					 acb_info,
1981 					 acct_flags,
1982 					 &user_pol,
1983 					 &access_granted,
1984 					 &user_rid,
1985 					 &result);
1986 	if (!NT_STATUS_IS_OK(status)) {
1987 		goto done;
1988 	}
1989 	if (!NT_STATUS_IS_OK(result)) {
1990 		status = result;
1991 		goto done;
1992 	}
1993 
1994 	status = dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1995 	if (!NT_STATUS_IS_OK(status)) goto done;
1996 
1997 	status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1998 	if (!NT_STATUS_IS_OK(status)) goto done;
1999 
2000 	status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2001 	if (!NT_STATUS_IS_OK(status)) goto done;
2002 
2003  done:
2004 	return status;
2005 }
2006 
2007 /* Create domain group */
2008 
cmd_samr_create_dom_group(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2009 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
2010                                           TALLOC_CTX *mem_ctx,
2011                                           int argc, const char **argv)
2012 {
2013 	struct policy_handle connect_pol, domain_pol, group_pol;
2014 	NTSTATUS status, result;
2015 	struct lsa_String grp_name;
2016 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2017 	uint32_t rid = 0;
2018 	struct dcerpc_binding_handle *b = cli->binding_handle;
2019 
2020 	if ((argc < 2) || (argc > 3)) {
2021 		printf("Usage: %s groupname [access mask]\n", argv[0]);
2022 		return NT_STATUS_OK;
2023 	}
2024 
2025 	init_lsa_String(&grp_name, argv[1]);
2026 
2027 	if (argc > 2)
2028                 sscanf(argv[2], "%x", &access_mask);
2029 
2030 	/* Get sam policy handle */
2031 
2032 	status = rpccli_try_samr_connects(cli, mem_ctx,
2033 					  MAXIMUM_ALLOWED_ACCESS,
2034 					  &connect_pol);
2035 	if (!NT_STATUS_IS_OK(status)) {
2036 		goto done;
2037 	}
2038 
2039 	/* Get domain policy handle */
2040 
2041 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
2042 					&connect_pol,
2043 					access_mask,
2044 					&domain_sid,
2045 					&domain_pol,
2046 					&result);
2047 	if (!NT_STATUS_IS_OK(status)) {
2048 		goto done;
2049 	}
2050 	if (!NT_STATUS_IS_OK(result)) {
2051 		status = result;
2052 		goto done;
2053 	}
2054 
2055 	/* Create domain user */
2056 	status = dcerpc_samr_CreateDomainGroup(b, mem_ctx,
2057 					       &domain_pol,
2058 					       &grp_name,
2059 					       MAXIMUM_ALLOWED_ACCESS,
2060 					       &group_pol,
2061 					       &rid,
2062 					       &result);
2063 	if (!NT_STATUS_IS_OK(status)) {
2064 		goto done;
2065 	}
2066 	if (!NT_STATUS_IS_OK(result)) {
2067 		status = result;
2068 		goto done;
2069 	}
2070 
2071 	status = dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
2072 	if (!NT_STATUS_IS_OK(status)) goto done;
2073 
2074 	status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2075 	if (!NT_STATUS_IS_OK(status)) goto done;
2076 
2077 	status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2078 	if (!NT_STATUS_IS_OK(status)) goto done;
2079 
2080  done:
2081 	return status;
2082 }
2083 
2084 /* Create domain alias */
2085 
cmd_samr_create_dom_alias(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2086 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
2087                                           TALLOC_CTX *mem_ctx,
2088                                           int argc, const char **argv)
2089 {
2090 	struct policy_handle connect_pol, domain_pol, alias_pol;
2091 	NTSTATUS status, result;
2092 	struct lsa_String alias_name;
2093 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2094 	uint32_t rid = 0;
2095 	struct dcerpc_binding_handle *b = cli->binding_handle;
2096 
2097 	if ((argc < 2) || (argc > 3)) {
2098 		printf("Usage: %s aliasname [access mask]\n", argv[0]);
2099 		return NT_STATUS_OK;
2100 	}
2101 
2102 	init_lsa_String(&alias_name, argv[1]);
2103 
2104 	if (argc > 2)
2105                 sscanf(argv[2], "%x", &access_mask);
2106 
2107 	/* Get sam policy handle */
2108 
2109 	status = rpccli_try_samr_connects(cli, mem_ctx,
2110 					  MAXIMUM_ALLOWED_ACCESS,
2111 					  &connect_pol);
2112 	if (!NT_STATUS_IS_OK(status)) {
2113 		goto done;
2114 	}
2115 
2116 	/* Get domain policy handle */
2117 
2118 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
2119 					&connect_pol,
2120 					access_mask,
2121 					&domain_sid,
2122 					&domain_pol,
2123 					&result);
2124 	if (!NT_STATUS_IS_OK(status)) {
2125 		goto done;
2126 	}
2127 	if (!NT_STATUS_IS_OK(result)) {
2128 		status = result;
2129 		goto done;
2130 	}
2131 
2132 	/* Create domain user */
2133 
2134 	status = dcerpc_samr_CreateDomAlias(b, mem_ctx,
2135 					    &domain_pol,
2136 					    &alias_name,
2137 					    MAXIMUM_ALLOWED_ACCESS,
2138 					    &alias_pol,
2139 					    &rid,
2140 					    &result);
2141 	if (!NT_STATUS_IS_OK(status)) {
2142 		goto done;
2143 	}
2144 	if (!NT_STATUS_IS_OK(result)) {
2145 		status = result;
2146 		goto done;
2147 	}
2148 
2149 
2150 	status = dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
2151 	if (!NT_STATUS_IS_OK(status)) goto done;
2152 
2153 	status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2154 	if (!NT_STATUS_IS_OK(status)) goto done;
2155 
2156 	status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2157 	if (!NT_STATUS_IS_OK(status)) goto done;
2158 
2159  done:
2160 	return status;
2161 }
2162 
2163 /* Lookup sam names */
2164 
cmd_samr_lookup_names(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2165 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
2166                                       TALLOC_CTX *mem_ctx,
2167                                       int argc, const char **argv)
2168 {
2169 	NTSTATUS status, result;
2170 	struct policy_handle connect_pol, domain_pol;
2171 	uint32_t num_names;
2172 	struct samr_Ids rids, name_types;
2173 	int i;
2174 	struct lsa_String *names = NULL;
2175 	struct dcerpc_binding_handle *b = cli->binding_handle;
2176 
2177 	if (argc < 3) {
2178 		printf("Usage: %s  domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
2179 		printf("check on the domain SID: S-1-5-21-x-y-z\n");
2180 		printf("or check on the builtin SID: S-1-5-32\n");
2181 		return NT_STATUS_OK;
2182 	}
2183 
2184 	/* Get sam policy and domain handles */
2185 
2186 	status = rpccli_try_samr_connects(cli, mem_ctx,
2187 					  MAXIMUM_ALLOWED_ACCESS,
2188 					  &connect_pol);
2189 	if (!NT_STATUS_IS_OK(status)) {
2190 		goto done;
2191 	}
2192 
2193 	status = get_domain_handle(cli, mem_ctx, argv[1],
2194 				   &connect_pol,
2195 				   MAXIMUM_ALLOWED_ACCESS,
2196 				   &domain_sid,
2197 				   &domain_pol);
2198 	if (!NT_STATUS_IS_OK(status)) {
2199 		goto done;
2200 	}
2201 
2202 	/* Look up names */
2203 
2204 	num_names = argc - 2;
2205 
2206 	if ((names = talloc_array(mem_ctx, struct lsa_String, num_names)) == NULL) {
2207 		dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2208 		dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2209 		status = NT_STATUS_NO_MEMORY;
2210 		goto done;
2211 	}
2212 
2213 	for (i = 0; i < num_names; i++) {
2214 		init_lsa_String(&names[i], argv[i + 2]);
2215 	}
2216 
2217 	status = dcerpc_samr_LookupNames(b, mem_ctx,
2218 					 &domain_pol,
2219 					 num_names,
2220 					 names,
2221 					 &rids,
2222 					 &name_types,
2223 					 &result);
2224 	if (!NT_STATUS_IS_OK(status)) {
2225 		goto done;
2226 	}
2227 	if (!NT_STATUS_IS_OK(result)) {
2228 		status = result;
2229 		goto done;
2230 	}
2231 	if (rids.count != num_names) {
2232 		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2233 		goto done;
2234 	}
2235 	if (name_types.count != num_names) {
2236 		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2237 		goto done;
2238 	}
2239 
2240 	/* Display results */
2241 
2242 	for (i = 0; i < num_names; i++)
2243 		printf("name %s: 0x%x (%d)\n", names[i].string, rids.ids[i],
2244 		       name_types.ids[i]);
2245 
2246 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2247 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2248  done:
2249 	return status;
2250 }
2251 
2252 /* Lookup sam rids */
2253 
cmd_samr_lookup_rids(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2254 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
2255                                      TALLOC_CTX *mem_ctx,
2256                                      int argc, const char **argv)
2257 {
2258 	NTSTATUS status, result;
2259 	struct policy_handle connect_pol, domain_pol;
2260 	uint32_t num_rids, *rids;
2261 	struct lsa_Strings names;
2262 	struct samr_Ids types;
2263 	struct dcerpc_binding_handle *b = cli->binding_handle;
2264 
2265 	int i;
2266 
2267 	if (argc < 3) {
2268 		printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
2269 		return NT_STATUS_OK;
2270 	}
2271 
2272 	/* Get sam policy and domain handles */
2273 
2274 	status = rpccli_try_samr_connects(cli, mem_ctx,
2275 					  MAXIMUM_ALLOWED_ACCESS,
2276 					  &connect_pol);
2277 	if (!NT_STATUS_IS_OK(status)) {
2278 		goto done;
2279 	}
2280 
2281 	status = get_domain_handle(cli, mem_ctx, argv[1],
2282 				   &connect_pol,
2283 				   MAXIMUM_ALLOWED_ACCESS,
2284 				   &domain_sid,
2285 				   &domain_pol);
2286 	if (!NT_STATUS_IS_OK(status)) {
2287 		goto done;
2288 	}
2289 
2290 	/* Look up rids */
2291 
2292 	num_rids = argc - 2;
2293 
2294 	if ((rids = talloc_array(mem_ctx, uint32_t, num_rids)) == NULL) {
2295 		dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2296 		dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2297 		status = NT_STATUS_NO_MEMORY;
2298 		goto done;
2299 	}
2300 
2301 	for (i = 0; i < argc - 2; i++)
2302                 sscanf(argv[i + 2], "%i", &rids[i]);
2303 
2304 	status = dcerpc_samr_LookupRids(b, mem_ctx,
2305 					&domain_pol,
2306 					num_rids,
2307 					rids,
2308 					&names,
2309 					&types,
2310 					&result);
2311 	if (!NT_STATUS_IS_OK(status)) {
2312 		goto done;
2313 	}
2314 	status = result;
2315 	if (!NT_STATUS_IS_OK(result) &&
2316 	    !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
2317 		goto done;
2318 
2319 	/* Display results */
2320 	if (num_rids != names.count) {
2321 		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2322 		goto done;
2323 	}
2324 	if (num_rids != types.count) {
2325 		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2326 		goto done;
2327 	}
2328 
2329 	for (i = 0; i < num_rids; i++) {
2330 		printf("rid 0x%x: %s (%d)\n",
2331 			rids[i], names.names[i].string, types.ids[i]);
2332 	}
2333 
2334 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2335 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2336  done:
2337 	return status;
2338 }
2339 
2340 /* Delete domain group */
2341 
cmd_samr_delete_dom_group(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2342 static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
2343                                          TALLOC_CTX *mem_ctx,
2344                                          int argc, const char **argv)
2345 {
2346 	NTSTATUS status, result;
2347 	struct policy_handle connect_pol, domain_pol, group_pol;
2348 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2349 	struct dcerpc_binding_handle *b = cli->binding_handle;
2350 
2351 	if ((argc < 2) || (argc > 3)) {
2352 		printf("Usage: %s groupname\n", argv[0]);
2353 		return NT_STATUS_OK;
2354 	}
2355 
2356 	if (argc > 2)
2357                 sscanf(argv[2], "%x", &access_mask);
2358 
2359 	/* Get sam policy and domain handles */
2360 
2361 	status = rpccli_try_samr_connects(cli, mem_ctx,
2362 					  MAXIMUM_ALLOWED_ACCESS,
2363 					  &connect_pol);
2364 	if (!NT_STATUS_IS_OK(status)) {
2365 		goto done;
2366 	}
2367 
2368 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
2369 					&connect_pol,
2370 					MAXIMUM_ALLOWED_ACCESS,
2371 					&domain_sid,
2372 					&domain_pol,
2373 					&result);
2374 	if (!NT_STATUS_IS_OK(status)) {
2375 		goto done;
2376 	}
2377 	if (!NT_STATUS_IS_OK(result)) {
2378 		status = result;
2379 		goto done;
2380 	}
2381 
2382 	/* Get handle on group */
2383 
2384 	{
2385 		struct samr_Ids group_rids, name_types;
2386 		struct lsa_String lsa_acct_name;
2387 
2388 		init_lsa_String(&lsa_acct_name, argv[1]);
2389 
2390 		status = dcerpc_samr_LookupNames(b, mem_ctx,
2391 						 &domain_pol,
2392 						 1,
2393 						 &lsa_acct_name,
2394 						 &group_rids,
2395 						 &name_types,
2396 						 &result);
2397 		if (!NT_STATUS_IS_OK(status)) {
2398 			goto done;
2399 		}
2400 		if (!NT_STATUS_IS_OK(result)) {
2401 			status = result;
2402 			goto done;
2403 		}
2404 		if (group_rids.count != 1) {
2405 			status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2406 			goto done;
2407 		}
2408 		if (name_types.count != 1) {
2409 			status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2410 			goto done;
2411 		}
2412 
2413 		status = dcerpc_samr_OpenGroup(b, mem_ctx,
2414 					       &domain_pol,
2415 					       access_mask,
2416 					       group_rids.ids[0],
2417 					       &group_pol,
2418 					       &result);
2419 		if (!NT_STATUS_IS_OK(status)) {
2420 			goto done;
2421 		}
2422 		if (!NT_STATUS_IS_OK(result)) {
2423 			status = result;
2424 			goto done;
2425 		}
2426 	}
2427 
2428 	/* Delete group */
2429 
2430 	status = dcerpc_samr_DeleteDomainGroup(b, mem_ctx,
2431 					       &group_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 	/* Display results */
2442 
2443 	dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
2444 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2445 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2446 
2447  done:
2448 	return status;
2449 }
2450 
2451 /* Delete domain user */
2452 
cmd_samr_delete_dom_user(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2453 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
2454                                          TALLOC_CTX *mem_ctx,
2455                                          int argc, const char **argv)
2456 {
2457 	NTSTATUS status, result;
2458 	struct policy_handle connect_pol, domain_pol, user_pol;
2459 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2460 	struct dcerpc_binding_handle *b = cli->binding_handle;
2461 
2462 	if ((argc < 2) || (argc > 3)) {
2463 		printf("Usage: %s username\n", argv[0]);
2464 		return NT_STATUS_OK;
2465 	}
2466 
2467 	if (argc > 2)
2468                 sscanf(argv[2], "%x", &access_mask);
2469 
2470 	/* Get sam policy and domain handles */
2471 
2472 	status = rpccli_try_samr_connects(cli, mem_ctx,
2473 					  MAXIMUM_ALLOWED_ACCESS,
2474 					  &connect_pol);
2475 	if (!NT_STATUS_IS_OK(status)) {
2476 		goto done;
2477 	}
2478 
2479 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
2480 					&connect_pol,
2481 					MAXIMUM_ALLOWED_ACCESS,
2482 					&domain_sid,
2483 					&domain_pol,
2484 					&result);
2485 	if (!NT_STATUS_IS_OK(status)) {
2486 		goto done;
2487 	}
2488 	if (!NT_STATUS_IS_OK(result)) {
2489 		status = result;
2490 		goto done;
2491 	}
2492 
2493 	/* Get handle on user */
2494 
2495 	{
2496 		struct samr_Ids user_rids, name_types;
2497 		struct lsa_String lsa_acct_name;
2498 
2499 		init_lsa_String(&lsa_acct_name, argv[1]);
2500 
2501 		status = dcerpc_samr_LookupNames(b, mem_ctx,
2502 						 &domain_pol,
2503 						 1,
2504 						 &lsa_acct_name,
2505 						 &user_rids,
2506 						 &name_types,
2507 						 &result);
2508 		if (!NT_STATUS_IS_OK(status)) {
2509 			goto done;
2510 		}
2511 		if (!NT_STATUS_IS_OK(result)) {
2512 			status = result;
2513 			goto done;
2514 		}
2515 		if (user_rids.count != 1) {
2516 			status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2517 			goto done;
2518 		}
2519 		if (name_types.count != 1) {
2520 			status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2521 			goto done;
2522 		}
2523 
2524 		status = dcerpc_samr_OpenUser(b, mem_ctx,
2525 					      &domain_pol,
2526 					      access_mask,
2527 					      user_rids.ids[0],
2528 					      &user_pol,
2529 					      &result);
2530 		if (!NT_STATUS_IS_OK(status)) {
2531 			goto done;
2532 		}
2533 		if (!NT_STATUS_IS_OK(result)) {
2534 			status = result;
2535 			goto done;
2536 		}
2537 	}
2538 
2539 	/* Delete user */
2540 
2541 	status = dcerpc_samr_DeleteUser(b, mem_ctx,
2542 					&user_pol,
2543 					&result);
2544 	if (!NT_STATUS_IS_OK(status)) {
2545 		goto done;
2546 	}
2547 	if (!NT_STATUS_IS_OK(result)) {
2548 		status = result;
2549 		goto done;
2550 	}
2551 
2552 	/* Display results */
2553 
2554 	dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2555 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2556 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2557 
2558  done:
2559 	return status;
2560 }
2561 
2562 /**********************************************************************
2563  * Query user security object
2564  */
cmd_samr_query_sec_obj(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2565 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
2566                                     TALLOC_CTX *mem_ctx,
2567                                     int argc, const char **argv)
2568 {
2569 	struct policy_handle connect_pol, domain_pol, user_pol, *pol;
2570 	NTSTATUS status, result;
2571 	uint32_t sec_info = SECINFO_DACL;
2572 	uint32_t user_rid = 0;
2573 	TALLOC_CTX *ctx = NULL;
2574 	struct sec_desc_buf *sec_desc_buf=NULL;
2575 	bool domain = False;
2576 	struct dcerpc_binding_handle *b = cli->binding_handle;
2577 
2578 	ctx=talloc_init("cmd_samr_query_sec_obj");
2579 
2580 	if ((argc < 1) || (argc > 3)) {
2581 		printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2582 		printf("\tSpecify rid for security on user, -d for security on domain\n");
2583 		talloc_destroy(ctx);
2584 		return NT_STATUS_OK;
2585 	}
2586 
2587 	if (argc > 1) {
2588 		if (strcmp(argv[1], "-d") == 0)
2589 			domain = True;
2590 		else
2591 			sscanf(argv[1], "%i", &user_rid);
2592 	}
2593 
2594 	if (argc == 3) {
2595 		sec_info = atoi(argv[2]);
2596 	}
2597 
2598 	status = rpccli_try_samr_connects(cli, mem_ctx,
2599 					  MAXIMUM_ALLOWED_ACCESS,
2600 					  &connect_pol);
2601 	if (!NT_STATUS_IS_OK(status)) {
2602 		goto done;
2603 	}
2604 
2605 	if (domain || user_rid) {
2606 		status = dcerpc_samr_OpenDomain(b, mem_ctx,
2607 						&connect_pol,
2608 						MAXIMUM_ALLOWED_ACCESS,
2609 						&domain_sid,
2610 						&domain_pol,
2611 						&result);
2612 		if (!NT_STATUS_IS_OK(status)) {
2613 			goto done;
2614 		}
2615 		if (!NT_STATUS_IS_OK(result)) {
2616 			status = result;
2617 			goto done;
2618 		}
2619 	}
2620 
2621 	if (user_rid) {
2622 		status = dcerpc_samr_OpenUser(b, mem_ctx,
2623 					      &domain_pol,
2624 					      MAXIMUM_ALLOWED_ACCESS,
2625 					      user_rid,
2626 					      &user_pol,
2627 					      &result);
2628 		if (!NT_STATUS_IS_OK(status)) {
2629 			goto done;
2630 		}
2631 		if (!NT_STATUS_IS_OK(result)) {
2632 			status = result;
2633 			goto done;
2634 		}
2635 	}
2636 
2637 	/* Pick which query pol to use */
2638 
2639 	pol = &connect_pol;
2640 
2641 	if (domain)
2642 		pol = &domain_pol;
2643 
2644 	if (user_rid)
2645 		pol = &user_pol;
2646 
2647 	/* Query SAM security object */
2648 
2649 	status = dcerpc_samr_QuerySecurity(b, mem_ctx,
2650 					   pol,
2651 					   sec_info,
2652 					   &sec_desc_buf,
2653 					   &result);
2654 	if (!NT_STATUS_IS_OK(status)) {
2655 		goto done;
2656 	}
2657 	if (!NT_STATUS_IS_OK(result)) {
2658 		status = result;
2659 		goto done;
2660 	}
2661 
2662 	display_sec_desc(sec_desc_buf->sd);
2663 
2664 	dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2665 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2666 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2667 done:
2668 	talloc_destroy(ctx);
2669 	return status;
2670 }
2671 
cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2672 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
2673 					   TALLOC_CTX *mem_ctx,
2674 					   int argc, const char **argv)
2675 {
2676 	NTSTATUS status, result;
2677 	struct policy_handle connect_pol, domain_pol, user_pol;
2678 	struct samr_PwInfo info;
2679 	uint32_t rid;
2680 	struct dcerpc_binding_handle *b = cli->binding_handle;
2681 
2682 	if (argc != 2) {
2683 		printf("Usage: %s rid\n", argv[0]);
2684 		return NT_STATUS_OK;
2685 	}
2686 
2687 	sscanf(argv[1], "%i", &rid);
2688 
2689 	status = rpccli_try_samr_connects(cli, mem_ctx,
2690 					  MAXIMUM_ALLOWED_ACCESS,
2691 					  &connect_pol);
2692 	if (!NT_STATUS_IS_OK(status)) {
2693 		goto done;
2694 	}
2695 
2696 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
2697 					&connect_pol,
2698 					MAXIMUM_ALLOWED_ACCESS,
2699 					&domain_sid,
2700 					&domain_pol,
2701 					&result);
2702 	if (!NT_STATUS_IS_OK(status)) {
2703 		goto done;
2704 	}
2705 	if (!NT_STATUS_IS_OK(result)) {
2706 		status = result;
2707 		goto done;
2708 	}
2709 
2710 	status = dcerpc_samr_OpenUser(b, mem_ctx,
2711 				      &domain_pol,
2712 				      MAXIMUM_ALLOWED_ACCESS,
2713 				      rid,
2714 				      &user_pol,
2715 				      &result);
2716 	if (!NT_STATUS_IS_OK(status)) {
2717 		goto done;
2718 	}
2719 	if (!NT_STATUS_IS_OK(result)) {
2720 		status = result;
2721 		goto done;
2722 	}
2723 
2724 	status = dcerpc_samr_GetUserPwInfo(b, mem_ctx,
2725 					   &user_pol,
2726 					   &info,
2727 					   &result);
2728 	if (!NT_STATUS_IS_OK(status)) {
2729 		goto done;
2730 	}
2731 	status = result;
2732 	if (NT_STATUS_IS_OK(result)) {
2733 		printf("%s\n",
2734 			NDR_PRINT_STRUCT_STRING(mem_ctx,
2735 				samr_PwInfo, &info));
2736 	}
2737 
2738  done:
2739 	dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2740 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2741 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2742 
2743 	return status;
2744 }
2745 
cmd_samr_get_dom_pwinfo(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2746 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2747 					TALLOC_CTX *mem_ctx,
2748 					int argc, const char **argv)
2749 {
2750 	NTSTATUS status, result;
2751 	struct lsa_String domain_name;
2752 	struct samr_PwInfo info;
2753 	struct dcerpc_binding_handle *b = cli->binding_handle;
2754 
2755 	if (argc < 1 || argc > 3) {
2756 		printf("Usage: %s <domain>\n", argv[0]);
2757 		return NT_STATUS_OK;
2758 	}
2759 
2760 	init_lsa_String(&domain_name, argv[1]);
2761 
2762 	status = dcerpc_samr_GetDomPwInfo(b, mem_ctx,
2763 					  &domain_name,
2764 					  &info,
2765 					  &result);
2766 	if (!NT_STATUS_IS_OK(status)) {
2767 		return status;
2768 	}
2769 	if (NT_STATUS_IS_OK(result)) {
2770 		printf("min_password_length: %d\n", info.min_password_length);
2771 		display_password_properties(info.password_properties);
2772 	}
2773 
2774 	return result;
2775 }
2776 
2777 /* Look up domain name */
2778 
cmd_samr_lookup_domain(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2779 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
2780 				       TALLOC_CTX *mem_ctx,
2781 				       int argc, const char **argv)
2782 {
2783 	struct policy_handle connect_pol, domain_pol;
2784 	NTSTATUS status, result;
2785 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2786 	struct lsa_String domain_name;
2787 	struct dom_sid *sid = NULL;
2788 	struct dcerpc_binding_handle *b = cli->binding_handle;
2789 
2790 	if (argc != 2) {
2791 		printf("Usage: %s domain_name\n", argv[0]);
2792 		return NT_STATUS_OK;
2793 	}
2794 
2795 	init_lsa_String(&domain_name, argv[1]);
2796 
2797 	status = rpccli_try_samr_connects(cli, mem_ctx,
2798 					  access_mask,
2799 					  &connect_pol);
2800 	if (!NT_STATUS_IS_OK(status)) {
2801 		goto done;
2802 	}
2803 
2804 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
2805 					&connect_pol,
2806 					access_mask,
2807 					&domain_sid,
2808 					&domain_pol,
2809 					&result);
2810 	if (!NT_STATUS_IS_OK(status)) {
2811 		goto done;
2812 	}
2813 	if (!NT_STATUS_IS_OK(result)) {
2814 		status = result;
2815 		goto done;
2816 	}
2817 
2818 	status = dcerpc_samr_LookupDomain(b, mem_ctx,
2819 					  &connect_pol,
2820 					  &domain_name,
2821 					  &sid,
2822 					  &result);
2823 	if (!NT_STATUS_IS_OK(status)) {
2824 		goto done;
2825 	}
2826 	if (!NT_STATUS_IS_OK(result)) {
2827 		status = result;
2828 		goto done;
2829 	}
2830 
2831 	if (NT_STATUS_IS_OK(result)) {
2832 		struct dom_sid_buf sid_str;
2833 		printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2834 		       argv[1],
2835 		       dom_sid_str_buf(sid, &sid_str));
2836 	}
2837 
2838 	dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2839 	dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2840 done:
2841 	return status;
2842 }
2843 
2844 /* Change user password */
2845 
cmd_samr_chgpasswd(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2846 static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli,
2847 				   TALLOC_CTX *mem_ctx,
2848 				   int argc, const char **argv)
2849 {
2850 	struct policy_handle connect_pol;
2851 	struct policy_handle domain_pol = { 0, };
2852 	struct policy_handle user_pol = { 0, };
2853 	NTSTATUS status, result;
2854 	const char *user, *oldpass, *newpass;
2855 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2856 	struct samr_Ids rids, types;
2857 	struct lsa_String lsa_acct_name;
2858 	struct dcerpc_binding_handle *b = cli->binding_handle;
2859 
2860 	if (argc < 3) {
2861 		printf("Usage: %s username oldpass newpass\n", argv[0]);
2862 		return NT_STATUS_INVALID_PARAMETER;
2863 	}
2864 
2865 	user = argv[1];
2866 	oldpass = argv[2];
2867 	newpass = argv[3];
2868 
2869 	/* Get sam policy handle */
2870 
2871 	status = rpccli_try_samr_connects(cli, mem_ctx,
2872 					  MAXIMUM_ALLOWED_ACCESS,
2873 					  &connect_pol);
2874 	if (!NT_STATUS_IS_OK(status)) {
2875 		goto done;
2876 	}
2877 
2878 	/* Get domain policy handle */
2879 
2880 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
2881 					&connect_pol,
2882 					access_mask,
2883 					&domain_sid,
2884 					&domain_pol,
2885 					&result);
2886 	if (!NT_STATUS_IS_OK(status)) {
2887 		goto done;
2888 	}
2889 	if (!NT_STATUS_IS_OK(result)) {
2890 		status = result;
2891 		goto done;
2892 	}
2893 
2894 	init_lsa_String(&lsa_acct_name, user);
2895 
2896 	status = dcerpc_samr_LookupNames(b, mem_ctx,
2897 					 &domain_pol,
2898 					 1,
2899 					 &lsa_acct_name,
2900 					 &rids,
2901 					 &types,
2902 					 &result);
2903 	if (!NT_STATUS_IS_OK(status)) {
2904 		goto done;
2905 	}
2906 	if (!NT_STATUS_IS_OK(result)) {
2907 		status = result;
2908 		goto done;
2909 	}
2910 	if (rids.count != 1) {
2911 		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2912 		goto done;
2913 	}
2914 	if (types.count != 1) {
2915 		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2916 		goto done;
2917 	}
2918 
2919 	status = dcerpc_samr_OpenUser(b, mem_ctx,
2920 				      &domain_pol,
2921 				      access_mask,
2922 				      rids.ids[0],
2923 				      &user_pol,
2924 				      &result);
2925 	if (!NT_STATUS_IS_OK(status)) {
2926 		goto done;
2927 	}
2928 	if (!NT_STATUS_IS_OK(result)) {
2929 		status = result;
2930 		goto done;
2931 	}
2932 
2933 	/* Change user password */
2934 	status = rpccli_samr_chgpasswd_user(cli, mem_ctx,
2935 					    &user_pol,
2936 					    newpass,
2937 					    oldpass);
2938 	if (!NT_STATUS_IS_OK(status)) {
2939 		goto done;
2940 	}
2941 
2942  done:
2943 	if (is_valid_policy_hnd(&user_pol)) {
2944 		dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2945 	}
2946 	if (is_valid_policy_hnd(&domain_pol)) {
2947 		dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2948 	}
2949 	if (is_valid_policy_hnd(&connect_pol)) {
2950 		dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2951 	}
2952 
2953 	return status;
2954 }
2955 
2956 
2957 /* Change user password */
2958 
cmd_samr_chgpasswd2(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)2959 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2960 				    TALLOC_CTX *mem_ctx,
2961 				    int argc, const char **argv)
2962 {
2963 	struct policy_handle connect_pol, domain_pol;
2964 	NTSTATUS status, result;
2965 	const char *user, *oldpass, *newpass;
2966 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2967 	struct dcerpc_binding_handle *b = cli->binding_handle;
2968 
2969 	if (argc < 3) {
2970 		printf("Usage: %s username oldpass newpass\n", argv[0]);
2971 		return NT_STATUS_INVALID_PARAMETER;
2972 	}
2973 
2974 	user = argv[1];
2975 	oldpass = argv[2];
2976 	newpass = argv[3];
2977 
2978 	/* Get sam policy handle */
2979 
2980 	status = rpccli_try_samr_connects(cli, mem_ctx,
2981 					  MAXIMUM_ALLOWED_ACCESS,
2982 					  &connect_pol);
2983 	if (!NT_STATUS_IS_OK(status)) {
2984 		goto done;
2985 	}
2986 
2987 	/* Get domain policy handle */
2988 
2989 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
2990 					&connect_pol,
2991 					access_mask,
2992 					&domain_sid,
2993 					&domain_pol,
2994 					&result);
2995 	if (!NT_STATUS_IS_OK(status)) {
2996 		goto done;
2997 	}
2998 	if (!NT_STATUS_IS_OK(result)) {
2999 		status = result;
3000 		goto done;
3001 	}
3002 
3003 	/* Change user password */
3004 	status = rpccli_samr_chgpasswd_user2(cli, mem_ctx, user, newpass, oldpass);
3005 
3006 	if (!NT_STATUS_IS_OK(status)) {
3007 		goto done;
3008 	}
3009 
3010 	status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
3011 	if (!NT_STATUS_IS_OK(status)) goto done;
3012 
3013 	status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
3014 	if (!NT_STATUS_IS_OK(status)) goto done;
3015 
3016  done:
3017 	return status;
3018 }
3019 
3020 
3021 /* Change user password */
3022 
cmd_samr_chgpasswd3(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)3023 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
3024 				    TALLOC_CTX *mem_ctx,
3025 				    int argc, const char **argv)
3026 {
3027 	struct policy_handle connect_pol, domain_pol;
3028 	NTSTATUS status, result;
3029 	const char *user, *oldpass, *newpass;
3030 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
3031 	struct samr_DomInfo1 *info = NULL;
3032 	struct userPwdChangeFailureInformation *reject = NULL;
3033 	struct dcerpc_binding_handle *b = cli->binding_handle;
3034 
3035 	if (argc < 3) {
3036 		printf("Usage: %s username oldpass newpass\n", argv[0]);
3037 		return NT_STATUS_INVALID_PARAMETER;
3038 	}
3039 
3040 	user = argv[1];
3041 	oldpass = argv[2];
3042 	newpass = argv[3];
3043 
3044 	/* Get sam policy handle */
3045 
3046 	status = rpccli_try_samr_connects(cli, mem_ctx,
3047 					  MAXIMUM_ALLOWED_ACCESS,
3048 					  &connect_pol);
3049 	if (!NT_STATUS_IS_OK(status)) {
3050 		goto done;
3051 	}
3052 
3053 	/* Get domain policy handle */
3054 
3055 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
3056 					&connect_pol,
3057 					access_mask,
3058 					&domain_sid,
3059 					&domain_pol,
3060 					&result);
3061 	if (!NT_STATUS_IS_OK(status)) {
3062 		goto done;
3063 	}
3064 	if (!NT_STATUS_IS_OK(result)) {
3065 		status = result;
3066 		goto done;
3067 	}
3068 
3069 	/* Change user password */
3070 	status = rpccli_samr_chgpasswd_user3(cli, mem_ctx,
3071 					     user,
3072 					     newpass,
3073 					     oldpass,
3074 					     &info,
3075 					     &reject);
3076 	if (!NT_STATUS_IS_OK(status)) {
3077 		goto done;
3078 	}
3079 
3080 	if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
3081 
3082 		display_sam_dom_info_1(info);
3083 
3084 		switch (reject->extendedFailureReason) {
3085 			case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT:
3086 				d_printf("SAM_PWD_CHANGE_PASSWORD_TOO_SHORT\n");
3087 				break;
3088 			case SAM_PWD_CHANGE_PWD_IN_HISTORY:
3089 				d_printf("SAM_PWD_CHANGE_PWD_IN_HISTORY\n");
3090 				break;
3091 			case SAM_PWD_CHANGE_NOT_COMPLEX:
3092 				d_printf("SAM_PWD_CHANGE_NOT_COMPLEX\n");
3093 				break;
3094 			default:
3095 				d_printf("unknown reject reason: %d\n",
3096 					reject->extendedFailureReason);
3097 				break;
3098 		}
3099 	}
3100 
3101 	if (!NT_STATUS_IS_OK(result)) {
3102 		status = result;
3103 		goto done;
3104 	}
3105 
3106 	status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
3107 	if (!NT_STATUS_IS_OK(status)) goto done;
3108 
3109 	status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
3110 	if (!NT_STATUS_IS_OK(status)) goto done;
3111 
3112  done:
3113 	return status;
3114 }
3115 
cmd_samr_setuserinfo_int(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv,int opcode)3116 static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli,
3117 					 TALLOC_CTX *mem_ctx,
3118 					 int argc, const char **argv,
3119 					 int opcode)
3120 {
3121 	struct policy_handle connect_pol, domain_pol, user_pol;
3122 	NTSTATUS status, result;
3123 	const char *user, *param;
3124 	uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
3125 	uint32_t level;
3126 	uint32_t user_rid;
3127 	union samr_UserInfo info;
3128 	struct samr_CryptPassword pwd_buf;
3129 	struct samr_CryptPasswordEx pwd_buf_ex;
3130 	uint8_t nt_hash[16];
3131 	uint8_t lm_hash[16];
3132 	DATA_BLOB session_key;
3133 	uint8_t password_expired = 0;
3134 	struct dcerpc_binding_handle *b = cli->binding_handle;
3135 	TALLOC_CTX *frame = NULL;
3136 	int rc;
3137 
3138 	if (argc < 4) {
3139 		printf("Usage: %s username level password [password_expired]\n",
3140 			argv[0]);
3141 		return NT_STATUS_INVALID_PARAMETER;
3142 	}
3143 
3144 	frame = talloc_stackframe();
3145 
3146 	user = argv[1];
3147 	level = atoi(argv[2]);
3148 	param = argv[3];
3149 
3150 	if (argc >= 5) {
3151 		password_expired = atoi(argv[4]);
3152 	}
3153 
3154 	status = cli_get_session_key(frame, cli, &session_key);
3155 	if (!NT_STATUS_IS_OK(status)) {
3156 		goto done;
3157 	}
3158 
3159 	status = init_samr_CryptPassword(param, &session_key, &pwd_buf);
3160 	if (!NT_STATUS_IS_OK(status)) {
3161 		goto done;
3162 	}
3163 	status = init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex);
3164 	if (!NT_STATUS_IS_OK(status)) {
3165 		goto done;
3166 	}
3167 	nt_lm_owf_gen(param, nt_hash, lm_hash);
3168 
3169 	switch (level) {
3170 	case 18:
3171 		{
3172 			DATA_BLOB in,out;
3173 			in = data_blob_const(nt_hash, 16);
3174 			out = data_blob_talloc_zero(frame, 16);
3175 			if (out.data == NULL) {
3176 				status = NT_STATUS_NO_MEMORY;
3177 				goto done;
3178 			}
3179 			rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
3180 			if (rc != 0) {
3181 				status = gnutls_error_to_ntstatus(rc,
3182 								  NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
3183 			}
3184 			memcpy(nt_hash, out.data, out.length);
3185 		}
3186 		{
3187 			DATA_BLOB in,out;
3188 			in = data_blob_const(lm_hash, 16);
3189 			out = data_blob_talloc_zero(frame, 15);
3190 			if (out.data == NULL) {
3191 				status = NT_STATUS_NO_MEMORY;
3192 				goto done;
3193 			}
3194 			rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
3195 			if (rc != 0) {
3196 				status = gnutls_error_to_ntstatus(rc,
3197 								  NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
3198 			}
3199 			memcpy(lm_hash, out.data, out.length);
3200 		}
3201 
3202 		memcpy(info.info18.nt_pwd.hash, nt_hash, 16);
3203 		memcpy(info.info18.lm_pwd.hash, lm_hash, 16);
3204 		info.info18.nt_pwd_active	= true;
3205 		info.info18.lm_pwd_active	= true;
3206 		info.info18.password_expired	= password_expired;
3207 
3208 		break;
3209 	case 21:
3210 		ZERO_STRUCT(info.info21);
3211 
3212 		info.info21.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3213 					     SAMR_FIELD_LM_PASSWORD_PRESENT;
3214 		if (argc >= 5) {
3215 			info.info21.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3216 			info.info21.password_expired = password_expired;
3217 		}
3218 
3219 		info.info21.lm_password_set = true;
3220 		info.info21.lm_owf_password.length = 16;
3221 		info.info21.lm_owf_password.size = 16;
3222 
3223 		info.info21.nt_password_set = true;
3224 		info.info21.nt_owf_password.length = 16;
3225 		info.info21.nt_owf_password.size = 16;
3226 
3227 		{
3228 			DATA_BLOB in,out;
3229 			in = data_blob_const(nt_hash, 16);
3230 			out = data_blob_talloc_zero(frame, 16);
3231 			if (out.data == NULL) {
3232 				status = NT_STATUS_NO_MEMORY;
3233 				goto done;
3234 			}
3235 			rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
3236 			if (rc != 0) {
3237 				status = gnutls_error_to_ntstatus(rc,
3238 								  NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
3239 			}
3240 			info.info21.nt_owf_password.array =
3241 				(uint16_t *)talloc_memdup(frame, out.data, 16);
3242 		}
3243 		{
3244 			DATA_BLOB in,out;
3245 			in = data_blob_const(lm_hash, 16);
3246 			out = data_blob_talloc_zero(frame, 16);
3247 			rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
3248 			if (rc != 0) {
3249 				status = gnutls_error_to_ntstatus(rc,
3250 								  NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
3251 			}
3252 			info.info21.lm_owf_password.array =
3253 				(uint16_t *)talloc_memdup(frame, out.data, 16);
3254 			if (out.data == NULL) {
3255 				status = NT_STATUS_NO_MEMORY;
3256 				goto done;
3257 			}
3258 		}
3259 
3260 		break;
3261 	case 23:
3262 		ZERO_STRUCT(info.info23);
3263 
3264 		info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3265 						  SAMR_FIELD_LM_PASSWORD_PRESENT;
3266 		if (argc >= 5) {
3267 			info.info23.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3268 			info.info23.info.password_expired = password_expired;
3269 		}
3270 
3271 		info.info23.password = pwd_buf;
3272 
3273 		break;
3274 	case 24:
3275 		info.info24.password		= pwd_buf;
3276 		info.info24.password_expired	= password_expired;
3277 
3278 		break;
3279 	case 25:
3280 		ZERO_STRUCT(info.info25);
3281 
3282 		info.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3283 						  SAMR_FIELD_LM_PASSWORD_PRESENT;
3284 		if (argc >= 5) {
3285 			info.info25.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3286 			info.info25.info.password_expired = password_expired;
3287 		}
3288 
3289 		info.info25.password = pwd_buf_ex;
3290 
3291 		break;
3292 	case 26:
3293 		info.info26.password		= pwd_buf_ex;
3294 		info.info26.password_expired	= password_expired;
3295 
3296 		break;
3297 	default:
3298 		return NT_STATUS_INVALID_INFO_CLASS;
3299 	}
3300 
3301 	/* Get sam policy handle */
3302 
3303 	status = rpccli_try_samr_connects(cli, frame,
3304 					  MAXIMUM_ALLOWED_ACCESS,
3305 					  &connect_pol);
3306 	if (!NT_STATUS_IS_OK(status)) {
3307 		goto done;
3308 	}
3309 
3310 	/* Get domain policy handle */
3311 
3312 	status = dcerpc_samr_OpenDomain(b, frame,
3313 					&connect_pol,
3314 					access_mask,
3315 					&domain_sid,
3316 					&domain_pol,
3317 					&result);
3318 
3319 	if (!NT_STATUS_IS_OK(status))
3320 		goto done;
3321 	if (!NT_STATUS_IS_OK(result)) {
3322 		status = result;
3323 		goto done;
3324 	}
3325 
3326 	user_rid = strtol(user, NULL, 0);
3327 	if (user_rid) {
3328 		status = dcerpc_samr_OpenUser(b, frame,
3329 					      &domain_pol,
3330 					      access_mask,
3331 					      user_rid,
3332 					      &user_pol,
3333 					      &result);
3334 		if (!NT_STATUS_IS_OK(status)) {
3335 			goto done;
3336 		}
3337 
3338 		status = result;
3339 	}
3340 
3341 	if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) ||
3342 	    (user_rid == 0)) {
3343 
3344 		/* Probably this was a user name, try lookupnames */
3345 		struct samr_Ids rids, types;
3346 		struct lsa_String lsa_acct_name;
3347 
3348 		init_lsa_String(&lsa_acct_name, user);
3349 
3350 		status = dcerpc_samr_LookupNames(b, frame,
3351 						 &domain_pol,
3352 						 1,
3353 						 &lsa_acct_name,
3354 						 &rids,
3355 						 &types,
3356 						 &result);
3357 		if (!NT_STATUS_IS_OK(status)) {
3358 			return status;
3359 		}
3360 		if (!NT_STATUS_IS_OK(result)) {
3361 			return result;
3362 		}
3363 		if (rids.count != 1) {
3364 			return NT_STATUS_INVALID_NETWORK_RESPONSE;
3365 		}
3366 		if (types.count != 1) {
3367 			return NT_STATUS_INVALID_NETWORK_RESPONSE;
3368 		}
3369 
3370 		status = dcerpc_samr_OpenUser(b, frame,
3371 					      &domain_pol,
3372 					      access_mask,
3373 					      rids.ids[0],
3374 					      &user_pol,
3375 					      &result);
3376 		if (!NT_STATUS_IS_OK(status)) {
3377 			return status;
3378 		}
3379 		if (!NT_STATUS_IS_OK(result)) {
3380 			return result;
3381 		}
3382 	}
3383 
3384 	switch (opcode) {
3385 	case NDR_SAMR_SETUSERINFO:
3386 		status = dcerpc_samr_SetUserInfo(b, frame,
3387 						 &user_pol,
3388 						 level,
3389 						 &info,
3390 						 &result);
3391 		break;
3392 	case NDR_SAMR_SETUSERINFO2:
3393 		status = dcerpc_samr_SetUserInfo2(b, frame,
3394 						  &user_pol,
3395 						  level,
3396 						  &info,
3397 						  &result);
3398 		break;
3399 	default:
3400 		return NT_STATUS_INVALID_PARAMETER;
3401 	}
3402 	if (!NT_STATUS_IS_OK(status)) {
3403 		DEBUG(0,("status: %s\n", nt_errstr(status)));
3404 		goto done;
3405 	}
3406 	if (!NT_STATUS_IS_OK(result)) {
3407 		status = result;
3408 		DEBUG(0,("result: %s\n", nt_errstr(status)));
3409 		goto done;
3410 	}
3411 
3412 	status = NT_STATUS_OK;
3413  done:
3414 	TALLOC_FREE(frame);
3415 	return status;
3416 }
3417 
cmd_samr_setuserinfo(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)3418 static NTSTATUS cmd_samr_setuserinfo(struct rpc_pipe_client *cli,
3419 				     TALLOC_CTX *mem_ctx,
3420 				     int argc, const char **argv)
3421 {
3422 	return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
3423 					NDR_SAMR_SETUSERINFO);
3424 }
3425 
cmd_samr_setuserinfo2(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)3426 static NTSTATUS cmd_samr_setuserinfo2(struct rpc_pipe_client *cli,
3427 				      TALLOC_CTX *mem_ctx,
3428 				      int argc, const char **argv)
3429 {
3430 	return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
3431 					NDR_SAMR_SETUSERINFO2);
3432 }
3433 
cmd_samr_get_dispinfo_idx(struct rpc_pipe_client * cli,TALLOC_CTX * mem_ctx,int argc,const char ** argv)3434 static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
3435 					  TALLOC_CTX *mem_ctx,
3436 					  int argc, const char **argv)
3437 {
3438 	NTSTATUS status, result;
3439 	struct policy_handle connect_handle;
3440 	struct policy_handle domain_handle = { 0, };
3441 	uint16_t level = 1;
3442 	struct lsa_String name;
3443 	uint32_t idx = 0;
3444 	struct dcerpc_binding_handle *b = cli->binding_handle;
3445 
3446 	if (argc < 2 || argc > 3) {
3447 		printf("Usage: %s name level\n", argv[0]);
3448 		return NT_STATUS_INVALID_PARAMETER;
3449 	}
3450 
3451 	init_lsa_String(&name, argv[1]);
3452 
3453 	if (argc == 3) {
3454 		level = atoi(argv[2]);
3455 	}
3456 
3457 	status = rpccli_try_samr_connects(cli, mem_ctx,
3458 					  SEC_FLAG_MAXIMUM_ALLOWED,
3459 					  &connect_handle);
3460 	if (!NT_STATUS_IS_OK(status)) {
3461 		goto done;
3462 	}
3463 
3464 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
3465 					&connect_handle,
3466 					SEC_FLAG_MAXIMUM_ALLOWED,
3467 					&domain_sid,
3468 					&domain_handle,
3469 					&result);
3470 	if (!NT_STATUS_IS_OK(status)) {
3471 		goto done;
3472 	}
3473 	if (!NT_STATUS_IS_OK(result)) {
3474 		status = result;
3475 		goto done;
3476 	}
3477 
3478 	status = dcerpc_samr_GetDisplayEnumerationIndex(b, mem_ctx,
3479 							&domain_handle,
3480 							level,
3481 							&name,
3482 							&idx,
3483 							&result);
3484 	if (!NT_STATUS_IS_OK(status)) {
3485 		goto done;
3486 	}
3487 
3488 	status = result;
3489 
3490 	if (NT_STATUS_IS_OK(status) ||
3491 	    NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
3492 		printf("idx: %d (0x%08x)\n", idx, idx);
3493 	}
3494  done:
3495 
3496 	if (is_valid_policy_hnd(&domain_handle)) {
3497 		dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
3498 	}
3499 	if (is_valid_policy_hnd(&connect_handle)) {
3500 		dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
3501 	}
3502 
3503 	return status;
3504 
3505 }
3506 /* List of commands exported by this module */
3507 
3508 struct cmd_set samr_commands[] = {
3509 
3510 	{
3511 		.name = "SAMR",
3512 	},
3513 
3514 	{
3515 		.name               = "queryuser",
3516 		.returntype         = RPC_RTYPE_NTSTATUS,
3517 		.ntfn               = cmd_samr_query_user,
3518 		.wfn                = NULL,
3519 		.table              = &ndr_table_samr,
3520 		.rpc_pipe           = NULL,
3521 		.description        = "Query user info",
3522 		.usage              = "",
3523 	},
3524 	{
3525 		.name               = "querygroup",
3526 		.returntype         = RPC_RTYPE_NTSTATUS,
3527 		.ntfn               = cmd_samr_query_group,
3528 		.wfn                = NULL,
3529 		.table              = &ndr_table_samr,
3530 		.rpc_pipe           = NULL,
3531 		.description        = "Query group info",
3532 		.usage              = "",
3533 	},
3534 	{
3535 		.name               = "queryusergroups",
3536 		.returntype         = RPC_RTYPE_NTSTATUS,
3537 		.ntfn               = cmd_samr_query_usergroups,
3538 		.wfn                = NULL,
3539 		.table              = &ndr_table_samr,
3540 		.rpc_pipe           = NULL,
3541 		.description        = "Query user groups",
3542 		.usage              = "",
3543 	},
3544 	{
3545 		.name               = "queryuseraliases",
3546 		.returntype         = RPC_RTYPE_NTSTATUS,
3547 		.ntfn               = cmd_samr_query_useraliases,
3548 		.wfn                = NULL,
3549 		.table              = &ndr_table_samr,
3550 		.rpc_pipe           = NULL,
3551 		.description        = "Query user aliases",
3552 		.usage              = "",
3553 	},
3554 	{
3555 		.name               = "querygroupmem",
3556 		.returntype         = RPC_RTYPE_NTSTATUS,
3557 		.ntfn               = cmd_samr_query_groupmem,
3558 		.wfn                = NULL,
3559 		.table              = &ndr_table_samr,
3560 		.rpc_pipe           = NULL,
3561 		.description        = "Query group membership",
3562 		.usage              = "",
3563 	},
3564 	{
3565 		.name               = "queryaliasmem",
3566 		.returntype         = RPC_RTYPE_NTSTATUS,
3567 		.ntfn               = cmd_samr_query_aliasmem,
3568 		.wfn                = NULL,
3569 		.table              = &ndr_table_samr,
3570 		.rpc_pipe           = NULL,
3571 		.description        = "Query alias membership",
3572 		.usage              = "",
3573 	},
3574 	{
3575 		.name               = "queryaliasinfo",
3576 		.returntype         = RPC_RTYPE_NTSTATUS,
3577 		.ntfn               = cmd_samr_query_aliasinfo,
3578 		.wfn                = NULL,
3579 		.table              = &ndr_table_samr,
3580 		.rpc_pipe           = NULL,
3581 		.description        = "Query alias info",
3582 		.usage              = "",
3583 	},
3584 	{
3585 		.name               = "deletealias",
3586 		.returntype         = RPC_RTYPE_NTSTATUS,
3587 		.ntfn               = cmd_samr_delete_alias,
3588 		.wfn                = NULL,
3589 		.table              = &ndr_table_samr,
3590 		.rpc_pipe           = NULL,
3591 		.description        = "Delete an alias",
3592 		.usage              = "",
3593 	},
3594 	{
3595 		.name               = "querydispinfo",
3596 		.returntype         = RPC_RTYPE_NTSTATUS,
3597 		.ntfn               = cmd_samr_query_dispinfo,
3598 		.wfn                = NULL,
3599 		.table              = &ndr_table_samr,
3600 		.rpc_pipe           = NULL,
3601 		.description        = "Query display info",
3602 		.usage              = "",
3603 	},
3604 	{
3605 		.name               = "querydispinfo2",
3606 		.returntype         = RPC_RTYPE_NTSTATUS,
3607 		.ntfn               = cmd_samr_query_dispinfo2,
3608 		.wfn                = NULL,
3609 		.table              = &ndr_table_samr,
3610 		.rpc_pipe           = NULL,
3611 		.description        = "Query display info",
3612 		.usage              = "",
3613 	},
3614 	{
3615 		.name               = "querydispinfo3",
3616 		.returntype         = RPC_RTYPE_NTSTATUS,
3617 		.ntfn               = cmd_samr_query_dispinfo3,
3618 		.wfn                = NULL,
3619 		.table              = &ndr_table_samr,
3620 		.rpc_pipe           = NULL,
3621 		.description        = "Query display info",
3622 		.usage              = "",
3623 	},
3624 	{
3625 		.name               = "querydominfo",
3626 		.returntype         = RPC_RTYPE_NTSTATUS,
3627 		.ntfn               = cmd_samr_query_dominfo,
3628 		.wfn                = NULL,
3629 		.table              = &ndr_table_samr,
3630 		.rpc_pipe           = NULL,
3631 		.description        = "Query domain info",
3632 		.usage              = "",
3633 	},
3634 	{
3635 		.name               = "enumdomusers",
3636 		.returntype         = RPC_RTYPE_NTSTATUS,
3637 		.ntfn               = cmd_samr_enum_dom_users,
3638 		.wfn                = NULL,
3639 		.table              = &ndr_table_samr,
3640 		.rpc_pipe           = NULL,
3641 		.description        = "Enumerate domain users",
3642 		.usage              = "",
3643 	},
3644 	{
3645 		.name               = "enumdomgroups",
3646 		.returntype         = RPC_RTYPE_NTSTATUS,
3647 		.ntfn               = cmd_samr_enum_dom_groups,
3648 		.wfn                = NULL,
3649 		.table              = &ndr_table_samr,
3650 		.rpc_pipe           = NULL,
3651 		.description        = "Enumerate domain groups",
3652 		.usage              = "",
3653 	},
3654 	{
3655 		.name               = "enumalsgroups",
3656 		.returntype         = RPC_RTYPE_NTSTATUS,
3657 		.ntfn               = cmd_samr_enum_als_groups,
3658 		.wfn                = NULL,
3659 		.table              = &ndr_table_samr,
3660 		.rpc_pipe           = NULL,
3661 		.description        = "Enumerate alias groups",
3662 		.usage              = "",
3663 	},
3664 	{
3665 		.name               = "enumdomains",
3666 		.returntype         = RPC_RTYPE_NTSTATUS,
3667 		.ntfn               = cmd_samr_enum_domains,
3668 		.wfn                = NULL,
3669 		.table              = &ndr_table_samr,
3670 		.rpc_pipe           = NULL,
3671 		.description        = "Enumerate domains",
3672 		.usage              = "",
3673 	},
3674 
3675 	{
3676 		.name               = "createdomuser",
3677 		.returntype         = RPC_RTYPE_NTSTATUS,
3678 		.ntfn               = cmd_samr_create_dom_user,
3679 		.wfn                = NULL,
3680 		.table              = &ndr_table_samr,
3681 		.rpc_pipe           = NULL,
3682 		.description        = "Create domain user",
3683 		.usage              = "",
3684 	},
3685 	{
3686 		.name               = "createdomgroup",
3687 		.returntype         = RPC_RTYPE_NTSTATUS,
3688 		.ntfn               = cmd_samr_create_dom_group,
3689 		.wfn                = NULL,
3690 		.table              = &ndr_table_samr,
3691 		.rpc_pipe           = NULL,
3692 		.description        = "Create domain group",
3693 		.usage              = "",
3694 	},
3695 	{
3696 		.name               = "createdomalias",
3697 		.returntype         = RPC_RTYPE_NTSTATUS,
3698 		.ntfn               = cmd_samr_create_dom_alias,
3699 		.wfn                = NULL,
3700 		.table              = &ndr_table_samr,
3701 		.rpc_pipe           = NULL,
3702 		.description        = "Create domain alias",
3703 		.usage              = "",
3704 	},
3705 	{
3706 		.name               = "samlookupnames",
3707 		.returntype         = RPC_RTYPE_NTSTATUS,
3708 		.ntfn               = cmd_samr_lookup_names,
3709 		.wfn                = NULL,
3710 		.table              = &ndr_table_samr,
3711 		.rpc_pipe           = NULL,
3712 		.description        = "Look up names",
3713 		.usage              = "",
3714 	},
3715 	{
3716 		.name               = "samlookuprids",
3717 		.returntype         = RPC_RTYPE_NTSTATUS,
3718 		.ntfn               = cmd_samr_lookup_rids,
3719 		.wfn                = NULL,
3720 		.table              = &ndr_table_samr,
3721 		.rpc_pipe           = NULL,
3722 		.description        = "Look up names",
3723 		.usage              = "",
3724 	},
3725 	{
3726 		.name               = "deletedomgroup",
3727 		.returntype         = RPC_RTYPE_NTSTATUS,
3728 		.ntfn               = cmd_samr_delete_dom_group,
3729 		.wfn                = NULL,
3730 		.table              = &ndr_table_samr,
3731 		.rpc_pipe           = NULL,
3732 		.description        = "Delete domain group",
3733 		.usage              = "",
3734 	},
3735 	{
3736 		.name               = "deletedomuser",
3737 		.returntype         = RPC_RTYPE_NTSTATUS,
3738 		.ntfn               = cmd_samr_delete_dom_user,
3739 		.wfn                = NULL,
3740 		.table              = &ndr_table_samr,
3741 		.rpc_pipe           = NULL,
3742 		.description        = "Delete domain user",
3743 		.usage              = "",
3744 	},
3745 	{
3746 		.name               = "samquerysecobj",
3747 		.returntype         = RPC_RTYPE_NTSTATUS,
3748 		.ntfn               = cmd_samr_query_sec_obj,
3749 		.wfn                = NULL,
3750 		.table              = &ndr_table_samr,
3751 		.rpc_pipe           = NULL,
3752 		.description        = "Query SAMR security object",
3753 		.usage              = "",
3754 	},
3755 	{
3756 		.name               = "getdompwinfo",
3757 		.returntype         = RPC_RTYPE_NTSTATUS,
3758 		.ntfn               = cmd_samr_get_dom_pwinfo,
3759 		.wfn                = NULL,
3760 		.table              = &ndr_table_samr,
3761 		.rpc_pipe           = NULL,
3762 		.description        = "Retrieve domain password info",
3763 		.usage              = "",
3764 	},
3765 	{
3766 		.name               = "getusrdompwinfo",
3767 		.returntype         = RPC_RTYPE_NTSTATUS,
3768 		.ntfn               = cmd_samr_get_usrdom_pwinfo,
3769 		.wfn                = NULL,
3770 		.table              = &ndr_table_samr,
3771 		.rpc_pipe           = NULL,
3772 		.description        = "Retrieve user domain password info",
3773 		.usage              = "",
3774 	},
3775 
3776 	{
3777 		.name               = "lookupdomain",
3778 		.returntype         = RPC_RTYPE_NTSTATUS,
3779 		.ntfn               = cmd_samr_lookup_domain,
3780 		.wfn                = NULL,
3781 		.table              = &ndr_table_samr,
3782 		.rpc_pipe           = NULL,
3783 		.description        = "Lookup Domain Name",
3784 		.usage              = "",
3785 	},
3786 	{
3787 		.name               = "chgpasswd",
3788 		.returntype         = RPC_RTYPE_NTSTATUS,
3789 		.ntfn               = cmd_samr_chgpasswd,
3790 		.wfn                = NULL,
3791 		.table              = &ndr_table_samr,
3792 		.rpc_pipe           = NULL,
3793 		.description        = "Change user password",
3794 		.usage              = "",
3795 	},
3796 	{
3797 		.name               = "chgpasswd2",
3798 		.returntype         = RPC_RTYPE_NTSTATUS,
3799 		.ntfn               = cmd_samr_chgpasswd2,
3800 		.wfn                = NULL,
3801 		.table              = &ndr_table_samr,
3802 		.rpc_pipe           = NULL,
3803 		.description        = "Change user password",
3804 		.usage              = "",
3805 	},
3806 	{
3807 		.name               = "chgpasswd3",
3808 		.returntype         = RPC_RTYPE_NTSTATUS,
3809 		.ntfn               = cmd_samr_chgpasswd3,
3810 		.wfn                = NULL,
3811 		.table              = &ndr_table_samr,
3812 		.rpc_pipe           = NULL,
3813 		.description        = "Change user password",
3814 		.usage              = "",
3815 	},
3816 	{
3817 		.name               = "getdispinfoidx",
3818 		.returntype         = RPC_RTYPE_NTSTATUS,
3819 		.ntfn               = cmd_samr_get_dispinfo_idx,
3820 		.wfn                = NULL,
3821 		.table              = &ndr_table_samr,
3822 		.rpc_pipe           = NULL,
3823 		.description        = "Get Display Information Index",
3824 		.usage              = "",
3825 	},
3826 	{
3827 		.name               = "setuserinfo",
3828 		.returntype         = RPC_RTYPE_NTSTATUS,
3829 		.ntfn               = cmd_samr_setuserinfo,
3830 		.wfn                = NULL,
3831 		.table              = &ndr_table_samr,
3832 		.rpc_pipe           = NULL,
3833 		.description        = "Set user info",
3834 		.usage              = "",
3835 	},
3836 	{
3837 		.name               = "setuserinfo2",
3838 		.returntype         = RPC_RTYPE_NTSTATUS,
3839 		.ntfn               = cmd_samr_setuserinfo2,
3840 		.wfn                = NULL,
3841 		.table              = &ndr_table_samr,
3842 		.rpc_pipe           = NULL,
3843 		.description        = "Set user info2",
3844 		.usage              = "",
3845 	},
3846 	{
3847 		.name = NULL,
3848 	},
3849 };
3850