2001-05-07 09:03:40 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-05-07 09:03:40 +04:00
Winbind daemon - miscellaneous other functions
2002-01-10 14:28:14 +03:00
Copyright ( C ) Tim Potter 2000
Copyright ( C ) Andrew Bartlett 2002
2001-05-07 09:03:40 +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
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 "winbindd.h"
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
2001-05-07 09:03:40 +04:00
/* Check the machine account password is valid */
2001-09-04 11:13:01 +04:00
enum winbindd_result winbindd_check_machine_acct ( struct winbindd_cli_state * state )
2001-05-07 09:03:40 +04:00
{
2001-11-23 03:14:04 +03:00
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2001-05-07 09:03:40 +04:00
uchar trust_passwd [ 16 ] ;
2001-07-25 10:16:27 +04:00
int num_retries = 0 ;
2001-11-23 03:14:04 +03:00
struct cli_state * cli ;
2003-04-21 18:09:03 +04:00
uint32 sec_channel_type ;
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: check machine account \n " , ( unsigned long ) state - > pid ) ) ;
2001-05-07 09:03:40 +04:00
/* Get trust account password */
2001-07-25 10:16:27 +04:00
again :
2003-01-15 20:39:47 +03:00
if ( ! secrets_fetch_trust_account_password (
2003-04-21 18:09:03 +04:00
lp_workgroup ( ) , trust_passwd , NULL , & sec_channel_type ) ) {
2001-11-23 03:14:04 +03:00
result = NT_STATUS_INTERNAL_ERROR ;
2001-05-07 09:03:40 +04:00
goto done ;
}
2001-11-23 03:14:04 +03:00
/* This call does a cli_nt_setup_creds() which implicitly checks
the trust account password . */
2001-05-07 09:03:40 +04:00
2002-03-19 09:36:37 +03:00
/* Don't shut this down - it belongs to the connection cache code */
2003-05-27 06:28:13 +04:00
result = cm_get_netlogon_cli ( lp_workgroup ( ) , trust_passwd , sec_channel_type , True , & cli ) ;
2001-05-07 09:03:40 +04:00
2001-11-23 03:14:04 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 3 , ( " could not open handle to NETLOGON pipe \n " ) ) ;
goto done ;
}
2001-05-07 09:03:40 +04:00
2001-07-25 10:16:27 +04:00
/* There is a race condition between fetching the trust account
2002-03-19 09:36:37 +03:00
password and the periodic machine password change . So it ' s
possible that the trust account password has been changed on us .
We are returned NT_STATUS_ACCESS_DENIED if this happens . */
2001-07-25 10:16:27 +04:00
# define MAX_RETRIES 8
if ( ( num_retries < MAX_RETRIES ) & &
2001-11-23 03:14:04 +03:00
NT_STATUS_V ( result ) = = NT_STATUS_V ( NT_STATUS_ACCESS_DENIED ) ) {
2001-07-25 10:16:27 +04:00
num_retries + + ;
goto again ;
}
2001-05-07 09:03:40 +04:00
/* Pass back result code - zero for success, other values for
specific failures . */
2001-11-23 03:14:04 +03:00
DEBUG ( 3 , ( " secret is %s \n " , NT_STATUS_IS_OK ( result ) ?
" good " : " bad " ) ) ;
2001-05-07 09:03:40 +04:00
done :
2002-07-15 14:35:28 +04:00
state - > response . data . auth . nt_status = NT_STATUS_V ( result ) ;
fstrcpy ( state - > response . data . auth . nt_status_string , nt_errstr ( result ) ) ;
fstrcpy ( state - > response . data . auth . error_string , nt_errstr ( result ) ) ;
state - > response . data . auth . pam_error = nt_status_to_pam ( result ) ;
DEBUG ( NT_STATUS_IS_OK ( result ) ? 5 : 2 , ( " Checking the trust account password returned %s \n " ,
state - > response . data . auth . nt_status_string ) ) ;
2001-11-23 03:14:04 +03:00
2002-07-15 14:35:28 +04:00
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
2001-05-07 09:03:40 +04:00
}
enum winbindd_result winbindd_list_trusted_domains ( struct winbindd_cli_state
* state )
{
struct winbindd_domain * domain ;
int total_entries = 0 , extra_data_len = 0 ;
2001-08-12 21:30:01 +04:00
char * ted , * extra_data = NULL ;
2001-05-07 09:03:40 +04:00
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: list trusted domains \n " , ( unsigned long ) state - > pid ) ) ;
2001-05-07 09:03:40 +04:00
2002-01-11 08:33:45 +03:00
/* We need to refresh the trusted domain list as the domains may
have changed since we last looked . There may be a sequence
number or something we should use but I haven ' t found it yet . */
2001-11-15 06:29:00 +03:00
2003-01-15 20:39:47 +03:00
if ( ! init_domain_list ( ) ) {
DEBUG ( 1 , ( " winbindd_list_trusted_domains: could not "
" refresh trusted domain list \n " ) ) ;
return WINBINDD_ERROR ;
}
2002-01-11 08:33:45 +03:00
for ( domain = domain_list ( ) ; domain ; domain = domain - > next ) {
2001-05-07 09:03:40 +04:00
/* Skip own domain */
2001-11-23 14:18:20 +03:00
if ( strequal ( domain - > name , lp_workgroup ( ) ) ) continue ;
2001-05-07 09:03:40 +04:00
/* Add domain to list */
total_entries + + ;
2001-08-12 21:30:01 +04:00
ted = Realloc ( extra_data , sizeof ( fstring ) *
2001-11-23 03:14:04 +03:00
total_entries ) ;
2001-05-07 09:03:40 +04:00
2001-08-12 21:30:01 +04:00
if ( ! ted ) {
DEBUG ( 0 , ( " winbindd_list_trusted_domains: failed to enlarge buffer! \n " ) ) ;
2001-09-17 08:52:45 +04:00
SAFE_FREE ( extra_data ) ;
2001-08-12 21:30:01 +04:00
return WINBINDD_ERROR ;
2001-11-23 03:14:04 +03:00
} else
extra_data = ted ;
2001-05-07 09:03:40 +04:00
memcpy ( & extra_data [ extra_data_len ] , domain - > name ,
strlen ( domain - > name ) ) ;
extra_data_len + = strlen ( domain - > name ) ;
extra_data [ extra_data_len + + ] = ' , ' ;
}
if ( extra_data ) {
2001-11-23 03:14:04 +03:00
if ( extra_data_len > 1 )
extra_data [ extra_data_len - 1 ] = ' \0 ' ;
2001-05-07 09:03:40 +04:00
state - > response . extra_data = extra_data ;
state - > response . length + = extra_data_len ;
}
return WINBINDD_OK ;
}
2002-01-10 13:23:54 +03:00
2002-01-31 14:49:29 +03:00
enum winbindd_result winbindd_show_sequence ( struct winbindd_cli_state * state )
{
struct winbindd_domain * domain ;
char * extra_data = NULL ;
2003-08-11 02:01:11 +04:00
const char * which_domain ;
2002-01-31 14:49:29 +03:00
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: show sequence \n " , ( unsigned long ) state - > pid ) ) ;
2002-01-31 14:49:29 +03:00
2003-08-11 02:01:11 +04:00
/* Ensure null termination */
state - > request . domain_name [ sizeof ( state - > request . domain_name ) - 1 ] = ' \0 ' ;
which_domain = state - > request . domain_name ;
2002-01-31 14:49:29 +03:00
extra_data = strdup ( " " ) ;
/* this makes for a very simple data format, and is easily parsable as well
if that is ever needed */
for ( domain = domain_list ( ) ; domain ; domain = domain - > next ) {
char * s ;
2003-08-11 02:01:11 +04:00
/* if we have a domain name restricting the request and this
one in the list doesn ' t match , then just bypass the remainder
of the loop */
if ( * which_domain & & ! strequal ( which_domain , domain - > name ) )
continue ;
2002-01-31 14:49:29 +03:00
domain - > methods - > sequence_number ( domain , & domain - > sequence_number ) ;
2002-03-06 22:48:09 +03:00
if ( DOM_SEQUENCE_NONE = = ( unsigned ) domain - > sequence_number ) {
asprintf ( & s , " %s%s : DISCONNECTED \n " , extra_data ,
domain - > name ) ;
2002-03-12 21:47:27 +03:00
} else {
asprintf ( & s , " %s%s : %u \n " , extra_data ,
domain - > name , ( unsigned ) domain - > sequence_number ) ;
2002-03-06 22:48:09 +03:00
}
2002-01-31 14:49:29 +03:00
free ( extra_data ) ;
extra_data = s ;
}
state - > response . extra_data = extra_data ;
2002-11-19 01:49:02 +03:00
/* must add one to length to copy the 0 for string termination */
state - > response . length + = strlen ( extra_data ) + 1 ;
2002-01-31 14:49:29 +03:00
return WINBINDD_OK ;
}
2002-01-10 13:23:54 +03:00
enum winbindd_result winbindd_ping ( struct winbindd_cli_state
* state )
{
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: ping \n " , ( unsigned long ) state - > pid ) ) ;
2002-01-10 13:23:54 +03:00
return WINBINDD_OK ;
}
2002-01-10 14:28:14 +03:00
/* List various tidbits of information */
enum winbindd_result winbindd_info ( struct winbindd_cli_state * state )
{
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: request misc info \n " , ( unsigned long ) state - > pid ) ) ;
2002-01-10 14:28:14 +03:00
state - > response . data . info . winbind_separator = * lp_winbind_separator ( ) ;
fstrcpy ( state - > response . data . info . samba_version , VERSION ) ;
return WINBINDD_OK ;
}
2002-01-26 12:52:55 +03:00
/* Tell the client the current interface version */
2002-01-10 14:28:14 +03:00
enum winbindd_result winbindd_interface_version ( struct winbindd_cli_state * state )
{
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: request interface version \n " , ( unsigned long ) state - > pid ) ) ;
2002-01-10 14:28:14 +03:00
state - > response . data . interface_version = WINBIND_INTERFACE_VERSION ;
return WINBINDD_OK ;
}
2002-01-26 12:52:55 +03:00
/* What domain are we a member of? */
enum winbindd_result winbindd_domain_name ( struct winbindd_cli_state * state )
{
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: request domain name \n " , ( unsigned long ) state - > pid ) ) ;
2002-01-26 12:52:55 +03:00
fstrcpy ( state - > response . data . domain_name , lp_workgroup ( ) ) ;
return WINBINDD_OK ;
}
2003-01-28 15:07:02 +03:00
/* What's my name again? */
enum winbindd_result winbindd_netbios_name ( struct winbindd_cli_state * state )
{
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: request netbios name \n " , ( unsigned long ) state - > pid ) ) ;
2003-01-28 15:07:02 +03:00
fstrcpy ( state - > response . data . netbios_name , global_myname ( ) ) ;
return WINBINDD_OK ;
}
2003-03-24 12:54:13 +03:00
2003-04-21 18:09:03 +04:00
/* Where can I find the privilaged pipe? */
2003-03-24 12:54:13 +03:00
enum winbindd_result winbindd_priv_pipe_dir ( struct winbindd_cli_state * state )
{
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: request location of privileged pipe \n " , ( unsigned long ) state - > pid ) ) ;
2003-03-24 12:54:13 +03:00
state - > response . extra_data = strdup ( get_winbind_priv_pipe_dir ( ) ) ;
if ( ! state - > response . extra_data )
return WINBINDD_ERROR ;
/* must add one to length to copy the 0 for string termination */
state - > response . length + = strlen ( ( char * ) state - > response . extra_data ) + 1 ;
return WINBINDD_OK ;
}