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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1996-05-04 11:50:46 +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 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1996-05-04 11:50:46 +04:00
*/
/*
* 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"
2007-10-19 04:40:25 +04:00
extern bool AllowDebugChange ;
2002-01-08 00:32:22 +03:00
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 ;
}
2005-12-01 17:46:56 +03:00
if ( lp_passdb_expand_explicit ( ) ) {
fprintf ( stderr , " WARNING: passdb expand explicit = yes is "
" deprecated \n " ) ;
}
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 ( ) ) {
2007-12-04 05:48:41 +03:00
const char * sec_setting ;
1999-12-13 16:27:58 +03:00
if ( lp_security ( ) = = SEC_SERVER )
2007-12-04 05:48:41 +03:00
sec_setting = " server " ;
1999-12-13 16:27:58 +03:00
else if ( lp_security ( ) = = SEC_DOMAIN )
2007-12-04 05:48:41 +03:00
sec_setting = " domain " ;
else
sec_setting = " " ;
1999-12-13 16:27:58 +03:00
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 ;
}
/*
* 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
2008-03-18 17:49:31 +03:00
if ( ( lp_passwd_program ( ) = = NULL ) | |
( strlen ( lp_passwd_program ( ) ) = = 0 ) )
{
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 {
2007-12-04 05:48:41 +03:00
const char * passwd_prog ;
char * truncated_prog = NULL ;
2002-11-13 02:20:50 +03:00
const char * p ;
2001-05-10 10:53:19 +04:00
2007-12-04 05:48:41 +03:00
passwd_prog = lp_passwd_program ( ) ;
2001-05-10 10:53:19 +04:00
p = passwd_prog ;
2007-12-04 05:48:41 +03:00
next_token_talloc ( talloc_tos ( ) ,
& p ,
& truncated_prog , NULL ) ;
if ( truncated_prog & & 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 ;
}
2008-03-18 17:33:25 +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 ;
2008-03-18 17:50:27 +03:00
}
if ( ( lp_passwd_program ( ) ! = NULL ) & &
( strlen ( lp_passwd_program ( ) ) > 0 ) )
{
/* check if there's a %u parameter present */
if ( strstr_m ( lp_passwd_program ( ) , " %u " ) = = NULL ) {
fprintf ( stderr , " ERROR: the 'passwd program' (%s) requires a '%%u' parameter. \n " , lp_passwd_program ( ) ) ;
ret = 1 ;
}
1999-12-13 16:27:58 +03:00
}
/*
* Check that we have a valid script and that it hasn ' t
* been written to expect the old password .
*/
if ( lp_encrypted_passwords ( ) ) {
2004-03-09 03:17:14 +03:00
if ( strstr_m ( 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
}
2007-09-04 17:21:24 +04:00
if ( lp_os_level ( ) > 255 ) {
fprintf ( stderr , " WARNING: Maximum value for 'os level' is 255! \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
{
2007-12-10 22:30:37 +03:00
const char * config_file = get_dyn_CONFIGFILE ( ) ;
2002-07-15 14:35:28 +04:00
int s ;
2007-10-19 22:38:36 +04:00
static int silent_mode = False ;
static int show_all_parameters = False ;
2002-07-15 14:35:28 +04:00
int ret = 0 ;
poptContext pc ;
2003-01-14 13:47:56 +03:00
static const char * term_code = " " ;
2005-06-12 20:00:29 +04:00
static char * parameter_name = NULL ;
2005-09-30 21:13:37 +04:00
static const char * section_name = NULL ;
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 " } ,
2005-06-12 20:00:29 +04:00
{ " show-all-parameters " , ' \0 ' , POPT_ARG_VAL , & show_all_parameters , True , " Show the parameters, type, possible values " } ,
{ " parameter-name " , ' \0 ' , POPT_ARG_STRING , & parameter_name , 0 , " Limit testparm to a named parameter " } ,
{ " section-name " , ' \0 ' , POPT_ARG_STRING , & section_name , 0 , " Limit testparm to a named section " } ,
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
2007-08-31 13:15:57 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2005-12-29 01:48:54 +03:00
load_case_tables ( ) ;
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
2005-06-12 20:00:29 +04:00
if ( show_all_parameters ) {
show_parameter_list ( ) ;
exit ( 0 ) ;
}
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
2006-01-29 01:53:04 +03:00
if ( ! lp_load ( config_file , False , True , False , True ) ) {
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 ) ) ;
}
2005-02-02 19:22:59 +03:00
# ifdef HAVE_CUPS
if ( lp_printing ( s ) = = PRINT_CUPS & & * ( lp_printcommand ( s ) ) ! = ' \0 ' ) {
fprintf ( stderr , " Warning: Service %s defines a print command, but \
print command parameter is ignored when using CUPS libraries . \ n " ,
lp_servicename ( s ) ) ;
}
# endif
2002-07-15 14:35:28 +04:00
}
}
2003-02-21 01:09:54 +03:00
2006-01-25 18:43:15 +03:00
if ( ! section_name & & ! parameter_name ) {
2005-12-22 02:26:23 +03:00
fprintf ( stderr , " Server role: %s \n " , server_role_str ( lp_server_role ( ) ) ) ;
2003-02-21 01:09:54 +03:00
}
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 ) ;
}
2005-06-12 20:00:29 +04:00
if ( parameter_name | | section_name ) {
2007-10-19 04:40:25 +04:00
bool isGlobal = False ;
2005-06-12 20:00:29 +04:00
s = GLOBAL_SECTION_SNUM ;
if ( ! section_name ) {
section_name = GLOBAL_NAME ;
isGlobal = True ;
} else if ( ( isGlobal = ! strwicmp ( section_name , GLOBAL_NAME ) ) = = 0 & &
( s = lp_servicenumber ( section_name ) ) = = - 1 ) {
fprintf ( stderr , " Unknown section %s \n " ,
section_name ) ;
return ( 1 ) ;
}
if ( parameter_name ) {
if ( ! dump_a_parameter ( s , parameter_name , stdout , isGlobal ) ) {
fprintf ( stderr , " Parameter %s unknown for section %s \n " ,
parameter_name , section_name ) ;
return ( 1 ) ;
}
} else {
if ( isGlobal = = True )
lp_dump ( stdout , show_defaults , 0 ) ;
else
lp_dump_one ( stdout , show_defaults , s ) ;
}
return ( ret ) ;
}
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 ) ) ;
}
}
}
}
2007-08-31 13:15:57 +04:00
TALLOC_FREE ( frame ) ;
2002-07-15 14:35:28 +04:00
return ( ret ) ;
1996-05-04 11:50:46 +04:00
}
2004-10-06 02:18:32 +04:00