python/samba/tests: add test cases for s3/registry init funcs
[Samba.git] / source3 / rpc_server / netlogon / srv_netlog_nt.c
blob5906464a9f310b5e4f2697b654fc85da0ab26d79
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.
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.
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.
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/>.
25 /* This is the implementation of the netlogon pipe. */
27 #include "includes.h"
28 #include "system/passwd.h" /* uid_wrapper */
29 #include "ntdomain.h"
30 #include "../libcli/auth/schannel.h"
31 #include "librpc/rpc/dcesrv_core.h"
32 #include "librpc/gen_ndr/ndr_netlogon.h"
33 #include "librpc/gen_ndr/ndr_netlogon_scompat.h"
34 #include "librpc/gen_ndr/ndr_samr_c.h"
35 #include "librpc/gen_ndr/ndr_lsa_c.h"
36 #include "rpc_client/cli_lsarpc.h"
37 #include "rpc_client/init_lsa.h"
38 #include "rpc_client/init_samr.h"
39 #include "rpc_server/rpc_ncacn_np.h"
40 #include "../libcli/security/security.h"
41 #include "../libcli/security/dom_sid.h"
42 #include "librpc/gen_ndr/ndr_drsblobs.h"
43 #include "lib/crypto/md4.h"
44 #include "nsswitch/libwbclient/wbclient.h"
45 #include "../libcli/registry/util_reg.h"
46 #include "passdb.h"
47 #include "auth.h"
48 #include "messages.h"
49 #include "../lib/tsocket/tsocket.h"
50 #include "lib/param/param.h"
51 #include "libsmb/dsgetdcname.h"
52 #include "lib/util/util_str_escape.h"
53 #include "source3/lib/substitute.h"
55 extern userdom_struct current_user_info;
57 #undef DBGC_CLASS
58 #define DBGC_CLASS DBGC_RPC_SRV
60 /*************************************************************************
61 _netr_LogonControl
62 *************************************************************************/
64 WERROR _netr_LogonControl(struct pipes_struct *p,
65 struct netr_LogonControl *r)
67 struct netr_LogonControl2Ex l;
69 switch (r->in.level) {
70 case 1:
71 break;
72 case 2:
73 return WERR_NOT_SUPPORTED;
74 default:
75 return WERR_INVALID_LEVEL;
78 switch (r->in.function_code) {
79 case NETLOGON_CONTROL_QUERY:
80 case NETLOGON_CONTROL_REPLICATE:
81 case NETLOGON_CONTROL_SYNCHRONIZE:
82 case NETLOGON_CONTROL_PDC_REPLICATE:
83 case NETLOGON_CONTROL_BREAKPOINT:
84 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
85 case NETLOGON_CONTROL_TRUNCATE_LOG:
86 break;
87 default:
88 return WERR_NOT_SUPPORTED;
91 l.in.logon_server = r->in.logon_server;
92 l.in.function_code = r->in.function_code;
93 l.in.level = r->in.level;
94 l.in.data = NULL;
95 l.out.query = r->out.query;
97 return _netr_LogonControl2Ex(p, &l);
100 /*************************************************************************
101 _netr_LogonControl2
102 *************************************************************************/
104 WERROR _netr_LogonControl2(struct pipes_struct *p,
105 struct netr_LogonControl2 *r)
107 struct netr_LogonControl2Ex l;
109 l.in.logon_server = r->in.logon_server;
110 l.in.function_code = r->in.function_code;
111 l.in.level = r->in.level;
112 l.in.data = r->in.data;
113 l.out.query = r->out.query;
115 return _netr_LogonControl2Ex(p, &l);
118 /*************************************************************************
119 *************************************************************************/
121 static bool wb_change_trust_creds(const char *domain, WERROR *tc_status)
123 wbcErr result;
124 struct wbcAuthErrorInfo *error = NULL;
126 result = wbcChangeTrustCredentials(domain, &error);
127 switch (result) {
128 case WBC_ERR_WINBIND_NOT_AVAILABLE:
129 return false;
130 case WBC_ERR_DOMAIN_NOT_FOUND:
131 *tc_status = WERR_NO_SUCH_DOMAIN;
132 return true;
133 case WBC_ERR_SUCCESS:
134 *tc_status = WERR_OK;
135 return true;
136 default:
137 break;
140 if (error && error->nt_status != 0) {
141 *tc_status = ntstatus_to_werror(NT_STATUS(error->nt_status));
142 } else {
143 *tc_status = WERR_TRUST_FAILURE;
145 wbcFreeMemory(error);
146 return true;
149 /*************************************************************************
150 *************************************************************************/
152 static bool wb_check_trust_creds(const char *domain, WERROR *tc_status)
154 wbcErr result;
155 struct wbcAuthErrorInfo *error = NULL;
157 result = wbcCheckTrustCredentials(domain, &error);
158 switch (result) {
159 case WBC_ERR_WINBIND_NOT_AVAILABLE:
160 return false;
161 case WBC_ERR_DOMAIN_NOT_FOUND:
162 *tc_status = WERR_NO_SUCH_DOMAIN;
163 return true;
164 case WBC_ERR_SUCCESS:
165 *tc_status = WERR_OK;
166 return true;
167 default:
168 break;
171 if (error && error->nt_status != 0) {
172 *tc_status = ntstatus_to_werror(NT_STATUS(error->nt_status));
173 } else {
174 *tc_status = WERR_TRUST_FAILURE;
176 wbcFreeMemory(error);
177 return true;
180 /****************************************************************
181 _netr_LogonControl2Ex
182 ****************************************************************/
184 WERROR _netr_LogonControl2Ex(struct pipes_struct *p,
185 struct netr_LogonControl2Ex *r)
187 struct dcesrv_call_state *dce_call = p->dce_call;
188 struct auth_session_info *session_info =
189 dcesrv_call_session_info(dce_call);
190 uint32_t flags = 0x0;
191 WERROR pdc_connection_status = WERR_OK;
192 uint32_t logon_attempts = 0x0;
193 WERROR tc_status;
194 fstring dc_name2;
195 const char *dc_name = NULL;
196 struct sockaddr_storage dc_ss;
197 const char *domain = NULL;
198 struct netr_NETLOGON_INFO_1 *info1;
199 struct netr_NETLOGON_INFO_2 *info2;
200 struct netr_NETLOGON_INFO_3 *info3;
201 struct netr_NETLOGON_INFO_4 *info4;
202 const char *fn;
203 NTSTATUS status;
204 struct netr_DsRGetDCNameInfo *dc_info;
206 switch (dce_call->pkt.u.request.opnum) {
207 case NDR_NETR_LOGONCONTROL:
208 fn = "_netr_LogonControl";
209 break;
210 case NDR_NETR_LOGONCONTROL2:
211 fn = "_netr_LogonControl2";
212 break;
213 case NDR_NETR_LOGONCONTROL2EX:
214 fn = "_netr_LogonControl2Ex";
215 break;
216 default:
217 return WERR_INVALID_PARAMETER;
220 switch (r->in.level) {
221 case 1:
222 case 2:
223 case 3:
224 case 4:
225 break;
226 default:
227 return WERR_INVALID_LEVEL;
230 switch (r->in.function_code) {
231 case NETLOGON_CONTROL_QUERY:
232 break;
233 default:
234 if ((geteuid() != sec_initial_uid()) &&
235 !nt_token_check_domain_rid(
236 session_info->security_token, DOMAIN_RID_ADMINS) &&
237 !nt_token_check_sid(
238 &global_sid_Builtin_Administrators,
239 session_info->security_token))
241 return WERR_ACCESS_DENIED;
243 break;
246 tc_status = WERR_NO_SUCH_DOMAIN;
248 switch (r->in.function_code) {
249 case NETLOGON_CONTROL_QUERY:
250 switch (r->in.level) {
251 case 1:
252 case 3:
253 break;
254 default:
255 return WERR_INVALID_PARAMETER;
258 tc_status = WERR_OK;
259 break;
260 case NETLOGON_CONTROL_REPLICATE:
261 case NETLOGON_CONTROL_SYNCHRONIZE:
262 case NETLOGON_CONTROL_PDC_REPLICATE:
263 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
264 case NETLOGON_CONTROL_BREAKPOINT:
265 case NETLOGON_CONTROL_TRUNCATE_LOG:
266 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
267 case NETLOGON_CONTROL_FORCE_DNS_REG:
268 case NETLOGON_CONTROL_QUERY_DNS_REG:
269 return WERR_NOT_SUPPORTED;
271 case NETLOGON_CONTROL_FIND_USER:
272 if (!r->in.data || !r->in.data->user) {
273 return WERR_NOT_SUPPORTED;
275 break;
276 case NETLOGON_CONTROL_SET_DBFLAG:
277 if (!r->in.data) {
278 return WERR_NOT_SUPPORTED;
280 break;
281 case NETLOGON_CONTROL_TC_VERIFY:
282 if (!r->in.data || !r->in.data->domain) {
283 return WERR_NOT_SUPPORTED;
286 if (!wb_check_trust_creds(r->in.data->domain, &tc_status)) {
287 return WERR_NOT_SUPPORTED;
289 break;
290 case NETLOGON_CONTROL_TC_QUERY:
291 if (!r->in.data || !r->in.data->domain) {
292 return WERR_NOT_SUPPORTED;
295 domain = r->in.data->domain;
297 if (!is_trusted_domain(domain)) {
298 break;
301 if (!get_dc_name(domain, NULL, dc_name2, &dc_ss)) {
302 tc_status = WERR_NO_LOGON_SERVERS;
303 break;
306 dc_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dc_name2);
307 if (!dc_name) {
308 return WERR_NOT_ENOUGH_MEMORY;
311 tc_status = WERR_OK;
313 break;
315 case NETLOGON_CONTROL_REDISCOVER:
316 if (!r->in.data || !r->in.data->domain) {
317 return WERR_NOT_SUPPORTED;
320 domain = r->in.data->domain;
322 if (!is_trusted_domain(domain)) {
323 break;
326 status = dsgetdcname(p->mem_ctx, p->msg_ctx, domain, NULL, NULL,
327 DS_FORCE_REDISCOVERY | DS_RETURN_FLAT_NAME,
328 &dc_info);
329 if (!NT_STATUS_IS_OK(status)) {
330 tc_status = WERR_NO_LOGON_SERVERS;
331 break;
334 dc_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dc_info->dc_unc);
335 if (!dc_name) {
336 return WERR_NOT_ENOUGH_MEMORY;
339 tc_status = WERR_OK;
341 break;
343 case NETLOGON_CONTROL_CHANGE_PASSWORD:
344 if (!r->in.data || !r->in.data->domain) {
345 return WERR_NOT_SUPPORTED;
348 if (!wb_change_trust_creds(r->in.data->domain, &tc_status)) {
349 return WERR_NOT_SUPPORTED;
351 break;
353 default:
354 /* no idea what this should be */
355 DEBUG(0,("%s: unimplemented function level [%d]\n",
356 fn, r->in.function_code));
357 return WERR_NOT_SUPPORTED;
360 /* prepare the response */
362 switch (r->in.level) {
363 case 1:
364 info1 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_1);
365 W_ERROR_HAVE_NO_MEMORY(info1);
367 info1->flags = flags;
368 info1->pdc_connection_status = pdc_connection_status;
370 r->out.query->info1 = info1;
371 break;
372 case 2:
373 info2 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_2);
374 W_ERROR_HAVE_NO_MEMORY(info2);
376 info2->flags = flags;
377 info2->pdc_connection_status = pdc_connection_status;
378 info2->trusted_dc_name = dc_name;
379 info2->tc_connection_status = tc_status;
381 r->out.query->info2 = info2;
382 break;
383 case 3:
384 info3 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_3);
385 W_ERROR_HAVE_NO_MEMORY(info3);
387 info3->flags = flags;
388 info3->logon_attempts = logon_attempts;
390 r->out.query->info3 = info3;
391 break;
392 case 4:
393 info4 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_4);
394 W_ERROR_HAVE_NO_MEMORY(info4);
396 info4->trusted_dc_name = dc_name;
397 info4->trusted_domain_name = r->in.data->domain;
399 r->out.query->info4 = info4;
400 break;
401 default:
402 return WERR_INVALID_LEVEL;
405 return WERR_OK;
408 /*************************************************************************
409 _netr_NetrEnumerateTrustedDomains
410 *************************************************************************/
412 NTSTATUS _netr_NetrEnumerateTrustedDomains(struct pipes_struct *p,
413 struct netr_NetrEnumerateTrustedDomains *r)
415 struct dcesrv_call_state *dce_call = p->dce_call;
416 struct dcesrv_connection *dcesrv_conn = dce_call->conn;
417 const struct tsocket_address *local_address =
418 dcesrv_connection_get_local_address(dcesrv_conn);
419 const struct tsocket_address *remote_address =
420 dcesrv_connection_get_remote_address(dcesrv_conn);
421 struct auth_session_info *session_info =
422 dcesrv_call_session_info(dce_call);
423 NTSTATUS status;
424 NTSTATUS result = NT_STATUS_OK;
425 DATA_BLOB blob;
426 size_t num_domains = 0;
427 const char **trusted_domains = NULL;
428 struct lsa_DomainList domain_list;
429 struct dcerpc_binding_handle *h = NULL;
430 struct policy_handle pol;
431 uint32_t enum_ctx = 0;
432 uint32_t max_size = (uint32_t)-1;
434 ZERO_STRUCT(pol);
435 DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
437 status = rpcint_binding_handle(p->mem_ctx,
438 &ndr_table_lsarpc,
439 remote_address,
440 local_address,
441 session_info,
442 p->msg_ctx,
443 &h);
444 if (!NT_STATUS_IS_OK(status)) {
445 return status;
448 status = dcerpc_lsa_open_policy2(h,
449 p->mem_ctx,
450 NULL,
451 true,
452 LSA_POLICY_VIEW_LOCAL_INFORMATION,
453 &pol,
454 &result);
455 if (any_nt_status_not_ok(status, result, &status)) {
456 goto out;
459 do {
460 uint32_t i;
462 /* Lookup list of trusted domains */
463 status = dcerpc_lsa_EnumTrustDom(h,
464 p->mem_ctx,
465 &pol,
466 &enum_ctx,
467 &domain_list,
468 max_size,
469 &result);
470 if (!NT_STATUS_IS_OK(status)) {
471 goto out;
473 if (!NT_STATUS_IS_OK(result) &&
474 !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
475 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
476 status = result;
477 goto out;
480 for (i = 0; i < domain_list.count; i++) {
481 if (!add_string_to_array(p->mem_ctx, domain_list.domains[i].name.string,
482 &trusted_domains, &num_domains)) {
483 status = NT_STATUS_NO_MEMORY;
484 goto out;
487 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
489 if (num_domains > 0) {
490 /* multi sz terminate */
491 trusted_domains = talloc_realloc(p->mem_ctx, trusted_domains, const char *, num_domains + 1);
492 if (trusted_domains == NULL) {
493 status = NT_STATUS_NO_MEMORY;
494 goto out;
497 trusted_domains[num_domains] = NULL;
500 if (!push_reg_multi_sz(trusted_domains, &blob, trusted_domains)) {
501 TALLOC_FREE(trusted_domains);
502 status = NT_STATUS_NO_MEMORY;
503 goto out;
506 r->out.trusted_domains_blob->data = blob.data;
507 r->out.trusted_domains_blob->length = blob.length;
509 DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
511 status = NT_STATUS_OK;
513 out:
514 if (is_valid_policy_hnd(&pol)) {
515 dcerpc_lsa_Close(h, p->mem_ctx, &pol, &result);
518 return status;
521 /*************************************************************************
522 *************************************************************************/
524 static NTSTATUS samr_find_machine_account(TALLOC_CTX *mem_ctx,
525 struct dcerpc_binding_handle *b,
526 const char *account_name,
527 uint32_t access_mask,
528 struct dom_sid2 **domain_sid_p,
529 uint32_t *user_rid_p,
530 struct policy_handle *user_handle)
532 NTSTATUS status;
533 NTSTATUS result = NT_STATUS_OK;
534 struct policy_handle connect_handle;
535 struct policy_handle domain_handle = { 0, };
536 struct lsa_String domain_name;
537 struct dom_sid2 *domain_sid;
538 struct lsa_String names;
539 struct samr_Ids rids;
540 struct samr_Ids types;
541 uint32_t rid;
543 status = dcerpc_samr_Connect2(b, mem_ctx,
544 lp_netbios_name(),
545 SAMR_ACCESS_CONNECT_TO_SERVER |
546 SAMR_ACCESS_ENUM_DOMAINS |
547 SAMR_ACCESS_LOOKUP_DOMAIN,
548 &connect_handle,
549 &result);
550 if (any_nt_status_not_ok(status, result, &status)) {
551 goto out;
554 init_lsa_String(&domain_name, get_global_sam_name());
556 status = dcerpc_samr_LookupDomain(b, mem_ctx,
557 &connect_handle,
558 &domain_name,
559 &domain_sid,
560 &result);
561 if (any_nt_status_not_ok(status, result, &status)) {
562 goto out;
565 status = dcerpc_samr_OpenDomain(b, mem_ctx,
566 &connect_handle,
567 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
568 domain_sid,
569 &domain_handle,
570 &result);
571 if (any_nt_status_not_ok(status, result, &status)) {
572 goto out;
575 init_lsa_String(&names, account_name);
577 status = dcerpc_samr_LookupNames(b, mem_ctx,
578 &domain_handle,
580 &names,
581 &rids,
582 &types,
583 &result);
584 if (any_nt_status_not_ok(status, result, &status)) {
585 goto out;
588 if (rids.count != 1) {
589 status = NT_STATUS_NO_SUCH_USER;
590 goto out;
592 if (types.count != 1) {
593 status = NT_STATUS_INVALID_PARAMETER;
594 goto out;
596 if (types.ids[0] != SID_NAME_USER) {
597 status = NT_STATUS_NO_SUCH_USER;
598 goto out;
601 rid = rids.ids[0];
603 status = dcerpc_samr_OpenUser(b, mem_ctx,
604 &domain_handle,
605 access_mask,
606 rid,
607 user_handle,
608 &result);
609 if (any_nt_status_not_ok(status, result, &status)) {
610 goto out;
613 if (user_rid_p) {
614 *user_rid_p = rid;
617 if (domain_sid_p) {
618 *domain_sid_p = domain_sid;
621 out:
622 if (is_valid_policy_hnd(&domain_handle)) {
623 dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
625 if (is_valid_policy_hnd(&connect_handle)) {
626 dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
629 return status;
632 /******************************************************************
633 gets a machine password entry. checks access rights of the host.
634 ******************************************************************/
636 static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
637 enum netr_SchannelType sec_chan_type,
638 struct dom_sid *sid,
639 struct messaging_context *msg_ctx)
641 NTSTATUS status;
642 NTSTATUS result = NT_STATUS_OK;
643 TALLOC_CTX *mem_ctx = NULL;
644 struct dcerpc_binding_handle *h = NULL;
645 struct tsocket_address *local = NULL;
646 struct policy_handle user_handle = { .handle_type = 0 };
647 uint32_t user_rid = UINT32_MAX;
648 struct dom_sid *domain_sid = NULL;
649 uint32_t acct_ctrl = 0;
650 union samr_UserInfo *info = NULL;
651 struct auth_session_info *session_info = NULL;
652 int rc;
654 #if 0
657 * Currently this code is redundant as we already have a filter
658 * by hostname list. What this code really needs to do is to
659 * get a hosts allowed/hosts denied list from the SAM database
660 * on a per user basis, and make the access decision there.
661 * I will leave this code here for now as a reminder to implement
662 * this at a later date. JRA.
665 if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
666 p->client_id.name,
667 p->client_id.addr)) {
668 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
669 return False;
671 #endif /* 0 */
673 mem_ctx = talloc_stackframe();
675 status = make_session_info_system(mem_ctx, &session_info);
676 if (!NT_STATUS_IS_OK(status)) {
677 goto out;
680 ZERO_STRUCT(user_handle);
682 rc = tsocket_address_inet_from_strings(mem_ctx,
683 "ip",
684 "127.0.0.1",
686 &local);
687 if (rc < 0) {
688 status = NT_STATUS_NO_MEMORY;
689 goto out;
692 status = rpcint_binding_handle(mem_ctx,
693 &ndr_table_samr,
694 local,
695 NULL,
696 session_info,
697 msg_ctx,
698 &h);
699 if (!NT_STATUS_IS_OK(status)) {
700 goto out;
703 status = samr_find_machine_account(mem_ctx, h, mach_acct,
704 SEC_FLAG_MAXIMUM_ALLOWED,
705 &domain_sid, &user_rid,
706 &user_handle);
707 if (!NT_STATUS_IS_OK(status)) {
708 goto out;
711 status = dcerpc_samr_QueryUserInfo2(h,
712 mem_ctx,
713 &user_handle,
714 UserControlInformation,
715 &info,
716 &result);
717 if (any_nt_status_not_ok(status, result, &status)) {
718 goto out;
721 acct_ctrl = info->info16.acct_flags;
723 if (acct_ctrl & ACB_DISABLED) {
724 DEBUG(0,("get_md4pw: Workstation %s: account is disabled\n", mach_acct));
725 status = NT_STATUS_ACCOUNT_DISABLED;
726 goto out;
729 if (!(acct_ctrl & ACB_SVRTRUST) &&
730 !(acct_ctrl & ACB_WSTRUST) &&
731 !(acct_ctrl & ACB_DOMTRUST))
733 DEBUG(0,("get_md4pw: Workstation %s: account is not a trust account\n", mach_acct));
734 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
735 goto out;
738 switch (sec_chan_type) {
739 case SEC_CHAN_BDC:
740 if (!(acct_ctrl & ACB_SVRTRUST)) {
741 DEBUG(0,("get_md4pw: Workstation %s: BDC secure channel requested "
742 "but not a server trust account\n", mach_acct));
743 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
744 goto out;
746 break;
747 case SEC_CHAN_WKSTA:
748 if (!(acct_ctrl & ACB_WSTRUST)) {
749 DEBUG(0,("get_md4pw: Workstation %s: WORKSTATION secure channel requested "
750 "but not a workstation trust account\n", mach_acct));
751 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
752 goto out;
754 break;
755 case SEC_CHAN_DOMAIN:
756 if (!(acct_ctrl & ACB_DOMTRUST)) {
757 DEBUG(0,("get_md4pw: Workstation %s: DOMAIN secure channel requested "
758 "but not a interdomain trust account\n", mach_acct));
759 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
760 goto out;
762 break;
763 default:
764 break;
767 become_root();
768 status = dcerpc_samr_QueryUserInfo2(h,
769 mem_ctx,
770 &user_handle,
771 UserInternal1Information,
772 &info,
773 &result);
774 unbecome_root();
775 if (any_nt_status_not_ok(status, result, &status)) {
776 goto out;
779 if (info->info18.nt_pwd_active == 0) {
780 DEBUG(0,("get_md4pw: Workstation %s: account does not have a password\n", mach_acct));
781 status = NT_STATUS_LOGON_FAILURE;
782 goto out;
785 /* samr gives out nthash unencrypted (!) */
786 memcpy(md4pw->hash, info->info18.nt_pwd.hash, 16);
788 sid_compose(sid, domain_sid, user_rid);
790 out:
791 if (h && is_valid_policy_hnd(&user_handle)) {
792 dcerpc_samr_Close(h, mem_ctx, &user_handle, &result);
795 talloc_free(mem_ctx);
797 return status;
800 /*************************************************************************
801 _netr_ServerReqChallenge
802 *************************************************************************/
804 NTSTATUS _netr_ServerReqChallenge(struct pipes_struct *p,
805 struct netr_ServerReqChallenge *r)
807 struct dcesrv_call_state *dce_call = p->dce_call;
808 struct netlogon_server_pipe_state *pipe_state = NULL;
809 NTSTATUS status;
811 pipe_state = dcesrv_iface_state_find_conn(
812 dce_call,
813 NETLOGON_SERVER_PIPE_STATE_MAGIC,
814 struct netlogon_server_pipe_state);
816 if (pipe_state) {
817 DEBUG(10,("_netr_ServerReqChallenge: new challenge requested. Clearing old state.\n"));
818 talloc_free(pipe_state);
821 pipe_state = talloc(p->mem_ctx, struct netlogon_server_pipe_state);
822 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
824 pipe_state->client_challenge = *r->in.credentials;
826 netlogon_creds_random_challenge(&pipe_state->server_challenge);
828 *r->out.return_credentials = pipe_state->server_challenge;
830 status = dcesrv_iface_state_store_conn(
831 dce_call,
832 NETLOGON_SERVER_PIPE_STATE_MAGIC,
833 pipe_state);
834 if (!NT_STATUS_IS_OK(status)) {
835 return status;
838 return NT_STATUS_OK;
841 /*************************************************************************
842 _netr_ServerAuthenticate
843 Create the initial credentials.
844 *************************************************************************/
846 NTSTATUS _netr_ServerAuthenticate(struct pipes_struct *p,
847 struct netr_ServerAuthenticate *r)
849 struct netr_ServerAuthenticate3 a;
850 uint32_t negotiate_flags = 0;
851 uint32_t rid;
853 a.in.server_name = r->in.server_name;
854 a.in.account_name = r->in.account_name;
855 a.in.secure_channel_type = r->in.secure_channel_type;
856 a.in.computer_name = r->in.computer_name;
857 a.in.credentials = r->in.credentials;
858 a.in.negotiate_flags = &negotiate_flags;
860 a.out.return_credentials = r->out.return_credentials;
861 a.out.rid = &rid;
862 a.out.negotiate_flags = &negotiate_flags;
864 return _netr_ServerAuthenticate3(p, &a);
868 /*************************************************************************
869 _netr_ServerAuthenticate3
870 *************************************************************************/
872 NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
873 struct netr_ServerAuthenticate3 *r)
875 struct dcesrv_call_state *dce_call = p->dce_call;
876 NTSTATUS status;
877 uint32_t srv_flgs;
878 /* r->in.negotiate_flags is an aliased pointer to r->out.negotiate_flags,
879 * so use a copy to avoid destroying the client values. */
880 uint32_t in_neg_flags = *r->in.negotiate_flags;
881 const char *fn;
882 struct loadparm_context *lp_ctx;
883 struct dom_sid sid;
884 struct samr_Password mach_pwd;
885 struct netlogon_creds_CredentialState *creds;
886 struct netlogon_server_pipe_state *pipe_state = NULL;
888 /* According to Microsoft (see bugid #6099)
889 * Windows 7 looks at the negotiate_flags
890 * returned in this structure *even if the
891 * call fails with access denied* ! So in order
892 * to allow Win7 to connect to a Samba NT style
893 * PDC we set the flags before we know if it's
894 * an error or not.
897 /* 0x000001ff */
898 srv_flgs = NETLOGON_NEG_ACCOUNT_LOCKOUT |
899 NETLOGON_NEG_PERSISTENT_SAMREPL |
900 NETLOGON_NEG_ARCFOUR |
901 NETLOGON_NEG_PROMOTION_COUNT |
902 NETLOGON_NEG_CHANGELOG_BDC |
903 NETLOGON_NEG_FULL_SYNC_REPL |
904 NETLOGON_NEG_MULTIPLE_SIDS |
905 NETLOGON_NEG_REDO |
906 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
907 NETLOGON_NEG_PASSWORD_SET2;
909 /* Ensure we support strong (128-bit) keys. */
910 if (in_neg_flags & NETLOGON_NEG_STRONG_KEYS) {
911 srv_flgs |= NETLOGON_NEG_STRONG_KEYS;
914 if (in_neg_flags & NETLOGON_NEG_SUPPORTS_AES) {
915 srv_flgs |= NETLOGON_NEG_SUPPORTS_AES;
918 if (in_neg_flags & NETLOGON_NEG_SCHANNEL) {
919 srv_flgs |= NETLOGON_NEG_SCHANNEL;
923 * Support authenticaten of trusted domains.
925 * These flags are the minimum required set which works with win2k3
926 * and win2k8.
928 if (pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX) {
929 srv_flgs |= NETLOGON_NEG_TRANSITIVE_TRUSTS |
930 NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
931 NETLOGON_NEG_CROSS_FOREST_TRUSTS |
932 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION;
936 * If weak cryto is disabled, do not announce that we support RC4.
938 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
939 srv_flgs &= ~NETLOGON_NEG_ARCFOUR;
942 switch (dce_call->pkt.u.request.opnum) {
943 case NDR_NETR_SERVERAUTHENTICATE:
944 fn = "_netr_ServerAuthenticate";
945 break;
946 case NDR_NETR_SERVERAUTHENTICATE2:
947 fn = "_netr_ServerAuthenticate2";
948 break;
949 case NDR_NETR_SERVERAUTHENTICATE3:
950 fn = "_netr_ServerAuthenticate3";
951 break;
952 default:
953 return NT_STATUS_INTERNAL_ERROR;
956 /* We use this as the key to store the creds: */
957 /* r->in.computer_name */
959 pipe_state = dcesrv_iface_state_find_conn(
960 dce_call,
961 NETLOGON_SERVER_PIPE_STATE_MAGIC,
962 struct netlogon_server_pipe_state);
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;
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;
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;
1005 creds->sid = dom_sid_dup(creds, &sid);
1006 if (!creds->sid) {
1007 status = NT_STATUS_NO_MEMORY;
1008 goto out;
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;
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();
1023 talloc_unlink(p->mem_ctx, lp_ctx);
1025 if (!NT_STATUS_IS_OK(status)) {
1026 ZERO_STRUCTP(r->out.return_credentials);
1027 goto out;
1030 sid_peek_rid(&sid, r->out.rid);
1032 status = NT_STATUS_OK;
1034 out:
1036 *r->out.negotiate_flags = srv_flgs;
1037 return status;
1040 /*************************************************************************
1041 _netr_ServerAuthenticate2
1042 *************************************************************************/
1044 NTSTATUS _netr_ServerAuthenticate2(struct pipes_struct *p,
1045 struct netr_ServerAuthenticate2 *r)
1047 struct netr_ServerAuthenticate3 a;
1048 uint32_t rid;
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;
1057 a.out.return_credentials = r->out.return_credentials;
1058 a.out.rid = &rid;
1059 a.out.negotiate_flags = r->out.negotiate_flags;
1061 return _netr_ServerAuthenticate3(p, &a);
1064 /*************************************************************************
1065 *************************************************************************/
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)
1074 struct dcesrv_call_state *dce_call = p->dce_call;
1075 NTSTATUS status;
1076 bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
1077 bool schannel_required = schannel_global_required;
1078 const char *explicit_opt = NULL;
1079 struct loadparm_context *lp_ctx;
1080 struct netlogon_creds_CredentialState *creds = NULL;
1081 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1082 uint16_t opnum = dce_call->pkt.u.request.opnum;
1083 const char *opname = "<unknown>";
1084 static bool warned_global_once = false;
1086 if (creds_out != NULL) {
1087 *creds_out = NULL;
1090 if (opnum < ndr_table_netlogon.num_calls) {
1091 opname = ndr_table_netlogon.calls[opnum].name;
1094 dcesrv_call_auth_info(dce_call, &auth_type, NULL);
1096 lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
1097 if (lp_ctx == NULL) {
1098 DEBUG(0, ("loadparm_init_s3 failed\n"));
1099 return NT_STATUS_INTERNAL_ERROR;
1102 status = schannel_check_creds_state(mem_ctx, lp_ctx,
1103 computer_name, received_authenticator,
1104 return_authenticator, &creds);
1105 talloc_unlink(mem_ctx, lp_ctx);
1107 if (!NT_STATUS_IS_OK(status)) {
1108 ZERO_STRUCTP(return_authenticator);
1109 return status;
1113 * We don't use lp_parm_bool(), as we
1114 * need the explicit_opt pointer in order to
1115 * adjust the debug messages.
1118 explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1119 "server require schannel",
1120 creds->account_name,
1121 NULL);
1122 if (explicit_opt != NULL) {
1123 schannel_required = lp_bool(explicit_opt);
1126 if (schannel_required) {
1127 if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1128 *creds_out = creds;
1129 return NT_STATUS_OK;
1132 DBG_ERR("CVE-2020-1472(ZeroLogon): "
1133 "%s request (opnum[%u]) without schannel from "
1134 "client_account[%s] client_computer_name[%s]\n",
1135 opname, opnum,
1136 log_escape(mem_ctx, creds->account_name),
1137 log_escape(mem_ctx, creds->computer_name));
1138 DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
1139 "'server require schannel:%s = no' is needed! \n",
1140 log_escape(mem_ctx, creds->account_name));
1141 TALLOC_FREE(creds);
1142 ZERO_STRUCTP(return_authenticator);
1143 return NT_STATUS_ACCESS_DENIED;
1146 if (!schannel_global_required && !warned_global_once) {
1148 * We want admins to notice their misconfiguration!
1150 DBG_ERR("CVE-2020-1472(ZeroLogon): "
1151 "Please configure 'server schannel = yes', "
1152 "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
1153 warned_global_once = true;
1156 if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1157 DBG_ERR("CVE-2020-1472(ZeroLogon): "
1158 "%s request (opnum[%u]) WITH schannel from "
1159 "client_account[%s] client_computer_name[%s]\n",
1160 opname, opnum,
1161 log_escape(mem_ctx, creds->account_name),
1162 log_escape(mem_ctx, creds->computer_name));
1163 DBG_ERR("CVE-2020-1472(ZeroLogon): "
1164 "Option 'server require schannel:%s = no' not needed!?\n",
1165 log_escape(mem_ctx, creds->account_name));
1167 *creds_out = creds;
1168 return NT_STATUS_OK;
1171 if (explicit_opt != NULL) {
1172 DBG_INFO("CVE-2020-1472(ZeroLogon): "
1173 "%s request (opnum[%u]) without schannel from "
1174 "client_account[%s] client_computer_name[%s]\n",
1175 opname, opnum,
1176 log_escape(mem_ctx, creds->account_name),
1177 log_escape(mem_ctx, creds->computer_name));
1178 DBG_INFO("CVE-2020-1472(ZeroLogon): "
1179 "Option 'server require schannel:%s = no' still needed!\n",
1180 log_escape(mem_ctx, creds->account_name));
1181 } else {
1182 DBG_ERR("CVE-2020-1472(ZeroLogon): "
1183 "%s request (opnum[%u]) without schannel from "
1184 "client_account[%s] client_computer_name[%s]\n",
1185 opname, opnum,
1186 log_escape(mem_ctx, creds->account_name),
1187 log_escape(mem_ctx, creds->computer_name));
1188 DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
1189 "'server require schannel:%s = no' might be needed!\n",
1190 log_escape(mem_ctx, creds->account_name));
1193 *creds_out = creds;
1194 return NT_STATUS_OK;
1198 /*************************************************************************
1199 *************************************************************************/
1201 static NTSTATUS samr_open_machine_account(
1202 struct dcerpc_binding_handle *b,
1203 const struct dom_sid *machine_sid,
1204 uint32_t access_mask,
1205 struct policy_handle *machine_handle)
1207 TALLOC_CTX *frame = talloc_stackframe();
1208 struct policy_handle connect_handle = { .handle_type = 0 };
1209 struct policy_handle domain_handle = { .handle_type = 0 };
1210 struct dom_sid domain_sid = *machine_sid;
1211 uint32_t machine_rid;
1212 NTSTATUS result = NT_STATUS_OK;
1213 NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
1214 bool ok;
1216 ok = sid_split_rid(&domain_sid, &machine_rid);
1217 if (!ok) {
1218 goto out;
1221 status = dcerpc_samr_Connect2(
1223 frame,
1224 lp_netbios_name(),
1225 SAMR_ACCESS_CONNECT_TO_SERVER |
1226 SAMR_ACCESS_ENUM_DOMAINS |
1227 SAMR_ACCESS_LOOKUP_DOMAIN,
1228 &connect_handle,
1229 &result);
1230 if (any_nt_status_not_ok(status, result, &status)) {
1231 goto out;
1234 status = dcerpc_samr_OpenDomain(
1236 frame,
1237 &connect_handle,
1238 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1239 &domain_sid,
1240 &domain_handle,
1241 &result);
1242 if (any_nt_status_not_ok(status, result, &status)) {
1243 goto out;
1246 status = dcerpc_samr_OpenUser(
1248 frame,
1249 &domain_handle,
1250 SEC_FLAG_MAXIMUM_ALLOWED,
1251 machine_rid,
1252 machine_handle,
1253 &result);
1254 if (any_nt_status_not_ok(status, result, &status)) {
1255 goto out;
1258 out:
1259 if ((b != NULL) && is_valid_policy_hnd(&domain_handle)) {
1260 dcerpc_samr_Close(b, frame, &domain_handle, &result);
1262 if ((b != NULL) && is_valid_policy_hnd(&connect_handle)) {
1263 dcerpc_samr_Close(b, frame, &connect_handle, &result);
1265 TALLOC_FREE(frame);
1266 return status;
1269 struct _samr_Credentials_t {
1270 enum {
1271 CRED_TYPE_NT_HASH,
1272 CRED_TYPE_PLAIN_TEXT,
1273 } cred_type;
1274 union {
1275 struct samr_Password *nt_hash;
1276 const char *password;
1277 } creds;
1281 static NTSTATUS netr_set_machine_account_password(
1282 TALLOC_CTX *mem_ctx,
1283 struct auth_session_info *session_info,
1284 struct messaging_context *msg_ctx,
1285 const struct dom_sid *machine_sid,
1286 struct _samr_Credentials_t *cr)
1288 NTSTATUS status;
1289 NTSTATUS result = NT_STATUS_OK;
1290 struct dcerpc_binding_handle *h = NULL;
1291 struct tsocket_address *local;
1292 struct policy_handle user_handle = { .handle_type = 0 };
1293 uint32_t acct_ctrl;
1294 union samr_UserInfo *info;
1295 struct samr_UserInfo18 info18;
1296 struct samr_UserInfo26 info26;
1297 DATA_BLOB in,out;
1298 int rc;
1299 DATA_BLOB session_key;
1300 enum samr_UserInfoLevel infolevel;
1301 TALLOC_CTX *frame = talloc_stackframe();
1303 status = session_extract_session_key(session_info,
1304 &session_key,
1305 KEY_USE_16BYTES);
1306 if (!NT_STATUS_IS_OK(status)) {
1307 goto out;
1310 rc = tsocket_address_inet_from_strings(frame,
1311 "ip",
1312 "127.0.0.1",
1314 &local);
1315 if (rc < 0) {
1316 status = NT_STATUS_NO_MEMORY;
1317 goto out;
1320 status = rpcint_binding_handle(frame,
1321 &ndr_table_samr,
1322 local,
1323 NULL,
1324 get_session_info_system(),
1325 msg_ctx,
1326 &h);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 goto out;
1331 status = samr_open_machine_account(
1332 h, machine_sid, SEC_FLAG_MAXIMUM_ALLOWED, &user_handle);
1333 if (!NT_STATUS_IS_OK(status)) {
1334 goto out;
1337 status = dcerpc_samr_QueryUserInfo2(h,
1338 frame,
1339 &user_handle,
1340 UserControlInformation,
1341 &info,
1342 &result);
1343 if (any_nt_status_not_ok(status, result, &status)) {
1344 goto out;
1347 acct_ctrl = info->info16.acct_flags;
1349 if (!(acct_ctrl & ACB_WSTRUST ||
1350 acct_ctrl & ACB_SVRTRUST ||
1351 acct_ctrl & ACB_DOMTRUST)) {
1352 status = NT_STATUS_NO_SUCH_USER;
1353 goto out;
1356 if (acct_ctrl & ACB_DISABLED) {
1357 status = NT_STATUS_ACCOUNT_DISABLED;
1358 goto out;
1361 switch(cr->cred_type) {
1362 case CRED_TYPE_NT_HASH:
1363 ZERO_STRUCT(info18);
1365 infolevel = UserInternal1Information;
1367 in = data_blob_const(cr->creds.nt_hash, 16);
1368 out = data_blob_talloc_zero(frame, 16);
1369 if (out.data == NULL) {
1370 status = NT_STATUS_NO_MEMORY;
1371 goto out;
1373 rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
1374 if (rc != 0) {
1375 status = gnutls_error_to_ntstatus(rc,
1376 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
1377 goto out;
1379 memcpy(info18.nt_pwd.hash, out.data, out.length);
1381 info18.nt_pwd_active = true;
1383 info->info18 = info18;
1384 break;
1385 case CRED_TYPE_PLAIN_TEXT:
1386 ZERO_STRUCT(info26);
1388 infolevel = UserInternal5InformationNew;
1390 status = init_samr_CryptPasswordEx(cr->creds.password,
1391 &session_key,
1392 &info26.password);
1393 if (!NT_STATUS_IS_OK(status)) {
1394 goto out;
1397 info26.password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON;
1398 info->info26 = info26;
1399 break;
1400 default:
1401 status = NT_STATUS_INTERNAL_ERROR;
1402 goto out;
1403 break;
1406 status = dcerpc_samr_SetUserInfo2(h,
1407 frame,
1408 &user_handle,
1409 infolevel,
1410 info,
1411 &result);
1412 if (any_nt_status_not_ok(status, result, &status)) {
1413 goto out;
1416 out:
1417 if (h && is_valid_policy_hnd(&user_handle)) {
1418 dcerpc_samr_Close(h, frame, &user_handle, &result);
1420 TALLOC_FREE(frame);
1422 return status;
1425 /*************************************************************************
1426 _netr_ServerPasswordSet
1427 *************************************************************************/
1429 NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
1430 struct netr_ServerPasswordSet *r)
1432 struct dcesrv_call_state *dce_call = p->dce_call;
1433 struct auth_session_info *session_info =
1434 dcesrv_call_session_info(dce_call);
1435 NTSTATUS status = NT_STATUS_OK;
1436 size_t i;
1437 struct netlogon_creds_CredentialState *creds = NULL;
1438 struct _samr_Credentials_t cr = { CRED_TYPE_NT_HASH, {0}};
1440 DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
1442 become_root();
1443 status = netr_creds_server_step_check(p, p->mem_ctx,
1444 r->in.computer_name,
1445 r->in.credential,
1446 r->out.return_authenticator,
1447 &creds);
1448 unbecome_root();
1450 if (!NT_STATUS_IS_OK(status)) {
1451 const char *computer_name = "<unknown>";
1453 if (creds != NULL && creds->computer_name != NULL) {
1454 computer_name = creds->computer_name;
1456 DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth "
1457 "request from client %s machine account %s\n",
1458 r->in.computer_name, computer_name));
1459 TALLOC_FREE(creds);
1460 return status;
1463 DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
1464 r->in.computer_name, creds->computer_name));
1466 status = netlogon_creds_des_decrypt(creds, r->in.new_password);
1467 if (!NT_STATUS_IS_OK(status)) {
1468 return status;
1471 DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
1472 for(i = 0; i < sizeof(r->in.new_password->hash); i++)
1473 DEBUG(100,("%02X ", r->in.new_password->hash[i]));
1474 DEBUG(100,("\n"));
1476 cr.creds.nt_hash = r->in.new_password;
1477 status = netr_set_machine_account_password(p->mem_ctx,
1478 session_info,
1479 p->msg_ctx,
1480 creds->sid,
1481 &cr);
1482 return status;
1485 /****************************************************************
1486 _netr_ServerPasswordSet2
1487 ****************************************************************/
1489 NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
1490 struct netr_ServerPasswordSet2 *r)
1492 struct dcesrv_call_state *dce_call = p->dce_call;
1493 struct auth_session_info *session_info =
1494 dcesrv_call_session_info(dce_call);
1495 NTSTATUS status;
1496 struct netlogon_creds_CredentialState *creds = NULL;
1497 DATA_BLOB plaintext = data_blob_null;
1498 DATA_BLOB new_password = data_blob_null;
1499 size_t confounder_len;
1500 DATA_BLOB dec_blob = data_blob_null;
1501 DATA_BLOB enc_blob = data_blob_null;
1502 struct samr_CryptPassword password_buf;
1503 struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}};
1504 bool ok;
1506 become_root();
1507 status = netr_creds_server_step_check(p, p->mem_ctx,
1508 r->in.computer_name,
1509 r->in.credential,
1510 r->out.return_authenticator,
1511 &creds);
1512 unbecome_root();
1514 if (!NT_STATUS_IS_OK(status)) {
1515 DBG_NOTICE("netlogon_creds_server_step failed. "
1516 "Rejecting auth request from client %s\n",
1517 r->in.computer_name);
1518 TALLOC_FREE(creds);
1519 return status;
1522 DBG_NOTICE("Server Password Set2 by remote "
1523 "machine:[%s] on account [%s]\n",
1524 r->in.computer_name,
1525 creds->computer_name != NULL ?
1526 creds->computer_name : "<unknown>");
1528 memcpy(password_buf.data, r->in.new_password->data, 512);
1529 SIVAL(password_buf.data, 512, r->in.new_password->length);
1531 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1532 status = netlogon_creds_aes_decrypt(creds,
1533 password_buf.data,
1534 516);
1535 } else {
1536 status = netlogon_creds_arcfour_crypt(creds,
1537 password_buf.data,
1538 516);
1540 if (!NT_STATUS_IS_OK(status)) {
1541 TALLOC_FREE(creds);
1542 return status;
1545 if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, &new_password)) {
1546 DEBUG(2,("_netr_ServerPasswordSet2: unable to extract password "
1547 "from a buffer. Rejecting auth request as a wrong password\n"));
1548 TALLOC_FREE(creds);
1549 return NT_STATUS_WRONG_PASSWORD;
1553 * Make sure the length field was encrypted,
1554 * otherwise we are under attack.
1556 if (new_password.length == r->in.new_password->length) {
1557 DBG_WARNING("Length[%zu] field not encrypted\n",
1558 new_password.length);
1559 TALLOC_FREE(creds);
1560 return NT_STATUS_WRONG_PASSWORD;
1564 * We don't allow empty passwords for machine accounts.
1566 if (new_password.length < 2) {
1567 DBG_WARNING("Empty password Length[%zu]\n",
1568 new_password.length);
1569 TALLOC_FREE(creds);
1570 return NT_STATUS_WRONG_PASSWORD;
1574 * Make sure the confounder part of CryptPassword
1575 * buffer was encrypted, otherwise we are under attack.
1577 confounder_len = 512 - new_password.length;
1578 enc_blob = data_blob_const(r->in.new_password->data, confounder_len);
1579 dec_blob = data_blob_const(password_buf.data, confounder_len);
1580 if (confounder_len > 0 && data_blob_cmp(&dec_blob, &enc_blob) == 0) {
1581 DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
1582 confounder_len);
1583 TALLOC_FREE(creds);
1584 return NT_STATUS_WRONG_PASSWORD;
1588 * Check that the password part was actually encrypted,
1589 * otherwise we are under attack.
1591 enc_blob = data_blob_const(r->in.new_password->data + confounder_len,
1592 new_password.length);
1593 dec_blob = data_blob_const(password_buf.data + confounder_len,
1594 new_password.length);
1595 if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
1596 DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
1597 new_password.length);
1598 TALLOC_FREE(creds);
1599 return NT_STATUS_WRONG_PASSWORD;
1603 * don't allow zero buffers
1605 if (all_zero(new_password.data, new_password.length)) {
1606 DBG_WARNING("Password zero buffer Length[%zu]\n",
1607 new_password.length);
1608 TALLOC_FREE(creds);
1609 return NT_STATUS_WRONG_PASSWORD;
1612 /* Convert from UTF16 -> plaintext. */
1613 ok = convert_string_talloc(p->mem_ctx,
1614 CH_UTF16,
1615 CH_UNIX,
1616 new_password.data,
1617 new_password.length,
1618 (void *)&plaintext.data,
1619 &plaintext.length);
1620 if (!ok) {
1621 DBG_WARNING("unable to extract password from a buffer. "
1622 "Rejecting auth request as a wrong password\n");
1623 TALLOC_FREE(creds);
1624 return NT_STATUS_WRONG_PASSWORD;
1628 * We don't allow empty passwords for machine accounts.
1631 cr.creds.password = (const char*) plaintext.data;
1632 if (strlen(cr.creds.password) == 0) {
1633 DBG_WARNING("Empty plaintext password\n");
1634 TALLOC_FREE(creds);
1635 return NT_STATUS_WRONG_PASSWORD;
1638 status = netr_set_machine_account_password(p->mem_ctx,
1639 session_info,
1640 p->msg_ctx,
1641 creds->sid,
1642 &cr);
1643 TALLOC_FREE(creds);
1644 return status;
1647 /*************************************************************************
1648 _netr_LogonSamLogoff
1649 *************************************************************************/
1651 NTSTATUS _netr_LogonSamLogoff(struct pipes_struct *p,
1652 struct netr_LogonSamLogoff *r)
1654 NTSTATUS status;
1655 struct netlogon_creds_CredentialState *creds;
1657 become_root();
1658 status = netr_creds_server_step_check(p, p->mem_ctx,
1659 r->in.computer_name,
1660 r->in.credential,
1661 r->out.return_authenticator,
1662 &creds);
1663 unbecome_root();
1665 return status;
1668 static NTSTATUS _netr_LogonSamLogon_check(const struct netr_LogonSamLogonEx *r)
1670 switch (r->in.logon_level) {
1671 case NetlogonInteractiveInformation:
1672 case NetlogonServiceInformation:
1673 case NetlogonInteractiveTransitiveInformation:
1674 case NetlogonServiceTransitiveInformation:
1675 if (r->in.logon->password == NULL) {
1676 return NT_STATUS_INVALID_PARAMETER;
1679 switch (r->in.validation_level) {
1680 case NetlogonValidationSamInfo: /* 2 */
1681 case NetlogonValidationSamInfo2: /* 3 */
1682 break;
1683 case NetlogonValidationSamInfo4: /* 6 */
1684 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
1685 DEBUG(10,("Not adding validation info level 6 "
1686 "without ADS passdb backend\n"));
1687 return NT_STATUS_INVALID_INFO_CLASS;
1689 break;
1690 default:
1691 return NT_STATUS_INVALID_INFO_CLASS;
1694 break;
1695 case NetlogonNetworkInformation:
1696 case NetlogonNetworkTransitiveInformation:
1697 if (r->in.logon->network == NULL) {
1698 return NT_STATUS_INVALID_PARAMETER;
1701 switch (r->in.validation_level) {
1702 case NetlogonValidationSamInfo: /* 2 */
1703 case NetlogonValidationSamInfo2: /* 3 */
1704 break;
1705 case NetlogonValidationSamInfo4: /* 6 */
1706 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
1707 DEBUG(10,("Not adding validation info level 6 "
1708 "without ADS passdb backend\n"));
1709 return NT_STATUS_INVALID_INFO_CLASS;
1711 break;
1712 default:
1713 return NT_STATUS_INVALID_INFO_CLASS;
1716 break;
1718 case NetlogonGenericInformation:
1719 if (r->in.logon->generic == NULL) {
1720 return NT_STATUS_INVALID_PARAMETER;
1723 /* we don't support this here */
1724 return NT_STATUS_INVALID_PARAMETER;
1725 #if 0
1726 switch (r->in.validation_level) {
1727 /* TODO: case NetlogonValidationGenericInfo: 4 */
1728 case NetlogonValidationGenericInfo2: /* 5 */
1729 break;
1730 default:
1731 return NT_STATUS_INVALID_INFO_CLASS;
1734 break;
1735 #endif
1736 default:
1737 return NT_STATUS_INVALID_PARAMETER;
1740 return NT_STATUS_OK;
1743 /*************************************************************************
1744 _netr_LogonSamLogon_base
1745 *************************************************************************/
1747 static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
1748 struct netr_LogonSamLogonEx *r,
1749 struct netlogon_creds_CredentialState *creds)
1751 struct dcesrv_call_state *dce_call = p->dce_call;
1752 struct dcesrv_connection *dcesrv_conn = dce_call->conn;
1753 const struct tsocket_address *local_address =
1754 dcesrv_connection_get_local_address(dcesrv_conn);
1755 const struct tsocket_address *remote_address =
1756 dcesrv_connection_get_remote_address(dcesrv_conn);
1757 NTSTATUS status = NT_STATUS_OK;
1758 union netr_LogonLevel *logon = r->in.logon;
1759 const char *nt_username, *nt_domain, *nt_workstation;
1760 char *sanitized_username = NULL;
1761 struct auth_usersupplied_info *user_info = NULL;
1762 struct auth_serversupplied_info *server_info = NULL;
1763 struct auth_context *auth_context = NULL;
1764 const char *fn;
1766 #ifdef DEBUG_PASSWORD
1767 logon = netlogon_creds_shallow_copy_logon(p->mem_ctx,
1768 r->in.logon_level,
1769 r->in.logon);
1770 if (logon == NULL) {
1771 logon = r->in.logon;
1773 #endif
1775 switch (dce_call->pkt.u.request.opnum) {
1776 case NDR_NETR_LOGONSAMLOGON:
1777 fn = "_netr_LogonSamLogon";
1778 break;
1779 case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
1780 fn = "_netr_LogonSamLogonWithFlags";
1781 break;
1782 case NDR_NETR_LOGONSAMLOGONEX:
1783 fn = "_netr_LogonSamLogonEx";
1784 break;
1785 default:
1786 return NT_STATUS_INTERNAL_ERROR;
1789 *r->out.authoritative = 1; /* authoritative response */
1791 switch (r->in.validation_level) {
1792 case 2:
1793 r->out.validation->sam2 = talloc_zero(p->mem_ctx, struct netr_SamInfo2);
1794 if (!r->out.validation->sam2) {
1795 return NT_STATUS_NO_MEMORY;
1797 break;
1798 case 3:
1799 r->out.validation->sam3 = talloc_zero(p->mem_ctx, struct netr_SamInfo3);
1800 if (!r->out.validation->sam3) {
1801 return NT_STATUS_NO_MEMORY;
1803 break;
1804 case 6:
1805 r->out.validation->sam6 = talloc_zero(p->mem_ctx, struct netr_SamInfo6);
1806 if (!r->out.validation->sam6) {
1807 return NT_STATUS_NO_MEMORY;
1809 break;
1810 default:
1811 DEBUG(0,("%s: bad validation_level value %d.\n",
1812 fn, (int)r->in.validation_level));
1813 return NT_STATUS_INVALID_INFO_CLASS;
1816 switch (r->in.logon_level) {
1817 case NetlogonInteractiveInformation:
1818 case NetlogonServiceInformation:
1819 case NetlogonInteractiveTransitiveInformation:
1820 case NetlogonServiceTransitiveInformation:
1821 nt_username = logon->password->identity_info.account_name.string ?
1822 logon->password->identity_info.account_name.string : "";
1823 nt_domain = logon->password->identity_info.domain_name.string ?
1824 logon->password->identity_info.domain_name.string : "";
1825 nt_workstation = logon->password->identity_info.workstation.string ?
1826 logon->password->identity_info.workstation.string : "";
1828 DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", lp_workgroup()));
1829 break;
1830 case NetlogonNetworkInformation:
1831 case NetlogonNetworkTransitiveInformation:
1832 nt_username = logon->network->identity_info.account_name.string ?
1833 logon->network->identity_info.account_name.string : "";
1834 nt_domain = logon->network->identity_info.domain_name.string ?
1835 logon->network->identity_info.domain_name.string : "";
1836 nt_workstation = logon->network->identity_info.workstation.string ?
1837 logon->network->identity_info.workstation.string : "";
1839 DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", lp_workgroup()));
1840 break;
1841 default:
1842 DEBUG(2,("SAM Logon: unsupported switch value\n"));
1843 return NT_STATUS_INVALID_INFO_CLASS;
1844 } /* end switch */
1846 DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username, nt_workstation, nt_domain));
1848 DEBUG(5,("Attempting validation level %d for unmapped username %s.\n",
1849 r->in.validation_level, nt_username));
1851 status = netlogon_creds_decrypt_samlogon_logon(creds,
1852 r->in.logon_level,
1853 logon);
1854 if (!NT_STATUS_IS_OK(status)) {
1855 return status;
1858 status = make_auth3_context_for_netlogon(talloc_tos(), &auth_context);
1859 if (!NT_STATUS_IS_OK(status)) {
1860 return status;
1863 switch (r->in.logon_level) {
1864 case NetlogonNetworkInformation:
1865 case NetlogonNetworkTransitiveInformation:
1867 const char *wksname = nt_workstation;
1868 const char *workgroup = lp_workgroup();
1869 bool ok;
1871 ok = auth3_context_set_challenge(
1872 auth_context, logon->network->challenge, "fixed");
1873 if (!ok) {
1874 return NT_STATUS_NO_MEMORY;
1877 /* For a network logon, the workstation name comes in with two
1878 * backslashes in the front. Strip them if they are there. */
1880 if (*wksname == '\\') wksname++;
1881 if (*wksname == '\\') wksname++;
1883 /* Standard challenge/response authentication */
1884 if (!make_user_info_netlogon_network(talloc_tos(),
1885 &user_info,
1886 nt_username, nt_domain,
1887 wksname,
1888 remote_address,
1889 local_address,
1890 logon->network->identity_info.parameter_control,
1891 logon->network->lm.data,
1892 logon->network->lm.length,
1893 logon->network->nt.data,
1894 logon->network->nt.length)) {
1895 status = NT_STATUS_NO_MEMORY;
1898 if (NT_STATUS_IS_OK(status)) {
1899 status = NTLMv2_RESPONSE_verify_netlogon_creds(
1900 user_info->client.account_name,
1901 user_info->client.domain_name,
1902 user_info->password.response.nt,
1903 creds, workgroup);
1905 break;
1907 case NetlogonInteractiveInformation:
1908 case NetlogonServiceInformation:
1909 case NetlogonInteractiveTransitiveInformation:
1910 case NetlogonServiceTransitiveInformation:
1912 /* 'Interactive' authentication, supplies the password in its
1913 MD4 form, encrypted with the session key. We will convert
1914 this to challenge/response for the auth subsystem to chew
1915 on */
1917 uint8_t chal[8];
1919 #ifdef DEBUG_PASSWORD
1920 if (logon != r->in.logon) {
1921 DEBUG(100,("lm owf password:"));
1922 dump_data(100,
1923 r->in.logon->password->lmpassword.hash, 16);
1925 DEBUG(100,("nt owf password:"));
1926 dump_data(100,
1927 r->in.logon->password->ntpassword.hash, 16);
1930 DEBUG(100,("decrypt of lm owf password:"));
1931 dump_data(100, logon->password->lmpassword.hash, 16);
1933 DEBUG(100,("decrypt of nt owf password:"));
1934 dump_data(100, logon->password->ntpassword.hash, 16);
1935 #endif
1937 auth_get_ntlm_challenge(auth_context, chal);
1939 if (!make_user_info_netlogon_interactive(talloc_tos(),
1940 &user_info,
1941 nt_username, nt_domain,
1942 nt_workstation,
1943 remote_address,
1944 local_address,
1945 logon->password->identity_info.parameter_control,
1946 chal,
1947 logon->password->lmpassword.hash,
1948 logon->password->ntpassword.hash)) {
1949 status = NT_STATUS_NO_MEMORY;
1951 break;
1953 default:
1954 DEBUG(2,("SAM Logon: unsupported switch value\n"));
1955 return NT_STATUS_INVALID_INFO_CLASS;
1956 } /* end switch */
1958 if ( NT_STATUS_IS_OK(status) ) {
1959 status = auth_check_ntlm_password(p->mem_ctx,
1960 auth_context,
1961 user_info,
1962 &server_info,
1963 r->out.authoritative);
1966 TALLOC_FREE(auth_context);
1967 TALLOC_FREE(user_info);
1969 DEBUG(5,("%s: check_password returned status %s\n",
1970 fn, nt_errstr(status)));
1972 /* Check account and password */
1974 if (!NT_STATUS_IS_OK(status)) {
1975 TALLOC_FREE(server_info);
1976 return status;
1979 if (server_info->guest) {
1980 /* We don't like guest domain logons... */
1981 DEBUG(5,("%s: Attempted domain logon as GUEST "
1982 "denied.\n", fn));
1983 TALLOC_FREE(server_info);
1984 return NT_STATUS_LOGON_FAILURE;
1987 sanitized_username = talloc_alpha_strcpy(talloc_tos(),
1988 nt_username,
1989 SAFE_NETBIOS_CHARS "$");
1990 if (sanitized_username == NULL) {
1991 TALLOC_FREE(server_info);
1992 return NT_STATUS_NO_MEMORY;
1995 set_current_user_info(sanitized_username,
1996 server_info->unix_name,
1997 server_info->info3->base.logon_domain.string);
1998 TALLOC_FREE(sanitized_username);
2000 /* This is the point at which, if the login was successful, that
2001 the SAM Local Security Authority should record that the user is
2002 logged in to the domain. */
2004 switch (r->in.validation_level) {
2005 case 2:
2006 status = serverinfo_to_SamInfo2(server_info,
2007 r->out.validation->sam2);
2008 break;
2009 case 3:
2010 status = serverinfo_to_SamInfo3(server_info,
2011 r->out.validation->sam3);
2012 break;
2013 case 6: {
2014 enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
2016 dcesrv_call_auth_info(dce_call, NULL, &auth_level);
2018 /* Only allow this if the pipe is protected. */
2019 if (auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
2020 DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n",
2021 get_remote_machine_name()));
2022 status = NT_STATUS_INVALID_PARAMETER;
2023 break;
2026 status = serverinfo_to_SamInfo6(server_info,
2027 r->out.validation->sam6);
2028 break;
2032 TALLOC_FREE(server_info);
2034 if (!NT_STATUS_IS_OK(status)) {
2035 return status;
2038 status = netlogon_creds_encrypt_samlogon_validation(creds,
2039 r->in.validation_level,
2040 r->out.validation);
2042 return status;
2045 /****************************************************************
2046 _netr_LogonSamLogonWithFlags
2047 ****************************************************************/
2049 NTSTATUS _netr_LogonSamLogonWithFlags(struct pipes_struct *p,
2050 struct netr_LogonSamLogonWithFlags *r)
2052 NTSTATUS status;
2053 struct netlogon_creds_CredentialState *creds;
2054 struct netr_LogonSamLogonEx r2;
2055 struct netr_Authenticator return_authenticator;
2057 *r->out.authoritative = true;
2059 r2.in.server_name = r->in.server_name;
2060 r2.in.computer_name = r->in.computer_name;
2061 r2.in.logon_level = r->in.logon_level;
2062 r2.in.logon = r->in.logon;
2063 r2.in.validation_level = r->in.validation_level;
2064 r2.in.flags = r->in.flags;
2065 r2.out.validation = r->out.validation;
2066 r2.out.authoritative = r->out.authoritative;
2067 r2.out.flags = r->out.flags;
2069 status = _netr_LogonSamLogon_check(&r2);
2070 if (!NT_STATUS_IS_OK(status)) {
2071 return status;
2074 become_root();
2075 status = netr_creds_server_step_check(p, p->mem_ctx,
2076 r->in.computer_name,
2077 r->in.credential,
2078 &return_authenticator,
2079 &creds);
2080 unbecome_root();
2081 if (!NT_STATUS_IS_OK(status)) {
2082 return status;
2085 status = _netr_LogonSamLogon_base(p, &r2, creds);
2087 *r->out.return_authenticator = return_authenticator;
2089 return status;
2092 /*************************************************************************
2093 _netr_LogonSamLogon
2094 *************************************************************************/
2096 NTSTATUS _netr_LogonSamLogon(struct pipes_struct *p,
2097 struct netr_LogonSamLogon *r)
2099 NTSTATUS status;
2100 struct netr_LogonSamLogonWithFlags r2;
2101 uint32_t flags = 0;
2103 r2.in.server_name = r->in.server_name;
2104 r2.in.computer_name = r->in.computer_name;
2105 r2.in.credential = r->in.credential;
2106 r2.in.logon_level = r->in.logon_level;
2107 r2.in.logon = r->in.logon;
2108 r2.in.validation_level = r->in.validation_level;
2109 r2.in.return_authenticator = r->in.return_authenticator;
2110 r2.in.flags = &flags;
2111 r2.out.validation = r->out.validation;
2112 r2.out.authoritative = r->out.authoritative;
2113 r2.out.flags = &flags;
2114 r2.out.return_authenticator = r->out.return_authenticator;
2116 status = _netr_LogonSamLogonWithFlags(p, &r2);
2118 return status;
2121 /*************************************************************************
2122 _netr_LogonSamLogonEx
2123 - no credential chaining. Map into net sam logon.
2124 *************************************************************************/
2126 NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
2127 struct netr_LogonSamLogonEx *r)
2129 struct dcesrv_call_state *dce_call = p->dce_call;
2130 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
2131 NTSTATUS status;
2132 struct netlogon_creds_CredentialState *creds = NULL;
2133 struct loadparm_context *lp_ctx;
2135 *r->out.authoritative = true;
2137 status = _netr_LogonSamLogon_check(r);
2138 if (!NT_STATUS_IS_OK(status)) {
2139 return status;
2142 /* Only allow this if the pipe is protected. */
2144 dcesrv_call_auth_info(dce_call, &auth_type, NULL);
2146 if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
2147 DEBUG(0,("_netr_LogonSamLogonEx: client %s not using schannel for netlogon\n",
2148 get_remote_machine_name() ));
2149 return NT_STATUS_INVALID_PARAMETER;
2152 lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
2153 if (lp_ctx == NULL) {
2154 DEBUG(0, ("loadparm_init_s3 failed\n"));
2155 return NT_STATUS_INTERNAL_ERROR;
2158 become_root();
2159 status = schannel_get_creds_state(p->mem_ctx, lp_ctx,
2160 r->in.computer_name, &creds);
2161 unbecome_root();
2162 talloc_unlink(p->mem_ctx, lp_ctx);
2164 if (!NT_STATUS_IS_OK(status)) {
2165 return status;
2168 status = _netr_LogonSamLogon_base(p, r, creds);
2169 TALLOC_FREE(creds);
2171 return status;
2174 /*************************************************************************
2175 _ds_enum_dom_trusts
2176 *************************************************************************/
2177 #if 0 /* JERRY -- not correct */
2178 NTSTATUS _ds_enum_dom_trusts(struct pipes_struct *p, DS_Q_ENUM_DOM_TRUSTS *q_u,
2179 DS_R_ENUM_DOM_TRUSTS *r_u)
2181 NTSTATUS status = NT_STATUS_OK;
2183 /* TODO: According to MSDN, the can only be executed against a
2184 DC or domain member running Windows 2000 or later. Need
2185 to test against a standalone 2k server and see what it
2186 does. A windows 2000 DC includes its own domain in the
2187 list. --jerry */
2189 return status;
2191 #endif /* JERRY */
2194 /****************************************************************
2195 ****************************************************************/
2197 WERROR _netr_LogonUasLogon(struct pipes_struct *p,
2198 struct netr_LogonUasLogon *r)
2200 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2201 return WERR_NOT_SUPPORTED;
2204 /****************************************************************
2205 ****************************************************************/
2207 WERROR _netr_LogonUasLogoff(struct pipes_struct *p,
2208 struct netr_LogonUasLogoff *r)
2210 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2211 return WERR_NOT_SUPPORTED;
2214 /****************************************************************
2215 ****************************************************************/
2217 NTSTATUS _netr_DatabaseDeltas(struct pipes_struct *p,
2218 struct netr_DatabaseDeltas *r)
2220 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2221 return NT_STATUS_NOT_IMPLEMENTED;
2224 /****************************************************************
2225 ****************************************************************/
2227 NTSTATUS _netr_DatabaseSync(struct pipes_struct *p,
2228 struct netr_DatabaseSync *r)
2230 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2231 return NT_STATUS_NOT_IMPLEMENTED;
2234 /****************************************************************
2235 ****************************************************************/
2237 NTSTATUS _netr_AccountDeltas(struct pipes_struct *p,
2238 struct netr_AccountDeltas *r)
2240 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2241 return NT_STATUS_NOT_IMPLEMENTED;
2244 /****************************************************************
2245 ****************************************************************/
2247 NTSTATUS _netr_AccountSync(struct pipes_struct *p,
2248 struct netr_AccountSync *r)
2250 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2251 return NT_STATUS_NOT_IMPLEMENTED;
2254 /****************************************************************
2255 ****************************************************************/
2257 static bool wb_getdcname(TALLOC_CTX *mem_ctx,
2258 const char *domain,
2259 const char **dcname,
2260 uint32_t flags,
2261 WERROR *werr)
2263 wbcErr result;
2264 struct wbcDomainControllerInfo *dc_info = NULL;
2266 result = wbcLookupDomainController(domain,
2267 flags,
2268 &dc_info);
2269 switch (result) {
2270 case WBC_ERR_SUCCESS:
2271 break;
2272 case WBC_ERR_WINBIND_NOT_AVAILABLE:
2273 return false;
2274 case WBC_ERR_DOMAIN_NOT_FOUND:
2275 *werr = WERR_NO_SUCH_DOMAIN;
2276 return true;
2277 default:
2278 *werr = WERR_DOMAIN_CONTROLLER_NOT_FOUND;
2279 return true;
2282 *dcname = talloc_strdup(mem_ctx, dc_info->dc_name);
2283 wbcFreeMemory(dc_info);
2284 if (!*dcname) {
2285 *werr = WERR_NOT_ENOUGH_MEMORY;
2286 return false;
2289 *werr = WERR_OK;
2291 return true;
2294 /****************************************************************
2295 _netr_GetDcName
2296 ****************************************************************/
2298 WERROR _netr_GetDcName(struct pipes_struct *p,
2299 struct netr_GetDcName *r)
2301 NTSTATUS status;
2302 WERROR werr;
2303 uint32_t flags;
2304 struct netr_DsRGetDCNameInfo *info;
2305 bool ret;
2307 ret = wb_getdcname(p->mem_ctx,
2308 r->in.domainname,
2309 r->out.dcname,
2310 WBC_LOOKUP_DC_IS_FLAT_NAME |
2311 WBC_LOOKUP_DC_RETURN_FLAT_NAME |
2312 WBC_LOOKUP_DC_PDC_REQUIRED,
2313 &werr);
2314 if (ret == true) {
2315 return werr;
2318 flags = DS_PDC_REQUIRED | DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME;
2320 status = dsgetdcname(p->mem_ctx,
2321 p->msg_ctx,
2322 r->in.domainname,
2323 NULL,
2324 NULL,
2325 flags,
2326 &info);
2327 if (!NT_STATUS_IS_OK(status)) {
2328 return ntstatus_to_werror(status);
2331 *r->out.dcname = talloc_strdup(p->mem_ctx, info->dc_unc);
2332 talloc_free(info);
2333 if (!*r->out.dcname) {
2334 return WERR_NOT_ENOUGH_MEMORY;
2337 return WERR_OK;
2340 /****************************************************************
2341 _netr_GetAnyDCName
2342 ****************************************************************/
2344 WERROR _netr_GetAnyDCName(struct pipes_struct *p,
2345 struct netr_GetAnyDCName *r)
2347 NTSTATUS status;
2348 WERROR werr;
2349 uint32_t flags;
2350 struct netr_DsRGetDCNameInfo *info;
2351 bool ret;
2353 ret = wb_getdcname(p->mem_ctx,
2354 r->in.domainname,
2355 r->out.dcname,
2356 WBC_LOOKUP_DC_IS_FLAT_NAME |
2357 WBC_LOOKUP_DC_RETURN_FLAT_NAME,
2358 &werr);
2359 if (ret == true) {
2360 return werr;
2363 flags = DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME;
2365 status = dsgetdcname(p->mem_ctx,
2366 p->msg_ctx,
2367 r->in.domainname,
2368 NULL,
2369 NULL,
2370 flags,
2371 &info);
2372 if (!NT_STATUS_IS_OK(status)) {
2373 return ntstatus_to_werror(status);
2376 *r->out.dcname = talloc_strdup(p->mem_ctx, info->dc_unc);
2377 talloc_free(info);
2378 if (!*r->out.dcname) {
2379 return WERR_NOT_ENOUGH_MEMORY;
2382 return WERR_OK;
2385 /****************************************************************
2386 ****************************************************************/
2388 NTSTATUS _netr_DatabaseSync2(struct pipes_struct *p,
2389 struct netr_DatabaseSync2 *r)
2391 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2392 return NT_STATUS_NOT_IMPLEMENTED;
2395 /****************************************************************
2396 ****************************************************************/
2398 NTSTATUS _netr_DatabaseRedo(struct pipes_struct *p,
2399 struct netr_DatabaseRedo *r)
2401 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2402 return NT_STATUS_NOT_IMPLEMENTED;
2405 /****************************************************************
2406 ****************************************************************/
2408 WERROR _netr_DsRGetDCName(struct pipes_struct *p,
2409 struct netr_DsRGetDCName *r)
2411 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2412 return WERR_NOT_SUPPORTED;
2415 /****************************************************************
2416 ****************************************************************/
2418 NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
2419 struct netr_LogonGetCapabilities *r)
2421 struct netlogon_creds_CredentialState *creds;
2422 NTSTATUS status;
2424 become_root();
2425 status = netr_creds_server_step_check(p, p->mem_ctx,
2426 r->in.computer_name,
2427 r->in.credential,
2428 r->out.return_authenticator,
2429 &creds);
2430 unbecome_root();
2431 if (!NT_STATUS_IS_OK(status)) {
2432 return status;
2435 if (r->in.query_level != 1) {
2436 return NT_STATUS_NOT_SUPPORTED;
2439 r->out.capabilities->server_capabilities = creds->negotiate_flags;
2441 return NT_STATUS_OK;
2444 /****************************************************************
2445 ****************************************************************/
2447 WERROR _netr_NETRLOGONSETSERVICEBITS(struct pipes_struct *p,
2448 struct netr_NETRLOGONSETSERVICEBITS *r)
2450 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2451 return WERR_NOT_SUPPORTED;
2454 /****************************************************************
2455 ****************************************************************/
2457 WERROR _netr_LogonGetTrustRid(struct pipes_struct *p,
2458 struct netr_LogonGetTrustRid *r)
2460 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2461 return WERR_NOT_SUPPORTED;
2464 /****************************************************************
2465 ****************************************************************/
2467 WERROR _netr_NETRLOGONCOMPUTESERVERDIGEST(struct pipes_struct *p,
2468 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
2470 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2471 return WERR_NOT_SUPPORTED;
2474 /****************************************************************
2475 ****************************************************************/
2477 WERROR _netr_NETRLOGONCOMPUTECLIENTDIGEST(struct pipes_struct *p,
2478 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
2480 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2481 return WERR_NOT_SUPPORTED;
2484 /****************************************************************
2485 ****************************************************************/
2487 WERROR _netr_DsRGetDCNameEx(struct pipes_struct *p,
2488 struct netr_DsRGetDCNameEx *r)
2490 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2491 return WERR_NOT_SUPPORTED;
2494 /****************************************************************
2495 ****************************************************************/
2497 WERROR _netr_DsRGetSiteName(struct pipes_struct *p,
2498 struct netr_DsRGetSiteName *r)
2500 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2501 return WERR_NOT_SUPPORTED;
2504 /****************************************************************
2505 ****************************************************************/
2507 NTSTATUS _netr_LogonGetDomainInfo(struct pipes_struct *p,
2508 struct netr_LogonGetDomainInfo *r)
2510 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2511 return NT_STATUS_NOT_IMPLEMENTED;
2514 /****************************************************************
2515 ****************************************************************/
2517 NTSTATUS _netr_ServerPasswordGet(struct pipes_struct *p,
2518 struct netr_ServerPasswordGet *r)
2520 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2521 return NT_STATUS_NOT_SUPPORTED;
2524 /****************************************************************
2525 ****************************************************************/
2527 NTSTATUS _netr_NetrLogonSendToSam(struct pipes_struct *p,
2528 struct netr_NetrLogonSendToSam *r)
2530 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2531 return NT_STATUS_NOT_IMPLEMENTED;
2534 /****************************************************************
2535 ****************************************************************/
2537 WERROR _netr_DsRAddressToSitenamesW(struct pipes_struct *p,
2538 struct netr_DsRAddressToSitenamesW *r)
2540 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2541 return WERR_NOT_SUPPORTED;
2544 /****************************************************************
2545 ****************************************************************/
2547 WERROR _netr_DsRGetDCNameEx2(struct pipes_struct *p,
2548 struct netr_DsRGetDCNameEx2 *r)
2550 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2551 return WERR_NOT_SUPPORTED;
2554 /****************************************************************
2555 ****************************************************************/
2557 WERROR _netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct pipes_struct *p,
2558 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
2560 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2561 return WERR_NOT_SUPPORTED;
2564 /****************************************************************
2565 ****************************************************************/
2567 WERROR _netr_NetrEnumerateTrustedDomainsEx(struct pipes_struct *p,
2568 struct netr_NetrEnumerateTrustedDomainsEx *r)
2570 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2571 return WERR_NOT_SUPPORTED;
2574 /****************************************************************
2575 ****************************************************************/
2577 WERROR _netr_DsRAddressToSitenamesExW(struct pipes_struct *p,
2578 struct netr_DsRAddressToSitenamesExW *r)
2580 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2581 return WERR_NOT_SUPPORTED;
2584 /****************************************************************
2585 ****************************************************************/
2587 WERROR _netr_DsrGetDcSiteCoverageW(struct pipes_struct *p,
2588 struct netr_DsrGetDcSiteCoverageW *r)
2590 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2591 return WERR_NOT_SUPPORTED;
2594 /****************************************************************
2595 ****************************************************************/
2597 WERROR _netr_DsrEnumerateDomainTrusts(struct pipes_struct *p,
2598 struct netr_DsrEnumerateDomainTrusts *r)
2600 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2601 return WERR_NOT_SUPPORTED;
2604 /****************************************************************
2605 ****************************************************************/
2607 WERROR _netr_DsrDeregisterDNSHostRecords(struct pipes_struct *p,
2608 struct netr_DsrDeregisterDNSHostRecords *r)
2610 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2611 return WERR_NOT_SUPPORTED;
2614 /****************************************************************
2615 ****************************************************************/
2617 NTSTATUS _netr_ServerTrustPasswordsGet(struct pipes_struct *p,
2618 struct netr_ServerTrustPasswordsGet *r)
2620 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2621 return NT_STATUS_NOT_IMPLEMENTED;
2624 /****************************************************************
2625 ****************************************************************/
2627 static NTSTATUS fill_forest_trust_array(TALLOC_CTX *mem_ctx,
2628 struct lsa_ForestTrustInformation *info)
2630 struct lsa_ForestTrustRecord *e;
2631 struct pdb_domain_info *dom_info;
2632 struct lsa_ForestTrustDomainInfo *domain_info;
2633 char **upn_suffixes = NULL;
2634 uint32_t num_suffixes = 0;
2635 uint32_t i = 0;
2636 NTSTATUS status;
2638 dom_info = pdb_get_domain_info(mem_ctx);
2639 if (dom_info == NULL) {
2640 return NT_STATUS_NO_MEMORY;
2643 info->count = 2;
2645 become_root();
2646 status = pdb_enum_upn_suffixes(info, &num_suffixes, &upn_suffixes);
2647 unbecome_root();
2648 if (NT_STATUS_IS_OK(status) && (num_suffixes > 0)) {
2649 info->count += num_suffixes;
2652 info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, info->count);
2653 if (info->entries == NULL) {
2654 return NT_STATUS_NO_MEMORY;
2657 e = talloc(info, struct lsa_ForestTrustRecord);
2658 if (e == NULL) {
2659 return NT_STATUS_NO_MEMORY;
2662 e->flags = 0;
2663 e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2664 e->time = 0; /* so far always 0 in trces. */
2665 e->forest_trust_data.top_level_name.string = talloc_steal(info,
2666 dom_info->dns_forest);
2668 info->entries[0] = e;
2670 if (num_suffixes > 0) {
2671 for (i = 0; i < num_suffixes ; i++) {
2672 e = talloc(info, struct lsa_ForestTrustRecord);
2673 if (e == NULL) {
2674 return NT_STATUS_NO_MEMORY;
2677 e->flags = 0;
2678 e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2679 e->time = 0; /* so far always 0 in traces. */
2680 e->forest_trust_data.top_level_name.string = upn_suffixes[i];
2681 info->entries[1 + i] = e;
2685 e = talloc(info, struct lsa_ForestTrustRecord);
2686 if (e == NULL) {
2687 return NT_STATUS_NO_MEMORY;
2690 /* TODO: check if disabled and set flags accordingly */
2691 e->flags = 0;
2692 e->type = LSA_FOREST_TRUST_DOMAIN_INFO;
2693 e->time = 0; /* so far always 0 in traces. */
2695 domain_info = &e->forest_trust_data.domain_info;
2696 domain_info->domain_sid = dom_sid_dup(info, &dom_info->sid);
2698 domain_info->dns_domain_name.string = talloc_steal(info,
2699 dom_info->dns_domain);
2700 domain_info->netbios_domain_name.string = talloc_steal(info,
2701 dom_info->name);
2703 info->entries[info->count - 1] = e;
2705 return NT_STATUS_OK;
2708 /****************************************************************
2709 ****************************************************************/
2711 WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
2712 struct netr_DsRGetForestTrustInformation *r)
2714 struct dcesrv_call_state *dce_call = p->dce_call;
2715 struct auth_session_info *session_info =
2716 dcesrv_call_session_info(dce_call);
2717 NTSTATUS status;
2718 struct lsa_ForestTrustInformation *info, **info_ptr;
2719 enum security_user_level security_level;
2721 security_level = security_session_user_level(session_info, NULL);
2722 if (security_level < SECURITY_USER) {
2723 return WERR_ACCESS_DENIED;
2726 if (r->in.flags & (~DS_GFTI_UPDATE_TDO)) {
2727 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2728 return WERR_INVALID_FLAGS;
2731 if ((r->in.flags & DS_GFTI_UPDATE_TDO) && (lp_server_role() != ROLE_DOMAIN_PDC)) {
2732 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2733 return WERR_NERR_NOTPRIMARY;
2736 if ((r->in.trusted_domain_name == NULL) && (r->in.flags & DS_GFTI_UPDATE_TDO)) {
2737 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2738 return WERR_INVALID_PARAMETER;
2741 /* retrieve forest trust information and stop further processing */
2742 if (r->in.trusted_domain_name == NULL) {
2743 info_ptr = talloc(p->mem_ctx, struct lsa_ForestTrustInformation *);
2744 if (info_ptr == NULL) {
2745 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
2746 return WERR_NOT_ENOUGH_MEMORY;
2748 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2749 if (info == NULL) {
2750 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
2751 return WERR_NOT_ENOUGH_MEMORY;
2754 /* Fill forest trust information and expand UPN suffixes list */
2755 status = fill_forest_trust_array(p->mem_ctx, info);
2756 if (!NT_STATUS_IS_OK(status)) {
2757 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
2758 return WERR_NOT_ENOUGH_MEMORY;
2761 *info_ptr = info;
2762 r->out.forest_trust_info = info_ptr;
2764 return WERR_OK;
2768 /* TODO: implement remaining parts of DsrGetForestTrustInformation (opnum 43)
2769 * when trusted_domain_name is not NULL */
2771 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2772 return WERR_NOT_SUPPORTED;
2775 /****************************************************************
2776 _netr_GetForestTrustInformation
2777 ****************************************************************/
2779 NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p,
2780 struct netr_GetForestTrustInformation *r)
2782 NTSTATUS status;
2783 struct netlogon_creds_CredentialState *creds;
2784 struct lsa_ForestTrustInformation *info, **info_ptr;
2786 /* TODO: check server name */
2788 become_root();
2789 status = netr_creds_server_step_check(p, p->mem_ctx,
2790 r->in.computer_name,
2791 r->in.credential,
2792 r->out.return_authenticator,
2793 &creds);
2794 unbecome_root();
2795 if (!NT_STATUS_IS_OK(status)) {
2796 return status;
2799 if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
2800 (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
2801 return NT_STATUS_NOT_IMPLEMENTED;
2804 info_ptr = talloc(p->mem_ctx, struct lsa_ForestTrustInformation *);
2805 if (!info_ptr) {
2806 return NT_STATUS_NO_MEMORY;
2808 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2809 if (!info) {
2810 return NT_STATUS_NO_MEMORY;
2813 /* Fill forest trust information, do expand UPN suffixes list */
2814 status = fill_forest_trust_array(p->mem_ctx, info);
2815 if (!NT_STATUS_IS_OK(status)) {
2816 return status;
2819 *info_ptr = info;
2820 r->out.forest_trust_info = info_ptr;
2822 return NT_STATUS_OK;
2825 /****************************************************************
2826 ****************************************************************/
2828 static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
2829 const DATA_BLOB *trustAuth_blob,
2830 struct netlogon_creds_CredentialState *creds,
2831 struct samr_Password *current_pw_enc,
2832 struct samr_Password *previous_pw_enc)
2834 enum ndr_err_code ndr_err;
2835 struct trustAuthInOutBlob trustAuth;
2836 NTSTATUS status;
2838 ndr_err = ndr_pull_struct_blob_all(trustAuth_blob, mem_ctx, &trustAuth,
2839 (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
2840 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2841 return NT_STATUS_UNSUCCESSFUL;
2844 if (trustAuth.count != 0 && trustAuth.current.count != 0 &&
2845 trustAuth.current.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) {
2846 mdfour(current_pw_enc->hash,
2847 trustAuth.current.array[0].AuthInfo.clear.password,
2848 trustAuth.current.array[0].AuthInfo.clear.size);
2849 status = netlogon_creds_des_encrypt(creds, current_pw_enc);
2850 if (!NT_STATUS_IS_OK(status)) {
2851 return status;
2853 } else {
2854 return NT_STATUS_UNSUCCESSFUL;
2858 if (trustAuth.previous.count != 0 &&
2859 trustAuth.previous.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) {
2860 mdfour(previous_pw_enc->hash,
2861 trustAuth.previous.array[0].AuthInfo.clear.password,
2862 trustAuth.previous.array[0].AuthInfo.clear.size);
2863 status = netlogon_creds_des_encrypt(creds, previous_pw_enc);
2864 if (!NT_STATUS_IS_OK(status)) {
2865 return status;
2867 } else {
2868 ZERO_STRUCTP(previous_pw_enc);
2871 return NT_STATUS_OK;
2874 /****************************************************************
2875 _netr_ServerGetTrustInfo
2876 ****************************************************************/
2878 NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
2879 struct netr_ServerGetTrustInfo *r)
2881 NTSTATUS status;
2882 struct netlogon_creds_CredentialState *creds;
2883 char *account_name;
2884 size_t account_name_last;
2885 bool trusted;
2886 struct netr_TrustInfo *trust_info;
2887 struct pdb_trusted_domain *td;
2889 /* TODO: check server name */
2891 become_root();
2892 status = netr_creds_server_step_check(p, p->mem_ctx,
2893 r->in.computer_name,
2894 r->in.credential,
2895 r->out.return_authenticator,
2896 &creds);
2897 unbecome_root();
2898 if (!NT_STATUS_IS_OK(status)) {
2899 return status;
2902 account_name = talloc_strdup(p->mem_ctx, r->in.account_name);
2903 if (account_name == NULL) {
2904 return NT_STATUS_NO_MEMORY;
2907 account_name_last = strlen(account_name);
2908 if (account_name_last == 0) {
2909 return NT_STATUS_INVALID_PARAMETER;
2911 account_name_last--;
2912 if (account_name[account_name_last] == '.') {
2913 account_name[account_name_last] = '\0';
2916 if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
2917 (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
2918 trusted = false;
2919 } else {
2920 trusted = true;
2924 if (trusted) {
2925 account_name_last = strlen(account_name);
2926 if (account_name_last == 0) {
2927 return NT_STATUS_INVALID_PARAMETER;
2929 account_name_last--;
2930 if (account_name[account_name_last] == '$') {
2931 account_name[account_name_last] = '\0';
2934 status = pdb_get_trusted_domain(p->mem_ctx, account_name, &td);
2935 if (!NT_STATUS_IS_OK(status)) {
2936 return status;
2939 if (r->out.trust_info != NULL) {
2940 trust_info = talloc_zero(p->mem_ctx, struct netr_TrustInfo);
2941 if (trust_info == NULL) {
2942 return NT_STATUS_NO_MEMORY;
2944 trust_info->count = 1;
2946 trust_info->data = talloc_array(trust_info, uint32_t, 1);
2947 if (trust_info->data == NULL) {
2948 return NT_STATUS_NO_MEMORY;
2950 trust_info->data[0] = td->trust_attributes;
2952 *r->out.trust_info = trust_info;
2955 if (td->trust_auth_incoming.data == NULL) {
2956 return NT_STATUS_INVALID_PARAMETER;
2959 status = get_password_from_trustAuth(p->mem_ctx,
2960 &td->trust_auth_incoming,
2961 creds,
2962 r->out.new_owf_password,
2963 r->out.old_owf_password);
2965 if (!NT_STATUS_IS_OK(status)) {
2966 return status;
2969 } else {
2970 /* TODO: look for machine password */
2971 ZERO_STRUCTP(r->out.new_owf_password);
2972 ZERO_STRUCTP(r->out.old_owf_password);
2974 return NT_STATUS_NOT_IMPLEMENTED;
2977 return NT_STATUS_OK;
2980 /****************************************************************
2981 ****************************************************************/
2983 NTSTATUS _netr_Unused47(struct pipes_struct *p,
2984 struct netr_Unused47 *r)
2986 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2987 return NT_STATUS_NOT_IMPLEMENTED;
2990 /****************************************************************
2991 ****************************************************************/
2993 NTSTATUS _netr_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
2994 struct netr_DsrUpdateReadOnlyServerDnsRecords *r)
2996 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2997 return NT_STATUS_NOT_IMPLEMENTED;
3000 /* include the generated boilerplate */
3001 #include "librpc/gen_ndr/ndr_netlogon_scompat.c"