2011-10-06 12:34:50 +04:00
/*
Unix SMB / CIFS implementation .
Parameter loading functions
Copyright ( C ) Karl Auer 1993 - 1998
Largely re - written by Andrew Tridgell , September 1994
Copyright ( C ) Simo Sorce 2001
Copyright ( C ) Alexander Bokovoy 2002
Copyright ( C ) Stefan ( metze ) Metzmacher 2002
Copyright ( C ) Jim McDonough ( jmcd @ us . ibm . com ) 2003.
Copyright ( C ) James Myers 2003 < myersjj @ samba . org >
Copyright ( C ) Jelmer Vernooij < jelmer @ samba . org > 2007
2012-07-18 07:39:58 +04:00
Copyright ( C ) Andrew Bartlett 2011 - 2012
2011-10-06 12:34:50 +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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
/*
* Load parameters .
*
* This module provides suitable callback functions for the params
* module . It builds the internal table of service details which is
* then used by the rest of the server .
*
* To add a parameter :
*
* 1 ) add it to the global or service structure definition
* 2 ) add it to the parm_table
* 3 ) add it to the list of available functions ( eg : using FN_GLOBAL_STRING ( ) )
* 4 ) If it ' s a global then initialise it in init_globals . If a local
* ( ie . service ) parameter then initialise it in the sDefault structure
*
*
* Notes :
* The configuration file is processed sequentially for speed . It is NOT
* accessed randomly as happens in ' real ' Windows . For this reason , there
* is a fair bit of sequence - dependent code here - ie . , code which assumes
* that certain things happen before others . In particular , the code which
* happens at the boundary between sections is delicately poised , so be
* careful !
*
*/
# include "includes.h"
# include "version.h"
# include "dynconfig/dynconfig.h"
# include "system/time.h"
# include "system/locale.h"
# include "system/network.h" /* needed for TCP_NODELAY */
# include "../lib/util/dlinklist.h"
# include "lib/param/param.h"
# include "lib/param/loadparm.h"
# include "auth/gensec/gensec.h"
2012-06-15 06:34:28 +04:00
# include "lib/param/s3_param.h"
2011-10-06 12:34:50 +04:00
# include "lib/util/bitmap.h"
# include "libcli/smb/smb_constants.h"
2014-03-26 18:06:08 +04:00
# include "tdb.h"
2015-03-01 10:04:00 +03:00
# include "librpc/gen_ndr/nbt.h"
2011-10-06 12:34:50 +04:00
# define standard_sub_basic talloc_strdup
2012-06-15 06:34:28 +04:00
# include "lib/param/param_global.h"
2011-10-06 12:34:50 +04:00
struct loadparm_service * lpcfg_default_service ( struct loadparm_context * lp_ctx )
{
return lp_ctx - > sDefault ;
}
/**
* Convenience routine to grab string parameters into temporary memory
* and run standard_sub_basic on them .
*
* The buffers can be written to by
* callers without affecting the source string .
*/
2014-02-14 01:23:36 +04:00
static const char * lpcfg_string ( const char * s )
2011-10-06 12:34:50 +04:00
{
#if 0 /* until REWRITE done to make thread-safe */
size_t len = s ? strlen ( s ) : 0 ;
char * ret ;
# endif
/* The follow debug is useful for tracking down memory problems
especially if you have an inner loop that is calling a lp_ * ( )
function that returns a string . Perhaps this debug should be
present all the time ? */
#if 0
2014-02-14 01:23:36 +04:00
DEBUG ( 10 , ( " lpcfg_string(%s) \n " , s ) ) ;
2011-10-06 12:34:50 +04:00
# endif
#if 0 /* until REWRITE done to make thread-safe */
if ( ! lp_talloc )
lp_talloc = talloc_init ( " lp_talloc " ) ;
ret = talloc_array ( lp_talloc , char , len + 100 ) ; /* leave room for substitution */
if ( ! ret )
return NULL ;
if ( ! s )
* ret = 0 ;
else
strlcpy ( ret , s , len ) ;
if ( trim_string ( ret , " \" " , " \" " ) ) {
if ( strchr ( ret , ' " ' ) ! = NULL )
strlcpy ( ret , s , len ) ;
}
standard_sub_basic ( ret , len + 100 ) ;
return ( ret ) ;
# endif
return s ;
}
/*
In this section all the functions that are used to access the
parameters from the rest of the program are defined
*/
/*
* the creation of separate lpcfg_ * ( ) and lp_ * ( ) functions is to allow
* for code compatibility between existing Samba4 and Samba3 code .
*/
/* this global context supports the lp_*() function varients */
static struct loadparm_context * global_loadparm_context ;
2013-10-14 06:34:40 +04:00
# define FN_GLOBAL_STRING(fn_name,var_name) \
2014-01-17 01:30:37 +04:00
_PUBLIC_ char * lpcfg_ # # fn_name ( struct loadparm_context * lp_ctx , TALLOC_CTX * ctx ) { \
2013-10-14 06:34:40 +04:00
if ( lp_ctx = = NULL ) return NULL ; \
if ( lp_ctx - > s3_fns ) { \
2014-01-24 06:38:59 +04:00
return lp_ctx - > globals - > var_name ? lp_ctx - > s3_fns - > lp_string ( ctx , lp_ctx - > globals - > var_name ) : talloc_strdup ( ctx , " " ) ; \
2013-10-14 06:34:40 +04:00
} \
2014-02-14 01:23:36 +04:00
return lp_ctx - > globals - > var_name ? talloc_strdup ( ctx , lpcfg_string ( lp_ctx - > globals - > var_name ) ) : talloc_strdup ( ctx , " " ) ; \
2013-10-14 06:34:40 +04:00
}
# define FN_GLOBAL_CONST_STRING(fn_name,var_name) \
2011-10-06 12:34:50 +04:00
_PUBLIC_ const char * lpcfg_ # # fn_name ( struct loadparm_context * lp_ctx ) { \
if ( lp_ctx = = NULL ) return NULL ; \
2014-02-14 01:23:36 +04:00
return lp_ctx - > globals - > var_name ? lpcfg_string ( lp_ctx - > globals - > var_name ) : " " ; \
2011-10-06 12:34:50 +04:00
}
# define FN_GLOBAL_LIST(fn_name,var_name) \
_PUBLIC_ const char * * lpcfg_ # # fn_name ( struct loadparm_context * lp_ctx ) { \
if ( lp_ctx = = NULL ) return NULL ; \
return lp_ctx - > globals - > var_name ; \
}
# define FN_GLOBAL_BOOL(fn_name,var_name) \
_PUBLIC_ bool lpcfg_ # # fn_name ( struct loadparm_context * lp_ctx ) { \
if ( lp_ctx = = NULL ) return false ; \
return lp_ctx - > globals - > var_name ; \
}
# define FN_GLOBAL_INTEGER(fn_name,var_name) \
_PUBLIC_ int lpcfg_ # # fn_name ( struct loadparm_context * lp_ctx ) { \
return lp_ctx - > globals - > var_name ; \
}
/* Local parameters don't need the ->s3_fns because the struct
* loadparm_service is shared and lpcfg_service ( ) checks the - > s3_fns
* hook */
# define FN_LOCAL_STRING(fn_name,val) \
2014-01-17 01:30:37 +04:00
_PUBLIC_ char * lpcfg_ # # fn_name ( struct loadparm_service * service , \
struct loadparm_service * sDefault , TALLOC_CTX * ctx ) { \
2014-02-14 01:23:36 +04:00
return ( talloc_strdup ( ctx , lpcfg_string ( ( const char * ) ( ( service ! = NULL & & service - > val ! = NULL ) ? service - > val : sDefault - > val ) ) ) ) ; \
2014-01-17 01:30:37 +04:00
}
# define FN_LOCAL_CONST_STRING(fn_name,val) \
2011-10-06 12:34:50 +04:00
_PUBLIC_ const char * lpcfg_ # # fn_name ( struct loadparm_service * service , \
struct loadparm_service * sDefault ) { \
2014-01-17 01:30:37 +04:00
return ( ( const char * ) ( ( service ! = NULL & & service - > val ! = NULL ) ? service - > val : sDefault - > val ) ) ; \
2011-10-06 12:34:50 +04:00
}
# define FN_LOCAL_LIST(fn_name,val) \
_PUBLIC_ const char * * lpcfg_ # # fn_name ( struct loadparm_service * service , \
struct loadparm_service * sDefault ) { \
return ( const char * * ) ( service ! = NULL & & service - > val ! = NULL ? service - > val : sDefault - > val ) ; \
}
# define FN_LOCAL_PARM_BOOL(fn_name, val) FN_LOCAL_BOOL(fn_name, val)
# define FN_LOCAL_BOOL(fn_name,val) \
_PUBLIC_ bool lpcfg_ # # fn_name ( struct loadparm_service * service , \
struct loadparm_service * sDefault ) { \
return ( ( service ! = NULL ) ? service - > val : sDefault - > val ) ; \
}
# define FN_LOCAL_INTEGER(fn_name,val) \
_PUBLIC_ int lpcfg_ # # fn_name ( struct loadparm_service * service , \
struct loadparm_service * sDefault ) { \
return ( ( service ! = NULL ) ? service - > val : sDefault - > val ) ; \
}
# define FN_LOCAL_PARM_INTEGER(fn_name, val) FN_LOCAL_INTEGER(fn_name, val)
2013-10-14 06:33:20 +04:00
# define FN_LOCAL_PARM_CHAR(fn_name,val) \
2011-10-06 12:34:50 +04:00
_PUBLIC_ char lpcfg_ # # fn_name ( struct loadparm_service * service , \
struct loadparm_service * sDefault ) { \
return ( ( service ! = NULL ) ? service - > val : sDefault - > val ) ; \
}
# include "lib/param/param_functions.c"
2014-01-14 08:53:49 +04:00
/* These functions cannot be auto-generated */
FN_LOCAL_BOOL ( autoloaded , autoloaded )
FN_GLOBAL_CONST_STRING ( dnsdomain , dnsdomain )
2011-10-06 12:34:50 +04:00
/* local prototypes */
2014-02-19 09:03:57 +04:00
static struct loadparm_service * lpcfg_getservicebyname ( struct loadparm_context * lp_ctx ,
2011-10-06 12:34:50 +04:00
const char * pszServiceName ) ;
static bool do_section ( const char * pszSectionName , void * ) ;
2014-03-14 01:27:54 +04:00
static bool set_variable_helper ( TALLOC_CTX * mem_ctx , int parmnum , void * parm_ptr ,
const char * pszParmName , const char * pszParmValue ) ;
2014-03-20 03:57:22 +04:00
static bool lp_do_parameter_parametric ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service ,
const char * pszParmName ,
const char * pszParmValue , int flags ) ;
2011-10-06 12:34:50 +04:00
2014-02-25 08:12:14 +04:00
/* The following are helper functions for parametrical options support. */
2011-10-06 12:34:50 +04:00
/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
/* Actual parametrical functions are quite simple */
2014-02-25 07:58:21 +04:00
struct parmlist_entry * get_parametric_helper ( struct loadparm_service * service ,
const char * type , const char * option ,
struct parmlist_entry * global_opts )
{
2014-11-26 23:35:27 +03:00
size_t type_len = strlen ( type ) ;
size_t option_len = strlen ( option ) ;
char param_key [ type_len + option_len + 2 ] ;
2014-02-25 07:58:21 +04:00
struct parmlist_entry * data = NULL ;
2014-11-26 23:35:27 +03:00
snprintf ( param_key , sizeof ( param_key ) , " %s:%s " , type , option ) ;
2014-02-25 07:58:21 +04:00
/*
* Try to fetch the option from the data .
*/
if ( service ! = NULL ) {
data = service - > param_opt ;
while ( data ! = NULL ) {
if ( strwicmp ( data - > key , param_key ) = = 0 ) {
return data ;
}
data = data - > next ;
}
}
/*
* Fall back to fetching from the globals .
*/
data = global_opts ;
while ( data ! = NULL ) {
if ( strwicmp ( data - > key , param_key ) = = 0 ) {
return data ;
}
data = data - > next ;
}
return NULL ;
}
2011-10-06 12:34:50 +04:00
const char * lpcfg_get_parametric ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service ,
const char * type , const char * option )
{
struct parmlist_entry * data ;
if ( lp_ctx = = NULL )
return NULL ;
2014-02-25 08:02:52 +04:00
data = get_parametric_helper ( service ,
type , option , lp_ctx - > globals - > param_opt ) ;
2011-10-06 12:34:50 +04:00
2014-02-25 08:02:52 +04:00
if ( data = = NULL ) {
return NULL ;
} else {
return data - > value ;
2014-02-25 07:36:57 +04:00
}
2011-10-06 12:34:50 +04:00
}
/**
* convenience routine to return int parameters .
*/
2014-02-21 06:13:58 +04:00
int lp_int ( const char * s )
2011-10-06 12:34:50 +04:00
{
2014-02-21 06:13:58 +04:00
if ( ! s | | ! * s ) {
2011-10-06 12:34:50 +04:00
DEBUG ( 0 , ( " lp_int(%s): is called with NULL! \n " , s ) ) ;
return - 1 ;
}
return strtol ( s , NULL , 0 ) ;
}
/**
* convenience routine to return unsigned long parameters .
*/
2014-02-21 06:16:26 +04:00
unsigned long lp_ulong ( const char * s )
2011-10-06 12:34:50 +04:00
{
2014-02-21 06:16:26 +04:00
if ( ! s | | ! * s ) {
2012-04-19 18:58:39 +04:00
DEBUG ( 0 , ( " lp_ulong(%s): is called with NULL! \n " , s ) ) ;
2011-10-06 12:34:50 +04:00
return - 1 ;
}
return strtoul ( s , NULL , 0 ) ;
}
2012-04-19 19:00:45 +04:00
/**
* convenience routine to return unsigned long parameters .
*/
static long lp_long ( const char * s )
{
if ( ! s ) {
DEBUG ( 0 , ( " lp_long(%s): is called with NULL! \n " , s ) ) ;
return - 1 ;
}
return strtol ( s , NULL , 0 ) ;
}
2011-10-06 12:34:50 +04:00
/**
* convenience routine to return unsigned long parameters .
*/
static double lp_double ( const char * s )
{
if ( ! s ) {
DEBUG ( 0 , ( " lp_double(%s): is called with NULL! \n " , s ) ) ;
return - 1 ;
}
return strtod ( s , NULL ) ;
}
/**
* convenience routine to return boolean parameters .
*/
2014-02-21 06:18:33 +04:00
bool lp_bool ( const char * s )
2011-10-06 12:34:50 +04:00
{
bool ret = false ;
2014-02-21 06:18:33 +04:00
if ( ! s | | ! * s ) {
2011-10-06 12:34:50 +04:00
DEBUG ( 0 , ( " lp_bool(%s): is called with NULL! \n " , s ) ) ;
return false ;
}
if ( ! set_boolean ( s , & ret ) ) {
DEBUG ( 0 , ( " lp_bool(%s): value is not boolean! \n " , s ) ) ;
return false ;
}
return ret ;
}
/**
* Return parametric option from a given service . Type is a part of option before ' : '
* Parametric option has following syntax : ' Type : option = value '
* Returned value is allocated in ' lp_talloc ' context
*/
const char * lpcfg_parm_string ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service , const char * type ,
const char * option )
{
const char * value = lpcfg_get_parametric ( lp_ctx , service , type , option ) ;
if ( value )
2014-02-14 01:23:36 +04:00
return lpcfg_string ( value ) ;
2011-10-06 12:34:50 +04:00
return NULL ;
}
/**
* Return parametric option from a given service . Type is a part of option before ' : '
* Parametric option has following syntax : ' Type : option = value '
* Returned value is allocated in ' lp_talloc ' context
*/
const char * * lpcfg_parm_string_list ( TALLOC_CTX * mem_ctx ,
struct loadparm_context * lp_ctx ,
struct loadparm_service * service ,
const char * type ,
const char * option , const char * separator )
{
const char * value = lpcfg_get_parametric ( lp_ctx , service , type , option ) ;
2014-02-26 11:07:47 +04:00
if ( value ! = NULL ) {
char * * l = str_list_make ( mem_ctx , value , separator ) ;
return discard_const_p ( const char * , l ) ;
}
2011-10-06 12:34:50 +04:00
return NULL ;
}
/**
* Return parametric option from a given service . Type is a part of option before ' : '
* Parametric option has following syntax : ' Type : option = value '
*/
int lpcfg_parm_int ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service , const char * type ,
const char * option , int default_v )
{
const char * value = lpcfg_get_parametric ( lp_ctx , service , type , option ) ;
if ( value )
return lp_int ( value ) ;
return default_v ;
}
/**
* Return parametric option from a given service . Type is a part of
* option before ' : ' .
* Parametric option has following syntax : ' Type : option = value ' .
*/
int lpcfg_parm_bytes ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service , const char * type ,
const char * option , int default_v )
{
uint64_t bval ;
const char * value = lpcfg_get_parametric ( lp_ctx , service , type , option ) ;
if ( value & & conv_str_size_error ( value , & bval ) ) {
if ( bval < = INT_MAX ) {
return ( int ) bval ;
}
}
return default_v ;
}
/**
* Return parametric option from a given service .
* Type is a part of option before ' : '
* Parametric option has following syntax : ' Type : option = value '
*/
unsigned long lpcfg_parm_ulong ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service , const char * type ,
const char * option , unsigned long default_v )
{
const char * value = lpcfg_get_parametric ( lp_ctx , service , type , option ) ;
if ( value )
return lp_ulong ( value ) ;
return default_v ;
}
2012-04-19 19:00:45 +04:00
long lpcfg_parm_long ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service , const char * type ,
const char * option , long default_v )
{
const char * value = lpcfg_get_parametric ( lp_ctx , service , type , option ) ;
if ( value )
return lp_long ( value ) ;
return default_v ;
}
2011-10-06 12:34:50 +04:00
double lpcfg_parm_double ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service , const char * type ,
const char * option , double default_v )
{
const char * value = lpcfg_get_parametric ( lp_ctx , service , type , option ) ;
if ( value ! = NULL )
return lp_double ( value ) ;
return default_v ;
}
/**
* Return parametric option from a given service . Type is a part of option before ' : '
* Parametric option has following syntax : ' Type : option = value '
*/
bool lpcfg_parm_bool ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service , const char * type ,
const char * option , bool default_v )
{
const char * value = lpcfg_get_parametric ( lp_ctx , service , type , option ) ;
if ( value ! = NULL )
return lp_bool ( value ) ;
return default_v ;
}
/**
* Set a string value , deallocating any existing space , and allocing the space
* for the string
*/
2014-02-21 07:09:01 +04:00
bool lpcfg_string_set ( TALLOC_CTX * mem_ctx , char * * dest , const char * src )
2011-10-06 12:34:50 +04:00
{
talloc_free ( * dest ) ;
if ( src = = NULL )
src = " " ;
* dest = talloc_strdup ( mem_ctx , src ) ;
if ( ( * dest ) = = NULL ) {
DEBUG ( 0 , ( " Out of memory in string_set \n " ) ) ;
return false ;
}
return true ;
}
/**
* Set a string value , deallocating any existing space , and allocing the space
* for the string
*/
2014-05-08 04:10:53 +04:00
bool lpcfg_string_set_upper ( TALLOC_CTX * mem_ctx , char * * dest , const char * src )
2011-10-06 12:34:50 +04:00
{
talloc_free ( * dest ) ;
if ( src = = NULL )
src = " " ;
* dest = strupper_talloc ( mem_ctx , src ) ;
if ( ( * dest ) = = NULL ) {
DEBUG ( 0 , ( " Out of memory in string_set_upper \n " ) ) ;
return false ;
}
return true ;
}
/**
* Add a new service to the services array initialising it with the given
* service .
*/
struct loadparm_service * lpcfg_add_service ( struct loadparm_context * lp_ctx ,
const struct loadparm_service * pservice ,
const char * name )
{
int i ;
int num_to_alloc = lp_ctx - > iNumServices + 1 ;
struct parmlist_entry * data , * pdata ;
2014-07-11 06:01:33 +04:00
if ( lp_ctx - > s3_fns ! = NULL ) {
smb_panic ( " Add a service should not be called on an s3 loadparm ctx " ) ;
}
2011-10-06 12:34:50 +04:00
if ( pservice = = NULL ) {
pservice = lp_ctx - > sDefault ;
}
/* it might already exist */
if ( name ) {
2014-02-19 09:03:57 +04:00
struct loadparm_service * service = lpcfg_getservicebyname ( lp_ctx ,
2011-10-06 12:34:50 +04:00
name ) ;
if ( service ! = NULL ) {
/* Clean all parametric options for service */
/* They will be added during parsing again */
data = service - > param_opt ;
while ( data ) {
pdata = data - > next ;
talloc_free ( data ) ;
data = pdata ;
}
service - > param_opt = NULL ;
return service ;
}
}
/* find an invalid one */
for ( i = 0 ; i < lp_ctx - > iNumServices ; i + + )
if ( lp_ctx - > services [ i ] = = NULL )
break ;
/* if not, then create one */
if ( i = = lp_ctx - > iNumServices ) {
struct loadparm_service * * tsp ;
tsp = talloc_realloc ( lp_ctx , lp_ctx - > services , struct loadparm_service * , num_to_alloc ) ;
if ( ! tsp ) {
DEBUG ( 0 , ( " lpcfg_add_service: failed to enlarge services! \n " ) ) ;
return NULL ;
} else {
lp_ctx - > services = tsp ;
lp_ctx - > services [ lp_ctx - > iNumServices ] = NULL ;
}
lp_ctx - > iNumServices + + ;
}
2014-02-18 04:26:22 +04:00
lp_ctx - > services [ i ] = talloc_zero ( lp_ctx - > services , struct loadparm_service ) ;
2011-10-06 12:34:50 +04:00
if ( lp_ctx - > services [ i ] = = NULL ) {
DEBUG ( 0 , ( " lpcfg_add_service: out of memory! \n " ) ) ;
return NULL ;
}
2014-02-18 04:26:22 +04:00
copy_service ( lp_ctx - > services [ i ] , pservice , NULL ) ;
2011-10-06 12:34:50 +04:00
if ( name ! = NULL )
2011-10-09 16:23:05 +04:00
lpcfg_string_set ( lp_ctx - > services [ i ] , & lp_ctx - > services [ i ] - > szService , name ) ;
2011-10-06 12:34:50 +04:00
return lp_ctx - > services [ i ] ;
}
/**
* Add a new home service , with the specified home directory , defaults coming
* from service ifrom .
*/
bool lpcfg_add_home ( struct loadparm_context * lp_ctx ,
const char * pszHomename ,
struct loadparm_service * default_service ,
const char * user , const char * pszHomedir )
{
struct loadparm_service * service ;
service = lpcfg_add_service ( lp_ctx , default_service , pszHomename ) ;
if ( service = = NULL )
return false ;
2014-02-02 17:05:39 +04:00
if ( ! ( * ( default_service - > path ) )
| | strequal ( default_service - > path , lp_ctx - > sDefault - > path ) ) {
service - > path = talloc_strdup ( service , pszHomedir ) ;
2011-10-06 12:34:50 +04:00
} else {
2014-01-17 01:30:37 +04:00
service - > path = string_sub_talloc ( service , lpcfg_path ( default_service , lp_ctx - > sDefault , service ) , " %H " , pszHomedir ) ;
2011-10-06 12:34:50 +04:00
}
if ( ! ( * ( service - > comment ) ) ) {
service - > comment = talloc_asprintf ( service , " Home directory of %s " , user ) ;
}
service - > bAvailable = default_service - > bAvailable ;
2013-12-24 07:03:17 +04:00
service - > browseable = default_service - > browseable ;
2011-10-06 12:34:50 +04:00
DEBUG ( 3 , ( " adding home's share [%s] for user '%s' at '%s' \n " ,
2014-02-02 17:05:39 +04:00
pszHomename , user , service - > path ) ) ;
2011-10-06 12:34:50 +04:00
return true ;
}
/**
* Add a new printer service , with defaults coming from service iFrom .
*/
bool lpcfg_add_printer ( struct loadparm_context * lp_ctx ,
const char * pszPrintername ,
struct loadparm_service * default_service )
{
const char * comment = " From Printcap " ;
struct loadparm_service * service ;
service = lpcfg_add_service ( lp_ctx , default_service , pszPrintername ) ;
if ( service = = NULL )
return false ;
/* note that we do NOT default the availability flag to True - */
/* we take it from the default service passed. This allows all */
/* dynamic printers to be disabled by disabling the [printers] */
/* entry (if/when the 'available' keyword is implemented!). */
/* the printer name is set to the service name. */
2014-01-30 07:54:39 +04:00
lpcfg_string_set ( service , & service - > _printername , pszPrintername ) ;
2011-10-09 16:23:05 +04:00
lpcfg_string_set ( service , & service - > comment , comment ) ;
2013-12-24 07:03:17 +04:00
service - > browseable = default_service - > browseable ;
2011-10-06 12:34:50 +04:00
/* Printers cannot be read_only. */
2014-02-02 17:44:05 +04:00
service - > read_only = false ;
2011-10-06 12:34:50 +04:00
/* Printer services must be printable. */
2014-02-02 17:53:44 +04:00
service - > printable = true ;
2011-10-06 12:34:50 +04:00
DEBUG ( 3 , ( " adding printer service %s \n " , pszPrintername ) ) ;
return true ;
}
/**
* Map a parameter ' s string representation to something we can use .
* Returns False if the parameter string is not recognised , else TRUE .
*/
2014-01-15 05:19:21 +04:00
int lpcfg_map_parameter ( const char * pszParmName )
2011-10-06 12:34:50 +04:00
{
int iIndex ;
for ( iIndex = 0 ; parm_table [ iIndex ] . label ; iIndex + + )
if ( strwicmp ( parm_table [ iIndex ] . label , pszParmName ) = = 0 )
return iIndex ;
/* Warn only if it isn't parametric option */
if ( strchr ( pszParmName , ' : ' ) = = NULL )
DEBUG ( 0 , ( " Unknown parameter encountered: \" %s \" \n " , pszParmName ) ) ;
/* We do return 'fail' for parametric options as well because they are
stored in different storage
*/
return - 1 ;
}
/**
return the parameter structure for a parameter
*/
struct parm_struct * lpcfg_parm_struct ( struct loadparm_context * lp_ctx , const char * name )
{
2014-07-09 04:25:36 +04:00
int num = lpcfg_map_parameter ( name ) ;
2011-10-06 12:34:50 +04:00
2014-07-09 04:25:36 +04:00
if ( num < 0 ) {
return NULL ;
2011-10-06 12:34:50 +04:00
}
2014-07-09 04:25:36 +04:00
return & parm_table [ num ] ;
2011-10-06 12:34:50 +04:00
}
/**
return the parameter pointer for a parameter
*/
void * lpcfg_parm_ptr ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service , struct parm_struct * parm )
{
if ( lp_ctx - > s3_fns ) {
return lp_ctx - > s3_fns - > get_parm_ptr ( service , parm ) ;
}
if ( service = = NULL ) {
if ( parm - > p_class = = P_LOCAL )
return ( ( char * ) lp_ctx - > sDefault ) + parm - > offset ;
else if ( parm - > p_class = = P_GLOBAL )
return ( ( char * ) lp_ctx - > globals ) + parm - > offset ;
else return NULL ;
} else {
return ( ( char * ) service ) + parm - > offset ;
}
}
2011-10-18 01:41:46 +04:00
/**
return the parameter pointer for a parameter
*/
bool lpcfg_parm_is_cmdline ( struct loadparm_context * lp_ctx , const char * name )
{
int parmnum ;
2014-01-15 05:19:21 +04:00
parmnum = lpcfg_map_parameter ( name ) ;
2011-10-18 01:41:46 +04:00
if ( parmnum = = - 1 ) return false ;
return lp_ctx - > flags [ parmnum ] & FLAG_CMDLINE ;
}
2011-10-06 12:34:50 +04:00
/**
* Find a service by name . Otherwise works like get_service .
*/
2014-02-19 09:03:57 +04:00
static struct loadparm_service * lpcfg_getservicebyname ( struct loadparm_context * lp_ctx ,
2011-10-06 12:34:50 +04:00
const char * pszServiceName )
{
int iService ;
if ( lp_ctx - > s3_fns ) {
return lp_ctx - > s3_fns - > get_service ( pszServiceName ) ;
}
for ( iService = lp_ctx - > iNumServices - 1 ; iService > = 0 ; iService - - )
if ( lp_ctx - > services [ iService ] ! = NULL & &
strwicmp ( lp_ctx - > services [ iService ] - > szService , pszServiceName ) = = 0 ) {
return lp_ctx - > services [ iService ] ;
}
return NULL ;
}
2014-02-18 03:06:57 +04:00
/**
* Add a parametric option to a parmlist_entry ,
* replacing old value , if already present .
*/
void set_param_opt ( TALLOC_CTX * mem_ctx ,
struct parmlist_entry * * opt_list ,
const char * opt_name ,
const char * opt_value ,
unsigned priority )
{
struct parmlist_entry * new_opt , * opt ;
bool not_added ;
opt = * opt_list ;
not_added = true ;
/* Traverse destination */
while ( opt ) {
/* If we already have same option, override it */
if ( strwicmp ( opt - > key , opt_name ) = = 0 ) {
if ( ( opt - > priority & FLAG_CMDLINE ) & &
! ( priority & FLAG_CMDLINE ) ) {
/* it's been marked as not to be
overridden */
return ;
}
TALLOC_FREE ( opt - > value ) ;
TALLOC_FREE ( opt - > list ) ;
opt - > value = talloc_strdup ( opt , opt_value ) ;
opt - > priority = priority ;
not_added = false ;
break ;
}
opt = opt - > next ;
}
if ( not_added ) {
new_opt = talloc ( mem_ctx , struct parmlist_entry ) ;
if ( new_opt = = NULL ) {
smb_panic ( " OOM " ) ;
}
new_opt - > key = talloc_strdup ( new_opt , opt_name ) ;
if ( new_opt - > key = = NULL ) {
smb_panic ( " talloc_strdup failed " ) ;
}
new_opt - > value = talloc_strdup ( new_opt , opt_value ) ;
if ( new_opt - > value = = NULL ) {
smb_panic ( " talloc_strdup failed " ) ;
}
new_opt - > list = NULL ;
new_opt - > priority = priority ;
DLIST_ADD ( * opt_list , new_opt ) ;
}
}
2011-10-06 12:34:50 +04:00
/**
* Copy a service structure to another .
* If pcopymapDest is NULL then copy all fields
*/
2014-02-19 04:47:38 +04:00
void copy_service ( struct loadparm_service * pserviceDest ,
const struct loadparm_service * pserviceSource ,
struct bitmap * pcopymapDest )
2011-10-06 12:34:50 +04:00
{
int i ;
bool bcopyall = ( pcopymapDest = = NULL ) ;
2014-02-18 03:25:35 +04:00
struct parmlist_entry * data ;
2011-10-06 12:34:50 +04:00
for ( i = 0 ; parm_table [ i ] . label ; i + + )
if ( parm_table [ i ] . p_class = = P_LOCAL & &
( bcopyall | | bitmap_query ( pcopymapDest , i ) ) ) {
2014-02-18 04:27:43 +04:00
const void * src_ptr =
( ( const char * ) pserviceSource ) + parm_table [ i ] . offset ;
2011-10-06 12:34:50 +04:00
void * dest_ptr =
( ( char * ) pserviceDest ) + parm_table [ i ] . offset ;
switch ( parm_table [ i ] . type ) {
case P_BOOL :
2014-01-15 05:13:13 +04:00
case P_BOOLREV :
2014-02-18 04:27:43 +04:00
* ( bool * ) dest_ptr = * ( const bool * ) src_ptr ;
2011-10-06 12:34:50 +04:00
break ;
case P_INTEGER :
2012-01-21 09:50:43 +04:00
case P_BYTES :
2011-10-06 12:34:50 +04:00
case P_OCTAL :
case P_ENUM :
2014-02-18 04:27:43 +04:00
* ( int * ) dest_ptr = * ( const int * ) src_ptr ;
2011-10-06 12:34:50 +04:00
break ;
2014-01-08 03:51:26 +04:00
case P_CHAR :
2014-02-18 04:27:43 +04:00
* ( char * ) dest_ptr = * ( const char * ) src_ptr ;
2014-01-08 03:51:26 +04:00
break ;
2011-10-06 12:34:50 +04:00
case P_STRING :
2011-10-09 16:23:05 +04:00
lpcfg_string_set ( pserviceDest ,
2011-10-06 12:34:50 +04:00
( char * * ) dest_ptr ,
2014-02-18 04:27:43 +04:00
* ( const char * const * ) src_ptr ) ;
2011-10-06 12:34:50 +04:00
break ;
case P_USTRING :
2011-10-09 16:23:05 +04:00
lpcfg_string_set_upper ( pserviceDest ,
2011-10-06 12:34:50 +04:00
( char * * ) dest_ptr ,
2014-02-18 04:27:43 +04:00
* ( const char * const * ) src_ptr ) ;
2011-10-06 12:34:50 +04:00
break ;
2014-02-24 04:08:52 +04:00
case P_CMDLIST :
2011-10-06 12:34:50 +04:00
case P_LIST :
2014-02-19 03:58:36 +04:00
TALLOC_FREE ( * ( ( char * * * ) dest_ptr ) ) ;
2014-02-26 11:07:47 +04:00
* ( char * * * ) dest_ptr = str_list_copy ( pserviceDest ,
* discard_const_p ( const char * * , src_ptr ) ) ;
2011-10-06 12:34:50 +04:00
break ;
default :
break ;
}
}
if ( bcopyall ) {
init_copymap ( pserviceDest ) ;
if ( pserviceSource - > copymap )
bitmap_copy ( pserviceDest - > copymap ,
pserviceSource - > copymap ) ;
}
2014-02-18 03:25:35 +04:00
for ( data = pserviceSource - > param_opt ; data ! = NULL ; data = data - > next ) {
set_param_opt ( pserviceDest , & pserviceDest - > param_opt ,
data - > key , data - > value , data - > priority ) ;
2011-10-06 12:34:50 +04:00
}
}
/**
* Check a service for consistency . Return False if the service is in any way
* incomplete or faulty , else True .
*/
2014-03-21 00:33:01 +04:00
bool lpcfg_service_ok ( struct loadparm_service * service )
2011-10-06 12:34:50 +04:00
{
bool bRetval ;
bRetval = true ;
if ( service - > szService [ 0 ] = = ' \0 ' ) {
DEBUG ( 0 , ( " The following message indicates an internal error: \n " ) ) ;
DEBUG ( 0 , ( " No service name in service entry. \n " ) ) ;
bRetval = false ;
}
/* The [printers] entry MUST be printable. I'm all for flexibility, but */
/* I can't see why you'd want a non-printable printer service... */
if ( strwicmp ( service - > szService , PRINTERS_NAME ) = = 0 ) {
2014-02-02 17:53:44 +04:00
if ( ! service - > printable ) {
2011-10-06 12:34:50 +04:00
DEBUG ( 0 , ( " WARNING: [%s] service MUST be printable! \n " ,
service - > szService ) ) ;
2014-02-02 17:53:44 +04:00
service - > printable = true ;
2011-10-06 12:34:50 +04:00
}
/* [printers] service must also be non-browsable. */
2013-12-24 07:03:17 +04:00
if ( service - > browseable )
service - > browseable = false ;
2011-10-06 12:34:50 +04:00
}
2014-03-21 00:30:26 +04:00
if ( service - > path [ 0 ] = = ' \0 ' & &
strwicmp ( service - > szService , HOMES_NAME ) ! = 0 & &
service - > msdfs_proxy [ 0 ] = = ' \0 ' )
{
DEBUG ( 0 , ( " WARNING: No path in service %s - making it unavailable! \n " ,
service - > szService ) ) ;
service - > bAvailable = false ;
}
2011-10-06 12:34:50 +04:00
if ( ! service - > bAvailable )
DEBUG ( 1 , ( " NOTE: Service %s is flagged unavailable. \n " ,
service - > szService ) ) ;
return bRetval ;
}
/*******************************************************************
Keep a linked list of all config files so we know when one has changed
it ' s date and needs to be reloaded .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-02-20 02:01:52 +04:00
void add_to_file_list ( TALLOC_CTX * mem_ctx , struct file_lists * * list ,
2011-10-06 12:34:50 +04:00
const char * fname , const char * subfname )
{
2014-02-20 02:01:52 +04:00
struct file_lists * f = * list ;
2011-10-06 12:34:50 +04:00
while ( f ) {
if ( f - > name & & ! strcmp ( f - > name , fname ) )
break ;
f = f - > next ;
}
if ( ! f ) {
2014-02-20 01:58:15 +04:00
f = talloc ( mem_ctx , struct file_lists ) ;
2011-10-06 12:34:50 +04:00
if ( ! f )
2014-02-20 02:01:52 +04:00
goto fail ;
f - > next = * list ;
2011-10-06 12:34:50 +04:00
f - > name = talloc_strdup ( f , fname ) ;
if ( ! f - > name ) {
2014-02-20 02:01:52 +04:00
TALLOC_FREE ( f ) ;
goto fail ;
2011-10-06 12:34:50 +04:00
}
f - > subfname = talloc_strdup ( f , subfname ) ;
if ( ! f - > subfname ) {
2014-02-20 02:01:52 +04:00
TALLOC_FREE ( f ) ;
goto fail ;
2011-10-06 12:34:50 +04:00
}
2014-02-20 02:01:52 +04:00
* list = f ;
2011-10-06 12:34:50 +04:00
f - > modtime = file_modtime ( subfname ) ;
} else {
time_t t = file_modtime ( subfname ) ;
if ( t )
f - > modtime = t ;
}
2014-02-20 02:01:52 +04:00
return ;
fail :
DEBUG ( 0 , ( " Unable to add file to file list: %s \n " , fname ) ) ;
2011-10-06 12:34:50 +04:00
}
/*******************************************************************
Check if a config file has changed date .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool lpcfg_file_list_changed ( struct loadparm_context * lp_ctx )
{
struct file_lists * f ;
2012-10-29 16:44:54 +04:00
DEBUG ( 6 , ( " lpcfg_file_list_changed() \n " ) ) ;
2011-10-06 12:34:50 +04:00
for ( f = lp_ctx - > file_lists ; f ! = NULL ; f = f - > next ) {
char * n2 ;
time_t mod_time ;
n2 = standard_sub_basic ( lp_ctx , f - > name ) ;
DEBUGADD ( 6 , ( " file %s -> %s last mod_time: %s \n " ,
f - > name , n2 , ctime ( & f - > modtime ) ) ) ;
mod_time = file_modtime ( n2 ) ;
if ( mod_time & & ( ( f - > modtime ! = mod_time ) | | ( f - > subfname = = NULL ) | | ( strcmp ( n2 , f - > subfname ) ! = 0 ) ) ) {
DEBUGADD ( 6 , ( " file %s modified: %s \n " , n2 ,
ctime ( & mod_time ) ) ) ;
f - > modtime = mod_time ;
talloc_free ( f - > subfname ) ;
f - > subfname = talloc_strdup ( f , n2 ) ;
2014-05-06 08:04:01 +04:00
TALLOC_FREE ( n2 ) ;
2011-10-06 12:34:50 +04:00
return true ;
}
2014-05-06 08:04:01 +04:00
TALLOC_FREE ( n2 ) ;
2011-10-06 12:34:50 +04:00
}
return false ;
}
2014-02-21 06:40:43 +04:00
/*
* set the value for a P_ENUM
*/
bool lp_set_enum_parm ( struct parm_struct * parm , const char * pszParmValue ,
int * ptr )
{
int i ;
for ( i = 0 ; parm - > enum_list [ i ] . name ; i + + ) {
2014-11-27 07:08:30 +03:00
if ( strwicmp ( pszParmValue , parm - > enum_list [ i ] . name ) = = 0 ) {
2014-02-21 06:40:43 +04:00
* ptr = parm - > enum_list [ i ] . value ;
return true ;
}
}
DEBUG ( 0 , ( " WARNING: Ignoring invalid value '%s' for parameter '%s' \n " ,
pszParmValue , parm - > label ) ) ;
return false ;
}
2011-10-06 12:34:50 +04:00
/***************************************************************************
Handle the " realm " parameter
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-03-20 03:57:22 +04:00
bool handle_realm ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
2014-02-18 00:41:39 +04:00
const char * pszParmValue , char * * ptr )
2011-10-06 12:34:50 +04:00
{
2014-02-18 00:41:39 +04:00
char * upper ;
char * lower ;
2011-10-06 12:34:50 +04:00
2014-02-18 00:41:39 +04:00
upper = strupper_talloc ( lp_ctx , pszParmValue ) ;
if ( upper = = NULL ) {
return false ;
}
2011-10-06 12:34:50 +04:00
2014-02-18 00:41:39 +04:00
lower = strlower_talloc ( lp_ctx , pszParmValue ) ;
if ( lower = = NULL ) {
TALLOC_FREE ( upper ) ;
return false ;
}
2014-03-21 00:10:52 +04:00
lpcfg_string_set ( lp_ctx - > globals - > ctx , ptr , pszParmValue ) ;
lpcfg_string_set ( lp_ctx - > globals - > ctx , & lp_ctx - > globals - > realm , upper ) ;
lpcfg_string_set ( lp_ctx - > globals - > ctx , & lp_ctx - > globals - > dnsdomain , lower ) ;
2011-10-06 12:34:50 +04:00
return true ;
}
/***************************************************************************
Handle the include operation .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-03-20 03:57:22 +04:00
bool handle_include ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
2011-10-06 12:34:50 +04:00
const char * pszParmValue , char * * ptr )
{
2014-02-21 06:13:28 +04:00
char * fname ;
if ( lp_ctx - > s3_fns ) {
2014-03-20 03:57:22 +04:00
return lp_ctx - > s3_fns - > lp_include ( lp_ctx , service , pszParmValue , ptr ) ;
2014-02-21 06:13:28 +04:00
}
fname = standard_sub_basic ( lp_ctx , pszParmValue ) ;
2011-10-06 12:34:50 +04:00
2014-02-20 01:58:15 +04:00
add_to_file_list ( lp_ctx , & lp_ctx - > file_lists , pszParmValue , fname ) ;
2011-10-06 12:34:50 +04:00
2011-10-09 16:23:05 +04:00
lpcfg_string_set ( lp_ctx , ptr , fname ) ;
2011-10-06 12:34:50 +04:00
if ( file_exist ( fname ) )
2014-03-20 02:00:11 +04:00
return pm_process ( fname , do_section , lpcfg_do_parameter , lp_ctx ) ;
2011-10-06 12:34:50 +04:00
DEBUG ( 2 , ( " Can't find include file %s \n " , fname ) ) ;
return false ;
}
/***************************************************************************
Handle the interpretation of the copy parameter .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-03-20 03:57:22 +04:00
bool handle_copy ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
2011-10-06 12:34:50 +04:00
const char * pszParmValue , char * * ptr )
{
bool bRetval ;
2014-02-20 01:24:00 +04:00
struct loadparm_service * serviceTemp = NULL ;
2011-10-06 12:34:50 +04:00
bRetval = false ;
DEBUG ( 3 , ( " Copying service from service %s \n " , pszParmValue ) ) ;
2014-02-19 09:03:57 +04:00
serviceTemp = lpcfg_getservicebyname ( lp_ctx , pszParmValue ) ;
2014-02-20 01:24:00 +04:00
2014-03-20 03:57:22 +04:00
if ( service = = NULL ) {
2014-03-27 05:22:41 +04:00
DEBUG ( 0 , ( " Unable to copy service - invalid service destination. \n " ) ) ;
2014-02-20 01:24:00 +04:00
return false ;
}
2014-02-19 09:03:57 +04:00
if ( serviceTemp ! = NULL ) {
2014-03-20 03:57:22 +04:00
if ( serviceTemp = = service ) {
2011-10-06 12:34:50 +04:00
DEBUG ( 0 , ( " Can't copy service %s - unable to copy self! \n " , pszParmValue ) ) ;
} else {
2014-03-20 03:57:22 +04:00
copy_service ( service ,
2011-10-06 12:34:50 +04:00
serviceTemp ,
2014-03-20 03:57:22 +04:00
service - > copymap ) ;
lpcfg_string_set ( service , ptr , pszParmValue ) ;
2014-02-20 01:24:00 +04:00
2011-10-06 12:34:50 +04:00
bRetval = true ;
}
} else {
DEBUG ( 0 , ( " Unable to copy service - source not found: %s \n " ,
pszParmValue ) ) ;
bRetval = false ;
}
return bRetval ;
}
2014-03-20 03:57:22 +04:00
bool handle_debug_list ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
2011-10-06 12:34:50 +04:00
const char * pszParmValue , char * * ptr )
{
2014-03-21 00:10:52 +04:00
lpcfg_string_set ( lp_ctx - > globals - > ctx , ptr , pszParmValue ) ;
2014-02-17 07:33:55 +04:00
return debug_parse_levels ( pszParmValue ) ;
2011-10-06 12:34:50 +04:00
}
2014-03-20 03:57:22 +04:00
bool handle_logfile ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
2014-02-17 07:38:59 +04:00
const char * pszParmValue , char * * ptr )
2011-10-06 12:34:50 +04:00
{
2014-03-21 00:10:52 +04:00
if ( lp_ctx - > s3_fns = = NULL ) {
2014-02-17 07:38:59 +04:00
debug_set_logfile ( pszParmValue ) ;
2011-10-06 12:34:50 +04:00
}
2014-02-17 07:38:59 +04:00
2014-03-21 00:10:52 +04:00
lpcfg_string_set ( lp_ctx - > globals - > ctx , ptr , pszParmValue ) ;
2011-10-06 12:34:50 +04:00
return true ;
}
2014-02-20 07:37:16 +04:00
/*
* These special charset handling methods only run in the source3 code .
*/
2014-03-20 03:57:22 +04:00
bool handle_charset ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
2014-02-20 07:37:16 +04:00
const char * pszParmValue , char * * ptr )
{
if ( lp_ctx - > s3_fns ) {
if ( * ptr = = NULL | | strcmp ( * ptr , pszParmValue ) ! = 0 ) {
global_iconv_handle = smb_iconv_handle_reinit ( NULL ,
lpcfg_dos_charset ( lp_ctx ) ,
lpcfg_unix_charset ( lp_ctx ) ,
true , global_iconv_handle ) ;
}
}
2014-03-21 00:10:52 +04:00
return lpcfg_string_set ( lp_ctx - > globals - > ctx , ptr , pszParmValue ) ;
2014-02-20 07:37:16 +04:00
}
2014-03-20 03:57:22 +04:00
bool handle_dos_charset ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
2014-02-20 07:37:16 +04:00
const char * pszParmValue , char * * ptr )
{
bool is_utf8 = false ;
size_t len = strlen ( pszParmValue ) ;
if ( lp_ctx - > s3_fns ) {
if ( len = = 4 | | len = = 5 ) {
/* Don't use StrCaseCmp here as we don't want to
initialize iconv . */
if ( ( toupper_m ( pszParmValue [ 0 ] ) = = ' U ' ) & &
( toupper_m ( pszParmValue [ 1 ] ) = = ' T ' ) & &
( toupper_m ( pszParmValue [ 2 ] ) = = ' F ' ) ) {
if ( len = = 4 ) {
if ( pszParmValue [ 3 ] = = ' 8 ' ) {
is_utf8 = true ;
}
} else {
if ( pszParmValue [ 3 ] = = ' - ' & &
pszParmValue [ 4 ] = = ' 8 ' ) {
is_utf8 = true ;
}
}
}
}
if ( * ptr = = NULL | | strcmp ( * ptr , pszParmValue ) ! = 0 ) {
if ( is_utf8 ) {
DEBUG ( 0 , ( " ERROR: invalid DOS charset: 'dos charset' must not "
" be UTF8, using (default value) %s instead. \n " ,
DEFAULT_DOS_CHARSET ) ) ;
pszParmValue = DEFAULT_DOS_CHARSET ;
}
global_iconv_handle = smb_iconv_handle_reinit ( NULL ,
lpcfg_dos_charset ( lp_ctx ) ,
lpcfg_unix_charset ( lp_ctx ) ,
true , global_iconv_handle ) ;
}
}
2014-03-21 00:10:52 +04:00
return lpcfg_string_set ( lp_ctx - > globals - > ctx , ptr , pszParmValue ) ;
2014-02-20 07:37:16 +04:00
}
2014-03-20 03:57:22 +04:00
bool handle_printing ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
2014-02-21 08:59:41 +04:00
const char * pszParmValue , char * * ptr )
{
static int parm_num = - 1 ;
if ( parm_num = = - 1 ) {
parm_num = lpcfg_map_parameter ( " printing " ) ;
}
if ( ! lp_set_enum_parm ( & parm_table [ parm_num ] , pszParmValue , ( int * ) ptr ) ) {
return false ;
}
if ( lp_ctx - > s3_fns ) {
2014-03-20 03:57:22 +04:00
if ( service = = NULL ) {
2014-03-27 06:32:42 +04:00
init_printer_values ( lp_ctx , lp_ctx - > globals - > ctx , lp_ctx - > sDefault ) ;
2014-02-21 08:59:41 +04:00
} else {
2014-03-27 06:32:42 +04:00
init_printer_values ( lp_ctx , service , service ) ;
2014-02-21 08:59:41 +04:00
}
}
return true ;
}
2014-03-20 03:57:22 +04:00
bool handle_ldap_debug_level ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
const char * pszParmValue , char * * ptr )
2014-02-24 00:53:44 +04:00
{
lp_ctx - > globals - > ldap_debug_level = lp_int ( pszParmValue ) ;
if ( lp_ctx - > s3_fns ) {
lp_ctx - > s3_fns - > init_ldap_debugging ( ) ;
}
return true ;
}
2014-02-21 08:59:41 +04:00
2014-03-20 03:57:22 +04:00
bool handle_netbios_aliases ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
const char * pszParmValue , char * * ptr )
2014-02-24 01:12:48 +04:00
{
TALLOC_FREE ( lp_ctx - > globals - > netbios_aliases ) ;
2014-02-26 11:07:47 +04:00
lp_ctx - > globals - > netbios_aliases = str_list_make_v3_const ( lp_ctx - > globals - > ctx ,
pszParmValue , NULL ) ;
2014-02-24 01:12:48 +04:00
if ( lp_ctx - > s3_fns ) {
return lp_ctx - > s3_fns - > set_netbios_aliases ( lp_ctx - > globals - > netbios_aliases ) ;
}
return true ;
}
2014-02-24 01:38:37 +04:00
/*
* idmap related parameters
*/
2014-03-20 03:57:22 +04:00
bool handle_idmap_backend ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
const char * pszParmValue , char * * ptr )
2014-02-24 01:38:37 +04:00
{
if ( lp_ctx - > s3_fns ) {
2014-03-20 03:57:22 +04:00
lp_do_parameter_parametric ( lp_ctx , service , " idmap config * : backend " ,
pszParmValue , 0 ) ;
2014-02-24 01:38:37 +04:00
}
2014-03-20 03:57:22 +04:00
return lpcfg_string_set ( lp_ctx - > globals - > ctx , ptr , pszParmValue ) ;
2014-02-24 01:38:37 +04:00
}
2014-03-20 03:57:22 +04:00
bool handle_idmap_uid ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
const char * pszParmValue , char * * ptr )
2014-02-24 01:38:37 +04:00
{
if ( lp_ctx - > s3_fns ) {
2014-03-20 03:57:22 +04:00
lp_do_parameter_parametric ( lp_ctx , service , " idmap config * : range " ,
pszParmValue , 0 ) ;
2014-02-24 01:38:37 +04:00
}
2014-03-20 03:57:22 +04:00
return lpcfg_string_set ( lp_ctx - > globals - > ctx , ptr , pszParmValue ) ;
2014-02-24 01:38:37 +04:00
}
2014-03-20 03:57:22 +04:00
bool handle_idmap_gid ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
const char * pszParmValue , char * * ptr )
2014-02-24 01:38:37 +04:00
{
if ( lp_ctx - > s3_fns ) {
2014-03-20 03:57:22 +04:00
lp_do_parameter_parametric ( lp_ctx , service , " idmap config * : range " ,
pszParmValue , 0 ) ;
2014-02-24 01:38:37 +04:00
}
2014-03-20 03:57:22 +04:00
return lpcfg_string_set ( lp_ctx - > globals - > ctx , ptr , pszParmValue ) ;
2014-02-24 01:38:37 +04:00
}
2014-03-20 03:57:22 +04:00
bool handle_smb_ports ( struct loadparm_context * lp_ctx , struct loadparm_service * service ,
const char * pszParmValue , char * * ptr )
2014-03-14 01:27:54 +04:00
{
static int parm_num = - 1 ;
int i ;
const char * * list ;
if ( ! pszParmValue | | ! * pszParmValue ) {
return false ;
}
if ( parm_num = = - 1 ) {
parm_num = lpcfg_map_parameter ( " smb ports " ) ;
2015-03-26 12:14:22 +03:00
if ( parm_num = = - 1 ) {
return false ;
}
2014-03-14 01:27:54 +04:00
}
if ( ! set_variable_helper ( lp_ctx - > globals - > ctx , parm_num , ptr , " smb ports " ,
pszParmValue ) ) {
return false ;
}
list = lp_ctx - > globals - > smb_ports ;
if ( list = = NULL ) {
return false ;
}
/* Check that each port is a valid integer and within range */
for ( i = 0 ; list [ i ] ! = NULL ; i + + ) {
char * end = NULL ;
int port = 0 ;
port = strtol ( list [ i ] , & end , 10 ) ;
if ( * end ! = ' \0 ' | | port < = 0 | | port > 65535 ) {
TALLOC_FREE ( list ) ;
return false ;
}
}
return true ;
}
2011-10-06 12:34:50 +04:00
/***************************************************************************
Initialise a copymap .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-09-10 05:14:42 +04:00
/**
* Initializes service copymap
* Note : pservice * must * be valid TALLOC_CTX
*/
2014-02-20 06:00:27 +04:00
void init_copymap ( struct loadparm_service * pservice )
2011-10-06 12:34:50 +04:00
{
int i ;
TALLOC_FREE ( pservice - > copymap ) ;
2014-09-10 05:14:42 +04:00
pservice - > copymap = bitmap_talloc ( pservice , num_parameters ( ) ) ;
2014-09-10 05:16:11 +04:00
if ( ! pservice - > copymap ) {
2011-10-06 12:34:50 +04:00
DEBUG ( 0 ,
( " Couldn't allocate copymap!! (size %d) \n " ,
2014-03-14 02:17:27 +04:00
( int ) num_parameters ( ) ) ) ;
2014-09-10 05:16:11 +04:00
} else {
for ( i = 0 ; i < num_parameters ( ) ; i + + ) {
2011-10-06 12:34:50 +04:00
bitmap_set ( pservice - > copymap , i ) ;
2014-09-10 05:16:11 +04:00
}
}
2011-10-06 12:34:50 +04:00
}
/**
* Process a parametric option
*/
static bool lp_do_parameter_parametric ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service ,
const char * pszParmName ,
const char * pszParmValue , int flags )
{
2014-02-24 00:34:45 +04:00
struct parmlist_entry * * data ;
2011-10-06 12:34:50 +04:00
char * name ;
TALLOC_CTX * mem_ctx ;
while ( isspace ( ( unsigned char ) * pszParmName ) ) {
pszParmName + + ;
}
name = strlower_talloc ( lp_ctx , pszParmName ) ;
if ( ! name ) return false ;
if ( service = = NULL ) {
2014-02-24 00:34:45 +04:00
data = & lp_ctx - > globals - > param_opt ;
2014-06-11 01:56:20 +04:00
/**
* s3 code cannot deal with parametric options stored on the globals ctx .
*/
if ( lp_ctx - > s3_fns ! = NULL ) {
mem_ctx = NULL ;
} else {
mem_ctx = lp_ctx - > globals - > ctx ;
}
2011-10-06 12:34:50 +04:00
} else {
2014-02-24 00:34:45 +04:00
data = & service - > param_opt ;
2011-10-06 12:34:50 +04:00
mem_ctx = service ;
}
2014-02-24 00:34:45 +04:00
set_param_opt ( mem_ctx , data , name , pszParmValue , flags ) ;
2011-10-06 12:34:50 +04:00
talloc_free ( name ) ;
return true ;
}
2014-02-28 02:58:55 +04:00
static bool set_variable_helper ( TALLOC_CTX * mem_ctx , int parmnum , void * parm_ptr ,
2014-02-26 03:28:49 +04:00
const char * pszParmName , const char * pszParmValue )
2011-10-06 12:34:50 +04:00
{
int i ;
2014-02-26 03:28:49 +04:00
/* switch on the type of variable it is */
2011-10-06 12:34:50 +04:00
switch ( parm_table [ parmnum ] . type )
{
case P_BOOL : {
bool b ;
if ( ! set_boolean ( pszParmValue , & b ) ) {
2014-05-08 04:10:04 +04:00
DEBUG ( 0 , ( " set_variable_helper(%s): value is not "
2012-10-29 18:16:04 +04:00
" boolean! \n " , pszParmValue ) ) ;
2011-10-06 12:34:50 +04:00
return false ;
}
* ( bool * ) parm_ptr = b ;
}
break ;
case P_BOOLREV : {
bool b ;
if ( ! set_boolean ( pszParmValue , & b ) ) {
2014-05-08 04:10:04 +04:00
DEBUG ( 0 , ( " set_variable_helper(%s): value is not "
2012-10-29 18:16:04 +04:00
" boolean! \n " , pszParmValue ) ) ;
2011-10-06 12:34:50 +04:00
return false ;
}
* ( bool * ) parm_ptr = ! b ;
}
break ;
case P_INTEGER :
2014-02-26 03:06:03 +04:00
* ( int * ) parm_ptr = lp_int ( pszParmValue ) ;
2011-10-06 12:34:50 +04:00
break ;
case P_CHAR :
* ( char * ) parm_ptr = * pszParmValue ;
break ;
case P_OCTAL :
2014-02-26 03:31:03 +04:00
i = sscanf ( pszParmValue , " %o " , ( int * ) parm_ptr ) ;
if ( i ! = 1 ) {
DEBUG ( 0 , ( " Invalid octal number %s \n " , pszParmName ) ) ;
return false ;
}
2011-10-06 12:34:50 +04:00
break ;
case P_BYTES :
{
uint64_t val ;
if ( conv_str_size_error ( pszParmValue , & val ) ) {
if ( val < = INT_MAX ) {
* ( int * ) parm_ptr = ( int ) val ;
break ;
}
}
2014-05-08 04:10:04 +04:00
DEBUG ( 0 , ( " set_variable_helper(%s): value is not "
2012-10-29 17:52:50 +04:00
" a valid size specifier! \n " , pszParmValue ) ) ;
2011-10-06 12:34:50 +04:00
return false ;
}
case P_CMDLIST :
2014-02-26 03:06:03 +04:00
TALLOC_FREE ( * ( char * * * ) parm_ptr ) ;
2014-02-26 11:07:47 +04:00
* ( char * * * ) parm_ptr = str_list_make_v3 ( mem_ctx ,
pszParmValue , NULL ) ;
2011-10-06 12:34:50 +04:00
break ;
2014-05-08 04:10:04 +04:00
2011-10-06 12:34:50 +04:00
case P_LIST :
{
2014-05-06 08:10:53 +04:00
char * * new_list = str_list_make_v3 ( mem_ctx ,
2011-10-06 12:34:50 +04:00
pszParmValue , NULL ) ;
2014-03-13 04:27:24 +04:00
if ( new_list = = NULL ) {
break ;
}
2011-10-06 12:34:50 +04:00
for ( i = 0 ; new_list [ i ] ; i + + ) {
2012-08-23 17:32:05 +04:00
if ( * ( const char * * * ) parm_ptr ! = NULL & &
new_list [ i ] [ 0 ] = = ' + ' & &
new_list [ i ] [ 1 ] )
{
2011-10-06 12:34:50 +04:00
if ( ! str_list_check ( * ( const char * * * ) parm_ptr ,
& new_list [ i ] [ 1 ] ) ) {
2011-12-06 04:30:24 +04:00
* ( const char * * * ) parm_ptr = str_list_add ( * ( const char * * * ) parm_ptr ,
& new_list [ i ] [ 1 ] ) ;
2011-10-06 12:34:50 +04:00
}
2012-08-23 17:32:05 +04:00
} else if ( * ( const char * * * ) parm_ptr ! = NULL & &
new_list [ i ] [ 0 ] = = ' - ' & &
new_list [ i ] [ 1 ] )
{
2011-10-06 12:34:50 +04:00
str_list_remove ( * ( const char * * * ) parm_ptr ,
& new_list [ i ] [ 1 ] ) ;
} else {
if ( i ! = 0 ) {
DEBUG ( 0 , ( " Unsupported list syntax for: %s = %s \n " ,
pszParmName , pszParmValue ) ) ;
return false ;
}
2014-02-26 11:07:47 +04:00
* ( char * * * ) parm_ptr = new_list ;
2011-10-06 12:34:50 +04:00
break ;
}
}
break ;
}
2014-05-08 04:10:04 +04:00
2011-10-06 12:34:50 +04:00
case P_STRING :
2011-10-09 16:23:05 +04:00
lpcfg_string_set ( mem_ctx , ( char * * ) parm_ptr , pszParmValue ) ;
2011-10-06 12:34:50 +04:00
break ;
case P_USTRING :
2011-10-09 16:23:05 +04:00
lpcfg_string_set_upper ( mem_ctx , ( char * * ) parm_ptr , pszParmValue ) ;
2011-10-06 12:34:50 +04:00
break ;
case P_ENUM :
2014-02-21 06:47:27 +04:00
if ( ! lp_set_enum_parm ( & parm_table [ parmnum ] , pszParmValue , ( int * ) parm_ptr ) ) {
2011-10-06 12:34:50 +04:00
return false ;
}
break ;
2012-02-05 23:12:23 +04:00
case P_SEP :
break ;
2011-10-06 12:34:50 +04:00
}
2014-02-26 03:28:49 +04:00
return true ;
}
2014-03-20 03:57:22 +04:00
bool set_variable ( TALLOC_CTX * mem_ctx , struct loadparm_service * service , int parmnum , void * parm_ptr ,
2014-02-26 03:28:49 +04:00
const char * pszParmName , const char * pszParmValue ,
struct loadparm_context * lp_ctx , bool on_globals )
{
int i ;
bool ok ;
/* if it is a special case then go ahead */
if ( parm_table [ parmnum ] . special ) {
2014-03-20 03:57:22 +04:00
ok = parm_table [ parmnum ] . special ( lp_ctx , service , pszParmValue ,
2014-02-26 03:28:49 +04:00
( char * * ) parm_ptr ) ;
2015-01-28 19:16:32 +03:00
} else {
ok = set_variable_helper ( mem_ctx , parmnum , parm_ptr ,
pszParmName , pszParmValue ) ;
2014-02-26 03:28:49 +04:00
}
if ( ! ok ) {
return false ;
}
2011-10-06 12:34:50 +04:00
if ( on_globals & & ( lp_ctx - > flags [ parmnum ] & FLAG_DEFAULT ) ) {
lp_ctx - > flags [ parmnum ] & = ~ FLAG_DEFAULT ;
/* we have to also unset FLAG_DEFAULT on aliases */
for ( i = parmnum - 1 ; i > = 0 & & parm_table [ i ] . offset = = parm_table [ parmnum ] . offset ; i - - ) {
lp_ctx - > flags [ i ] & = ~ FLAG_DEFAULT ;
}
2014-03-14 02:17:27 +04:00
for ( i = parmnum + 1 ; i < num_parameters ( ) & & parm_table [ i ] . offset = = parm_table [ parmnum ] . offset ; i + + ) {
2011-10-06 12:34:50 +04:00
lp_ctx - > flags [ i ] & = ~ FLAG_DEFAULT ;
}
}
return true ;
}
bool lpcfg_do_global_parameter ( struct loadparm_context * lp_ctx ,
const char * pszParmName , const char * pszParmValue )
{
2014-01-15 05:19:21 +04:00
int parmnum = lpcfg_map_parameter ( pszParmName ) ;
2011-10-06 12:34:50 +04:00
void * parm_ptr ;
if ( parmnum < 0 ) {
if ( strchr ( pszParmName , ' : ' ) ) {
return lp_do_parameter_parametric ( lp_ctx , NULL , pszParmName , pszParmValue , 0 ) ;
}
DEBUG ( 0 , ( " Ignoring unknown parameter \" %s \" \n " , pszParmName ) ) ;
return true ;
}
/* if the flag has been set on the command line, then don't allow override,
but don ' t report an error */
if ( lp_ctx - > flags [ parmnum ] & FLAG_CMDLINE ) {
return true ;
}
2014-02-27 07:23:06 +04:00
if ( parm_table [ parmnum ] . flags & FLAG_DEPRECATED ) {
DEBUG ( 1 , ( " WARNING: The \" %s \" option is deprecated \n " ,
pszParmName ) ) ;
}
2011-10-06 12:34:50 +04:00
parm_ptr = lpcfg_parm_ptr ( lp_ctx , NULL , & parm_table [ parmnum ] ) ;
2014-03-20 03:57:22 +04:00
return set_variable ( lp_ctx - > globals - > ctx , NULL , parmnum , parm_ptr ,
2011-10-06 12:34:50 +04:00
pszParmName , pszParmValue , lp_ctx , true ) ;
}
bool lpcfg_do_service_parameter ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service ,
const char * pszParmName , const char * pszParmValue )
{
void * parm_ptr ;
int i ;
2014-01-15 05:19:21 +04:00
int parmnum = lpcfg_map_parameter ( pszParmName ) ;
2011-10-06 12:34:50 +04:00
if ( parmnum < 0 ) {
if ( strchr ( pszParmName , ' : ' ) ) {
return lp_do_parameter_parametric ( lp_ctx , service , pszParmName , pszParmValue , 0 ) ;
}
DEBUG ( 0 , ( " Ignoring unknown parameter \" %s \" \n " , pszParmName ) ) ;
return true ;
}
/* if the flag has been set on the command line, then don't allow override,
but don ' t report an error */
if ( lp_ctx - > flags [ parmnum ] & FLAG_CMDLINE ) {
return true ;
}
2014-02-27 07:23:06 +04:00
if ( parm_table [ parmnum ] . flags & FLAG_DEPRECATED ) {
DEBUG ( 1 , ( " WARNING: The \" %s \" option is deprecated \n " ,
pszParmName ) ) ;
}
2011-10-06 12:34:50 +04:00
if ( parm_table [ parmnum ] . p_class = = P_GLOBAL ) {
DEBUG ( 0 ,
( " Global parameter %s found in service section! \n " ,
pszParmName ) ) ;
return true ;
}
parm_ptr = ( ( char * ) service ) + parm_table [ parmnum ] . offset ;
if ( ! service - > copymap )
init_copymap ( service ) ;
/* this handles the aliases - set the copymap for other
* entries with the same data pointer */
for ( i = 0 ; parm_table [ i ] . label ; i + + )
if ( parm_table [ i ] . offset = = parm_table [ parmnum ] . offset & &
parm_table [ i ] . p_class = = parm_table [ parmnum ] . p_class )
bitmap_clear ( service - > copymap , i ) ;
2014-03-20 03:57:22 +04:00
return set_variable ( service , service , parmnum , parm_ptr , pszParmName ,
2011-10-06 12:34:50 +04:00
pszParmValue , lp_ctx , false ) ;
}
/**
* Process a parameter .
*/
2014-03-20 02:00:11 +04:00
bool lpcfg_do_parameter ( const char * pszParmName , const char * pszParmValue ,
2011-10-06 12:34:50 +04:00
void * userdata )
{
struct loadparm_context * lp_ctx = ( struct loadparm_context * ) userdata ;
if ( lp_ctx - > bInGlobalSection )
return lpcfg_do_global_parameter ( lp_ctx , pszParmName ,
pszParmValue ) ;
else
return lpcfg_do_service_parameter ( lp_ctx , lp_ctx - > currentService ,
pszParmName , pszParmValue ) ;
}
/*
variable argument do parameter
*/
bool lpcfg_do_global_parameter_var ( struct loadparm_context * lp_ctx , const char * pszParmName , const char * fmt , . . . ) PRINTF_ATTRIBUTE ( 3 , 4 ) ;
bool lpcfg_do_global_parameter_var ( struct loadparm_context * lp_ctx ,
const char * pszParmName , const char * fmt , . . . )
{
char * s ;
bool ret ;
va_list ap ;
va_start ( ap , fmt ) ;
s = talloc_vasprintf ( NULL , fmt , ap ) ;
va_end ( ap ) ;
ret = lpcfg_do_global_parameter ( lp_ctx , pszParmName , s ) ;
talloc_free ( s ) ;
return ret ;
}
/*
set a parameter from the commandline - this is called from command line parameter
parsing code . It sets the parameter then marks the parameter as unable to be modified
by smb . conf processing
*/
bool lpcfg_set_cmdline ( struct loadparm_context * lp_ctx , const char * pszParmName ,
const char * pszParmValue )
{
int parmnum ;
int i ;
2014-02-20 07:53:28 +04:00
while ( isspace ( ( unsigned char ) * pszParmValue ) ) pszParmValue + + ;
2014-01-15 05:19:21 +04:00
parmnum = lpcfg_map_parameter ( pszParmName ) ;
2011-10-06 12:34:50 +04:00
if ( parmnum < 0 & & strchr ( pszParmName , ' : ' ) ) {
/* set a parametric option */
2014-02-28 03:53:32 +04:00
bool ok ;
ok = lp_do_parameter_parametric ( lp_ctx , NULL , pszParmName ,
pszParmValue , FLAG_CMDLINE ) ;
if ( lp_ctx - > s3_fns ! = NULL ) {
if ( ok ) {
lp_ctx - > s3_fns - > store_cmdline ( pszParmName , pszParmValue ) ;
}
}
return ok ;
2011-10-06 12:34:50 +04:00
}
if ( parmnum < 0 ) {
DEBUG ( 0 , ( " Unknown option '%s' \n " , pszParmName ) ) ;
return false ;
}
/* reset the CMDLINE flag in case this has been called before */
lp_ctx - > flags [ parmnum ] & = ~ FLAG_CMDLINE ;
2014-04-17 05:49:05 +04:00
if ( ! lpcfg_do_global_parameter ( lp_ctx , pszParmName , pszParmValue ) ) {
return false ;
2011-10-06 12:34:50 +04:00
}
lp_ctx - > flags [ parmnum ] | = FLAG_CMDLINE ;
/* we have to also set FLAG_CMDLINE on aliases */
2014-01-29 02:59:29 +04:00
for ( i = parmnum - 1 ;
i > = 0 & & parm_table [ i ] . p_class = = parm_table [ parmnum ] . p_class & &
parm_table [ i ] . offset = = parm_table [ parmnum ] . offset ;
i - - ) {
2011-10-06 12:34:50 +04:00
lp_ctx - > flags [ i ] | = FLAG_CMDLINE ;
}
2014-01-29 02:59:29 +04:00
for ( i = parmnum + 1 ;
2014-03-14 02:17:27 +04:00
i < num_parameters ( ) & &
2014-01-29 02:59:29 +04:00
parm_table [ i ] . p_class = = parm_table [ parmnum ] . p_class & &
parm_table [ i ] . offset = = parm_table [ parmnum ] . offset ;
i + + ) {
2011-10-06 12:34:50 +04:00
lp_ctx - > flags [ i ] | = FLAG_CMDLINE ;
}
2014-02-28 03:53:32 +04:00
if ( lp_ctx - > s3_fns ! = NULL ) {
lp_ctx - > s3_fns - > store_cmdline ( pszParmName , pszParmValue ) ;
}
2011-10-06 12:34:50 +04:00
return true ;
}
/*
set a option from the commandline in ' a = b ' format . Use to support - - option
*/
bool lpcfg_set_option ( struct loadparm_context * lp_ctx , const char * option )
{
char * p , * s ;
bool ret ;
2011-10-09 16:23:45 +04:00
s = talloc_strdup ( NULL , option ) ;
2011-10-06 12:34:50 +04:00
if ( ! s ) {
return false ;
}
p = strchr ( s , ' = ' ) ;
if ( ! p ) {
2011-10-09 16:23:45 +04:00
talloc_free ( s ) ;
2011-10-06 12:34:50 +04:00
return false ;
}
* p = 0 ;
ret = lpcfg_set_cmdline ( lp_ctx , s , p + 1 ) ;
2011-10-09 16:23:45 +04:00
talloc_free ( s ) ;
2011-10-06 12:34:50 +04:00
return ret ;
}
# define BOOLSTR(b) ((b) ? "Yes" : "No")
/**
* Print a parameter of the specified type .
*/
2014-01-15 04:39:14 +04:00
void lpcfg_print_parameter ( struct parm_struct * p , void * ptr , FILE * f )
2011-10-06 12:34:50 +04:00
{
/* For the seperation of lists values that we print below */
const char * list_sep = " , " ;
int i ;
switch ( p - > type )
{
case P_ENUM :
for ( i = 0 ; p - > enum_list [ i ] . name ; i + + ) {
if ( * ( int * ) ptr = = p - > enum_list [ i ] . value ) {
fprintf ( f , " %s " ,
p - > enum_list [ i ] . name ) ;
break ;
}
}
break ;
case P_BOOL :
fprintf ( f , " %s " , BOOLSTR ( * ( bool * ) ptr ) ) ;
break ;
case P_BOOLREV :
fprintf ( f , " %s " , BOOLSTR ( ! * ( bool * ) ptr ) ) ;
break ;
case P_INTEGER :
case P_BYTES :
fprintf ( f , " %d " , * ( int * ) ptr ) ;
break ;
case P_CHAR :
fprintf ( f , " %c " , * ( char * ) ptr ) ;
break ;
case P_OCTAL : {
int val = * ( int * ) ptr ;
if ( val = = - 1 ) {
fprintf ( f , " -1 " ) ;
} else {
2014-01-03 03:22:19 +04:00
fprintf ( f , " 0%03o " , val ) ;
2011-10-06 12:34:50 +04:00
}
break ;
}
case P_CMDLIST :
list_sep = " " ;
/* fall through */
case P_LIST :
if ( ( char * * * ) ptr & & * ( char * * * ) ptr ) {
char * * list = * ( char * * * ) ptr ;
for ( ; * list ; list + + ) {
/* surround strings with whitespace in double quotes */
if ( * ( list + 1 ) = = NULL ) {
/* last item, no extra separator */
list_sep = " " ;
}
if ( strchr_m ( * list , ' ' ) ) {
fprintf ( f , " \" %s \" %s " , * list , list_sep ) ;
} else {
fprintf ( f , " %s%s " , * list , list_sep ) ;
}
}
}
break ;
case P_STRING :
case P_USTRING :
if ( * ( char * * ) ptr ) {
fprintf ( f , " %s " , * ( char * * ) ptr ) ;
}
break ;
case P_SEP :
break ;
}
}
/**
* Check if two parameters are equal .
*/
2014-01-27 06:34:06 +04:00
static bool lpcfg_equal_parameter ( parm_type type , void * ptr1 , void * ptr2 )
2011-10-06 12:34:50 +04:00
{
switch ( type ) {
case P_BOOL :
case P_BOOLREV :
return ( * ( ( bool * ) ptr1 ) = = * ( ( bool * ) ptr2 ) ) ;
case P_INTEGER :
case P_ENUM :
case P_OCTAL :
case P_BYTES :
return ( * ( ( int * ) ptr1 ) = = * ( ( int * ) ptr2 ) ) ;
case P_CHAR :
return ( * ( ( char * ) ptr1 ) = = * ( ( char * ) ptr2 ) ) ;
case P_LIST :
case P_CMDLIST :
return str_list_equal ( * ( const char * * * ) ptr1 , * ( const char * * * ) ptr2 ) ;
case P_STRING :
case P_USTRING :
{
char * p1 = * ( char * * ) ptr1 , * p2 = * ( char * * ) ptr2 ;
if ( p1 & & ! * p1 )
p1 = NULL ;
if ( p2 & & ! * p2 )
p2 = NULL ;
return ( p1 = = p2 | | strequal ( p1 , p2 ) ) ;
}
case P_SEP :
break ;
}
return false ;
}
/**
* Process a new section ( service ) .
*
* At this stage all sections are services .
* Later we ' ll have special sections that permit server parameters to be set .
* Returns True on success , False on failure .
*/
static bool do_section ( const char * pszSectionName , void * userdata )
{
struct loadparm_context * lp_ctx = ( struct loadparm_context * ) userdata ;
bool bRetval ;
2014-02-28 01:16:05 +04:00
bool isglobal ;
if ( lp_ctx - > s3_fns ! = NULL ) {
return lp_ctx - > s3_fns - > do_section ( pszSectionName , lp_ctx ) ;
}
isglobal = ( ( strwicmp ( pszSectionName , GLOBAL_NAME ) = = 0 ) | |
2011-10-06 12:34:50 +04:00
( strwicmp ( pszSectionName , GLOBAL_NAME2 ) = = 0 ) ) ;
2014-02-28 01:16:05 +04:00
2011-10-06 12:34:50 +04:00
bRetval = false ;
/* if we've just struck a global section, note the fact. */
lp_ctx - > bInGlobalSection = isglobal ;
/* check for multiple global sections */
if ( lp_ctx - > bInGlobalSection ) {
DEBUG ( 4 , ( " Processing section \" [%s] \" \n " , pszSectionName ) ) ;
return true ;
}
/* if we have a current service, tidy it up before moving on */
bRetval = true ;
if ( lp_ctx - > currentService ! = NULL )
2011-10-09 16:22:11 +04:00
bRetval = lpcfg_service_ok ( lp_ctx - > currentService ) ;
2011-10-06 12:34:50 +04:00
/* if all is still well, move to the next record in the services array */
if ( bRetval ) {
/* We put this here to avoid an odd message order if messages are */
/* issued by the post-processing of a previous section. */
DEBUG ( 4 , ( " Processing section \" [%s] \" \n " , pszSectionName ) ) ;
if ( ( lp_ctx - > currentService = lpcfg_add_service ( lp_ctx , lp_ctx - > sDefault ,
pszSectionName ) )
= = NULL ) {
DEBUG ( 0 , ( " Failed to add a new service \n " ) ) ;
return false ;
}
}
return bRetval ;
}
/**
* Determine if a particular base parameter is currently set to the default value .
*/
2014-07-09 03:44:51 +04:00
static bool is_default ( void * base_structure , int i )
2011-10-06 12:34:50 +04:00
{
2014-03-21 01:27:46 +04:00
void * def_ptr = ( ( char * ) base_structure ) + parm_table [ i ] . offset ;
2011-10-06 12:34:50 +04:00
switch ( parm_table [ i ] . type ) {
case P_CMDLIST :
case P_LIST :
2014-02-18 04:27:43 +04:00
return str_list_equal ( ( const char * const * ) parm_table [ i ] . def . lvalue ,
2014-02-26 11:07:47 +04:00
* ( const char * const * * ) def_ptr ) ;
2011-10-06 12:34:50 +04:00
case P_STRING :
case P_USTRING :
return strequal ( parm_table [ i ] . def . svalue ,
* ( char * * ) def_ptr ) ;
case P_BOOL :
case P_BOOLREV :
return parm_table [ i ] . def . bvalue = =
* ( bool * ) def_ptr ;
case P_INTEGER :
case P_CHAR :
case P_OCTAL :
case P_BYTES :
case P_ENUM :
return parm_table [ i ] . def . ivalue = =
* ( int * ) def_ptr ;
2012-02-05 23:12:23 +04:00
case P_SEP :
break ;
2011-10-06 12:34:50 +04:00
}
return false ;
}
/**
* Display the contents of the global structure .
*/
2014-03-26 23:51:56 +04:00
void lpcfg_dump_globals ( struct loadparm_context * lp_ctx , FILE * f ,
2011-10-06 12:34:50 +04:00
bool show_defaults )
{
int i ;
struct parmlist_entry * data ;
fprintf ( f , " # Global parameters \n [global] \n " ) ;
for ( i = 0 ; parm_table [ i ] . label ; i + + )
if ( parm_table [ i ] . p_class = = P_GLOBAL & &
( i = = 0 | | ( parm_table [ i ] . offset ! = parm_table [ i - 1 ] . offset ) ) ) {
2014-03-21 01:44:15 +04:00
if ( ! show_defaults ) {
if ( lp_ctx - > flags & & ( lp_ctx - > flags [ i ] & FLAG_DEFAULT ) ) {
continue ;
}
if ( is_default ( lp_ctx - > globals , i ) ) {
continue ;
}
}
2011-10-06 12:34:50 +04:00
fprintf ( f , " \t %s = " , parm_table [ i ] . label ) ;
2014-01-15 04:39:14 +04:00
lpcfg_print_parameter ( & parm_table [ i ] , lpcfg_parm_ptr ( lp_ctx , NULL , & parm_table [ i ] ) , f ) ;
2011-10-06 12:34:50 +04:00
fprintf ( f , " \n " ) ;
}
if ( lp_ctx - > globals - > param_opt ! = NULL ) {
for ( data = lp_ctx - > globals - > param_opt ; data ;
data = data - > next ) {
if ( ! show_defaults & & ( data - > priority & FLAG_DEFAULT ) ) {
continue ;
}
fprintf ( f , " \t %s = %s \n " , data - > key , data - > value ) ;
}
}
}
/**
* Display the contents of a single services record .
*/
2014-01-27 06:32:39 +04:00
void lpcfg_dump_a_service ( struct loadparm_service * pService , struct loadparm_service * sDefault , FILE * f ,
unsigned int * flags , bool show_defaults )
2011-10-06 12:34:50 +04:00
{
int i ;
struct parmlist_entry * data ;
if ( pService ! = sDefault )
fprintf ( f , " \n [%s] \n " , pService - > szService ) ;
for ( i = 0 ; parm_table [ i ] . label ; i + + ) {
if ( parm_table [ i ] . p_class = = P_LOCAL & &
( * parm_table [ i ] . label ! = ' - ' ) & &
( i = = 0 | | ( parm_table [ i ] . offset ! = parm_table [ i - 1 ] . offset ) ) )
{
if ( pService = = sDefault ) {
2014-01-27 06:32:39 +04:00
if ( ! show_defaults ) {
2014-11-28 00:03:29 +03:00
if ( flags & & ( flags [ i ] & FLAG_DEFAULT ) ) {
continue ;
}
2011-10-06 12:34:50 +04:00
if ( is_default ( sDefault , i ) ) {
continue ;
}
}
} else {
2014-01-15 06:56:34 +04:00
if ( lpcfg_equal_parameter ( parm_table [ i ] . type ,
( ( char * ) pService ) +
parm_table [ i ] . offset ,
( ( char * ) sDefault ) +
parm_table [ i ] . offset ) )
2011-10-06 12:34:50 +04:00
continue ;
}
fprintf ( f , " \t %s = " , parm_table [ i ] . label ) ;
2014-01-15 04:39:14 +04:00
lpcfg_print_parameter ( & parm_table [ i ] ,
2011-10-06 12:34:50 +04:00
( ( char * ) pService ) + parm_table [ i ] . offset , f ) ;
fprintf ( f , " \n " ) ;
}
}
if ( pService - > param_opt ! = NULL ) {
for ( data = pService - > param_opt ; data ; data = data - > next ) {
2014-02-26 07:43:44 +04:00
if ( ! show_defaults & & ( data - > priority & FLAG_DEFAULT ) ) {
continue ;
}
2011-10-06 12:34:50 +04:00
fprintf ( f , " \t %s = %s \n " , data - > key , data - > value ) ;
}
}
}
bool lpcfg_dump_a_parameter ( struct loadparm_context * lp_ctx ,
struct loadparm_service * service ,
const char * parm_name , FILE * f )
{
struct parm_struct * parm ;
void * ptr ;
2014-02-26 04:22:33 +04:00
char * local_parm_name ;
char * parm_opt ;
const char * parm_opt_value ;
2011-10-06 12:34:50 +04:00
2014-02-26 04:22:33 +04:00
/* check for parametrical option */
local_parm_name = talloc_strdup ( lp_ctx , parm_name ) ;
if ( local_parm_name = = NULL ) {
return false ;
}
parm_opt = strchr ( local_parm_name , ' : ' ) ;
if ( parm_opt ) {
* parm_opt = ' \0 ' ;
parm_opt + + ;
if ( strlen ( parm_opt ) ) {
parm_opt_value = lpcfg_parm_string ( lp_ctx , service ,
local_parm_name , parm_opt ) ;
if ( parm_opt_value ) {
fprintf ( f , " %s \n " , parm_opt_value ) ;
return true ;
}
}
return false ;
}
/* parameter is not parametric, search the table */
2011-10-06 12:34:50 +04:00
parm = lpcfg_parm_struct ( lp_ctx , parm_name ) ;
if ( ! parm ) {
return false ;
}
2013-12-31 05:30:30 +04:00
if ( service ! = NULL & & parm - > p_class = = P_GLOBAL ) {
return false ;
}
2011-10-06 12:34:50 +04:00
ptr = lpcfg_parm_ptr ( lp_ctx , service , parm ) ;
2014-01-15 04:39:14 +04:00
lpcfg_print_parameter ( parm , ptr , f ) ;
2011-10-06 12:34:50 +04:00
fprintf ( f , " \n " ) ;
return true ;
}
/**
* Auto - load some home services .
*/
static void lpcfg_add_auto_services ( struct loadparm_context * lp_ctx ,
const char * str )
{
return ;
}
2014-03-27 06:27:40 +04:00
/***************************************************************************
Initialise the sDefault parameter structure for the printer values .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void init_printer_values ( struct loadparm_context * lp_ctx , TALLOC_CTX * ctx ,
struct loadparm_service * pService )
{
/* choose defaults depending on the type of printing */
switch ( pService - > printing ) {
case PRINT_BSD :
case PRINT_AIX :
case PRINT_LPRNT :
case PRINT_LPROS2 :
lpcfg_string_set ( ctx , & pService - > lpq_command , " lpq -P'%p' " ) ;
lpcfg_string_set ( ctx , & pService - > lprm_command , " lprm -P'%p' %j " ) ;
lpcfg_string_set ( ctx , & pService - > print_command , " lpr -r -P'%p' %s " ) ;
break ;
case PRINT_LPRNG :
case PRINT_PLP :
lpcfg_string_set ( ctx , & pService - > lpq_command , " lpq -P'%p' " ) ;
lpcfg_string_set ( ctx , & pService - > lprm_command , " lprm -P'%p' %j " ) ;
lpcfg_string_set ( ctx , & pService - > print_command , " lpr -r -P'%p' %s " ) ;
lpcfg_string_set ( ctx , & pService - > queuepause_command , " lpc stop '%p' " ) ;
lpcfg_string_set ( ctx , & pService - > queueresume_command , " lpc start '%p' " ) ;
lpcfg_string_set ( ctx , & pService - > lppause_command , " lpc hold '%p' %j " ) ;
lpcfg_string_set ( ctx , & pService - > lpresume_command , " lpc release '%p' %j " ) ;
break ;
case PRINT_CUPS :
case PRINT_IPRINT :
/* set the lpq command to contain the destination printer
name only . This is used by cups_queue_get ( ) */
lpcfg_string_set ( ctx , & pService - > lpq_command , " %p " ) ;
lpcfg_string_set ( ctx , & pService - > lprm_command , " " ) ;
lpcfg_string_set ( ctx , & pService - > print_command , " " ) ;
lpcfg_string_set ( ctx , & pService - > lppause_command , " " ) ;
lpcfg_string_set ( ctx , & pService - > lpresume_command , " " ) ;
lpcfg_string_set ( ctx , & pService - > queuepause_command , " " ) ;
lpcfg_string_set ( ctx , & pService - > queueresume_command , " " ) ;
break ;
case PRINT_SYSV :
case PRINT_HPUX :
lpcfg_string_set ( ctx , & pService - > lpq_command , " lpstat -o%p " ) ;
lpcfg_string_set ( ctx , & pService - > lprm_command , " cancel %p-%j " ) ;
lpcfg_string_set ( ctx , & pService - > print_command , " lp -c -d%p %s; rm %s " ) ;
lpcfg_string_set ( ctx , & pService - > queuepause_command , " disable %p " ) ;
lpcfg_string_set ( ctx , & pService - > queueresume_command , " enable %p " ) ;
# ifndef HPUX
lpcfg_string_set ( ctx , & pService - > lppause_command , " lp -i %p-%j -H hold " ) ;
lpcfg_string_set ( ctx , & pService - > lpresume_command , " lp -i %p-%j -H resume " ) ;
# endif /* HPUX */
break ;
case PRINT_QNX :
lpcfg_string_set ( ctx , & pService - > lpq_command , " lpq -P%p " ) ;
lpcfg_string_set ( ctx , & pService - > lprm_command , " lprm -P%p %j " ) ;
lpcfg_string_set ( ctx , & pService - > print_command , " lp -r -P%p %s " ) ;
break ;
# if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
case PRINT_TEST :
case PRINT_VLP : {
const char * tdbfile ;
TALLOC_CTX * tmp_ctx = talloc_new ( ctx ) ;
const char * tmp ;
tmp = lpcfg_parm_string ( lp_ctx , NULL , " vlp " , " tdbfile " ) ;
if ( tmp = = NULL ) {
tmp = " /tmp/vlp.tdb " ;
}
tdbfile = talloc_asprintf ( tmp_ctx , " tdbfile=%s " , tmp ) ;
if ( tdbfile = = NULL ) {
tdbfile = " tdbfile=/tmp/vlp.tdb " ;
}
tmp = talloc_asprintf ( tmp_ctx , " vlp %s print %%p %%s " ,
tdbfile ) ;
lpcfg_string_set ( ctx , & pService - > print_command ,
tmp ? tmp : " vlp print %p %s " ) ;
tmp = talloc_asprintf ( tmp_ctx , " vlp %s lpq %%p " ,
tdbfile ) ;
lpcfg_string_set ( ctx , & pService - > lpq_command ,
tmp ? tmp : " vlp lpq %p " ) ;
tmp = talloc_asprintf ( tmp_ctx , " vlp %s lprm %%p %%j " ,
tdbfile ) ;
lpcfg_string_set ( ctx , & pService - > lprm_command ,
tmp ? tmp : " vlp lprm %p %j " ) ;
tmp = talloc_asprintf ( tmp_ctx , " vlp %s lppause %%p %%j " ,
tdbfile ) ;
lpcfg_string_set ( ctx , & pService - > lppause_command ,
tmp ? tmp : " vlp lppause %p %j " ) ;
tmp = talloc_asprintf ( tmp_ctx , " vlp %s lpresume %%p %%j " ,
tdbfile ) ;
lpcfg_string_set ( ctx , & pService - > lpresume_command ,
tmp ? tmp : " vlp lpresume %p %j " ) ;
tmp = talloc_asprintf ( tmp_ctx , " vlp %s queuepause %%p " ,
tdbfile ) ;
lpcfg_string_set ( ctx , & pService - > queuepause_command ,
tmp ? tmp : " vlp queuepause %p " ) ;
tmp = talloc_asprintf ( tmp_ctx , " vlp %s queueresume %%p " ,
tdbfile ) ;
lpcfg_string_set ( ctx , & pService - > queueresume_command ,
tmp ? tmp : " vlp queueresume %p " ) ;
TALLOC_FREE ( tmp_ctx ) ;
break ;
}
# endif /* DEVELOPER */
}
}
2011-10-06 12:34:50 +04:00
/**
* Unload unused services .
*/
void lpcfg_killunused ( struct loadparm_context * lp_ctx ,
struct smbsrv_connection * smb ,
bool ( * snumused ) ( struct smbsrv_connection * , int ) )
{
int i ;
2014-07-11 06:01:33 +04:00
if ( lp_ctx - > s3_fns ! = NULL ) {
smb_panic ( " Cannot be used from an s3 loadparm ctx " ) ;
}
2011-10-06 12:34:50 +04:00
for ( i = 0 ; i < lp_ctx - > iNumServices ; i + + ) {
if ( lp_ctx - > services [ i ] = = NULL )
continue ;
if ( ! snumused | | ! snumused ( smb , i ) ) {
talloc_free ( lp_ctx - > services [ i ] ) ;
lp_ctx - > services [ i ] = NULL ;
}
}
}
static int lpcfg_destructor ( struct loadparm_context * lp_ctx )
{
struct parmlist_entry * data ;
if ( lp_ctx - > refuse_free ) {
/* someone is trying to free the
global_loadparm_context .
We can ' t allow that . */
return - 1 ;
}
if ( lp_ctx - > globals - > param_opt ! = NULL ) {
struct parmlist_entry * next ;
for ( data = lp_ctx - > globals - > param_opt ; data ; data = next ) {
next = data - > next ;
if ( data - > priority & FLAG_CMDLINE ) continue ;
DLIST_REMOVE ( lp_ctx - > globals - > param_opt , data ) ;
talloc_free ( data ) ;
}
}
return 0 ;
}
2015-03-16 02:30:27 +03:00
struct defaults_hook_data {
const char * name ;
lpcfg_defaults_hook hook ;
struct defaults_hook_data * prev , * next ;
} * defaults_hooks = NULL ;
bool lpcfg_register_defaults_hook ( const char * name , lpcfg_defaults_hook hook )
{
struct defaults_hook_data * hook_data = talloc ( talloc_autofree_context ( ) ,
struct defaults_hook_data ) ;
hook_data - > name = talloc_strdup ( hook_data , name ) ;
hook_data - > hook = hook ;
DLIST_ADD ( defaults_hooks , hook_data ) ;
return false ;
}
2011-10-06 12:34:50 +04:00
/**
* Initialise the global parameter structure .
*
* Note that most callers should use loadparm_init_global ( ) instead
*/
struct loadparm_context * loadparm_init ( TALLOC_CTX * mem_ctx )
{
int i ;
char * myname ;
struct loadparm_context * lp_ctx ;
struct parmlist_entry * parm ;
char * logfile ;
2015-03-16 02:30:27 +03:00
struct defaults_hook_data * defaults_hook ;
2011-10-06 12:34:50 +04:00
lp_ctx = talloc_zero ( mem_ctx , struct loadparm_context ) ;
if ( lp_ctx = = NULL )
return NULL ;
talloc_set_destructor ( lp_ctx , lpcfg_destructor ) ;
lp_ctx - > bInGlobalSection = true ;
lp_ctx - > globals = talloc_zero ( lp_ctx , struct loadparm_global ) ;
2014-03-20 00:09:58 +04:00
/* This appears odd, but globals in s3 isn't a pointer */
lp_ctx - > globals - > ctx = lp_ctx - > globals ;
2011-10-06 12:34:50 +04:00
lp_ctx - > sDefault = talloc_zero ( lp_ctx , struct loadparm_service ) ;
2014-03-14 02:17:27 +04:00
lp_ctx - > flags = talloc_zero_array ( lp_ctx , unsigned int , num_parameters ( ) ) ;
2011-10-06 12:34:50 +04:00
lp_ctx - > sDefault - > iMaxPrintJobs = 1000 ;
lp_ctx - > sDefault - > bAvailable = true ;
2013-12-24 07:03:17 +04:00
lp_ctx - > sDefault - > browseable = true ;
2014-02-02 17:44:05 +04:00
lp_ctx - > sDefault - > read_only = true ;
2013-12-24 07:03:18 +04:00
lp_ctx - > sDefault - > map_archive = true ;
2013-12-24 07:03:31 +04:00
lp_ctx - > sDefault - > strict_locking = true ;
2013-12-24 07:03:18 +04:00
lp_ctx - > sDefault - > oplocks = true ;
2013-12-24 07:03:19 +04:00
lp_ctx - > sDefault - > create_mask = 0744 ;
2013-12-24 07:03:19 +04:00
lp_ctx - > sDefault - > force_create_mode = 0000 ;
2014-02-02 18:04:13 +04:00
lp_ctx - > sDefault - > directory_mask = 0755 ;
2014-02-03 05:48:28 +04:00
lp_ctx - > sDefault - > force_directory_mode = 0000 ;
2011-10-06 12:34:50 +04:00
DEBUG ( 3 , ( " Initialising global parameters \n " ) ) ;
for ( i = 0 ; parm_table [ i ] . label ; i + + ) {
if ( ( parm_table [ i ] . type = = P_STRING | |
parm_table [ i ] . type = = P_USTRING ) & &
! ( lp_ctx - > flags [ i ] & FLAG_CMDLINE ) ) {
char * * r ;
if ( parm_table [ i ] . p_class = = P_LOCAL ) {
r = ( char * * ) ( ( ( char * ) lp_ctx - > sDefault ) + parm_table [ i ] . offset ) ;
} else {
r = ( char * * ) ( ( ( char * ) lp_ctx - > globals ) + parm_table [ i ] . offset ) ;
}
* r = talloc_strdup ( lp_ctx , " " ) ;
}
}
logfile = talloc_asprintf ( lp_ctx , " %s/log.samba " , dyn_LOGFILEBASE ) ;
lpcfg_do_global_parameter ( lp_ctx , " log file " , logfile ) ;
talloc_free ( logfile ) ;
lpcfg_do_global_parameter ( lp_ctx , " log level " , " 0 " ) ;
2013-07-04 20:11:02 +04:00
lpcfg_do_global_parameter ( lp_ctx , " syslog " , " 1 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " syslog only " , " No " ) ;
lpcfg_do_global_parameter ( lp_ctx , " debug timestamp " , " Yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " debug prefix timestamp " , " No " ) ;
lpcfg_do_global_parameter ( lp_ctx , " debug hires timestamp " , " Yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " debug pid " , " No " ) ;
lpcfg_do_global_parameter ( lp_ctx , " debug uid " , " No " ) ;
lpcfg_do_global_parameter ( lp_ctx , " debug class " , " No " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " share backend " , " classic " ) ;
2011-11-10 05:45:54 +04:00
lpcfg_do_global_parameter ( lp_ctx , " server role " , " auto " ) ;
2011-11-08 04:36:00 +04:00
lpcfg_do_global_parameter ( lp_ctx , " domain logons " , " No " ) ;
lpcfg_do_global_parameter ( lp_ctx , " domain master " , " Auto " ) ;
2011-10-06 12:34:50 +04:00
/* options that can be set on the command line must be initialised via
the slower lpcfg_do_global_parameter ( ) to ensure that FLAG_CMDLINE is obeyed */
# ifdef TCP_NODELAY
lpcfg_do_global_parameter ( lp_ctx , " socket options " , " TCP_NODELAY " ) ;
# endif
lpcfg_do_global_parameter ( lp_ctx , " workgroup " , DEFAULT_WORKGROUP ) ;
myname = get_myname ( lp_ctx ) ;
lpcfg_do_global_parameter ( lp_ctx , " netbios name " , myname ) ;
talloc_free ( myname ) ;
2013-12-31 08:25:14 +04:00
lpcfg_do_global_parameter ( lp_ctx , " name resolve order " , " lmhosts wins host bcast " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " fstype " , " NTFS " ) ;
lpcfg_do_global_parameter ( lp_ctx , " ntvfs handler " , " unixuid default " ) ;
2013-12-31 08:12:15 +04:00
lpcfg_do_global_parameter ( lp_ctx , " max connections " , " 0 " ) ;
2011-10-06 12:34:50 +04:00
2012-06-16 06:54:12 +04:00
lpcfg_do_global_parameter ( lp_ctx , " dcerpc endpoint servers " , " epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver " ) ;
2014-05-20 02:15:31 +04:00
lpcfg_do_global_parameter ( lp_ctx , " server services " , " s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns " ) ;
2014-09-26 02:49:37 +04:00
lpcfg_do_global_parameter ( lp_ctx , " kccsrv:samba_kcc " , " false " ) ;
2011-10-06 12:34:50 +04:00
/* the winbind method for domain controllers is for both RODC
auth forwarding and for trusted domains */
lpcfg_do_global_parameter ( lp_ctx , " private dir " , dyn_PRIVATE_DIR ) ;
lpcfg_do_global_parameter ( lp_ctx , " registry:HKEY_LOCAL_MACHINE " , " hklm.ldb " ) ;
/* This hive should be dynamically generated by Samba using
data from the sam , but for the moment leave it in a tdb to
keep regedt32 from popping up an annoying dialog . */
lpcfg_do_global_parameter ( lp_ctx , " registry:HKEY_USERS " , " hku.ldb " ) ;
/* using UTF8 by default allows us to support all chars */
2013-12-31 05:31:01 +04:00
lpcfg_do_global_parameter ( lp_ctx , " unix charset " , " UTF-8 " ) ;
2011-10-06 12:34:50 +04:00
/* Use codepage 850 as a default for the dos character set */
lpcfg_do_global_parameter ( lp_ctx , " dos charset " , " CP850 " ) ;
/*
* Allow the default PASSWD_CHAT to be overridden in local . h .
*/
lpcfg_do_global_parameter ( lp_ctx , " passwd chat " , DEFAULT_PASSWD_CHAT ) ;
lpcfg_do_global_parameter ( lp_ctx , " pid directory " , dyn_PIDDIR ) ;
lpcfg_do_global_parameter ( lp_ctx , " lock dir " , dyn_LOCKDIR ) ;
lpcfg_do_global_parameter ( lp_ctx , " state directory " , dyn_STATEDIR ) ;
lpcfg_do_global_parameter ( lp_ctx , " cache directory " , dyn_CACHEDIR ) ;
lpcfg_do_global_parameter ( lp_ctx , " ncalrpc dir " , dyn_NCALRPCDIR ) ;
2014-01-08 04:27:23 +04:00
lpcfg_do_global_parameter ( lp_ctx , " nbt client socket address " , " 0.0.0.0 " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter_var ( lp_ctx , " server string " ,
" Samba %s " , SAMBA_VERSION_STRING ) ;
lpcfg_do_global_parameter ( lp_ctx , " password server " , " * " ) ;
lpcfg_do_global_parameter ( lp_ctx , " max mux " , " 50 " ) ;
2014-01-07 08:10:52 +04:00
lpcfg_do_global_parameter ( lp_ctx , " max xmit " , " 16644 " ) ;
2011-12-16 02:26:04 +04:00
lpcfg_do_global_parameter ( lp_ctx , " host msdfs " , " true " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " LargeReadwrite " , " True " ) ;
2014-01-08 04:33:15 +04:00
lpcfg_do_global_parameter ( lp_ctx , " server min protocol " , " LANMAN1 " ) ;
2014-01-08 04:34:49 +04:00
lpcfg_do_global_parameter ( lp_ctx , " server max protocol " , " SMB3 " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " client min protocol " , " CORE " ) ;
2014-09-24 01:08:10 +04:00
lpcfg_do_global_parameter ( lp_ctx , " client max protocol " , " default " ) ;
2011-11-10 05:45:54 +04:00
lpcfg_do_global_parameter ( lp_ctx , " security " , " AUTO " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " EncryptPasswords " , " True " ) ;
lpcfg_do_global_parameter ( lp_ctx , " ReadRaw " , " True " ) ;
lpcfg_do_global_parameter ( lp_ctx , " WriteRaw " , " True " ) ;
lpcfg_do_global_parameter ( lp_ctx , " NullPasswords " , " False " ) ;
2013-12-09 05:23:49 +04:00
lpcfg_do_global_parameter ( lp_ctx , " old password allowed period " , " 60 " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " ObeyPamRestrictions " , " False " ) ;
lpcfg_do_global_parameter ( lp_ctx , " TimeServer " , " False " ) ;
lpcfg_do_global_parameter ( lp_ctx , " BindInterfacesOnly " , " False " ) ;
lpcfg_do_global_parameter ( lp_ctx , " Unicode " , " True " ) ;
lpcfg_do_global_parameter ( lp_ctx , " ClientLanManAuth " , " False " ) ;
lpcfg_do_global_parameter ( lp_ctx , " ClientNTLMv2Auth " , " True " ) ;
lpcfg_do_global_parameter ( lp_ctx , " LanmanAuth " , " False " ) ;
lpcfg_do_global_parameter ( lp_ctx , " NTLMAuth " , " True " ) ;
lpcfg_do_global_parameter ( lp_ctx , " client use spnego principal " , " False " ) ;
2014-01-08 04:28:23 +04:00
lpcfg_do_global_parameter ( lp_ctx , " UnixExtensions " , " True " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " PreferredMaster " , " Auto " ) ;
lpcfg_do_global_parameter ( lp_ctx , " LocalMaster " , " True " ) ;
lpcfg_do_global_parameter ( lp_ctx , " wins support " , " False " ) ;
lpcfg_do_global_parameter ( lp_ctx , " dns proxy " , " True " ) ;
lpcfg_do_global_parameter ( lp_ctx , " winbind separator " , " \\ " ) ;
lpcfg_do_global_parameter ( lp_ctx , " winbind sealed pipes " , " True " ) ;
2013-10-17 20:39:56 +04:00
lpcfg_do_global_parameter ( lp_ctx , " require strong key " , " True " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " winbindd socket directory " , dyn_WINBINDD_SOCKET_DIR ) ;
lpcfg_do_global_parameter ( lp_ctx , " winbindd privileged socket directory " , dyn_WINBINDD_PRIVILEGED_SOCKET_DIR ) ;
2011-10-09 16:25:11 +04:00
lpcfg_do_global_parameter ( lp_ctx , " ntp signd socket directory " , dyn_NTP_SIGND_SOCKET_DIR ) ;
lpcfg_do_global_parameter_var ( lp_ctx , " dns update command " , " %s/samba_dnsupdate " , dyn_SCRIPTSBINDIR ) ;
lpcfg_do_global_parameter_var ( lp_ctx , " spn update command " , " %s/samba_spnupdate " , dyn_SCRIPTSBINDIR ) ;
2011-12-04 20:58:16 +04:00
lpcfg_do_global_parameter_var ( lp_ctx , " samba kcc command " ,
" %s/samba_kcc " , dyn_SCRIPTSBINDIR ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " template shell " , " /bin/false " ) ;
2014-03-28 07:32:06 +04:00
lpcfg_do_global_parameter ( lp_ctx , " template homedir " , " /home/%D/%U " ) ;
2011-10-06 12:34:50 +04:00
2011-11-02 21:03:24 +04:00
lpcfg_do_global_parameter ( lp_ctx , " client signing " , " default " ) ;
2011-11-02 21:03:24 +04:00
lpcfg_do_global_parameter ( lp_ctx , " server signing " , " default " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " use spnego " , " True " ) ;
2011-10-12 15:36:40 +04:00
lpcfg_do_global_parameter ( lp_ctx , " use mmap " , " True " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " smb ports " , " 445 139 " ) ;
2015-03-01 10:04:00 +03:00
lpcfg_do_global_parameter_var ( lp_ctx , " nbt port " , " %d " , NBT_NAME_SERVICE_PORT ) ;
lpcfg_do_global_parameter_var ( lp_ctx , " dgram port " , " %d " , NBT_DGRAM_SERVICE_PORT ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " cldap port " , " 389 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " krb5 port " , " 88 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " kpasswd port " , " 464 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " web port " , " 901 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " nt status support " , " True " ) ;
lpcfg_do_global_parameter ( lp_ctx , " max wins ttl " , " 518400 " ) ; /* 6 days */
2013-12-31 07:38:24 +04:00
lpcfg_do_global_parameter ( lp_ctx , " min wins ttl " , " 21600 " ) ;
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " tls enabled " , " True " ) ;
lpcfg_do_global_parameter ( lp_ctx , " tls keyfile " , " tls/key.pem " ) ;
lpcfg_do_global_parameter ( lp_ctx , " tls certfile " , " tls/cert.pem " ) ;
lpcfg_do_global_parameter ( lp_ctx , " tls cafile " , " tls/ca.pem " ) ;
lpcfg_do_global_parameter ( lp_ctx , " prefork children:smb " , " 4 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " rndc command " , " /usr/sbin/rndc " ) ;
lpcfg_do_global_parameter ( lp_ctx , " nsupdate command " , " /usr/bin/nsupdate -g " ) ;
2012-09-12 11:31:17 +04:00
lpcfg_do_global_parameter ( lp_ctx , " allow dns updates " , " secure only " ) ;
2012-03-27 16:42:15 +04:00
lpcfg_do_global_parameter ( lp_ctx , " dns forwarder " , " " ) ;
2011-12-16 17:25:57 +04:00
2014-01-07 08:33:56 +04:00
lpcfg_do_global_parameter ( lp_ctx , " algorithmic rid base " , " 1000 " ) ;
2014-01-07 08:36:57 +04:00
lpcfg_do_global_parameter ( lp_ctx , " enhanced browsing " , " True " ) ;
2014-01-07 08:41:28 +04:00
lpcfg_do_global_parameter ( lp_ctx , " winbind nss info " , " template " ) ;
2014-01-07 09:12:47 +04:00
lpcfg_do_global_parameter ( lp_ctx , " server schannel " , " Auto " ) ;
2014-01-08 00:54:13 +04:00
lpcfg_do_global_parameter ( lp_ctx , " short preserve case " , " True " ) ;
2014-01-08 00:55:44 +04:00
lpcfg_do_global_parameter ( lp_ctx , " max open files " , " 16384 " ) ;
2014-01-08 00:58:17 +04:00
lpcfg_do_global_parameter ( lp_ctx , " cups connection timeout " , " 30 " ) ;
2014-01-08 01:00:31 +04:00
lpcfg_do_global_parameter ( lp_ctx , " locking " , " True " ) ;
2014-01-08 01:02:33 +04:00
lpcfg_do_global_parameter ( lp_ctx , " block size " , " 1024 " ) ;
2014-01-08 01:04:11 +04:00
lpcfg_do_global_parameter ( lp_ctx , " client use spnego " , " True " ) ;
2014-01-08 01:05:35 +04:00
lpcfg_do_global_parameter ( lp_ctx , " change notify " , " True " ) ;
2014-01-08 01:07:22 +04:00
lpcfg_do_global_parameter ( lp_ctx , " name cache timeout " , " 660 " ) ;
2014-01-08 01:09:36 +04:00
lpcfg_do_global_parameter ( lp_ctx , " defer sharing violations " , " True " ) ;
2014-01-08 01:10:43 +04:00
lpcfg_do_global_parameter ( lp_ctx , " ldap replication sleep " , " 1000 " ) ;
2014-01-08 01:12:45 +04:00
lpcfg_do_global_parameter ( lp_ctx , " idmap backend " , " tdb " ) ;
2014-01-08 01:14:22 +04:00
lpcfg_do_global_parameter ( lp_ctx , " enable privileges " , " True " ) ;
2014-01-16 04:32:42 +04:00
lpcfg_do_global_parameter_var ( lp_ctx , " smb2 max write " , " %u " , DEFAULT_SMB2_MAX_WRITE ) ;
2014-01-08 01:15:46 +04:00
2014-01-08 01:18:43 +04:00
lpcfg_do_global_parameter ( lp_ctx , " passdb backend " , " tdbsam " ) ;
2014-01-08 01:20:20 +04:00
lpcfg_do_global_parameter ( lp_ctx , " getwd cache " , " True " ) ;
2014-01-08 01:21:56 +04:00
lpcfg_do_global_parameter ( lp_ctx , " winbind nested groups " , " True " ) ;
2014-01-08 01:23:19 +04:00
lpcfg_do_global_parameter ( lp_ctx , " mangled names " , " True " ) ;
2014-01-16 04:32:42 +04:00
lpcfg_do_global_parameter_var ( lp_ctx , " smb2 max credits " , " %u " , DEFAULT_SMB2_MAX_CREDITS ) ;
2014-01-08 01:25:05 +04:00
2014-01-08 01:34:08 +04:00
lpcfg_do_global_parameter ( lp_ctx , " ldap ssl " , " start tls " ) ;
2014-01-08 01:39:33 +04:00
lpcfg_do_global_parameter ( lp_ctx , " ldap deref " , " auto " ) ;
2014-01-08 01:41:21 +04:00
lpcfg_do_global_parameter ( lp_ctx , " lm interval " , " 60 " ) ;
2014-01-08 01:43:02 +04:00
lpcfg_do_global_parameter ( lp_ctx , " mangling method " , " hash2 " ) ;
2014-01-08 01:44:35 +04:00
lpcfg_do_global_parameter ( lp_ctx , " hide dot files " , " True " ) ;
2014-01-08 01:45:55 +04:00
lpcfg_do_global_parameter ( lp_ctx , " browse list " , " True " ) ;
2014-01-08 01:50:02 +04:00
lpcfg_do_global_parameter ( lp_ctx , " passwd chat timeout " , " 2 " ) ;
2014-01-08 01:51:03 +04:00
lpcfg_do_global_parameter ( lp_ctx , " guest account " , GUEST_ACCOUNT ) ;
2014-01-08 04:21:39 +04:00
lpcfg_do_global_parameter ( lp_ctx , " client schannel " , " auto " ) ;
lpcfg_do_global_parameter ( lp_ctx , " smb encrypt " , " default " ) ;
lpcfg_do_global_parameter ( lp_ctx , " max log size " , " 5000 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " idmap negative cache time " , " 120 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " ldap follow referral " , " auto " ) ;
lpcfg_do_global_parameter ( lp_ctx , " multicast dns register " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " winbind reconnect delay " , " 30 " ) ;
2014-07-25 23:44:53 +04:00
lpcfg_do_global_parameter ( lp_ctx , " winbind request timeout " , " 60 " ) ;
2014-01-08 04:21:39 +04:00
lpcfg_do_global_parameter ( lp_ctx , " nt acl support " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " acl check permissions " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " keepalive " , " 300 " ) ;
2014-10-09 16:56:28 +04:00
lpcfg_do_global_parameter ( lp_ctx , " smbd profiling level " , " off " ) ;
2014-01-08 04:21:39 +04:00
lpcfg_do_global_parameter ( lp_ctx , " winbind cache time " , " 300 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " level2 oplocks " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " show add printer wizard " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " allocation roundup size " , " 1048576 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " ldap page size " , " 1024 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " kernel share modes " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " strict locking " , " Auto " ) ;
lpcfg_do_global_parameter ( lp_ctx , " map readonly " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " allow trusted domains " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " default devmode " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " os level " , " 20 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " dos filetimes " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " mangling char " , " ~ " ) ;
lpcfg_do_global_parameter ( lp_ctx , " printcap cache time " , " 750 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " create krb5 conf " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " winbind max clients " , " 200 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " acl map full control " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " nt pipe support " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " ldap debug threshold " , " 10 " ) ;
2014-09-05 09:38:38 +04:00
lpcfg_do_global_parameter ( lp_ctx , " client ldap sasl wrapping " , " sign " ) ;
2014-01-08 04:21:39 +04:00
lpcfg_do_global_parameter ( lp_ctx , " follow symlinks " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " machine password timeout " , " 604800 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " ldap connection timeout " , " 2 " ) ;
2014-07-24 11:12:14 +04:00
lpcfg_do_global_parameter ( lp_ctx , " winbind expand groups " , " 0 " ) ;
2014-01-08 04:21:39 +04:00
lpcfg_do_global_parameter ( lp_ctx , " stat cache " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " lpq cache time " , " 30 " ) ;
2014-01-16 04:32:42 +04:00
lpcfg_do_global_parameter_var ( lp_ctx , " smb2 max trans " , " %u " , DEFAULT_SMB2_MAX_TRANSACT ) ;
2014-01-08 04:21:39 +04:00
2014-01-16 04:32:42 +04:00
lpcfg_do_global_parameter_var ( lp_ctx , " smb2 max read " , " %u " , DEFAULT_SMB2_MAX_READ ) ;
2014-01-08 04:21:39 +04:00
lpcfg_do_global_parameter ( lp_ctx , " durable handles " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " max stat cache size " , " 256 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " ldap passwd sync " , " no " ) ;
lpcfg_do_global_parameter ( lp_ctx , " kernel change notify " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " max ttl " , " 259200 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " blocking locks " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " oplock contention limit " , " 2 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " load printers " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " idmap cache time " , " 604800 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " preserve case " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " lm announce " , " auto " ) ;
lpcfg_do_global_parameter ( lp_ctx , " afs token lifetime " , " 604800 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " enable core files " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " winbind max domain connections " , " 1 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " case sensitive " , " auto " ) ;
lpcfg_do_global_parameter ( lp_ctx , " ldap timeout " , " 15 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " mangle prefix " , " 1 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " posix locking " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " lock spin time " , " 200 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " directory name cache size " , " 100 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " nmbd bind explicit broadcast " , " yes " ) ;
lpcfg_do_global_parameter ( lp_ctx , " init logon delay " , " 100 " ) ;
lpcfg_do_global_parameter ( lp_ctx , " usershare owner only " , " yes " ) ;
2014-01-08 05:38:09 +04:00
lpcfg_do_global_parameter ( lp_ctx , " -valid " , " yes " ) ;
2014-01-09 04:33:15 +04:00
lpcfg_do_global_parameter_var ( lp_ctx , " usershare path " , " %s/usershares " , get_dyn_STATEDIR ( ) ) ;
2014-01-09 04:33:51 +04:00
# ifdef DEVELOPER
lpcfg_do_global_parameter_var ( lp_ctx , " panic action " , " /bin/sleep 999999999 " ) ;
# endif
2014-01-09 04:34:58 +04:00
lpcfg_do_global_parameter ( lp_ctx , " smb passwd file " , get_dyn_SMB_PASSWD_FILE ( ) ) ;
2014-01-09 04:36:24 +04:00
lpcfg_do_global_parameter ( lp_ctx , " logon home " , " \\ \\ %N \\ %U " ) ;
2014-01-09 04:37:05 +04:00
lpcfg_do_global_parameter ( lp_ctx , " logon path " , " \\ \\ %N \\ %U \\ profile " ) ;
2014-01-09 04:38:07 +04:00
lpcfg_do_global_parameter ( lp_ctx , " printjob username " , " %U " ) ;
2015-03-16 02:30:27 +03:00
/* Allow modules to adjust defaults */
for ( defaults_hook = defaults_hooks ; defaults_hook ;
defaults_hook = defaults_hook - > next ) {
bool ret ;
ret = defaults_hook - > hook ( lp_ctx ) ;
if ( ! ret ) {
DEBUG ( 1 , ( " Defaults hook %s failed to run. " ,
defaults_hook - > name ) ) ;
talloc_free ( lp_ctx ) ;
return NULL ;
}
}
2011-10-06 12:34:50 +04:00
for ( i = 0 ; parm_table [ i ] . label ; i + + ) {
if ( ! ( lp_ctx - > flags [ i ] & FLAG_CMDLINE ) ) {
lp_ctx - > flags [ i ] | = FLAG_DEFAULT ;
}
}
for ( parm = lp_ctx - > globals - > param_opt ; parm ; parm = parm - > next ) {
if ( ! ( parm - > priority & FLAG_CMDLINE ) ) {
parm - > priority | = FLAG_DEFAULT ;
}
}
2014-02-26 07:43:44 +04:00
for ( parm = lp_ctx - > sDefault - > param_opt ; parm ; parm = parm - > next ) {
if ( ! ( parm - > priority & FLAG_CMDLINE ) ) {
parm - > priority | = FLAG_DEFAULT ;
}
}
2011-10-06 12:34:50 +04:00
return lp_ctx ;
}
/**
* Initialise the global parameter structure .
*/
struct loadparm_context * loadparm_init_global ( bool load_default )
{
if ( global_loadparm_context = = NULL ) {
global_loadparm_context = loadparm_init ( NULL ) ;
}
if ( global_loadparm_context = = NULL ) {
return NULL ;
}
global_loadparm_context - > global = true ;
if ( load_default & & ! global_loadparm_context - > loaded ) {
lpcfg_load_default ( global_loadparm_context ) ;
}
global_loadparm_context - > refuse_free = true ;
return global_loadparm_context ;
}
/**
* Initialise the global parameter structure .
*/
struct loadparm_context * loadparm_init_s3 ( TALLOC_CTX * mem_ctx ,
2012-06-27 17:24:39 +04:00
const struct loadparm_s3_helpers * s3_fns )
2011-10-06 12:34:50 +04:00
{
2011-10-13 13:16:28 +04:00
struct loadparm_context * loadparm_context = talloc_zero ( mem_ctx , struct loadparm_context ) ;
2011-10-06 12:34:50 +04:00
if ( ! loadparm_context ) {
return NULL ;
}
loadparm_context - > s3_fns = s3_fns ;
2014-01-24 06:38:59 +04:00
loadparm_context - > globals = s3_fns - > globals ;
2014-02-28 04:19:16 +04:00
loadparm_context - > flags = s3_fns - > flags ;
2011-10-06 12:34:50 +04:00
return loadparm_context ;
}
const char * lpcfg_configfile ( struct loadparm_context * lp_ctx )
{
return lp_ctx - > szConfigFile ;
}
const char * lp_default_path ( void )
{
if ( getenv ( " SMB_CONF_PATH " ) )
return getenv ( " SMB_CONF_PATH " ) ;
else
return dyn_CONFIGFILE ;
}
/**
* Update the internal state of a loadparm context after settings
* have changed .
*/
static bool lpcfg_update ( struct loadparm_context * lp_ctx )
{
struct debug_settings settings ;
2014-01-17 01:30:37 +04:00
TALLOC_CTX * tmp_ctx ;
tmp_ctx = talloc_new ( lp_ctx ) ;
if ( tmp_ctx = = NULL ) {
return false ;
}
lpcfg_add_auto_services ( lp_ctx , lpcfg_auto_services ( lp_ctx , tmp_ctx ) ) ;
2011-10-06 12:34:50 +04:00
2013-12-24 07:04:26 +04:00
if ( ! lp_ctx - > globals - > wins_server_list & & lp_ctx - > globals - > we_are_a_wins_server ) {
2011-10-06 12:34:50 +04:00
lpcfg_do_global_parameter ( lp_ctx , " wins server " , " 127.0.0.1 " ) ;
}
if ( ! lp_ctx - > global ) {
2014-01-17 01:30:37 +04:00
TALLOC_FREE ( tmp_ctx ) ;
2011-10-06 12:34:50 +04:00
return true ;
}
2013-12-24 07:04:32 +04:00
panic_action = lp_ctx - > globals - > panic_action ;
2011-10-06 12:34:50 +04:00
reload_charcnv ( lp_ctx ) ;
ZERO_STRUCT ( settings ) ;
/* Add any more debug-related smb.conf parameters created in
* future here */
2013-12-24 07:03:54 +04:00
settings . timestamp_logs = lp_ctx - > globals - > timestamp_logs ;
2013-12-24 07:03:45 +04:00
settings . debug_prefix_timestamp = lp_ctx - > globals - > debug_prefix_timestamp ;
2013-12-24 07:03:45 +04:00
settings . debug_hires_timestamp = lp_ctx - > globals - > debug_hires_timestamp ;
2013-12-24 07:03:45 +04:00
settings . debug_pid = lp_ctx - > globals - > debug_pid ;
2013-12-24 07:03:45 +04:00
settings . debug_uid = lp_ctx - > globals - > debug_uid ;
2013-12-24 07:03:45 +04:00
settings . debug_class = lp_ctx - > globals - > debug_class ;
2015-01-10 00:46:32 +03:00
debug_set_settings ( & settings , lp_ctx - > globals - > logging ,
lp_ctx - > globals - > syslog ,
lp_ctx - > globals - > syslog_only ) ;
2011-10-06 12:34:50 +04:00
/* FIXME: This is a bit of a hack, but we can't use a global, since
* not everything that uses lp also uses the socket library */
if ( lpcfg_parm_bool ( lp_ctx , NULL , " socket " , " testnonblock " , false ) ) {
setenv ( " SOCKET_TESTNONBLOCK " , " 1 " , 1 ) ;
} else {
unsetenv ( " SOCKET_TESTNONBLOCK " ) ;
}
2014-01-17 01:30:37 +04:00
TALLOC_FREE ( tmp_ctx ) ;
2011-10-06 12:34:50 +04:00
return true ;
}
bool lpcfg_load_default ( struct loadparm_context * lp_ctx )
{
const char * path ;
path = lp_default_path ( ) ;
if ( ! file_exist ( path ) ) {
/* We allow the default smb.conf file to not exist,
* basically the equivalent of an empty file . */
return lpcfg_update ( lp_ctx ) ;
}
return lpcfg_load ( lp_ctx , path ) ;
}
/**
* Load the services array from the services file .
*
* Return True on success , False on failure .
*/
bool lpcfg_load ( struct loadparm_context * lp_ctx , const char * filename )
{
char * n2 ;
bool bRetval ;
filename = talloc_strdup ( lp_ctx , filename ) ;
lp_ctx - > szConfigFile = filename ;
if ( lp_ctx - > s3_fns ) {
return lp_ctx - > s3_fns - > load ( filename ) ;
}
lp_ctx - > bInGlobalSection = true ;
n2 = standard_sub_basic ( lp_ctx , lp_ctx - > szConfigFile ) ;
DEBUG ( 2 , ( " lpcfg_load: refreshing parameters from %s \n " , n2 ) ) ;
2014-02-20 01:58:15 +04:00
add_to_file_list ( lp_ctx , & lp_ctx - > file_lists , lp_ctx - > szConfigFile , n2 ) ;
2011-10-06 12:34:50 +04:00
/* We get sections first, so have to start 'behind' to make up */
lp_ctx - > currentService = NULL ;
2014-03-20 02:00:11 +04:00
bRetval = pm_process ( n2 , do_section , lpcfg_do_parameter , lp_ctx ) ;
2011-10-06 12:34:50 +04:00
/* finish up the last section */
DEBUG ( 4 , ( " pm_process() returned %s \n " , BOOLSTR ( bRetval ) ) ) ;
if ( bRetval )
if ( lp_ctx - > currentService ! = NULL )
2011-10-09 16:22:11 +04:00
bRetval = lpcfg_service_ok ( lp_ctx - > currentService ) ;
2011-10-06 12:34:50 +04:00
bRetval = bRetval & & lpcfg_update ( lp_ctx ) ;
/* we do this unconditionally, so that it happens even
for a missing smb . conf */
reload_charcnv ( lp_ctx ) ;
if ( bRetval = = true ) {
/* set this up so that any child python tasks will
find the right smb . conf */
setenv ( " SMB_CONF_PATH " , filename , 1 ) ;
/* set the context used by the lp_*() function
varients */
global_loadparm_context = lp_ctx ;
lp_ctx - > loaded = true ;
}
return bRetval ;
}
/**
* Return the max number of services .
*/
int lpcfg_numservices ( struct loadparm_context * lp_ctx )
{
if ( lp_ctx - > s3_fns ) {
return lp_ctx - > s3_fns - > get_numservices ( ) ;
}
return lp_ctx - > iNumServices ;
}
/**
* Display the contents of the services array in human - readable form .
*/
void lpcfg_dump ( struct loadparm_context * lp_ctx , FILE * f , bool show_defaults ,
int maxtoprint )
{
int iService ;
if ( lp_ctx - > s3_fns ) {
lp_ctx - > s3_fns - > dump ( f , show_defaults , maxtoprint ) ;
return ;
}
2014-03-21 01:45:51 +04:00
lpcfg_dump_globals ( lp_ctx , f , show_defaults ) ;
2011-10-06 12:34:50 +04:00
2014-01-27 06:32:39 +04:00
lpcfg_dump_a_service ( lp_ctx - > sDefault , lp_ctx - > sDefault , f , lp_ctx - > flags , show_defaults ) ;
2011-10-06 12:34:50 +04:00
for ( iService = 0 ; iService < maxtoprint ; iService + + )
lpcfg_dump_one ( f , show_defaults , lp_ctx - > services [ iService ] , lp_ctx - > sDefault ) ;
}
/**
* Display the contents of one service in human - readable form .
*/
void lpcfg_dump_one ( FILE * f , bool show_defaults , struct loadparm_service * service , struct loadparm_service * sDefault )
{
if ( service ! = NULL ) {
if ( service - > szService [ 0 ] = = ' \0 ' )
return ;
2014-01-27 06:32:39 +04:00
lpcfg_dump_a_service ( service , sDefault , f , NULL , show_defaults ) ;
2011-10-06 12:34:50 +04:00
}
}
struct loadparm_service * lpcfg_servicebynum ( struct loadparm_context * lp_ctx ,
int snum )
{
if ( lp_ctx - > s3_fns ) {
return lp_ctx - > s3_fns - > get_servicebynum ( snum ) ;
}
return lp_ctx - > services [ snum ] ;
}
struct loadparm_service * lpcfg_service ( struct loadparm_context * lp_ctx ,
const char * service_name )
{
int iService ;
char * serviceName ;
if ( lp_ctx - > s3_fns ) {
return lp_ctx - > s3_fns - > get_service ( service_name ) ;
}
for ( iService = lp_ctx - > iNumServices - 1 ; iService > = 0 ; iService - - ) {
if ( lp_ctx - > services [ iService ] & &
lp_ctx - > services [ iService ] - > szService ) {
/*
* The substitution here is used to support % U is
* service names
*/
serviceName = standard_sub_basic (
lp_ctx - > services [ iService ] ,
lp_ctx - > services [ iService ] - > szService ) ;
if ( strequal ( serviceName , service_name ) ) {
talloc_free ( serviceName ) ;
return lp_ctx - > services [ iService ] ;
}
talloc_free ( serviceName ) ;
}
}
DEBUG ( 7 , ( " lpcfg_servicenumber: couldn't find %s \n " , service_name ) ) ;
return NULL ;
}
const char * lpcfg_servicename ( const struct loadparm_service * service )
{
2014-02-14 01:23:36 +04:00
return lpcfg_string ( ( const char * ) service - > szService ) ;
2011-10-06 12:34:50 +04:00
}
/**
* A useful volume label function .
*/
const char * lpcfg_volume_label ( struct loadparm_service * service , struct loadparm_service * sDefault )
{
const char * ret ;
2014-02-14 01:23:36 +04:00
ret = lpcfg_string ( ( const char * ) ( ( service ! = NULL & & service - > volume ! = NULL ) ?
2011-10-06 12:34:50 +04:00
service - > volume : sDefault - > volume ) ) ;
if ( ! * ret )
return lpcfg_servicename ( service ) ;
return ret ;
}
/**
2014-01-10 02:19:56 +04:00
* Return the correct printer name .
2011-10-06 12:34:50 +04:00
*/
const char * lpcfg_printername ( struct loadparm_service * service , struct loadparm_service * sDefault )
{
const char * ret ;
2014-02-14 01:23:36 +04:00
ret = lpcfg_string ( ( const char * ) ( ( service ! = NULL & & service - > _printername ! = NULL ) ?
2014-01-30 07:54:39 +04:00
service - > _printername : sDefault - > _printername ) ) ;
2011-10-06 12:34:50 +04:00
if ( ret = = NULL | | ( ret ! = NULL & & * ret = = ' \0 ' ) )
ret = lpcfg_servicename ( service ) ;
return ret ;
}
/**
* Return the max print jobs per queue .
*/
int lpcfg_maxprintjobs ( struct loadparm_service * service , struct loadparm_service * sDefault )
{
int maxjobs = ( service ! = NULL ) ? service - > iMaxPrintJobs : sDefault - > iMaxPrintJobs ;
if ( maxjobs < = 0 | | maxjobs > = PRINT_MAX_JOBID )
maxjobs = PRINT_MAX_JOBID - 1 ;
return maxjobs ;
}
struct smb_iconv_handle * lpcfg_iconv_handle ( struct loadparm_context * lp_ctx )
{
if ( lp_ctx = = NULL ) {
return get_iconv_handle ( ) ;
}
return lp_ctx - > iconv_handle ;
}
_PUBLIC_ void reload_charcnv ( struct loadparm_context * lp_ctx )
{
struct smb_iconv_handle * old_ic = lp_ctx - > iconv_handle ;
if ( ! lp_ctx - > global ) {
return ;
}
if ( old_ic = = NULL ) {
old_ic = global_iconv_handle ;
}
lp_ctx - > iconv_handle = smb_iconv_handle_reinit_lp ( lp_ctx , lp_ctx , old_ic ) ;
global_iconv_handle = lp_ctx - > iconv_handle ;
}
_PUBLIC_ char * lpcfg_tls_keyfile ( TALLOC_CTX * mem_ctx , struct loadparm_context * lp_ctx )
{
2014-01-16 04:13:11 +04:00
return lpcfg_private_path ( mem_ctx , lp_ctx , lpcfg__tls_keyfile ( lp_ctx ) ) ;
2011-10-06 12:34:50 +04:00
}
_PUBLIC_ char * lpcfg_tls_certfile ( TALLOC_CTX * mem_ctx , struct loadparm_context * lp_ctx )
{
2014-01-16 04:13:11 +04:00
return lpcfg_private_path ( mem_ctx , lp_ctx , lpcfg__tls_certfile ( lp_ctx ) ) ;
2011-10-06 12:34:50 +04:00
}
_PUBLIC_ char * lpcfg_tls_cafile ( TALLOC_CTX * mem_ctx , struct loadparm_context * lp_ctx )
{
2014-01-16 04:13:11 +04:00
return lpcfg_private_path ( mem_ctx , lp_ctx , lpcfg__tls_cafile ( lp_ctx ) ) ;
2011-10-06 12:34:50 +04:00
}
_PUBLIC_ char * lpcfg_tls_crlfile ( TALLOC_CTX * mem_ctx , struct loadparm_context * lp_ctx )
{
2014-01-16 04:13:11 +04:00
return lpcfg_private_path ( mem_ctx , lp_ctx , lpcfg__tls_crlfile ( lp_ctx ) ) ;
2011-10-06 12:34:50 +04:00
}
_PUBLIC_ char * lpcfg_tls_dhpfile ( TALLOC_CTX * mem_ctx , struct loadparm_context * lp_ctx )
{
2014-01-16 04:13:11 +04:00
return lpcfg_private_path ( mem_ctx , lp_ctx , lpcfg__tls_dhpfile ( lp_ctx ) ) ;
2011-10-06 12:34:50 +04:00
}
struct gensec_settings * lpcfg_gensec_settings ( TALLOC_CTX * mem_ctx , struct loadparm_context * lp_ctx )
{
2011-12-26 03:53:56 +04:00
struct gensec_settings * settings = talloc_zero ( mem_ctx , struct gensec_settings ) ;
2011-10-06 12:34:50 +04:00
if ( settings = = NULL )
return NULL ;
SMB_ASSERT ( lp_ctx ! = NULL ) ;
settings - > lp_ctx = talloc_reference ( settings , lp_ctx ) ;
settings - > target_hostname = lpcfg_parm_string ( lp_ctx , NULL , " gensec " , " target_hostname " ) ;
return settings ;
}
2011-11-10 05:45:54 +04:00
int lpcfg_server_role ( struct loadparm_context * lp_ctx )
{
2012-07-23 07:32:31 +04:00
int domain_master = lpcfg__domain_master ( lp_ctx ) ;
2011-11-10 05:45:54 +04:00
2012-07-23 07:32:31 +04:00
return lp_find_server_role ( lpcfg__server_role ( lp_ctx ) ,
lpcfg__security ( lp_ctx ) ,
lpcfg__domain_logons ( lp_ctx ) ,
( domain_master = = true ) | |
( domain_master = = Auto ) ) ;
2011-11-10 05:45:54 +04:00
}
2011-11-10 10:11:18 +04:00
int lpcfg_security ( struct loadparm_context * lp_ctx )
{
2012-07-23 07:32:31 +04:00
return lp_find_security ( lpcfg__server_role ( lp_ctx ) ,
lpcfg__security ( lp_ctx ) ) ;
2011-11-10 10:11:18 +04:00
}
2013-10-14 04:45:42 +04:00
2014-09-24 01:08:10 +04:00
int lpcfg_client_max_protocol ( struct loadparm_context * lp_ctx )
{
int client_max_protocol = lpcfg__client_max_protocol ( lp_ctx ) ;
if ( client_max_protocol = = PROTOCOL_DEFAULT ) {
return PROTOCOL_NT1 ;
}
return client_max_protocol ;
}
2013-10-14 04:45:42 +04:00
bool lpcfg_server_signing_allowed ( struct loadparm_context * lp_ctx , bool * mandatory )
{
bool allowed = true ;
enum smb_signing_setting signing_setting = lpcfg_server_signing ( lp_ctx ) ;
* mandatory = false ;
if ( signing_setting = = SMB_SIGNING_DEFAULT ) {
/*
* If we are a domain controller , SMB signing is
* really important , as it can prevent a number of
* attacks on communications between us and the
* clients
*
* However , it really sucks ( no sendfile , CPU
* overhead ) performance - wise when used on a
* file server , so disable it by default
* on non - DCs
*/
if ( lpcfg_server_role ( lp_ctx ) > = ROLE_ACTIVE_DIRECTORY_DC ) {
signing_setting = SMB_SIGNING_REQUIRED ;
} else {
signing_setting = SMB_SIGNING_OFF ;
}
}
switch ( signing_setting ) {
case SMB_SIGNING_REQUIRED :
* mandatory = true ;
break ;
case SMB_SIGNING_IF_REQUIRED :
break ;
case SMB_SIGNING_DEFAULT :
case SMB_SIGNING_OFF :
allowed = false ;
break ;
}
return allowed ;
}
2014-03-26 18:04:41 +04:00
int lpcfg_tdb_hash_size ( struct loadparm_context * lp_ctx , const char * name )
{
const char * base ;
if ( name = = NULL ) {
return 0 ;
}
base = strrchr_m ( name , ' / ' ) ;
if ( base ! = NULL ) {
base + = 1 ;
} else {
base = name ;
}
return lpcfg_parm_int ( lp_ctx , NULL , " tdb_hashsize " , base , 0 ) ;
}
2014-03-26 18:06:08 +04:00
int lpcfg_tdb_flags ( struct loadparm_context * lp_ctx , int tdb_flags )
{
if ( ! lpcfg_use_mmap ( lp_ctx ) ) {
tdb_flags | = TDB_NOMMAP ;
}
return tdb_flags ;
}