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