2004-05-15 11:51:38 +04:00
/*
Unix SMB / CIFS implementation .
endpoint server for the netlogon pipe
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2004
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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
# include "rpc_server/common/common.h"
struct server_pipe_state {
TALLOC_CTX * mem_ctx ;
struct netr_Credential client_challenge ;
struct netr_Credential server_challenge ;
BOOL authenticated ;
char * account_name ;
char * computer_name ; /* for logging only */
2004-05-25 20:24:13 +04:00
uint32_t acct_flags ;
2004-05-25 21:24:24 +04:00
uint16_t sec_chan_type ;
2004-05-15 11:51:38 +04:00
struct creds_CredentialState * creds ;
} ;
2004-06-14 12:12:50 +04:00
/*
a client has connected to the netlogon server using schannel , so we need
to re - establish the credentials state
*/
static NTSTATUS netlogon_schannel_setup ( struct dcesrv_call_state * dce_call )
{
struct server_pipe_state * state ;
NTSTATUS status ;
TALLOC_CTX * mem_ctx ;
mem_ctx = talloc_init ( " netlogon_bind " ) ;
if ( ! mem_ctx ) {
return NT_STATUS_NO_MEMORY ;
}
state = talloc_p ( mem_ctx , struct server_pipe_state ) ;
if ( state = = NULL ) {
talloc_destroy ( mem_ctx ) ;
}
ZERO_STRUCTP ( state ) ;
state - > mem_ctx = mem_ctx ;
state - > authenticated = True ;
state - > creds = talloc_p ( mem_ctx , struct creds_CredentialState ) ;
if ( state - > creds = = NULL ) {
talloc_destroy ( mem_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCTP ( state - > creds ) ;
if ( dce_call - > conn - > auth_state . session_info = = NULL ) {
talloc_destroy ( mem_ctx ) ;
return NT_STATUS_NO_USER_SESSION_KEY ;
}
status = schannel_fetch_session_key ( mem_ctx ,
dce_call - > conn - > auth_state . session_info - > workstation ,
state - > creds ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_destroy ( mem_ctx ) ;
return status ;
}
dce_call - > conn - > private = state ;
return NT_STATUS_OK ;
}
/*
a hook for bind on the netlogon pipe
*/
2004-05-15 11:51:38 +04:00
static NTSTATUS netlogon_bind ( struct dcesrv_call_state * dce_call , const struct dcesrv_interface * di )
{
dce_call - > conn - > private = NULL ;
2004-06-14 12:12:50 +04:00
/* if this is a schannel bind then we need to reconstruct the pipe state */
if ( dce_call - > conn - > auth_state . auth_info & &
dce_call - > conn - > auth_state . auth_info - > auth_type = = DCERPC_AUTH_TYPE_SCHANNEL ) {
NTSTATUS status ;
status = netlogon_schannel_setup ( dce_call ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
}
2004-05-15 11:51:38 +04:00
return NT_STATUS_OK ;
}
/* this function is called when the client disconnects the endpoint */
static void netlogon_unbind ( struct dcesrv_connection * conn , const struct dcesrv_interface * di )
{
struct server_pipe_state * pipe_state = conn - > private ;
2004-06-07 07:46:32 +04:00
if ( pipe_state ) {
2004-05-15 11:51:38 +04:00
talloc_destroy ( pipe_state - > mem_ctx ) ;
2004-06-07 07:46:32 +04:00
}
2004-05-15 11:51:38 +04:00
conn - > private = NULL ;
}
# define DCESRV_INTERFACE_NETLOGON_BIND netlogon_bind
# define DCESRV_INTERFACE_NETLOGON_UNBIND netlogon_unbind
static NTSTATUS netr_ServerReqChallenge ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_ServerReqChallenge * r )
{
struct server_pipe_state * pipe_state = dce_call - > conn - > private ;
TALLOC_CTX * pipe_mem_ctx ;
2004-05-30 17:15:15 +04:00
ZERO_STRUCTP ( r - > out . credentials ) ;
2004-05-15 11:51:38 +04:00
/* destroyed on pipe shutdown */
if ( pipe_state ) {
talloc_destroy ( pipe_state - > mem_ctx ) ;
dce_call - > conn - > private = NULL ;
}
pipe_mem_ctx = talloc_init ( " internal netlogon pipe state for %s " ,
r - > in . computer_name ) ;
if ( ! pipe_mem_ctx ) {
return NT_STATUS_NO_MEMORY ;
}
pipe_state = talloc_p ( pipe_mem_ctx , struct server_pipe_state ) ;
if ( ! pipe_state ) {
talloc_destroy ( pipe_mem_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
pipe_state - > mem_ctx = pipe_mem_ctx ;
pipe_state - > authenticated = False ;
pipe_state - > creds = NULL ;
pipe_state - > account_name = NULL ;
pipe_state - > computer_name = NULL ;
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 ,
sizeof ( pipe_state - > server_challenge . data ) ,
False ) ;
2004-05-30 17:15:15 +04:00
* r - > out . credentials = pipe_state - > server_challenge ;
2004-05-15 11:51:38 +04:00
dce_call - > conn - > private = pipe_state ;
return NT_STATUS_OK ;
}
2004-05-30 17:15:15 +04:00
static NTSTATUS netr_ServerAuthenticate3 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_ServerAuthenticate3 * r )
2004-05-15 11:51:38 +04:00
{
2004-05-30 17:15:15 +04:00
struct server_pipe_state * pipe_state = dce_call - > conn - > private ;
2004-05-15 11:51:38 +04:00
void * sam_ctx ;
2004-06-05 07:22:10 +04:00
struct samr_Password * mach_pwd ;
2004-05-25 21:24:24 +04:00
uint16_t acct_flags ;
2004-05-15 11:51:38 +04:00
int num_records ;
struct ldb_message * * msgs ;
NTSTATUS nt_status ;
2004-05-30 17:15:15 +04:00
const char * attrs [ ] = { " unicodePwd " , " lmPwdHash " , " ntPwdHash " , " userAccountControl " ,
" objectSid " , NULL } ;
2004-05-15 11:51:38 +04:00
2004-05-30 17:15:15 +04:00
ZERO_STRUCTP ( r - > out . credentials ) ;
* r - > out . rid = 0 ;
2004-06-04 03:15:16 +04:00
* r - > out . negotiate_flags = * r - > in . negotiate_flags ;
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 ;
}
sam_ctx = samdb_connect ( ) ;
if ( sam_ctx = = NULL ) {
return NT_STATUS_INVALID_SYSTEM_SERVICE ;
}
/* pull the user attributes */
num_records = samdb_search ( sam_ctx , mem_ctx , NULL , & msgs , attrs ,
" (&(sAMAccountName=%s)(objectclass=user)) " ,
2004-06-05 07:22:10 +04:00
r - > in . 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 ) ) ;
2004-05-15 11:51:38 +04:00
samdb_close ( sam_ctx ) ;
return NT_STATUS_NO_SUCH_USER ;
}
if ( num_records > 1 ) {
2004-06-05 07:22:10 +04:00
DEBUG ( 1 , ( " Found %d records matching user [%s] \n " , num_records , r - > in . account_name ) ) ;
2004-05-15 11:51:38 +04:00
samdb_close ( sam_ctx ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
acct_flags = samdb_result_acct_flags ( msgs [ 0 ] ,
" userAccountControl " ) ;
if ( acct_flags & ACB_DISABLED ) {
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 ) {
2004-05-15 11:51:38 +04:00
if ( ! ( acct_flags & ACB_WSTRUST ) ) {
DEBUG ( 1 , ( " Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x \n " , acct_flags ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
2004-05-30 17:15:15 +04:00
} else if ( r - > in . secure_channel_type = = SEC_CHAN_DOMAIN ) {
2004-05-15 11:51:38 +04:00
if ( ! ( acct_flags & ACB_DOMTRUST ) ) {
DEBUG ( 1 , ( " Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x \n " , acct_flags ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
2004-05-30 17:15:15 +04:00
} else if ( r - > in . secure_channel_type = = SEC_CHAN_BDC ) {
2004-05-15 11:51:38 +04:00
if ( ! ( acct_flags & ACB_SVRTRUST ) ) {
DEBUG ( 1 , ( " Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x \n " , acct_flags ) ) ;
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 ;
}
pipe_state - > acct_flags = acct_flags ;
2004-05-30 17:15:15 +04:00
pipe_state - > sec_chan_type = r - > in . secure_channel_type ;
* r - > out . rid = samdb_result_rid_from_sid ( mem_ctx , msgs [ 0 ] , " objectSid " , 0 ) ;
2004-05-15 11:51:38 +04:00
2004-05-30 17:15:15 +04:00
nt_status = samdb_result_passwords ( mem_ctx , msgs [ 0 ] , NULL , & mach_pwd ) ;
2004-06-05 08:51:24 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) | | mach_pwd = = NULL ) {
2004-05-15 11:51:38 +04:00
samdb_close ( sam_ctx ) ;
return NT_STATUS_ACCESS_DENIED ;
}
samdb_close ( sam_ctx ) ;
if ( ! pipe_state - > creds ) {
2004-05-17 01:30:48 +04:00
pipe_state - > creds = talloc_p ( pipe_state - > mem_ctx , struct creds_CredentialState ) ;
2004-05-15 11:51:38 +04:00
if ( ! pipe_state - > creds ) {
return NT_STATUS_NO_MEMORY ;
}
}
creds_server_init ( pipe_state - > creds , & pipe_state - > client_challenge ,
& pipe_state - > server_challenge , mach_pwd ,
2004-06-04 03:15:16 +04:00
r - > out . credentials ,
* r - > in . negotiate_flags ) ;
2004-05-30 17:15:15 +04:00
if ( ! creds_server_check ( pipe_state - > creds , r - > in . credentials ) ) {
2004-05-15 11:51:38 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
pipe_state - > authenticated = True ;
if ( pipe_state - > account_name ) {
/* We don't want a memory leak on this long-lived talloc context */
talloc_free ( pipe_state - > mem_ctx , pipe_state - > account_name ) ;
}
2004-06-05 07:22:10 +04:00
pipe_state - > account_name = talloc_strdup ( pipe_state - > mem_ctx , r - > in . account_name ) ;
2004-05-15 11:51:38 +04:00
if ( pipe_state - > computer_name ) {
/* We don't want a memory leak on this long-lived talloc context */
talloc_free ( pipe_state - > mem_ctx , pipe_state - > account_name ) ;
}
2004-05-30 17:15:15 +04:00
pipe_state - > computer_name = talloc_strdup ( pipe_state - > mem_ctx , r - > in . computer_name ) ;
2004-05-15 11:51:38 +04:00
2004-06-05 05:29:20 +04:00
/* remember this session key state */
nt_status = schannel_store_session_key ( mem_ctx , pipe_state - > computer_name , pipe_state - > creds ) ;
return nt_status ;
2004-05-15 11:51:38 +04:00
}
static NTSTATUS netr_ServerAuthenticate ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_ServerAuthenticate * r )
{
2004-05-30 17:15:15 +04:00
struct netr_ServerAuthenticate3 r3 ;
uint32 negotiate_flags , rid ;
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 ;
r3 . out . credentials = r - > out . credentials ;
r3 . in . negotiate_flags = & negotiate_flags ;
r3 . out . negotiate_flags = & negotiate_flags ;
r3 . out . rid = & rid ;
2004-05-15 11:51:38 +04:00
2004-05-30 17:15:15 +04:00
return netr_ServerAuthenticate3 ( dce_call , mem_ctx , & r3 ) ;
2004-05-15 11:51:38 +04:00
}
static NTSTATUS 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 ;
uint32 rid ;
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 ;
r3 . out . credentials = r - > out . credentials ;
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
2004-05-30 17:15:15 +04:00
return netr_ServerAuthenticate3 ( dce_call , mem_ctx , & r3 ) ;
2004-05-15 11:51:38 +04:00
}
2004-05-30 17:15:15 +04:00
2004-05-17 01:30:48 +04:00
static BOOL netr_creds_server_step_check ( struct server_pipe_state * pipe_state ,
struct netr_Authenticator * received_authenticator ,
struct netr_Authenticator * return_authenticator )
{
if ( ! pipe_state - > authenticated ) {
return False ;
}
return creds_server_step_check ( pipe_state - > creds ,
received_authenticator ,
return_authenticator ) ;
}
2004-05-15 16:04:07 +04:00
static NTSTATUS netr_ServerPasswordSet ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_ServerPasswordSet * r )
{
2004-05-17 01:30:48 +04:00
struct server_pipe_state * pipe_state = dce_call - > conn - > private ;
void * sam_ctx ;
int num_records ;
int num_records_domain ;
int ret ;
struct ldb_message * * msgs ;
struct ldb_message * * msgs_domain ;
NTSTATUS nt_status ;
struct ldb_message mod , * msg_set_pw = & mod ;
const char * domain_dn ;
2004-05-22 11:55:48 +04:00
const char * domain_sid ;
2004-05-17 01:30:48 +04:00
2004-05-30 17:15:15 +04:00
const char * attrs [ ] = { " objectSid " , NULL } ;
2004-05-15 16:04:07 +04:00
2004-05-17 01:30:48 +04:00
const char * * domain_attrs = attrs ;
ZERO_STRUCT ( mod ) ;
2004-06-07 12:54:49 +04:00
if ( ! pipe_state ) {
DEBUG ( 1 , ( " No challenge requested by client, cannot authenticate \n " ) ) ;
2004-05-17 01:30:48 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2004-06-07 12:54:49 +04:00
if ( ! netr_creds_server_step_check ( pipe_state , & r - > in . credential , & r - > out . return_authenticator ) ) {
2004-05-17 01:30:48 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
sam_ctx = samdb_connect ( ) ;
if ( sam_ctx = = NULL ) {
return NT_STATUS_INVALID_SYSTEM_SERVICE ;
}
/* pull the user attributes */
num_records = samdb_search ( sam_ctx , mem_ctx , NULL , & msgs , attrs ,
" (&(sAMAccountName=%s)(objectclass=user)) " ,
pipe_state - > account_name ) ;
if ( num_records = = 0 ) {
DEBUG ( 3 , ( " Couldn't find user [%s] in samdb. \n " ,
pipe_state - > account_name ) ) ;
samdb_close ( sam_ctx ) ;
return NT_STATUS_NO_SUCH_USER ;
}
if ( num_records > 1 ) {
DEBUG ( 1 , ( " Found %d records matching user [%s] \n " , num_records ,
pipe_state - > account_name ) ) ;
samdb_close ( sam_ctx ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-05-22 11:55:48 +04:00
domain_sid = samdb_result_sid_prefix ( mem_ctx , msgs [ 0 ] , " objectSid " ) ;
2004-05-17 01:30:48 +04:00
if ( ! domain_sid ) {
samdb_close ( sam_ctx ) ;
2004-06-05 08:51:24 +04:00
DEBUG ( 1 , ( " no objectSid in user record \n " ) ) ;
2004-05-17 01:30:48 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
/* find the domain's DN */
num_records_domain = samdb_search ( sam_ctx , mem_ctx , NULL ,
& msgs_domain , domain_attrs ,
" (&(objectSid=%s)(objectclass=domain)) " ,
2004-05-22 11:55:48 +04:00
domain_sid ) ;
2004-05-17 01:30:48 +04:00
if ( num_records_domain = = 0 ) {
DEBUG ( 3 , ( " check_sam_security: Couldn't find domain [%s] in passdb file. \n " ,
2004-05-22 11:55:48 +04:00
domain_sid ) ) ;
2004-05-17 01:30:48 +04:00
samdb_close ( sam_ctx ) ;
return NT_STATUS_NO_SUCH_USER ;
}
if ( num_records_domain > 1 ) {
2004-05-22 11:55:48 +04:00
DEBUG ( 1 , ( " Found %d records matching domain [%s] \n " ,
num_records_domain , domain_sid ) ) ;
2004-05-17 01:30:48 +04:00
samdb_close ( sam_ctx ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
domain_dn = msgs_domain [ 0 ] - > dn ;
mod . dn = talloc_strdup ( mem_ctx , msgs [ 0 ] - > dn ) ;
if ( ! mod . dn ) {
samdb_close ( sam_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2004-05-15 16:04:07 +04:00
2004-05-17 01:30:48 +04:00
creds_des_decrypt ( pipe_state - > creds , & r - > in . new_password ) ;
/* set the password - samdb needs to know both the domain and user DNs,
so the domain password policy can be used */
nt_status = samdb_set_password ( sam_ctx , mem_ctx ,
msgs [ 0 ] - > dn , domain_dn ,
msg_set_pw ,
NULL , /* Don't have plaintext */
2004-06-04 15:58:46 +04:00
NULL , & r - > in . new_password ,
2004-05-25 17:57:39 +04:00
False /* This is not considered a password change */ ,
NULL ) ;
2004-05-17 01:30:48 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
samdb_close ( sam_ctx ) ;
return nt_status ;
}
2004-05-15 16:04:07 +04:00
2004-05-22 11:55:48 +04:00
ret = samdb_replace ( sam_ctx , mem_ctx , msg_set_pw ) ;
2004-05-17 01:30:48 +04:00
if ( ret ! = 0 ) {
/* we really need samdb.c to return NTSTATUS */
samdb_close ( sam_ctx ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
samdb_close ( sam_ctx ) ;
return NT_STATUS_OK ;
2004-05-15 16:04:07 +04:00
}
2004-05-15 11:51:38 +04:00
/*
netr_LogonUasLogon
*/
static WERROR 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
*/
static WERROR netr_LogonUasLogoff ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonUasLogoff * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_LogonSamLogon
*/
2004-06-07 07:46:32 +04:00
static NTSTATUS netr_LogonSamLogon ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonSamLogon * r )
{
struct server_pipe_state * pipe_state = dce_call - > conn - > private ;
struct auth_context * auth_context ;
struct auth_usersupplied_info * user_info ;
struct auth_serversupplied_info * server_info ;
NTSTATUS nt_status ;
const uint8_t * chal ;
2004-06-07 12:54:49 +04:00
static const char zeros [ 16 ] ;
struct netr_SamInfo2 * sam2 ;
struct netr_SamInfo3 * sam ;
2004-06-07 07:46:32 +04:00
2004-06-07 12:54:49 +04:00
if ( ! pipe_state ) {
DEBUG ( 1 , ( " No challenge requested by client, cannot authenticate \n " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
r - > out . return_authenticator = talloc_p ( mem_ctx , struct netr_Authenticator ) ;
if ( ! r - > out . return_authenticator ) {
return NT_STATUS_NO_MEMORY ;
}
if ( ! netr_creds_server_step_check ( pipe_state , r - > in . credential , r - > out . return_authenticator ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
2004-06-07 07:46:32 +04:00
switch ( r - > in . logon_level ) {
case 1 :
case 3 :
creds_arcfour_crypt ( pipe_state - > creds ,
r - > in . logon . password - > lmpassword . hash ,
sizeof ( r - > in . logon . password - > lmpassword . hash ) ) ;
creds_arcfour_crypt ( pipe_state - > creds ,
r - > in . logon . password - > ntpassword . hash ,
sizeof ( r - > in . logon . password - > ntpassword . hash ) ) ;
nt_status = make_auth_context_subsystem ( & auth_context ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
chal = auth_context - > get_ntlm_challenge ( auth_context ) ;
nt_status = make_user_info_netlogon_interactive ( & user_info ,
r - > in . logon . password - > identity_info . account_name . string ,
r - > in . logon . password - > identity_info . domain_name . string ,
r - > in . logon . password - > identity_info . workstation . string ,
chal ,
& r - > in . logon . password - > lmpassword ,
& r - > in . logon . password - > ntpassword ) ;
break ;
case 2 :
case 6 :
nt_status = make_auth_context_fixed ( & auth_context , r - > in . logon . network - > challenge ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
nt_status = make_user_info_netlogon_network ( & user_info ,
r - > in . logon . network - > identity_info . account_name . string ,
r - > in . logon . network - > identity_info . domain_name . string ,
r - > in . logon . network - > identity_info . workstation . string ,
2004-06-07 12:54:49 +04:00
r - > in . logon . network - > lm . data , r - > in . logon . network - > lm . length ,
r - > in . logon . network - > nt . data , r - > in . logon . network - > nt . length ) ;
2004-06-07 07:46:32 +04:00
break ;
default :
free_auth_context ( & auth_context ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
nt_status = auth_context - > check_ntlm_password ( auth_context ,
user_info ,
& server_info ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
free_auth_context ( & auth_context ) ;
return nt_status ;
}
free_auth_context ( & auth_context ) ;
2004-06-07 12:54:49 +04:00
sam = talloc_p ( mem_ctx , struct netr_SamInfo3 ) ;
sam - > last_logon = server_info - > last_logon ;
sam - > last_logoff = server_info - > last_logoff ;
sam - > acct_expiry = server_info - > acct_expiry ;
sam - > last_password_change = server_info - > last_password_change ;
sam - > allow_password_change = server_info - > allow_password_change ;
sam - > force_password_change = server_info - > force_password_change ;
sam - > account_name . string = talloc_strdup ( mem_ctx , server_info - > account_name ) ;
sam - > full_name . string = talloc_strdup ( mem_ctx , server_info - > full_name ) ;
sam - > logon_script . string = talloc_strdup ( mem_ctx , server_info - > account_name ) ;
sam - > profile_path . string = talloc_strdup ( mem_ctx , server_info - > profile_path ) ;
sam - > home_directory . string = talloc_strdup ( mem_ctx , server_info - > home_directory ) ;
sam - > home_drive . string = talloc_strdup ( mem_ctx , server_info - > home_drive ) ;
sam - > logon_count = server_info - > logon_count ;
sam - > bad_password_count = sam - > bad_password_count ;
sam - > rid = server_info - > user_sid - > sub_auths [ server_info - > user_sid - > num_auths - 1 ] ;
sam - > primary_gid = server_info - > primary_group_sid - > sub_auths [ server_info - > primary_group_sid - > num_auths - 1 ] ;
sam - > group_count = 0 ;
sam - > groupids = NULL ;
sam - > acct_flags = server_info - > acct_flags ;
sam - > logon_server . string = lp_netbios_name ( ) ;
sam - > domain . string = talloc_strdup ( mem_ctx , server_info - > domain ) ;
sam - > domain_sid = dom_sid_dup ( mem_ctx , server_info - > user_sid ) ;
sam - > domain_sid - > num_auths - - ;
2004-06-08 02:17:51 +04:00
sam - > AccountControl = 0 ;
sam - > unknown1 = 0 ;
sam - > unknown2 = 0 ;
sam - > unknown3 = 0 ;
sam - > unknown4 = 0 ;
sam - > unknown5 = 0 ;
sam - > unknown6 = 0 ;
sam - > unknown7 = 0 ;
2004-06-07 12:54:49 +04:00
sam - > sidcount = 0 ;
sam - > sids = NULL ;
if ( server_info - > user_session_key . length = = sizeof ( sam - > key . key ) ) {
memcpy ( sam - > key . key , server_info - > user_session_key . data , sizeof ( sam - > key . key ) ) ;
} else {
ZERO_STRUCT ( sam - > key . key ) ;
}
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-06-07 12:54:49 +04:00
if ( memcmp ( sam - > key . key , zeros ,
sizeof ( sam - > key . key ) ) ! = 0 ) {
creds_arcfour_crypt ( pipe_state - > creds ,
sam - > key . key ,
sizeof ( sam - > key . key ) ) ;
}
if ( server_info - > lm_session_key . length = = sizeof ( sam - > LMSessKey . key ) ) {
memcpy ( sam - > LMSessKey . key , server_info - > lm_session_key . data ,
sizeof ( sam - > LMSessKey . key ) ) ;
} else {
ZERO_STRUCT ( sam - > LMSessKey . key ) ;
}
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-06-07 12:54:49 +04:00
if ( memcmp ( sam - > LMSessKey . key , zeros ,
sizeof ( sam - > LMSessKey . key ) ) ! = 0 ) {
creds_arcfour_crypt ( pipe_state - > creds ,
sam - > LMSessKey . key ,
sizeof ( sam - > LMSessKey . key ) ) ;
}
2004-06-07 07:46:32 +04:00
switch ( r - > in . validation_level ) {
case 2 :
{
2004-06-07 12:54:49 +04:00
sam2 = talloc_p ( mem_ctx , struct netr_SamInfo2 ) ;
r - > out . validation . sam2 = sam2 ;
sam2 - > last_logon = sam - > last_logon ;
sam2 - > last_logoff = sam - > last_logoff ;
sam2 - > acct_expiry = sam - > acct_expiry ;
sam2 - > last_password_change = sam - > last_password_change ;
2004-06-08 02:17:51 +04:00
sam2 - > allow_password_change = sam - > allow_password_change ;
sam2 - > force_password_change = sam - > force_password_change ;
2004-06-07 12:54:49 +04:00
sam2 - > account_name = sam - > account_name ;
sam2 - > full_name = sam - > full_name ;
sam2 - > logon_script = sam - > logon_script ;
sam2 - > profile_path = sam - > profile_path ;
sam2 - > home_directory = sam - > home_directory ;
sam2 - > home_drive = sam - > home_drive ;
sam2 - > logon_count = sam - > logon_count ;
sam2 - > bad_password_count = sam - > bad_password_count ;
sam2 - > rid = sam - > rid ;
sam2 - > primary_gid = sam - > primary_gid ;
sam2 - > group_count = sam - > group_count ;
sam2 - > groupids = sam - > groupids ;
sam2 - > acct_flags = sam - > acct_flags ;
sam2 - > key = sam - > key ;
sam2 - > logon_server = sam - > logon_server ;
sam2 - > domain = sam - > domain ;
sam2 - > domain_sid = sam - > domain_sid ;
sam2 - > LMSessKey = sam - > LMSessKey ;
sam2 - > AccountControl = sam - > AccountControl ;
sam2 - > unknown1 = sam - > unknown1 ;
sam2 - > unknown2 = sam - > unknown2 ;
sam2 - > unknown3 = sam - > unknown3 ;
sam2 - > unknown4 = sam - > unknown4 ;
sam2 - > unknown5 = sam - > unknown5 ;
sam2 - > unknown6 = sam - > unknown6 ;
sam2 - > unknown7 = sam - > unknown7 ;
2004-06-07 07:46:32 +04:00
break ;
}
case 3 :
{
2004-06-07 12:54:49 +04:00
r - > out . validation . sam3 = sam ;
2004-06-07 07:46:32 +04:00
break ;
}
default :
break ;
}
r - > out . authoritative = 1 ;
return NT_STATUS_OK ;
}
2004-05-15 11:51:38 +04:00
/*
netr_LogonSamLogoff
*/
static NTSTATUS netr_LogonSamLogoff ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonSamLogoff * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DatabaseDeltas
*/
static NTSTATUS netr_DatabaseDeltas ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DatabaseDeltas * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DatabaseSync
*/
static NTSTATUS netr_DatabaseSync ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DatabaseSync * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_AccountDeltas
*/
static NTSTATUS netr_AccountDeltas ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_AccountDeltas * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_AccountSync
*/
static NTSTATUS netr_AccountSync ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_AccountSync * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_GetDcName
*/
static NTSTATUS netr_GetDcName ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_GetDcName * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_LogonControl
*/
static WERROR netr_LogonControl ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonControl * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_GetAnyDCName
*/
static WERROR netr_GetAnyDCName ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_GetAnyDCName * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_LogonControl2
*/
static WERROR netr_LogonControl2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonControl2 * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DatabaseSync2
*/
static NTSTATUS netr_DatabaseSync2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DatabaseSync2 * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DatabaseRedo
*/
static NTSTATUS netr_DatabaseRedo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DatabaseRedo * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_LogonControl2Ex
*/
static WERROR netr_LogonControl2Ex ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonControl2Ex * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2004-05-28 17:23:30 +04:00
/*
netr_NETRENUMERATETRUSTEDDOMAINS
*/
static WERROR netr_NETRENUMERATETRUSTEDDOMAINS ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRENUMERATETRUSTEDDOMAINS * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DSRGETDCNAME
*/
static WERROR netr_DSRGETDCNAME ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DSRGETDCNAME * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONDUMMYROUTINE1
*/
static WERROR netr_NETRLOGONDUMMYROUTINE1 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRLOGONDUMMYROUTINE1 * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONSETSERVICEBITS
*/
static WERROR netr_NETRLOGONSETSERVICEBITS ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRLOGONSETSERVICEBITS * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONGETTRUSTRID
*/
static WERROR netr_NETRLOGONGETTRUSTRID ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRLOGONGETTRUSTRID * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONCOMPUTESERVERDIGEST
*/
static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRLOGONCOMPUTESERVERDIGEST * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONCOMPUTECLIENTDIGEST
*/
static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRLOGONCOMPUTECLIENTDIGEST * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DSRGETDCNAMEX
*/
static WERROR netr_DSRGETDCNAMEX ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DSRGETDCNAMEX * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DSRGETSITENAME
*/
static WERROR netr_DSRGETSITENAME ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DSRGETSITENAME * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2004-06-14 12:12:50 +04:00
/*
fill in a netr_DomainTrustInfo from a ldb search result
*/
static NTSTATUS fill_domain_trust_info ( TALLOC_CTX * mem_ctx , struct ldb_message * res ,
struct netr_DomainTrustInfo * info )
{
ZERO_STRUCTP ( info ) ;
info - > domainname . string = samdb_result_string ( res , " flatName " , NULL ) ;
if ( info - > domainname . string = = NULL ) {
info - > domainname . string = samdb_result_string ( res , " name " , NULL ) ;
info - > fulldomainname . string = samdb_result_string ( res , " dnsDomain " , NULL ) ;
} else {
info - > fulldomainname . string = samdb_result_string ( res , " name " , NULL ) ;
}
/* TODO: we need proper forest support */
info - > forest . string = info - > fulldomainname . string ;
info - > guid = samdb_result_guid ( res , " objectGUID " ) ;
info - > sid = samdb_result_dom_sid ( mem_ctx , res , " objectSid " ) ;
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 .
2004-05-28 17:23:30 +04:00
*/
2004-06-14 12:12:50 +04:00
static NTSTATUS netr_LogonGetDomainInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_LogonGetDomainInfo * r )
2004-05-28 17:23:30 +04:00
{
2004-06-14 12:12:50 +04:00
struct server_pipe_state * pipe_state = dce_call - > conn - > private ;
const char * const attrs [ ] = { " name " , " dnsDomain " , " objectSid " ,
" objectGUID " , " flatName " , NULL } ;
void * sam_ctx ;
struct ldb_message * * res1 , * * res2 ;
struct netr_DomainInfo1 * info1 ;
int ret1 , ret2 , i ;
NTSTATUS status ;
if ( ! pipe_state ) {
return NT_STATUS_ACCESS_DENIED ;
}
if ( ! netr_creds_server_step_check ( pipe_state ,
r - > in . credential , r - > out . credential ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
sam_ctx = samdb_connect ( ) ;
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 */
ret1 = samdb_search ( sam_ctx , mem_ctx , NULL , & res1 , attrs , " (objectClass=domainDNS) " ) ;
if ( ret1 ! = 1 ) {
samdb_close ( sam_ctx ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
ret2 = samdb_search ( sam_ctx , mem_ctx , NULL , & res2 , attrs , " (objectClass=trustedDomain) " ) ;
if ( ret2 = = - 1 ) {
samdb_close ( sam_ctx ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
/* we don't need the db link any more */
samdb_close ( sam_ctx ) ;
info1 = talloc_p ( mem_ctx , struct netr_DomainInfo1 ) ;
if ( info1 = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCTP ( info1 ) ;
info1 - > num_trusts = ret2 + 1 ;
info1 - > trusts = talloc_array_p ( mem_ctx , struct netr_DomainTrustInfo ,
info1 - > num_trusts ) ;
if ( info1 - > trusts = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
status = fill_domain_trust_info ( mem_ctx , res1 [ 0 ] , & info1 - > domaininfo ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = fill_domain_trust_info ( mem_ctx , res1 [ 0 ] , & info1 - > trusts [ 0 ] ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
for ( i = 0 ; i < ret2 ; i + + ) {
status = fill_domain_trust_info ( mem_ctx , res2 [ i ] , & info1 - > trusts [ i + 1 ] ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
}
r - > out . info . info1 = info1 ;
return NT_STATUS_OK ;
2004-05-28 17:23:30 +04:00
}
/*
netr_NETRSERVERPASSWORDSET2
*/
static WERROR netr_NETRSERVERPASSWORDSET2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRSERVERPASSWORDSET2 * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRSERVERPASSWORDGET
*/
static WERROR netr_NETRSERVERPASSWORDGET ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRSERVERPASSWORDGET * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONSENDTOSAM
*/
static WERROR netr_NETRLOGONSENDTOSAM ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRLOGONSENDTOSAM * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DSRADDRESSTOSITENAMESW
*/
static WERROR netr_DSRADDRESSTOSITENAMESW ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DSRADDRESSTOSITENAMESW * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DSRGETDCNAMEEX2
*/
static WERROR netr_DSRGETDCNAMEEX2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DSRGETDCNAMEEX2 * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
*/
static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRENUMERATETRUSTEDDOMAINSEX
*/
static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRENUMERATETRUSTEDDOMAINSEX * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DSRADDRESSTOSITENAMESEXW
*/
static WERROR netr_DSRADDRESSTOSITENAMESEXW ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DSRADDRESSTOSITENAMESEXW * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DSRGETDCSITECOVERAGEW
*/
static WERROR netr_DSRGETDCSITECOVERAGEW ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DSRGETDCSITECOVERAGEW * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONSAMLOGONEX
*/
static WERROR netr_NETRLOGONSAMLOGONEX ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRLOGONSAMLOGONEX * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DsrEnumerateDomainTrusts
*/
static WERROR netr_DsrEnumerateDomainTrusts ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DsrEnumerateDomainTrusts * r )
{
struct netr_DomainTrust * trusts ;
void * sam_ctx ;
int ret , i ;
struct ldb_message * * res ;
const char * const attrs [ ] = { " name " , " dnsDomain " , " objectSid " , " objectGUID " , NULL } ;
ZERO_STRUCT ( r - > out ) ;
sam_ctx = samdb_connect ( ) ;
if ( sam_ctx = = NULL ) {
return WERR_GENERAL_FAILURE ;
}
ret = samdb_search ( sam_ctx , mem_ctx , NULL , & res , attrs , " (objectClass=domainDNS) " ) ;
if ( ret = = - 1 ) {
samdb_close ( sam_ctx ) ;
return WERR_GENERAL_FAILURE ;
}
if ( ret = = 0 ) {
return WERR_OK ;
}
trusts = talloc_array_p ( mem_ctx , struct netr_DomainTrust , ret ) ;
if ( trusts = = NULL ) {
return WERR_NOMEM ;
}
r - > out . count = ret ;
r - > out . trusts = trusts ;
2004-05-30 17:15:15 +04:00
/* TODO: add filtering by trust_flags, and correct trust_type
and attributes */
2004-05-28 17:23:30 +04:00
for ( i = 0 ; i < ret ; i + + ) {
trusts [ i ] . netbios_name = samdb_result_string ( res [ i ] , " name " , NULL ) ;
trusts [ i ] . dns_name = samdb_result_string ( res [ i ] , " dnsDomain " , NULL ) ;
trusts [ i ] . trust_flags =
NETR_TRUST_FLAG_TREEROOT |
NETR_TRUST_FLAG_IN_FOREST |
NETR_TRUST_FLAG_PRIMARY ;
trusts [ i ] . parent_index = 0 ;
trusts [ i ] . trust_type = 2 ;
trusts [ i ] . trust_attributes = 0 ;
trusts [ i ] . sid = samdb_result_dom_sid ( mem_ctx , res [ i ] , " objectSid " ) ;
trusts [ i ] . guid = samdb_result_guid ( res [ i ] , " objectGUID " ) ;
}
return WERR_OK ;
}
/*
netr_DSRDEREGISTERDNSHOSTRECORDS
*/
static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DSRDEREGISTERDNSHOSTRECORDS * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRSERVERTRUSTPASSWORDSGET
*/
static WERROR netr_NETRSERVERTRUSTPASSWORDSGET ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRSERVERTRUSTPASSWORDSGET * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_DSRGETFORESTTRUSTINFORMATION
*/
static WERROR netr_DSRGETFORESTTRUSTINFORMATION ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_DSRGETFORESTTRUSTINFORMATION * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRGETFORESTTRUSTINFORMATION
*/
static WERROR netr_NETRGETFORESTTRUSTINFORMATION ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRGETFORESTTRUSTINFORMATION * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRLOGONSAMLOGONWITHFLAGS
*/
static WERROR netr_NETRLOGONSAMLOGONWITHFLAGS ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRLOGONSAMLOGONWITHFLAGS * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
netr_NETRSERVERGETTRUSTINFO
*/
static WERROR netr_NETRSERVERGETTRUSTINFO ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct netr_NETRSERVERGETTRUSTINFO * r )
{
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"