1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997.
7  *  Copyright (C) Jeremy Allison               1998-2001.
8  *  Copyright (C) Andrew Bartlett                   2001.
9  *  Copyright (C) Guenther Deschner		    2008-2009.
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 /* This is the implementation of the netlogon pipe. */
26 
27 #include "includes.h"
28 #include "system/passwd.h" /* uid_wrapper */
29 #include "ntdomain.h"
30 #include "../libcli/auth/schannel.h"
31 #include "../librpc/gen_ndr/srv_netlogon.h"
32 #include "../librpc/gen_ndr/ndr_samr_c.h"
33 #include "../librpc/gen_ndr/ndr_lsa_c.h"
34 #include "rpc_client/cli_lsarpc.h"
35 #include "rpc_client/init_lsa.h"
36 #include "rpc_client/init_samr.h"
37 #include "rpc_server/rpc_ncacn_np.h"
38 #include "../libcli/security/security.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "librpc/gen_ndr/ndr_drsblobs.h"
41 #include "lib/crypto/md4.h"
42 #include "nsswitch/libwbclient/wbclient.h"
43 #include "../libcli/registry/util_reg.h"
44 #include "passdb.h"
45 #include "auth.h"
46 #include "messages.h"
47 #include "../lib/tsocket/tsocket.h"
48 #include "lib/param/param.h"
49 #include "libsmb/dsgetdcname.h"
50 #include "lib/util/util_str_escape.h"
51 
52 extern userdom_struct current_user_info;
53 
54 #undef DBGC_CLASS
55 #define DBGC_CLASS DBGC_RPC_SRV
56 
57 struct netlogon_server_pipe_state {
58 	struct netr_Credential client_challenge;
59 	struct netr_Credential server_challenge;
60 };
61 
62 /*************************************************************************
63  _netr_LogonControl
64  *************************************************************************/
65 
_netr_LogonControl(struct pipes_struct * p,struct netr_LogonControl * r)66 WERROR _netr_LogonControl(struct pipes_struct *p,
67 			  struct netr_LogonControl *r)
68 {
69 	struct netr_LogonControl2Ex l;
70 
71 	switch (r->in.level) {
72 	case 1:
73 		break;
74 	case 2:
75 		return WERR_NOT_SUPPORTED;
76 	default:
77 		return WERR_INVALID_LEVEL;
78 	}
79 
80 	switch (r->in.function_code) {
81 	case NETLOGON_CONTROL_QUERY:
82 	case NETLOGON_CONTROL_REPLICATE:
83 	case NETLOGON_CONTROL_SYNCHRONIZE:
84 	case NETLOGON_CONTROL_PDC_REPLICATE:
85 	case NETLOGON_CONTROL_BREAKPOINT:
86 	case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
87 	case NETLOGON_CONTROL_TRUNCATE_LOG:
88 		break;
89 	default:
90 		return WERR_NOT_SUPPORTED;
91 	}
92 
93 	l.in.logon_server	= r->in.logon_server;
94 	l.in.function_code	= r->in.function_code;
95 	l.in.level		= r->in.level;
96 	l.in.data		= NULL;
97 	l.out.query		= r->out.query;
98 
99 	return _netr_LogonControl2Ex(p, &l);
100 }
101 
102 /*************************************************************************
103  _netr_LogonControl2
104  *************************************************************************/
105 
_netr_LogonControl2(struct pipes_struct * p,struct netr_LogonControl2 * r)106 WERROR _netr_LogonControl2(struct pipes_struct *p,
107 			   struct netr_LogonControl2 *r)
108 {
109 	struct netr_LogonControl2Ex l;
110 
111 	l.in.logon_server	= r->in.logon_server;
112 	l.in.function_code	= r->in.function_code;
113 	l.in.level		= r->in.level;
114 	l.in.data		= r->in.data;
115 	l.out.query		= r->out.query;
116 
117 	return _netr_LogonControl2Ex(p, &l);
118 }
119 
120 /*************************************************************************
121  *************************************************************************/
122 
wb_change_trust_creds(const char * domain,WERROR * tc_status)123 static bool wb_change_trust_creds(const char *domain, WERROR *tc_status)
124 {
125 	wbcErr result;
126 	struct wbcAuthErrorInfo *error = NULL;
127 
128 	result = wbcChangeTrustCredentials(domain, &error);
129 	switch (result) {
130 	case WBC_ERR_WINBIND_NOT_AVAILABLE:
131 		return false;
132 	case WBC_ERR_DOMAIN_NOT_FOUND:
133 		*tc_status = WERR_NO_SUCH_DOMAIN;
134 		return true;
135 	case WBC_ERR_SUCCESS:
136 		*tc_status = WERR_OK;
137 		return true;
138 	default:
139 		break;
140 	}
141 
142 	if (error && error->nt_status != 0) {
143 		*tc_status = ntstatus_to_werror(NT_STATUS(error->nt_status));
144 	} else {
145 		*tc_status = WERR_TRUST_FAILURE;
146 	}
147 	wbcFreeMemory(error);
148 	return true;
149 }
150 
151 /*************************************************************************
152  *************************************************************************/
153 
wb_check_trust_creds(const char * domain,WERROR * tc_status)154 static bool wb_check_trust_creds(const char *domain, WERROR *tc_status)
155 {
156 	wbcErr result;
157 	struct wbcAuthErrorInfo *error = NULL;
158 
159 	result = wbcCheckTrustCredentials(domain, &error);
160 	switch (result) {
161 	case WBC_ERR_WINBIND_NOT_AVAILABLE:
162 		return false;
163 	case WBC_ERR_DOMAIN_NOT_FOUND:
164 		*tc_status = WERR_NO_SUCH_DOMAIN;
165 		return true;
166 	case WBC_ERR_SUCCESS:
167 		*tc_status = WERR_OK;
168 		return true;
169 	default:
170 		break;
171 	}
172 
173 	if (error && error->nt_status != 0) {
174 		*tc_status = ntstatus_to_werror(NT_STATUS(error->nt_status));
175 	} else {
176 		*tc_status = WERR_TRUST_FAILURE;
177 	}
178 	wbcFreeMemory(error);
179 	return true;
180 }
181 
182 /****************************************************************
183  _netr_LogonControl2Ex
184 ****************************************************************/
185 
_netr_LogonControl2Ex(struct pipes_struct * p,struct netr_LogonControl2Ex * r)186 WERROR _netr_LogonControl2Ex(struct pipes_struct *p,
187 			     struct netr_LogonControl2Ex *r)
188 {
189 	uint32_t flags = 0x0;
190 	WERROR pdc_connection_status = WERR_OK;
191 	uint32_t logon_attempts = 0x0;
192 	WERROR tc_status;
193 	fstring dc_name2;
194 	const char *dc_name = NULL;
195 	struct sockaddr_storage dc_ss;
196 	const char *domain = NULL;
197 	struct netr_NETLOGON_INFO_1 *info1;
198 	struct netr_NETLOGON_INFO_2 *info2;
199 	struct netr_NETLOGON_INFO_3 *info3;
200 	struct netr_NETLOGON_INFO_4 *info4;
201 	const char *fn;
202 	NTSTATUS status;
203 	struct netr_DsRGetDCNameInfo *dc_info;
204 
205 	switch (p->opnum) {
206 	case NDR_NETR_LOGONCONTROL:
207 		fn = "_netr_LogonControl";
208 		break;
209 	case NDR_NETR_LOGONCONTROL2:
210 		fn = "_netr_LogonControl2";
211 		break;
212 	case NDR_NETR_LOGONCONTROL2EX:
213 		fn = "_netr_LogonControl2Ex";
214 		break;
215 	default:
216 		return WERR_INVALID_PARAMETER;
217 	}
218 
219 	switch (r->in.level) {
220 	case 1:
221 	case 2:
222 	case 3:
223 	case 4:
224 		break;
225 	default:
226 		return WERR_INVALID_LEVEL;
227 	}
228 
229 	switch (r->in.function_code) {
230 	case NETLOGON_CONTROL_QUERY:
231 		break;
232 	default:
233 		if ((geteuid() != sec_initial_uid()) &&
234 		    !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS) &&
235 		    !nt_token_check_sid(&global_sid_Builtin_Administrators, p->session_info->security_token))
236 		{
237 			return WERR_ACCESS_DENIED;
238 		}
239 		break;
240 	}
241 
242 	tc_status = WERR_NO_SUCH_DOMAIN;
243 
244 	switch (r->in.function_code) {
245 	case NETLOGON_CONTROL_QUERY:
246 		switch (r->in.level) {
247 		case 1:
248 		case 3:
249 			break;
250 		default:
251 			return WERR_INVALID_PARAMETER;
252 		}
253 
254 		tc_status = WERR_OK;
255 		break;
256 	case NETLOGON_CONTROL_REPLICATE:
257 	case NETLOGON_CONTROL_SYNCHRONIZE:
258 	case NETLOGON_CONTROL_PDC_REPLICATE:
259 	case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
260 	case NETLOGON_CONTROL_BREAKPOINT:
261 	case NETLOGON_CONTROL_TRUNCATE_LOG:
262 	case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
263 	case NETLOGON_CONTROL_FORCE_DNS_REG:
264 	case NETLOGON_CONTROL_QUERY_DNS_REG:
265 		return WERR_NOT_SUPPORTED;
266 
267 	case NETLOGON_CONTROL_FIND_USER:
268 		if (!r->in.data || !r->in.data->user) {
269 			return WERR_NOT_SUPPORTED;
270 		}
271 		break;
272 	case NETLOGON_CONTROL_SET_DBFLAG:
273 		if (!r->in.data) {
274 			return WERR_NOT_SUPPORTED;
275 		}
276 		break;
277 	case NETLOGON_CONTROL_TC_VERIFY:
278 		if (!r->in.data || !r->in.data->domain) {
279 			return WERR_NOT_SUPPORTED;
280 		}
281 
282 		if (!wb_check_trust_creds(r->in.data->domain, &tc_status)) {
283 			return WERR_NOT_SUPPORTED;
284 		}
285 		break;
286 	case NETLOGON_CONTROL_TC_QUERY:
287 		if (!r->in.data || !r->in.data->domain) {
288 			return WERR_NOT_SUPPORTED;
289 		}
290 
291 		domain = r->in.data->domain;
292 
293 		if (!is_trusted_domain(domain)) {
294 			break;
295 		}
296 
297 		if (!get_dc_name(domain, NULL, dc_name2, &dc_ss)) {
298 			tc_status = WERR_NO_LOGON_SERVERS;
299 			break;
300 		}
301 
302 		dc_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dc_name2);
303 		if (!dc_name) {
304 			return WERR_NOT_ENOUGH_MEMORY;
305 		}
306 
307 		tc_status = WERR_OK;
308 
309 		break;
310 
311 	case NETLOGON_CONTROL_REDISCOVER:
312 		if (!r->in.data || !r->in.data->domain) {
313 			return WERR_NOT_SUPPORTED;
314 		}
315 
316 		domain = r->in.data->domain;
317 
318 		if (!is_trusted_domain(domain)) {
319 			break;
320 		}
321 
322 		status = dsgetdcname(p->mem_ctx, p->msg_ctx, domain, NULL, NULL,
323 				     DS_FORCE_REDISCOVERY | DS_RETURN_FLAT_NAME,
324 				     &dc_info);
325 		if (!NT_STATUS_IS_OK(status)) {
326 			tc_status = WERR_NO_LOGON_SERVERS;
327 			break;
328 		}
329 
330 		dc_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dc_info->dc_unc);
331 		if (!dc_name) {
332 			return WERR_NOT_ENOUGH_MEMORY;
333 		}
334 
335 		tc_status = WERR_OK;
336 
337 		break;
338 
339 	case NETLOGON_CONTROL_CHANGE_PASSWORD:
340 		if (!r->in.data || !r->in.data->domain) {
341 			return WERR_NOT_SUPPORTED;
342 		}
343 
344 		if (!wb_change_trust_creds(r->in.data->domain, &tc_status)) {
345 			return WERR_NOT_SUPPORTED;
346 		}
347 		break;
348 
349 	default:
350 		/* no idea what this should be */
351 		DEBUG(0,("%s: unimplemented function level [%d]\n",
352 			fn, r->in.function_code));
353 		return WERR_NOT_SUPPORTED;
354 	}
355 
356 	/* prepare the response */
357 
358 	switch (r->in.level) {
359 	case 1:
360 		info1 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_1);
361 		W_ERROR_HAVE_NO_MEMORY(info1);
362 
363 		info1->flags			= flags;
364 		info1->pdc_connection_status	= pdc_connection_status;
365 
366 		r->out.query->info1 = info1;
367 		break;
368 	case 2:
369 		info2 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_2);
370 		W_ERROR_HAVE_NO_MEMORY(info2);
371 
372 		info2->flags			= flags;
373 		info2->pdc_connection_status	= pdc_connection_status;
374 		info2->trusted_dc_name		= dc_name;
375 		info2->tc_connection_status	= tc_status;
376 
377 		r->out.query->info2 = info2;
378 		break;
379 	case 3:
380 		info3 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_3);
381 		W_ERROR_HAVE_NO_MEMORY(info3);
382 
383 		info3->flags			= flags;
384 		info3->logon_attempts		= logon_attempts;
385 
386 		r->out.query->info3 = info3;
387 		break;
388 	case 4:
389 		info4 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_4);
390 		W_ERROR_HAVE_NO_MEMORY(info4);
391 
392 		info4->trusted_dc_name		= dc_name;
393 		info4->trusted_domain_name	= r->in.data->domain;
394 
395 		r->out.query->info4 = info4;
396 		break;
397 	default:
398 		return WERR_INVALID_LEVEL;
399 	}
400 
401 	return WERR_OK;
402 }
403 
404 /*************************************************************************
405  _netr_NetrEnumerateTrustedDomains
406  *************************************************************************/
407 
_netr_NetrEnumerateTrustedDomains(struct pipes_struct * p,struct netr_NetrEnumerateTrustedDomains * r)408 NTSTATUS _netr_NetrEnumerateTrustedDomains(struct pipes_struct *p,
409 					   struct netr_NetrEnumerateTrustedDomains *r)
410 {
411 	NTSTATUS status;
412 	NTSTATUS result = NT_STATUS_OK;
413 	DATA_BLOB blob;
414 	size_t num_domains = 0;
415 	const char **trusted_domains = NULL;
416 	struct lsa_DomainList domain_list;
417 	struct dcerpc_binding_handle *h = NULL;
418 	struct policy_handle pol;
419 	uint32_t enum_ctx = 0;
420 	int i;
421 	uint32_t max_size = (uint32_t)-1;
422 
423 	ZERO_STRUCT(pol);
424 	DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
425 
426 	status = rpcint_binding_handle(p->mem_ctx,
427 				       &ndr_table_lsarpc,
428 				       p->remote_address,
429 				       p->local_address,
430 				       p->session_info,
431 				       p->msg_ctx,
432 				       &h);
433 	if (!NT_STATUS_IS_OK(status)) {
434 		return status;
435 	}
436 
437 	status = dcerpc_lsa_open_policy2(h,
438 					 p->mem_ctx,
439 					 NULL,
440 					 true,
441 					 LSA_POLICY_VIEW_LOCAL_INFORMATION,
442 					 &pol,
443 					 &result);
444 	if (!NT_STATUS_IS_OK(status)) {
445 		goto out;
446 	}
447 	if (!NT_STATUS_IS_OK(result)) {
448 		status = result;
449 		goto out;
450 	}
451 
452 	do {
453 		/* Lookup list of trusted domains */
454 		status = dcerpc_lsa_EnumTrustDom(h,
455 						 p->mem_ctx,
456 						 &pol,
457 						 &enum_ctx,
458 						 &domain_list,
459 						 max_size,
460 						 &result);
461 		if (!NT_STATUS_IS_OK(status)) {
462 			goto out;
463 		}
464 		if (!NT_STATUS_IS_OK(result) &&
465 		    !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
466 		    !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
467 			status = result;
468 			goto out;
469 		}
470 
471 		for (i = 0; i < domain_list.count; i++) {
472 			if (!add_string_to_array(p->mem_ctx, domain_list.domains[i].name.string,
473 						 &trusted_domains, &num_domains)) {
474 				status = NT_STATUS_NO_MEMORY;
475 				goto out;
476 			}
477 		}
478 	} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
479 
480 	if (num_domains > 0) {
481 		/* multi sz terminate */
482 		trusted_domains = talloc_realloc(p->mem_ctx, trusted_domains, const char *, num_domains + 1);
483 		if (trusted_domains == NULL) {
484 			status = NT_STATUS_NO_MEMORY;
485 			goto out;
486 		}
487 
488 		trusted_domains[num_domains] = NULL;
489 	}
490 
491 	if (!push_reg_multi_sz(trusted_domains, &blob, trusted_domains)) {
492 		TALLOC_FREE(trusted_domains);
493 		status = NT_STATUS_NO_MEMORY;
494 		goto out;
495 	}
496 
497 	r->out.trusted_domains_blob->data = blob.data;
498 	r->out.trusted_domains_blob->length = blob.length;
499 
500 	DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
501 
502 	status = NT_STATUS_OK;
503 
504  out:
505 	if (is_valid_policy_hnd(&pol)) {
506 		dcerpc_lsa_Close(h, p->mem_ctx, &pol, &result);
507 	}
508 
509 	return status;
510 }
511 
512 /*************************************************************************
513  *************************************************************************/
514 
samr_find_machine_account(TALLOC_CTX * mem_ctx,struct dcerpc_binding_handle * b,const char * account_name,uint32_t access_mask,struct dom_sid2 ** domain_sid_p,uint32_t * user_rid_p,struct policy_handle * user_handle)515 static NTSTATUS samr_find_machine_account(TALLOC_CTX *mem_ctx,
516 					  struct dcerpc_binding_handle *b,
517 					  const char *account_name,
518 					  uint32_t access_mask,
519 					  struct dom_sid2 **domain_sid_p,
520 					  uint32_t *user_rid_p,
521 					  struct policy_handle *user_handle)
522 {
523 	NTSTATUS status;
524 	NTSTATUS result = NT_STATUS_OK;
525 	struct policy_handle connect_handle;
526 	struct policy_handle domain_handle = { 0, };
527 	struct lsa_String domain_name;
528 	struct dom_sid2 *domain_sid;
529 	struct lsa_String names;
530 	struct samr_Ids rids;
531 	struct samr_Ids types;
532 	uint32_t rid;
533 
534 	status = dcerpc_samr_Connect2(b, mem_ctx,
535 				      lp_netbios_name(),
536 				      SAMR_ACCESS_CONNECT_TO_SERVER |
537 				      SAMR_ACCESS_ENUM_DOMAINS |
538 				      SAMR_ACCESS_LOOKUP_DOMAIN,
539 				      &connect_handle,
540 				      &result);
541 	if (!NT_STATUS_IS_OK(status)) {
542 		goto out;
543 	}
544 	if (!NT_STATUS_IS_OK(result)) {
545 		status = result;
546 		goto out;
547 	}
548 
549 	init_lsa_String(&domain_name, get_global_sam_name());
550 
551 	status = dcerpc_samr_LookupDomain(b, mem_ctx,
552 					  &connect_handle,
553 					  &domain_name,
554 					  &domain_sid,
555 					  &result);
556 	if (!NT_STATUS_IS_OK(status)) {
557 		goto out;
558 	}
559 	if (!NT_STATUS_IS_OK(result)) {
560 		status = result;
561 		goto out;
562 	}
563 
564 	status = dcerpc_samr_OpenDomain(b, mem_ctx,
565 					&connect_handle,
566 					SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
567 					domain_sid,
568 					&domain_handle,
569 					&result);
570 	if (!NT_STATUS_IS_OK(status)) {
571 		goto out;
572 	}
573 	if (!NT_STATUS_IS_OK(result)) {
574 		status = result;
575 		goto out;
576 	}
577 
578 	init_lsa_String(&names, account_name);
579 
580 	status = dcerpc_samr_LookupNames(b, mem_ctx,
581 					 &domain_handle,
582 					 1,
583 					 &names,
584 					 &rids,
585 					 &types,
586 					 &result);
587 	if (!NT_STATUS_IS_OK(status)) {
588 		goto out;
589 	}
590 	if (!NT_STATUS_IS_OK(result)) {
591 		status = result;
592 		goto out;
593 	}
594 
595 	if (rids.count != 1) {
596 		status = NT_STATUS_NO_SUCH_USER;
597 		goto out;
598 	}
599 	if (types.count != 1) {
600 		status = NT_STATUS_INVALID_PARAMETER;
601 		goto out;
602 	}
603 	if (types.ids[0] != SID_NAME_USER) {
604 		status = NT_STATUS_NO_SUCH_USER;
605 		goto out;
606 	}
607 
608 	rid = rids.ids[0];
609 
610 	status = dcerpc_samr_OpenUser(b, mem_ctx,
611 				      &domain_handle,
612 				      access_mask,
613 				      rid,
614 				      user_handle,
615 				      &result);
616 	if (!NT_STATUS_IS_OK(status)) {
617 		goto out;
618 	}
619 	if (!NT_STATUS_IS_OK(result)) {
620 		status = result;
621 		goto out;
622 	}
623 
624 	if (user_rid_p) {
625 		*user_rid_p = rid;
626 	}
627 
628 	if (domain_sid_p) {
629 		*domain_sid_p = domain_sid;
630 	}
631 
632  out:
633 	if (is_valid_policy_hnd(&domain_handle)) {
634 		dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
635 	}
636 	if (is_valid_policy_hnd(&connect_handle)) {
637 		dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
638 	}
639 
640 	return status;
641 }
642 
643 /******************************************************************
644  gets a machine password entry.  checks access rights of the host.
645  ******************************************************************/
646 
get_md4pw(struct samr_Password * md4pw,const char * mach_acct,enum netr_SchannelType sec_chan_type,struct dom_sid * sid,struct messaging_context * msg_ctx)647 static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
648 			  enum netr_SchannelType sec_chan_type,
649 			  struct dom_sid *sid,
650 			  struct messaging_context *msg_ctx)
651 {
652 	NTSTATUS status;
653 	NTSTATUS result = NT_STATUS_OK;
654 	TALLOC_CTX *mem_ctx;
655 	struct dcerpc_binding_handle *h = NULL;
656 	struct tsocket_address *local;
657 	struct policy_handle user_handle;
658 	uint32_t user_rid;
659 	struct dom_sid *domain_sid;
660 	uint32_t acct_ctrl;
661 	union samr_UserInfo *info;
662 	struct auth_session_info *session_info;
663 	int rc;
664 
665 #if 0
666 
667     /*
668      * Currently this code is redundant as we already have a filter
669      * by hostname list. What this code really needs to do is to
670      * get a hosts allowed/hosts denied list from the SAM database
671      * on a per user basis, and make the access decision there.
672      * I will leave this code here for now as a reminder to implement
673      * this at a later date. JRA.
674      */
675 
676 	if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
677 			  p->client_id.name,
678 			  p->client_id.addr)) {
679 		DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
680 		return False;
681 	}
682 #endif /* 0 */
683 
684 	mem_ctx = talloc_stackframe();
685 	if (mem_ctx == NULL) {
686 		status = NT_STATUS_NO_MEMORY;
687 		goto out;
688 	}
689 
690 	status = make_session_info_system(mem_ctx, &session_info);
691 	if (!NT_STATUS_IS_OK(status)) {
692 		goto out;
693 	}
694 
695 	ZERO_STRUCT(user_handle);
696 
697 	rc = tsocket_address_inet_from_strings(mem_ctx,
698 					       "ip",
699 					       "127.0.0.1",
700 					       0,
701 					       &local);
702 	if (rc < 0) {
703 		status = NT_STATUS_NO_MEMORY;
704 		goto out;
705 	}
706 
707 	status = rpcint_binding_handle(mem_ctx,
708 				       &ndr_table_samr,
709 				       local,
710 				       NULL,
711 				       session_info,
712 				       msg_ctx,
713 				       &h);
714 	if (!NT_STATUS_IS_OK(status)) {
715 		goto out;
716 	}
717 
718 	status = samr_find_machine_account(mem_ctx, h, mach_acct,
719 					   SEC_FLAG_MAXIMUM_ALLOWED,
720 					   &domain_sid, &user_rid,
721 					   &user_handle);
722 	if (!NT_STATUS_IS_OK(status)) {
723 		goto out;
724 	}
725 
726 	status = dcerpc_samr_QueryUserInfo2(h,
727 					    mem_ctx,
728 					    &user_handle,
729 					    UserControlInformation,
730 					    &info,
731 					    &result);
732 	if (!NT_STATUS_IS_OK(status)) {
733 		goto out;
734 	}
735 	if (!NT_STATUS_IS_OK(result)) {
736 		status = result;
737 		goto out;
738 	}
739 
740 	acct_ctrl = info->info16.acct_flags;
741 
742 	if (acct_ctrl & ACB_DISABLED) {
743 		DEBUG(0,("get_md4pw: Workstation %s: account is disabled\n", mach_acct));
744 		status = NT_STATUS_ACCOUNT_DISABLED;
745 		goto out;
746 	}
747 
748 	if (!(acct_ctrl & ACB_SVRTRUST) &&
749 	    !(acct_ctrl & ACB_WSTRUST) &&
750 	    !(acct_ctrl & ACB_DOMTRUST))
751 	{
752 		DEBUG(0,("get_md4pw: Workstation %s: account is not a trust account\n", mach_acct));
753 		status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
754 		goto out;
755 	}
756 
757 	switch (sec_chan_type) {
758 		case SEC_CHAN_BDC:
759 			if (!(acct_ctrl & ACB_SVRTRUST)) {
760 				DEBUG(0,("get_md4pw: Workstation %s: BDC secure channel requested "
761 					 "but not a server trust account\n", mach_acct));
762 				status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
763 				goto out;
764 			}
765 			break;
766 		case SEC_CHAN_WKSTA:
767 			if (!(acct_ctrl & ACB_WSTRUST)) {
768 				DEBUG(0,("get_md4pw: Workstation %s: WORKSTATION secure channel requested "
769 					 "but not a workstation trust account\n", mach_acct));
770 				status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
771 				goto out;
772 			}
773 			break;
774 		case SEC_CHAN_DOMAIN:
775 			if (!(acct_ctrl & ACB_DOMTRUST)) {
776 				DEBUG(0,("get_md4pw: Workstation %s: DOMAIN secure channel requested "
777 					 "but not a interdomain trust account\n", mach_acct));
778 				status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
779 				goto out;
780 			}
781 			break;
782 		default:
783 			break;
784 	}
785 
786 	become_root();
787 	status = dcerpc_samr_QueryUserInfo2(h,
788 					    mem_ctx,
789 					    &user_handle,
790 					    UserInternal1Information,
791 					    &info,
792 					    &result);
793 	unbecome_root();
794 	if (!NT_STATUS_IS_OK(status)) {
795 		goto out;
796 	}
797 	if (!NT_STATUS_IS_OK(result)) {
798 		status = result;
799 		goto out;
800 	}
801 
802 	if (info->info18.nt_pwd_active == 0) {
803 		DEBUG(0,("get_md4pw: Workstation %s: account does not have a password\n", mach_acct));
804 		status = NT_STATUS_LOGON_FAILURE;
805 		goto out;
806 	}
807 
808 	/* samr gives out nthash unencrypted (!) */
809 	memcpy(md4pw->hash, info->info18.nt_pwd.hash, 16);
810 
811 	sid_compose(sid, domain_sid, user_rid);
812 
813  out:
814 	if (h && is_valid_policy_hnd(&user_handle)) {
815 		dcerpc_samr_Close(h, mem_ctx, &user_handle, &result);
816 	}
817 
818 	talloc_free(mem_ctx);
819 
820 	return status;
821 }
822 
823 /*************************************************************************
824  _netr_ServerReqChallenge
825  *************************************************************************/
826 
_netr_ServerReqChallenge(struct pipes_struct * p,struct netr_ServerReqChallenge * r)827 NTSTATUS _netr_ServerReqChallenge(struct pipes_struct *p,
828 				  struct netr_ServerReqChallenge *r)
829 {
830 	struct netlogon_server_pipe_state *pipe_state =
831 		talloc_get_type(p->private_data, struct netlogon_server_pipe_state);
832 
833 	if (pipe_state) {
834 		DEBUG(10,("_netr_ServerReqChallenge: new challenge requested. Clearing old state.\n"));
835 		talloc_free(pipe_state);
836 		p->private_data = NULL;
837 	}
838 
839 	pipe_state = talloc(p, struct netlogon_server_pipe_state);
840 	NT_STATUS_HAVE_NO_MEMORY(pipe_state);
841 
842 	pipe_state->client_challenge = *r->in.credentials;
843 
844 	netlogon_creds_random_challenge(&pipe_state->server_challenge);
845 
846 	*r->out.return_credentials = pipe_state->server_challenge;
847 
848 	p->private_data = pipe_state;
849 
850 	return NT_STATUS_OK;
851 }
852 
853 /*************************************************************************
854  _netr_ServerAuthenticate
855  Create the initial credentials.
856  *************************************************************************/
857 
_netr_ServerAuthenticate(struct pipes_struct * p,struct netr_ServerAuthenticate * r)858 NTSTATUS _netr_ServerAuthenticate(struct pipes_struct *p,
859 				  struct netr_ServerAuthenticate *r)
860 {
861 	struct netr_ServerAuthenticate3 a;
862 	uint32_t negotiate_flags = 0;
863 	uint32_t rid;
864 
865 	a.in.server_name		= r->in.server_name;
866 	a.in.account_name		= r->in.account_name;
867 	a.in.secure_channel_type	= r->in.secure_channel_type;
868 	a.in.computer_name		= r->in.computer_name;
869 	a.in.credentials		= r->in.credentials;
870 	a.in.negotiate_flags		= &negotiate_flags;
871 
872 	a.out.return_credentials	= r->out.return_credentials;
873 	a.out.rid			= &rid;
874 	a.out.negotiate_flags		= &negotiate_flags;
875 
876 	return _netr_ServerAuthenticate3(p, &a);
877 
878 }
879 
880 /*************************************************************************
881  _netr_ServerAuthenticate3
882  *************************************************************************/
883 
_netr_ServerAuthenticate3(struct pipes_struct * p,struct netr_ServerAuthenticate3 * r)884 NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
885 				   struct netr_ServerAuthenticate3 *r)
886 {
887 	NTSTATUS status;
888 	uint32_t srv_flgs;
889 	/* r->in.negotiate_flags is an aliased pointer to r->out.negotiate_flags,
890 	 * so use a copy to avoid destroying the client values. */
891 	uint32_t in_neg_flags = *r->in.negotiate_flags;
892 	const char *fn;
893 	struct loadparm_context *lp_ctx;
894 	struct dom_sid sid;
895 	struct samr_Password mach_pwd;
896 	struct netlogon_creds_CredentialState *creds;
897 	struct netlogon_server_pipe_state *pipe_state =
898 		talloc_get_type(p->private_data, struct netlogon_server_pipe_state);
899 
900 	/* According to Microsoft (see bugid #6099)
901 	 * Windows 7 looks at the negotiate_flags
902 	 * returned in this structure *even if the
903 	 * call fails with access denied* ! So in order
904 	 * to allow Win7 to connect to a Samba NT style
905 	 * PDC we set the flags before we know if it's
906 	 * an error or not.
907 	 */
908 
909 	/* 0x000001ff */
910 	srv_flgs = NETLOGON_NEG_ACCOUNT_LOCKOUT |
911 		   NETLOGON_NEG_PERSISTENT_SAMREPL |
912 		   NETLOGON_NEG_ARCFOUR |
913 		   NETLOGON_NEG_PROMOTION_COUNT |
914 		   NETLOGON_NEG_CHANGELOG_BDC |
915 		   NETLOGON_NEG_FULL_SYNC_REPL |
916 		   NETLOGON_NEG_MULTIPLE_SIDS |
917 		   NETLOGON_NEG_REDO |
918 		   NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
919 		   NETLOGON_NEG_PASSWORD_SET2;
920 
921 	/* Ensure we support strong (128-bit) keys. */
922 	if (in_neg_flags & NETLOGON_NEG_STRONG_KEYS) {
923 		srv_flgs |= NETLOGON_NEG_STRONG_KEYS;
924 	}
925 
926 	if (in_neg_flags & NETLOGON_NEG_SUPPORTS_AES) {
927 		srv_flgs |= NETLOGON_NEG_SUPPORTS_AES;
928 	}
929 
930 	if (in_neg_flags & NETLOGON_NEG_SCHANNEL) {
931 		srv_flgs |= NETLOGON_NEG_SCHANNEL;
932 	}
933 
934 	/*
935 	 * Support authenticaten of trusted domains.
936 	 *
937 	 * These flags are the minimum required set which works with win2k3
938 	 * and win2k8.
939 	 */
940 	if (pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX) {
941 		srv_flgs |= NETLOGON_NEG_TRANSITIVE_TRUSTS |
942 			    NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
943 			    NETLOGON_NEG_CROSS_FOREST_TRUSTS |
944 			    NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION;
945 	}
946 
947 	switch (p->opnum) {
948 		case NDR_NETR_SERVERAUTHENTICATE:
949 			fn = "_netr_ServerAuthenticate";
950 			break;
951 		case NDR_NETR_SERVERAUTHENTICATE2:
952 			fn = "_netr_ServerAuthenticate2";
953 			break;
954 		case NDR_NETR_SERVERAUTHENTICATE3:
955 			fn = "_netr_ServerAuthenticate3";
956 			break;
957 		default:
958 			return NT_STATUS_INTERNAL_ERROR;
959 	}
960 
961 	/* We use this as the key to store the creds: */
962 	/* r->in.computer_name */
963 
964 	if (!pipe_state) {
965 		DEBUG(0,("%s: no challenge sent to client %s\n", fn,
966 			r->in.computer_name));
967 		status = NT_STATUS_ACCESS_DENIED;
968 		goto out;
969 	}
970 
971 	status = get_md4pw(&mach_pwd,
972 			   r->in.account_name,
973 			   r->in.secure_channel_type,
974 			   &sid, p->msg_ctx);
975 	if (!NT_STATUS_IS_OK(status)) {
976 		DEBUG(0,("%s: failed to get machine password for "
977 			"account %s: %s\n",
978 			fn, r->in.account_name, nt_errstr(status) ));
979 		/* always return NT_STATUS_ACCESS_DENIED */
980 		status = NT_STATUS_ACCESS_DENIED;
981 		goto out;
982 	}
983 
984 	/* From the client / server challenges and md4 password, generate sess key */
985 	/* Check client credentials are valid. */
986 	creds = netlogon_creds_server_init(p->mem_ctx,
987 					   r->in.account_name,
988 					   r->in.computer_name,
989 					   r->in.secure_channel_type,
990 					   &pipe_state->client_challenge,
991 					   &pipe_state->server_challenge,
992 					   &mach_pwd,
993 					   r->in.credentials,
994 					   r->out.return_credentials,
995 					   srv_flgs);
996 	if (!creds) {
997 		DEBUG(0,("%s: netlogon_creds_server_check failed. Rejecting auth "
998 			"request from client %s machine account %s\n",
999 			fn, r->in.computer_name,
1000 			r->in.account_name));
1001 		status = NT_STATUS_ACCESS_DENIED;
1002 		goto out;
1003 	}
1004 
1005 	creds->sid = dom_sid_dup(creds, &sid);
1006 	if (!creds->sid) {
1007 		status = NT_STATUS_NO_MEMORY;
1008 		goto out;
1009 	}
1010 
1011 	lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
1012 	if (lp_ctx == NULL) {
1013 		DEBUG(10, ("loadparm_init_s3 failed\n"));
1014 		status = NT_STATUS_INTERNAL_ERROR;
1015 		goto out;
1016 	}
1017 
1018 	/* Store off the state so we can continue after client disconnect. */
1019 	become_root();
1020 	status = schannel_save_creds_state(p->mem_ctx, lp_ctx, creds);
1021 	unbecome_root();
1022 
1023 	talloc_unlink(p->mem_ctx, lp_ctx);
1024 
1025 	if (!NT_STATUS_IS_OK(status)) {
1026 		ZERO_STRUCTP(r->out.return_credentials);
1027 		goto out;
1028 	}
1029 
1030 	sid_peek_rid(&sid, r->out.rid);
1031 
1032 	status = NT_STATUS_OK;
1033 
1034   out:
1035 
1036 	*r->out.negotiate_flags = srv_flgs;
1037 	return status;
1038 }
1039 
1040 /*************************************************************************
1041  _netr_ServerAuthenticate2
1042  *************************************************************************/
1043 
_netr_ServerAuthenticate2(struct pipes_struct * p,struct netr_ServerAuthenticate2 * r)1044 NTSTATUS _netr_ServerAuthenticate2(struct pipes_struct *p,
1045 				   struct netr_ServerAuthenticate2 *r)
1046 {
1047 	struct netr_ServerAuthenticate3 a;
1048 	uint32_t rid;
1049 
1050 	a.in.server_name		= r->in.server_name;
1051 	a.in.account_name		= r->in.account_name;
1052 	a.in.secure_channel_type	= r->in.secure_channel_type;
1053 	a.in.computer_name		= r->in.computer_name;
1054 	a.in.credentials		= r->in.credentials;
1055 	a.in.negotiate_flags		= r->in.negotiate_flags;
1056 
1057 	a.out.return_credentials	= r->out.return_credentials;
1058 	a.out.rid			= &rid;
1059 	a.out.negotiate_flags		= r->out.negotiate_flags;
1060 
1061 	return _netr_ServerAuthenticate3(p, &a);
1062 }
1063 
1064 /*************************************************************************
1065  *************************************************************************/
1066 
netr_creds_server_step_check(struct pipes_struct * p,TALLOC_CTX * mem_ctx,const char * computer_name,struct netr_Authenticator * received_authenticator,struct netr_Authenticator * return_authenticator,struct netlogon_creds_CredentialState ** creds_out)1067 static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
1068 					     TALLOC_CTX *mem_ctx,
1069 					     const char *computer_name,
1070 					     struct netr_Authenticator *received_authenticator,
1071 					     struct netr_Authenticator *return_authenticator,
1072 					     struct netlogon_creds_CredentialState **creds_out)
1073 {
1074 	NTSTATUS status;
1075 	bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
1076 	bool schannel_required = schannel_global_required;
1077 	const char *explicit_opt = NULL;
1078 	struct loadparm_context *lp_ctx;
1079 	struct netlogon_creds_CredentialState *creds = NULL;
1080 	enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1081 	uint16_t opnum = p->opnum;
1082 	const char *opname = "<unknown>";
1083 	static bool warned_global_once = false;
1084 
1085 	if (creds_out != NULL) {
1086 		*creds_out = NULL;
1087 	}
1088 
1089 	if (opnum < ndr_table_netlogon.num_calls) {
1090 		opname = ndr_table_netlogon.calls[opnum].name;
1091 	}
1092 
1093 	auth_type = p->auth.auth_type;
1094 
1095 	lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
1096 	if (lp_ctx == NULL) {
1097 		DEBUG(0, ("loadparm_init_s3 failed\n"));
1098 		return NT_STATUS_INTERNAL_ERROR;
1099 	}
1100 
1101 	status = schannel_check_creds_state(mem_ctx, lp_ctx,
1102 					    computer_name, received_authenticator,
1103 					    return_authenticator, &creds);
1104 	talloc_unlink(mem_ctx, lp_ctx);
1105 
1106 	if (!NT_STATUS_IS_OK(status)) {
1107 		ZERO_STRUCTP(return_authenticator);
1108 		return status;
1109 	}
1110 
1111 	/*
1112 	 * We don't use lp_parm_bool(), as we
1113 	 * need the explicit_opt pointer in order to
1114 	 * adjust the debug messages.
1115 	 */
1116 
1117 	explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1118 					    "server require schannel",
1119 					    creds->account_name,
1120 					    NULL);
1121 	if (explicit_opt != NULL) {
1122 		schannel_required = lp_bool(explicit_opt);
1123 	}
1124 
1125 	if (schannel_required) {
1126 		if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1127 			*creds_out = creds;
1128 			return NT_STATUS_OK;
1129 		}
1130 
1131 		DBG_ERR("CVE-2020-1472(ZeroLogon): "
1132 			"%s request (opnum[%u]) without schannel from "
1133 			"client_account[%s] client_computer_name[%s]\n",
1134 			opname, opnum,
1135 			log_escape(mem_ctx, creds->account_name),
1136 			log_escape(mem_ctx, creds->computer_name));
1137 		DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
1138 			"'server require schannel:%s = no' is needed! \n",
1139 			log_escape(mem_ctx, creds->account_name));
1140 		TALLOC_FREE(creds);
1141 		ZERO_STRUCTP(return_authenticator);
1142 		return NT_STATUS_ACCESS_DENIED;
1143 	}
1144 
1145 	if (!schannel_global_required && !warned_global_once) {
1146 		/*
1147 		 * We want admins to notice their misconfiguration!
1148 		 */
1149 		DBG_ERR("CVE-2020-1472(ZeroLogon): "
1150 			"Please configure 'server schannel = yes', "
1151 			"See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
1152 		warned_global_once = true;
1153 	}
1154 
1155 	if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1156 		DBG_ERR("CVE-2020-1472(ZeroLogon): "
1157 			"%s request (opnum[%u]) WITH schannel from "
1158 			"client_account[%s] client_computer_name[%s]\n",
1159 			opname, opnum,
1160 			log_escape(mem_ctx, creds->account_name),
1161 			log_escape(mem_ctx, creds->computer_name));
1162 		DBG_ERR("CVE-2020-1472(ZeroLogon): "
1163 			"Option 'server require schannel:%s = no' not needed!?\n",
1164 			log_escape(mem_ctx, creds->account_name));
1165 
1166 		*creds_out = creds;
1167 		return NT_STATUS_OK;
1168 	}
1169 
1170 	if (explicit_opt != NULL) {
1171 		DBG_INFO("CVE-2020-1472(ZeroLogon): "
1172 			 "%s request (opnum[%u]) without schannel from "
1173 			 "client_account[%s] client_computer_name[%s]\n",
1174 			 opname, opnum,
1175 			 log_escape(mem_ctx, creds->account_name),
1176 			 log_escape(mem_ctx, creds->computer_name));
1177 		DBG_INFO("CVE-2020-1472(ZeroLogon): "
1178 			 "Option 'server require schannel:%s = no' still needed!\n",
1179 			 log_escape(mem_ctx, creds->account_name));
1180 	} else {
1181 		DBG_ERR("CVE-2020-1472(ZeroLogon): "
1182 			"%s request (opnum[%u]) without schannel from "
1183 			"client_account[%s] client_computer_name[%s]\n",
1184 			opname, opnum,
1185 			log_escape(mem_ctx, creds->account_name),
1186 			log_escape(mem_ctx, creds->computer_name));
1187 		DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
1188 			"'server require schannel:%s = no' might be needed!\n",
1189 			log_escape(mem_ctx, creds->account_name));
1190 	}
1191 
1192 	*creds_out = creds;
1193 	return NT_STATUS_OK;
1194 }
1195 
1196 
1197 /*************************************************************************
1198  *************************************************************************/
1199 
1200 struct _samr_Credentials_t {
1201 	enum {
1202 		CRED_TYPE_NT_HASH,
1203 		CRED_TYPE_PLAIN_TEXT,
1204 	} cred_type;
1205 	union {
1206 		struct samr_Password *nt_hash;
1207 		const char *password;
1208 	} creds;
1209 };
1210 
1211 
netr_set_machine_account_password(TALLOC_CTX * mem_ctx,struct auth_session_info * session_info,struct messaging_context * msg_ctx,const char * account_name,struct _samr_Credentials_t * cr)1212 static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
1213 						  struct auth_session_info *session_info,
1214 						  struct messaging_context *msg_ctx,
1215 						  const char *account_name,
1216 						  struct _samr_Credentials_t *cr)
1217 {
1218 	NTSTATUS status;
1219 	NTSTATUS result = NT_STATUS_OK;
1220 	struct dcerpc_binding_handle *h = NULL;
1221 	struct tsocket_address *local;
1222 	struct policy_handle user_handle;
1223 	uint32_t acct_ctrl;
1224 	union samr_UserInfo *info;
1225 	struct samr_UserInfo18 info18;
1226 	struct samr_UserInfo26 info26;
1227 	DATA_BLOB in,out;
1228 	int rc;
1229 	DATA_BLOB session_key;
1230 	enum samr_UserInfoLevel infolevel;
1231 	TALLOC_CTX *frame = talloc_stackframe();
1232 
1233 	ZERO_STRUCT(user_handle);
1234 
1235 	status = session_extract_session_key(session_info,
1236 					     &session_key,
1237 					     KEY_USE_16BYTES);
1238 	if (!NT_STATUS_IS_OK(status)) {
1239 		goto out;
1240 	}
1241 
1242 	rc = tsocket_address_inet_from_strings(frame,
1243 					       "ip",
1244 					       "127.0.0.1",
1245 					       0,
1246 					       &local);
1247 	if (rc < 0) {
1248 		status = NT_STATUS_NO_MEMORY;
1249 		goto out;
1250 	}
1251 
1252 	status = rpcint_binding_handle(frame,
1253 				       &ndr_table_samr,
1254 				       local,
1255 				       NULL,
1256 				       session_info,
1257 				       msg_ctx,
1258 				       &h);
1259 	if (!NT_STATUS_IS_OK(status)) {
1260 		goto out;
1261 	}
1262 
1263 	become_root();
1264 	status = samr_find_machine_account(frame,
1265 					   h,
1266 					   account_name,
1267 					   SEC_FLAG_MAXIMUM_ALLOWED,
1268 					   NULL,
1269 					   NULL,
1270 					   &user_handle);
1271 	unbecome_root();
1272 	if (!NT_STATUS_IS_OK(status)) {
1273 		goto out;
1274 	}
1275 
1276 	status = dcerpc_samr_QueryUserInfo2(h,
1277 					    frame,
1278 					    &user_handle,
1279 					    UserControlInformation,
1280 					    &info,
1281 					    &result);
1282 	if (!NT_STATUS_IS_OK(status)) {
1283 		goto out;
1284 	}
1285 	if (!NT_STATUS_IS_OK(result)) {
1286 		status = result;
1287 		goto out;
1288 	}
1289 
1290 	acct_ctrl = info->info16.acct_flags;
1291 
1292 	if (!(acct_ctrl & ACB_WSTRUST ||
1293 	      acct_ctrl & ACB_SVRTRUST ||
1294 	      acct_ctrl & ACB_DOMTRUST)) {
1295 		status = NT_STATUS_NO_SUCH_USER;
1296 		goto out;
1297 	}
1298 
1299 	if (acct_ctrl & ACB_DISABLED) {
1300 		status = NT_STATUS_ACCOUNT_DISABLED;
1301 		goto out;
1302 	}
1303 
1304 	switch(cr->cred_type) {
1305 		case CRED_TYPE_NT_HASH:
1306 			ZERO_STRUCT(info18);
1307 
1308 			infolevel = UserInternal1Information;
1309 
1310 			in = data_blob_const(cr->creds.nt_hash, 16);
1311 			out = data_blob_talloc_zero(frame, 16);
1312 			if (out.data == NULL) {
1313 				status = NT_STATUS_NO_MEMORY;
1314 				goto out;
1315 			}
1316 			rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
1317 			if (rc != 0) {
1318 				status = gnutls_error_to_ntstatus(rc,
1319 								  NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
1320 				goto out;
1321 			}
1322 			memcpy(info18.nt_pwd.hash, out.data, out.length);
1323 
1324 			info18.nt_pwd_active = true;
1325 
1326 			info->info18 = info18;
1327 		break;
1328 		case CRED_TYPE_PLAIN_TEXT:
1329 			ZERO_STRUCT(info26);
1330 
1331 			infolevel = UserInternal5InformationNew;
1332 
1333 			status = init_samr_CryptPasswordEx(cr->creds.password,
1334 							   &session_key,
1335 							   &info26.password);
1336 			if (!NT_STATUS_IS_OK(status)) {
1337 				goto out;
1338 			}
1339 
1340 			info26.password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON;
1341 			info->info26 = info26;
1342 		break;
1343 		default:
1344 			status = NT_STATUS_INTERNAL_ERROR;
1345 			goto out;
1346 		break;
1347 	}
1348 
1349 	become_root();
1350 	status = dcerpc_samr_SetUserInfo2(h,
1351 					  frame,
1352 					  &user_handle,
1353 					  infolevel,
1354 					  info,
1355 					  &result);
1356 	unbecome_root();
1357 	if (!NT_STATUS_IS_OK(status)) {
1358 		goto out;
1359 	}
1360 	if (!NT_STATUS_IS_OK(result)) {
1361 		status = result;
1362 		goto out;
1363 	}
1364 
1365  out:
1366 	if (h && is_valid_policy_hnd(&user_handle)) {
1367 		dcerpc_samr_Close(h, frame, &user_handle, &result);
1368 	}
1369 	TALLOC_FREE(frame);
1370 
1371 	return status;
1372 }
1373 
1374 /*************************************************************************
1375  _netr_ServerPasswordSet
1376  *************************************************************************/
1377 
_netr_ServerPasswordSet(struct pipes_struct * p,struct netr_ServerPasswordSet * r)1378 NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
1379 				 struct netr_ServerPasswordSet *r)
1380 {
1381 	NTSTATUS status = NT_STATUS_OK;
1382 	int i;
1383 	struct netlogon_creds_CredentialState *creds = NULL;
1384 	struct _samr_Credentials_t cr = { CRED_TYPE_NT_HASH, {0}};
1385 
1386 	DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
1387 
1388 	become_root();
1389 	status = netr_creds_server_step_check(p, p->mem_ctx,
1390 					      r->in.computer_name,
1391 					      r->in.credential,
1392 					      r->out.return_authenticator,
1393 					      &creds);
1394 	unbecome_root();
1395 
1396 	if (!NT_STATUS_IS_OK(status)) {
1397 		const char *computer_name = "<unknown>";
1398 
1399 		if (creds != NULL && creds->computer_name != NULL) {
1400 			computer_name = creds->computer_name;
1401 		}
1402 		DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth "
1403 			"request from client %s machine account %s\n",
1404 			r->in.computer_name, computer_name));
1405 		TALLOC_FREE(creds);
1406 		return status;
1407 	}
1408 
1409 	DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
1410 			r->in.computer_name, creds->computer_name));
1411 
1412 	status = netlogon_creds_des_decrypt(creds, r->in.new_password);
1413 	if (!NT_STATUS_IS_OK(status)) {
1414 		return status;
1415 	}
1416 
1417 	DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
1418 	for(i = 0; i < sizeof(r->in.new_password->hash); i++)
1419 		DEBUG(100,("%02X ", r->in.new_password->hash[i]));
1420 	DEBUG(100,("\n"));
1421 
1422 	cr.creds.nt_hash = r->in.new_password;
1423 	status = netr_set_machine_account_password(p->mem_ctx,
1424 						   p->session_info,
1425 						   p->msg_ctx,
1426 						   creds->account_name,
1427 						   &cr);
1428 	return status;
1429 }
1430 
1431 /****************************************************************
1432  _netr_ServerPasswordSet2
1433 ****************************************************************/
1434 
_netr_ServerPasswordSet2(struct pipes_struct * p,struct netr_ServerPasswordSet2 * r)1435 NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
1436 				  struct netr_ServerPasswordSet2 *r)
1437 {
1438 	NTSTATUS status;
1439 	struct netlogon_creds_CredentialState *creds = NULL;
1440 	DATA_BLOB plaintext = data_blob_null;
1441 	DATA_BLOB new_password = data_blob_null;
1442 	size_t confounder_len;
1443 	DATA_BLOB dec_blob = data_blob_null;
1444 	DATA_BLOB enc_blob = data_blob_null;
1445 	struct samr_CryptPassword password_buf;
1446 	struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}};
1447 	bool ok;
1448 
1449 	become_root();
1450 	status = netr_creds_server_step_check(p, p->mem_ctx,
1451 					      r->in.computer_name,
1452 					      r->in.credential,
1453 					      r->out.return_authenticator,
1454 					      &creds);
1455 	unbecome_root();
1456 
1457 	if (!NT_STATUS_IS_OK(status)) {
1458 		const char *computer_name = "<unknown>";
1459 
1460 		if (creds && creds->computer_name) {
1461 			computer_name = creds->computer_name;
1462 		}
1463 		DEBUG(2,("_netr_ServerPasswordSet2: netlogon_creds_server_step "
1464 			"failed. Rejecting auth request from client %s machine account %s\n",
1465 			r->in.computer_name, computer_name));
1466 		TALLOC_FREE(creds);
1467 		return status;
1468 	}
1469 
1470 	DEBUG(3,("_netr_ServerPasswordSet2: Server Password Seti2 by remote "
1471 		 "machine:[%s] on account [%s]\n",
1472 		 r->in.computer_name, creds->computer_name));
1473 
1474 	memcpy(password_buf.data, r->in.new_password->data, 512);
1475 	SIVAL(password_buf.data, 512, r->in.new_password->length);
1476 
1477 	if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1478 		status = netlogon_creds_aes_decrypt(creds,
1479 						    password_buf.data,
1480 						    516);
1481 	} else {
1482 		status = netlogon_creds_arcfour_crypt(creds,
1483 						      password_buf.data,
1484 						      516);
1485 	}
1486 	if (!NT_STATUS_IS_OK(status)) {
1487 		TALLOC_FREE(creds);
1488 		return status;
1489 	}
1490 
1491 	if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, &new_password)) {
1492 		DEBUG(2,("_netr_ServerPasswordSet2: unable to extract password "
1493 			 "from a buffer. Rejecting auth request as a wrong password\n"));
1494 		TALLOC_FREE(creds);
1495 		return NT_STATUS_WRONG_PASSWORD;
1496 	}
1497 
1498 	/*
1499 	 * Make sure the length field was encrypted,
1500 	 * otherwise we are under attack.
1501 	 */
1502 	if (new_password.length == r->in.new_password->length) {
1503 		DBG_WARNING("Length[%zu] field not encrypted\n",
1504 			new_password.length);
1505 		TALLOC_FREE(creds);
1506 		return NT_STATUS_WRONG_PASSWORD;
1507 	}
1508 
1509 	/*
1510 	 * We don't allow empty passwords for machine accounts.
1511 	 */
1512 	if (new_password.length < 2) {
1513 		DBG_WARNING("Empty password Length[%zu]\n",
1514 			new_password.length);
1515 		TALLOC_FREE(creds);
1516 		return NT_STATUS_WRONG_PASSWORD;
1517 	}
1518 
1519 	/*
1520 	 * Make sure the confounder part of CryptPassword
1521 	 * buffer was encrypted, otherwise we are under attack.
1522 	 */
1523 	confounder_len = 512 - new_password.length;
1524 	enc_blob = data_blob_const(r->in.new_password->data, confounder_len);
1525 	dec_blob = data_blob_const(password_buf.data, confounder_len);
1526 	if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
1527 		DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
1528 			    confounder_len);
1529 		TALLOC_FREE(creds);
1530 		return NT_STATUS_WRONG_PASSWORD;
1531 	}
1532 
1533 	/*
1534 	 * Check that the password part was actually encrypted,
1535 	 * otherwise we are under attack.
1536 	 */
1537 	enc_blob = data_blob_const(r->in.new_password->data + confounder_len,
1538 				   new_password.length);
1539 	dec_blob = data_blob_const(password_buf.data + confounder_len,
1540 				   new_password.length);
1541 	if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
1542 		DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
1543 			    new_password.length);
1544 		TALLOC_FREE(creds);
1545 		return NT_STATUS_WRONG_PASSWORD;
1546 	}
1547 
1548 	/*
1549 	 * don't allow zero buffers
1550 	 */
1551 	if (all_zero(new_password.data, new_password.length)) {
1552 		DBG_WARNING("Password zero buffer Length[%zu]\n",
1553 			    new_password.length);
1554 		TALLOC_FREE(creds);
1555 		return NT_STATUS_WRONG_PASSWORD;
1556 	}
1557 
1558 	/* Convert from UTF16 -> plaintext. */
1559 	ok = convert_string_talloc(p->mem_ctx,
1560 				CH_UTF16,
1561 				CH_UNIX,
1562 				new_password.data,
1563 				new_password.length,
1564 				(void *)&plaintext.data,
1565 				&plaintext.length);
1566 	if (!ok) {
1567 		DBG_WARNING("unable to extract password from a buffer. "
1568 			    "Rejecting auth request as a wrong password\n");
1569 		TALLOC_FREE(creds);
1570 		return NT_STATUS_WRONG_PASSWORD;
1571 	}
1572 
1573 	/*
1574 	 * We don't allow empty passwords for machine accounts.
1575 	 */
1576 
1577 	cr.creds.password = (const char*) plaintext.data;
1578 	if (strlen(cr.creds.password) == 0) {
1579 		DBG_WARNING("Empty plaintext password\n");
1580 		TALLOC_FREE(creds);
1581 		return NT_STATUS_WRONG_PASSWORD;
1582 	}
1583 
1584 	status = netr_set_machine_account_password(p->mem_ctx,
1585 						   p->session_info,
1586 						   p->msg_ctx,
1587 						   creds->account_name,
1588 						   &cr);
1589 	TALLOC_FREE(creds);
1590 	return status;
1591 }
1592 
1593 /*************************************************************************
1594  _netr_LogonSamLogoff
1595  *************************************************************************/
1596 
_netr_LogonSamLogoff(struct pipes_struct * p,struct netr_LogonSamLogoff * r)1597 NTSTATUS _netr_LogonSamLogoff(struct pipes_struct *p,
1598 			      struct netr_LogonSamLogoff *r)
1599 {
1600 	NTSTATUS status;
1601 	struct netlogon_creds_CredentialState *creds;
1602 
1603 	become_root();
1604 	status = netr_creds_server_step_check(p, p->mem_ctx,
1605 					      r->in.computer_name,
1606 					      r->in.credential,
1607 					      r->out.return_authenticator,
1608 					      &creds);
1609 	unbecome_root();
1610 
1611 	return status;
1612 }
1613 
_netr_LogonSamLogon_check(const struct netr_LogonSamLogonEx * r)1614 static NTSTATUS _netr_LogonSamLogon_check(const struct netr_LogonSamLogonEx *r)
1615 {
1616 	switch (r->in.logon_level) {
1617 	case NetlogonInteractiveInformation:
1618 	case NetlogonServiceInformation:
1619 	case NetlogonInteractiveTransitiveInformation:
1620 	case NetlogonServiceTransitiveInformation:
1621 		if (r->in.logon->password == NULL) {
1622 			return NT_STATUS_INVALID_PARAMETER;
1623 		}
1624 
1625 		switch (r->in.validation_level) {
1626 		case NetlogonValidationSamInfo:  /* 2 */
1627 		case NetlogonValidationSamInfo2: /* 3 */
1628 			break;
1629 		case NetlogonValidationSamInfo4: /* 6 */
1630 			if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
1631 				DEBUG(10,("Not adding validation info level 6 "
1632 				   "without ADS passdb backend\n"));
1633 				return NT_STATUS_INVALID_INFO_CLASS;
1634 			}
1635 			break;
1636 		default:
1637 			return NT_STATUS_INVALID_INFO_CLASS;
1638 		}
1639 
1640 		break;
1641 	case NetlogonNetworkInformation:
1642 	case NetlogonNetworkTransitiveInformation:
1643 		if (r->in.logon->network == NULL) {
1644 			return NT_STATUS_INVALID_PARAMETER;
1645 		}
1646 
1647 		switch (r->in.validation_level) {
1648 		case NetlogonValidationSamInfo:  /* 2 */
1649 		case NetlogonValidationSamInfo2: /* 3 */
1650 			break;
1651 		case NetlogonValidationSamInfo4: /* 6 */
1652 			if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
1653 				DEBUG(10,("Not adding validation info level 6 "
1654 				   "without ADS passdb backend\n"));
1655 				return NT_STATUS_INVALID_INFO_CLASS;
1656 			}
1657 			break;
1658 		default:
1659 			return NT_STATUS_INVALID_INFO_CLASS;
1660 		}
1661 
1662 		break;
1663 
1664 	case NetlogonGenericInformation:
1665 		if (r->in.logon->generic == NULL) {
1666 			return NT_STATUS_INVALID_PARAMETER;
1667 		}
1668 
1669 		/* we don't support this here */
1670 		return NT_STATUS_INVALID_PARAMETER;
1671 #if 0
1672 		switch (r->in.validation_level) {
1673 		/* TODO: case NetlogonValidationGenericInfo: 4 */
1674 		case NetlogonValidationGenericInfo2: /* 5 */
1675 			break;
1676 		default:
1677 			return NT_STATUS_INVALID_INFO_CLASS;
1678 		}
1679 
1680 		break;
1681 #endif
1682 	default:
1683 		return NT_STATUS_INVALID_PARAMETER;
1684 	}
1685 
1686 	return NT_STATUS_OK;
1687 }
1688 
1689 /*************************************************************************
1690  _netr_LogonSamLogon_base
1691  *************************************************************************/
1692 
_netr_LogonSamLogon_base(struct pipes_struct * p,struct netr_LogonSamLogonEx * r,struct netlogon_creds_CredentialState * creds)1693 static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
1694 					 struct netr_LogonSamLogonEx *r,
1695 					 struct netlogon_creds_CredentialState *creds)
1696 {
1697 	NTSTATUS status = NT_STATUS_OK;
1698 	union netr_LogonLevel *logon = r->in.logon;
1699 	const char *nt_username, *nt_domain, *nt_workstation;
1700 	struct auth_usersupplied_info *user_info = NULL;
1701 	struct auth_serversupplied_info *server_info = NULL;
1702 	struct auth_context *auth_context = NULL;
1703 	const char *fn;
1704 
1705 #ifdef DEBUG_PASSWORD
1706 	logon = netlogon_creds_shallow_copy_logon(p->mem_ctx,
1707 						  r->in.logon_level,
1708 						  r->in.logon);
1709 	if (logon == NULL) {
1710 		logon = r->in.logon;
1711 	}
1712 #endif
1713 
1714 	switch (p->opnum) {
1715 		case NDR_NETR_LOGONSAMLOGON:
1716 			fn = "_netr_LogonSamLogon";
1717 			break;
1718 		case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
1719 			fn = "_netr_LogonSamLogonWithFlags";
1720 			break;
1721 		case NDR_NETR_LOGONSAMLOGONEX:
1722 			fn = "_netr_LogonSamLogonEx";
1723 			break;
1724 		default:
1725 			return NT_STATUS_INTERNAL_ERROR;
1726 	}
1727 
1728 	*r->out.authoritative = 1; /* authoritative response */
1729 
1730 	switch (r->in.validation_level) {
1731 	case 2:
1732 		r->out.validation->sam2 = talloc_zero(p->mem_ctx, struct netr_SamInfo2);
1733 		if (!r->out.validation->sam2) {
1734 			return NT_STATUS_NO_MEMORY;
1735 		}
1736 		break;
1737 	case 3:
1738 		r->out.validation->sam3 = talloc_zero(p->mem_ctx, struct netr_SamInfo3);
1739 		if (!r->out.validation->sam3) {
1740 			return NT_STATUS_NO_MEMORY;
1741 		}
1742 		break;
1743 	case 6:
1744 		r->out.validation->sam6 = talloc_zero(p->mem_ctx, struct netr_SamInfo6);
1745 		if (!r->out.validation->sam6) {
1746 			return NT_STATUS_NO_MEMORY;
1747 		}
1748 		break;
1749 	default:
1750 		DEBUG(0,("%s: bad validation_level value %d.\n",
1751 			fn, (int)r->in.validation_level));
1752 		return NT_STATUS_INVALID_INFO_CLASS;
1753 	}
1754 
1755 	switch (r->in.logon_level) {
1756 	case NetlogonInteractiveInformation:
1757 	case NetlogonServiceInformation:
1758 	case NetlogonInteractiveTransitiveInformation:
1759 	case NetlogonServiceTransitiveInformation:
1760 		nt_username	= logon->password->identity_info.account_name.string ?
1761 				  logon->password->identity_info.account_name.string : "";
1762 		nt_domain	= logon->password->identity_info.domain_name.string ?
1763 				  logon->password->identity_info.domain_name.string : "";
1764 		nt_workstation	= logon->password->identity_info.workstation.string ?
1765 				  logon->password->identity_info.workstation.string : "";
1766 
1767 		DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", lp_workgroup()));
1768 		break;
1769 	case NetlogonNetworkInformation:
1770 	case NetlogonNetworkTransitiveInformation:
1771 		nt_username	= logon->network->identity_info.account_name.string ?
1772 				  logon->network->identity_info.account_name.string : "";
1773 		nt_domain	= logon->network->identity_info.domain_name.string ?
1774 				  logon->network->identity_info.domain_name.string : "";
1775 		nt_workstation	= logon->network->identity_info.workstation.string ?
1776 				  logon->network->identity_info.workstation.string : "";
1777 
1778 		DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", lp_workgroup()));
1779 		break;
1780 	default:
1781 		DEBUG(2,("SAM Logon: unsupported switch value\n"));
1782 		return NT_STATUS_INVALID_INFO_CLASS;
1783 	} /* end switch */
1784 
1785 	DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username, nt_workstation, nt_domain));
1786 	fstrcpy(current_user_info.smb_name, nt_username);
1787 	sub_set_smb_name(nt_username);
1788 
1789 	DEBUG(5,("Attempting validation level %d for unmapped username %s.\n",
1790 		r->in.validation_level, nt_username));
1791 
1792 	status = netlogon_creds_decrypt_samlogon_logon(creds,
1793 						       r->in.logon_level,
1794 						       logon);
1795 	if (!NT_STATUS_IS_OK(status)) {
1796 		return status;
1797 	}
1798 
1799 	status = make_auth3_context_for_netlogon(talloc_tos(), &auth_context);
1800 	if (!NT_STATUS_IS_OK(status)) {
1801 		return status;
1802 	}
1803 
1804 	switch (r->in.logon_level) {
1805 	case NetlogonNetworkInformation:
1806 	case NetlogonNetworkTransitiveInformation:
1807 	{
1808 		const char *wksname = nt_workstation;
1809 		const char *workgroup = lp_workgroup();
1810 		bool ok;
1811 
1812 		ok = auth3_context_set_challenge(
1813 			auth_context, logon->network->challenge, "fixed");
1814 		if (!ok) {
1815 			return NT_STATUS_NO_MEMORY;
1816 		}
1817 
1818 		/* For a network logon, the workstation name comes in with two
1819 		 * backslashes in the front. Strip them if they are there. */
1820 
1821 		if (*wksname == '\\') wksname++;
1822 		if (*wksname == '\\') wksname++;
1823 
1824 		/* Standard challenge/response authentication */
1825 		if (!make_user_info_netlogon_network(talloc_tos(),
1826 						     &user_info,
1827 						     nt_username, nt_domain,
1828 						     wksname,
1829 						     p->remote_address,
1830 						     p->local_address,
1831 						     logon->network->identity_info.parameter_control,
1832 						     logon->network->lm.data,
1833 						     logon->network->lm.length,
1834 						     logon->network->nt.data,
1835 						     logon->network->nt.length)) {
1836 			status = NT_STATUS_NO_MEMORY;
1837 		}
1838 
1839 		if (NT_STATUS_IS_OK(status)) {
1840 			status = NTLMv2_RESPONSE_verify_netlogon_creds(
1841 						user_info->client.account_name,
1842 						user_info->client.domain_name,
1843 						user_info->password.response.nt,
1844 						creds, workgroup);
1845 		}
1846 		break;
1847 	}
1848 	case NetlogonInteractiveInformation:
1849 	case NetlogonServiceInformation:
1850 	case NetlogonInteractiveTransitiveInformation:
1851 	case NetlogonServiceTransitiveInformation:
1852 
1853 		/* 'Interactive' authentication, supplies the password in its
1854 		   MD4 form, encrypted with the session key.  We will convert
1855 		   this to challenge/response for the auth subsystem to chew
1856 		   on */
1857 	{
1858 		uint8_t chal[8];
1859 
1860 #ifdef DEBUG_PASSWORD
1861 		if (logon != r->in.logon) {
1862 			DEBUG(100,("lm owf password:"));
1863 			dump_data(100,
1864 				  r->in.logon->password->lmpassword.hash, 16);
1865 
1866 			DEBUG(100,("nt owf password:"));
1867 			dump_data(100,
1868 				  r->in.logon->password->ntpassword.hash, 16);
1869 		}
1870 
1871 		DEBUG(100,("decrypt of lm owf password:"));
1872 		dump_data(100, logon->password->lmpassword.hash, 16);
1873 
1874 		DEBUG(100,("decrypt of nt owf password:"));
1875 		dump_data(100, logon->password->ntpassword.hash, 16);
1876 #endif
1877 
1878 		auth_get_ntlm_challenge(auth_context, chal);
1879 
1880 		if (!make_user_info_netlogon_interactive(talloc_tos(),
1881 							 &user_info,
1882 							 nt_username, nt_domain,
1883 							 nt_workstation,
1884 							 p->remote_address,
1885 							 p->local_address,
1886 							 logon->password->identity_info.parameter_control,
1887 							 chal,
1888 							 logon->password->lmpassword.hash,
1889 							 logon->password->ntpassword.hash)) {
1890 			status = NT_STATUS_NO_MEMORY;
1891 		}
1892 		break;
1893 	}
1894 	default:
1895 		DEBUG(2,("SAM Logon: unsupported switch value\n"));
1896 		return NT_STATUS_INVALID_INFO_CLASS;
1897 	} /* end switch */
1898 
1899 	if ( NT_STATUS_IS_OK(status) ) {
1900 		status = auth_check_ntlm_password(p->mem_ctx,
1901 						  auth_context,
1902 						  user_info,
1903 						  &server_info,
1904 						  r->out.authoritative);
1905 	}
1906 
1907 	TALLOC_FREE(auth_context);
1908 	TALLOC_FREE(user_info);
1909 
1910 	DEBUG(5,("%s: check_password returned status %s\n",
1911 		  fn, nt_errstr(status)));
1912 
1913 	/* Check account and password */
1914 
1915 	if (!NT_STATUS_IS_OK(status)) {
1916 		TALLOC_FREE(server_info);
1917 		return status;
1918 	}
1919 
1920 	if (server_info->guest) {
1921 		/* We don't like guest domain logons... */
1922 		DEBUG(5,("%s: Attempted domain logon as GUEST "
1923 			 "denied.\n", fn));
1924 		TALLOC_FREE(server_info);
1925 		return NT_STATUS_LOGON_FAILURE;
1926 	}
1927 
1928 	/* This is the point at which, if the login was successful, that
1929            the SAM Local Security Authority should record that the user is
1930            logged in to the domain.  */
1931 
1932 	switch (r->in.validation_level) {
1933 	case 2:
1934 		status = serverinfo_to_SamInfo2(server_info,
1935 						r->out.validation->sam2);
1936 		break;
1937 	case 3:
1938 		status = serverinfo_to_SamInfo3(server_info,
1939 						r->out.validation->sam3);
1940 		break;
1941 	case 6:
1942 		/* Only allow this if the pipe is protected. */
1943 		if (p->auth.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
1944 			DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n",
1945 				get_remote_machine_name()));
1946 			status = NT_STATUS_INVALID_PARAMETER;
1947 			break;
1948 		}
1949 
1950 		status = serverinfo_to_SamInfo6(server_info,
1951 						r->out.validation->sam6);
1952 		break;
1953 	}
1954 
1955 	TALLOC_FREE(server_info);
1956 
1957 	if (!NT_STATUS_IS_OK(status)) {
1958 		return status;
1959 	}
1960 
1961 	status = netlogon_creds_encrypt_samlogon_validation(creds,
1962 							    r->in.validation_level,
1963 							    r->out.validation);
1964 
1965 	return status;
1966 }
1967 
1968 /****************************************************************
1969  _netr_LogonSamLogonWithFlags
1970 ****************************************************************/
1971 
_netr_LogonSamLogonWithFlags(struct pipes_struct * p,struct netr_LogonSamLogonWithFlags * r)1972 NTSTATUS _netr_LogonSamLogonWithFlags(struct pipes_struct *p,
1973 				      struct netr_LogonSamLogonWithFlags *r)
1974 {
1975 	NTSTATUS status;
1976 	struct netlogon_creds_CredentialState *creds;
1977 	struct netr_LogonSamLogonEx r2;
1978 	struct netr_Authenticator return_authenticator;
1979 
1980 	*r->out.authoritative = true;
1981 
1982 	r2.in.server_name	= r->in.server_name;
1983 	r2.in.computer_name	= r->in.computer_name;
1984 	r2.in.logon_level	= r->in.logon_level;
1985 	r2.in.logon		= r->in.logon;
1986 	r2.in.validation_level	= r->in.validation_level;
1987 	r2.in.flags		= r->in.flags;
1988 	r2.out.validation	= r->out.validation;
1989 	r2.out.authoritative	= r->out.authoritative;
1990 	r2.out.flags		= r->out.flags;
1991 
1992 	status = _netr_LogonSamLogon_check(&r2);
1993 	if (!NT_STATUS_IS_OK(status)) {
1994 		return status;
1995 	}
1996 
1997 	become_root();
1998 	status = netr_creds_server_step_check(p, p->mem_ctx,
1999 					      r->in.computer_name,
2000 					      r->in.credential,
2001 					      &return_authenticator,
2002 					      &creds);
2003 	unbecome_root();
2004 	if (!NT_STATUS_IS_OK(status)) {
2005 		return status;
2006 	}
2007 
2008 	status = _netr_LogonSamLogon_base(p, &r2, creds);
2009 
2010 	*r->out.return_authenticator = return_authenticator;
2011 
2012 	return status;
2013 }
2014 
2015 /*************************************************************************
2016  _netr_LogonSamLogon
2017  *************************************************************************/
2018 
_netr_LogonSamLogon(struct pipes_struct * p,struct netr_LogonSamLogon * r)2019 NTSTATUS _netr_LogonSamLogon(struct pipes_struct *p,
2020 			     struct netr_LogonSamLogon *r)
2021 {
2022 	NTSTATUS status;
2023 	struct netr_LogonSamLogonWithFlags r2;
2024 	uint32_t flags = 0;
2025 
2026 	r2.in.server_name		= r->in.server_name;
2027 	r2.in.computer_name		= r->in.computer_name;
2028 	r2.in.credential		= r->in.credential;
2029 	r2.in.logon_level		= r->in.logon_level;
2030 	r2.in.logon			= r->in.logon;
2031 	r2.in.validation_level		= r->in.validation_level;
2032 	r2.in.return_authenticator	= r->in.return_authenticator;
2033 	r2.in.flags			= &flags;
2034 	r2.out.validation		= r->out.validation;
2035 	r2.out.authoritative		= r->out.authoritative;
2036 	r2.out.flags			= &flags;
2037 	r2.out.return_authenticator	= r->out.return_authenticator;
2038 
2039 	status = _netr_LogonSamLogonWithFlags(p, &r2);
2040 
2041 	return status;
2042 }
2043 
2044 /*************************************************************************
2045  _netr_LogonSamLogonEx
2046  - no credential chaining. Map into net sam logon.
2047  *************************************************************************/
2048 
_netr_LogonSamLogonEx(struct pipes_struct * p,struct netr_LogonSamLogonEx * r)2049 NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
2050 			       struct netr_LogonSamLogonEx *r)
2051 {
2052 	NTSTATUS status;
2053 	struct netlogon_creds_CredentialState *creds = NULL;
2054 	struct loadparm_context *lp_ctx;
2055 
2056 	*r->out.authoritative = true;
2057 
2058 	status = _netr_LogonSamLogon_check(r);
2059 	if (!NT_STATUS_IS_OK(status)) {
2060 		return status;
2061 	}
2062 
2063 	/* Only allow this if the pipe is protected. */
2064 	if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
2065 		DEBUG(0,("_netr_LogonSamLogonEx: client %s not using schannel for netlogon\n",
2066 			get_remote_machine_name() ));
2067 		return NT_STATUS_INVALID_PARAMETER;
2068         }
2069 
2070 	lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
2071 	if (lp_ctx == NULL) {
2072 		DEBUG(0, ("loadparm_init_s3 failed\n"));
2073 		return NT_STATUS_INTERNAL_ERROR;
2074 	}
2075 
2076 	become_root();
2077 	status = schannel_get_creds_state(p->mem_ctx, lp_ctx,
2078 					  r->in.computer_name, &creds);
2079 	unbecome_root();
2080 	talloc_unlink(p->mem_ctx, lp_ctx);
2081 
2082 	if (!NT_STATUS_IS_OK(status)) {
2083 		return status;
2084 	}
2085 
2086 	status = _netr_LogonSamLogon_base(p, r, creds);
2087 	TALLOC_FREE(creds);
2088 
2089 	return status;
2090 }
2091 
2092 /*************************************************************************
2093  _ds_enum_dom_trusts
2094  *************************************************************************/
2095 #if 0	/* JERRY -- not correct */
2096  NTSTATUS _ds_enum_dom_trusts(struct pipes_struct *p, DS_Q_ENUM_DOM_TRUSTS *q_u,
2097 			     DS_R_ENUM_DOM_TRUSTS *r_u)
2098 {
2099 	NTSTATUS status = NT_STATUS_OK;
2100 
2101 	/* TODO: According to MSDN, the can only be executed against a
2102 	   DC or domain member running Windows 2000 or later.  Need
2103 	   to test against a standalone 2k server and see what it
2104 	   does.  A windows 2000 DC includes its own domain in the
2105 	   list.  --jerry */
2106 
2107 	return status;
2108 }
2109 #endif	/* JERRY */
2110 
2111 
2112 /****************************************************************
2113 ****************************************************************/
2114 
_netr_LogonUasLogon(struct pipes_struct * p,struct netr_LogonUasLogon * r)2115 WERROR _netr_LogonUasLogon(struct pipes_struct *p,
2116 			   struct netr_LogonUasLogon *r)
2117 {
2118 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2119 	return WERR_NOT_SUPPORTED;
2120 }
2121 
2122 /****************************************************************
2123 ****************************************************************/
2124 
_netr_LogonUasLogoff(struct pipes_struct * p,struct netr_LogonUasLogoff * r)2125 WERROR _netr_LogonUasLogoff(struct pipes_struct *p,
2126 			    struct netr_LogonUasLogoff *r)
2127 {
2128 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2129 	return WERR_NOT_SUPPORTED;
2130 }
2131 
2132 /****************************************************************
2133 ****************************************************************/
2134 
_netr_DatabaseDeltas(struct pipes_struct * p,struct netr_DatabaseDeltas * r)2135 NTSTATUS _netr_DatabaseDeltas(struct pipes_struct *p,
2136 			      struct netr_DatabaseDeltas *r)
2137 {
2138 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2139 	return NT_STATUS_NOT_IMPLEMENTED;
2140 }
2141 
2142 /****************************************************************
2143 ****************************************************************/
2144 
_netr_DatabaseSync(struct pipes_struct * p,struct netr_DatabaseSync * r)2145 NTSTATUS _netr_DatabaseSync(struct pipes_struct *p,
2146 			    struct netr_DatabaseSync *r)
2147 {
2148 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2149 	return NT_STATUS_NOT_IMPLEMENTED;
2150 }
2151 
2152 /****************************************************************
2153 ****************************************************************/
2154 
_netr_AccountDeltas(struct pipes_struct * p,struct netr_AccountDeltas * r)2155 NTSTATUS _netr_AccountDeltas(struct pipes_struct *p,
2156 			     struct netr_AccountDeltas *r)
2157 {
2158 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2159 	return NT_STATUS_NOT_IMPLEMENTED;
2160 }
2161 
2162 /****************************************************************
2163 ****************************************************************/
2164 
_netr_AccountSync(struct pipes_struct * p,struct netr_AccountSync * r)2165 NTSTATUS _netr_AccountSync(struct pipes_struct *p,
2166 			   struct netr_AccountSync *r)
2167 {
2168 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2169 	return NT_STATUS_NOT_IMPLEMENTED;
2170 }
2171 
2172 /****************************************************************
2173 ****************************************************************/
2174 
wb_getdcname(TALLOC_CTX * mem_ctx,const char * domain,const char ** dcname,uint32_t flags,WERROR * werr)2175 static bool wb_getdcname(TALLOC_CTX *mem_ctx,
2176 			 const char *domain,
2177 			 const char **dcname,
2178 			 uint32_t flags,
2179 			 WERROR *werr)
2180 {
2181 	wbcErr result;
2182 	struct wbcDomainControllerInfo *dc_info = NULL;
2183 
2184 	result = wbcLookupDomainController(domain,
2185 					   flags,
2186 					   &dc_info);
2187 	switch (result) {
2188 	case WBC_ERR_SUCCESS:
2189 		break;
2190 	case WBC_ERR_WINBIND_NOT_AVAILABLE:
2191 		return false;
2192 	case WBC_ERR_DOMAIN_NOT_FOUND:
2193 		*werr = WERR_NO_SUCH_DOMAIN;
2194 		return true;
2195 	default:
2196 		*werr = WERR_DOMAIN_CONTROLLER_NOT_FOUND;
2197 		return true;
2198 	}
2199 
2200 	*dcname = talloc_strdup(mem_ctx, dc_info->dc_name);
2201 	wbcFreeMemory(dc_info);
2202 	if (!*dcname) {
2203 		*werr = WERR_NOT_ENOUGH_MEMORY;
2204 		return false;
2205 	}
2206 
2207 	*werr = WERR_OK;
2208 
2209 	return true;
2210 }
2211 
2212 /****************************************************************
2213  _netr_GetDcName
2214 ****************************************************************/
2215 
_netr_GetDcName(struct pipes_struct * p,struct netr_GetDcName * r)2216 WERROR _netr_GetDcName(struct pipes_struct *p,
2217 		       struct netr_GetDcName *r)
2218 {
2219 	NTSTATUS status;
2220 	WERROR werr;
2221 	uint32_t flags;
2222 	struct netr_DsRGetDCNameInfo *info;
2223 	bool ret;
2224 
2225 	ret = wb_getdcname(p->mem_ctx,
2226 			   r->in.domainname,
2227 			   r->out.dcname,
2228 			   WBC_LOOKUP_DC_IS_FLAT_NAME |
2229 			   WBC_LOOKUP_DC_RETURN_FLAT_NAME |
2230 			   WBC_LOOKUP_DC_PDC_REQUIRED,
2231 			   &werr);
2232 	if (ret == true) {
2233 		return werr;
2234 	}
2235 
2236 	flags = DS_PDC_REQUIRED | DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME;
2237 
2238 	status = dsgetdcname(p->mem_ctx,
2239 			     p->msg_ctx,
2240 			     r->in.domainname,
2241 			     NULL,
2242 			     NULL,
2243 			     flags,
2244 			     &info);
2245 	if (!NT_STATUS_IS_OK(status)) {
2246 		return ntstatus_to_werror(status);
2247 	}
2248 
2249 	*r->out.dcname = talloc_strdup(p->mem_ctx, info->dc_unc);
2250 	talloc_free(info);
2251 	if (!*r->out.dcname) {
2252 		return WERR_NOT_ENOUGH_MEMORY;
2253 	}
2254 
2255 	return WERR_OK;
2256 }
2257 
2258 /****************************************************************
2259  _netr_GetAnyDCName
2260 ****************************************************************/
2261 
_netr_GetAnyDCName(struct pipes_struct * p,struct netr_GetAnyDCName * r)2262 WERROR _netr_GetAnyDCName(struct pipes_struct *p,
2263 			  struct netr_GetAnyDCName *r)
2264 {
2265 	NTSTATUS status;
2266 	WERROR werr;
2267 	uint32_t flags;
2268 	struct netr_DsRGetDCNameInfo *info;
2269 	bool ret;
2270 
2271 	ret = wb_getdcname(p->mem_ctx,
2272 			   r->in.domainname,
2273 			   r->out.dcname,
2274 			   WBC_LOOKUP_DC_IS_FLAT_NAME |
2275 			   WBC_LOOKUP_DC_RETURN_FLAT_NAME,
2276 			   &werr);
2277 	if (ret == true) {
2278 		return werr;
2279 	}
2280 
2281 	flags = DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME;
2282 
2283 	status = dsgetdcname(p->mem_ctx,
2284 			     p->msg_ctx,
2285 			     r->in.domainname,
2286 			     NULL,
2287 			     NULL,
2288 			     flags,
2289 			     &info);
2290 	if (!NT_STATUS_IS_OK(status)) {
2291 		return ntstatus_to_werror(status);
2292 	}
2293 
2294 	*r->out.dcname = talloc_strdup(p->mem_ctx, info->dc_unc);
2295 	talloc_free(info);
2296 	if (!*r->out.dcname) {
2297 		return WERR_NOT_ENOUGH_MEMORY;
2298 	}
2299 
2300 	return WERR_OK;
2301 }
2302 
2303 /****************************************************************
2304 ****************************************************************/
2305 
_netr_DatabaseSync2(struct pipes_struct * p,struct netr_DatabaseSync2 * r)2306 NTSTATUS _netr_DatabaseSync2(struct pipes_struct *p,
2307 			     struct netr_DatabaseSync2 *r)
2308 {
2309 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2310 	return NT_STATUS_NOT_IMPLEMENTED;
2311 }
2312 
2313 /****************************************************************
2314 ****************************************************************/
2315 
_netr_DatabaseRedo(struct pipes_struct * p,struct netr_DatabaseRedo * r)2316 NTSTATUS _netr_DatabaseRedo(struct pipes_struct *p,
2317 			    struct netr_DatabaseRedo *r)
2318 {
2319 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2320 	return NT_STATUS_NOT_IMPLEMENTED;
2321 }
2322 
2323 /****************************************************************
2324 ****************************************************************/
2325 
_netr_DsRGetDCName(struct pipes_struct * p,struct netr_DsRGetDCName * r)2326 WERROR _netr_DsRGetDCName(struct pipes_struct *p,
2327 			  struct netr_DsRGetDCName *r)
2328 {
2329 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2330 	return WERR_NOT_SUPPORTED;
2331 }
2332 
2333 /****************************************************************
2334 ****************************************************************/
2335 
_netr_LogonGetCapabilities(struct pipes_struct * p,struct netr_LogonGetCapabilities * r)2336 NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
2337 				    struct netr_LogonGetCapabilities *r)
2338 {
2339 	struct netlogon_creds_CredentialState *creds;
2340 	NTSTATUS status;
2341 
2342 	become_root();
2343 	status = netr_creds_server_step_check(p, p->mem_ctx,
2344 					      r->in.computer_name,
2345 					      r->in.credential,
2346 					      r->out.return_authenticator,
2347 					      &creds);
2348 	unbecome_root();
2349 	if (!NT_STATUS_IS_OK(status)) {
2350 		return status;
2351 	}
2352 
2353 	if (r->in.query_level != 1) {
2354 		return NT_STATUS_NOT_SUPPORTED;
2355 	}
2356 
2357 	r->out.capabilities->server_capabilities = creds->negotiate_flags;
2358 
2359 	return NT_STATUS_OK;
2360 }
2361 
2362 /****************************************************************
2363 ****************************************************************/
2364 
_netr_NETRLOGONSETSERVICEBITS(struct pipes_struct * p,struct netr_NETRLOGONSETSERVICEBITS * r)2365 WERROR _netr_NETRLOGONSETSERVICEBITS(struct pipes_struct *p,
2366 				     struct netr_NETRLOGONSETSERVICEBITS *r)
2367 {
2368 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2369 	return WERR_NOT_SUPPORTED;
2370 }
2371 
2372 /****************************************************************
2373 ****************************************************************/
2374 
_netr_LogonGetTrustRid(struct pipes_struct * p,struct netr_LogonGetTrustRid * r)2375 WERROR _netr_LogonGetTrustRid(struct pipes_struct *p,
2376 			      struct netr_LogonGetTrustRid *r)
2377 {
2378 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2379 	return WERR_NOT_SUPPORTED;
2380 }
2381 
2382 /****************************************************************
2383 ****************************************************************/
2384 
_netr_NETRLOGONCOMPUTESERVERDIGEST(struct pipes_struct * p,struct netr_NETRLOGONCOMPUTESERVERDIGEST * r)2385 WERROR _netr_NETRLOGONCOMPUTESERVERDIGEST(struct pipes_struct *p,
2386 					  struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
2387 {
2388 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2389 	return WERR_NOT_SUPPORTED;
2390 }
2391 
2392 /****************************************************************
2393 ****************************************************************/
2394 
_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct pipes_struct * p,struct netr_NETRLOGONCOMPUTECLIENTDIGEST * r)2395 WERROR _netr_NETRLOGONCOMPUTECLIENTDIGEST(struct pipes_struct *p,
2396 					  struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
2397 {
2398 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2399 	return WERR_NOT_SUPPORTED;
2400 }
2401 
2402 /****************************************************************
2403 ****************************************************************/
2404 
_netr_DsRGetDCNameEx(struct pipes_struct * p,struct netr_DsRGetDCNameEx * r)2405 WERROR _netr_DsRGetDCNameEx(struct pipes_struct *p,
2406 			    struct netr_DsRGetDCNameEx *r)
2407 {
2408 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2409 	return WERR_NOT_SUPPORTED;
2410 }
2411 
2412 /****************************************************************
2413 ****************************************************************/
2414 
_netr_DsRGetSiteName(struct pipes_struct * p,struct netr_DsRGetSiteName * r)2415 WERROR _netr_DsRGetSiteName(struct pipes_struct *p,
2416 			    struct netr_DsRGetSiteName *r)
2417 {
2418 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2419 	return WERR_NOT_SUPPORTED;
2420 }
2421 
2422 /****************************************************************
2423 ****************************************************************/
2424 
_netr_LogonGetDomainInfo(struct pipes_struct * p,struct netr_LogonGetDomainInfo * r)2425 NTSTATUS _netr_LogonGetDomainInfo(struct pipes_struct *p,
2426 				  struct netr_LogonGetDomainInfo *r)
2427 {
2428 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2429 	return NT_STATUS_NOT_IMPLEMENTED;
2430 }
2431 
2432 /****************************************************************
2433 ****************************************************************/
2434 
_netr_ServerPasswordGet(struct pipes_struct * p,struct netr_ServerPasswordGet * r)2435 NTSTATUS _netr_ServerPasswordGet(struct pipes_struct *p,
2436 				 struct netr_ServerPasswordGet *r)
2437 {
2438 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2439 	return NT_STATUS_NOT_SUPPORTED;
2440 }
2441 
2442 /****************************************************************
2443 ****************************************************************/
2444 
_netr_NetrLogonSendToSam(struct pipes_struct * p,struct netr_NetrLogonSendToSam * r)2445 NTSTATUS _netr_NetrLogonSendToSam(struct pipes_struct *p,
2446 				struct netr_NetrLogonSendToSam *r)
2447 {
2448 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2449 	return NT_STATUS_NOT_IMPLEMENTED;
2450 }
2451 
2452 /****************************************************************
2453 ****************************************************************/
2454 
_netr_DsRAddressToSitenamesW(struct pipes_struct * p,struct netr_DsRAddressToSitenamesW * r)2455 WERROR _netr_DsRAddressToSitenamesW(struct pipes_struct *p,
2456 				    struct netr_DsRAddressToSitenamesW *r)
2457 {
2458 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2459 	return WERR_NOT_SUPPORTED;
2460 }
2461 
2462 /****************************************************************
2463 ****************************************************************/
2464 
_netr_DsRGetDCNameEx2(struct pipes_struct * p,struct netr_DsRGetDCNameEx2 * r)2465 WERROR _netr_DsRGetDCNameEx2(struct pipes_struct *p,
2466 			     struct netr_DsRGetDCNameEx2 *r)
2467 {
2468 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2469 	return WERR_NOT_SUPPORTED;
2470 }
2471 
2472 /****************************************************************
2473 ****************************************************************/
2474 
_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct pipes_struct * p,struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN * r)2475 WERROR _netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct pipes_struct *p,
2476 						 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
2477 {
2478 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2479 	return WERR_NOT_SUPPORTED;
2480 }
2481 
2482 /****************************************************************
2483 ****************************************************************/
2484 
_netr_NetrEnumerateTrustedDomainsEx(struct pipes_struct * p,struct netr_NetrEnumerateTrustedDomainsEx * r)2485 WERROR _netr_NetrEnumerateTrustedDomainsEx(struct pipes_struct *p,
2486 					   struct netr_NetrEnumerateTrustedDomainsEx *r)
2487 {
2488 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2489 	return WERR_NOT_SUPPORTED;
2490 }
2491 
2492 /****************************************************************
2493 ****************************************************************/
2494 
_netr_DsRAddressToSitenamesExW(struct pipes_struct * p,struct netr_DsRAddressToSitenamesExW * r)2495 WERROR _netr_DsRAddressToSitenamesExW(struct pipes_struct *p,
2496 				      struct netr_DsRAddressToSitenamesExW *r)
2497 {
2498 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2499 	return WERR_NOT_SUPPORTED;
2500 }
2501 
2502 /****************************************************************
2503 ****************************************************************/
2504 
_netr_DsrGetDcSiteCoverageW(struct pipes_struct * p,struct netr_DsrGetDcSiteCoverageW * r)2505 WERROR _netr_DsrGetDcSiteCoverageW(struct pipes_struct *p,
2506 				   struct netr_DsrGetDcSiteCoverageW *r)
2507 {
2508 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2509 	return WERR_NOT_SUPPORTED;
2510 }
2511 
2512 /****************************************************************
2513 ****************************************************************/
2514 
_netr_DsrEnumerateDomainTrusts(struct pipes_struct * p,struct netr_DsrEnumerateDomainTrusts * r)2515 WERROR _netr_DsrEnumerateDomainTrusts(struct pipes_struct *p,
2516 				      struct netr_DsrEnumerateDomainTrusts *r)
2517 {
2518 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2519 	return WERR_NOT_SUPPORTED;
2520 }
2521 
2522 /****************************************************************
2523 ****************************************************************/
2524 
_netr_DsrDeregisterDNSHostRecords(struct pipes_struct * p,struct netr_DsrDeregisterDNSHostRecords * r)2525 WERROR _netr_DsrDeregisterDNSHostRecords(struct pipes_struct *p,
2526 					 struct netr_DsrDeregisterDNSHostRecords *r)
2527 {
2528 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2529 	return WERR_NOT_SUPPORTED;
2530 }
2531 
2532 /****************************************************************
2533 ****************************************************************/
2534 
_netr_ServerTrustPasswordsGet(struct pipes_struct * p,struct netr_ServerTrustPasswordsGet * r)2535 NTSTATUS _netr_ServerTrustPasswordsGet(struct pipes_struct *p,
2536 				       struct netr_ServerTrustPasswordsGet *r)
2537 {
2538 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2539 	return NT_STATUS_NOT_IMPLEMENTED;
2540 }
2541 
2542 /****************************************************************
2543 ****************************************************************/
2544 
fill_forest_trust_array(TALLOC_CTX * mem_ctx,struct lsa_ForestTrustInformation * info)2545 static NTSTATUS fill_forest_trust_array(TALLOC_CTX *mem_ctx,
2546 					struct lsa_ForestTrustInformation *info)
2547 {
2548 	struct lsa_ForestTrustRecord *e;
2549 	struct pdb_domain_info *dom_info;
2550 	struct lsa_ForestTrustDomainInfo *domain_info;
2551 	char **upn_suffixes = NULL;
2552 	uint32_t num_suffixes = 0;
2553 	uint32_t i = 0;
2554 	NTSTATUS status;
2555 
2556 	dom_info = pdb_get_domain_info(mem_ctx);
2557 	if (dom_info == NULL) {
2558 		return NT_STATUS_NO_MEMORY;
2559 	}
2560 
2561 	info->count = 2;
2562 
2563 	become_root();
2564 	status = pdb_enum_upn_suffixes(info, &num_suffixes, &upn_suffixes);
2565 	unbecome_root();
2566 	if (NT_STATUS_IS_OK(status) && (num_suffixes > 0)) {
2567 		info->count += num_suffixes;
2568 	}
2569 
2570 	info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, info->count);
2571 	if (info->entries == NULL) {
2572 		return NT_STATUS_NO_MEMORY;
2573 	}
2574 
2575 	e = talloc(info, struct lsa_ForestTrustRecord);
2576 	if (e == NULL) {
2577 		return NT_STATUS_NO_MEMORY;
2578 	}
2579 
2580 	e->flags = 0;
2581 	e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2582 	e->time = 0; /* so far always 0 in trces. */
2583 	e->forest_trust_data.top_level_name.string = talloc_steal(info,
2584 								  dom_info->dns_forest);
2585 
2586 	info->entries[0] = e;
2587 
2588 	if (num_suffixes > 0) {
2589 		for (i = 0; i < num_suffixes ; i++) {
2590 			e = talloc(info, struct lsa_ForestTrustRecord);
2591 			if (e == NULL) {
2592 				return NT_STATUS_NO_MEMORY;
2593 			}
2594 
2595 			e->flags = 0;
2596 			e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2597 			e->time = 0; /* so far always 0 in traces. */
2598 			e->forest_trust_data.top_level_name.string = upn_suffixes[i];
2599 			info->entries[1 + i] = e;
2600 		}
2601 	}
2602 
2603 	e = talloc(info, struct lsa_ForestTrustRecord);
2604 	if (e == NULL) {
2605 		return NT_STATUS_NO_MEMORY;
2606 	}
2607 
2608 	/* TODO: check if disabled and set flags accordingly */
2609 	e->flags = 0;
2610 	e->type = LSA_FOREST_TRUST_DOMAIN_INFO;
2611 	e->time = 0; /* so far always 0 in traces. */
2612 
2613 	domain_info = &e->forest_trust_data.domain_info;
2614 	domain_info->domain_sid = dom_sid_dup(info, &dom_info->sid);
2615 
2616 	domain_info->dns_domain_name.string = talloc_steal(info,
2617 							   dom_info->dns_domain);
2618 	domain_info->netbios_domain_name.string = talloc_steal(info,
2619 							       dom_info->name);
2620 
2621 	info->entries[info->count - 1] = e;
2622 
2623 	return NT_STATUS_OK;
2624 }
2625 
2626 /****************************************************************
2627 ****************************************************************/
2628 
_netr_DsRGetForestTrustInformation(struct pipes_struct * p,struct netr_DsRGetForestTrustInformation * r)2629 WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
2630 					  struct netr_DsRGetForestTrustInformation *r)
2631 {
2632 	NTSTATUS status;
2633 	struct lsa_ForestTrustInformation *info, **info_ptr;
2634 	enum security_user_level security_level;
2635 
2636 	security_level = security_session_user_level(p->session_info, NULL);
2637 	if (security_level < SECURITY_USER) {
2638 		return WERR_ACCESS_DENIED;
2639 	}
2640 
2641 	if (r->in.flags & (~DS_GFTI_UPDATE_TDO)) {
2642 		p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2643 		return WERR_INVALID_FLAGS;
2644 	}
2645 
2646 	if ((r->in.flags & DS_GFTI_UPDATE_TDO) && (lp_server_role() != ROLE_DOMAIN_PDC)) {
2647 		p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2648 		return WERR_NERR_NOTPRIMARY;
2649 	}
2650 
2651 	if ((r->in.trusted_domain_name == NULL) && (r->in.flags & DS_GFTI_UPDATE_TDO)) {
2652 		p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2653 		return WERR_INVALID_PARAMETER;
2654 	}
2655 
2656 	/* retrieve forest trust information and stop further processing */
2657 	if (r->in.trusted_domain_name == NULL) {
2658 		info_ptr = talloc(p->mem_ctx, struct lsa_ForestTrustInformation *);
2659 		if (info_ptr == NULL) {
2660 			p->fault_state = DCERPC_FAULT_CANT_PERFORM;
2661 			return WERR_NOT_ENOUGH_MEMORY;
2662 		}
2663 		info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2664 		if (info == NULL) {
2665 			p->fault_state = DCERPC_FAULT_CANT_PERFORM;
2666 			return WERR_NOT_ENOUGH_MEMORY;
2667 		}
2668 
2669 		/* Fill forest trust information and expand UPN suffixes list */
2670 		status = fill_forest_trust_array(p->mem_ctx, info);
2671 		if (!NT_STATUS_IS_OK(status)) {
2672 			p->fault_state = DCERPC_FAULT_CANT_PERFORM;
2673 			return WERR_NOT_ENOUGH_MEMORY;
2674 		}
2675 
2676 		*info_ptr = info;
2677 		r->out.forest_trust_info = info_ptr;
2678 
2679 		return WERR_OK;
2680 
2681 	}
2682 
2683 	/* TODO: implement remaining parts of DsrGetForestTrustInformation (opnum 43)
2684 	 *       when trusted_domain_name is not NULL */
2685 
2686 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2687 	return WERR_NOT_SUPPORTED;
2688 }
2689 
2690 /****************************************************************
2691  _netr_GetForestTrustInformation
2692 ****************************************************************/
2693 
_netr_GetForestTrustInformation(struct pipes_struct * p,struct netr_GetForestTrustInformation * r)2694 NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p,
2695 					 struct netr_GetForestTrustInformation *r)
2696 {
2697 	NTSTATUS status;
2698 	struct netlogon_creds_CredentialState *creds;
2699 	struct lsa_ForestTrustInformation *info, **info_ptr;
2700 
2701 	/* TODO: check server name */
2702 
2703 	become_root();
2704 	status = netr_creds_server_step_check(p, p->mem_ctx,
2705 					      r->in.computer_name,
2706 					      r->in.credential,
2707 					      r->out.return_authenticator,
2708 					      &creds);
2709 	unbecome_root();
2710 	if (!NT_STATUS_IS_OK(status)) {
2711 		return status;
2712 	}
2713 
2714 	if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
2715 	    (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
2716 		return NT_STATUS_NOT_IMPLEMENTED;
2717 	}
2718 
2719 	info_ptr = talloc(p->mem_ctx, struct lsa_ForestTrustInformation *);
2720 	if (!info_ptr) {
2721 		return NT_STATUS_NO_MEMORY;
2722 	}
2723 	info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2724 	if (!info) {
2725 		return NT_STATUS_NO_MEMORY;
2726 	}
2727 
2728 	/* Fill forest trust information, do expand UPN suffixes list */
2729 	status = fill_forest_trust_array(p->mem_ctx, info);
2730 	if (!NT_STATUS_IS_OK(status)) {
2731 		return status;
2732 	}
2733 
2734 	*info_ptr = info;
2735 	r->out.forest_trust_info = info_ptr;
2736 
2737 	return NT_STATUS_OK;
2738 }
2739 
2740 /****************************************************************
2741 ****************************************************************/
2742 
get_password_from_trustAuth(TALLOC_CTX * mem_ctx,const DATA_BLOB * trustAuth_blob,struct netlogon_creds_CredentialState * creds,struct samr_Password * current_pw_enc,struct samr_Password * previous_pw_enc)2743 static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
2744 					    const DATA_BLOB *trustAuth_blob,
2745 					    struct netlogon_creds_CredentialState *creds,
2746 					    struct samr_Password *current_pw_enc,
2747 					    struct samr_Password *previous_pw_enc)
2748 {
2749 	enum ndr_err_code ndr_err;
2750 	struct trustAuthInOutBlob trustAuth;
2751 	NTSTATUS status;
2752 
2753 	ndr_err = ndr_pull_struct_blob_all(trustAuth_blob, mem_ctx, &trustAuth,
2754 					   (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
2755 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2756 		return NT_STATUS_UNSUCCESSFUL;
2757 	}
2758 
2759 	if (trustAuth.count != 0 && trustAuth.current.count != 0 &&
2760 	    trustAuth.current.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) {
2761 		mdfour(current_pw_enc->hash,
2762 		       trustAuth.current.array[0].AuthInfo.clear.password,
2763 		       trustAuth.current.array[0].AuthInfo.clear.size);
2764 		status = netlogon_creds_des_encrypt(creds, current_pw_enc);
2765 		if (!NT_STATUS_IS_OK(status)) {
2766 			return status;
2767 		}
2768 	} else {
2769 		return NT_STATUS_UNSUCCESSFUL;
2770 	}
2771 
2772 
2773 	if (trustAuth.previous.count != 0 &&
2774 	    trustAuth.previous.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) {
2775 		mdfour(previous_pw_enc->hash,
2776 		       trustAuth.previous.array[0].AuthInfo.clear.password,
2777 		       trustAuth.previous.array[0].AuthInfo.clear.size);
2778 		status = netlogon_creds_des_encrypt(creds, previous_pw_enc);
2779 		if (!NT_STATUS_IS_OK(status)) {
2780 			return status;
2781 		}
2782 	} else {
2783 		ZERO_STRUCTP(previous_pw_enc);
2784 	}
2785 
2786 	return NT_STATUS_OK;
2787 }
2788 
2789 /****************************************************************
2790  _netr_ServerGetTrustInfo
2791 ****************************************************************/
2792 
_netr_ServerGetTrustInfo(struct pipes_struct * p,struct netr_ServerGetTrustInfo * r)2793 NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
2794 				  struct netr_ServerGetTrustInfo *r)
2795 {
2796 	NTSTATUS status;
2797 	struct netlogon_creds_CredentialState *creds;
2798 	char *account_name;
2799 	size_t account_name_last;
2800 	bool trusted;
2801 	struct netr_TrustInfo *trust_info;
2802 	struct pdb_trusted_domain *td;
2803 
2804 	/* TODO: check server name */
2805 
2806 	become_root();
2807 	status = netr_creds_server_step_check(p, p->mem_ctx,
2808 					      r->in.computer_name,
2809 					      r->in.credential,
2810 					      r->out.return_authenticator,
2811 					      &creds);
2812 	unbecome_root();
2813 	if (!NT_STATUS_IS_OK(status)) {
2814 		return status;
2815 	}
2816 
2817 	account_name = talloc_strdup(p->mem_ctx, r->in.account_name);
2818 	if (account_name == NULL) {
2819 		return NT_STATUS_NO_MEMORY;
2820 	}
2821 
2822 	account_name_last = strlen(account_name);
2823 	if (account_name_last == 0) {
2824 		return NT_STATUS_INVALID_PARAMETER;
2825 	}
2826 	account_name_last--;
2827 	if (account_name[account_name_last] == '.') {
2828 		account_name[account_name_last] = '\0';
2829 	}
2830 
2831 	if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
2832 	    (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
2833 		trusted = false;
2834 	} else {
2835 		trusted = true;
2836 	}
2837 
2838 
2839 	if (trusted) {
2840 		account_name_last = strlen(account_name);
2841 		if (account_name_last == 0) {
2842 			return NT_STATUS_INVALID_PARAMETER;
2843 		}
2844 		account_name_last--;
2845 		if (account_name[account_name_last] == '$') {
2846 			account_name[account_name_last] = '\0';
2847 		}
2848 
2849 		status = pdb_get_trusted_domain(p->mem_ctx, account_name, &td);
2850 		if (!NT_STATUS_IS_OK(status)) {
2851 			return status;
2852 		}
2853 
2854 		if (r->out.trust_info != NULL) {
2855 			trust_info = talloc_zero(p->mem_ctx, struct netr_TrustInfo);
2856 			if (trust_info == NULL) {
2857 				return NT_STATUS_NO_MEMORY;
2858 			}
2859 			trust_info->count = 1;
2860 
2861 			trust_info->data = talloc_array(trust_info, uint32_t, 1);
2862 			if (trust_info->data == NULL) {
2863 				return NT_STATUS_NO_MEMORY;
2864 			}
2865 			trust_info->data[0] = td->trust_attributes;
2866 
2867 			*r->out.trust_info = trust_info;
2868 		}
2869 
2870 		if (td->trust_auth_incoming.data == NULL) {
2871 			return NT_STATUS_INVALID_PARAMETER;
2872 		}
2873 
2874 		status = get_password_from_trustAuth(p->mem_ctx,
2875 						     &td->trust_auth_incoming,
2876 						     creds,
2877 						     r->out.new_owf_password,
2878 						     r->out.old_owf_password);
2879 
2880 		if (!NT_STATUS_IS_OK(status)) {
2881 			return status;
2882 		}
2883 
2884 	} else {
2885 /* TODO: look for machine password */
2886 		ZERO_STRUCTP(r->out.new_owf_password);
2887 		ZERO_STRUCTP(r->out.old_owf_password);
2888 
2889 		return NT_STATUS_NOT_IMPLEMENTED;
2890 	}
2891 
2892 	return NT_STATUS_OK;
2893 }
2894 
2895 /****************************************************************
2896 ****************************************************************/
2897 
_netr_Unused47(struct pipes_struct * p,struct netr_Unused47 * r)2898 NTSTATUS _netr_Unused47(struct pipes_struct *p,
2899 			struct netr_Unused47 *r)
2900 {
2901 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2902 	return NT_STATUS_NOT_IMPLEMENTED;
2903 }
2904 
2905 /****************************************************************
2906 ****************************************************************/
2907 
_netr_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct * p,struct netr_DsrUpdateReadOnlyServerDnsRecords * r)2908 NTSTATUS _netr_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
2909 						 struct netr_DsrUpdateReadOnlyServerDnsRecords *r)
2910 {
2911 	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2912 	return NT_STATUS_NOT_IMPLEMENTED;
2913 }
2914