2004-05-15 11:51:38 +04:00
/*
Unix SMB / CIFS implementation .
endpoint server for the netlogon pipe
2008-09-05 10:45:37 +04:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2004 - 2008
2005-01-09 15:55:25 +03:00
Copyright ( C ) Stefan Metzmacher < metze @ samba . org > 2005
2004-05-15 11:51:38 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-05-15 11:51:38 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-05-15 11:51:38 +04:00
*/
# include "includes.h"
2004-11-02 10:42:47 +03:00
# include "rpc_server/dcerpc_server.h"
2004-05-15 11:51:38 +04:00
# include "rpc_server/common/common.h"
2004-11-16 12:00:52 +03:00
# include "lib/ldb/include/ldb.h"
2005-10-07 15:31:45 +04:00
# include "auth/auth.h"
2007-12-10 06:33:29 +03:00
# include "auth/auth_sam_reply.h"
2005-12-28 18:38:36 +03:00
# include "dsdb/samdb/samdb.h"
2009-06-12 16:27:19 +04:00
# include "../libds/common/flags.h"
2006-03-07 02:28:18 +03:00
# include "rpc_server/samr/proto.h"
2008-10-11 23:31:42 +04:00
# include "../lib/util/util_ldb.h"
2006-03-14 18:03:25 +03:00
# include "libcli/auth/libcli_auth.h"
2009-04-06 16:54:44 +04:00
# include "auth/gensec/schannel.h"
2006-04-29 21:34:49 +04:00
# include "libcli/security/security.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2008-09-03 09:30:17 +04:00
# include "lib/messaging/irpc.h"
# include "librpc/gen_ndr/ndr_irpc.h"
2008-10-04 04:52:59 +04:00
# include "librpc/gen_ndr/ndr_netlogon.h"
2004-05-15 11:51:38 +04:00
2009-04-06 16:54:44 +04:00
struct netlogon_server_pipe_state {
2004-05-15 11:51:38 +04:00
struct netr_Credential client_challenge ;
struct netr_Credential server_challenge ;
} ;
2004-06-14 12:12:50 +04:00
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_ServerReqChallenge ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_ServerReqChallenge * r )
{
2009-04-06 16:54:44 +04:00
struct netlogon_server_pipe_state * pipe_state =
talloc_get_type ( dce_call - > context - > private_data , struct netlogon_server_pipe_state ) ;
2004-05-15 11:51:38 +04:00
2008-10-29 03:23:49 +03:00
ZERO_STRUCTP ( r - > out . return_credentials ) ;
2004-05-15 11:51:38 +04:00
/* destroyed on pipe shutdown */
if ( pipe_state ) {
2004-09-25 17:28:38 +04:00
talloc_free ( pipe_state ) ;
2009-02-02 12:01:36 +03:00
dce_call - > context - > private_data = NULL ;
2004-05-15 11:51:38 +04:00
}
2009-04-06 16:54:44 +04:00
pipe_state = talloc ( dce_call - > context , struct netlogon_server_pipe_state ) ;
2006-07-27 13:37:55 +04:00
NT_STATUS_HAVE_NO_MEMORY ( pipe_state ) ;
2004-05-15 11:51:38 +04:00
2004-05-30 17:15:15 +04:00
pipe_state - > client_challenge = * r - > in . credentials ;
2004-05-15 11:51:38 +04:00
generate_random_buffer ( pipe_state - > server_challenge . data ,
2004-07-14 16:14:07 +04:00
sizeof ( pipe_state - > server_challenge . data ) ) ;
2004-05-15 11:51:38 +04:00
2008-10-29 03:23:49 +03:00
* r - > out . return_credentials = pipe_state - > server_challenge ;
2004-05-15 11:51:38 +04:00
2009-02-02 12:01:36 +03:00
dce_call - > context - > private_data = pipe_state ;
2004-05-15 11:51:38 +04:00
return NT_STATUS_OK ;
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_ServerAuthenticate3 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-30 17:15:15 +04:00
struct netr_ServerAuthenticate3 * r )
2004-05-15 11:51:38 +04:00
{
2009-04-06 16:54:44 +04:00
struct netlogon_server_pipe_state * pipe_state =
talloc_get_type ( dce_call - > context - > private_data , struct netlogon_server_pipe_state ) ;
struct netlogon_creds_CredentialState * creds ;
struct ldb_context * schannel_ldb ;
struct ldb_context * sam_ctx ;
2004-06-05 07:22:10 +04:00
struct samr_Password * mach_pwd ;
2008-02-28 00:50:00 +03:00
uint32_t user_account_control ;
2004-05-15 11:51:38 +04:00
int num_records ;
struct ldb_message * * msgs ;
NTSTATUS nt_status ;
2007-02-15 15:54:58 +03:00
const char * attrs [ ] = { " unicodePwd " , " userAccountControl " ,
2004-05-30 17:15:15 +04:00
" objectSid " , NULL } ;
2004-05-15 11:51:38 +04:00
2008-10-02 00:31:22 +04:00
const char * trust_dom_attrs [ ] = { " flatname " , NULL } ;
const char * account_name ;
2008-10-29 03:14:08 +03:00
ZERO_STRUCTP ( r - > out . return_credentials ) ;
2004-05-30 17:15:15 +04:00
* r - > out . rid = 0 ;
2009-02-16 11:42:24 +03:00
/*
* According to Microsoft ( see bugid # 6099 )
* Windows 7 looks at the negotiate_flags
* returned in this structure * even if the
* call fails with access denied !
*/
* r - > out . negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
NETLOGON_NEG_PERSISTENT_SAMREPL |
NETLOGON_NEG_ARCFOUR |
NETLOGON_NEG_PROMOTION_COUNT |
NETLOGON_NEG_CHANGELOG_BDC |
NETLOGON_NEG_FULL_SYNC_REPL |
NETLOGON_NEG_MULTIPLE_SIDS |
NETLOGON_NEG_REDO |
NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
NETLOGON_NEG_GENERIC_PASSTHROUGH |
NETLOGON_NEG_CONCURRENT_RPC |
NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
NETLOGON_NEG_STRONG_KEYS |
NETLOGON_NEG_TRANSITIVE_TRUSTS |
NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
NETLOGON_NEG_PASSWORD_SET2 |
NETLOGON_NEG_GETDOMAININFO |
NETLOGON_NEG_CROSS_FOREST_TRUSTS |
NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
NETLOGON_NEG_RODC_PASSTHROUGH |
NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
NETLOGON_NEG_AUTHENTICATED_RPC ;
2004-05-15 11:51:38 +04:00
if ( ! pipe_state ) {
2004-06-05 07:37:27 +04:00
DEBUG ( 1 , ( " No challenge requested by client, cannot authenticate \n " ) ) ;
2004-05-15 11:51:38 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2008-04-17 14:23:44 +04:00
sam_ctx = samdb_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx ,
2007-12-06 18:36:54 +03:00
system_session ( mem_ctx , dce_call - > conn - > dce_ctx - > lp_ctx ) ) ;
2004-05-15 11:51:38 +04:00
if ( sam_ctx = = NULL ) {
return NT_STATUS_INVALID_SYSTEM_SERVICE ;
}
2008-10-02 00:31:22 +04:00
if ( r - > in . secure_channel_type = = SEC_CHAN_DNS_DOMAIN ) {
char * encoded_account = ldb_binary_encode_string ( mem_ctx , r - > in . account_name ) ;
2008-10-16 05:48:16 +04:00
const char * flatname ;
2008-10-02 00:31:22 +04:00
if ( ! encoded_account ) {
return NT_STATUS_NO_MEMORY ;
}
/* Kill the trailing dot */
if ( encoded_account [ strlen ( encoded_account ) - 1 ] = = ' . ' ) {
encoded_account [ strlen ( encoded_account ) - 1 ] = ' \0 ' ;
}
/* pull the user attributes */
2009-02-24 23:08:07 +03:00
num_records = gendb_search ( ( struct ldb_context * ) sam_ctx ,
mem_ctx , NULL , & msgs ,
trust_dom_attrs ,
2008-10-02 00:31:22 +04:00
" (&(trustPartner=%s)(objectclass=trustedDomain)) " ,
encoded_account ) ;
if ( num_records = = 0 ) {
DEBUG ( 3 , ( " Couldn't find trust [%s] in samdb. \n " ,
encoded_account ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
if ( num_records > 1 ) {
DEBUG ( 0 , ( " Found %d records matching user [%s] \n " , num_records , r - > in . account_name ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
flatname = ldb_msg_find_attr_as_string ( msgs [ 0 ] , " flatname " , NULL ) ;
if ( ! flatname ) {
/* No flatname for this trust - we can't proceed */
return NT_STATUS_ACCESS_DENIED ;
}
account_name = talloc_asprintf ( mem_ctx , " %s$ " , flatname ) ;
if ( ! account_name ) {
return NT_STATUS_NO_MEMORY ;
}
} else {
account_name = r - > in . account_name ;
}
2004-05-15 11:51:38 +04:00
/* pull the user attributes */
2009-02-24 23:08:07 +03:00
num_records = gendb_search ( ( struct ldb_context * ) sam_ctx , mem_ctx ,
NULL , & msgs , attrs ,
2004-05-15 11:51:38 +04:00
" (&(sAMAccountName=%s)(objectclass=user)) " ,
2008-10-02 00:31:22 +04:00
ldb_binary_encode_string ( mem_ctx , account_name ) ) ;
2004-05-15 11:51:38 +04:00
if ( num_records = = 0 ) {
2004-05-17 01:30:48 +04:00
DEBUG ( 3 , ( " Couldn't find user [%s] in samdb. \n " ,
2004-06-05 07:22:10 +04:00
r - > in . account_name ) ) ;
2005-10-07 15:31:45 +04:00
return NT_STATUS_ACCESS_DENIED ;
2004-05-15 11:51:38 +04:00
}
if ( num_records > 1 ) {
2004-07-05 11:24:14 +04:00
DEBUG ( 0 , ( " Found %d records matching user [%s] \n " , num_records , r - > in . account_name ) ) ;
2004-05-15 11:51:38 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2008-02-28 00:50:00 +03:00
user_account_control = ldb_msg_find_attr_as_uint ( msgs [ 0 ] , " userAccountControl " , 0 ) ;
2004-05-15 11:51:38 +04:00
2008-02-28 00:50:00 +03:00
if ( user_account_control & UF_ACCOUNTDISABLE ) {
2004-06-05 07:22:10 +04:00
DEBUG ( 1 , ( " Account [%s] is disabled \n " , r - > in . account_name ) ) ;
2004-05-15 11:51:38 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2004-05-30 17:15:15 +04:00
if ( r - > in . secure_channel_type = = SEC_CHAN_WKSTA ) {
2008-02-28 00:50:00 +03:00
if ( ! ( user_account_control & UF_WORKSTATION_TRUST_ACCOUNT ) ) {
DEBUG ( 1 , ( " Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x \n " , user_account_control ) ) ;
2004-05-15 11:51:38 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2008-10-02 00:31:22 +04:00
} else if ( r - > in . secure_channel_type = = SEC_CHAN_DOMAIN | |
r - > in . secure_channel_type = = SEC_CHAN_DNS_DOMAIN ) {
2008-02-28 00:50:00 +03:00
if ( ! ( user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT ) ) {
DEBUG ( 1 , ( " Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x \n " , user_account_control ) ) ;
2004-05-15 11:51:38 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2004-05-30 17:15:15 +04:00
} else if ( r - > in . secure_channel_type = = SEC_CHAN_BDC ) {
2008-02-28 00:50:00 +03:00
if ( ! ( user_account_control & UF_SERVER_TRUST_ACCOUNT ) ) {
DEBUG ( 1 , ( " Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x \n " , user_account_control ) ) ;
2004-05-15 11:51:38 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
} else {
2004-05-30 17:15:15 +04:00
DEBUG ( 1 , ( " Client asked for an invalid secure channel type: %d \n " ,
r - > in . secure_channel_type ) ) ;
2004-05-15 11:51:38 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2005-12-30 11:40:16 +03:00
* r - > out . rid = samdb_result_rid_from_sid ( mem_ctx , msgs [ 0 ] ,
" objectSid " , 0 ) ;
2004-05-30 17:15:15 +04:00
2007-02-15 15:54:58 +03:00
mach_pwd = samdb_result_hash ( mem_ctx , msgs [ 0 ] , " unicodePwd " ) ;
2005-12-30 11:40:16 +03:00
if ( mach_pwd = = NULL ) {
2004-05-15 11:51:38 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2009-04-06 16:54:44 +04:00
creds = netlogon_creds_server_init ( mem_ctx ,
r - > in . account_name ,
2009-04-09 08:26:04 +04:00
r - > in . computer_name ,
2009-04-06 16:54:44 +04:00
r - > in . secure_channel_type ,
& pipe_state - > client_challenge ,
& pipe_state - > server_challenge ,
mach_pwd ,
r - > in . credentials ,
r - > out . return_credentials ,
* r - > in . negotiate_flags ) ;
2004-06-04 03:15:16 +04:00
2009-04-06 16:54:44 +04:00
if ( ! creds ) {
2004-05-15 11:51:38 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2006-02-09 05:30:43 +03:00
creds - > sid = samdb_result_dom_sid ( creds , msgs [ 0 ] , " objectSid " ) ;
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
2009-04-06 16:54:44 +04:00
schannel_ldb = schannel_db_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx ) ;
if ( ! schannel_ldb ) {
return NT_STATUS_ACCESS_DENIED ;
}
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
2009-04-06 16:54:44 +04:00
nt_status = schannel_store_session_key ( schannel_ldb , mem_ctx , creds ) ;
talloc_free ( schannel_ldb ) ;
2006-02-09 05:30:43 +03:00
2004-06-05 05:29:20 +04:00
return nt_status ;
2004-05-15 11:51:38 +04:00
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_ServerAuthenticate ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_ServerAuthenticate * r )
{
2009-04-06 16:54:44 +04:00
struct netr_ServerAuthenticate3 a ;
uint32_t rid ;
2004-06-24 04:08:15 +04:00
/* TODO:
* negotiate_flags is used as an [ in ] parameter
* so it need to be initialised .
*
* ( I think . . . = 0 ; seems wrong here - - metze )
*/
2009-02-18 08:26:30 +03:00
uint32_t negotiate_flags_in = 0 ;
uint32_t negotiate_flags_out = 0 ;
2004-05-30 17:15:15 +04:00
2009-04-06 16:54:44 +04:00
a . in . server_name = r - > in . server_name ;
a . in . account_name = r - > in . account_name ;
a . in . secure_channel_type = r - > in . secure_channel_type ;
a . in . computer_name = r - > in . computer_name ;
a . in . credentials = r - > in . credentials ;
a . in . negotiate_flags = & negotiate_flags_in ;
a . out . return_credentials = r - > out . return_credentials ;
a . out . rid = & rid ;
a . out . negotiate_flags = & negotiate_flags_out ;
return dcesrv_netr_ServerAuthenticate3 ( dce_call , mem_ctx , & a ) ;
2004-05-15 11:51:38 +04:00
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_ServerAuthenticate2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-30 17:15:15 +04:00
struct netr_ServerAuthenticate2 * r )
{
struct netr_ServerAuthenticate3 r3 ;
2005-02-10 08:09:35 +03:00
uint32_t rid = 0 ;
2004-05-30 17:15:15 +04:00
r3 . in . server_name = r - > in . server_name ;
2004-06-05 07:22:10 +04:00
r3 . in . account_name = r - > in . account_name ;
2004-05-30 17:15:15 +04:00
r3 . in . secure_channel_type = r - > in . secure_channel_type ;
r3 . in . computer_name = r - > in . computer_name ;
r3 . in . credentials = r - > in . credentials ;
2008-10-29 03:14:08 +03:00
r3 . out . return_credentials = r - > out . return_credentials ;
2004-05-30 17:15:15 +04:00
r3 . in . negotiate_flags = r - > in . negotiate_flags ;
r3 . out . negotiate_flags = r - > out . negotiate_flags ;
r3 . out . rid = & rid ;
2004-05-15 11:51:38 +04:00
2007-01-17 17:49:36 +03:00
return dcesrv_netr_ServerAuthenticate3 ( dce_call , mem_ctx , & r3 ) ;
2004-05-15 11:51:38 +04:00
}
2006-02-13 03:04:28 +03:00
/*
Validate an incoming authenticator against the credentials for the remote machine .
The credentials are ( re ) read and from the schannel database , and
written back after the caclulations are performed .
The creds_out parameter ( if not NULL ) returns the credentials , if
the caller needs some of that information .
2004-05-30 17:15:15 +04:00
2006-02-13 03:04:28 +03:00
*/
2009-04-06 16:54:44 +04:00
static NTSTATUS dcesrv_netr_creds_server_step_check ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
2009-04-09 08:26:04 +04:00
const char * computer_name ,
2009-04-06 16:54:44 +04:00
struct netr_Authenticator * received_authenticator ,
struct netr_Authenticator * return_authenticator ,
struct netlogon_creds_CredentialState * * creds_out )
2004-05-17 01:30:48 +04:00
{
2006-02-09 05:30:43 +03:00
NTSTATUS nt_status ;
struct ldb_context * ldb ;
2009-04-09 08:26:04 +04:00
bool schannel_global_required = false ; /* Should be lp_schannel_server() == true */
bool schannel_in_use = dce_call - > conn - > auth_state . auth_info
& & dce_call - > conn - > auth_state . auth_info - > auth_type = = DCERPC_AUTH_TYPE_SCHANNEL
2009-04-06 16:54:44 +04:00
& & ( dce_call - > conn - > auth_state . auth_info - > auth_level = = DCERPC_AUTH_LEVEL_INTEGRITY
| | dce_call - > conn - > auth_state . auth_info - > auth_level = = DCERPC_AUTH_LEVEL_PRIVACY ) ;
2006-02-09 05:30:43 +03:00
2009-04-06 16:54:44 +04:00
ldb = schannel_db_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx ) ;
2006-02-09 05:30:43 +03:00
if ( ! ldb ) {
return NT_STATUS_ACCESS_DENIED ;
}
2009-04-06 16:54:44 +04:00
nt_status = schannel_creds_server_step_check ( ldb , mem_ctx ,
computer_name ,
2009-04-09 08:26:04 +04:00
schannel_global_required ,
schannel_in_use ,
2009-04-06 16:54:44 +04:00
received_authenticator ,
return_authenticator , creds_out ) ;
2006-02-09 05:30:43 +03:00
talloc_free ( ldb ) ;
return nt_status ;
2004-05-17 01:30:48 +04:00
}
2006-02-09 05:30:43 +03:00
/*
Change the machine account password for the currently connected
client . Supplies only the NT # .
*/
2004-05-15 16:04:07 +04:00
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_ServerPasswordSet ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 16:04:07 +04:00
struct netr_ServerPasswordSet * r )
{
2009-04-06 16:54:44 +04:00
struct netlogon_creds_CredentialState * creds ;
2005-10-20 07:17:42 +04:00
struct ldb_context * sam_ctx ;
2004-05-17 01:30:48 +04:00
NTSTATUS nt_status ;
2009-04-06 16:54:44 +04:00
nt_status = dcesrv_netr_creds_server_step_check ( dce_call ,
2009-04-09 08:26:04 +04:00
mem_ctx ,
r - > in . computer_name ,
2009-04-06 16:54:44 +04:00
r - > in . credential , r - > out . return_authenticator ,
& creds ) ;
2005-01-10 19:12:41 +03:00
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
2004-05-17 01:30:48 +04:00
2008-04-17 14:23:44 +04:00
sam_ctx = samdb_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , system_session ( mem_ctx , dce_call - > conn - > dce_ctx - > lp_ctx ) ) ;
2004-05-17 01:30:48 +04:00
if ( sam_ctx = = NULL ) {
return NT_STATUS_INVALID_SYSTEM_SERVICE ;
}
2009-04-06 16:54:44 +04:00
netlogon_creds_des_decrypt ( creds , r - > in . new_password ) ;
2004-05-17 01:30:48 +04:00
2005-10-20 07:17:42 +04:00
/* Using the sid for the account as the key, set the password */
nt_status = samdb_set_password_sid ( sam_ctx , mem_ctx ,
2006-02-09 05:30:43 +03:00
creds - > sid ,
2005-10-20 07:17:42 +04:00
NULL , /* Don't have plaintext */
2008-10-29 03:34:49 +03:00
NULL , r - > in . new_password ,
2008-10-16 05:48:16 +04:00
true , /* Password change */
2005-10-20 07:17:42 +04:00
NULL , NULL ) ;
return nt_status ;
2004-05-15 16:04:07 +04:00
}
2006-02-09 05:30:43 +03:00
/*
Change the machine account password for the currently connected
client . Supplies new plaintext .
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_ServerPasswordSet2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-02-09 05:30:43 +03:00
struct netr_ServerPasswordSet2 * r )
{
2009-04-06 16:54:44 +04:00
struct netlogon_creds_CredentialState * creds ;
2006-02-09 05:30:43 +03:00
struct ldb_context * sam_ctx ;
NTSTATUS nt_status ;
2008-10-16 05:48:16 +04:00
DATA_BLOB new_password ;
2006-02-09 05:30:43 +03:00
struct samr_CryptPassword password_buf ;
2009-04-06 16:54:44 +04:00
nt_status = dcesrv_netr_creds_server_step_check ( dce_call ,
2009-04-09 08:26:04 +04:00
mem_ctx ,
r - > in . computer_name ,
2008-10-29 03:41:09 +03:00
r - > in . credential , r - > out . return_authenticator ,
2008-10-16 05:48:16 +04:00
& creds ) ;
2006-02-09 05:30:43 +03:00
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
2008-04-17 14:23:44 +04:00
sam_ctx = samdb_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , system_session ( mem_ctx , dce_call - > conn - > dce_ctx - > lp_ctx ) ) ;
2006-02-09 05:30:43 +03:00
if ( sam_ctx = = NULL ) {
return NT_STATUS_INVALID_SYSTEM_SERVICE ;
}
2008-10-29 03:41:09 +03:00
memcpy ( password_buf . data , r - > in . new_password - > data , 512 ) ;
SIVAL ( password_buf . data , 512 , r - > in . new_password - > length ) ;
2009-04-06 16:54:44 +04:00
netlogon_creds_arcfour_crypt ( creds , password_buf . data , 516 ) ;
2006-02-09 05:30:43 +03:00
2008-10-16 05:48:16 +04:00
if ( ! extract_pw_from_buffer ( mem_ctx , password_buf . data , & new_password ) ) {
DEBUG ( 3 , ( " samr: failed to decode password buffer \n " ) ) ;
return NT_STATUS_WRONG_PASSWORD ;
2006-02-09 05:30:43 +03:00
}
2008-10-16 05:48:16 +04:00
2006-02-09 05:30:43 +03:00
/* Using the sid for the account as the key, set the password */
nt_status = samdb_set_password_sid ( sam_ctx , mem_ctx ,
creds - > sid ,
2008-10-16 05:48:16 +04:00
& new_password , /* we have plaintext */
2006-02-09 05:30:43 +03:00
NULL , NULL ,
2008-10-16 05:48:16 +04:00
true , /* Password change */
2006-02-09 05:30:43 +03:00
NULL , NULL ) ;
return nt_status ;
}
2004-05-15 16:04:07 +04:00
2004-05-15 11:51:38 +04:00
/*
netr_LogonUasLogon
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_LogonUasLogon ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct netr_LogonUasLogon * r )
2004-05-15 11:51:38 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_LogonUasLogoff
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_LogonUasLogoff ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_LogonUasLogoff * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2006-02-21 03:07:59 +03:00
netr_LogonSamLogon_base
2004-05-15 11:51:38 +04:00
2005-01-03 09:23:02 +03:00
This version of the function allows other wrappers to say ' do not check the credentials '
2006-02-21 03:07:59 +03:00
We can ' t do the traditional ' wrapping ' format completly , as this function must only run under schannel
2004-05-15 11:51:38 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_LogonSamLogon_base ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2009-04-06 16:54:44 +04:00
struct netr_LogonSamLogonEx * r , struct netlogon_creds_CredentialState * creds )
2004-06-07 07:46:32 +04:00
{
struct auth_context * auth_context ;
struct auth_usersupplied_info * user_info ;
struct auth_serversupplied_info * server_info ;
NTSTATUS nt_status ;
2004-06-07 12:54:49 +04:00
static const char zeros [ 16 ] ;
2004-06-14 16:06:53 +04:00
struct netr_SamBaseInfo * sam ;
2004-06-07 12:54:49 +04:00
struct netr_SamInfo2 * sam2 ;
2004-06-14 16:06:53 +04:00
struct netr_SamInfo3 * sam3 ;
struct netr_SamInfo6 * sam6 ;
2004-06-07 07:46:32 +04:00
2005-07-22 08:10:07 +04:00
user_info = talloc ( mem_ctx , struct auth_usersupplied_info ) ;
2006-07-27 13:37:55 +04:00
NT_STATUS_HAVE_NO_MEMORY ( user_info ) ;
2005-07-22 08:10:07 +04:00
user_info - > flags = 0 ;
2007-10-07 02:25:41 +04:00
user_info - > mapped_state = false ;
2005-07-22 08:10:07 +04:00
user_info - > remote_host = NULL ;
2004-06-07 07:46:32 +04:00
switch ( r - > in . logon_level ) {
2008-08-12 11:46:01 +04:00
case NetlogonInteractiveInformation :
case NetlogonServiceInformation :
case NetlogonInteractiveTransitiveInformation :
case NetlogonServiceTransitiveInformation :
2006-02-21 03:07:59 +03:00
if ( creds - > negotiate_flags & NETLOGON_NEG_ARCFOUR ) {
2009-04-06 16:54:44 +04:00
netlogon_creds_arcfour_crypt ( creds ,
2008-10-28 21:03:50 +03:00
r - > in . logon - > password - > lmpassword . hash ,
sizeof ( r - > in . logon - > password - > lmpassword . hash ) ) ;
2009-04-06 16:54:44 +04:00
netlogon_creds_arcfour_crypt ( creds ,
2008-10-28 21:03:50 +03:00
r - > in . logon - > password - > ntpassword . hash ,
sizeof ( r - > in . logon - > password - > ntpassword . hash ) ) ;
2005-01-03 09:23:02 +03:00
} else {
2009-04-06 16:54:44 +04:00
netlogon_creds_des_decrypt ( creds , & r - > in . logon - > password - > lmpassword ) ;
netlogon_creds_des_decrypt ( creds , & r - > in . logon - > password - > ntpassword ) ;
2005-01-03 09:23:02 +03:00
}
2004-06-07 07:46:32 +04:00
2005-01-09 15:55:25 +03:00
/* TODO: we need to deny anonymous access here */
2007-07-03 12:05:55 +04:00
nt_status = auth_context_create ( mem_ctx ,
2006-07-31 18:05:08 +04:00
dce_call - > event_ctx , dce_call - > msg_ctx ,
2007-12-04 22:05:00 +03:00
dce_call - > conn - > dce_ctx - > lp_ctx ,
2006-07-31 18:05:08 +04:00
& auth_context ) ;
2005-01-09 15:55:25 +03:00
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
2008-10-28 21:03:50 +03:00
user_info - > logon_parameters = r - > in . logon - > password - > identity_info . parameter_control ;
user_info - > client . account_name = r - > in . logon - > password - > identity_info . account_name . string ;
user_info - > client . domain_name = r - > in . logon - > password - > identity_info . domain_name . string ;
user_info - > workstation_name = r - > in . logon - > password - > identity_info . workstation . string ;
2005-07-22 08:10:07 +04:00
2006-07-27 13:37:55 +04:00
user_info - > flags | = USER_INFO_INTERACTIVE_LOGON ;
2005-07-22 08:10:07 +04:00
user_info - > password_state = AUTH_PASSWORD_HASH ;
2006-07-27 13:37:55 +04:00
2005-07-22 08:10:07 +04:00
user_info - > password . hash . lanman = talloc ( user_info , struct samr_Password ) ;
2006-07-27 13:37:55 +04:00
NT_STATUS_HAVE_NO_MEMORY ( user_info - > password . hash . lanman ) ;
2008-10-28 21:03:50 +03:00
* user_info - > password . hash . lanman = r - > in . logon - > password - > lmpassword ;
2004-06-07 07:46:32 +04:00
2005-07-22 08:10:07 +04:00
user_info - > password . hash . nt = talloc ( user_info , struct samr_Password ) ;
2006-07-27 13:37:55 +04:00
NT_STATUS_HAVE_NO_MEMORY ( user_info - > password . hash . nt ) ;
2008-10-28 21:03:50 +03:00
* user_info - > password . hash . nt = r - > in . logon - > password - > ntpassword ;
2005-10-28 15:20:48 +04:00
2006-07-27 13:37:55 +04:00
break ;
2008-08-12 11:46:01 +04:00
case NetlogonNetworkInformation :
case NetlogonNetworkTransitiveInformation :
2005-07-22 08:10:07 +04:00
2005-01-09 15:55:25 +03:00
/* TODO: we need to deny anonymous access here */
2007-07-03 12:05:55 +04:00
nt_status = auth_context_create ( mem_ctx ,
2006-07-31 18:05:08 +04:00
dce_call - > event_ctx , dce_call - > msg_ctx ,
2007-12-04 22:05:00 +03:00
dce_call - > conn - > dce_ctx - > lp_ctx ,
2006-07-31 18:05:08 +04:00
& auth_context ) ;
2005-01-09 15:55:25 +03:00
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
2008-10-28 21:03:50 +03:00
nt_status = auth_context_set_challenge ( auth_context , r - > in . logon - > network - > challenge , " netr_LogonSamLogonWithFlags " ) ;
2005-01-09 15:55:25 +03:00
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
2004-06-07 07:46:32 +04:00
2008-10-28 21:03:50 +03:00
user_info - > logon_parameters = r - > in . logon - > network - > identity_info . parameter_control ;
user_info - > client . account_name = r - > in . logon - > network - > identity_info . account_name . string ;
user_info - > client . domain_name = r - > in . logon - > network - > identity_info . domain_name . string ;
user_info - > workstation_name = r - > in . logon - > network - > identity_info . workstation . string ;
2005-07-22 08:10:07 +04:00
user_info - > password_state = AUTH_PASSWORD_RESPONSE ;
2008-10-28 21:03:50 +03:00
user_info - > password . response . lanman = data_blob_talloc ( mem_ctx , r - > in . logon - > network - > lm . data , r - > in . logon - > network - > lm . length ) ;
user_info - > password . response . nt = data_blob_talloc ( mem_ctx , r - > in . logon - > network - > nt . data , r - > in . logon - > network - > nt . length ) ;
2005-07-22 08:10:07 +04:00
2004-06-07 07:46:32 +04:00
break ;
2008-08-12 11:46:01 +04:00
case NetlogonGenericInformation :
{
2008-08-29 12:05:06 +04:00
if ( creds - > negotiate_flags & NETLOGON_NEG_ARCFOUR ) {
2009-04-06 16:54:44 +04:00
netlogon_creds_arcfour_crypt ( creds ,
2008-10-28 21:03:50 +03:00
r - > in . logon - > generic - > data , r - > in . logon - > generic - > length ) ;
2008-08-29 12:05:06 +04:00
} else {
/* Using DES to verify kerberos tickets makes no sense */
return NT_STATUS_INVALID_PARAMETER ;
}
2008-10-28 21:03:50 +03:00
if ( strcmp ( r - > in . logon - > generic - > package_name . string , " Kerberos " ) = = 0 ) {
2008-09-03 09:30:17 +04:00
NTSTATUS status ;
struct server_id * kdc ;
struct kdc_check_generic_kerberos check ;
struct netr_GenericInfo2 * generic = talloc_zero ( mem_ctx , struct netr_GenericInfo2 ) ;
NT_STATUS_HAVE_NO_MEMORY ( generic ) ;
2008-10-28 21:03:50 +03:00
* r - > out . authoritative = 1 ;
2008-09-03 09:30:17 +04:00
/* TODO: Describe and deal with these flags */
2008-10-28 21:03:50 +03:00
* r - > out . flags = 0 ;
2008-08-29 12:05:06 +04:00
2008-10-28 21:03:50 +03:00
r - > out . validation - > generic = generic ;
2008-09-03 09:30:17 +04:00
kdc = irpc_servers_byname ( dce_call - > msg_ctx , mem_ctx , " kdc_server " ) ;
if ( ( kdc = = NULL ) | | ( kdc [ 0 ] . id = = 0 ) ) {
return NT_STATUS_NO_LOGON_SERVERS ;
2008-08-29 12:05:06 +04:00
}
2008-09-03 09:30:17 +04:00
check . in . generic_request =
2008-10-28 21:03:50 +03:00
data_blob_const ( r - > in . logon - > generic - > data ,
r - > in . logon - > generic - > length ) ;
2008-09-03 09:30:17 +04:00
status = irpc_call ( dce_call - > msg_ctx , kdc [ 0 ] ,
& ndr_table_irpc , NDR_KDC_CHECK_GENERIC_KERBEROS ,
& check , mem_ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2008-08-29 12:05:06 +04:00
}
2008-09-03 09:30:17 +04:00
generic - > length = check . out . generic_reply . length ;
generic - > data = check . out . generic_reply . data ;
return NT_STATUS_OK ;
2008-08-29 12:05:06 +04:00
}
/* Until we get an implemetnation of these other packages */
2008-08-12 11:46:01 +04:00
return NT_STATUS_INVALID_PARAMETER ;
}
2004-06-07 07:46:32 +04:00
default :
return NT_STATUS_INVALID_PARAMETER ;
}
2005-01-09 15:55:25 +03:00
nt_status = auth_check_password ( auth_context , mem_ctx , user_info , & server_info ) ;
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
2004-06-07 07:46:32 +04:00
2005-06-29 17:55:09 +04:00
nt_status = auth_convert_server_info_sambaseinfo ( mem_ctx , server_info , & sam ) ;
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
2005-01-10 15:14:26 +03:00
2004-06-08 02:17:51 +04:00
/* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
2004-09-22 16:17:51 +04:00
/* It appears that level 6 is not individually encrypted */
2006-07-27 13:37:55 +04:00
if ( ( r - > in . validation_level ! = 6 ) & &
memcmp ( sam - > key . key , zeros , sizeof ( sam - > key . key ) ) ! = 0 ) {
2005-01-03 09:23:02 +03:00
/* This key is sent unencrypted without the ARCFOUR flag set */
2006-02-09 05:30:43 +03:00
if ( creds - > negotiate_flags & NETLOGON_NEG_ARCFOUR ) {
2009-04-06 16:54:44 +04:00
netlogon_creds_arcfour_crypt ( creds ,
2005-01-03 09:23:02 +03:00
sam - > key . key ,
sizeof ( sam - > key . key ) ) ;
}
2004-06-07 12:54:49 +04:00
}
2005-01-10 15:14:26 +03:00
2004-06-08 02:17:51 +04:00
/* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
2004-09-22 16:17:51 +04:00
/* It appears that level 6 is not individually encrypted */
2006-07-27 13:37:55 +04:00
if ( ( r - > in . validation_level ! = 6 ) & &
memcmp ( sam - > LMSessKey . key , zeros , sizeof ( sam - > LMSessKey . key ) ) ! = 0 ) {
2006-02-09 05:30:43 +03:00
if ( creds - > negotiate_flags & NETLOGON_NEG_ARCFOUR ) {
2009-04-06 16:54:44 +04:00
netlogon_creds_arcfour_crypt ( creds ,
2005-01-03 09:23:02 +03:00
sam - > LMSessKey . key ,
sizeof ( sam - > LMSessKey . key ) ) ;
} else {
2009-04-06 16:54:44 +04:00
netlogon_creds_des_encrypt_LMKey ( creds ,
2005-01-03 09:23:02 +03:00
& sam - > LMSessKey ) ;
}
2004-06-07 12:54:49 +04:00
}
2004-06-07 07:46:32 +04:00
switch ( r - > in . validation_level ) {
case 2 :
2005-01-10 18:56:37 +03:00
sam2 = talloc_zero ( mem_ctx , struct netr_SamInfo2 ) ;
2005-01-09 15:55:25 +03:00
NT_STATUS_HAVE_NO_MEMORY ( sam2 ) ;
2004-06-14 16:06:53 +04:00
sam2 - > base = * sam ;
2008-10-28 21:03:50 +03:00
r - > out . validation - > sam2 = sam2 ;
2004-06-07 07:46:32 +04:00
break ;
2004-06-14 16:06:53 +04:00
2004-06-07 07:46:32 +04:00
case 3 :
2005-01-10 18:56:37 +03:00
sam3 = talloc_zero ( mem_ctx , struct netr_SamInfo3 ) ;
2005-01-09 15:55:25 +03:00
NT_STATUS_HAVE_NO_MEMORY ( sam3 ) ;
2004-06-14 16:06:53 +04:00
sam3 - > base = * sam ;
2008-10-28 21:03:50 +03:00
r - > out . validation - > sam3 = sam3 ;
2004-06-07 07:46:32 +04:00
break ;
2004-06-14 16:06:53 +04:00
case 6 :
2005-01-10 18:56:37 +03:00
sam6 = talloc_zero ( mem_ctx , struct netr_SamInfo6 ) ;
2005-01-09 15:55:25 +03:00
NT_STATUS_HAVE_NO_MEMORY ( sam6 ) ;
2004-06-14 16:06:53 +04:00
sam6 - > base = * sam ;
2007-12-04 22:05:00 +03:00
sam6 - > forest . string = lp_realm ( dce_call - > conn - > dce_ctx - > lp_ctx ) ;
2004-06-14 16:06:53 +04:00
sam6 - > principle . string = talloc_asprintf ( mem_ctx , " %s@%s " ,
2004-06-15 07:53:21 +04:00
sam - > account_name . string , sam6 - > forest . string ) ;
2005-01-10 18:56:37 +03:00
NT_STATUS_HAVE_NO_MEMORY ( sam6 - > principle . string ) ;
2008-10-28 21:03:50 +03:00
r - > out . validation - > sam6 = sam6 ;
2004-06-14 16:06:53 +04:00
break ;
2004-06-07 07:46:32 +04:00
default :
break ;
}
2008-10-28 21:03:50 +03:00
* r - > out . authoritative = 1 ;
2004-06-07 07:46:32 +04:00
2005-01-10 15:30:13 +03:00
/* TODO: Describe and deal with these flags */
2008-10-28 21:03:50 +03:00
* r - > out . flags = 0 ;
2005-01-10 15:30:13 +03:00
2004-06-07 07:46:32 +04:00
return NT_STATUS_OK ;
}
2004-05-15 11:51:38 +04:00
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_LogonSamLogonEx ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-02-21 03:07:59 +03:00
struct netr_LogonSamLogonEx * r )
{
NTSTATUS nt_status ;
2009-04-06 16:54:44 +04:00
struct netlogon_creds_CredentialState * creds ;
struct ldb_context * ldb = schannel_db_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx ) ;
if ( ! ldb ) {
return NT_STATUS_ACCESS_DENIED ;
}
nt_status = schannel_fetch_session_key ( ldb , mem_ctx , r - > in . computer_name , & creds ) ;
2006-02-21 03:07:59 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
2006-07-27 13:37:55 +04:00
if ( ! dce_call - > conn - > auth_state . auth_info | |
dce_call - > conn - > auth_state . auth_info - > auth_type ! = DCERPC_AUTH_TYPE_SCHANNEL ) {
2009-04-06 16:54:44 +04:00
return NT_STATUS_ACCESS_DENIED ;
2006-02-21 03:07:59 +03:00
}
2007-01-17 17:49:36 +03:00
return dcesrv_netr_LogonSamLogon_base ( dce_call , mem_ctx , r , creds ) ;
2006-02-21 03:07:59 +03:00
}
2005-01-03 09:23:02 +03:00
/*
netr_LogonSamLogonWithFlags
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-03 09:23:02 +03:00
struct netr_LogonSamLogonWithFlags * r )
{
NTSTATUS nt_status ;
2009-04-06 16:54:44 +04:00
struct netlogon_creds_CredentialState * creds ;
2005-01-03 09:23:02 +03:00
struct netr_LogonSamLogonEx r2 ;
2005-01-10 18:56:37 +03:00
struct netr_Authenticator * return_authenticator ;
2005-01-03 09:23:02 +03:00
2005-01-10 18:56:37 +03:00
return_authenticator = talloc ( mem_ctx , struct netr_Authenticator ) ;
NT_STATUS_HAVE_NO_MEMORY ( return_authenticator ) ;
2005-01-03 09:23:02 +03:00
2009-04-06 16:54:44 +04:00
nt_status = dcesrv_netr_creds_server_step_check ( dce_call ,
2009-04-09 08:26:04 +04:00
mem_ctx ,
r - > in . computer_name ,
2009-04-06 16:54:44 +04:00
r - > in . credential , return_authenticator ,
& creds ) ;
2005-01-10 18:56:37 +03:00
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
2005-01-03 09:23:02 +03:00
ZERO_STRUCT ( r2 ) ;
2005-01-10 18:56:37 +03:00
r2 . in . server_name = r - > in . server_name ;
2006-02-21 03:07:59 +03:00
r2 . in . computer_name = r - > in . computer_name ;
2005-01-10 18:56:37 +03:00
r2 . in . logon_level = r - > in . logon_level ;
r2 . in . logon = r - > in . logon ;
r2 . in . validation_level = r - > in . validation_level ;
r2 . in . flags = r - > in . flags ;
2008-10-28 21:03:50 +03:00
r2 . out . validation = r - > out . validation ;
r2 . out . authoritative = r - > out . authoritative ;
r2 . out . flags = r - > out . flags ;
2005-01-03 09:23:02 +03:00
2007-01-17 17:49:36 +03:00
nt_status = dcesrv_netr_LogonSamLogon_base ( dce_call , mem_ctx , & r2 , creds ) ;
2005-01-03 09:23:02 +03:00
2005-01-10 18:56:37 +03:00
r - > out . return_authenticator = return_authenticator ;
2005-01-03 09:23:02 +03:00
return nt_status ;
}
2004-06-14 13:31:47 +04:00
/*
netr_LogonSamLogon
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_LogonSamLogon ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-06-14 13:31:47 +04:00
struct netr_LogonSamLogon * r )
{
struct netr_LogonSamLogonWithFlags r2 ;
2008-10-28 21:03:50 +03:00
uint32_t flags = 0 ;
2004-06-14 13:31:47 +04:00
NTSTATUS status ;
ZERO_STRUCT ( r2 ) ;
r2 . in . server_name = r - > in . server_name ;
2006-02-21 03:07:59 +03:00
r2 . in . computer_name = r - > in . computer_name ;
2004-06-14 13:31:47 +04:00
r2 . in . credential = r - > in . credential ;
r2 . in . return_authenticator = r - > in . return_authenticator ;
r2 . in . logon_level = r - > in . logon_level ;
r2 . in . logon = r - > in . logon ;
r2 . in . validation_level = r - > in . validation_level ;
2008-10-28 21:03:50 +03:00
r2 . in . flags = & flags ;
r2 . out . validation = r - > out . validation ;
r2 . out . authoritative = r - > out . authoritative ;
r2 . out . flags = & flags ;
2004-06-14 13:31:47 +04:00
2007-01-17 17:49:36 +03:00
status = dcesrv_netr_LogonSamLogonWithFlags ( dce_call , mem_ctx , & r2 ) ;
2004-06-14 13:31:47 +04:00
r - > out . return_authenticator = r2 . out . return_authenticator ;
return status ;
}
2004-05-15 11:51:38 +04:00
/*
netr_LogonSamLogoff
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_LogonSamLogoff ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_LogonSamLogoff * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DatabaseDeltas
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_DatabaseDeltas ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_DatabaseDeltas * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2009-06-12 14:38:22 +04:00
/*
netr_DatabaseSync2
*/
static NTSTATUS dcesrv_netr_DatabaseSync2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DatabaseSync2 * r )
{
/* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
return NT_STATUS_NOT_IMPLEMENTED ;
}
2004-05-15 11:51:38 +04:00
/*
netr_DatabaseSync
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_DatabaseSync ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_DatabaseSync * r )
{
2009-06-12 14:38:22 +04:00
struct netr_DatabaseSync2 r2 ;
NTSTATUS status ;
ZERO_STRUCT ( r2 ) ;
r2 . in . logon_server = r - > in . logon_server ;
r2 . in . computername = r - > in . computername ;
r2 . in . credential = r - > in . credential ;
r2 . in . database_id = r - > in . database_id ;
r2 . in . restart_state = SYNCSTATE_NORMAL_STATE ;
r2 . in . sync_context = r - > in . sync_context ;
r2 . out . sync_context = r - > out . sync_context ;
r2 . out . delta_enum_array = r - > out . delta_enum_array ;
r2 . in . preferredmaximumlength = r - > in . preferredmaximumlength ;
status = dcesrv_netr_DatabaseSync2 ( dce_call , mem_ctx , & r2 ) ;
return status ;
2004-05-15 11:51:38 +04:00
}
/*
netr_AccountDeltas
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_AccountDeltas ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_AccountDeltas * r )
{
2006-09-01 14:41:27 +04:00
/* w2k3 returns "NOT IMPLEMENTED" for this call */
return NT_STATUS_NOT_IMPLEMENTED ;
2004-05-15 11:51:38 +04:00
}
/*
netr_AccountSync
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_AccountSync ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_AccountSync * r )
{
2006-09-01 14:41:27 +04:00
/* w2k3 returns "NOT IMPLEMENTED" for this call */
return NT_STATUS_NOT_IMPLEMENTED ;
2004-05-15 11:51:38 +04:00
}
/*
netr_GetDcName
*/
2007-06-08 14:32:29 +04:00
static WERROR dcesrv_netr_GetDcName ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_GetDcName * r )
{
2008-12-04 13:56:51 +03:00
const char * const attrs [ ] = { NULL } ;
void * sam_ctx ;
struct ldb_message * * res ;
struct ldb_dn * domain_dn ;
int ret ;
const char * dcname ;
sam_ctx = samdb_connect ( mem_ctx , dce_call - > event_ctx ,
dce_call - > conn - > dce_ctx - > lp_ctx ,
dce_call - > conn - > auth_state . session_info ) ;
if ( sam_ctx = = NULL ) {
return WERR_DS_SERVICE_UNAVAILABLE ;
}
2009-02-24 23:08:07 +03:00
domain_dn = samdb_domain_to_dn ( ( struct ldb_context * ) sam_ctx , mem_ctx ,
2008-12-04 13:56:51 +03:00
r - > in . domainname ) ;
if ( domain_dn = = NULL ) {
return WERR_DS_SERVICE_UNAVAILABLE ;
}
2009-02-24 23:08:07 +03:00
ret = gendb_search_dn ( ( struct ldb_context * ) sam_ctx , mem_ctx ,
domain_dn , & res , attrs ) ;
2008-12-04 13:56:51 +03:00
if ( ret ! = 1 ) {
return WERR_NO_SUCH_DOMAIN ;
}
/* TODO: - return real IP address
* - check all r - > in . * parameters ( server_unc is ignored by w2k3 ! )
*/
dcname = talloc_asprintf ( mem_ctx , " \\ \\ %s " ,
lp_netbios_name ( dce_call - > conn - > dce_ctx - > lp_ctx ) ) ;
W_ERROR_HAVE_NO_MEMORY ( dcname ) ;
* r - > out . dcname = dcname ;
return WERR_OK ;
2004-05-15 11:51:38 +04:00
}
/*
2009-06-12 14:38:22 +04:00
netr_LogonControl2Ex
2004-05-15 11:51:38 +04:00
*/
2009-06-12 14:38:22 +04:00
static WERROR dcesrv_netr_LogonControl2Ex ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonControl2Ex * r )
2004-05-15 11:51:38 +04:00
{
2009-06-12 14:38:22 +04:00
return WERR_NOT_SUPPORTED ;
2004-05-15 11:51:38 +04:00
}
/*
2009-06-12 14:38:22 +04:00
netr_LogonControl
2004-05-15 11:51:38 +04:00
*/
2009-06-12 14:38:22 +04:00
static WERROR dcesrv_netr_LogonControl ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonControl * r )
2004-05-15 11:51:38 +04:00
{
2009-06-12 14:38:22 +04:00
struct netr_LogonControl2Ex r2 ;
2008-12-04 14:03:01 +03:00
WERROR werr ;
2009-06-12 14:38:22 +04:00
if ( r - > in . level = = 0x00000001 ) {
ZERO_STRUCT ( r2 ) ;
2008-12-04 14:03:01 +03:00
2009-06-12 14:38:22 +04:00
r2 . in . logon_server = r - > in . logon_server ;
r2 . in . function_code = r - > in . function_code ;
r2 . in . level = r - > in . level ;
r2 . in . data = NULL ;
r2 . out . query = r - > out . query ;
2008-12-04 14:03:01 +03:00
2009-06-12 14:38:22 +04:00
werr = dcesrv_netr_LogonControl2Ex ( dce_call , mem_ctx , & r2 ) ;
} else if ( r - > in . level = = 0x00000002 ) {
werr = WERR_NOT_SUPPORTED ;
} else {
werr = WERR_UNKNOWN_LEVEL ;
}
2008-12-04 14:03:01 +03:00
return werr ;
2004-05-15 11:51:38 +04:00
}
/*
netr_LogonControl2
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_LogonControl2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_LogonControl2 * r )
{
2009-06-12 14:38:22 +04:00
struct netr_LogonControl2Ex r2 ;
WERROR werr ;
ZERO_STRUCT ( r2 ) ;
r2 . in . logon_server = r - > in . logon_server ;
r2 . in . function_code = r - > in . function_code ;
r2 . in . level = r - > in . level ;
r2 . in . data = r - > in . data ;
r2 . out . query = r - > out . query ;
werr = dcesrv_netr_LogonControl2Ex ( dce_call , mem_ctx , & r2 ) ;
return werr ;
2004-05-15 11:51:38 +04:00
}
/*
2009-06-12 14:38:22 +04:00
netr_GetAnyDCName
2004-05-15 11:51:38 +04:00
*/
2009-06-12 14:38:22 +04:00
static WERROR dcesrv_netr_GetAnyDCName ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_GetAnyDCName * r )
2004-05-15 11:51:38 +04:00
{
2009-06-12 14:38:22 +04:00
struct netr_GetDcName r2 ;
WERROR werr ;
ZERO_STRUCT ( r2 ) ;
r2 . in . logon_server = r - > in . logon_server ;
r2 . in . domainname = r - > in . domainname ;
r2 . out . dcname = r - > out . dcname ;
werr = dcesrv_netr_GetDcName ( dce_call , mem_ctx , & r2 ) ;
return werr ;
2004-05-15 11:51:38 +04:00
}
/*
netr_DatabaseRedo
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_DatabaseRedo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-15 11:51:38 +04:00
struct netr_DatabaseRedo * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2004-05-28 17:23:30 +04:00
/*
2007-12-04 01:38:54 +03:00
netr_NetrEnumerateTurstedDomains
2004-05-28 17:23:30 +04:00
*/
2007-12-04 01:38:54 +03:00
static WERROR dcesrv_netr_NetrEnumerateTrustedDomains ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NetrEnumerateTrustedDomains * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2009-02-16 13:00:07 +03:00
netr_LogonGetCapabilities
2004-05-28 17:23:30 +04:00
*/
2009-02-16 13:00:07 +03:00
static NTSTATUS dcesrv_netr_LogonGetCapabilities ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonGetCapabilities * r )
2004-05-28 17:23:30 +04:00
{
2009-02-16 13:00:07 +03:00
/* we don't support AES yet */
return NT_STATUS_NOT_IMPLEMENTED ;
2004-05-28 17:23:30 +04:00
}
/*
netr_NETRLOGONSETSERVICEBITS
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-28 17:23:30 +04:00
struct netr_NETRLOGONSETSERVICEBITS * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2008-01-25 02:04:24 +03:00
/*
netr_LogonGetTrustRid
2004-05-28 17:23:30 +04:00
*/
2008-01-25 02:04:24 +03:00
static WERROR dcesrv_netr_LogonGetTrustRid ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonGetTrustRid * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONCOMPUTESERVERDIGEST
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-28 17:23:30 +04:00
struct netr_NETRLOGONCOMPUTESERVERDIGEST * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONCOMPUTECLIENTDIGEST
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-28 17:23:30 +04:00
struct netr_NETRLOGONCOMPUTECLIENTDIGEST * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2005-10-31 05:12:13 +03:00
netr_DsRGetSiteName
2004-05-28 17:23:30 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_DsRGetSiteName ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-10-31 05:12:13 +03:00
struct netr_DsRGetSiteName * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2005-07-08 09:19:28 +04:00
/*
fill in a netr_DomainTrustInfo from a ldb search result
*/
2006-09-01 14:41:27 +04:00
static NTSTATUS fill_domain_trust_info ( TALLOC_CTX * mem_ctx ,
2009-05-26 06:31:39 +04:00
struct loadparm_context * lp_ctx ,
struct ldb_context * sam_ctx ,
2006-09-01 14:41:27 +04:00
struct ldb_message * res ,
2005-08-04 00:27:33 +04:00
struct netr_DomainTrustInfo * info ,
2008-10-04 04:52:59 +04:00
bool is_local , bool is_trust_list )
2004-06-14 12:12:50 +04:00
{
ZERO_STRUCTP ( info ) ;
2004-12-21 14:52:53 +03:00
2008-10-04 04:52:59 +04:00
info - > trust_extension . info = talloc_zero ( mem_ctx , struct netr_trust_extension ) ;
info - > trust_extension . length = 16 ;
info - > trust_extension . info - > flags =
2009-05-26 06:31:39 +04:00
NETR_TRUST_FLAG_TREEROOT |
2008-10-04 04:52:59 +04:00
NETR_TRUST_FLAG_IN_FOREST |
NETR_TRUST_FLAG_PRIMARY ;
2009-05-26 06:31:39 +04:00
2008-10-04 04:52:59 +04:00
info - > trust_extension . info - > parent_index = 0 ; /* should be index into array
of parent */
info - > trust_extension . info - > trust_type = LSA_TRUST_TYPE_UPLEVEL ; /* should be based on ldb search for trusts */
info - > trust_extension . info - > trust_attributes = LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE ; /* needs to be based on ldb search */
if ( is_trust_list ) {
/* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
info - > forest . string = NULL ;
} else {
2009-05-26 06:31:39 +04:00
char * p ;
2008-10-05 08:48:46 +04:00
/* TODO: we need a common function for pulling the forest */
2009-05-26 06:31:39 +04:00
info - > forest . string = ldb_dn_canonical_string ( info , ldb_get_root_basedn ( sam_ctx ) ) ;
if ( ! info - > forest . string ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
p = strchr ( info - > forest . string , ' / ' ) ;
if ( p ) {
* p = ' \0 ' ;
}
2008-10-04 04:52:59 +04:00
}
2004-12-21 14:52:53 +03:00
if ( is_local ) {
2009-05-26 06:31:39 +04:00
info - > domainname . string = lp_sam_name ( lp_ctx ) ;
info - > fulldomainname . string = lp_realm ( lp_ctx ) ;
2004-12-21 14:52:53 +03:00
info - > guid = samdb_result_guid ( res , " objectGUID " ) ;
info - > sid = samdb_result_dom_sid ( mem_ctx , res , " objectSid " ) ;
2004-06-14 12:12:50 +04:00
} else {
2004-12-21 14:52:53 +03:00
info - > domainname . string = samdb_result_string ( res , " flatName " , NULL ) ;
2006-09-01 14:41:27 +04:00
info - > fulldomainname . string = samdb_result_string ( res , " trustPartner " , NULL ) ;
2004-12-21 14:52:53 +03:00
info - > guid = samdb_result_guid ( res , " objectGUID " ) ;
info - > sid = samdb_result_dom_sid ( mem_ctx , res , " securityIdentifier " ) ;
2004-06-14 12:12:50 +04:00
}
return NT_STATUS_OK ;
}
2004-05-28 17:23:30 +04:00
/*
2004-06-14 12:12:50 +04:00
netr_LogonGetDomainInfo
this is called as part of the ADS domain logon procedure .
2008-01-11 01:24:38 +03:00
It has an important role in convaying details about the client , such
as Operating System , Version , Service Pack etc .
2004-05-28 17:23:30 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_netr_LogonGetDomainInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-06-14 12:12:50 +04:00
struct netr_LogonGetDomainInfo * r )
2004-05-28 17:23:30 +04:00
{
2006-09-01 14:41:27 +04:00
const char * const attrs [ ] = { " objectSid " ,
2004-12-21 14:52:53 +03:00
" objectGUID " , " flatName " , " securityIdentifier " ,
2006-09-01 14:41:27 +04:00
" trustPartner " , NULL } ;
2005-08-04 00:27:33 +04:00
struct ldb_context * sam_ctx ;
2009-05-26 06:31:39 +04:00
struct ldb_message * * res1 , * * res2 ;
2004-06-14 12:12:50 +04:00
struct netr_DomainInfo1 * info1 ;
2009-05-26 06:31:39 +04:00
int ret1 , ret2 , i ;
2004-06-14 12:12:50 +04:00
NTSTATUS status ;
2005-08-04 00:27:33 +04:00
const char * local_domain ;
2009-04-06 16:54:44 +04:00
status = dcesrv_netr_creds_server_step_check ( dce_call ,
2009-04-09 08:26:04 +04:00
mem_ctx ,
r - > in . computer_name ,
r - > in . credential ,
r - > out . return_authenticator ,
NULL ) ;
2008-10-04 04:52:59 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( __location__ " Bad credentials - error \n " ) ) ;
}
2006-07-27 13:37:55 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2004-06-14 12:12:50 +04:00
2008-04-17 14:23:44 +04:00
sam_ctx = samdb_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , dce_call - > conn - > auth_state . session_info ) ;
2004-06-14 12:12:50 +04:00
if ( sam_ctx = = NULL ) {
return NT_STATUS_INVALID_SYSTEM_SERVICE ;
}
/* we need to do two searches. The first will pull our primary
domain and the second will pull any trusted domains . Our
primary domain is also a " trusted " domain , so we need to
put the primary domain into the lists of returned trusts as
well */
2006-09-01 14:41:27 +04:00
ret1 = gendb_search_dn ( sam_ctx , mem_ctx , samdb_base_dn ( sam_ctx ) , & res1 , attrs ) ;
2004-06-14 12:12:50 +04:00
if ( ret1 ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-08-04 00:27:33 +04:00
/* try and find the domain */
2009-05-26 06:31:39 +04:00
local_domain = lp_sam_name ( dce_call - > conn - > dce_ctx - > lp_ctx ) ;
2005-08-04 00:27:33 +04:00
2006-08-25 11:08:06 +04:00
ret2 = gendb_search ( sam_ctx , mem_ctx , NULL , & res2 , attrs , " (objectClass=trustedDomain) " ) ;
2004-06-14 12:12:50 +04:00
if ( ret2 = = - 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-01-27 10:08:20 +03:00
info1 = talloc ( mem_ctx , struct netr_DomainInfo1 ) ;
2006-07-27 13:37:55 +04:00
NT_STATUS_HAVE_NO_MEMORY ( info1 ) ;
2004-06-14 12:12:50 +04:00
ZERO_STRUCTP ( info1 ) ;
info1 - > num_trusts = ret2 + 1 ;
2005-01-27 10:08:20 +03:00
info1 - > trusts = talloc_array ( mem_ctx , struct netr_DomainTrustInfo ,
2004-06-14 12:12:50 +04:00
info1 - > num_trusts ) ;
2006-07-27 13:37:55 +04:00
NT_STATUS_HAVE_NO_MEMORY ( info1 - > trusts ) ;
2004-06-14 12:12:50 +04:00
2009-05-26 06:31:39 +04:00
status = fill_domain_trust_info ( mem_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , sam_ctx , res1 [ 0 ] , & info1 - > domaininfo ,
2008-10-04 04:52:59 +04:00
true , false ) ;
2006-07-27 13:37:55 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2004-06-14 12:12:50 +04:00
for ( i = 0 ; i < ret2 ; i + + ) {
2009-05-26 06:31:39 +04:00
status = fill_domain_trust_info ( mem_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , sam_ctx , res2 [ i ] , & info1 - > trusts [ i ] ,
2008-10-04 04:52:59 +04:00
false , true ) ;
2006-07-27 13:37:55 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2004-06-14 12:12:50 +04:00
}
2009-05-26 06:31:39 +04:00
status = fill_domain_trust_info ( mem_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , sam_ctx , res1 [ 0 ] , & info1 - > trusts [ i ] ,
2008-10-04 04:52:59 +04:00
true , true ) ;
2006-07-27 13:37:55 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2005-07-08 09:19:28 +04:00
2009-05-26 06:31:39 +04:00
info1 - > dns_hostname . string = lp_realm ( dce_call - > conn - > dce_ctx - > lp_ctx ) ;
2008-10-04 04:52:59 +04:00
info1 - > workstation_flags =
NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | NETR_WS_FLAG_HANDLES_SPN_UPDATE ;
info1 - > supported_enc_types = 0 ; /* w2008 gives this 0 */
2008-10-28 04:25:30 +03:00
r - > out . info - > info1 = info1 ;
2004-06-14 12:12:50 +04:00
return NT_STATUS_OK ;
2004-05-28 17:23:30 +04:00
}
2007-12-04 11:41:28 +03:00
/*
netr_ServerPasswordGet
2004-05-28 17:23:30 +04:00
*/
2007-12-04 11:41:28 +03:00
static WERROR dcesrv_netr_ServerPasswordGet ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_ServerPasswordGet * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONSENDTOSAM
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_NETRLOGONSENDTOSAM ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-28 17:23:30 +04:00
struct netr_NETRLOGONSENDTOSAM * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2007-11-07 20:42:00 +03:00
netr_DsRAddressToSitenamesW
2004-05-28 17:23:30 +04:00
*/
2007-11-07 20:42:00 +03:00
static WERROR dcesrv_netr_DsRAddressToSitenamesW ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DsRAddressToSitenamesW * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2005-10-31 05:12:13 +03:00
netr_DsRGetDCNameEx2
2004-05-28 17:23:30 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_DsRGetDCNameEx2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-10-31 05:12:13 +03:00
struct netr_DsRGetDCNameEx2 * r )
2004-05-28 17:23:30 +04:00
{
2009-02-10 09:28:05 +03:00
const char * const attrs [ ] = { " objectGUID " , NULL } ;
2009-05-26 06:31:39 +04:00
struct ldb_context * sam_ctx ;
2004-11-22 20:14:57 +03:00
struct ldb_message * * res ;
2007-12-05 02:40:48 +03:00
struct ldb_dn * domain_dn ;
2004-11-22 20:14:57 +03:00
int ret ;
2008-10-28 03:43:06 +03:00
struct netr_DsRGetDCNameInfo * info ;
2004-11-22 20:14:57 +03:00
2008-10-28 03:43:06 +03:00
ZERO_STRUCTP ( r - > out . info ) ;
2004-11-22 20:14:57 +03:00
2008-04-17 14:23:44 +04:00
sam_ctx = samdb_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , dce_call - > conn - > auth_state . session_info ) ;
2004-11-22 20:14:57 +03:00
if ( sam_ctx = = NULL ) {
return WERR_DS_SERVICE_UNAVAILABLE ;
}
2009-02-10 09:28:05 +03:00
/* Win7-beta will send the domain name in the form the user typed, so we have to cope
with both the short and long form here */
2009-05-26 06:31:39 +04:00
if ( r - > in . domain_name ! = NULL & & ! lp_is_my_domain_or_realm ( dce_call - > conn - > dce_ctx - > lp_ctx ,
r - > in . domain_name ) ) {
return WERR_NO_SUCH_DOMAIN ;
2009-02-10 09:28:05 +03:00
}
2009-05-26 06:31:39 +04:00
domain_dn = ldb_get_default_basedn ( sam_ctx ) ;
2007-12-05 02:40:48 +03:00
if ( domain_dn = = NULL ) {
return WERR_DS_SERVICE_UNAVAILABLE ;
}
2009-05-26 06:31:39 +04:00
ret = gendb_search_dn ( sam_ctx , mem_ctx ,
2009-02-24 23:08:07 +03:00
domain_dn , & res , attrs ) ;
2004-11-22 20:14:57 +03:00
if ( ret ! = 1 ) {
}
2008-10-28 03:43:06 +03:00
info = talloc ( mem_ctx , struct netr_DsRGetDCNameInfo ) ;
W_ERROR_HAVE_NO_MEMORY ( info ) ;
2004-11-22 20:14:57 +03:00
/* TODO: - return real IP address
* - check all r - > in . * parameters ( server_unc is ignored by w2k3 ! )
*/
2008-10-28 03:43:06 +03:00
info - > dc_unc = talloc_asprintf ( mem_ctx , " \\ \\ %s.%s " ,
2007-12-04 22:05:00 +03:00
lp_netbios_name ( dce_call - > conn - > dce_ctx - > lp_ctx ) ,
lp_realm ( dce_call - > conn - > dce_ctx - > lp_ctx ) ) ;
2008-10-28 03:43:06 +03:00
W_ERROR_HAVE_NO_MEMORY ( info - > dc_unc ) ;
info - > dc_address = talloc_strdup ( mem_ctx , " \\ \\ 0.0.0.0 " ) ;
W_ERROR_HAVE_NO_MEMORY ( info - > dc_address ) ;
info - > dc_address_type = DS_ADDRESS_TYPE_INET ;
info - > domain_guid = samdb_result_guid ( res [ 0 ] , " objectGUID " ) ;
2009-02-10 09:28:05 +03:00
info - > domain_name = lp_realm ( dce_call - > conn - > dce_ctx - > lp_ctx ) ;
info - > forest_name = lp_realm ( dce_call - > conn - > dce_ctx - > lp_ctx ) ;
2008-10-28 03:43:06 +03:00
info - > dc_flags = DS_DNS_FOREST |
2007-05-25 03:38:46 +04:00
DS_DNS_DOMAIN |
DS_DNS_CONTROLLER |
DS_SERVER_WRITABLE |
DS_SERVER_CLOSEST |
DS_SERVER_TIMESERV |
DS_SERVER_KDC |
DS_SERVER_DS |
DS_SERVER_LDAP |
DS_SERVER_GC |
DS_SERVER_PDC ;
2008-10-28 03:43:06 +03:00
info - > dc_site_name = talloc_strdup ( mem_ctx , " Default-First-Site-Name " ) ;
W_ERROR_HAVE_NO_MEMORY ( info - > dc_site_name ) ;
info - > client_site_name = talloc_strdup ( mem_ctx , " Default-First-Site-Name " ) ;
W_ERROR_HAVE_NO_MEMORY ( info - > client_site_name ) ;
* r - > out . info = info ;
2004-11-22 20:14:57 +03:00
return WERR_OK ;
2004-05-28 17:23:30 +04:00
}
2005-10-31 05:12:13 +03:00
/*
netr_DsRGetDCNameEx
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_DsRGetDCNameEx ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-10-31 05:12:13 +03:00
struct netr_DsRGetDCNameEx * r )
{
struct netr_DsRGetDCNameEx2 r2 ;
WERROR werr ;
ZERO_STRUCT ( r2 ) ;
r2 . in . server_unc = r - > in . server_unc ;
r2 . in . client_account = NULL ;
r2 . in . mask = 0 ;
r2 . in . domain_guid = r - > in . domain_guid ;
r2 . in . domain_name = r - > in . domain_name ;
r2 . in . site_name = r - > in . site_name ;
r2 . in . flags = r - > in . flags ;
2008-10-28 03:43:06 +03:00
r2 . out . info = r - > out . info ;
2005-10-31 05:12:13 +03:00
2007-01-17 17:49:36 +03:00
werr = dcesrv_netr_DsRGetDCNameEx2 ( dce_call , mem_ctx , & r2 ) ;
2008-10-28 03:43:06 +03:00
2005-10-31 05:12:13 +03:00
return werr ;
}
/*
netr_DsRGetDCName
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_DsRGetDCName ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-10-31 05:12:13 +03:00
struct netr_DsRGetDCName * r )
{
struct netr_DsRGetDCNameEx2 r2 ;
WERROR werr ;
ZERO_STRUCT ( r2 ) ;
r2 . in . server_unc = r - > in . server_unc ;
r2 . in . client_account = NULL ;
r2 . in . mask = 0 ;
r2 . in . domain_name = r - > in . domain_name ;
r2 . in . domain_guid = r - > in . domain_guid ;
r2 . in . site_name = NULL ; /* should fill in from site GUID */
r2 . in . flags = r - > in . flags ;
2008-10-28 03:43:06 +03:00
r2 . out . info = r - > out . info ;
2005-10-31 05:12:13 +03:00
2007-01-17 17:49:36 +03:00
werr = dcesrv_netr_DsRGetDCNameEx2 ( dce_call , mem_ctx , & r2 ) ;
2008-10-28 03:43:06 +03:00
2005-10-31 05:12:13 +03:00
return werr ;
}
2004-05-28 17:23:30 +04:00
/*
netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-28 17:23:30 +04:00
struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2007-12-04 01:38:54 +03:00
/*
netr_NetrEnumerateTrustedDomainsEx
2004-05-28 17:23:30 +04:00
*/
2007-12-04 01:38:54 +03:00
static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NetrEnumerateTrustedDomainsEx * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2007-11-07 20:42:00 +03:00
netr_DsRAddressToSitenamesExW
2004-05-28 17:23:30 +04:00
*/
2007-11-07 20:42:00 +03:00
static WERROR dcesrv_netr_DsRAddressToSitenamesExW ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DsRAddressToSitenamesExW * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2007-05-30 14:24:40 +04:00
netr_DsrGetDcSiteCoverageW
2004-05-28 17:23:30 +04:00
*/
2007-05-30 14:24:40 +04:00
static WERROR dcesrv_netr_DsrGetDcSiteCoverageW ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DsrGetDcSiteCoverageW * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DsrEnumerateDomainTrusts
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_netr_DsrEnumerateDomainTrusts ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-28 17:23:30 +04:00
struct netr_DsrEnumerateDomainTrusts * r )
{
2008-10-27 18:07:33 +03:00
struct netr_DomainTrustList * trusts ;
2004-05-28 17:23:30 +04:00
void * sam_ctx ;
2005-08-03 11:24:42 +04:00
int ret ;
2009-05-26 06:31:39 +04:00
struct ldb_message * * dom_res ;
2006-09-01 14:41:27 +04:00
const char * const dom_attrs [ ] = { " objectSid " , " objectGUID " , NULL } ;
2004-05-28 17:23:30 +04:00
ZERO_STRUCT ( r - > out ) ;
2008-04-17 14:23:44 +04:00
sam_ctx = samdb_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , dce_call - > conn - > auth_state . session_info ) ;
2004-05-28 17:23:30 +04:00
if ( sam_ctx = = NULL ) {
return WERR_GENERAL_FAILURE ;
}
2009-02-24 23:08:07 +03:00
ret = gendb_search_dn ( ( struct ldb_context * ) sam_ctx , mem_ctx , NULL ,
& dom_res , dom_attrs ) ;
2004-05-28 17:23:30 +04:00
if ( ret = = - 1 ) {
return WERR_GENERAL_FAILURE ;
}
2005-08-03 11:24:42 +04:00
if ( ret ! = 1 ) {
return WERR_GENERAL_FAILURE ;
}
2008-10-27 18:07:33 +03:00
trusts = talloc ( mem_ctx , struct netr_DomainTrustList ) ;
2006-07-27 13:37:55 +04:00
W_ERROR_HAVE_NO_MEMORY ( trusts ) ;
2008-10-27 18:07:33 +03:00
trusts - > array = talloc_array ( trusts , struct netr_DomainTrust , ret ) ;
W_ERROR_HAVE_NO_MEMORY ( trusts - > array ) ;
trusts - > count = 1 ; /* ?? */
2004-05-28 17:23:30 +04:00
r - > out . trusts = trusts ;
2004-05-30 17:15:15 +04:00
/* TODO: add filtering by trust_flags, and correct trust_type
and attributes */
2009-05-26 06:31:39 +04:00
trusts - > array [ 0 ] . netbios_name = lp_sam_name ( dce_call - > conn - > dce_ctx - > lp_ctx ) ;
trusts - > array [ 0 ] . dns_name = lp_realm ( dce_call - > conn - > dce_ctx - > lp_ctx ) ;
2008-10-27 18:07:33 +03:00
trusts - > array [ 0 ] . trust_flags =
2005-08-03 11:24:42 +04:00
NETR_TRUST_FLAG_TREEROOT |
NETR_TRUST_FLAG_IN_FOREST |
NETR_TRUST_FLAG_PRIMARY ;
2008-10-27 18:07:33 +03:00
trusts - > array [ 0 ] . parent_index = 0 ;
trusts - > array [ 0 ] . trust_type = 2 ;
trusts - > array [ 0 ] . trust_attributes = 0 ;
trusts - > array [ 0 ] . sid = samdb_result_dom_sid ( mem_ctx , dom_res [ 0 ] , " objectSid " ) ;
trusts - > array [ 0 ] . guid = samdb_result_guid ( dom_res [ 0 ] , " objectGUID " ) ;
2004-05-28 17:23:30 +04:00
return WERR_OK ;
}
2008-01-26 00:42:14 +03:00
/*
netr_DsrDeregisterDNSHostRecords
2004-05-28 17:23:30 +04:00
*/
2008-01-26 00:42:14 +03:00
static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DsrDeregisterDNSHostRecords * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2007-12-04 12:20:13 +03:00
/*
netr_ServerTrustPasswordsGet
2004-05-28 17:23:30 +04:00
*/
2007-12-04 12:20:13 +03:00
static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_ServerTrustPasswordsGet * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2007-06-08 14:49:46 +04:00
netr_DsRGetForestTrustInformation
2004-05-28 17:23:30 +04:00
*/
2007-06-08 14:49:46 +04:00
static WERROR dcesrv_netr_DsRGetForestTrustInformation ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DsRGetForestTrustInformation * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2007-12-22 08:52:14 +03:00
/*
netr_GetForestTrustInformation
2004-05-28 17:23:30 +04:00
*/
2007-12-22 08:52:14 +03:00
static WERROR dcesrv_netr_GetForestTrustInformation ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_GetForestTrustInformation * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2008-12-10 04:51:16 +03:00
/*
netr_ServerGetTrustInfo
2004-05-28 17:23:30 +04:00
*/
2008-12-10 04:51:16 +03:00
static NTSTATUS dcesrv_netr_ServerGetTrustInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_ServerGetTrustInfo * r )
2004-05-28 17:23:30 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2004-05-15 11:51:38 +04:00
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_netlogon_s.c"