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. */
28 #include "system/passwd.h" /* uid_wrapper */
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"
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"
54 #include "librpc/rpc/server/netlogon/schannel_util.h"
57 #define DBGC_CLASS DBGC_RPC_SRV
59 /*************************************************************************
61 *************************************************************************/
63 WERROR
_netr_LogonControl(struct pipes_struct
*p
,
64 struct netr_LogonControl
*r
)
66 struct netr_LogonControl2Ex l
;
68 switch (r
->in
.level
) {
72 return WERR_NOT_SUPPORTED
;
74 return WERR_INVALID_LEVEL
;
77 switch (r
->in
.function_code
) {
78 case NETLOGON_CONTROL_QUERY
:
79 case NETLOGON_CONTROL_REPLICATE
:
80 case NETLOGON_CONTROL_SYNCHRONIZE
:
81 case NETLOGON_CONTROL_PDC_REPLICATE
:
82 case NETLOGON_CONTROL_BREAKPOINT
:
83 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG
:
84 case NETLOGON_CONTROL_TRUNCATE_LOG
:
87 return WERR_NOT_SUPPORTED
;
90 l
.in
.logon_server
= r
->in
.logon_server
;
91 l
.in
.function_code
= r
->in
.function_code
;
92 l
.in
.level
= r
->in
.level
;
94 l
.out
.query
= r
->out
.query
;
96 return _netr_LogonControl2Ex(p
, &l
);
99 /*************************************************************************
101 *************************************************************************/
103 WERROR
_netr_LogonControl2(struct pipes_struct
*p
,
104 struct netr_LogonControl2
*r
)
106 struct netr_LogonControl2Ex l
;
108 l
.in
.logon_server
= r
->in
.logon_server
;
109 l
.in
.function_code
= r
->in
.function_code
;
110 l
.in
.level
= r
->in
.level
;
111 l
.in
.data
= r
->in
.data
;
112 l
.out
.query
= r
->out
.query
;
114 return _netr_LogonControl2Ex(p
, &l
);
117 /*************************************************************************
118 *************************************************************************/
120 static bool wb_change_trust_creds(const char *domain
, WERROR
*tc_status
)
123 struct wbcAuthErrorInfo
*error
= NULL
;
125 result
= wbcChangeTrustCredentials(domain
, &error
);
127 case WBC_ERR_WINBIND_NOT_AVAILABLE
:
129 case WBC_ERR_DOMAIN_NOT_FOUND
:
130 *tc_status
= WERR_NO_SUCH_DOMAIN
;
132 case WBC_ERR_SUCCESS
:
133 *tc_status
= WERR_OK
;
139 if (error
&& error
->nt_status
!= 0) {
140 *tc_status
= ntstatus_to_werror(NT_STATUS(error
->nt_status
));
142 *tc_status
= WERR_TRUST_FAILURE
;
144 wbcFreeMemory(error
);
148 /*************************************************************************
149 *************************************************************************/
151 static bool wb_check_trust_creds(const char *domain
, WERROR
*tc_status
)
154 struct wbcAuthErrorInfo
*error
= NULL
;
156 result
= wbcCheckTrustCredentials(domain
, &error
);
158 case WBC_ERR_WINBIND_NOT_AVAILABLE
:
160 case WBC_ERR_DOMAIN_NOT_FOUND
:
161 *tc_status
= WERR_NO_SUCH_DOMAIN
;
163 case WBC_ERR_SUCCESS
:
164 *tc_status
= WERR_OK
;
170 if (error
&& error
->nt_status
!= 0) {
171 *tc_status
= ntstatus_to_werror(NT_STATUS(error
->nt_status
));
173 *tc_status
= WERR_TRUST_FAILURE
;
175 wbcFreeMemory(error
);
179 /****************************************************************
180 _netr_LogonControl2Ex
181 ****************************************************************/
183 WERROR
_netr_LogonControl2Ex(struct pipes_struct
*p
,
184 struct netr_LogonControl2Ex
*r
)
186 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
187 struct auth_session_info
*session_info
=
188 dcesrv_call_session_info(dce_call
);
189 uint32_t flags
= 0x0;
190 WERROR pdc_connection_status
= WERR_OK
;
191 uint32_t logon_attempts
= 0x0;
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
;
203 struct netr_DsRGetDCNameInfo
*dc_info
;
205 switch (dce_call
->pkt
.u
.request
.opnum
) {
206 case NDR_NETR_LOGONCONTROL
:
207 fn
= "_netr_LogonControl";
209 case NDR_NETR_LOGONCONTROL2
:
210 fn
= "_netr_LogonControl2";
212 case NDR_NETR_LOGONCONTROL2EX
:
213 fn
= "_netr_LogonControl2Ex";
216 return WERR_INVALID_PARAMETER
;
219 switch (r
->in
.level
) {
226 return WERR_INVALID_LEVEL
;
229 switch (r
->in
.function_code
) {
230 case NETLOGON_CONTROL_QUERY
:
233 if ((geteuid() != sec_initial_uid()) &&
234 !nt_token_check_domain_rid(
235 session_info
->security_token
, DOMAIN_RID_ADMINS
) &&
237 &global_sid_Builtin_Administrators
,
238 session_info
->security_token
))
240 return WERR_ACCESS_DENIED
;
245 tc_status
= WERR_NO_SUCH_DOMAIN
;
247 switch (r
->in
.function_code
) {
248 case NETLOGON_CONTROL_QUERY
:
249 switch (r
->in
.level
) {
254 return WERR_INVALID_PARAMETER
;
259 case NETLOGON_CONTROL_REPLICATE
:
260 case NETLOGON_CONTROL_SYNCHRONIZE
:
261 case NETLOGON_CONTROL_PDC_REPLICATE
:
262 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG
:
263 case NETLOGON_CONTROL_BREAKPOINT
:
264 case NETLOGON_CONTROL_TRUNCATE_LOG
:
265 case NETLOGON_CONTROL_TRANSPORT_NOTIFY
:
266 case NETLOGON_CONTROL_FORCE_DNS_REG
:
267 case NETLOGON_CONTROL_QUERY_DNS_REG
:
268 return WERR_NOT_SUPPORTED
;
270 case NETLOGON_CONTROL_FIND_USER
:
271 if (!r
->in
.data
|| !r
->in
.data
->user
) {
272 return WERR_NOT_SUPPORTED
;
275 case NETLOGON_CONTROL_SET_DBFLAG
:
277 return WERR_NOT_SUPPORTED
;
280 case NETLOGON_CONTROL_TC_VERIFY
:
281 if (!r
->in
.data
|| !r
->in
.data
->domain
) {
282 return WERR_NOT_SUPPORTED
;
285 if (!wb_check_trust_creds(r
->in
.data
->domain
, &tc_status
)) {
286 return WERR_NOT_SUPPORTED
;
289 case NETLOGON_CONTROL_TC_QUERY
:
290 if (!r
->in
.data
|| !r
->in
.data
->domain
) {
291 return WERR_NOT_SUPPORTED
;
294 domain
= r
->in
.data
->domain
;
296 if (!is_trusted_domain(domain
)) {
300 if (!get_dc_name(domain
, NULL
, dc_name2
, &dc_ss
)) {
301 tc_status
= WERR_NO_LOGON_SERVERS
;
305 dc_name
= talloc_asprintf(p
->mem_ctx
, "\\\\%s", dc_name2
);
307 return WERR_NOT_ENOUGH_MEMORY
;
314 case NETLOGON_CONTROL_REDISCOVER
:
315 if (!r
->in
.data
|| !r
->in
.data
->domain
) {
316 return WERR_NOT_SUPPORTED
;
319 domain
= r
->in
.data
->domain
;
321 if (!is_trusted_domain(domain
)) {
325 status
= dsgetdcname(p
->mem_ctx
, p
->msg_ctx
, domain
, NULL
, NULL
,
326 DS_FORCE_REDISCOVERY
| DS_RETURN_FLAT_NAME
,
328 if (!NT_STATUS_IS_OK(status
)) {
329 tc_status
= WERR_NO_LOGON_SERVERS
;
333 dc_name
= talloc_asprintf(p
->mem_ctx
, "\\\\%s", dc_info
->dc_unc
);
335 return WERR_NOT_ENOUGH_MEMORY
;
342 case NETLOGON_CONTROL_CHANGE_PASSWORD
:
343 if (!r
->in
.data
|| !r
->in
.data
->domain
) {
344 return WERR_NOT_SUPPORTED
;
347 if (!wb_change_trust_creds(r
->in
.data
->domain
, &tc_status
)) {
348 return WERR_NOT_SUPPORTED
;
353 /* no idea what this should be */
354 DEBUG(0,("%s: unimplemented function level [%d]\n",
355 fn
, r
->in
.function_code
));
356 return WERR_NOT_SUPPORTED
;
359 /* prepare the response */
361 switch (r
->in
.level
) {
363 info1
= talloc_zero(p
->mem_ctx
, struct netr_NETLOGON_INFO_1
);
364 W_ERROR_HAVE_NO_MEMORY(info1
);
366 info1
->flags
= flags
;
367 info1
->pdc_connection_status
= pdc_connection_status
;
369 r
->out
.query
->info1
= info1
;
372 info2
= talloc_zero(p
->mem_ctx
, struct netr_NETLOGON_INFO_2
);
373 W_ERROR_HAVE_NO_MEMORY(info2
);
375 info2
->flags
= flags
;
376 info2
->pdc_connection_status
= pdc_connection_status
;
377 info2
->trusted_dc_name
= dc_name
;
378 info2
->tc_connection_status
= tc_status
;
380 r
->out
.query
->info2
= info2
;
383 info3
= talloc_zero(p
->mem_ctx
, struct netr_NETLOGON_INFO_3
);
384 W_ERROR_HAVE_NO_MEMORY(info3
);
386 info3
->flags
= flags
;
387 info3
->logon_attempts
= logon_attempts
;
389 r
->out
.query
->info3
= info3
;
392 info4
= talloc_zero(p
->mem_ctx
, struct netr_NETLOGON_INFO_4
);
393 W_ERROR_HAVE_NO_MEMORY(info4
);
395 info4
->trusted_dc_name
= dc_name
;
396 info4
->trusted_domain_name
= r
->in
.data
->domain
;
398 r
->out
.query
->info4
= info4
;
401 return WERR_INVALID_LEVEL
;
407 /*************************************************************************
408 _netr_NetrEnumerateTrustedDomains
409 *************************************************************************/
411 NTSTATUS
_netr_NetrEnumerateTrustedDomains(struct pipes_struct
*p
,
412 struct netr_NetrEnumerateTrustedDomains
*r
)
414 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
415 struct dcesrv_connection
*dcesrv_conn
= dce_call
->conn
;
416 const struct tsocket_address
*local_address
=
417 dcesrv_connection_get_local_address(dcesrv_conn
);
418 const struct tsocket_address
*remote_address
=
419 dcesrv_connection_get_remote_address(dcesrv_conn
);
420 struct auth_session_info
*session_info
=
421 dcesrv_call_session_info(dce_call
);
423 NTSTATUS result
= NT_STATUS_OK
;
425 size_t num_domains
= 0;
426 const char **trusted_domains
= NULL
;
427 struct lsa_DomainList domain_list
;
428 struct dcerpc_binding_handle
*h
= NULL
;
429 struct policy_handle pol
;
430 uint32_t enum_ctx
= 0;
431 uint32_t max_size
= (uint32_t)-1;
432 union lsa_revision_info out_revision_info
= {
437 uint32_t out_version
= 0;
440 DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__
));
442 status
= rpcint_binding_handle(p
->mem_ctx
,
449 if (!NT_STATUS_IS_OK(status
)) {
453 status
= dcerpc_lsa_open_policy_fallback(
458 LSA_POLICY_VIEW_LOCAL_INFORMATION
,
463 if (any_nt_status_not_ok(status
, result
, &status
)) {
470 /* Lookup list of trusted domains */
471 status
= dcerpc_lsa_EnumTrustDom(h
,
478 if (!NT_STATUS_IS_OK(status
)) {
481 if (!NT_STATUS_IS_OK(result
) &&
482 !NT_STATUS_EQUAL(result
, NT_STATUS_NO_MORE_ENTRIES
) &&
483 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
488 for (i
= 0; i
< domain_list
.count
; i
++) {
489 if (!add_string_to_array(p
->mem_ctx
, domain_list
.domains
[i
].name
.string
,
490 &trusted_domains
, &num_domains
)) {
491 status
= NT_STATUS_NO_MEMORY
;
495 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
497 if (num_domains
> 0) {
498 /* multi sz terminate */
499 trusted_domains
= talloc_realloc(p
->mem_ctx
, trusted_domains
, const char *, num_domains
+ 1);
500 if (trusted_domains
== NULL
) {
501 status
= NT_STATUS_NO_MEMORY
;
505 trusted_domains
[num_domains
] = NULL
;
508 if (!push_reg_multi_sz(trusted_domains
, &blob
, trusted_domains
)) {
509 TALLOC_FREE(trusted_domains
);
510 status
= NT_STATUS_NO_MEMORY
;
514 r
->out
.trusted_domains_blob
->data
= blob
.data
;
515 r
->out
.trusted_domains_blob
->length
= blob
.length
;
517 DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__
));
519 status
= NT_STATUS_OK
;
522 if (is_valid_policy_hnd(&pol
)) {
523 dcerpc_lsa_Close(h
, p
->mem_ctx
, &pol
, &result
);
529 /*************************************************************************
530 *************************************************************************/
532 static NTSTATUS
samr_find_machine_account(TALLOC_CTX
*mem_ctx
,
533 struct dcerpc_binding_handle
*b
,
534 const char *account_name
,
535 uint32_t access_mask
,
536 struct dom_sid2
**domain_sid_p
,
537 uint32_t *user_rid_p
,
538 struct policy_handle
*user_handle
)
541 NTSTATUS result
= NT_STATUS_OK
;
542 struct policy_handle connect_handle
;
543 struct policy_handle domain_handle
= { 0, };
544 struct lsa_String domain_name
;
545 struct dom_sid2
*domain_sid
;
546 struct lsa_String names
;
547 struct samr_Ids rids
;
548 struct samr_Ids types
;
551 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
553 SAMR_ACCESS_CONNECT_TO_SERVER
|
554 SAMR_ACCESS_ENUM_DOMAINS
|
555 SAMR_ACCESS_LOOKUP_DOMAIN
,
558 if (any_nt_status_not_ok(status
, result
, &status
)) {
562 init_lsa_String(&domain_name
, get_global_sam_name());
564 status
= dcerpc_samr_LookupDomain(b
, mem_ctx
,
569 if (any_nt_status_not_ok(status
, result
, &status
)) {
573 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
575 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
579 if (any_nt_status_not_ok(status
, result
, &status
)) {
583 init_lsa_String(&names
, account_name
);
585 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
592 if (any_nt_status_not_ok(status
, result
, &status
)) {
596 if (rids
.count
!= 1) {
597 status
= NT_STATUS_NO_SUCH_USER
;
600 if (types
.count
!= 1) {
601 status
= NT_STATUS_INVALID_PARAMETER
;
604 if (types
.ids
[0] != SID_NAME_USER
) {
605 status
= NT_STATUS_NO_SUCH_USER
;
611 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
617 if (any_nt_status_not_ok(status
, result
, &status
)) {
626 *domain_sid_p
= domain_sid
;
630 if (is_valid_policy_hnd(&domain_handle
)) {
631 dcerpc_samr_Close(b
, mem_ctx
, &domain_handle
, &result
);
633 if (is_valid_policy_hnd(&connect_handle
)) {
634 dcerpc_samr_Close(b
, mem_ctx
, &connect_handle
, &result
);
640 /******************************************************************
641 gets a machine password entry. checks access rights of the host.
642 ******************************************************************/
644 static NTSTATUS
get_md4pw(struct samr_Password
*md4pw
, const char *mach_acct
,
645 enum netr_SchannelType sec_chan_type
,
647 struct messaging_context
*msg_ctx
)
650 NTSTATUS result
= NT_STATUS_OK
;
651 TALLOC_CTX
*mem_ctx
= NULL
;
652 struct dcerpc_binding_handle
*h
= NULL
;
653 struct tsocket_address
*local
= NULL
;
654 struct policy_handle user_handle
= { .handle_type
= 0 };
655 uint32_t user_rid
= UINT32_MAX
;
656 struct dom_sid
*domain_sid
= NULL
;
657 uint32_t acct_ctrl
= 0;
658 union samr_UserInfo
*info
= NULL
;
659 struct auth_session_info
*session_info
= NULL
;
665 * Currently this code is redundant as we already have a filter
666 * by hostname list. What this code really needs to do is to
667 * get a hosts allowed/hosts denied list from the SAM database
668 * on a per user basis, and make the access decision there.
669 * I will leave this code here for now as a reminder to implement
670 * this at a later date. JRA.
673 if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
675 p
->client_id
.addr
)) {
676 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct
));
681 mem_ctx
= talloc_stackframe();
683 status
= make_session_info_system(mem_ctx
, &session_info
);
684 if (!NT_STATUS_IS_OK(status
)) {
688 ZERO_STRUCT(user_handle
);
690 rc
= tsocket_address_inet_from_strings(mem_ctx
,
696 status
= NT_STATUS_NO_MEMORY
;
700 status
= rpcint_binding_handle(mem_ctx
,
707 if (!NT_STATUS_IS_OK(status
)) {
711 status
= samr_find_machine_account(mem_ctx
, h
, mach_acct
,
712 SEC_FLAG_MAXIMUM_ALLOWED
,
713 &domain_sid
, &user_rid
,
715 if (!NT_STATUS_IS_OK(status
)) {
719 status
= dcerpc_samr_QueryUserInfo2(h
,
722 UserControlInformation
,
725 if (any_nt_status_not_ok(status
, result
, &status
)) {
729 acct_ctrl
= info
->info16
.acct_flags
;
731 if (acct_ctrl
& ACB_DISABLED
) {
732 DEBUG(0,("get_md4pw: Workstation %s: account is disabled\n", mach_acct
));
733 status
= NT_STATUS_ACCOUNT_DISABLED
;
737 if (!(acct_ctrl
& ACB_SVRTRUST
) &&
738 !(acct_ctrl
& ACB_WSTRUST
) &&
739 !(acct_ctrl
& ACB_DOMTRUST
))
741 DEBUG(0,("get_md4pw: Workstation %s: account is not a trust account\n", mach_acct
));
742 status
= NT_STATUS_NO_TRUST_SAM_ACCOUNT
;
746 switch (sec_chan_type
) {
748 if (!(acct_ctrl
& ACB_SVRTRUST
)) {
749 DEBUG(0,("get_md4pw: Workstation %s: BDC secure channel requested "
750 "but not a server trust account\n", mach_acct
));
751 status
= NT_STATUS_NO_TRUST_SAM_ACCOUNT
;
756 if (!(acct_ctrl
& ACB_WSTRUST
)) {
757 DEBUG(0,("get_md4pw: Workstation %s: WORKSTATION secure channel requested "
758 "but not a workstation trust account\n", mach_acct
));
759 status
= NT_STATUS_NO_TRUST_SAM_ACCOUNT
;
763 case SEC_CHAN_DOMAIN
:
764 if (!(acct_ctrl
& ACB_DOMTRUST
)) {
765 DEBUG(0,("get_md4pw: Workstation %s: DOMAIN secure channel requested "
766 "but not a interdomain trust account\n", mach_acct
));
767 status
= NT_STATUS_NO_TRUST_SAM_ACCOUNT
;
776 status
= dcerpc_samr_QueryUserInfo2(h
,
779 UserInternal1Information
,
783 if (any_nt_status_not_ok(status
, result
, &status
)) {
787 if (info
->info18
.nt_pwd_active
== 0) {
788 DEBUG(0,("get_md4pw: Workstation %s: account does not have a password\n", mach_acct
));
789 status
= NT_STATUS_LOGON_FAILURE
;
793 /* samr gives out nthash unencrypted (!) */
794 memcpy(md4pw
->hash
, info
->info18
.nt_pwd
.hash
, 16);
796 sid_compose(sid
, domain_sid
, user_rid
);
799 if (h
&& is_valid_policy_hnd(&user_handle
)) {
800 dcerpc_samr_Close(h
, mem_ctx
, &user_handle
, &result
);
803 talloc_free(mem_ctx
);
808 /*************************************************************************
809 _netr_ServerReqChallenge
810 *************************************************************************/
812 NTSTATUS
_netr_ServerReqChallenge(struct pipes_struct
*p
,
813 struct netr_ServerReqChallenge
*r
)
815 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
816 struct netlogon_server_pipe_state
*pipe_state
= NULL
;
819 pipe_state
= dcesrv_iface_state_find_conn(
821 NETLOGON_SERVER_PIPE_STATE_MAGIC
,
822 struct netlogon_server_pipe_state
);
825 DEBUG(10,("_netr_ServerReqChallenge: new challenge requested. Clearing old state.\n"));
826 talloc_free(pipe_state
);
829 pipe_state
= talloc(p
->mem_ctx
, struct netlogon_server_pipe_state
);
830 NT_STATUS_HAVE_NO_MEMORY(pipe_state
);
832 pipe_state
->client_challenge
= *r
->in
.credentials
;
834 netlogon_creds_random_challenge(&pipe_state
->server_challenge
);
836 *r
->out
.return_credentials
= pipe_state
->server_challenge
;
838 status
= dcesrv_iface_state_store_conn(
840 NETLOGON_SERVER_PIPE_STATE_MAGIC
,
842 if (!NT_STATUS_IS_OK(status
)) {
849 /*************************************************************************
850 _netr_ServerAuthenticate
851 Create the initial credentials.
852 *************************************************************************/
854 NTSTATUS
_netr_ServerAuthenticate(struct pipes_struct
*p
,
855 struct netr_ServerAuthenticate
*r
)
857 struct netr_ServerAuthenticate3 a
;
858 uint32_t negotiate_flags
= 0;
861 a
.in
.server_name
= r
->in
.server_name
;
862 a
.in
.account_name
= r
->in
.account_name
;
863 a
.in
.secure_channel_type
= r
->in
.secure_channel_type
;
864 a
.in
.computer_name
= r
->in
.computer_name
;
865 a
.in
.credentials
= r
->in
.credentials
;
866 a
.in
.negotiate_flags
= &negotiate_flags
;
868 a
.out
.return_credentials
= r
->out
.return_credentials
;
870 a
.out
.negotiate_flags
= &negotiate_flags
;
872 return _netr_ServerAuthenticate3(p
, &a
);
876 /*************************************************************************
877 _netr_ServerAuthenticate3
878 *************************************************************************/
880 NTSTATUS
_netr_ServerAuthenticate3(struct pipes_struct
*p
,
881 struct netr_ServerAuthenticate3
*r
)
883 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
886 /* r->in.negotiate_flags is an aliased pointer to r->out.negotiate_flags,
887 * so use a copy to avoid destroying the client values. */
888 uint32_t in_neg_flags
= *r
->in
.negotiate_flags
;
890 struct loadparm_context
*lp_ctx
= p
->dce_call
->conn
->dce_ctx
->lp_ctx
;
892 struct samr_Password mach_pwd
;
893 struct netlogon_creds_CredentialState
*creds
;
894 struct netlogon_server_pipe_state
*pipe_state
= NULL
;
896 /* According to Microsoft (see bugid #6099)
897 * Windows 7 looks at the negotiate_flags
898 * returned in this structure *even if the
899 * call fails with access denied* ! So in order
900 * to allow Win7 to connect to a Samba NT style
901 * PDC we set the flags before we know if it's
906 srv_flgs
= NETLOGON_NEG_ACCOUNT_LOCKOUT
|
907 NETLOGON_NEG_PERSISTENT_SAMREPL
|
908 NETLOGON_NEG_ARCFOUR
|
909 NETLOGON_NEG_PROMOTION_COUNT
|
910 NETLOGON_NEG_CHANGELOG_BDC
|
911 NETLOGON_NEG_FULL_SYNC_REPL
|
912 NETLOGON_NEG_MULTIPLE_SIDS
|
914 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL
|
915 NETLOGON_NEG_PASSWORD_SET2
;
917 /* Ensure we support strong (128-bit) keys. */
918 if (in_neg_flags
& NETLOGON_NEG_STRONG_KEYS
) {
919 srv_flgs
|= NETLOGON_NEG_STRONG_KEYS
;
922 if (in_neg_flags
& NETLOGON_NEG_SUPPORTS_AES
) {
923 srv_flgs
|= NETLOGON_NEG_SUPPORTS_AES
;
926 if (in_neg_flags
& NETLOGON_NEG_SCHANNEL
) {
927 srv_flgs
|= NETLOGON_NEG_SCHANNEL
;
931 * Support authentication of trusted domains.
933 * These flags are the minimum required set which works with win2k3
936 if (pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX
) {
937 srv_flgs
|= NETLOGON_NEG_TRANSITIVE_TRUSTS
|
938 NETLOGON_NEG_DNS_DOMAIN_TRUSTS
|
939 NETLOGON_NEG_CROSS_FOREST_TRUSTS
|
940 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION
;
944 * If weak crypto is disabled, do not announce that we support RC4.
946 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED
) {
947 srv_flgs
&= ~NETLOGON_NEG_ARCFOUR
;
950 switch (dce_call
->pkt
.u
.request
.opnum
) {
951 case NDR_NETR_SERVERAUTHENTICATE
:
952 fn
= "_netr_ServerAuthenticate";
954 case NDR_NETR_SERVERAUTHENTICATE2
:
955 fn
= "_netr_ServerAuthenticate2";
957 case NDR_NETR_SERVERAUTHENTICATE3
:
958 fn
= "_netr_ServerAuthenticate3";
961 return NT_STATUS_INTERNAL_ERROR
;
964 /* We use this as the key to store the creds: */
965 /* r->in.computer_name */
967 pipe_state
= dcesrv_iface_state_find_conn(
969 NETLOGON_SERVER_PIPE_STATE_MAGIC
,
970 struct netlogon_server_pipe_state
);
973 DEBUG(0,("%s: no challenge sent to client %s\n", fn
,
974 r
->in
.computer_name
));
975 status
= NT_STATUS_ACCESS_DENIED
;
979 status
= get_md4pw(&mach_pwd
,
981 r
->in
.secure_channel_type
,
983 if (!NT_STATUS_IS_OK(status
)) {
984 DEBUG(0,("%s: failed to get machine password for "
986 fn
, r
->in
.account_name
, nt_errstr(status
) ));
987 /* always return NT_STATUS_ACCESS_DENIED */
988 status
= NT_STATUS_ACCESS_DENIED
;
992 /* From the client / server challenges and md4 password, generate sess key */
993 /* Check client credentials are valid. */
994 creds
= netlogon_creds_server_init(p
->mem_ctx
,
997 r
->in
.secure_channel_type
,
998 &pipe_state
->client_challenge
,
999 &pipe_state
->server_challenge
,
1002 r
->out
.return_credentials
,
1005 DEBUG(0,("%s: netlogon_creds_server_check failed. Rejecting auth "
1006 "request from client %s machine account %s\n",
1007 fn
, r
->in
.computer_name
,
1008 r
->in
.account_name
));
1009 status
= NT_STATUS_ACCESS_DENIED
;
1013 creds
->sid
= dom_sid_dup(creds
, &sid
);
1015 status
= NT_STATUS_NO_MEMORY
;
1019 /* Store off the state so we can continue after client disconnect. */
1021 status
= schannel_save_creds_state(p
->mem_ctx
, lp_ctx
, creds
);
1024 if (!NT_STATUS_IS_OK(status
)) {
1025 ZERO_STRUCTP(r
->out
.return_credentials
);
1029 sid_peek_rid(&sid
, r
->out
.rid
);
1031 status
= NT_STATUS_OK
;
1035 *r
->out
.negotiate_flags
= srv_flgs
;
1039 /*************************************************************************
1040 _netr_ServerAuthenticate2
1041 *************************************************************************/
1043 NTSTATUS
_netr_ServerAuthenticate2(struct pipes_struct
*p
,
1044 struct netr_ServerAuthenticate2
*r
)
1046 struct netr_ServerAuthenticate3 a
;
1049 a
.in
.server_name
= r
->in
.server_name
;
1050 a
.in
.account_name
= r
->in
.account_name
;
1051 a
.in
.secure_channel_type
= r
->in
.secure_channel_type
;
1052 a
.in
.computer_name
= r
->in
.computer_name
;
1053 a
.in
.credentials
= r
->in
.credentials
;
1054 a
.in
.negotiate_flags
= r
->in
.negotiate_flags
;
1056 a
.out
.return_credentials
= r
->out
.return_credentials
;
1058 a
.out
.negotiate_flags
= r
->out
.negotiate_flags
;
1060 return _netr_ServerAuthenticate3(p
, &a
);
1063 /*************************************************************************
1064 *************************************************************************/
1066 static NTSTATUS
samr_open_machine_account(
1067 struct dcerpc_binding_handle
*b
,
1068 const struct dom_sid
*machine_sid
,
1069 uint32_t access_mask
,
1070 struct policy_handle
*machine_handle
)
1072 TALLOC_CTX
*frame
= talloc_stackframe();
1073 struct policy_handle connect_handle
= { .handle_type
= 0 };
1074 struct policy_handle domain_handle
= { .handle_type
= 0 };
1075 struct dom_sid domain_sid
= *machine_sid
;
1076 uint32_t machine_rid
;
1077 NTSTATUS result
= NT_STATUS_OK
;
1078 NTSTATUS status
= NT_STATUS_INVALID_PARAMETER
;
1081 ok
= sid_split_rid(&domain_sid
, &machine_rid
);
1086 status
= dcerpc_samr_Connect2(
1090 SAMR_ACCESS_CONNECT_TO_SERVER
|
1091 SAMR_ACCESS_ENUM_DOMAINS
|
1092 SAMR_ACCESS_LOOKUP_DOMAIN
,
1095 if (any_nt_status_not_ok(status
, result
, &status
)) {
1099 status
= dcerpc_samr_OpenDomain(
1103 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1107 if (any_nt_status_not_ok(status
, result
, &status
)) {
1111 status
= dcerpc_samr_OpenUser(
1115 SEC_FLAG_MAXIMUM_ALLOWED
,
1119 if (any_nt_status_not_ok(status
, result
, &status
)) {
1124 if ((b
!= NULL
) && is_valid_policy_hnd(&domain_handle
)) {
1125 dcerpc_samr_Close(b
, frame
, &domain_handle
, &result
);
1127 if ((b
!= NULL
) && is_valid_policy_hnd(&connect_handle
)) {
1128 dcerpc_samr_Close(b
, frame
, &connect_handle
, &result
);
1134 struct _samr_Credentials_t
{
1137 CRED_TYPE_PLAIN_TEXT
,
1140 struct samr_Password
*nt_hash
;
1141 const char *password
;
1146 static NTSTATUS
netr_set_machine_account_password(
1147 TALLOC_CTX
*mem_ctx
,
1148 struct auth_session_info
*session_info
,
1149 struct messaging_context
*msg_ctx
,
1150 const struct dom_sid
*machine_sid
,
1151 struct _samr_Credentials_t
*cr
)
1154 NTSTATUS result
= NT_STATUS_OK
;
1155 struct dcerpc_binding_handle
*h
= NULL
;
1156 struct tsocket_address
*local
;
1157 struct policy_handle user_handle
= { .handle_type
= 0 };
1159 union samr_UserInfo
*info
;
1160 struct samr_UserInfo18 info18
;
1161 struct samr_UserInfo26 info26
;
1164 DATA_BLOB session_key
;
1165 enum samr_UserInfoLevel infolevel
;
1166 TALLOC_CTX
*frame
= talloc_stackframe();
1168 status
= session_extract_session_key(session_info
,
1171 if (!NT_STATUS_IS_OK(status
)) {
1175 rc
= tsocket_address_inet_from_strings(frame
,
1181 status
= NT_STATUS_NO_MEMORY
;
1185 status
= rpcint_binding_handle(frame
,
1189 get_session_info_system(),
1192 if (!NT_STATUS_IS_OK(status
)) {
1196 status
= samr_open_machine_account(
1197 h
, machine_sid
, SEC_FLAG_MAXIMUM_ALLOWED
, &user_handle
);
1198 if (!NT_STATUS_IS_OK(status
)) {
1202 status
= dcerpc_samr_QueryUserInfo2(h
,
1205 UserControlInformation
,
1208 if (any_nt_status_not_ok(status
, result
, &status
)) {
1212 acct_ctrl
= info
->info16
.acct_flags
;
1214 if (!(acct_ctrl
& ACB_WSTRUST
||
1215 acct_ctrl
& ACB_SVRTRUST
||
1216 acct_ctrl
& ACB_DOMTRUST
)) {
1217 status
= NT_STATUS_NO_SUCH_USER
;
1221 if (acct_ctrl
& ACB_DISABLED
) {
1222 status
= NT_STATUS_ACCOUNT_DISABLED
;
1226 switch(cr
->cred_type
) {
1227 case CRED_TYPE_NT_HASH
:
1228 ZERO_STRUCT(info18
);
1230 infolevel
= UserInternal1Information
;
1232 in
= data_blob_const(cr
->creds
.nt_hash
, 16);
1233 out
= data_blob_talloc_zero(frame
, 16);
1234 if (out
.data
== NULL
) {
1235 status
= NT_STATUS_NO_MEMORY
;
1238 rc
= sess_crypt_blob(&out
, &in
, &session_key
, SAMBA_GNUTLS_ENCRYPT
);
1240 status
= gnutls_error_to_ntstatus(rc
,
1241 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER
);
1244 memcpy(info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1246 info18
.nt_pwd_active
= true;
1248 info
->info18
= info18
;
1250 case CRED_TYPE_PLAIN_TEXT
:
1251 ZERO_STRUCT(info26
);
1253 infolevel
= UserInternal5InformationNew
;
1255 status
= init_samr_CryptPasswordEx(cr
->creds
.password
,
1258 if (!NT_STATUS_IS_OK(status
)) {
1262 info26
.password_expired
= PASS_DONT_CHANGE_AT_NEXT_LOGON
;
1263 info
->info26
= info26
;
1266 status
= NT_STATUS_INTERNAL_ERROR
;
1271 status
= dcerpc_samr_SetUserInfo2(h
,
1277 if (any_nt_status_not_ok(status
, result
, &status
)) {
1282 if (h
&& is_valid_policy_hnd(&user_handle
)) {
1283 dcerpc_samr_Close(h
, frame
, &user_handle
, &result
);
1290 /*************************************************************************
1291 _netr_ServerPasswordSet
1292 *************************************************************************/
1294 NTSTATUS
_netr_ServerPasswordSet(struct pipes_struct
*p
,
1295 struct netr_ServerPasswordSet
*r
)
1297 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
1298 struct auth_session_info
*session_info
=
1299 dcesrv_call_session_info(dce_call
);
1300 NTSTATUS status
= NT_STATUS_OK
;
1302 struct netlogon_creds_CredentialState
*creds
= NULL
;
1303 struct _samr_Credentials_t cr
= { CRED_TYPE_NT_HASH
, {0}};
1305 DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__
));
1308 status
= dcesrv_netr_creds_server_step_check(p
->dce_call
,
1310 r
->in
.computer_name
,
1312 r
->out
.return_authenticator
,
1316 if (!NT_STATUS_IS_OK(status
)) {
1317 const char *computer_name
= "<unknown>";
1319 if (creds
!= NULL
&& creds
->computer_name
!= NULL
) {
1320 computer_name
= creds
->computer_name
;
1322 DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth "
1323 "request from client %s machine account %s\n",
1324 r
->in
.computer_name
, computer_name
));
1329 DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
1330 r
->in
.computer_name
, creds
->computer_name
));
1332 status
= netlogon_creds_des_decrypt(creds
, r
->in
.new_password
);
1333 if (!NT_STATUS_IS_OK(status
)) {
1337 DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
1338 for(i
= 0; i
< sizeof(r
->in
.new_password
->hash
); i
++)
1339 DEBUG(100,("%02X ", r
->in
.new_password
->hash
[i
]));
1342 cr
.creds
.nt_hash
= r
->in
.new_password
;
1343 status
= netr_set_machine_account_password(p
->mem_ctx
,
1351 /****************************************************************
1352 _netr_ServerPasswordSet2
1353 ****************************************************************/
1355 NTSTATUS
_netr_ServerPasswordSet2(struct pipes_struct
*p
,
1356 struct netr_ServerPasswordSet2
*r
)
1358 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
1359 struct auth_session_info
*session_info
=
1360 dcesrv_call_session_info(dce_call
);
1362 struct netlogon_creds_CredentialState
*creds
= NULL
;
1363 DATA_BLOB plaintext
= data_blob_null
;
1364 DATA_BLOB new_password
= data_blob_null
;
1365 size_t confounder_len
;
1366 DATA_BLOB dec_blob
= data_blob_null
;
1367 DATA_BLOB enc_blob
= data_blob_null
;
1368 struct samr_CryptPassword password_buf
;
1369 struct _samr_Credentials_t cr
= { CRED_TYPE_PLAIN_TEXT
, {0}};
1373 status
= dcesrv_netr_creds_server_step_check(p
->dce_call
,
1375 r
->in
.computer_name
,
1377 r
->out
.return_authenticator
,
1381 if (!NT_STATUS_IS_OK(status
)) {
1382 DBG_NOTICE("netlogon_creds_server_step failed. "
1383 "Rejecting auth request from client %s\n",
1384 r
->in
.computer_name
);
1389 DBG_NOTICE("Server Password Set2 by remote "
1390 "machine:[%s] on account [%s]\n",
1391 r
->in
.computer_name
,
1392 creds
->computer_name
!= NULL
?
1393 creds
->computer_name
: "<unknown>");
1395 memcpy(password_buf
.data
, r
->in
.new_password
->data
, 512);
1396 SIVAL(password_buf
.data
, 512, r
->in
.new_password
->length
);
1398 if (creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
) {
1399 status
= netlogon_creds_aes_decrypt(creds
,
1403 status
= netlogon_creds_arcfour_crypt(creds
,
1407 if (!NT_STATUS_IS_OK(status
)) {
1412 if (!extract_pw_from_buffer(p
->mem_ctx
, password_buf
.data
, &new_password
)) {
1413 DEBUG(2,("_netr_ServerPasswordSet2: unable to extract password "
1414 "from a buffer. Rejecting auth request as a wrong password\n"));
1416 return NT_STATUS_WRONG_PASSWORD
;
1420 * Make sure the length field was encrypted,
1421 * otherwise we are under attack.
1423 if (new_password
.length
== r
->in
.new_password
->length
) {
1424 DBG_WARNING("Length[%zu] field not encrypted\n",
1425 new_password
.length
);
1427 return NT_STATUS_WRONG_PASSWORD
;
1431 * We don't allow empty passwords for machine accounts.
1433 if (new_password
.length
< 2) {
1434 DBG_WARNING("Empty password Length[%zu]\n",
1435 new_password
.length
);
1437 return NT_STATUS_WRONG_PASSWORD
;
1441 * Make sure the confounder part of CryptPassword
1442 * buffer was encrypted, otherwise we are under attack.
1444 confounder_len
= 512 - new_password
.length
;
1445 enc_blob
= data_blob_const(r
->in
.new_password
->data
, confounder_len
);
1446 dec_blob
= data_blob_const(password_buf
.data
, confounder_len
);
1447 if (confounder_len
> 0 && data_blob_equal_const_time(&dec_blob
, &enc_blob
)) {
1448 DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
1451 return NT_STATUS_WRONG_PASSWORD
;
1455 * Check that the password part was actually encrypted,
1456 * otherwise we are under attack.
1458 enc_blob
= data_blob_const(r
->in
.new_password
->data
+ confounder_len
,
1459 new_password
.length
);
1460 dec_blob
= data_blob_const(password_buf
.data
+ confounder_len
,
1461 new_password
.length
);
1462 if (data_blob_equal_const_time(&dec_blob
, &enc_blob
)) {
1463 DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
1464 new_password
.length
);
1466 return NT_STATUS_WRONG_PASSWORD
;
1470 * don't allow zero buffers
1472 if (all_zero(new_password
.data
, new_password
.length
)) {
1473 DBG_WARNING("Password zero buffer Length[%zu]\n",
1474 new_password
.length
);
1476 return NT_STATUS_WRONG_PASSWORD
;
1479 /* Convert from UTF16 -> plaintext. */
1480 ok
= convert_string_talloc(p
->mem_ctx
,
1484 new_password
.length
,
1488 DBG_WARNING("unable to extract password from a buffer. "
1489 "Rejecting auth request as a wrong password\n");
1491 return NT_STATUS_WRONG_PASSWORD
;
1495 * We don't allow empty passwords for machine accounts.
1498 cr
.creds
.password
= (const char*) plaintext
.data
;
1499 if (strlen(cr
.creds
.password
) == 0) {
1500 DBG_WARNING("Empty plaintext password\n");
1502 return NT_STATUS_WRONG_PASSWORD
;
1505 status
= netr_set_machine_account_password(p
->mem_ctx
,
1514 /*************************************************************************
1515 _netr_LogonSamLogoff
1516 *************************************************************************/
1518 NTSTATUS
_netr_LogonSamLogoff(struct pipes_struct
*p
,
1519 struct netr_LogonSamLogoff
*r
)
1522 struct netlogon_creds_CredentialState
*creds
;
1525 status
= dcesrv_netr_creds_server_step_check(p
->dce_call
,
1527 r
->in
.computer_name
,
1529 r
->out
.return_authenticator
,
1536 static NTSTATUS
_netr_LogonSamLogon_check(const struct netr_LogonSamLogonEx
*r
)
1538 switch (r
->in
.logon_level
) {
1539 case NetlogonInteractiveInformation
:
1540 case NetlogonServiceInformation
:
1541 case NetlogonInteractiveTransitiveInformation
:
1542 case NetlogonServiceTransitiveInformation
:
1543 if (r
->in
.logon
->password
== NULL
) {
1544 return NT_STATUS_INVALID_PARAMETER
;
1547 switch (r
->in
.validation_level
) {
1548 case NetlogonValidationSamInfo
: /* 2 */
1549 case NetlogonValidationSamInfo2
: /* 3 */
1551 case NetlogonValidationSamInfo4
: /* 6 */
1552 if ((pdb_capabilities() & PDB_CAP_ADS
) == 0) {
1553 DEBUG(10,("Not adding validation info level 6 "
1554 "without ADS passdb backend\n"));
1555 return NT_STATUS_INVALID_INFO_CLASS
;
1559 return NT_STATUS_INVALID_INFO_CLASS
;
1563 case NetlogonNetworkInformation
:
1564 case NetlogonNetworkTransitiveInformation
:
1565 if (r
->in
.logon
->network
== NULL
) {
1566 return NT_STATUS_INVALID_PARAMETER
;
1569 switch (r
->in
.validation_level
) {
1570 case NetlogonValidationSamInfo
: /* 2 */
1571 case NetlogonValidationSamInfo2
: /* 3 */
1573 case NetlogonValidationSamInfo4
: /* 6 */
1574 if ((pdb_capabilities() & PDB_CAP_ADS
) == 0) {
1575 DEBUG(10,("Not adding validation info level 6 "
1576 "without ADS passdb backend\n"));
1577 return NT_STATUS_INVALID_INFO_CLASS
;
1581 return NT_STATUS_INVALID_INFO_CLASS
;
1586 case NetlogonGenericInformation
:
1587 if (r
->in
.logon
->generic
== NULL
) {
1588 return NT_STATUS_INVALID_PARAMETER
;
1591 /* we don't support this here */
1592 return NT_STATUS_INVALID_PARAMETER
;
1594 switch (r
->in
.validation_level
) {
1595 /* TODO: case NetlogonValidationGenericInfo: 4 */
1596 case NetlogonValidationGenericInfo2
: /* 5 */
1599 return NT_STATUS_INVALID_INFO_CLASS
;
1605 return NT_STATUS_INVALID_PARAMETER
;
1608 return NT_STATUS_OK
;
1611 /*************************************************************************
1612 _netr_LogonSamLogon_base
1613 *************************************************************************/
1615 static NTSTATUS
_netr_LogonSamLogon_base(struct pipes_struct
*p
,
1616 struct netr_LogonSamLogonEx
*r
,
1617 struct netlogon_creds_CredentialState
*creds
)
1619 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
1620 struct dcesrv_connection
*dcesrv_conn
= dce_call
->conn
;
1621 const struct tsocket_address
*local_address
=
1622 dcesrv_connection_get_local_address(dcesrv_conn
);
1623 const struct tsocket_address
*remote_address
=
1624 dcesrv_connection_get_remote_address(dcesrv_conn
);
1625 NTSTATUS status
= NT_STATUS_OK
;
1626 union netr_LogonLevel
*logon
= r
->in
.logon
;
1627 const char *nt_username
, *nt_domain
, *nt_workstation
;
1628 char *sanitized_username
= NULL
;
1629 struct auth_usersupplied_info
*user_info
= NULL
;
1630 struct auth_serversupplied_info
*server_info
= NULL
;
1631 struct auth_context
*auth_context
= NULL
;
1633 enum dcerpc_AuthType auth_type
= DCERPC_AUTH_TYPE_NONE
;
1634 enum dcerpc_AuthLevel auth_level
= DCERPC_AUTH_LEVEL_NONE
;
1635 uint16_t opnum
= dce_call
->pkt
.u
.request
.opnum
;
1637 dcesrv_call_auth_info(dce_call
, &auth_type
, &auth_level
);
1639 #ifdef DEBUG_PASSWORD
1640 logon
= netlogon_creds_shallow_copy_logon(p
->mem_ctx
,
1643 if (logon
== NULL
) {
1644 logon
= r
->in
.logon
;
1649 case NDR_NETR_LOGONSAMLOGON
:
1650 fn
= "_netr_LogonSamLogon";
1652 * Already called netr_check_schannel() via
1653 * netr_creds_server_step_check()
1656 case NDR_NETR_LOGONSAMLOGONWITHFLAGS
:
1657 fn
= "_netr_LogonSamLogonWithFlags";
1659 * Already called netr_check_schannel() via
1660 * netr_creds_server_step_check()
1663 case NDR_NETR_LOGONSAMLOGONEX
:
1664 fn
= "_netr_LogonSamLogonEx";
1666 if (auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
) {
1667 return NT_STATUS_ACCESS_DENIED
;
1670 status
= dcesrv_netr_check_schannel(p
->dce_call
,
1675 if (NT_STATUS_IS_ERR(status
)) {
1681 return NT_STATUS_INTERNAL_ERROR
;
1684 *r
->out
.authoritative
= 1; /* authoritative response */
1686 switch (r
->in
.validation_level
) {
1688 r
->out
.validation
->sam2
= talloc_zero(p
->mem_ctx
, struct netr_SamInfo2
);
1689 if (!r
->out
.validation
->sam2
) {
1690 return NT_STATUS_NO_MEMORY
;
1694 r
->out
.validation
->sam3
= talloc_zero(p
->mem_ctx
, struct netr_SamInfo3
);
1695 if (!r
->out
.validation
->sam3
) {
1696 return NT_STATUS_NO_MEMORY
;
1700 r
->out
.validation
->sam6
= talloc_zero(p
->mem_ctx
, struct netr_SamInfo6
);
1701 if (!r
->out
.validation
->sam6
) {
1702 return NT_STATUS_NO_MEMORY
;
1706 DEBUG(0,("%s: bad validation_level value %d.\n",
1707 fn
, (int)r
->in
.validation_level
));
1708 return NT_STATUS_INVALID_INFO_CLASS
;
1711 switch (r
->in
.logon_level
) {
1712 case NetlogonInteractiveInformation
:
1713 case NetlogonServiceInformation
:
1714 case NetlogonInteractiveTransitiveInformation
:
1715 case NetlogonServiceTransitiveInformation
:
1716 nt_username
= logon
->password
->identity_info
.account_name
.string
?
1717 logon
->password
->identity_info
.account_name
.string
: "";
1718 nt_domain
= logon
->password
->identity_info
.domain_name
.string
?
1719 logon
->password
->identity_info
.domain_name
.string
: "";
1720 nt_workstation
= logon
->password
->identity_info
.workstation
.string
?
1721 logon
->password
->identity_info
.workstation
.string
: "";
1723 DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", lp_workgroup()));
1725 case NetlogonNetworkInformation
:
1726 case NetlogonNetworkTransitiveInformation
:
1727 nt_username
= logon
->network
->identity_info
.account_name
.string
?
1728 logon
->network
->identity_info
.account_name
.string
: "";
1729 nt_domain
= logon
->network
->identity_info
.domain_name
.string
?
1730 logon
->network
->identity_info
.domain_name
.string
: "";
1731 nt_workstation
= logon
->network
->identity_info
.workstation
.string
?
1732 logon
->network
->identity_info
.workstation
.string
: "";
1734 DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", lp_workgroup()));
1737 DEBUG(2,("SAM Logon: unsupported switch value\n"));
1738 return NT_STATUS_INVALID_INFO_CLASS
;
1741 DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username
, nt_workstation
, nt_domain
));
1743 DEBUG(5,("Attempting validation level %d for unmapped username %s.\n",
1744 r
->in
.validation_level
, nt_username
));
1746 status
= netlogon_creds_decrypt_samlogon_logon(creds
,
1749 if (!NT_STATUS_IS_OK(status
)) {
1753 status
= make_auth3_context_for_netlogon(talloc_tos(), &auth_context
);
1754 if (!NT_STATUS_IS_OK(status
)) {
1758 switch (r
->in
.logon_level
) {
1759 case NetlogonNetworkInformation
:
1760 case NetlogonNetworkTransitiveInformation
:
1762 const char *wksname
= nt_workstation
;
1763 const char *workgroup
= lp_workgroup();
1766 ok
= auth3_context_set_challenge(
1767 auth_context
, logon
->network
->challenge
, "fixed");
1769 return NT_STATUS_NO_MEMORY
;
1772 /* For a network logon, the workstation name comes in with two
1773 * backslashes in the front. Strip them if they are there. */
1775 if (*wksname
== '\\') wksname
++;
1776 if (*wksname
== '\\') wksname
++;
1778 /* Standard challenge/response authentication */
1779 if (!make_user_info_netlogon_network(talloc_tos(),
1781 nt_username
, nt_domain
,
1785 logon
->network
->identity_info
.parameter_control
,
1786 logon
->network
->lm
.data
,
1787 logon
->network
->lm
.length
,
1788 logon
->network
->nt
.data
,
1789 logon
->network
->nt
.length
)) {
1790 status
= NT_STATUS_NO_MEMORY
;
1793 if (NT_STATUS_IS_OK(status
)) {
1794 status
= NTLMv2_RESPONSE_verify_netlogon_creds(
1795 user_info
->client
.account_name
,
1796 user_info
->client
.domain_name
,
1797 user_info
->password
.response
.nt
,
1802 case NetlogonInteractiveInformation
:
1803 case NetlogonServiceInformation
:
1804 case NetlogonInteractiveTransitiveInformation
:
1805 case NetlogonServiceTransitiveInformation
:
1807 /* 'Interactive' authentication, supplies the password in its
1808 MD4 form, encrypted with the session key. We will convert
1809 this to challenge/response for the auth subsystem to chew
1814 #ifdef DEBUG_PASSWORD
1815 if (logon
!= r
->in
.logon
) {
1816 DEBUG(100,("lm owf password:"));
1818 r
->in
.logon
->password
->lmpassword
.hash
, 16);
1820 DEBUG(100,("nt owf password:"));
1822 r
->in
.logon
->password
->ntpassword
.hash
, 16);
1825 DEBUG(100,("decrypt of lm owf password:"));
1826 dump_data(100, logon
->password
->lmpassword
.hash
, 16);
1828 DEBUG(100,("decrypt of nt owf password:"));
1829 dump_data(100, logon
->password
->ntpassword
.hash
, 16);
1832 auth_get_ntlm_challenge(auth_context
, chal
);
1834 if (!make_user_info_netlogon_interactive(talloc_tos(),
1836 nt_username
, nt_domain
,
1840 logon
->password
->identity_info
.parameter_control
,
1842 logon
->password
->lmpassword
.hash
,
1843 logon
->password
->ntpassword
.hash
)) {
1844 status
= NT_STATUS_NO_MEMORY
;
1849 DEBUG(2,("SAM Logon: unsupported switch value\n"));
1850 return NT_STATUS_INVALID_INFO_CLASS
;
1853 if ( NT_STATUS_IS_OK(status
) ) {
1854 status
= auth_check_ntlm_password(p
->mem_ctx
,
1858 r
->out
.authoritative
);
1861 TALLOC_FREE(auth_context
);
1862 TALLOC_FREE(user_info
);
1864 DEBUG(5,("%s: check_password returned status %s\n",
1865 fn
, nt_errstr(status
)));
1867 /* Check account and password */
1869 if (!NT_STATUS_IS_OK(status
)) {
1870 TALLOC_FREE(server_info
);
1874 if (server_info
->guest
) {
1875 /* We don't like guest domain logons... */
1876 DEBUG(5,("%s: Attempted domain logon as GUEST "
1878 TALLOC_FREE(server_info
);
1879 return NT_STATUS_LOGON_FAILURE
;
1882 sanitized_username
= talloc_alpha_strcpy(talloc_tos(),
1884 SAFE_NETBIOS_CHARS
"$");
1885 if (sanitized_username
== NULL
) {
1886 TALLOC_FREE(server_info
);
1887 return NT_STATUS_NO_MEMORY
;
1890 set_current_user_info(sanitized_username
,
1891 server_info
->unix_name
,
1892 server_info
->info3
->base
.logon_domain
.string
);
1893 TALLOC_FREE(sanitized_username
);
1895 /* This is the point at which, if the login was successful, that
1896 the SAM Local Security Authority should record that the user is
1897 logged in to the domain. */
1899 switch (r
->in
.validation_level
) {
1901 status
= serverinfo_to_SamInfo2(server_info
,
1902 r
->out
.validation
->sam2
);
1905 status
= serverinfo_to_SamInfo3(server_info
,
1906 r
->out
.validation
->sam3
);
1909 /* Only allow this if the pipe is protected. */
1910 if (auth_level
< DCERPC_AUTH_LEVEL_PRIVACY
) {
1911 DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n",
1912 get_remote_machine_name()));
1913 status
= NT_STATUS_INVALID_PARAMETER
;
1917 status
= serverinfo_to_SamInfo6(server_info
,
1918 r
->out
.validation
->sam6
);
1923 TALLOC_FREE(server_info
);
1925 if (!NT_STATUS_IS_OK(status
)) {
1929 status
= netlogon_creds_encrypt_samlogon_validation(creds
,
1930 r
->in
.validation_level
,
1936 /****************************************************************
1937 _netr_LogonSamLogonWithFlags
1938 ****************************************************************/
1940 NTSTATUS
_netr_LogonSamLogonWithFlags(struct pipes_struct
*p
,
1941 struct netr_LogonSamLogonWithFlags
*r
)
1944 struct netlogon_creds_CredentialState
*creds
;
1945 struct netr_LogonSamLogonEx r2
;
1946 struct netr_Authenticator return_authenticator
;
1948 *r
->out
.authoritative
= true;
1950 r2
.in
.server_name
= r
->in
.server_name
;
1951 r2
.in
.computer_name
= r
->in
.computer_name
;
1952 r2
.in
.logon_level
= r
->in
.logon_level
;
1953 r2
.in
.logon
= r
->in
.logon
;
1954 r2
.in
.validation_level
= r
->in
.validation_level
;
1955 r2
.in
.flags
= r
->in
.flags
;
1956 r2
.out
.validation
= r
->out
.validation
;
1957 r2
.out
.authoritative
= r
->out
.authoritative
;
1958 r2
.out
.flags
= r
->out
.flags
;
1960 status
= _netr_LogonSamLogon_check(&r2
);
1961 if (!NT_STATUS_IS_OK(status
)) {
1966 status
= dcesrv_netr_creds_server_step_check(p
->dce_call
,
1968 r
->in
.computer_name
,
1970 &return_authenticator
,
1973 if (!NT_STATUS_IS_OK(status
)) {
1977 status
= _netr_LogonSamLogon_base(p
, &r2
, creds
);
1979 *r
->out
.return_authenticator
= return_authenticator
;
1984 /*************************************************************************
1986 *************************************************************************/
1988 NTSTATUS
_netr_LogonSamLogon(struct pipes_struct
*p
,
1989 struct netr_LogonSamLogon
*r
)
1992 struct netr_LogonSamLogonWithFlags r2
;
1995 r2
.in
.server_name
= r
->in
.server_name
;
1996 r2
.in
.computer_name
= r
->in
.computer_name
;
1997 r2
.in
.credential
= r
->in
.credential
;
1998 r2
.in
.logon_level
= r
->in
.logon_level
;
1999 r2
.in
.logon
= r
->in
.logon
;
2000 r2
.in
.validation_level
= r
->in
.validation_level
;
2001 r2
.in
.return_authenticator
= r
->in
.return_authenticator
;
2002 r2
.in
.flags
= &flags
;
2003 r2
.out
.validation
= r
->out
.validation
;
2004 r2
.out
.authoritative
= r
->out
.authoritative
;
2005 r2
.out
.flags
= &flags
;
2006 r2
.out
.return_authenticator
= r
->out
.return_authenticator
;
2008 status
= _netr_LogonSamLogonWithFlags(p
, &r2
);
2013 /*************************************************************************
2014 _netr_LogonSamLogonEx
2015 - no credential chaining. Map into net sam logon.
2016 *************************************************************************/
2018 NTSTATUS
_netr_LogonSamLogonEx(struct pipes_struct
*p
,
2019 struct netr_LogonSamLogonEx
*r
)
2022 struct netlogon_creds_CredentialState
*creds
= NULL
;
2023 struct loadparm_context
*lp_ctx
= p
->dce_call
->conn
->dce_ctx
->lp_ctx
;
2025 *r
->out
.authoritative
= true;
2027 status
= _netr_LogonSamLogon_check(r
);
2028 if (!NT_STATUS_IS_OK(status
)) {
2033 status
= schannel_get_creds_state(p
->mem_ctx
, lp_ctx
,
2034 r
->in
.computer_name
, &creds
);
2036 if (!NT_STATUS_IS_OK(status
)) {
2040 status
= _netr_LogonSamLogon_base(p
, r
, creds
);
2046 /*************************************************************************
2048 *************************************************************************/
2049 #if 0 /* JERRY -- not correct */
2050 NTSTATUS
_ds_enum_dom_trusts(struct pipes_struct
*p
, DS_Q_ENUM_DOM_TRUSTS
*q_u
,
2051 DS_R_ENUM_DOM_TRUSTS
*r_u
)
2053 NTSTATUS status
= NT_STATUS_OK
;
2055 /* TODO: According to MSDN, the can only be executed against a
2056 DC or domain member running Windows 2000 or later. Need
2057 to test against a standalone 2k server and see what it
2058 does. A windows 2000 DC includes its own domain in the
2066 /****************************************************************
2067 ****************************************************************/
2069 WERROR
_netr_LogonUasLogon(struct pipes_struct
*p
,
2070 struct netr_LogonUasLogon
*r
)
2072 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2073 return WERR_NOT_SUPPORTED
;
2076 /****************************************************************
2077 ****************************************************************/
2079 WERROR
_netr_LogonUasLogoff(struct pipes_struct
*p
,
2080 struct netr_LogonUasLogoff
*r
)
2082 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2083 return WERR_NOT_SUPPORTED
;
2086 /****************************************************************
2087 ****************************************************************/
2089 NTSTATUS
_netr_DatabaseDeltas(struct pipes_struct
*p
,
2090 struct netr_DatabaseDeltas
*r
)
2092 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2093 return NT_STATUS_NOT_IMPLEMENTED
;
2096 /****************************************************************
2097 ****************************************************************/
2099 NTSTATUS
_netr_DatabaseSync(struct pipes_struct
*p
,
2100 struct netr_DatabaseSync
*r
)
2102 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2103 return NT_STATUS_NOT_IMPLEMENTED
;
2106 /****************************************************************
2107 ****************************************************************/
2109 NTSTATUS
_netr_AccountDeltas(struct pipes_struct
*p
,
2110 struct netr_AccountDeltas
*r
)
2112 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2113 return NT_STATUS_NOT_IMPLEMENTED
;
2116 /****************************************************************
2117 ****************************************************************/
2119 NTSTATUS
_netr_AccountSync(struct pipes_struct
*p
,
2120 struct netr_AccountSync
*r
)
2122 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2123 return NT_STATUS_NOT_IMPLEMENTED
;
2126 /****************************************************************
2127 ****************************************************************/
2129 static bool wb_getdcname(TALLOC_CTX
*mem_ctx
,
2131 const char **dcname
,
2136 struct wbcDomainControllerInfo
*dc_info
= NULL
;
2138 result
= wbcLookupDomainController(domain
,
2142 case WBC_ERR_SUCCESS
:
2144 case WBC_ERR_WINBIND_NOT_AVAILABLE
:
2146 case WBC_ERR_DOMAIN_NOT_FOUND
:
2147 *werr
= WERR_NO_SUCH_DOMAIN
;
2150 *werr
= WERR_DOMAIN_CONTROLLER_NOT_FOUND
;
2154 *dcname
= talloc_strdup(mem_ctx
, dc_info
->dc_name
);
2155 wbcFreeMemory(dc_info
);
2157 *werr
= WERR_NOT_ENOUGH_MEMORY
;
2166 /****************************************************************
2168 ****************************************************************/
2170 WERROR
_netr_GetDcName(struct pipes_struct
*p
,
2171 struct netr_GetDcName
*r
)
2176 struct netr_DsRGetDCNameInfo
*info
;
2179 ret
= wb_getdcname(p
->mem_ctx
,
2182 WBC_LOOKUP_DC_IS_FLAT_NAME
|
2183 WBC_LOOKUP_DC_RETURN_FLAT_NAME
|
2184 WBC_LOOKUP_DC_PDC_REQUIRED
,
2190 flags
= DS_PDC_REQUIRED
| DS_IS_FLAT_NAME
| DS_RETURN_FLAT_NAME
;
2192 status
= dsgetdcname(p
->mem_ctx
,
2199 if (!NT_STATUS_IS_OK(status
)) {
2200 return ntstatus_to_werror(status
);
2203 *r
->out
.dcname
= talloc_strdup(p
->mem_ctx
, info
->dc_unc
);
2205 if (!*r
->out
.dcname
) {
2206 return WERR_NOT_ENOUGH_MEMORY
;
2212 /****************************************************************
2214 ****************************************************************/
2216 WERROR
_netr_GetAnyDCName(struct pipes_struct
*p
,
2217 struct netr_GetAnyDCName
*r
)
2222 struct netr_DsRGetDCNameInfo
*info
;
2225 ret
= wb_getdcname(p
->mem_ctx
,
2228 WBC_LOOKUP_DC_IS_FLAT_NAME
|
2229 WBC_LOOKUP_DC_RETURN_FLAT_NAME
,
2235 flags
= DS_IS_FLAT_NAME
| DS_RETURN_FLAT_NAME
;
2237 status
= dsgetdcname(p
->mem_ctx
,
2244 if (!NT_STATUS_IS_OK(status
)) {
2245 return ntstatus_to_werror(status
);
2248 *r
->out
.dcname
= talloc_strdup(p
->mem_ctx
, info
->dc_unc
);
2250 if (!*r
->out
.dcname
) {
2251 return WERR_NOT_ENOUGH_MEMORY
;
2257 /****************************************************************
2258 ****************************************************************/
2260 NTSTATUS
_netr_DatabaseSync2(struct pipes_struct
*p
,
2261 struct netr_DatabaseSync2
*r
)
2263 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2264 return NT_STATUS_NOT_IMPLEMENTED
;
2267 /****************************************************************
2268 ****************************************************************/
2270 NTSTATUS
_netr_DatabaseRedo(struct pipes_struct
*p
,
2271 struct netr_DatabaseRedo
*r
)
2273 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2274 return NT_STATUS_NOT_IMPLEMENTED
;
2277 /****************************************************************
2278 ****************************************************************/
2280 WERROR
_netr_DsRGetDCName(struct pipes_struct
*p
,
2281 struct netr_DsRGetDCName
*r
)
2283 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2284 return WERR_NOT_SUPPORTED
;
2287 /****************************************************************
2288 ****************************************************************/
2290 NTSTATUS
_netr_LogonGetCapabilities(struct pipes_struct
*p
,
2291 struct netr_LogonGetCapabilities
*r
)
2293 struct netlogon_creds_CredentialState
*creds
;
2296 switch (r
->in
.query_level
) {
2301 * Until we know the details behind KB5028166
2302 * just return DCERPC_NCA_S_FAULT_INVALID_TAG
2303 * like an unpatched Windows Server.
2308 * There would not be a way to marshall the
2309 * the response. Which would mean our final
2310 * ndr_push would fail an we would return
2311 * an RPC-level fault with DCERPC_FAULT_BAD_STUB_DATA.
2313 * But it's important to match a Windows server
2314 * especially before KB5028166, see also our bug #15418
2315 * Otherwise Windows client would stop talking to us.
2317 p
->fault_state
= DCERPC_NCA_S_FAULT_INVALID_TAG
;
2318 return NT_STATUS_NOT_SUPPORTED
;
2322 status
= dcesrv_netr_creds_server_step_check(p
->dce_call
,
2324 r
->in
.computer_name
,
2326 r
->out
.return_authenticator
,
2329 if (!NT_STATUS_IS_OK(status
)) {
2333 r
->out
.capabilities
->server_capabilities
= creds
->negotiate_flags
;
2335 return NT_STATUS_OK
;
2338 /****************************************************************
2339 ****************************************************************/
2341 WERROR
_netr_NETRLOGONSETSERVICEBITS(struct pipes_struct
*p
,
2342 struct netr_NETRLOGONSETSERVICEBITS
*r
)
2344 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2345 return WERR_NOT_SUPPORTED
;
2348 /****************************************************************
2349 ****************************************************************/
2351 WERROR
_netr_LogonGetTrustRid(struct pipes_struct
*p
,
2352 struct netr_LogonGetTrustRid
*r
)
2354 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2355 return WERR_NOT_SUPPORTED
;
2358 /****************************************************************
2359 ****************************************************************/
2361 WERROR
_netr_NETRLOGONCOMPUTESERVERDIGEST(struct pipes_struct
*p
,
2362 struct netr_NETRLOGONCOMPUTESERVERDIGEST
*r
)
2364 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2365 return WERR_NOT_SUPPORTED
;
2368 /****************************************************************
2369 ****************************************************************/
2371 WERROR
_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct pipes_struct
*p
,
2372 struct netr_NETRLOGONCOMPUTECLIENTDIGEST
*r
)
2374 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2375 return WERR_NOT_SUPPORTED
;
2378 /****************************************************************
2379 ****************************************************************/
2381 WERROR
_netr_DsRGetDCNameEx(struct pipes_struct
*p
,
2382 struct netr_DsRGetDCNameEx
*r
)
2384 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2385 return WERR_NOT_SUPPORTED
;
2388 /****************************************************************
2389 ****************************************************************/
2391 WERROR
_netr_DsRGetSiteName(struct pipes_struct
*p
,
2392 struct netr_DsRGetSiteName
*r
)
2394 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2395 return WERR_NOT_SUPPORTED
;
2398 /****************************************************************
2399 ****************************************************************/
2401 NTSTATUS
_netr_LogonGetDomainInfo(struct pipes_struct
*p
,
2402 struct netr_LogonGetDomainInfo
*r
)
2404 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2405 return NT_STATUS_NOT_IMPLEMENTED
;
2408 /****************************************************************
2409 ****************************************************************/
2411 NTSTATUS
_netr_ServerPasswordGet(struct pipes_struct
*p
,
2412 struct netr_ServerPasswordGet
*r
)
2414 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2415 return NT_STATUS_NOT_SUPPORTED
;
2418 /****************************************************************
2419 ****************************************************************/
2421 NTSTATUS
_netr_NetrLogonSendToSam(struct pipes_struct
*p
,
2422 struct netr_NetrLogonSendToSam
*r
)
2424 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2425 return NT_STATUS_NOT_IMPLEMENTED
;
2428 /****************************************************************
2429 ****************************************************************/
2431 WERROR
_netr_DsRAddressToSitenamesW(struct pipes_struct
*p
,
2432 struct netr_DsRAddressToSitenamesW
*r
)
2434 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2435 return WERR_NOT_SUPPORTED
;
2438 /****************************************************************
2439 ****************************************************************/
2441 WERROR
_netr_DsRGetDCNameEx2(struct pipes_struct
*p
,
2442 struct netr_DsRGetDCNameEx2
*r
)
2444 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2445 return WERR_NOT_SUPPORTED
;
2448 /****************************************************************
2449 ****************************************************************/
2451 WERROR
_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct pipes_struct
*p
,
2452 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
*r
)
2454 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2455 return WERR_NOT_SUPPORTED
;
2458 /****************************************************************
2459 ****************************************************************/
2461 WERROR
_netr_NetrEnumerateTrustedDomainsEx(struct pipes_struct
*p
,
2462 struct netr_NetrEnumerateTrustedDomainsEx
*r
)
2464 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2465 return WERR_NOT_SUPPORTED
;
2468 /****************************************************************
2469 ****************************************************************/
2471 WERROR
_netr_DsRAddressToSitenamesExW(struct pipes_struct
*p
,
2472 struct netr_DsRAddressToSitenamesExW
*r
)
2474 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2475 return WERR_NOT_SUPPORTED
;
2478 /****************************************************************
2479 ****************************************************************/
2481 WERROR
_netr_DsrGetDcSiteCoverageW(struct pipes_struct
*p
,
2482 struct netr_DsrGetDcSiteCoverageW
*r
)
2484 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2485 return WERR_NOT_SUPPORTED
;
2488 /****************************************************************
2489 ****************************************************************/
2491 WERROR
_netr_DsrEnumerateDomainTrusts(struct pipes_struct
*p
,
2492 struct netr_DsrEnumerateDomainTrusts
*r
)
2494 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2495 return WERR_NOT_SUPPORTED
;
2498 /****************************************************************
2499 ****************************************************************/
2501 WERROR
_netr_DsrDeregisterDNSHostRecords(struct pipes_struct
*p
,
2502 struct netr_DsrDeregisterDNSHostRecords
*r
)
2504 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2505 return WERR_NOT_SUPPORTED
;
2508 /****************************************************************
2509 ****************************************************************/
2511 NTSTATUS
_netr_ServerTrustPasswordsGet(struct pipes_struct
*p
,
2512 struct netr_ServerTrustPasswordsGet
*r
)
2514 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2515 return NT_STATUS_NOT_IMPLEMENTED
;
2518 /****************************************************************
2519 ****************************************************************/
2521 static NTSTATUS
fill_forest_trust_array(TALLOC_CTX
*mem_ctx
,
2522 struct lsa_ForestTrustInformation
*info
)
2524 struct lsa_ForestTrustRecord
*e
;
2525 struct pdb_domain_info
*dom_info
;
2526 struct lsa_ForestTrustDomainInfo
*domain_info
;
2527 char **upn_suffixes
= NULL
;
2528 uint32_t num_suffixes
= 0;
2532 dom_info
= pdb_get_domain_info(mem_ctx
);
2533 if (dom_info
== NULL
) {
2534 return NT_STATUS_NO_MEMORY
;
2540 status
= pdb_enum_upn_suffixes(info
, &num_suffixes
, &upn_suffixes
);
2542 if (NT_STATUS_IS_OK(status
) && (num_suffixes
> 0)) {
2543 info
->count
+= num_suffixes
;
2546 info
->entries
= talloc_array(info
, struct lsa_ForestTrustRecord
*, info
->count
);
2547 if (info
->entries
== NULL
) {
2548 return NT_STATUS_NO_MEMORY
;
2551 e
= talloc(info
, struct lsa_ForestTrustRecord
);
2553 return NT_STATUS_NO_MEMORY
;
2557 e
->type
= LSA_FOREST_TRUST_TOP_LEVEL_NAME
;
2558 e
->time
= 0; /* so far always 0 in trces. */
2559 e
->forest_trust_data
.top_level_name
.string
= talloc_steal(info
,
2560 dom_info
->dns_forest
);
2562 info
->entries
[0] = e
;
2564 if (num_suffixes
> 0) {
2565 for (i
= 0; i
< num_suffixes
; i
++) {
2566 e
= talloc(info
, struct lsa_ForestTrustRecord
);
2568 return NT_STATUS_NO_MEMORY
;
2572 e
->type
= LSA_FOREST_TRUST_TOP_LEVEL_NAME
;
2573 e
->time
= 0; /* so far always 0 in traces. */
2574 e
->forest_trust_data
.top_level_name
.string
= upn_suffixes
[i
];
2575 info
->entries
[1 + i
] = e
;
2579 e
= talloc(info
, struct lsa_ForestTrustRecord
);
2581 return NT_STATUS_NO_MEMORY
;
2584 /* TODO: check if disabled and set flags accordingly */
2586 e
->type
= LSA_FOREST_TRUST_DOMAIN_INFO
;
2587 e
->time
= 0; /* so far always 0 in traces. */
2589 domain_info
= &e
->forest_trust_data
.domain_info
;
2590 domain_info
->domain_sid
= dom_sid_dup(info
, &dom_info
->sid
);
2592 domain_info
->dns_domain_name
.string
= talloc_steal(info
,
2593 dom_info
->dns_domain
);
2594 domain_info
->netbios_domain_name
.string
= talloc_steal(info
,
2597 info
->entries
[info
->count
- 1] = e
;
2599 return NT_STATUS_OK
;
2602 /****************************************************************
2603 ****************************************************************/
2605 WERROR
_netr_DsRGetForestTrustInformation(struct pipes_struct
*p
,
2606 struct netr_DsRGetForestTrustInformation
*r
)
2608 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
2609 struct auth_session_info
*session_info
=
2610 dcesrv_call_session_info(dce_call
);
2612 struct lsa_ForestTrustInformation
*info
, **info_ptr
;
2613 enum security_user_level security_level
;
2615 security_level
= security_session_user_level(session_info
, NULL
);
2616 if (security_level
< SECURITY_USER
) {
2617 return WERR_ACCESS_DENIED
;
2620 if (r
->in
.flags
& (~DS_GFTI_UPDATE_TDO
)) {
2621 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2622 return WERR_INVALID_FLAGS
;
2625 if ((r
->in
.flags
& DS_GFTI_UPDATE_TDO
) && (lp_server_role() != ROLE_DOMAIN_PDC
)) {
2626 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2627 return WERR_NERR_NOTPRIMARY
;
2630 if ((r
->in
.trusted_domain_name
== NULL
) && (r
->in
.flags
& DS_GFTI_UPDATE_TDO
)) {
2631 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2632 return WERR_INVALID_PARAMETER
;
2635 /* retrieve forest trust information and stop further processing */
2636 if (r
->in
.trusted_domain_name
== NULL
) {
2637 info_ptr
= talloc(p
->mem_ctx
, struct lsa_ForestTrustInformation
*);
2638 if (info_ptr
== NULL
) {
2639 p
->fault_state
= DCERPC_FAULT_CANT_PERFORM
;
2640 return WERR_NOT_ENOUGH_MEMORY
;
2642 info
= talloc_zero(info_ptr
, struct lsa_ForestTrustInformation
);
2644 p
->fault_state
= DCERPC_FAULT_CANT_PERFORM
;
2645 return WERR_NOT_ENOUGH_MEMORY
;
2648 /* Fill forest trust information and expand UPN suffixes list */
2649 status
= fill_forest_trust_array(p
->mem_ctx
, info
);
2650 if (!NT_STATUS_IS_OK(status
)) {
2651 p
->fault_state
= DCERPC_FAULT_CANT_PERFORM
;
2652 return WERR_NOT_ENOUGH_MEMORY
;
2656 r
->out
.forest_trust_info
= info_ptr
;
2662 /* TODO: implement remaining parts of DsrGetForestTrustInformation (opnum 43)
2663 * when trusted_domain_name is not NULL */
2665 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2666 return WERR_NOT_SUPPORTED
;
2669 /****************************************************************
2670 _netr_GetForestTrustInformation
2671 ****************************************************************/
2673 NTSTATUS
_netr_GetForestTrustInformation(struct pipes_struct
*p
,
2674 struct netr_GetForestTrustInformation
*r
)
2677 struct netlogon_creds_CredentialState
*creds
;
2678 struct lsa_ForestTrustInformation
*info
, **info_ptr
;
2680 /* TODO: check server name */
2683 status
= dcesrv_netr_creds_server_step_check(p
->dce_call
,
2685 r
->in
.computer_name
,
2687 r
->out
.return_authenticator
,
2690 if (!NT_STATUS_IS_OK(status
)) {
2694 if ((creds
->secure_channel_type
!= SEC_CHAN_DNS_DOMAIN
) &&
2695 (creds
->secure_channel_type
!= SEC_CHAN_DOMAIN
)) {
2696 return NT_STATUS_NOT_IMPLEMENTED
;
2699 info_ptr
= talloc(p
->mem_ctx
, struct lsa_ForestTrustInformation
*);
2701 return NT_STATUS_NO_MEMORY
;
2703 info
= talloc_zero(info_ptr
, struct lsa_ForestTrustInformation
);
2705 return NT_STATUS_NO_MEMORY
;
2708 /* Fill forest trust information, do expand UPN suffixes list */
2709 status
= fill_forest_trust_array(p
->mem_ctx
, info
);
2710 if (!NT_STATUS_IS_OK(status
)) {
2715 r
->out
.forest_trust_info
= info_ptr
;
2717 return NT_STATUS_OK
;
2720 /****************************************************************
2721 ****************************************************************/
2723 static NTSTATUS
get_password_from_trustAuth(TALLOC_CTX
*mem_ctx
,
2724 const DATA_BLOB
*trustAuth_blob
,
2725 struct netlogon_creds_CredentialState
*creds
,
2726 struct samr_Password
*current_pw_enc
,
2727 struct samr_Password
*previous_pw_enc
)
2729 enum ndr_err_code ndr_err
;
2730 struct trustAuthInOutBlob trustAuth
;
2733 ndr_err
= ndr_pull_struct_blob_all(trustAuth_blob
, mem_ctx
, &trustAuth
,
2734 (ndr_pull_flags_fn_t
)ndr_pull_trustAuthInOutBlob
);
2735 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2736 return NT_STATUS_UNSUCCESSFUL
;
2739 if (trustAuth
.count
!= 0 && trustAuth
.current
.count
!= 0 &&
2740 trustAuth
.current
.array
[0].AuthType
== TRUST_AUTH_TYPE_CLEAR
) {
2741 mdfour(current_pw_enc
->hash
,
2742 trustAuth
.current
.array
[0].AuthInfo
.clear
.password
,
2743 trustAuth
.current
.array
[0].AuthInfo
.clear
.size
);
2744 status
= netlogon_creds_des_encrypt(creds
, current_pw_enc
);
2745 if (!NT_STATUS_IS_OK(status
)) {
2749 return NT_STATUS_UNSUCCESSFUL
;
2753 if (trustAuth
.previous
.count
!= 0 &&
2754 trustAuth
.previous
.array
[0].AuthType
== TRUST_AUTH_TYPE_CLEAR
) {
2755 mdfour(previous_pw_enc
->hash
,
2756 trustAuth
.previous
.array
[0].AuthInfo
.clear
.password
,
2757 trustAuth
.previous
.array
[0].AuthInfo
.clear
.size
);
2758 status
= netlogon_creds_des_encrypt(creds
, previous_pw_enc
);
2759 if (!NT_STATUS_IS_OK(status
)) {
2763 ZERO_STRUCTP(previous_pw_enc
);
2766 return NT_STATUS_OK
;
2769 /****************************************************************
2770 _netr_ServerGetTrustInfo
2771 ****************************************************************/
2773 NTSTATUS
_netr_ServerGetTrustInfo(struct pipes_struct
*p
,
2774 struct netr_ServerGetTrustInfo
*r
)
2777 struct netlogon_creds_CredentialState
*creds
;
2779 size_t account_name_last
;
2781 struct netr_TrustInfo
*trust_info
;
2782 struct pdb_trusted_domain
*td
;
2784 /* TODO: check server name */
2787 status
= dcesrv_netr_creds_server_step_check(p
->dce_call
,
2789 r
->in
.computer_name
,
2791 r
->out
.return_authenticator
,
2794 if (!NT_STATUS_IS_OK(status
)) {
2798 account_name
= talloc_strdup(p
->mem_ctx
, r
->in
.account_name
);
2799 if (account_name
== NULL
) {
2800 return NT_STATUS_NO_MEMORY
;
2803 account_name_last
= strlen(account_name
);
2804 if (account_name_last
== 0) {
2805 return NT_STATUS_INVALID_PARAMETER
;
2807 account_name_last
--;
2808 if (account_name
[account_name_last
] == '.') {
2809 account_name
[account_name_last
] = '\0';
2812 if ((creds
->secure_channel_type
!= SEC_CHAN_DNS_DOMAIN
) &&
2813 (creds
->secure_channel_type
!= SEC_CHAN_DOMAIN
)) {
2821 account_name_last
= strlen(account_name
);
2822 if (account_name_last
== 0) {
2823 return NT_STATUS_INVALID_PARAMETER
;
2825 account_name_last
--;
2826 if (account_name
[account_name_last
] == '$') {
2827 account_name
[account_name_last
] = '\0';
2830 status
= pdb_get_trusted_domain(p
->mem_ctx
, account_name
, &td
);
2831 if (!NT_STATUS_IS_OK(status
)) {
2835 if (r
->out
.trust_info
!= NULL
) {
2836 trust_info
= talloc_zero(p
->mem_ctx
, struct netr_TrustInfo
);
2837 if (trust_info
== NULL
) {
2838 return NT_STATUS_NO_MEMORY
;
2840 trust_info
->count
= 1;
2842 trust_info
->data
= talloc_array(trust_info
, uint32_t, 1);
2843 if (trust_info
->data
== NULL
) {
2844 return NT_STATUS_NO_MEMORY
;
2846 trust_info
->data
[0] = td
->trust_attributes
;
2848 *r
->out
.trust_info
= trust_info
;
2851 if (td
->trust_auth_incoming
.data
== NULL
) {
2852 return NT_STATUS_INVALID_PARAMETER
;
2855 status
= get_password_from_trustAuth(p
->mem_ctx
,
2856 &td
->trust_auth_incoming
,
2858 r
->out
.new_owf_password
,
2859 r
->out
.old_owf_password
);
2861 if (!NT_STATUS_IS_OK(status
)) {
2866 /* TODO: look for machine password */
2867 ZERO_STRUCTP(r
->out
.new_owf_password
);
2868 ZERO_STRUCTP(r
->out
.old_owf_password
);
2870 return NT_STATUS_NOT_IMPLEMENTED
;
2873 return NT_STATUS_OK
;
2876 /****************************************************************
2877 ****************************************************************/
2879 NTSTATUS
_netr_Unused47(struct pipes_struct
*p
,
2880 struct netr_Unused47
*r
)
2882 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2883 return NT_STATUS_NOT_IMPLEMENTED
;
2886 /****************************************************************
2887 ****************************************************************/
2889 NTSTATUS
_netr_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct
*p
,
2890 struct netr_DsrUpdateReadOnlyServerDnsRecords
*r
)
2892 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2893 return NT_STATUS_NOT_IMPLEMENTED
;
2897 * Define the bind function that will be used by ndr_netlogon_scompat.c,
2898 * included at the bottom of this file.
2900 #define DCESRV_INTERFACE_NETLOGON_BIND(context, iface) \
2901 dcesrv_interface_netlogon_bind(context, iface)
2903 static NTSTATUS
dcesrv_interface_netlogon_bind(struct dcesrv_connection_context
*context
,
2904 const struct dcesrv_interface
*iface
)
2906 struct loadparm_context
*lp_ctx
= context
->conn
->dce_ctx
->lp_ctx
;
2907 int schannel
= lpcfg_server_schannel(lp_ctx
);
2908 bool schannel_global_required
= (schannel
== true);
2909 bool global_require_seal
= lpcfg_server_schannel_require_seal(lp_ctx
);
2910 static bool warned_global_schannel_once
= false;
2911 static bool warned_global_seal_once
= false;
2913 if (!schannel_global_required
&& !warned_global_schannel_once
) {
2915 * We want admins to notice their misconfiguration!
2917 D_ERR("CVE-2020-1472(ZeroLogon): "
2918 "Please configure 'server schannel = yes' (the default), "
2919 "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
2920 warned_global_schannel_once
= true;
2923 if (!global_require_seal
&& !warned_global_seal_once
) {
2925 * We want admins to notice their misconfiguration!
2927 D_ERR("CVE-2022-38023 (and others): "
2928 "Please configure 'server schannel require seal = yes' (the default), "
2929 "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
2930 warned_global_seal_once
= true;
2933 return NT_STATUS_OK
;
2936 /* include the generated boilerplate */
2937 #include "librpc/gen_ndr/ndr_netlogon_scompat.c"