1996-05-04 11:50:46 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1996-05-04 11:50:46 +04:00
Test validity of smb . conf
1998-01-22 16:27:43 +03:00
Copyright ( C ) Karl Auer 1993 , 1994 - 1998
1996-05-04 11:50:46 +04:00
Extensively modified by Andrew Tridgell , 1995
2002-07-15 14:35:28 +04:00
Converted to popt by Jelmer Vernooij ( jelmer @ nl . linux . org ) , 2002
1996-05-04 11:50:46 +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 .
*/
/*
* Testbed for loadparm . c / params . c
*
* This module simply loads a specified configuration file and
* if successful , dumps it ' s contents to stdout . Note that the
* operation is performed with DEBUGLEVEL at 3.
*
* Useful for a quick ' syntax check ' of a configuration file .
*
*/
# include "includes.h"
2002-01-08 00:32:22 +03:00
extern BOOL AllowDebugChange ;
1998-05-22 05:51:14 +04:00
/***********************************************
Here we do a set of ' hard coded ' checks for bad
configuration settings .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
static int do_global_checks ( void )
1998-05-22 05:51:14 +04:00
{
1999-12-13 16:27:58 +03:00
int ret = 0 ;
1998-09-02 00:11:54 +04:00
SMB_STRUCT_STAT st ;
1999-12-13 16:27:58 +03:00
2002-03-15 12:24:56 +03:00
if ( lp_security ( ) > = SEC_DOMAIN & & ! lp_encrypted_passwords ( ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must always be set to 'true'. \n " ) ;
1999-12-13 16:27:58 +03:00
ret = 1 ;
1998-11-10 23:51:25 +03:00
}
2002-09-30 23:26:44 +04:00
if ( lp_wins_support ( ) & & lp_wins_server_list ( ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: both 'wins support = true' and 'wins server = <server list>' \
1998-05-22 05:51:14 +04:00
cannot be set in the smb . conf file . nmbd will abort with this setting . \ n " );
1999-12-13 16:27:58 +03:00
ret = 1 ;
1998-08-20 07:11:46 +04:00
}
if ( ! directory_exist ( lp_lockdir ( ) , & st ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: lock directory %s does not exist \n " ,
1998-08-20 07:11:46 +04:00
lp_lockdir ( ) ) ;
1999-12-13 16:27:58 +03:00
ret = 1 ;
1998-08-21 11:25:57 +04:00
} else if ( ( st . st_mode & 0777 ) ! = 0755 ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " WARNING: lock directory %s should have permissions 0755 for browsing to work \n " ,
1998-08-20 07:11:46 +04:00
lp_lockdir ( ) ) ;
1999-12-13 16:27:58 +03:00
ret = 1 ;
}
2002-07-15 14:35:28 +04:00
if ( ! directory_exist ( lp_piddir ( ) , & st ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: pid directory %s does not exist \n " ,
2002-07-15 14:35:28 +04:00
lp_piddir ( ) ) ;
ret = 1 ;
}
1999-12-13 16:27:58 +03:00
/*
* Password server sanity checks .
*/
2002-03-15 12:24:56 +03:00
if ( ( lp_security ( ) = = SEC_SERVER | | lp_security ( ) > = SEC_DOMAIN ) & & ! lp_passwordserver ( ) ) {
1999-12-13 16:27:58 +03:00
pstring sec_setting ;
if ( lp_security ( ) = = SEC_SERVER )
pstrcpy ( sec_setting , " server " ) ;
else if ( lp_security ( ) = = SEC_DOMAIN )
pstrcpy ( sec_setting , " domain " ) ;
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: The setting 'security=%s' requires the 'password server' parameter be set \
1999-12-13 16:27:58 +03:00
to a valid password server . \ n " , sec_setting );
ret = 1 ;
}
2001-09-20 11:27:55 +04:00
/*
2002-04-08 03:41:55 +04:00
* Check ' hosts equiv ' and ' use rhosts ' compatibility with ' hostname lookup ' value .
2001-09-20 11:27:55 +04:00
*/
if ( * lp_hosts_equiv ( ) & & ! lp_hostname_lookups ( ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: The setting 'hosts equiv = %s' requires that 'hostname lookups = yes'. \n " , lp_hosts_equiv ( ) ) ;
2001-09-20 11:27:55 +04:00
ret = 1 ;
}
1999-12-13 16:27:58 +03:00
/*
* Password chat sanity checks .
*/
if ( lp_security ( ) = = SEC_USER & & lp_unix_password_sync ( ) ) {
/*
2001-05-10 10:53:19 +04:00
* Check that we have a valid lp_passwd_program ( ) if not using pam .
1999-12-13 16:27:58 +03:00
*/
2001-05-10 10:53:19 +04:00
# ifdef WITH_PAM
if ( ! lp_pam_password_change ( ) ) {
# endif
if ( lp_passwd_program ( ) = = NULL ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \
1999-12-13 16:27:58 +03:00
parameter . \ n " );
ret = 1 ;
2001-05-10 10:53:19 +04:00
} else {
pstring passwd_prog ;
pstring truncated_prog ;
2002-11-13 02:20:50 +03:00
const char * p ;
2001-05-10 10:53:19 +04:00
pstrcpy ( passwd_prog , lp_passwd_program ( ) ) ;
p = passwd_prog ;
* truncated_prog = ' \0 ' ;
next_token ( & p , truncated_prog , NULL , sizeof ( pstring ) ) ;
if ( access ( truncated_prog , F_OK ) = = - 1 ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \
2001-05-10 10:53:19 +04:00
cannot be executed ( error was % s ) . \ n " , truncated_prog, strerror(errno) ) ;
ret = 1 ;
}
1999-12-13 16:27:58 +03:00
}
2001-05-10 10:53:19 +04:00
# ifdef WITH_PAM
1999-12-13 16:27:58 +03:00
}
2001-05-10 10:53:19 +04:00
# endif
1999-12-13 16:27:58 +03:00
if ( lp_passwd_chat ( ) = = NULL ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \
1999-12-13 16:27:58 +03:00
parameter . \ n " );
ret = 1 ;
}
/*
* Check that we have a valid script and that it hasn ' t
* been written to expect the old password .
*/
if ( lp_encrypted_passwords ( ) ) {
if ( strstr ( lp_passwd_chat ( ) , " %o " ) ! = NULL ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \
1999-12-13 16:27:58 +03:00
via the % % o substitution . With encrypted passwords this is not possible . \ n " , lp_passwd_chat() );
ret = 1 ;
}
}
}
2002-04-14 16:20:10 +04:00
if ( strlen ( lp_winbind_separator ( ) ) ! = 1 ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: the 'winbind separator' parameter must be a single character. \n " ) ;
2002-04-14 16:20:10 +04:00
ret = 1 ;
}
if ( * lp_winbind_separator ( ) = = ' + ' ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " 'winbind separator = +' might cause problems with group membership. \n " ) ;
2002-04-14 16:20:10 +04:00
}
2002-11-05 10:20:27 +03:00
if ( lp_algorithmic_rid_base ( ) < BASE_RID ) {
/* Try to prevent admin foot-shooting, we can't put algorithmic
rids below 1000 , that ' s the ' well known RIDs ' on NT */
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " 'algorithmic rid base' must be equal to or above %lu \n " , BASE_RID ) ;
2002-11-05 10:20:27 +03:00
}
if ( lp_algorithmic_rid_base ( ) & 1 ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " 'algorithmic rid base' must be even. \n " ) ;
2002-11-05 10:20:27 +03:00
}
2003-04-15 02:23:02 +04:00
# ifndef HAVE_DLOPEN
2003-04-15 20:01:14 +04:00
if ( lp_preload_modules ( ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " WARNING: 'preload modules = ' set while loading plugins not supported. \n " ) ;
2003-04-15 20:01:14 +04:00
}
2003-04-15 02:23:02 +04:00
# endif
2003-04-15 20:01:14 +04:00
2003-06-20 21:41:04 +04:00
if ( ! lp_passdb_backend ( ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ERROR: passdb backend must have a value or be left out \n " ) ;
2003-06-20 21:41:04 +04:00
}
1999-12-13 16:27:58 +03:00
return ret ;
1998-05-22 05:51:14 +04:00
}
2003-04-14 07:59:04 +04:00
int main ( int argc , const char * argv [ ] )
1999-12-13 16:27:58 +03:00
{
2002-07-15 14:35:28 +04:00
const char * config_file = dyn_CONFIGFILE ;
int s ;
static BOOL silent_mode = False ;
int ret = 0 ;
poptContext pc ;
2003-01-14 13:47:56 +03:00
static const char * term_code = " " ;
2002-08-17 18:45:04 +04:00
static char * new_local_machine = NULL ;
2002-07-15 14:35:28 +04:00
const char * cname ;
const char * caddr ;
2002-09-25 19:19:00 +04:00
static int show_defaults ;
1999-12-13 16:27:58 +03:00
2002-07-15 14:35:28 +04:00
struct poptOption long_options [ ] = {
POPT_AUTOHELP
{ " suppress-prompt " , ' s ' , POPT_ARG_VAL , & silent_mode , 1 , " Suppress prompt for enter " } ,
2002-09-25 19:19:00 +04:00
{ " verbose " , ' v ' , POPT_ARG_NONE , & show_defaults , 1 , " Show default options too " } ,
2002-07-15 14:35:28 +04:00
{ " server " , ' L ' , POPT_ARG_STRING , & new_local_machine , 0 , " Set %%L macro to servername \n " } ,
{ " encoding " , ' t ' , POPT_ARG_STRING , & term_code , 0 , " Print parameters with encoding " } ,
2003-04-14 07:59:04 +04:00
POPT_COMMON_VERSION
POPT_TABLEEND
2002-07-15 14:35:28 +04:00
} ;
1999-12-13 16:27:58 +03:00
2002-09-25 19:19:00 +04:00
pc = poptGetContext ( NULL , argc , argv , long_options ,
POPT_CONTEXT_KEEP_FIRST ) ;
2002-11-09 19:57:45 +03:00
poptSetOtherOptionHelp ( pc , " [OPTION...] <config-file> [host-name] [host-ip] " ) ;
2002-07-15 14:35:28 +04:00
2003-04-14 07:59:04 +04:00
while ( poptGetNextOpt ( pc ) ! = - 1 ) ;
2002-07-15 14:35:28 +04:00
setup_logging ( poptGetArg ( pc ) , True ) ;
if ( poptPeekArg ( pc ) )
config_file = poptGetArg ( pc ) ;
cname = poptGetArg ( pc ) ;
caddr = poptGetArg ( pc ) ;
2003-09-29 06:39:41 +04:00
if ( cname & & ! caddr ) {
printf ( " ERROR: You must specify both a machine name and an IP address. \n " ) ;
return ( 1 ) ;
}
2002-08-17 18:45:04 +04:00
if ( new_local_machine ) {
2003-03-18 14:08:24 +03:00
set_local_machine_name ( new_local_machine , True ) ;
2002-08-17 18:45:04 +04:00
}
2002-07-15 14:35:28 +04:00
2003-10-20 08:51:40 +04:00
dbf = x_stderr ;
2002-07-15 14:35:28 +04:00
DEBUGLEVEL = 2 ;
AllowDebugChange = False ;
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Load smb config files from %s \n " , config_file ) ;
2002-07-15 14:35:28 +04:00
if ( ! lp_load ( config_file , False , True , False ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Error loading services. \n " ) ;
2002-07-15 14:35:28 +04:00
return ( 1 ) ;
}
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Loaded services file OK. \n " ) ;
2002-07-15 14:35:28 +04:00
ret = do_global_checks ( ) ;
for ( s = 0 ; s < 1000 ; s + + ) {
if ( VALID_SNUM ( s ) )
2003-09-15 21:01:26 +04:00
if ( strlen ( lp_servicename ( s ) ) > 12 ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " WARNING: You have some share names that are longer than 12 characters. \n " ) ;
fprintf ( stderr , " These may not be accessible to some older clients. \n " ) ;
fprintf ( stderr , " (Eg. Windows9x, WindowsMe, and smbclient prior to Samba 3.0.) \n " ) ;
2002-07-15 14:35:28 +04:00
break ;
}
}
for ( s = 0 ; s < 1000 ; s + + ) {
if ( VALID_SNUM ( s ) ) {
2002-11-13 02:20:50 +03:00
const char * * deny_list = lp_hostsdeny ( s ) ;
const char * * allow_list = lp_hostsallow ( s ) ;
2002-07-15 14:35:28 +04:00
int i ;
if ( deny_list ) {
for ( i = 0 ; deny_list [ i ] ; i + + ) {
char * hasstar = strchr_m ( deny_list [ i ] , ' * ' ) ;
char * hasquery = strchr_m ( deny_list [ i ] , ' ? ' ) ;
if ( hasstar | | hasquery ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Invalid character %c in hosts deny list (%s) for service %s. \n " ,
2002-07-15 14:35:28 +04:00
hasstar ? * hasstar : * hasquery , deny_list [ i ] , lp_servicename ( s ) ) ;
}
}
}
if ( allow_list ) {
for ( i = 0 ; allow_list [ i ] ; i + + ) {
char * hasstar = strchr_m ( allow_list [ i ] , ' * ' ) ;
char * hasquery = strchr_m ( allow_list [ i ] , ' ? ' ) ;
if ( hasstar | | hasquery ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Invalid character %c in hosts allow list (%s) for service %s. \n " ,
2002-07-15 14:35:28 +04:00
hasstar ? * hasstar : * hasquery , allow_list [ i ] , lp_servicename ( s ) ) ;
}
}
}
if ( lp_level2_oplocks ( s ) & & ! lp_oplocks ( s ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Invalid combination of parameters for service %s. \
2002-07-15 14:35:28 +04:00
Level II oplocks can only be set if oplocks are also set . \ n " ,
lp_servicename ( s ) ) ;
}
2003-08-12 08:28:22 +04:00
if ( lp_map_hidden ( s ) & & ! ( lp_create_mask ( s ) & S_IXOTH ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Invalid combination of parameters for service %s. \
2003-08-12 08:28:22 +04:00
Map hidden can only work if create mask includes octal 01 ( S_IXOTH ) . \ n " ,
lp_servicename ( s ) ) ;
}
if ( lp_map_hidden ( s ) & & ( lp_force_create_mode ( s ) & S_IXOTH ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Invalid combination of parameters for service %s. \
2003-08-12 08:28:22 +04:00
Map hidden can only work if force create mode excludes octal 01 ( S_IXOTH ) . \ n " ,
lp_servicename ( s ) ) ;
}
if ( lp_map_system ( s ) & & ! ( lp_create_mask ( s ) & S_IXGRP ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Invalid combination of parameters for service %s. \
2003-09-08 22:41:42 +04:00
Map system can only work if create mask includes octal 010 ( S_IXGRP ) . \ n " ,
2003-08-12 08:28:22 +04:00
lp_servicename ( s ) ) ;
}
if ( lp_map_system ( s ) & & ( lp_force_create_mode ( s ) & S_IXGRP ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Invalid combination of parameters for service %s. \
2003-09-08 22:41:42 +04:00
Map system can only work if force create mode excludes octal 010 ( S_IXGRP ) . \ n " ,
2003-08-12 08:28:22 +04:00
lp_servicename ( s ) ) ;
}
2002-07-15 14:35:28 +04:00
}
}
2003-02-21 01:09:54 +03:00
if ( ! silent_mode ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Server role: " ) ;
2003-02-21 01:09:54 +03:00
switch ( lp_server_role ( ) ) {
case ROLE_STANDALONE :
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ROLE_STANDALONE \n " ) ;
2003-02-21 01:09:54 +03:00
break ;
case ROLE_DOMAIN_MEMBER :
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ROLE_DOMAIN_MEMBER \n " ) ;
2003-02-21 01:09:54 +03:00
break ;
case ROLE_DOMAIN_BDC :
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ROLE_DOMAIN_BDC \n " ) ;
2003-02-21 01:09:54 +03:00
break ;
case ROLE_DOMAIN_PDC :
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " ROLE_DOMAIN_PDC \n " ) ;
2003-02-21 01:09:54 +03:00
break ;
default :
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Unknown -- internal error? \n " ) ;
2003-02-21 01:09:54 +03:00
break ;
}
}
2002-07-15 14:35:28 +04:00
if ( ! cname ) {
if ( ! silent_mode ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Press enter to see a dump of your service definitions \n " ) ;
2002-07-15 14:35:28 +04:00
fflush ( stdout ) ;
getc ( stdin ) ;
}
2002-09-25 19:19:00 +04:00
lp_dump ( stdout , show_defaults , lp_numservices ( ) ) ;
2002-07-15 14:35:28 +04:00
}
if ( cname & & caddr ) {
/* this is totally ugly, a real `quick' hack */
for ( s = 0 ; s < 1000 ; s + + ) {
2003-09-29 06:39:41 +04:00
if ( VALID_SNUM ( s ) ) {
if ( allow_access ( lp_hostsdeny ( - 1 ) , lp_hostsallow ( - 1 ) , cname , caddr )
& & allow_access ( lp_hostsdeny ( s ) , lp_hostsallow ( s ) , cname , caddr ) ) {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Allow connection from %s (%s) to %s \n " ,
2002-07-15 14:35:28 +04:00
cname , caddr , lp_servicename ( s ) ) ;
} else {
2003-10-20 08:51:40 +04:00
fprintf ( stderr , " Deny connection from %s (%s) to %s \n " ,
2002-07-15 14:35:28 +04:00
cname , caddr , lp_servicename ( s ) ) ;
}
}
}
}
return ( ret ) ;
1996-05-04 11:50:46 +04:00
}