diff options
Diffstat (limited to 'source3/param')
-rw-r--r-- | source3/param/.cvsignore | 3 | ||||
-rw-r--r-- | source3/param/loadparm.c | 5015 | ||||
-rw-r--r-- | source3/param/params.c | 882 |
3 files changed, 4182 insertions, 1718 deletions
diff --git a/source3/param/.cvsignore b/source3/param/.cvsignore new file mode 100644 index 0000000000..76e2d7ff3e --- /dev/null +++ b/source3/param/.cvsignore @@ -0,0 +1,3 @@ +*.po32 +*.po + diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index c61ab26781..bdd710f5fe 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -1,10 +1,11 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. Parameter loading functions - Copyright (C) Karl Auer 1993,1994 + Copyright (C) Karl Auer 1993-1998 Largely re-written by Andrew Tridgell, September 1994 + + Copyright (C) Simo Sorce 2001 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 @@ -49,29 +50,19 @@ #include "includes.h" -#include "params.h" -#include "loadparm.h" -#include "pcap.h" - +BOOL in_client = False; /* Not in the client by default */ BOOL bLoaded = False; -extern int DEBUGLEVEL; -extern int ReadSize; +extern userdom_struct current_user_info; +extern int DEBUGLEVEL_CLASS[DBGC_LAST]; extern pstring user_socket_options; -extern pstring smbrun_path; +extern pstring global_myname; +pstring global_scope = ""; #ifndef GLOBAL_NAME #define GLOBAL_NAME "global" #endif -#ifndef PRINTCAP_NAME -#ifdef AIX -#define PRINTCAP_NAME "/etc/qconfig" -#else -#define PRINTCAP_NAME "/etc/printcap" -#endif -#endif - #ifndef PRINTERS_NAME #define PRINTERS_NAME "printers" #endif @@ -81,87 +72,211 @@ extern pstring smbrun_path; #endif /* some helpful bits */ -#define pSERVICE(i) ServicePtrs[i] -#define iSERVICE(i) (*pSERVICE(i)) -#define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid) -#define VALID(i) iSERVICE(i).valid - -/* these are the types of parameter we have */ -typedef enum -{ - P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_STRING,P_GSTRING -} parm_type; - -typedef enum -{ - P_LOCAL,P_GLOBAL,P_NONE -} parm_class; +#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid) +#define VALID(i) ServicePtrs[i]->valid -int keepalive=0; -extern BOOL use_getwd_cache; +int keepalive = DEFAULT_KEEPALIVE; +BOOL use_getwd_cache = True; extern int extra_time_offset; -#ifdef KANJI -extern int coding_system; -#endif + +static BOOL defaults_saved = False; /* * This structure describes global (ie., server-wide) parameters. */ typedef struct { - char *szPrintcapname; - char *szLockDir; - char *szRootdir; - char *szDefaultService; - char *szDfree; - char *szMsgCommand; - char *szHostsEquiv; - char *szServerString; - char *szAutoServices; - char *szPasswdProgram; - char *szPasswdChat; - char *szLogFile; - char *szConfigFile; - char *szSMBPasswdFile; - char *szPasswordServer; - char *szSocketOptions; - char *szValidChars; - char *szWorkGroup; - char *szDomainController; - char *szUsernameMap; - char *szCharacterSet; - char *szLogonScript; - int max_log_size; - int mangled_stack; - int max_xmit; - int max_mux; - int max_packet; - int pwordlevel; - int deadtime; - int maxprotocol; - int security; - int printing; - int maxdisksize; - int lpqcachetime; - int syslog; - int os_level; - int max_ttl; - BOOL bPreferredMaster; - BOOL bDomainMaster; - BOOL bDomainLogons; - BOOL bEncryptPasswords; - BOOL bStripDot; - BOOL bNullPasswords; - BOOL bLoadPrinters; - BOOL bUseRhosts; - BOOL bReadRaw; - BOOL bWriteRaw; - BOOL bReadPrediction; - BOOL bReadbmpx; - BOOL bSyslogOnly; - BOOL bBrowseList; -} global; + char *dos_charset; + char *unix_charset; + char *display_charset; + char *szPrintcapname; + char *szEnumPortsCommand; + char *szAddPrinterCommand; + char *szDeletePrinterCommand; + char *szOs2DriverMap; + char *szLockDir; + char *szRootdir; + char *szDefaultService; + char *szDfree; + char *szMsgCommand; + char *szHostsEquiv; + char *szServerString; + char *szAutoServices; + char *szPasswdProgram; + char *szPasswdChat; + char *szLogFile; + char *szConfigFile; + char *szSMBPasswdFile; + char *szPrivateDir; + char *szPassdbBackend; + char *szPasswordServer; + char *szSocketOptions; + char *szWorkGroup; + char *szRealm; + char *szADSserver; + char *szUsernameMap; + char *szLogonScript; + char *szLogonPath; + char *szLogonDrive; + char *szLogonHome; + char *szWINSserver; + char **szInterfaces; + char *szRemoteAnnounce; + char *szRemoteBrowseSync; + char *szSocketAddress; + char *szNISHomeMapName; + char *szAnnounceVersion; /* This is initialised in init_globals */ + char **szNetbiosAliases; + char *szDomainOtherSIDs; + char *szNameResolveOrder; + char *szPanicAction; + char *szAddUserScript; + char *szDelUserScript; + char *szAddGroupScript; + char *szDelGroupScript; + char *szAddUserToGroupScript; + char *szDelUserToGroupScript; + char *szAddMachineScript; + char *szShutdownScript; + char *szAbortShutdownScript; + char *szWINSHook; + char *szWINSPartners; +#ifdef WITH_UTMP + char *szUtmpDir; + char *szWtmpDir; + BOOL bUtmp; +#endif + char *szSourceEnv; + char *szWinbindUID; + char *szWinbindGID; + char *szNonUnixAccountRange; + char *szTemplateHomedir; + char *szTemplateShell; + char *szWinbindSeparator; + BOOL bWinbindEnumUsers; + BOOL bWinbindEnumGroups; + BOOL bWinbindUseDefaultDomain; + char *szAddShareCommand; + char *szChangeShareCommand; + char *szDeleteShareCommand; + char *szGuestaccount; + char *szManglingMethod; + int max_log_size; + int mangled_stack; + int max_xmit; + int max_mux; + int max_open_files; + int max_packet; + int pwordlevel; + int unamelevel; + int deadtime; + int maxprotocol; + int minprotocol; + int security; + char **AuthMethods; + BOOL paranoid_server_security; + int maxdisksize; + int lpqcachetime; + int iMaxSmbdProcesses; + BOOL bDisableSpoolss; + int iTotalPrintJobs; + int syslog; + int os_level; + int enhanced_browsing; + int max_ttl; + int max_wins_ttl; + int min_wins_ttl; + int ReadSize; + int lm_announce; + int lm_interval; + int announce_as; /* This is initialised in init_globals */ + int machine_password_timeout; + int change_notify_timeout; + int stat_cache_size; + int map_to_guest; + int min_passwd_length; + int oplock_break_wait_time; + int winbind_cache_time; + int iLockSpinCount; + int iLockSpinTime; +#ifdef WITH_LDAP_SAM + char *szLdapMachineSuffix; + char *szLdapUserSuffix; + int ldap_port; + int ldap_ssl; + char *szLdapSuffix; + char *szLdapFilter; + char *szLdapAdminDn; +#endif /* WITH_LDAP_SAM */ +#ifdef WITH_SSL + int sslVersion; + char **sslHostsRequire; + char **sslHostsResign; + char *sslCaCertDir; + char *sslCaCertFile; + char *sslServerCert; + char *sslServerPrivKey; + char *sslClientCert; + char *sslClientPrivKey; + char *sslCiphers; + char *sslEgdSocket; + char *sslEntropyFile; + int sslEntropyBytes; + BOOL sslEnabled; + BOOL sslReqClientCert; + BOOL sslReqServerCert; + BOOL sslCompatibility; +#endif /* WITH_SSL */ + BOOL bMsAddPrinterWizard; + BOOL bDNSproxy; + BOOL bWINSsupport; + BOOL bWINSproxy; + BOOL bLocalMaster; + BOOL bPreferredMaster; + BOOL bDomainMaster; + BOOL bDomainLogons; + BOOL bEncryptPasswords; + BOOL bUpdateEncrypt; + BOOL bStripDot; + BOOL bNullPasswords; + BOOL bObeyPamRestrictions; + BOOL bLoadPrinters; + BOOL bLargeReadwrite; + BOOL bReadRaw; + BOOL bWriteRaw; + BOOL bReadPrediction; + BOOL bReadbmpx; + BOOL bSyslogOnly; + BOOL bAdminLog; + BOOL bBrowseList; + BOOL bNISHomeMap; + BOOL bTimeServer; + BOOL bBindInterfacesOnly; + BOOL bPamPasswordChange; + BOOL bUnixPasswdSync; + BOOL bPasswdChatDebug; + BOOL bTimestampLogs; + BOOL bNTSmbSupport; + BOOL bNTPipeSupport; + BOOL bNTStatusSupport; + BOOL bStatCache; + BOOL bKernelOplocks; + BOOL bAllowTrustedDomains; + BOOL bRestrictAnonymous; + BOOL bLanmanAuth; + BOOL bNTLMAuth; + BOOL bDebugHiresTimestamp; + BOOL bDebugPid; + BOOL bDebugUid; + BOOL bHostMSDfs; + BOOL bHideLocalUsers; + BOOL bUnicode; + BOOL bUseMmap; + BOOL bHostnameLookups; + BOOL bUseSpnego; +} +global; static global Globals; @@ -172,477 +287,1195 @@ static global Globals; */ typedef struct { - BOOL valid; - char *szService; - char *szPath; - char *szUsername; - char *szGuestaccount; - char *szInvalidUsers; - char *szValidUsers; - char *szAdminUsers; - char *szCopy; - char *szInclude; - char *szPreExec; - char *szPostExec; - char *szRootPreExec; - char *szRootPostExec; - char *szPrintcommand; - char *szLpqcommand; - char *szLprmcommand; - char *szLppausecommand; - char *szLpresumecommand; - char *szPrintername; - char *szDontdescend; - char *szHostsallow; - char *szHostsdeny; - char *szMagicScript; - char *szMagicOutput; - char *szMangledMap; - char *comment; - char *force_user; - char *force_group; - char *readlist; - char *writelist; - char *volume; - int iMinPrintSpace; - int iCreate_mode; - int iMaxConnections; - int iDefaultCase; - BOOL bAlternatePerm; - BOOL bRevalidate; - BOOL bCaseSensitive; - BOOL bCasePreserve; - BOOL bShortCasePreserve; - BOOL bCaseMangle; - BOOL status; - BOOL bHideDotFiles; - BOOL bBrowseable; - BOOL bAvailable; - BOOL bRead_only; - BOOL bNo_set_dir; - BOOL bGuest_only; - BOOL bGuest_ok; - BOOL bPrint_ok; - BOOL bPostscript; - BOOL bMap_system; - BOOL bMap_hidden; - BOOL bMap_archive; - BOOL bLocking; - BOOL bStrictLocking; - BOOL bShareModes; - BOOL bOnlyUser; - BOOL bMangledNames; - BOOL bWidelinks; - BOOL bSyncAlways; - char magic_char; - BOOL *copymap; - char dummy[3]; /* for alignment */ -} service; + BOOL valid; + BOOL autoloaded; + char *szService; + char *szPath; + char *szUsername; + char **szInvalidUsers; + char **szValidUsers; + char **szAdminUsers; + char *szCopy; + char *szInclude; + char *szPreExec; + char *szPostExec; + char *szRootPreExec; + char *szRootPostExec; + char *szPrintcommand; + char *szLpqcommand; + char *szLprmcommand; + char *szLppausecommand; + char *szLpresumecommand; + char *szQueuepausecommand; + char *szQueueresumecommand; + char *szPrintername; + char *szPrinterDriver; + char *szPrinterDriverLocation; + char *szDriverFile; + char *szDontdescend; + char **szHostsallow; + char **szHostsdeny; + char *szMagicScript; + char *szMagicOutput; + char *szMangledMap; + char *szVetoFiles; + char *szHideFiles; + char *szVetoOplockFiles; + char *comment; + char *force_user; + char *force_group; + char **readlist; + char **writelist; + char **printer_admin; + char *volume; + char *fstype; + char *szVfsObjectFile; + char *szVfsOptions; + int iMinPrintSpace; + int iMaxPrintJobs; + int iWriteCacheSize; + int iCreate_mask; + int iCreate_force_mode; + int iSecurity_mask; + int iSecurity_force_mode; + int iDir_mask; + int iDir_force_mode; + int iDir_Security_mask; + int iDir_Security_force_mode; + int iMaxConnections; + int iDefaultCase; + int iPrinting; + int iOplockContentionLimit; + int iCSCPolicy; + BOOL bAlternatePerm; + BOOL bPreexecClose; + BOOL bRootpreexecClose; + BOOL bCaseSensitive; + BOOL bCasePreserve; + BOOL bShortCasePreserve; + BOOL bCaseMangle; + BOOL bHideDotFiles; + BOOL bHideUnReadable; + BOOL bBrowseable; + BOOL bAvailable; + BOOL bRead_only; + BOOL bNo_set_dir; + BOOL bGuest_only; + BOOL bGuest_ok; + BOOL bPrint_ok; + BOOL bPostscript; + BOOL bMap_system; + BOOL bMap_hidden; + BOOL bMap_archive; + BOOL bLocking; + BOOL bStrictLocking; + BOOL bPosixLocking; + BOOL bShareModes; + BOOL bOpLocks; + BOOL bLevel2OpLocks; + BOOL bOnlyUser; + BOOL bMangledNames; + BOOL bWidelinks; + BOOL bSymlinks; + BOOL bSyncAlways; + BOOL bStrictAllocate; + BOOL bStrictSync; + char magic_char; + BOOL *copymap; + BOOL bDeleteReadonly; + BOOL bFakeOplocks; + BOOL bDeleteVetoFiles; + BOOL bDosFilemode; + BOOL bDosFiletimes; + BOOL bDosFiletimeResolution; + BOOL bFakeDirCreateTimes; + BOOL bBlockingLocks; + BOOL bInheritPerms; + BOOL bInheritACLS; + BOOL bMSDfsRoot; + BOOL bUseClientDriver; + BOOL bDefaultDevmode; + BOOL bNTAclSupport; + + char dummy[3]; /* for alignment */ +} +service; /* This is a default service used to prime a services structure */ -static service sDefault = -{ - True, /* valid */ - NULL, /* szService */ - NULL, /* szPath */ - NULL, /* szUsername */ - NULL, /* szGuestAccount */ - NULL, /* szInvalidUsers */ - NULL, /* szValidUsers */ - NULL, /* szAdminUsers */ - NULL, /* szCopy */ - NULL, /* szInclude */ - NULL, /* szPreExec */ - NULL, /* szPostExec */ - NULL, /* szRootPreExec */ - NULL, /* szRootPostExec */ - NULL, /* szPrintcommand */ - NULL, /* szLpqcommand */ - NULL, /* szLprmcommand */ - NULL, /* szLppausecommand */ - NULL, /* szLpresumecommand */ - NULL, /* szPrintername */ - NULL, /* szDontdescend */ - NULL, /* szHostsallow */ - NULL, /* szHostsdeny */ - NULL, /* szMagicScript */ - NULL, /* szMagicOutput */ - NULL, /* szMangledMap */ - NULL, /* comment */ - NULL, /* force user */ - NULL, /* force group */ - NULL, /* readlist */ - NULL, /* writelist */ - NULL, /* volume */ - 0, /* iMinPrintSpace */ - 0755, /* iCreate_mode */ - 0, /* iMaxConnections */ - CASE_LOWER, /* iDefaultCase */ - False, /* bAlternatePerm */ - False, /* revalidate */ - False, /* case sensitive */ - False, /* case preserve */ - False, /* short case preserve */ - False, /* case mangle */ - True, /* status */ - True, /* bHideDotFiles */ - True, /* bBrowseable */ - True, /* bAvailable */ - True, /* bRead_only */ - True, /* bNo_set_dir */ - False, /* bGuest_only */ - False, /* bGuest_ok */ - False, /* bPrint_ok */ - False, /* bPostscript */ - False, /* bMap_system */ - False, /* bMap_hidden */ - True, /* bMap_archive */ - True, /* bLocking */ - False, /* bStrictLocking */ - True, /* bShareModes */ - False, /* bOnlyUser */ - True, /* bMangledNames */ - True, /* bWidelinks */ - False, /* bSyncAlways */ - '~', /* magic char */ - NULL, /* copymap */ - "" /* dummy */ +static service sDefault = { + True, /* valid */ + False, /* not autoloaded */ + NULL, /* szService */ + NULL, /* szPath */ + NULL, /* szUsername */ + NULL, /* szInvalidUsers */ + NULL, /* szValidUsers */ + NULL, /* szAdminUsers */ + NULL, /* szCopy */ + NULL, /* szInclude */ + NULL, /* szPreExec */ + NULL, /* szPostExec */ + NULL, /* szRootPreExec */ + NULL, /* szRootPostExec */ + NULL, /* szPrintcommand */ + NULL, /* szLpqcommand */ + NULL, /* szLprmcommand */ + NULL, /* szLppausecommand */ + NULL, /* szLpresumecommand */ + NULL, /* szQueuepausecommand */ + NULL, /* szQueueresumecommand */ + NULL, /* szPrintername */ + NULL, /* szPrinterDriver - this is set in init_globals() */ + NULL, /* szPrinterDriverLocation */ + NULL, /* szDriverFile */ + NULL, /* szDontdescend */ + NULL, /* szHostsallow */ + NULL, /* szHostsdeny */ + NULL, /* szMagicScript */ + NULL, /* szMagicOutput */ + NULL, /* szMangledMap */ + NULL, /* szVetoFiles */ + NULL, /* szHideFiles */ + NULL, /* szVetoOplockFiles */ + NULL, /* comment */ + NULL, /* force user */ + NULL, /* force group */ + NULL, /* readlist */ + NULL, /* writelist */ + NULL, /* printer admin */ + NULL, /* volume */ + NULL, /* fstype */ + NULL, /* vfs object */ + NULL, /* vfs options */ + 0, /* iMinPrintSpace */ + 1000, /* iMaxPrintJobs */ + 0, /* iWriteCacheSize */ + 0744, /* iCreate_mask */ + 0000, /* iCreate_force_mode */ + 0777, /* iSecurity_mask */ + 0, /* iSecurity_force_mode */ + 0755, /* iDir_mask */ + 0000, /* iDir_force_mode */ + 0777, /* iDir_Security_mask */ + 0, /* iDir_Security_force_mode */ + 0, /* iMaxConnections */ + CASE_LOWER, /* iDefaultCase */ + DEFAULT_PRINTING, /* iPrinting */ + 2, /* iOplockContentionLimit */ + 0, /* iCSCPolicy */ + False, /* bAlternatePerm */ + False, /* bPreexecClose */ + False, /* bRootpreexecClose */ + False, /* case sensitive */ + True, /* case preserve */ + True, /* short case preserve */ + False, /* case mangle */ + True, /* bHideDotFiles */ + False, /* bHideUnReadable */ + True, /* bBrowseable */ + True, /* bAvailable */ + True, /* bRead_only */ + True, /* bNo_set_dir */ + False, /* bGuest_only */ + False, /* bGuest_ok */ + False, /* bPrint_ok */ + False, /* bPostscript */ + False, /* bMap_system */ + False, /* bMap_hidden */ + True, /* bMap_archive */ + True, /* bLocking */ + True, /* bStrictLocking */ + True, /* bPosixLocking */ + True, /* bShareModes */ + True, /* bOpLocks */ + True, /* bLevel2OpLocks */ + False, /* bOnlyUser */ + True, /* bMangledNames */ + True, /* bWidelinks */ + True, /* bSymlinks */ + False, /* bSyncAlways */ + False, /* bStrictAllocate */ + False, /* bStrictSync */ + '~', /* magic char */ + NULL, /* copymap */ + False, /* bDeleteReadonly */ + False, /* bFakeOplocks */ + False, /* bDeleteVetoFiles */ + False, /* bDosFilemode */ + False, /* bDosFiletimes */ + False, /* bDosFiletimeResolution */ + False, /* bFakeDirCreateTimes */ + True, /* bBlockingLocks */ + False, /* bInheritPerms */ + False, /* bInheritACLS */ + False, /* bMSDfsRoot */ + False, /* bUseClientDriver */ + False, /* bDefaultDevmode */ + True, /* bNTAclSupport */ + + "" /* dummy */ }; - - /* local variables */ static service **ServicePtrs = NULL; static int iNumServices = 0; static int iServiceIndex = 0; static BOOL bInGlobalSection = True; static BOOL bGlobalOnly = False; - +static int server_role; +static int default_server_announce; #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct)) /* prototypes for the special type handlers */ -static BOOL handle_valid_chars(char *pszParmValue, char **ptr); static BOOL handle_include(char *pszParmValue, char **ptr); static BOOL handle_copy(char *pszParmValue, char **ptr); -static BOOL handle_protocol(char *pszParmValue,int *val); -static BOOL handle_security(char *pszParmValue,int *val); -static BOOL handle_case(char *pszParmValue,int *val); -static BOOL handle_printing(char *pszParmValue,int *val); -static BOOL handle_character_set(char *pszParmValue,int *val); -#ifdef KANJI -static BOOL handle_coding_system(char *pszParmValue,int *val); -#endif /* KANJI */ - -struct parm_struct -{ - char *label; - parm_type type; - parm_class class; - void *ptr; - BOOL (*special)(); -} parm_table[] = -{ - {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL}, - {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL}, - {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL}, - {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL}, - {"protocol", P_INTEGER, P_GLOBAL, &Globals.maxprotocol,handle_protocol}, - {"security", P_INTEGER, P_GLOBAL, &Globals.security,handle_security}, - {"printing", P_INTEGER, P_GLOBAL, &Globals.printing,handle_printing}, - {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL}, - {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL}, - {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL}, - {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL}, - {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL}, - {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL}, - {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL}, - {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL}, - {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL}, - {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL}, - {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL}, - {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL}, - {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL}, - {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL}, - {"smbrun", P_GSTRING, P_GLOBAL, smbrun_path, NULL}, - {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL}, - {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL}, - {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL}, - {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL}, - {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL}, - {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL}, - {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL}, - {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL}, - {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL}, - {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL}, - {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL}, - {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL}, - {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL}, - {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL}, - {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL}, - {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL}, - {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL}, - {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL}, - {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL}, - {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL}, - {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars}, - {"workgroup", P_STRING, P_GLOBAL, &Globals.szWorkGroup, NULL}, - {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL}, - {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL}, - {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set}, - {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL}, - {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL}, - {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL}, - {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL}, - {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL}, - {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL}, - {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL}, - {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL}, - {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL}, - {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL}, - {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL}, - {"read size", P_INTEGER, P_GLOBAL, &ReadSize, NULL}, -#ifdef KANJI - {"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system}, -#endif /* KANJI */ - {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL}, - {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL}, - {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL}, - {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL}, - {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL}, - {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL}, - {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL}, - - {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL}, - {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL}, - {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy}, - {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include}, - {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL}, - {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL}, - {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL}, - {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL}, - {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL}, - {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL}, - {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL}, - {"default case", P_INTEGER, P_LOCAL, &sDefault.iDefaultCase, handle_case}, - {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL}, - {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL}, - {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL}, - {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL}, - {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL}, - {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL}, - {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL}, - {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL}, - {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL}, - {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL}, - {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL}, - {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL}, - {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL}, - {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL}, - {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL}, - {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL}, - {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL}, - {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL}, - {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL}, - {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL}, - {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL}, - {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL}, - {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL}, - {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL}, - {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL}, - {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL}, - {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL}, - {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL}, - {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL}, - {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL}, - {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mode, NULL}, - {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mode, NULL}, - {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL}, - {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL}, - {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL}, - {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL}, - {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL}, - {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL}, - {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL}, - {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL}, - {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL}, - {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL}, - {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL}, - {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL}, - {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL}, - {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL}, - {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL}, - {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL}, - {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL}, - {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL}, - {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL}, - {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL}, - {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL}, - {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL}, - {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL}, - {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL}, - {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL}, - {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL}, - {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL}, - {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL}, - {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL}, - {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL}, - {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL}, - {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL}, - {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL}, - {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL}, - {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL}, - - {NULL, P_BOOL, P_NONE, NULL, NULL} +static BOOL handle_vfs_object(char *pszParmValue, char **ptr); +static BOOL handle_source_env(char *pszParmValue, char **ptr); +static BOOL handle_netbios_name(char *pszParmValue, char **ptr); +static BOOL handle_winbind_uid(char *pszParmValue, char **ptr); +static BOOL handle_winbind_gid(char *pszParmValue, char **ptr); +static BOOL handle_non_unix_account_range(char *pszParmValue, char **ptr); +static BOOL handle_wins_server_list(char *pszParmValue, char **ptr); +static BOOL handle_debug_list( char *pszParmValue, char **ptr ); + +#if WITH_LDAP_SAM +static BOOL handle_ldap_machine_suffix ( char *pszParmValue, char **ptr ); +static BOOL handle_ldap_user_suffix ( char *pszParmValue, char **ptr ); +static BOOL handle_ldap_suffix ( char *pszParmValue, char **ptr ); +#endif + +static void set_server_role(void); +static void set_default_server_announce_type(void); + +static struct enum_list enum_protocol[] = { + {PROTOCOL_NT1, "NT1"}, + {PROTOCOL_LANMAN2, "LANMAN2"}, + {PROTOCOL_LANMAN1, "LANMAN1"}, + {PROTOCOL_CORE, "CORE"}, + {PROTOCOL_COREPLUS, "COREPLUS"}, + {PROTOCOL_COREPLUS, "CORE+"}, + {-1, NULL} }; +static struct enum_list enum_security[] = { + {SEC_SHARE, "SHARE"}, + {SEC_USER, "USER"}, + {SEC_SERVER, "SERVER"}, + {SEC_DOMAIN, "DOMAIN"}, + {SEC_ADS, "ADS"}, + {-1, NULL} +}; +static struct enum_list enum_printing[] = { + {PRINT_SYSV, "sysv"}, + {PRINT_AIX, "aix"}, + {PRINT_HPUX, "hpux"}, + {PRINT_BSD, "bsd"}, + {PRINT_QNX, "qnx"}, + {PRINT_PLP, "plp"}, + {PRINT_LPRNG, "lprng"}, + {PRINT_SOFTQ, "softq"}, + {PRINT_CUPS, "cups"}, + {PRINT_LPRNT, "nt"}, + {PRINT_LPROS2, "os2"}, +#ifdef DEVELOPER + {PRINT_TEST, "test"}, + {PRINT_VLP, "vlp"}, +#endif /* DEVELOPER */ + {-1, NULL} +}; -/*************************************************************************** -Initialise the global parameter structure. -***************************************************************************/ -static void init_globals(void) -{ - static BOOL done_init = False; - pstring s; +#ifdef WITH_LDAP_SAM +static struct enum_list enum_ldap_ssl[] = { + {LDAP_SSL_ON, "Yes"}, + {LDAP_SSL_ON, "yes"}, + {LDAP_SSL_ON, "on"}, + {LDAP_SSL_ON, "On"}, + {LDAP_SSL_OFF, "no"}, + {LDAP_SSL_OFF, "No"}, + {LDAP_SSL_OFF, "off"}, + {LDAP_SSL_OFF, "Off"}, + {LDAP_SSL_START_TLS, "start tls"}, + {LDAP_SSL_START_TLS, "start_tls"}, + {-1, NULL} +}; +#endif /* WITH_LDAP_SAM */ + +/* Types of machine we can announce as. */ +#define ANNOUNCE_AS_NT_SERVER 1 +#define ANNOUNCE_AS_WIN95 2 +#define ANNOUNCE_AS_WFW 3 +#define ANNOUNCE_AS_NT_WORKSTATION 4 + +static struct enum_list enum_announce_as[] = { + {ANNOUNCE_AS_NT_SERVER, "NT"}, + {ANNOUNCE_AS_NT_SERVER, "NT Server"}, + {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"}, + {ANNOUNCE_AS_WIN95, "win95"}, + {ANNOUNCE_AS_WFW, "WfW"}, + {-1, NULL} +}; + +static struct enum_list enum_case[] = { + {CASE_LOWER, "lower"}, + {CASE_UPPER, "upper"}, + {-1, NULL} +}; + +static struct enum_list enum_bool_auto[] = { + {False, "False"}, + {False, "No"}, + {False, "0"}, + {True, "True"}, + {True, "Yes"}, + {True, "1"}, + {Auto, "Auto"}, + {-1, NULL} +}; + +/* Client-side offline caching policy types */ +#define CSC_POLICY_MANUAL 0 +#define CSC_POLICY_DOCUMENTS 1 +#define CSC_POLICY_PROGRAMS 2 +#define CSC_POLICY_DISABLE 3 + +static struct enum_list enum_csc_policy[] = { + {CSC_POLICY_MANUAL, "manual"}, + {CSC_POLICY_DOCUMENTS, "documents"}, + {CSC_POLICY_PROGRAMS, "programs"}, + {CSC_POLICY_DISABLE, "disable"} +}; - if (!done_init) - { - int i; - bzero((void *)&Globals,sizeof(Globals)); +/* + Do you want session setups at user level security with a invalid + password to be rejected or allowed in as guest? WinNT rejects them + but it can be a pain as it means "net view" needs to use a password - for (i = 0; parm_table[i].label; i++) - if (parm_table[i].type == P_STRING && - parm_table[i].ptr) - string_init(parm_table[i].ptr,""); + You have 3 choices in the setting of map_to_guest: - string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT); + "Never" means session setups with an invalid password + are rejected. This is the default. - done_init = True; - } + "Bad User" means session setups with an invalid password + are rejected, unless the username does not exist, in which case it + is treated as a guest login + "Bad Password" means session setups with an invalid password + are treated as a guest login - DEBUG(3,("Initialising global parameters\n")); + Note that map_to_guest only has an effect in user or server + level security. +*/ -#ifdef SMB_PASSWD_FILE - string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE); +static struct enum_list enum_map_to_guest[] = { + {NEVER_MAP_TO_GUEST, "Never"}, + {MAP_TO_GUEST_ON_BAD_USER, "Bad User"}, + {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"}, + {-1, NULL} +}; + +#ifdef WITH_SSL +static struct enum_list enum_ssl_version[] = { + {SMB_SSL_V2, "ssl2"}, + {SMB_SSL_V3, "ssl3"}, + {SMB_SSL_V23, "ssl2or3"}, + {SMB_SSL_TLS1, "tls1"}, + {-1, NULL} +}; #endif - string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*"); - string_set(&Globals.szWorkGroup, WORKGROUP); -#ifdef SMB_PASSWD - string_set(&Globals.szPasswdProgram, SMB_PASSWD); -#else - string_set(&Globals.szPasswdProgram, "/bin/passwd"); + +/* note that we do not initialise the defaults union - it is not allowed in ANSI C */ +static struct parm_struct parm_table[] = { + {"Base Options", P_SEP, P_SEPARATOR}, + + {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, 0}, + {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, 0}, + {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, 0}, + {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, + {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, + {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0}, + {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC}, + {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC}, + {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC}, + {"netbios name", P_UGSTRING, P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC}, + {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0}, + {"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, 0}, + {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC }, + {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC}, + {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, 0}, + + {"Security Options", P_SEP, P_SEPARATOR}, + + {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC}, + {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC}, + {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC}, + {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC}, + {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, 0}, + {"alternate permissions", P_BOOL, P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL | FLAG_DEPRECATED}, + {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0}, + {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0}, + {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0}, + {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, 0}, + {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0}, + {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, 0}, + {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0}, + {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0}, + {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, 0}, + {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, 0}, + {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, 0}, + {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, + {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, + {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, + {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC}, + + {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, 0}, + {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0}, + {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0}, + {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0}, + {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0}, + {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0}, + {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0}, + {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0}, + {"restrict anonymous", P_BOOL, P_GLOBAL, &Globals.bRestrictAnonymous, NULL, NULL, 0}, + {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, 0}, + {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, 0}, + + {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0}, + {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0}, + + {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_PRINT}, + {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE}, + {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE}, + {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0}, + + {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_SHARE}, + {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0}, + {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0}, + {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0}, + + {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL}, + {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL}, + {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE}, + {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_SHARE}, + {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE}, + {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0}, + + {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, + {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0}, + + {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE}, + {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, + {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0}, + {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, + {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0}, + +#ifdef WITH_SSL + {"Secure Socket Layer Options", P_SEP, P_SEPARATOR}, + {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0}, + + {"ssl hosts", P_LIST, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0}, + {"ssl hosts resign", P_LIST, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0}, + {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0}, + {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0}, + {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslServerCert, NULL, NULL, 0}, + {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslServerPrivKey, NULL, NULL, 0}, + {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0}, + {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0}, + {"ssl egd socket", P_STRING, P_GLOBAL, &Globals.sslEgdSocket, NULL, NULL, 0}, + {"ssl entropy file", P_STRING, P_GLOBAL, &Globals.sslEntropyFile, NULL, NULL, 0}, + {"ssl entropy bytes", P_INTEGER, P_GLOBAL, &Globals.sslEntropyBytes, NULL, NULL, 0}, + {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL, 0}, + {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL, 0}, + {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0}, + {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0}, + {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0}, +#endif /* WITH_SSL */ + + {"Logging Options", P_SEP, P_SEPARATOR}, + + {"admin log", P_BOOL, P_GLOBAL, &Globals.bAdminLog, NULL, NULL, 0}, + {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL_CLASS[DBGC_ALL], handle_debug_list, NULL, 0}, + {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL_CLASS[DBGC_ALL], handle_debug_list, NULL, 0}, + {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0}, + {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0}, + {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0}, + + {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0}, + {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0}, + {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0}, + {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, 0}, + {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, 0}, + {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, 0}, + + {"Protocol Options", P_SEP, P_SEPARATOR}, + + {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0}, + {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, 0}, + {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0}, + {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, 0}, + {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, 0}, + {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0}, + {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0}, + {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0}, + + {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0}, + {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE }, + {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, 0}, + {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0}, + {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0}, + {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0}, + {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0}, + + {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0}, + {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0}, + {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0}, + {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0}, + {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0}, + {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0}, + {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0}, + {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, 0}, + + {"Tuning Options", P_SEP, P_SEPARATOR}, + + {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0}, + {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0}, + {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0}, + {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0}, + + {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0}, + {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, 0}, + {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE}, + {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, 0}, + {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0}, + {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0}, + {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT}, + {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0}, + + {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0}, + {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0}, + {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_SHARE}, + {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE}, + {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE}, + {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, 0}, + {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, 0}, + {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE}, + + {"Printing Options", P_SEP, P_SEPARATOR}, + + {"total print jobs", P_INTEGER, P_GLOBAL, &Globals.iTotalPrintJobs, NULL, NULL, FLAG_PRINT}, + {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT}, + {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT}, + {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT}, + {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0}, + {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT}, + {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0}, + {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT}, + {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL}, + {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, + {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, + {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, + {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, + {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, + {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, + {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, + {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, + + {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, 0}, + {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, 0}, + {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, 0}, + {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, 0}, + {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, 0}, + + {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT}, + {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0}, + {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_PRINT}, + {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_PRINT}, + {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT}, + {"printer driver file", P_STRING, P_LOCAL, &sDefault.szDriverFile, NULL, NULL, FLAG_PRINT}, + {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, + + {"Filename Handling", P_SEP, P_SEPARATOR}, + {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0}, + {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, 0}, + + {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0}, + {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE}, + {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0}, + {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL }, + {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL }, + {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL }, + {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0}, + + {"Domain Options", P_SEP, P_SEPARATOR}, + + {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0}, + + {"Logon Options", P_SEP, P_SEPARATOR}, + + {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, 0}, + {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, 0}, + {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, 0}, + {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, 0}, + {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, 0}, + {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserToGroupScript, NULL, NULL, 0}, + {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, 0}, + {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, 0}, + {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, 0}, + + {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0}, + {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0}, + {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0}, + {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0}, + {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0}, + + {"Browse Options", P_SEP, P_SEPARATOR}, + + {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC}, + {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, 0}, + {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0}, + {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC}, + {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE}, + {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC}, + {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC}, + {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0}, + {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, + {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0}, + {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL}, + + {"WINS Options", P_SEP, P_SEPARATOR}, + {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0}, + {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0}, + + {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, handle_wins_server_list, NULL, FLAG_BASIC}, + {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC}, + {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, 0}, + {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, 0}, + + {"Locking Options", P_SEP, P_SEPARATOR}, + + {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL}, + {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE}, + {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL}, + {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL}, + {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL}, + + {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_GLOBAL}, + {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + +#ifdef WITH_LDAP_SAM + {"Ldap Options", P_SEP, P_SEPARATOR}, + + {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, 0}, + {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, 0}, + {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, 0}, + {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0}, + {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, 0}, + {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, 0}, +#endif /* WITH_LDAP_SAM */ + + {"Miscellaneous Options", P_SEP, P_SEPARATOR}, + {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, 0}, + {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, 0}, + {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, 0}, + + {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, + {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0}, + {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0}, + {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, + {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, +#ifdef WITH_UTMP + {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0}, + {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, 0}, + {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, 0}, #endif - string_set(&Globals.szPrintcapname, PRINTCAP_NAME); - string_set(&Globals.szLockDir, LOCKDIR); - string_set(&Globals.szRootdir, "/"); - sprintf(s,"Samba %s",VERSION); - string_set(&Globals.szServerString,s); - Globals.bLoadPrinters = True; - Globals.bUseRhosts = False; - Globals.max_packet = 65535; - Globals.mangled_stack = 50; - Globals.max_xmit = Globals.max_packet; - Globals.max_mux = 2; - Globals.lpqcachetime = 10; - Globals.pwordlevel = 0; - Globals.deadtime = 0; - Globals.max_log_size = 5000; - Globals.maxprotocol = PROTOCOL_NT1; - Globals.security = SEC_SHARE; - Globals.bEncryptPasswords = False; - Globals.printing = DEFAULT_PRINTING; - Globals.bReadRaw = True; - Globals.bWriteRaw = True; - Globals.bReadPrediction = False; - Globals.bReadbmpx = True; - Globals.bNullPasswords = False; - Globals.bStripDot = False; - Globals.syslog = 1; - Globals.bSyslogOnly = False; - Globals.os_level = 0; - Globals.max_ttl = 60*60*4; /* 2 hours default */ - Globals.bPreferredMaster = True; - Globals.bDomainMaster = False; - Globals.bDomainLogons = False; - Globals.bBrowseList = True; - -#ifdef KANJI - coding_system = interpret_coding_system (KANJI, SJIS_CODE); -#endif /* KANJI */ + + {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0}, + {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0}, + {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0}, + {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0}, + {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0}, + {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, 0}, + {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0}, + {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0}, + {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0}, + {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0}, + {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE}, + + {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE}, + {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE}, + {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT}, + {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0}, + + {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE}, + {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT}, + {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT}, + {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_SHARE}, + {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT}, + {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, + {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE }, + {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE}, + {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE}, + {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, 0}, + {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE}, + {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE}, + {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE}, + {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + + {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0}, + {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, + NULL, 0}, + + {"VFS module options", P_SEP, P_SEPARATOR}, + + {"vfs object", P_STRING, P_LOCAL, &sDefault.szVfsObjectFile, handle_vfs_object, NULL, FLAG_SHARE}, + {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE}, + + + {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE}, + {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, 0}, + + {"Winbind options", P_SEP, P_SEPARATOR}, + + {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, 0}, + {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, 0}, + {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, 0}, + {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, 0}, + {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, 0}, + {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, 0}, + {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, 0}, + {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, 0}, + {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, 0}, + + {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0} +}; -} /*************************************************************************** -check if a string is initialised and if not then initialise it +Initialise the sDefault parameter structure for the printer values. ***************************************************************************/ -static void string_initial(char **s,char *v) +static void init_printer_values(void) { - if (!*s || !**s) - string_init(s,v); -} + string_set(&sDefault.szPrinterDriver, ""); + string_set(&sDefault.szDriverFile, dyn_DRIVERFILE); + /* choose defaults depending on the type of printing */ + switch (sDefault.iPrinting) + { + case PRINT_BSD: + case PRINT_AIX: + case PRINT_LPRNT: + case PRINT_LPROS2: + string_set(&sDefault.szLpqcommand, "lpq -P%p"); + string_set(&sDefault.szLprmcommand, "lprm -P%p %j"); + string_set(&sDefault.szPrintcommand, + "lpr -r -P%p %s"); + break; + + case PRINT_LPRNG: + case PRINT_PLP: + string_set(&sDefault.szLpqcommand, "lpq -P%p"); + string_set(&sDefault.szLprmcommand, "lprm -P%p %j"); + string_set(&sDefault.szPrintcommand, + "lpr -r -P%p %s"); + string_set(&sDefault.szQueuepausecommand, + "lpc stop %p"); + string_set(&sDefault.szQueueresumecommand, + "lpc start %p"); + string_set(&sDefault.szLppausecommand, + "lpc hold %p %j"); + string_set(&sDefault.szLpresumecommand, + "lpc release %p %j"); + break; + + case PRINT_CUPS: +#ifdef HAVE_CUPS + string_set(&sDefault.szLpqcommand, ""); + string_set(&sDefault.szLprmcommand, ""); + string_set(&sDefault.szPrintcommand, ""); + string_set(&sDefault.szLppausecommand, ""); + string_set(&sDefault.szLpresumecommand, ""); + string_set(&sDefault.szQueuepausecommand, ""); + string_set(&sDefault.szQueueresumecommand, ""); + + string_set(&Globals.szPrintcapname, "cups"); +#else + string_set(&sDefault.szLpqcommand, + "/usr/bin/lpstat -o %p"); + string_set(&sDefault.szLprmcommand, + "/usr/bin/cancel %p-%j"); + string_set(&sDefault.szPrintcommand, + "/usr/bin/lp -d %p %s; rm %s"); + string_set(&sDefault.szLppausecommand, + "lp -i %p-%j -H hold"); + string_set(&sDefault.szLpresumecommand, + "lp -i %p-%j -H resume"); + string_set(&sDefault.szQueuepausecommand, + "/usr/bin/disable %p"); + string_set(&sDefault.szQueueresumecommand, + "/usr/bin/enable %p"); + string_set(&Globals.szPrintcapname, "lpstat"); +#endif /* HAVE_CUPS */ + break; + + case PRINT_SYSV: + case PRINT_HPUX: + string_set(&sDefault.szLpqcommand, "lpstat -o%p"); + string_set(&sDefault.szLprmcommand, "cancel %p-%j"); + string_set(&sDefault.szPrintcommand, + "lp -c -d%p %s; rm %s"); + string_set(&sDefault.szQueuepausecommand, + "disable %p"); + string_set(&sDefault.szQueueresumecommand, + "enable %p"); +#ifndef HPUX + string_set(&sDefault.szLppausecommand, + "lp -i %p-%j -H hold"); + string_set(&sDefault.szLpresumecommand, + "lp -i %p-%j -H resume"); +#endif /* SYSV */ + break; + + case PRINT_QNX: + string_set(&sDefault.szLpqcommand, "lpq -P%p"); + string_set(&sDefault.szLprmcommand, "lprm -P%p %j"); + string_set(&sDefault.szPrintcommand, "lp -r -P%p %s"); + break; + + case PRINT_SOFTQ: + string_set(&sDefault.szLpqcommand, "qstat -l -d%p"); + string_set(&sDefault.szLprmcommand, + "qstat -s -j%j -c"); + string_set(&sDefault.szPrintcommand, + "lp -d%p -s %s; rm %s"); + string_set(&sDefault.szLppausecommand, + "qstat -s -j%j -h"); + string_set(&sDefault.szLpresumecommand, + "qstat -s -j%j -r"); + break; +#ifdef DEVELOPER + case PRINT_TEST: + case PRINT_VLP: + string_set(&sDefault.szPrintcommand, "vlp print %p %s"); + string_set(&sDefault.szLpqcommand, "vlp lpq %p"); + string_set(&sDefault.szLprmcommand, "vlp lprm %p %j"); + string_set(&sDefault.szLppausecommand, "vlp lppause %p %j"); + string_set(&sDefault.szLpresumecommand, "vlp lpresum %p %j"); + string_set(&sDefault.szQueuepausecommand, "vlp queuepause %p"); + string_set(&sDefault.szQueueresumecommand, "vlp queueresume %p"); + break; +#endif /* DEVELOPER */ + + } +} /*************************************************************************** -Initialise the sDefault parameter structure. +Initialise the global parameter structure. ***************************************************************************/ -static void init_locals(void) -{ - /* choose defaults depending on the type of printing */ - switch (Globals.printing) - { - case PRINT_BSD: - case PRINT_AIX: - string_initial(&sDefault.szLpqcommand,"lpq -P%p"); - string_initial(&sDefault.szLprmcommand,"lprm -P%p %j"); - string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s"); - break; - - case PRINT_SYSV: - case PRINT_HPUX: - string_initial(&sDefault.szLpqcommand,"lpstat -o%p"); - string_initial(&sDefault.szLprmcommand,"cancel %p-%j"); - string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s"); -#ifdef SVR4 - string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold"); - string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume"); +static void init_globals(void) +{ + static BOOL done_init = False; + pstring s; + + if (!done_init) + { + int i; + memset((void *)&Globals, '\0', sizeof(Globals)); + + for (i = 0; parm_table[i].label; i++) + if ((parm_table[i].type == P_STRING || + parm_table[i].type == P_USTRING) && + parm_table[i].ptr) + string_set(parm_table[i].ptr, ""); + + string_set(&sDefault.fstype, FSTYPE_STRING); + + init_printer_values(); + + done_init = True; + } + + + DEBUG(3, ("Initialising global parameters\n")); + + string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE); + string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR); + string_set(&Globals.szPassdbBackend, "smbpasswd"); + + string_set(&Globals.szGuestaccount, GUEST_ACCOUNT); + + /* using UTF8 by default allows us to support all chars */ + string_set(&Globals.unix_charset, "UTF8"); + + /* + * Allow the default PASSWD_CHAT to be overridden in local.h. + */ + string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT); + string_set(&Globals.szWorkGroup, WORKGROUP); + string_set(&Globals.szPasswdProgram, ""); + string_set(&Globals.szPrintcapname, PRINTCAP_NAME); + string_set(&Globals.szLockDir, dyn_LOCKDIR); + string_set(&Globals.szSocketAddress, "0.0.0.0"); + pstrcpy(s, "Samba "); + pstrcat(s, VERSION); + string_set(&Globals.szServerString, s); + slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION, + DEFAULT_MINOR_VERSION); + string_set(&Globals.szAnnounceVersion, s); + + pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS); + + string_set(&Globals.szLogonDrive, ""); + /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */ + string_set(&Globals.szLogonHome, "\\\\%N\\%U"); + string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile"); + + string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast"); + string_set(&Globals.szPasswordServer, "*"); + + Globals.bLoadPrinters = True; + Globals.max_packet = 65535; + Globals.mangled_stack = 50; + Globals.max_xmit = 65535; + Globals.max_mux = 50; /* This is *needed* for profile support. */ + Globals.lpqcachetime = 10; + Globals.bDisableSpoolss = False; + Globals.iMaxSmbdProcesses = 0;/* no limit specified */ + Globals.iTotalPrintJobs = 0; /* no limit specified */ + Globals.pwordlevel = 0; + Globals.unamelevel = 0; + Globals.deadtime = 0; + Globals.bLargeReadwrite = True; + Globals.max_log_size = 5000; + Globals.max_open_files = MAX_OPEN_FILES; + Globals.maxprotocol = PROTOCOL_NT1; + Globals.minprotocol = PROTOCOL_CORE; + Globals.security = SEC_USER; + Globals.paranoid_server_security = True; + Globals.bEncryptPasswords = True; + Globals.bUpdateEncrypt = False; + Globals.bReadRaw = True; + Globals.bWriteRaw = True; + Globals.bReadPrediction = False; + Globals.bReadbmpx = False; + Globals.bNullPasswords = False; + Globals.bObeyPamRestrictions = False; + Globals.bStripDot = False; + Globals.syslog = 1; + Globals.bSyslogOnly = False; + Globals.bAdminLog = False; + Globals.bTimestampLogs = True; + Globals.bDebugHiresTimestamp = False; + Globals.bDebugPid = False; + Globals.bDebugUid = False; + Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */ + Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */ + Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */ + Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */ + Globals.change_notify_timeout = 60; /* 1 minute default. */ + Globals.ReadSize = 16 * 1024; + Globals.lm_announce = 2; /* = Auto: send only if LM clients found */ + Globals.lm_interval = 60; + Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */ + Globals.announce_as = ANNOUNCE_AS_NT_SERVER; +#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) + Globals.bNISHomeMap = False; +#ifdef WITH_NISPLUS_HOME + string_set(&Globals.szNISHomeMapName, "auto_home.org_dir"); +#else + string_set(&Globals.szNISHomeMapName, "auto.home"); +#endif +#endif + Globals.bTimeServer = False; + Globals.bBindInterfacesOnly = False; + Globals.bUnixPasswdSync = False; + Globals.bPamPasswordChange = False; + Globals.bPasswdChatDebug = False; + Globals.bUnicode = True; /* Do unicode on the wire by default */ + Globals.bNTPipeSupport = True; /* Do NT pipes by default. */ + Globals.bNTStatusSupport = True; /* Use NT status by default. */ + Globals.bStatCache = True; /* use stat cache by default */ + Globals.bRestrictAnonymous = False; + Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */ + Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */ + Globals.map_to_guest = 0; /* By Default, "Never" */ + Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */ + Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */ + Globals.enhanced_browsing = True; + Globals.iLockSpinCount = 3; /* Try 2 times. */ + Globals.iLockSpinTime = 10; /* usec. */ +#ifdef MMAP_BLACKLIST + Globals.bUseMmap = False; +#else + Globals.bUseMmap = True; #endif - break; - case PRINT_QNX: - string_initial(&sDefault.szLpqcommand,"lpq -P%p"); - string_initial(&sDefault.szLprmcommand,"lprm -P%p %j"); - string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s"); - break; + /* hostname lookups can be very expensive and are broken on + a large number of sites (tridge) */ + Globals.bHostnameLookups = False; + +#ifdef WITH_LDAP_SAM + string_set(&Globals.szLdapSuffix, ""); + string_set(&Globals.szLdapMachineSuffix, ""); + string_set(&Globals.szLdapUserSuffix, ""); + + string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))"); + string_set(&Globals.szLdapAdminDn, ""); + Globals.ldap_ssl = LDAP_SSL_ON; +#endif /* WITH_LDAP_SAM */ + +#ifdef WITH_SSL + Globals.sslVersion = SMB_SSL_V23; + /* Globals.sslHostsRequire = NULL; + Globals.sslHostsResign = NULL; */ + string_set(&Globals.sslCaCertDir, ""); + string_set(&Globals.sslCaCertFile, ""); + string_set(&Globals.sslServerCert, ""); + string_set(&Globals.sslServerPrivKey, ""); + string_set(&Globals.sslClientCert, ""); + string_set(&Globals.sslClientPrivKey, ""); + string_set(&Globals.sslCiphers, ""); + string_set(&Globals.sslEgdSocket, ""); + string_set(&Globals.sslEntropyFile, ""); + Globals.sslEntropyBytes = 256; + Globals.sslEnabled = False; + Globals.sslReqClientCert = False; + Globals.sslReqServerCert = False; + Globals.sslCompatibility = False; +#endif /* WITH_SSL */ + +/* these parameters are set to defaults that are more appropriate + for the increasing samba install base: + + as a member of the workgroup, that will possibly become a + _local_ master browser (lm = True). this is opposed to a forced + local master browser startup (pm = True). + + doesn't provide WINS server service by default (wsupp = False), + and doesn't provide domain master browser services by default, either. + +*/ + + Globals.bMsAddPrinterWizard = True; + Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */ + Globals.os_level = 20; + Globals.bLocalMaster = True; + Globals.bDomainMaster = Auto; /* depending on bDomainLogons */ + Globals.bDomainLogons = False; + Globals.bBrowseList = True; + Globals.bWINSsupport = False; + Globals.bWINSproxy = False; + + Globals.bDNSproxy = True; + + /* this just means to use them if they exist */ + Globals.bKernelOplocks = True; + + Globals.bAllowTrustedDomains = True; + + string_set(&Globals.szTemplateShell, "/bin/false"); + string_set(&Globals.szTemplateHomedir, "/home/%D/%U"); + string_set(&Globals.szWinbindSeparator, "\\"); + + Globals.winbind_cache_time = 15; + Globals.bWinbindEnumUsers = True; + Globals.bWinbindEnumGroups = True; + Globals.bWinbindUseDefaultDomain = False; + + Globals.bUseSpnego = True; - - } } +static TALLOC_CTX *lp_talloc; + +/******************************************************************* a +free up temporary memory - called from the main loop +********************************************************************/ +void lp_talloc_free(void) +{ + if (!lp_talloc) + return; + talloc_destroy(lp_talloc); + lp_talloc = NULL; +} /******************************************************************* -a convenience rooutine to grab string parameters into a rotating -static buffer, and run standard_sub_basic on them. The buffers -can be written to by callers +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. ********************************************************************/ -char *lp_string(char *s) +static char *lp_string(const char *s) { - static pstring bufs[10]; - static int next=0; - char *ret; - - ret = &bufs[next][0]; - next = (next+1)%10; + size_t len = s ? strlen(s) : 0; + char *ret; - if (!s) - *ret = 0; - else - StrnCpy(ret,s,sizeof(pstring)-1); + /* 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? */ - standard_sub_basic(ret); - return(ret); +#if 0 + DEBUG(10, ("lp_string(%s)\n", s)); +#endif + + if (!lp_talloc) + lp_talloc = talloc_init_named("lp_talloc"); + + ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */ + + if (!ret) + return NULL; + + if (!s) + *ret = 0; + else + StrnCpy(ret, s, len); + + trim_string(ret, "\"", "\""); + + standard_sub_basic(current_user_info.smb_name,ret); + return (ret); } @@ -653,6 +1486,8 @@ char *lp_string(char *s) #define FN_GLOBAL_STRING(fn_name,ptr) \ char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));} +#define FN_GLOBAL_LIST(fn_name,ptr) \ + char **fn_name(void) {return(*(char ***)(ptr));} #define FN_GLOBAL_BOOL(fn_name,ptr) \ BOOL fn_name(void) {return(*(BOOL *)(ptr));} #define FN_GLOBAL_CHAR(fn_name,ptr) \ @@ -661,346 +1496,539 @@ char *lp_string(char *s) int fn_name(void) {return(*(int *)(ptr));} #define FN_LOCAL_STRING(fn_name,val) \ - char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));} + char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));} +#define FN_LOCAL_LIST(fn_name,val) \ + char **fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);} #define FN_LOCAL_BOOL(fn_name,val) \ - BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} + BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);} #define FN_LOCAL_CHAR(fn_name,val) \ - char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} + char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);} #define FN_LOCAL_INTEGER(fn_name,val) \ - int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} - -FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile) -FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile) -FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile) -FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString) -FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname) -FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir) -FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir) -FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService) -FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand) -FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree) -FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv) -FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices) -FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram) -FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat) -FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer) -FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup) -FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController) -FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap) -FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet) -FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript) - -FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster) -FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons) -FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster) -FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters) -FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts) -FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache) -FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction) -FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx) -FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw) -FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw) -FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords) -FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot) -FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords) -FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly) -FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList) - -FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level) -FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl) -FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size) -FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack) -FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit) -FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux) -FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet) -FN_GLOBAL_INTEGER(lp_keepalive,&keepalive) -FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel) -FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime) -FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol) -FN_GLOBAL_INTEGER(lp_security,&Globals.security) -FN_GLOBAL_INTEGER(lp_printing,&Globals.printing) -FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize) -FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime) -FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog) - -FN_LOCAL_STRING(lp_preexec,szPreExec) -FN_LOCAL_STRING(lp_postexec,szPostExec) -FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec) -FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec) -FN_LOCAL_STRING(lp_servicename,szService) -FN_LOCAL_STRING(lp_pathname,szPath) -FN_LOCAL_STRING(lp_dontdescend,szDontdescend) -FN_LOCAL_STRING(lp_username,szUsername) -FN_LOCAL_STRING(lp_guestaccount,szGuestaccount) -FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers) -FN_LOCAL_STRING(lp_valid_users,szValidUsers) -FN_LOCAL_STRING(lp_admin_users,szAdminUsers) -FN_LOCAL_STRING(lp_printcommand,szPrintcommand) -FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand) -FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand) -FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand) -FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand) -FN_LOCAL_STRING(lp_printername,szPrintername) -FN_LOCAL_STRING(lp_hostsallow,szHostsallow) -FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny) -FN_LOCAL_STRING(lp_magicscript,szMagicScript) -FN_LOCAL_STRING(lp_magicoutput,szMagicOutput) -FN_LOCAL_STRING(lp_comment,comment) -FN_LOCAL_STRING(lp_force_user,force_user) -FN_LOCAL_STRING(lp_force_group,force_group) -FN_LOCAL_STRING(lp_readlist,readlist) -FN_LOCAL_STRING(lp_writelist,writelist) -FN_LOCAL_STRING(lp_volume,volume) -FN_LOCAL_STRING(lp_mangled_map,szMangledMap) - -FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm) -FN_LOCAL_BOOL(lp_revalidate,bRevalidate) -FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive) -FN_LOCAL_BOOL(lp_preservecase,bCasePreserve) -FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve) -FN_LOCAL_BOOL(lp_casemangle,bCaseMangle) -FN_LOCAL_BOOL(lp_status,status) -FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles) -FN_LOCAL_BOOL(lp_browseable,bBrowseable) -FN_LOCAL_BOOL(lp_readonly,bRead_only) -FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir) -FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok) -FN_LOCAL_BOOL(lp_guest_only,bGuest_only) -FN_LOCAL_BOOL(lp_print_ok,bPrint_ok) -FN_LOCAL_BOOL(lp_postscript,bPostscript) -FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden) -FN_LOCAL_BOOL(lp_map_archive,bMap_archive) -FN_LOCAL_BOOL(lp_locking,bLocking) -FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking) -FN_LOCAL_BOOL(lp_share_modes,bShareModes) -FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser) -FN_LOCAL_BOOL(lp_manglednames,bMangledNames) -FN_LOCAL_BOOL(lp_widelinks,bWidelinks) -FN_LOCAL_BOOL(lp_syncalways,bSyncAlways) -FN_LOCAL_BOOL(lp_map_system,bMap_system) - -FN_LOCAL_INTEGER(lp_create_mode,iCreate_mode) -FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections) -FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase) -FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace) - -FN_LOCAL_CHAR(lp_magicchar,magic_char) - - + int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);} + +FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset) +FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset) +FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset) +FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile) +FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile) +FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile) +FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir) +FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend) +FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString) +FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname) +FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand) +FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand) +FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand) +FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap) +FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir) +FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod) +#ifdef WITH_UTMP +FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir) +FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir) +FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp) +#endif +FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir) +FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv) +FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService) +FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand) +FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree) +FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv) +FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices) +FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram) +FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat) +FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer) +FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder) +FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkGroup) +FN_GLOBAL_STRING(lp_realm, &Globals.szRealm) +FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver) +FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap) +FN_GLOBAL_STRING(lp_logon_script, &Globals.szLogonScript) +FN_GLOBAL_STRING(lp_logon_path, &Globals.szLogonPath) +FN_GLOBAL_STRING(lp_logon_drive, &Globals.szLogonDrive) +FN_GLOBAL_STRING(lp_logon_home, &Globals.szLogonHome) +FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce) +FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync) +FN_GLOBAL_STRING(lp_wins_server_list, &Globals.szWINSserver) +FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces) +FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress) +FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName) +static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion) +FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases) +FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction) +FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript) +FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript) + +FN_GLOBAL_STRING(lp_guestaccount, &Globals.szGuestaccount) +FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript) +FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript) +FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript) +FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserToGroupScript) + +FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript) + +FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript) +FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript) + +FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook) +FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners) +FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir) +FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell) +FN_GLOBAL_STRING(lp_winbind_separator, &Globals.szWinbindSeparator) +FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers) +FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups) +FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain) +#ifdef WITH_LDAP_SAM +FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix) +FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix) +FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix) +FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter) +FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn) +FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl) +#endif /* WITH_LDAP_SAM */ +FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand) +FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand) +FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand) + +#ifdef WITH_SSL +FN_GLOBAL_INTEGER(lp_ssl_version, &Globals.sslVersion) +FN_GLOBAL_LIST(lp_ssl_hosts, &Globals.sslHostsRequire) +FN_GLOBAL_LIST(lp_ssl_hosts_resign, &Globals.sslHostsResign) +FN_GLOBAL_STRING(lp_ssl_cacertdir, &Globals.sslCaCertDir) +FN_GLOBAL_STRING(lp_ssl_cacertfile, &Globals.sslCaCertFile) +FN_GLOBAL_STRING(lp_ssl_server_cert, &Globals.sslServerCert) +FN_GLOBAL_STRING(lp_ssl_server_privkey, &Globals.sslServerPrivKey) +FN_GLOBAL_STRING(lp_ssl_client_cert, &Globals.sslClientCert) +FN_GLOBAL_STRING(lp_ssl_client_privkey, &Globals.sslClientPrivKey) +FN_GLOBAL_STRING(lp_ssl_ciphers, &Globals.sslCiphers) +FN_GLOBAL_STRING(lp_ssl_egdsocket, &Globals.sslEgdSocket) +FN_GLOBAL_STRING(lp_ssl_entropyfile, &Globals.sslEntropyFile) +FN_GLOBAL_INTEGER(lp_ssl_entropybytes, &Globals.sslEntropyBytes) +FN_GLOBAL_BOOL(lp_ssl_enabled, &Globals.sslEnabled) +FN_GLOBAL_BOOL(lp_ssl_reqClientCert, &Globals.sslReqClientCert) +FN_GLOBAL_BOOL(lp_ssl_reqServerCert, &Globals.sslReqServerCert) +FN_GLOBAL_BOOL(lp_ssl_compatibility, &Globals.sslCompatibility) +#endif /* WITH_SSL */ + +FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard) +FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy) +FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport) +FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport) +FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy) +FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster) +FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons) +FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters) +FN_GLOBAL_BOOL(lp_readprediction, &Globals.bReadPrediction) +FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx) +FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw) +FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite) +FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw) +FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords) +FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions) +FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot) +FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords) +FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt) +FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly) +FN_GLOBAL_BOOL(lp_admin_log, &Globals.bAdminLog) +FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs) +FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp) +FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid) +FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid) +FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList) +FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap) +static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer) +FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly) +FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange) +FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync) +FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug) +FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode) +FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport) +FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport) +FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache) +FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains) +FN_GLOBAL_BOOL(lp_restrict_anonymous, &Globals.bRestrictAnonymous) +FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth) +FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth) +FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs) +FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks) +FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing) +FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap) +FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego) +FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups) +FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level) +FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl) +FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl) +FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl) +FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size) +FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files) +FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit) +FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux) +FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel) +FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel) +FN_GLOBAL_INTEGER(lp_readsize, &Globals.ReadSize) +FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime) +FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol) +FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol) +FN_GLOBAL_INTEGER(lp_security, &Globals.security) +FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods) +FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security) +FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize) +FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime) +FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses) +FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss) +FN_GLOBAL_INTEGER(lp_totalprintjobs, &Globals.iTotalPrintJobs) +FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog) +static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as) +FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce) +FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval) +FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout) +FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout) +FN_GLOBAL_INTEGER(lp_stat_cache_size, &Globals.stat_cache_size) +FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest) +FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length) +FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time) +FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount) +FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime) +FN_LOCAL_STRING(lp_preexec, szPreExec) +FN_LOCAL_STRING(lp_postexec, szPostExec) +FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec) +FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec) +FN_LOCAL_STRING(lp_servicename, szService) +FN_LOCAL_STRING(lp_pathname, szPath) +FN_LOCAL_STRING(lp_dontdescend, szDontdescend) +FN_LOCAL_STRING(lp_username, szUsername) +FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers) +FN_LOCAL_LIST(lp_valid_users, szValidUsers) +FN_LOCAL_LIST(lp_admin_users, szAdminUsers) +FN_LOCAL_STRING(lp_printcommand, szPrintcommand) +FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand) +FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand) +FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand) +FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand) +FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand) +FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand) +static FN_LOCAL_STRING(_lp_printername, szPrintername) +FN_LOCAL_STRING(lp_driverfile, szDriverFile) +FN_LOCAL_STRING(lp_printerdriver, szPrinterDriver) +FN_LOCAL_LIST(lp_hostsallow, szHostsallow) +FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny) +FN_LOCAL_STRING(lp_magicscript, szMagicScript) +FN_LOCAL_STRING(lp_magicoutput, szMagicOutput) +FN_LOCAL_STRING(lp_comment, comment) +FN_LOCAL_STRING(lp_force_user, force_user) +FN_LOCAL_STRING(lp_force_group, force_group) +FN_LOCAL_LIST(lp_readlist, readlist) +FN_LOCAL_LIST(lp_writelist, writelist) +FN_LOCAL_LIST(lp_printer_admin, printer_admin) +FN_LOCAL_STRING(lp_fstype, fstype) +FN_LOCAL_STRING(lp_vfsobj, szVfsObjectFile) +FN_LOCAL_STRING(lp_vfs_options, szVfsOptions) +static FN_LOCAL_STRING(lp_volume, volume) +FN_LOCAL_STRING(lp_mangled_map, szMangledMap) +FN_LOCAL_STRING(lp_veto_files, szVetoFiles) +FN_LOCAL_STRING(lp_hide_files, szHideFiles) +FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles) +FN_LOCAL_STRING(lp_driverlocation, szPrinterDriverLocation) +FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot) +FN_LOCAL_BOOL(lp_autoloaded, autoloaded) +FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose) +FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose) +FN_LOCAL_BOOL(lp_casesensitive, bCaseSensitive) +FN_LOCAL_BOOL(lp_preservecase, bCasePreserve) +FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve) +FN_LOCAL_BOOL(lp_casemangle, bCaseMangle) +FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles) +FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable) +FN_LOCAL_BOOL(lp_browseable, bBrowseable) +FN_LOCAL_BOOL(lp_readonly, bRead_only) +FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir) +FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok) +FN_LOCAL_BOOL(lp_guest_only, bGuest_only) +FN_LOCAL_BOOL(lp_print_ok, bPrint_ok) +FN_LOCAL_BOOL(lp_postscript, bPostscript) +FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden) +FN_LOCAL_BOOL(lp_map_archive, bMap_archive) +FN_LOCAL_BOOL(lp_locking, bLocking) +FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking) +FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking) +FN_LOCAL_BOOL(lp_share_modes, bShareModes) +FN_LOCAL_BOOL(lp_oplocks, bOpLocks) +FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks) +FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser) +FN_LOCAL_BOOL(lp_manglednames, bMangledNames) +FN_LOCAL_BOOL(lp_widelinks, bWidelinks) +FN_LOCAL_BOOL(lp_symlinks, bSymlinks) +FN_LOCAL_BOOL(lp_syncalways, bSyncAlways) +FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate) +FN_LOCAL_BOOL(lp_strict_sync, bStrictSync) +FN_LOCAL_BOOL(lp_map_system, bMap_system) +FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly) +FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks) +FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles) +FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode) +FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes) +FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution) +FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes) +FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks) +FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms) +FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS) +FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver) +FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode) +FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport) +FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask) +FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode) +FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask) +FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode) +FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask) +FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode) +FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask) +FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode) +FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections) +FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase) +FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace) +FN_LOCAL_INTEGER(lp_maxprintjobs, iMaxPrintJobs) +FN_LOCAL_INTEGER(lp_printing, iPrinting) +FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit) +FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy) +FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize) +FN_LOCAL_CHAR(lp_magicchar, magic_char) +FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time) +FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers) /* local prototypes */ -static int strwicmp( char *psz1, char *psz2 ); -static int map_parameter( char *pszParmName); -static BOOL set_boolean( BOOL *pb, char *pszParmValue ); -static int getservicebyname(char *pszServiceName, service *pserviceDest); -static void copy_service( service *pserviceDest, - service *pserviceSource, - BOOL *pcopymapDest ); -static BOOL service_ok(int iService); -static BOOL do_parameter(char *pszParmName, char *pszParmValue); -static BOOL do_section(char *pszSectionName); -static void dump_globals(void); -static void dump_a_service(service *pService); -static void init_copymap(service *pservice); + +static int map_parameter(char *pszParmName); +static BOOL set_boolean(BOOL *pb, char *pszParmValue); +static int getservicebyname(const char *pszServiceName, + service * pserviceDest); +static void copy_service(service * pserviceDest, + service * pserviceSource, BOOL *pcopymapDest); +static BOOL service_ok(int iService); +static BOOL do_parameter(char *pszParmName, char *pszParmValue); +static BOOL do_section(char *pszSectionName); +static void init_copymap(service * pservice); /*************************************************************************** initialise a service to the defaults ***************************************************************************/ -static void init_service(service *pservice) +static void init_service(service * pservice) { - bzero((char *)pservice,sizeof(service)); - copy_service(pservice,&sDefault,NULL); + memset((char *)pservice, '\0', sizeof(service)); + copy_service(pservice, &sDefault, NULL); } /*************************************************************************** free the dynamically allocated parts of a service struct ***************************************************************************/ -static void free_service(service *pservice) +static void free_service(service * pservice) { - int i; - if (!pservice) - return; + int i; + if (!pservice) + return; + + if (pservice->szService) + DEBUG(5, + ("free_service: Freeing service %s\n", + pservice->szService)); + + string_free(&pservice->szService); + SAFE_FREE(pservice->copymap); - for (i=0;parm_table[i].label;i++) - if (parm_table[i].type == P_STRING && parm_table[i].class == P_LOCAL) - string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault))); + for (i = 0; parm_table[i].label; i++) + { + if ((parm_table[i].type == P_STRING || + parm_table[i].type == P_USTRING) && + parm_table[i].class == P_LOCAL) + string_free((char **) + (((char *)pservice) + + PTR_DIFF(parm_table[i].ptr, &sDefault))); + else if (parm_table[i].type == P_LIST && + parm_table[i].class == P_LOCAL) + lp_list_free((char ***) + (((char *)pservice) + + PTR_DIFF(parm_table[i].ptr, &sDefault))); + } + + + ZERO_STRUCTP(pservice); } /*************************************************************************** add a new service to the services array initialising it with the given -service +service. ***************************************************************************/ -static int add_a_service(service *pservice, char *name) +static int add_a_service(const service * pservice, const char *name) { - int i; - service tservice; - int num_to_alloc = iNumServices+1; - - tservice = *pservice; + int i; + service tservice; + int num_to_alloc = iNumServices + 1; - /* it might already exist */ - if (name) - { - i = getservicebyname(name,NULL); - if (i >= 0) - return(i); - } + tservice = *pservice; - /* find an invalid one */ - for (i=0;i<iNumServices;i++) - if (!pSERVICE(i)->valid) - break; - - /* if not, then create one */ - if (i == iNumServices) - { - ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc); - if (ServicePtrs) - pSERVICE(iNumServices) = (service *)malloc(sizeof(service)); - - if (!ServicePtrs || !pSERVICE(iNumServices)) - return(-1); + /* it might already exist */ + if (name) + { + i = getservicebyname(name, NULL); + if (i >= 0) + return (i); + } - iNumServices++; - } - else - free_service(pSERVICE(i)); + /* find an invalid one */ + for (i = 0; i < iNumServices; i++) + if (!ServicePtrs[i]->valid) + break; - pSERVICE(i)->valid = True; + /* if not, then create one */ + if (i == iNumServices) + { + service **tsp; + + tsp = (service **) Realloc(ServicePtrs, + sizeof(service *) * + num_to_alloc); + + if (!tsp) { + DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n")); + return (-1); + } + else { + ServicePtrs = tsp; + ServicePtrs[iNumServices] = + (service *) malloc(sizeof(service)); + } + if (!ServicePtrs[iNumServices]) { + DEBUG(0,("add_a_service: out of memory!\n")); + return (-1); + } + + iNumServices++; + } + else + free_service(ServicePtrs[i]); - init_service(pSERVICE(i)); - copy_service(pSERVICE(i),&tservice,NULL); - if (name) - string_set(&iSERVICE(i).szService,name); + ServicePtrs[i]->valid = True; - return(i); + init_service(ServicePtrs[i]); + copy_service(ServicePtrs[i], &tservice, NULL); + if (name) + { + string_set(&ServicePtrs[i]->szService, name); + } + return (i); } /*************************************************************************** add a new home service, with the specified home directory, defaults coming -from service ifrom +from service ifrom. ***************************************************************************/ -BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir) +BOOL lp_add_home(const char *pszHomename, int iDefaultService, const char *pszHomedir) { - int i = add_a_service(pSERVICE(iDefaultService),pszHomename); + int i; + SMB_STRUCT_STAT buf; - if (i < 0) - return(False); + /* if the user's home directory doesn't exist, then don't + add it to the list of available shares */ + if (sys_stat(pszHomedir, &buf)) + return False; - if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1))) - string_set(&iSERVICE(i).szPath,pszHomedir); - if (!(*(iSERVICE(i).comment))) - { - pstring comment; - sprintf(comment,"Home directory of %s",pszHomename); - string_set(&iSERVICE(i).comment,comment); - } - iSERVICE(i).bAvailable = sDefault.bAvailable; - iSERVICE(i).bBrowseable = sDefault.bBrowseable; + i = add_a_service(ServicePtrs[iDefaultService], pszHomename); - DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir)); + if (i < 0) + return (False); - return(True); + if (!(*(ServicePtrs[i]->szPath)) + || strequal(ServicePtrs[i]->szPath, lp_pathname(-1))) + string_set(&ServicePtrs[i]->szPath, pszHomedir); + if (!(*(ServicePtrs[i]->comment))) + { + pstring comment; + slprintf(comment, sizeof(comment) - 1, + "Home directory of %s", pszHomename); + string_set(&ServicePtrs[i]->comment, comment); + } + ServicePtrs[i]->bAvailable = sDefault.bAvailable; + ServicePtrs[i]->bBrowseable = sDefault.bBrowseable; + + DEBUG(3, + ("adding home directory %s at %s\n", pszHomename, pszHomedir)); + + return (True); } /*************************************************************************** -add a new service, based on an old one +add a new service, based on an old one. ***************************************************************************/ -int lp_add_service(char *pszService, int iDefaultService) +int lp_add_service(const char *pszService, int iDefaultService) { - return(add_a_service(pSERVICE(iDefaultService),pszService)); + return (add_a_service(ServicePtrs[iDefaultService], pszService)); } /*************************************************************************** add the IPC service ***************************************************************************/ -static BOOL lp_add_ipc(void) +static BOOL lp_add_ipc(char *ipc_name, BOOL guest_ok) { - pstring comment; - int i = add_a_service(&sDefault,"IPC$"); - - if (i < 0) - return(False); - - sprintf(comment,"IPC Service (%s)",lp_serverstring()); - - string_set(&iSERVICE(i).szPath,"/tmp"); - string_set(&iSERVICE(i).szUsername,""); - string_set(&iSERVICE(i).comment,comment); - iSERVICE(i).status = False; - iSERVICE(i).iMaxConnections = 0; - iSERVICE(i).bAvailable = True; - iSERVICE(i).bRead_only = True; - iSERVICE(i).bGuest_only = False; - iSERVICE(i).bGuest_ok = True; - iSERVICE(i).bPrint_ok = False; - iSERVICE(i).bBrowseable = sDefault.bBrowseable; - - DEBUG(3,("adding IPC service\n")); - - return(True); + pstring comment; + int i = add_a_service(&sDefault, ipc_name); + + if (i < 0) + return (False); + + slprintf(comment, sizeof(comment) - 1, + "IPC Service (%s)", Globals.szServerString); + + string_set(&ServicePtrs[i]->szPath, tmpdir()); + string_set(&ServicePtrs[i]->szUsername, ""); + string_set(&ServicePtrs[i]->comment, comment); + string_set(&ServicePtrs[i]->fstype, "IPC"); + ServicePtrs[i]->iMaxConnections = 0; + ServicePtrs[i]->bAvailable = True; + ServicePtrs[i]->bRead_only = True; + ServicePtrs[i]->bGuest_only = False; + ServicePtrs[i]->bGuest_ok = guest_ok; + ServicePtrs[i]->bPrint_ok = False; + ServicePtrs[i]->bBrowseable = sDefault.bBrowseable; + + DEBUG(3, ("adding IPC service\n")); + + return (True); } /*************************************************************************** -add a new printer service, with defaults coming from service iFrom +add a new printer service, with defaults coming from service iFrom. ***************************************************************************/ BOOL lp_add_printer(char *pszPrintername, int iDefaultService) { - char *comment = "From Printcap"; - int i = add_a_service(pSERVICE(iDefaultService),pszPrintername); - - if (i < 0) - 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. */ - string_set(&iSERVICE(i).szPrintername,pszPrintername); - string_set(&iSERVICE(i).comment,comment); - iSERVICE(i).bBrowseable = sDefault.bBrowseable; - - DEBUG(3,("adding printer service %s\n",pszPrintername)); - - return(True); -} - - -/*************************************************************************** -Do a case-insensitive, whitespace-ignoring string compare. -***************************************************************************/ -static int strwicmp(char *psz1, char *psz2) -{ - /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */ - /* appropriate value. */ - if (psz1 == psz2) - return (0); - else - if (psz1 == NULL) - return (-1); - else - if (psz2 == NULL) - return (1); - - /* sync the strings on first non-whitespace */ - while (1) - { - while (isspace(*psz1)) - psz1++; - while (isspace(*psz2)) - psz2++; - if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0') - break; - psz1++; - psz2++; - } - return (*psz1 - *psz2); + char *comment = "From Printcap"; + int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername); + + if (i < 0) + 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. */ + string_set(&ServicePtrs[i]->szPrintername, pszPrintername); + string_set(&ServicePtrs[i]->comment, comment); + ServicePtrs[i]->bBrowseable = sDefault.bBrowseable; + /* Printers cannot be read_only. */ + ServicePtrs[i]->bRead_only = False; + /* No share modes on printer services. */ + ServicePtrs[i]->bShareModes = False; + /* No oplocks on printer services. */ + ServicePtrs[i]->bOpLocks = False; + /* Printer services must be printable. */ + ServicePtrs[i]->bPrint_ok = True; + + DEBUG(3, ("adding printer service %s\n", pszPrintername)); + + return (True); } /*************************************************************************** @@ -1009,17 +2037,17 @@ Returns False if the parameter string is not recognised, else TRUE. ***************************************************************************/ static int map_parameter(char *pszParmName) { - int iIndex; + int iIndex; - if (*pszParmName == '-') - return(-1); + if (*pszParmName == '-') + return (-1); - for (iIndex = 0; parm_table[iIndex].label; iIndex++) - if (strwicmp(parm_table[iIndex].label, pszParmName) == 0) - return(iIndex); + for (iIndex = 0; parm_table[iIndex].label; iIndex++) + if (strwicmp(parm_table[iIndex].label, pszParmName) == 0) + return (iIndex); - DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName)); - return(-1); + DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName)); + return (-1); } @@ -1030,44 +2058,45 @@ represent a boolean. ***************************************************************************/ static BOOL set_boolean(BOOL *pb, char *pszParmValue) { - BOOL bRetval; - - bRetval = True; - if (strwicmp(pszParmValue, "yes") == 0 || - strwicmp(pszParmValue, "true") == 0 || - strwicmp(pszParmValue, "1") == 0) - *pb = True; - else - if (strwicmp(pszParmValue, "no") == 0 || - strwicmp(pszParmValue, "False") == 0 || - strwicmp(pszParmValue, "0") == 0) - *pb = False; - else - { - DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n", - pszParmValue)); - bRetval = False; - } - return (bRetval); + BOOL bRetval; + + bRetval = True; + if (strwicmp(pszParmValue, "yes") == 0 || + strwicmp(pszParmValue, "true") == 0 || + strwicmp(pszParmValue, "1") == 0) + *pb = True; + else + if (strwicmp(pszParmValue, "no") == 0 || + strwicmp(pszParmValue, "False") == 0 || + strwicmp(pszParmValue, "0") == 0) + *pb = False; + else + { + DEBUG(0, + ("ERROR: Badly formed boolean in configuration file: \"%s\".\n", + pszParmValue)); + bRetval = False; + } + return (bRetval); } /*************************************************************************** Find a service by name. Otherwise works like get_service. ***************************************************************************/ -static int getservicebyname(char *pszServiceName, service *pserviceDest) +static int getservicebyname(const char *pszServiceName, service * pserviceDest) { - int iService; - - for (iService = iNumServices - 1; iService >= 0; iService--) - if (VALID(iService) && - strwicmp(iSERVICE(iService).szService, pszServiceName) == 0) - { - if (pserviceDest != NULL) - copy_service(pserviceDest, pSERVICE(iService), NULL); - break; - } - - return (iService); + int iService; + + for (iService = iNumServices - 1; iService >= 0; iService--) + if (VALID(iService) && + strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) + { + if (pserviceDest != NULL) + copy_service(pserviceDest, ServicePtrs[iService], NULL); + break; + } + + return (iService); } @@ -1077,54 +2106,67 @@ Copy a service structure to another If pcopymapDest is NULL then copy all fields ***************************************************************************/ -static void copy_service(service *pserviceDest, - service *pserviceSource, - BOOL *pcopymapDest) -{ - int i; - BOOL bcopyall = (pcopymapDest == NULL); - - for (i=0;parm_table[i].label;i++) - if (parm_table[i].ptr && parm_table[i].class == P_LOCAL && - (bcopyall || pcopymapDest[i])) - { - void *def_ptr = parm_table[i].ptr; - void *src_ptr = - ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault); - void *dest_ptr = - ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault); - - switch (parm_table[i].type) - { - case P_BOOL: - case P_BOOLREV: - *(BOOL *)dest_ptr = *(BOOL *)src_ptr; - break; - - case P_INTEGER: - case P_OCTAL: - *(int *)dest_ptr = *(int *)src_ptr; - break; - - case P_CHAR: - *(char *)dest_ptr = *(char *)src_ptr; - break; - - case P_STRING: - string_set(dest_ptr,*(char **)src_ptr); - break; - default: - break; - } - } - - if (bcopyall) - { - init_copymap(pserviceDest); - if (pserviceSource->copymap) - memcpy((void *)pserviceDest->copymap, - (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS); - } +static void copy_service(service * pserviceDest, + service * pserviceSource, BOOL *pcopymapDest) +{ + int i; + BOOL bcopyall = (pcopymapDest == NULL); + + for (i = 0; parm_table[i].label; i++) + if (parm_table[i].ptr && parm_table[i].class == P_LOCAL && + (bcopyall || pcopymapDest[i])) + { + void *def_ptr = parm_table[i].ptr; + void *src_ptr = + ((char *)pserviceSource) + PTR_DIFF(def_ptr, + &sDefault); + void *dest_ptr = + ((char *)pserviceDest) + PTR_DIFF(def_ptr, + &sDefault); + + switch (parm_table[i].type) + { + case P_BOOL: + case P_BOOLREV: + *(BOOL *)dest_ptr = *(BOOL *)src_ptr; + break; + + case P_INTEGER: + case P_ENUM: + case P_OCTAL: + *(int *)dest_ptr = *(int *)src_ptr; + break; + + case P_CHAR: + *(char *)dest_ptr = *(char *)src_ptr; + break; + + case P_STRING: + string_set(dest_ptr, + *(char **)src_ptr); + break; + + case P_USTRING: + string_set(dest_ptr, + *(char **)src_ptr); + strupper(*(char **)dest_ptr); + break; + case P_LIST: + lp_list_copy((char ***)dest_ptr, *(char ***)src_ptr); + break; + default: + break; + } + } + + if (bcopyall) + { + init_copymap(pserviceDest); + if (pserviceSource->copymap) + memcpy((void *)pserviceDest->copymap, + (void *)pserviceSource->copymap, + sizeof(BOOL) * NUMPARAMETERS); + } } /*************************************************************************** @@ -1133,79 +2175,97 @@ incomplete or faulty, else True. ***************************************************************************/ static BOOL service_ok(int iService) { - BOOL bRetval; - - bRetval = True; - if (iSERVICE(iService).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(iSERVICE(iService).szService,PRINTERS_NAME) == 0) - if (!iSERVICE(iService).bPrint_ok) - { - DEBUG(0,( "WARNING: [%s] service MUST be printable!\n", - iSERVICE(iService).szService)); - iSERVICE(iService).bPrint_ok = True; - } - - if (iSERVICE(iService).szPath[0] == '\0' && - strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0) - { - DEBUG(0,("No path in service %s - using /tmp\n",iSERVICE(iService).szService)); - string_set(&iSERVICE(iService).szPath,"/tmp"); - } - - /* If a service is flagged unavailable, log the fact at level 0. */ - if (!iSERVICE(iService).bAvailable) - DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n", - iSERVICE(iService).szService)); - - return (bRetval); -} - -static struct file_lists { - struct file_lists *next; - char *name; - time_t modtime; -} *file_lists = NULL; + BOOL bRetval; + + bRetval = True; + if (ServicePtrs[iService]->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(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) { + if (!ServicePtrs[iService]->bPrint_ok) { + DEBUG(0, + ("WARNING: [%s] service MUST be printable!\n", + ServicePtrs[iService]->szService)); + ServicePtrs[iService]->bPrint_ok = True; + } + /* [printers] service must also be non-browsable. */ + if (ServicePtrs[iService]->bBrowseable) + ServicePtrs[iService]->bBrowseable = False; + } + + if (ServicePtrs[iService]->szPath[0] == '\0' && + strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) + { + DEBUG(0, + ("No path in service %s - using %s\n", + ServicePtrs[iService]->szService, tmpdir())); + string_set(&ServicePtrs[iService]->szPath, tmpdir()); + } + + /* If a service is flagged unavailable, log the fact at level 0. */ + if (!ServicePtrs[iService]->bAvailable) + DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n", + ServicePtrs[iService]->szService)); + + return (bRetval); +} + +static struct file_lists +{ + struct file_lists *next; + char *name; + char *subfname; + time_t modtime; +} + *file_lists = NULL; /******************************************************************* keep a linked list of all config files so we know when one has changed it's date and needs to be reloaded ********************************************************************/ -static void add_to_file_list(char *fname) +static void add_to_file_list(const char *fname, const char *subfname) { - struct file_lists *f=file_lists; + struct file_lists *f = file_lists; - while (f) { - if (f->name && !strcmp(f->name,fname)) break; - f = f->next; - } - - if (!f) { - f = (struct file_lists *)malloc(sizeof(file_lists[0])); - if (!f) return; - f->next = file_lists; - f->name = strdup(fname); - if (!f->name) { - free(f); - return; - } - file_lists = f; - } - - { - pstring n2; - strcpy(n2,fname); - standard_sub_basic(n2); - f->modtime = file_modtime(n2); - } + while (f) + { + if (f->name && !strcmp(f->name, fname)) + break; + f = f->next; + } + if (!f) + { + f = (struct file_lists *)malloc(sizeof(file_lists[0])); + if (!f) + return; + f->next = file_lists; + f->name = strdup(fname); + if (!f->name) + { + SAFE_FREE(f); + return; + } + f->subfname = strdup(subfname); + if (!f->subfname) + { + SAFE_FREE(f); + return; + } + file_lists = f; + f->modtime = file_modtime(subfname); + } else { + time_t t = file_modtime(subfname); + if (t) + f->modtime = t; + } } /******************************************************************* @@ -1213,679 +2273,1816 @@ check if a config file has changed date ********************************************************************/ BOOL lp_file_list_changed(void) { - struct file_lists *f = file_lists; - while (f) { - pstring n2; - strcpy(n2,f->name); - standard_sub_basic(n2); - if (f->modtime != file_modtime(n2)) return(True); - f = f->next; - } - return(False); + struct file_lists *f = file_lists; + DEBUG(6, ("lp_file_list_changed()\n")); + + while (f) { + pstring n2; + time_t mod_time; + + pstrcpy(n2, f->name); + standard_sub_basic(current_user_info.smb_name, n2); + + 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; + SAFE_FREE(f->subfname); + f->subfname = strdup(n2); + return (True); + } + f = f->next; + } + return (False); } -#ifdef KANJI /*************************************************************************** - handle the interpretation of the coding system parameter - *************************************************************************/ -static BOOL handle_coding_system(char *pszParmValue,int *val) + Run standard_sub_basic on netbios name... needed because global_myname + is not accessed through any lp_ macro. + Note: We must *NOT* use string_set() here as ptr points to global_myname. +***************************************************************************/ + +static BOOL handle_netbios_name(char *pszParmValue, char **ptr) { - *val = interpret_coding_system(pszParmValue,*val); - return(True); + pstring netbios_name; + + pstrcpy(netbios_name, pszParmValue); + + standard_sub_basic(current_user_info.smb_name, netbios_name); + strupper(netbios_name); + + pstrcpy(global_myname, netbios_name); + + DEBUG(4, + ("handle_netbios_name: set global_myname to: %s\n", + global_myname)); + + return (True); } -#endif /* KANJI */ /*************************************************************************** -handle the interpretation of the character set system parameter + Do the work of sourcing in environment variable/value pairs. ***************************************************************************/ -static BOOL handle_character_set(char *pszParmValue,int *val) + +static BOOL source_env(char **lines) { - string_set(&Globals.szCharacterSet,pszParmValue); - *val = interpret_character_set(pszParmValue,*val); - return(True); -} + char *varval; + size_t len; + int i; + char *p; + for (i = 0; lines[i]; i++) + { + char *line = lines[i]; + + if ((len = strlen(line)) == 0) + continue; + + if (line[len - 1] == '\n') + line[--len] = '\0'; + + if ((varval = malloc(len + 1)) == NULL) + { + DEBUG(0, ("source_env: Not enough memory!\n")); + return (False); + } + + DEBUG(4, ("source_env: Adding to environment: %s\n", line)); + strncpy(varval, line, len); + varval[len] = '\0'; + + p = strchr_m(line, (int)'='); + if (p == NULL) + { + DEBUG(4, ("source_env: missing '=': %s\n", line)); + continue; + } + + if (putenv(varval)) + { + DEBUG(0, + ("source_env: Failed to put environment variable %s\n", + varval)); + continue; + } + + *p = '\0'; + p++; + DEBUG(4, + ("source_env: getting var %s = %s\n", line, + getenv(line))); + } + + DEBUG(4, ("source_env: returning successfully\n")); + return (True); +} /*************************************************************************** -handle the interpretation of the protocol parameter + Handle the source environment operation ***************************************************************************/ -static BOOL handle_protocol(char *pszParmValue,int *val) + +static BOOL handle_source_env(char *pszParmValue, char **ptr) { - *val = interpret_protocol(pszParmValue,*val); - return(True); + pstring fname; + char *p = fname; + BOOL result; + char **lines; + + pstrcpy(fname, pszParmValue); + + standard_sub_basic(current_user_info.smb_name, fname); + + string_set(ptr, pszParmValue); + + DEBUG(4, ("handle_source_env: checking env type\n")); + + /* + * Filename starting with '|' means popen and read from stdin. + */ + + if (*p == '|') + { + lines = file_lines_pload(p + 1, NULL); + } + else + { + lines = file_lines_load(fname, NULL); + } + + if (!lines) + { + DEBUG(0, + ("handle_source_env: Failed to open file %s, Error was %s\n", + fname, strerror(errno))); + return (False); + } + + result = source_env(lines); + file_lines_free(lines); + + return (result); } /*************************************************************************** -handle the interpretation of the security parameter -***************************************************************************/ -static BOOL handle_security(char *pszParmValue,int *val) + handle the interpretation of the vfs object parameter + *************************************************************************/ +static BOOL handle_vfs_object(char *pszParmValue, char **ptr) { - *val = interpret_security(pszParmValue,*val); - return(True); + /* Set string value */ + + string_set(ptr, pszParmValue); + + /* Do any other initialisation required for vfs. Note that + anything done here may have linking repercussions in nmbd. */ + + return True; } + /*************************************************************************** -handle the interpretation of the default case +handle the include operation ***************************************************************************/ -static BOOL handle_case(char *pszParmValue,int *val) + +static BOOL handle_include(char *pszParmValue, char **ptr) { - if (strequal(pszParmValue,"LOWER")) - *val = CASE_LOWER; - else if (strequal(pszParmValue,"UPPER")) - *val = CASE_UPPER; - return(True); + pstring fname; + pstrcpy(fname, pszParmValue); + + standard_sub_basic(current_user_info.smb_name, fname); + + add_to_file_list(pszParmValue, fname); + + string_set(ptr, fname); + + if (file_exist(fname, NULL)) + return (pm_process(fname, do_section, do_parameter)); + + DEBUG(2, ("Can't find include file %s\n", fname)); + + return (False); } + /*************************************************************************** -handle the interpretation of the printing system +handle the interpretation of the copy parameter ***************************************************************************/ -static BOOL handle_printing(char *pszParmValue,int *val) +static BOOL handle_copy(char *pszParmValue, char **ptr) { - if (strequal(pszParmValue,"sysv")) - *val = PRINT_SYSV; - else if (strequal(pszParmValue,"aix")) - *val = PRINT_AIX; - else if (strequal(pszParmValue,"hpux")) - *val = PRINT_HPUX; - else if (strequal(pszParmValue,"bsd")) - *val = PRINT_BSD; - else if (strequal(pszParmValue,"qnx")) - *val = PRINT_QNX; - return(True); + BOOL bRetval; + int iTemp; + service serviceTemp; + + string_set(ptr, pszParmValue); + + init_service(&serviceTemp); + + bRetval = False; + + DEBUG(3, ("Copying service from service %s\n", pszParmValue)); + + if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) + { + if (iTemp == iServiceIndex) + { + DEBUG(0, + ("Can't copy service %s - unable to copy self!\n", + pszParmValue)); + } + else + { + copy_service(ServicePtrs[iServiceIndex], + &serviceTemp, + ServicePtrs[iServiceIndex]->copymap); + bRetval = True; + } + } + else + { + DEBUG(0, ("Unable to copy service - source not found: %s\n", + pszParmValue)); + bRetval = False; + } + + free_service(&serviceTemp); + return (bRetval); } /*************************************************************************** -handle the valid chars lines + Handle winbind/non unix account uid and gid allocation parameters. The format of these + parameters is: + + [global] + + winbind uid = 1000-1999 + winbind gid = 700-899 + + We only do simple parsing checks here. The strings are parsed into useful + structures in the winbind daemon code. + ***************************************************************************/ -static BOOL handle_valid_chars(char *pszParmValue,char **ptr) -{ - string_set(ptr,pszParmValue); - add_char_string(pszParmValue); - return(True); +/* Some lp_ routines to return winbind [ug]id information */ + +static uid_t winbind_uid_low, winbind_uid_high; +static gid_t winbind_gid_low, winbind_gid_high; +static uint32 non_unix_account_low, non_unix_account_high; + +BOOL lp_winbind_uid(uid_t *low, uid_t *high) +{ + if (winbind_uid_low == 0 || winbind_uid_high == 0) + return False; + + if (low) + *low = winbind_uid_low; + + if (high) + *high = winbind_uid_high; + + return True; } +BOOL lp_winbind_gid(gid_t *low, gid_t *high) +{ + if (winbind_gid_low == 0 || winbind_gid_high == 0) + return False; -/*************************************************************************** -handle the include operation -***************************************************************************/ -static BOOL handle_include(char *pszParmValue,char **ptr) -{ - pstring fname; - strcpy(fname,pszParmValue); + if (low) + *low = winbind_gid_low; - add_to_file_list(fname); + if (high) + *high = winbind_gid_high; - standard_sub_basic(fname); + return True; +} - string_set(ptr,fname); +BOOL lp_non_unix_account_range(uint32 *low, uint32 *high) +{ + if (non_unix_account_low == 0 || non_unix_account_high == 0) + return False; - if (file_exist(fname,NULL)) - return(pm_process(fname, do_section, do_parameter)); + if (low) + *low = non_unix_account_low; - DEBUG(2,("Can't find include file %s\n",fname)); + if (high) + *high = non_unix_account_high; - return(False); + return True; } +/* Do some simple checks on "winbind [ug]id" parameter values */ + +static BOOL handle_winbind_uid(char *pszParmValue, char **ptr) +{ + uint32 low, high; + + if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low) + return False; + + /* Parse OK */ + + string_set(ptr, pszParmValue); + + winbind_uid_low = low; + winbind_uid_high = high; + + return True; +} + +static BOOL handle_winbind_gid(char *pszParmValue, char **ptr) +{ + uint32 low, high; + + if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low) + return False; + + /* Parse OK */ + + string_set(ptr, pszParmValue); + + winbind_gid_low = low; + winbind_gid_high = high; + + return True; +} + +/* Do some simple checks on "non unix account range" parameter values */ + +static BOOL handle_non_unix_account_range(char *pszParmValue, char **ptr) +{ + uint32 low, high; + + if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low) + return False; + + /* Parse OK */ + + string_set(ptr, pszParmValue); + + non_unix_account_low = low; + non_unix_account_high = high; + + return True; +} /*************************************************************************** -handle the interpretation of the copy parameter + Handle the WINS SERVER list ***************************************************************************/ -static BOOL handle_copy(char *pszParmValue,char **ptr) +static BOOL handle_wins_server_list( char *pszParmValue, char **ptr ) + { + if( !wins_srv_load_list( pszParmValue ) ) + return( False ); /* Parse failed. */ + + string_set( ptr, pszParmValue ); + return( True ); + } + + +/*************************************************************************** + Handle the DEBUG level list +***************************************************************************/ +static BOOL handle_debug_list( char *pszParmValueIn, char **ptr ) { - BOOL bRetval; - int iTemp; - service serviceTemp; + pstring pszParmValue; + + pstrcpy(pszParmValue, pszParmValueIn); + return debug_parse_levels( pszParmValue ); +} - string_set(ptr,pszParmValue); +#ifdef WITH_LDAP_SAM +/*************************************************************************** + Handle the ldap machine suffix option +***************************************************************************/ +static BOOL handle_ldap_machine_suffix( char *pszParmValue, char **ptr) +{ + pstring suffix; + + pstrcpy(suffix, pszParmValue); - init_service(&serviceTemp); + if (! *Globals.szLdapSuffix ) { + string_set( ptr, suffix ); + return True; + } - bRetval = False; - - DEBUG(3,("Copying service from service %s\n",pszParmValue)); - - if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) - { - if (iTemp == iServiceIndex) - { - DEBUG(0,("Can't copy service %s - unable to copy self!\n", - pszParmValue)); - } - else - { - copy_service(pSERVICE(iServiceIndex), - &serviceTemp, - iSERVICE(iServiceIndex).copymap); - bRetval = True; - } - } - else - { - DEBUG(0,( "Unable to copy service - source not found: %s\n", - pszParmValue)); - bRetval = False; - } - - free_service(&serviceTemp); - return (bRetval); + if (! strstr(suffix, Globals.szLdapSuffix) ) { + if ( *pszParmValue ) + pstrcat(suffix, ","); + pstrcat(suffix, Globals.szLdapSuffix); + } + string_set( ptr, suffix ); + return True; } +/*************************************************************************** + Handle the ldap user suffix option +***************************************************************************/ +static BOOL handle_ldap_user_suffix( char *pszParmValue, char **ptr) +{ + pstring suffix; + + pstrcpy(suffix, pszParmValue); + + if (! *Globals.szLdapSuffix ) { + string_set( ptr, suffix ); + return True; + } + + if (! strstr(suffix, Globals.szLdapSuffix) ) { + if ( *pszParmValue ) + pstrcat(suffix, ","); + pstrcat(suffix, Globals.szLdapSuffix); + } + string_set( ptr, suffix ); + return True; +} + +/*************************************************************************** + Handle setting ldap suffix and determines whether ldap machine suffix needs + to be set as well +***************************************************************************/ +static BOOL handle_ldap_suffix( char *pszParmValue, char **ptr) +{ + pstring suffix; + pstring user_suffix; + pstring machine_suffix; + + pstrcpy(suffix, pszParmValue); + + if (! *Globals.szLdapMachineSuffix ) + string_set(&Globals.szLdapMachineSuffix, suffix); + if (! *Globals.szLdapUserSuffix ) + string_set(&Globals.szLdapUserSuffix, suffix); + + if (! strstr(Globals.szLdapMachineSuffix, suffix)) { + pstrcpy(machine_suffix, Globals.szLdapMachineSuffix); + if ( *Globals.szLdapMachineSuffix ) + pstrcat(machine_suffix, ","); + pstrcat(machine_suffix, suffix); + string_set(&Globals.szLdapMachineSuffix, machine_suffix); + } + + if (! strstr(Globals.szLdapUserSuffix, suffix)) { + pstrcpy(user_suffix, Globals.szLdapUserSuffix); + if ( *Globals.szLdapUserSuffix ) + pstrcat(user_suffix, ","); + pstrcat(user_suffix, suffix); + string_set(&Globals.szLdapUserSuffix, user_suffix); + } + + string_set(ptr, suffix); + return True; +} +#endif /* WITH_LDAP_SAM */ /*************************************************************************** initialise a copymap ***************************************************************************/ -static void init_copymap(service *pservice) +static void init_copymap(service * pservice) { - int i; - if (pservice->copymap) free(pservice->copymap); - pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS); - if (!pservice->copymap) - DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS)); + int i; + SAFE_FREE(pservice->copymap); + pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS); + if (!pservice->copymap) + DEBUG(0, + ("Couldn't allocate copymap!! (size %d)\n", + (int)NUMPARAMETERS)); + else + for (i = 0; i < NUMPARAMETERS; i++) + pservice->copymap[i] = True; +} + - for (i=0;i<NUMPARAMETERS;i++) - pservice->copymap[i] = True; +/*************************************************************************** + return the local pointer to a parameter given the service number and the + pointer into the default structure +***************************************************************************/ +void *lp_local_ptr(int snum, void *ptr) +{ + return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault)); } +/*************************************************************************** +Process a parameter for a particular service number. If snum < 0 +then assume we are in the globals +***************************************************************************/ +BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue) +{ + int parmnum, i; + void *parm_ptr = NULL; /* where we are going to store the result */ + void *def_ptr = NULL; + + parmnum = map_parameter(pszParmName); + + if (parmnum < 0) + { + DEBUG(0, + ("Ignoring unknown parameter \"%s\"\n", pszParmName)); + return (True); + } + + if (parm_table[parmnum].flags & FLAG_DEPRECATED) + { + DEBUG(1, ("WARNING: The \"%s\"option is deprecated\n", + pszParmName)); + } + + def_ptr = parm_table[parmnum].ptr; + + /* we might point at a service, the default service or a global */ + if (snum < 0) + { + parm_ptr = def_ptr; + } + else + { + if (parm_table[parmnum].class == P_GLOBAL) + { + DEBUG(0, + ("Global parameter %s found in service section!\n", + pszParmName)); + return (True); + } + parm_ptr = + ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr, + &sDefault); + } + + if (snum >= 0) + { + if (!ServicePtrs[snum]->copymap) + init_copymap(ServicePtrs[snum]); + + /* 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].ptr == parm_table[parmnum].ptr) + ServicePtrs[snum]->copymap[i] = False; + } + + /* if it is a special case then go ahead */ + if (parm_table[parmnum].special) + { + parm_table[parmnum].special(pszParmValue, (char **)parm_ptr); + return (True); + } + + /* now switch on the type of variable it is */ + switch (parm_table[parmnum].type) + { + case P_BOOL: + set_boolean(parm_ptr, pszParmValue); + break; + + case P_BOOLREV: + set_boolean(parm_ptr, pszParmValue); + *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr; + break; + + case P_INTEGER: + *(int *)parm_ptr = atoi(pszParmValue); + break; + + case P_CHAR: + *(char *)parm_ptr = *pszParmValue; + break; + + case P_OCTAL: + sscanf(pszParmValue, "%o", (int *)parm_ptr); + break; + + case P_LIST: + *(char ***)parm_ptr = lp_list_make(pszParmValue); + break; + + case P_STRING: + string_set(parm_ptr, pszParmValue); + break; + + case P_USTRING: + string_set(parm_ptr, pszParmValue); + strupper(*(char **)parm_ptr); + break; + + case P_GSTRING: + pstrcpy((char *)parm_ptr, pszParmValue); + break; + + case P_UGSTRING: + pstrcpy((char *)parm_ptr, pszParmValue); + strupper((char *)parm_ptr); + break; + + case P_ENUM: + for (i = 0; parm_table[parmnum].enum_list[i].name; + i++) + { + if (strequal + (pszParmValue, + parm_table[parmnum].enum_list[i].name)) + { + *(int *)parm_ptr = + parm_table[parmnum]. + enum_list[i].value; + break; + } + } + break; + case P_SEP: + break; + } + + return (True); +} /*************************************************************************** Process a parameter. ***************************************************************************/ static BOOL do_parameter(char *pszParmName, char *pszParmValue) { - int parmnum; - void *parm_ptr=NULL; /* where we are going to store the result */ - void *def_ptr=NULL; + if (!bInGlobalSection && bGlobalOnly) + return (True); - if (!bInGlobalSection && bGlobalOnly) return(True); + DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue)); - DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue)); - - parmnum = map_parameter(pszParmName); - - if (parmnum < 0) - { - DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName)); - return(True); - } - - def_ptr = parm_table[parmnum].ptr; - - /* we might point at a service, the default service or a global */ - if (bInGlobalSection) - parm_ptr = def_ptr; - else - { - if (parm_table[parmnum].class == P_GLOBAL) - { - DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName)); - return(True); - } - parm_ptr = ((char *)pSERVICE(iServiceIndex)) + PTR_DIFF(def_ptr,&sDefault); - } - - if (!bInGlobalSection) - { - int i; - if (!iSERVICE(iServiceIndex).copymap) - init_copymap(pSERVICE(iServiceIndex)); - - /* 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].ptr == parm_table[parmnum].ptr) - iSERVICE(iServiceIndex).copymap[i] = False; - } - - /* if it is a special case then go ahead */ - if (parm_table[parmnum].special) - { - parm_table[parmnum].special(pszParmValue,parm_ptr); - return(True); - } - - /* now switch on the type of variable it is */ - switch (parm_table[parmnum].type) - { - case P_BOOL: - set_boolean(parm_ptr,pszParmValue); - break; - - case P_BOOLREV: - set_boolean(parm_ptr,pszParmValue); - *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr; - break; - - case P_INTEGER: - *(int *)parm_ptr = atoi(pszParmValue); - break; - - case P_CHAR: - *(char *)parm_ptr = *pszParmValue; - break; - - case P_OCTAL: - sscanf(pszParmValue,"%o",(int *)parm_ptr); - break; - - case P_STRING: - string_set(parm_ptr,pszParmValue); - break; - - case P_GSTRING: - strcpy((char *)parm_ptr,pszParmValue); - break; - } - - return(True); + return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex, + pszParmName, pszParmValue)); } + /*************************************************************************** print a parameter of the specified type ***************************************************************************/ -static void print_parameter(parm_type type,void *ptr) -{ - switch (type) - { - case P_BOOL: - printf("%s",BOOLSTR(*(BOOL *)ptr)); - break; - - case P_BOOLREV: - printf("%s",BOOLSTR(! *(BOOL *)ptr)); - break; - - case P_INTEGER: - printf("%d",*(int *)ptr); - break; - - case P_CHAR: - printf("%c",*(char *)ptr); - break; - - case P_OCTAL: - printf("0%o",*(int *)ptr); - break; - - case P_GSTRING: - if ((char *)ptr) - printf("%s",(char *)ptr); - break; - - case P_STRING: - if (*(char **)ptr) - printf("%s",*(char **)ptr); - break; - } +static void print_parameter(struct parm_struct *p, void *ptr, FILE * f) +{ + 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: + fprintf(f, "%d", *(int *)ptr); + break; + + case P_CHAR: + fprintf(f, "%c", *(char *)ptr); + break; + + case P_OCTAL: + fprintf(f, "%s", octal_string(*(int *)ptr)); + break; + + case P_LIST: + if ((char ***)ptr && *(char ***)ptr) { + char **list = *(char ***)ptr; + + for (; *list; list++) + fprintf(f, "%s%s", *list, + ((*(list+1))?", ":"")); + } + break; + + case P_GSTRING: + case P_UGSTRING: + if ((char *)ptr) { + fprintf(f, "%s", (char *)ptr); + } + 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 ***************************************************************************/ -static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2) -{ - switch (type) - { - case P_BOOL: - case P_BOOLREV: - return(*((BOOL *)ptr1) == *((BOOL *)ptr2)); - - case P_INTEGER: - case P_OCTAL: - return(*((int *)ptr1) == *((int *)ptr2)); - - case P_CHAR: - return(*((char *)ptr1) == *((char *)ptr2)); - - case P_GSTRING: - { - 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_STRING: - { - char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2; - if (p1 && !*p1) p1 = NULL; - if (p2 && !*p2) p2 = NULL; - return(p1==p2 || strequal(p1,p2)); - } - } - return(False); +static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2) +{ + switch (type) + { + case P_BOOL: + case P_BOOLREV: + return (*((BOOL *)ptr1) == *((BOOL *)ptr2)); + + case P_INTEGER: + case P_ENUM: + case P_OCTAL: + return (*((int *)ptr1) == *((int *)ptr2)); + + case P_CHAR: + return (*((char *)ptr1) == *((char *)ptr2)); + + case P_LIST: + return lp_list_compare(*(char ***)ptr1, *(char ***)ptr2); + + case P_GSTRING: + case P_UGSTRING: + { + 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_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); +} + +/*************************************************************************** + Initialize any local varients in the sDefault table. +***************************************************************************/ + +void init_locals(void) +{ + /* None as yet. */ } /*************************************************************************** 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. +Returns True on success, False on failure. ***************************************************************************/ static BOOL do_section(char *pszSectionName) { - BOOL bRetval; - BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) || - (strwicmp(pszSectionName, GLOBAL_NAME2) == 0)); - bRetval = False; + BOOL bRetval; + BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) || + (strwicmp(pszSectionName, GLOBAL_NAME2) == 0)); + bRetval = False; - /* if we were in a global section then do the local inits */ - if (bInGlobalSection && !isglobal) - init_locals(); + /* if we were in a global section then do the local inits */ + if (bInGlobalSection && !isglobal) + init_locals(); - /* if we've just struck a global section, note the fact. */ - bInGlobalSection = isglobal; + /* if we've just struck a global section, note the fact. */ + bInGlobalSection = isglobal; - /* check for multiple global sections */ - if (bInGlobalSection) - { - DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName)); - return(True); - } + /* check for multiple global sections */ + if (bInGlobalSection) + { + DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName)); + return (True); + } - if (!bInGlobalSection && bGlobalOnly) return(True); + if (!bInGlobalSection && bGlobalOnly) + return (True); - /* if we have a current service, tidy it up before moving on */ - bRetval = True; + /* if we have a current service, tidy it up before moving on */ + bRetval = True; - if (iServiceIndex >= 0) - bRetval = service_ok(iServiceIndex); + if (iServiceIndex >= 0) + bRetval = service_ok(iServiceIndex); - /* 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(2,( "Processing section \"[%s]\"\n", pszSectionName)); + /* 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(2, ("Processing section \"[%s]\"\n", pszSectionName)); + + if ((iServiceIndex = add_a_service(&sDefault, pszSectionName)) + < 0) + { + DEBUG(0, ("Failed to add a new service\n")); + return (False); + } + } + + return (bRetval); +} - if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0) - { - DEBUG(0,("Failed to add a new service\n")); - return(False); - } - } - return (bRetval); +/*************************************************************************** +determine if a partcular base parameter is currentl set to the default value. +***************************************************************************/ +static BOOL is_default(int i) +{ + if (!defaults_saved) + return False; + switch (parm_table[i].type) + { + case P_LIST: + return lp_list_compare (parm_table[i].def.lvalue, + *(char ***)parm_table[i].ptr); + case P_STRING: + case P_USTRING: + return strequal(parm_table[i].def.svalue, + *(char **)parm_table[i].ptr); + case P_GSTRING: + case P_UGSTRING: + return strequal(parm_table[i].def.svalue, + (char *)parm_table[i].ptr); + case P_BOOL: + case P_BOOLREV: + return parm_table[i].def.bvalue == + *(BOOL *)parm_table[i].ptr; + case P_CHAR: + return parm_table[i].def.cvalue == + *(char *)parm_table[i].ptr; + case P_INTEGER: + case P_OCTAL: + case P_ENUM: + return parm_table[i].def.ivalue == + *(int *)parm_table[i].ptr; + case P_SEP: + break; + } + return False; } + /*************************************************************************** Display the contents of the global structure. ***************************************************************************/ -static void dump_globals(void) +static void dump_globals(FILE *f) { - int i; - printf("Global parameters:\n"); + int i; + fprintf(f, "# Global parameters\n[global]\n"); + + for (i = 0; parm_table[i].label; i++) + if (parm_table[i].class == P_GLOBAL && + parm_table[i].ptr && + (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) + { + if (defaults_saved && is_default(i)) + continue; + fprintf(f, "\t%s = ", parm_table[i].label); + print_parameter(&parm_table[i], parm_table[i].ptr, f); + fprintf(f, "\n"); + } +} - for (i=0;parm_table[i].label;i++) - if (parm_table[i].class == P_GLOBAL && - parm_table[i].ptr && - (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) - { - printf("\t%s: ",parm_table[i].label); - print_parameter(parm_table[i].type,parm_table[i].ptr); - printf("\n"); - } +/*************************************************************************** +return True if a local parameter is currently set to the global default +***************************************************************************/ +BOOL lp_is_default(int snum, struct parm_struct *parm) +{ + int pdiff = PTR_DIFF(parm->ptr, &sDefault); + + return equal_parameter(parm->type, + ((char *)ServicePtrs[snum]) + pdiff, + ((char *)&sDefault) + pdiff); } + /*************************************************************************** Display the contents of a single services record. ***************************************************************************/ -static void dump_a_service(service *pService) -{ - int i; - if (pService == &sDefault) - printf("\nDefault service parameters:\n"); - else - printf("\nService parameters [%s]:\n",pService->szService); - - for (i=0;parm_table[i].label;i++) - if (parm_table[i].class == P_LOCAL && - parm_table[i].ptr && - (*parm_table[i].label != '-') && - (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) - { - int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault); - - if (pService == &sDefault || !equal_parameter(parm_table[i].type, - ((char *)pService) + pdiff, - ((char *)&sDefault) + pdiff)) - { - printf("\t%s: ",parm_table[i].label); - print_parameter(parm_table[i].type, - ((char *)pService) + pdiff); - printf("\n"); - } - } +static void dump_a_service(service * pService, FILE * f) +{ + int i; + if (pService != &sDefault) + fprintf(f, "\n[%s]\n", pService->szService); + + for (i = 0; parm_table[i].label; i++) + if (parm_table[i].class == P_LOCAL && + parm_table[i].ptr && + (*parm_table[i].label != '-') && + (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) + { + int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault); + + if (pService == &sDefault) + { + if (defaults_saved && is_default(i)) + continue; + } + else + { + if (equal_parameter(parm_table[i].type, + ((char *)pService) + + pdiff, + ((char *)&sDefault) + + pdiff)) + continue; + } + + fprintf(f, "\t%s = ", parm_table[i].label); + print_parameter(&parm_table[i], + ((char *)pService) + pdiff, f); + fprintf(f, "\n"); + } +} + + +/*************************************************************************** +return info about the next service in a service. snum==-1 gives the globals + +return NULL when out of parameters +***************************************************************************/ +struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters) +{ + if (snum == -1) + { + /* do the globals */ + for (; parm_table[*i].label; (*i)++) + { + if (parm_table[*i].class == P_SEPARATOR) + return &parm_table[(*i)++]; + + if (!parm_table[*i].ptr + || (*parm_table[*i].label == '-')) + continue; + + if ((*i) > 0 + && (parm_table[*i].ptr == + parm_table[(*i) - 1].ptr)) + continue; + + return &parm_table[(*i)++]; + } + } + else + { + service *pService = ServicePtrs[snum]; + + for (; parm_table[*i].label; (*i)++) + { + if (parm_table[*i].class == P_SEPARATOR) + return &parm_table[(*i)++]; + + if (parm_table[*i].class == P_LOCAL && + parm_table[*i].ptr && + (*parm_table[*i].label != '-') && + ((*i) == 0 || + (parm_table[*i].ptr != + parm_table[(*i) - 1].ptr))) + { + int pdiff = + PTR_DIFF(parm_table[*i].ptr, + &sDefault); + + if (allparameters || + !equal_parameter(parm_table[*i].type, + ((char *)pService) + + pdiff, + ((char *)&sDefault) + + pdiff)) + { + return &parm_table[(*i)++]; + } + } + } + } + + return NULL; } + #if 0 /*************************************************************************** Display the contents of a single copy structure. ***************************************************************************/ static void dump_copy_map(BOOL *pcopymap) { - int i; - if (!pcopymap) return; - - printf("\n\tNon-Copied parameters:\n"); - - for (i=0;parm_table[i].label;i++) - if (parm_table[i].class == P_LOCAL && - parm_table[i].ptr && !pcopymap[i] && - (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) - { - printf("\t\t%s\n",parm_table[i].label); - } + int i; + if (!pcopymap) + return; + + printf("\n\tNon-Copied parameters:\n"); + + for (i = 0; parm_table[i].label; i++) + if (parm_table[i].class == P_LOCAL && + parm_table[i].ptr && !pcopymap[i] && + (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) + { + printf("\t\t%s\n", parm_table[i].label); + } } #endif /*************************************************************************** Return TRUE if the passed service number is within range. ***************************************************************************/ + BOOL lp_snum_ok(int iService) { - return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable); + return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable); } - /*************************************************************************** -auto-load some homes and printer services + Auto-load some home services. ***************************************************************************/ + static void lp_add_auto_services(char *str) { - char *s; - char *p; - int homes = lp_servicenumber(HOMES_NAME); - int printers = lp_servicenumber(PRINTERS_NAME); + char *s; + char *p; + int homes; - if (!str) - return; + if (!str) + return; - s = strdup(str); - if (!s) return; + s = strdup(str); + if (!s) + return; - for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) - { - char *home = get_home_dir(p); + homes = lp_servicenumber(HOMES_NAME); - if (lp_servicenumber(p) >= 0) continue; + for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) { + char *home = get_user_service_home_dir(p); - if (home && homes >= 0) - { - lp_add_home(p,homes,home); - continue; - } + if (lp_servicenumber(p) >= 0) + continue; - if (printers >= 0 && pcap_printername_ok(p,NULL)) - lp_add_printer(p,printers); - } - free(s); + if (home && homes >= 0) + lp_add_home(p, homes, home); + } + SAFE_FREE(s); } /*************************************************************************** -auto-load one printer + Auto-load one printer. ***************************************************************************/ -static void lp_add_one_printer(char *name,char *comment) -{ - int printers = lp_servicenumber(PRINTERS_NAME); - int i; - if (lp_servicenumber(name) < 0) - { - lp_add_printer(name,printers); - if ((i=lp_servicenumber(name)) >= 0) - string_set(&iSERVICE(i).comment,comment); - } +void lp_add_one_printer(char *name, char *comment) +{ + int printers = lp_servicenumber(PRINTERS_NAME); + int i; + + if (lp_servicenumber(name) < 0) { + lp_add_printer(name, printers); + if ((i = lp_servicenumber(name)) >= 0) { + string_set(&ServicePtrs[i]->comment, comment); + ServicePtrs[i]->autoloaded = True; + } + } } - /*************************************************************************** -auto-load printer services + Have we loaded a services file yet? ***************************************************************************/ -static void lp_add_all_printers(void) + +BOOL lp_loaded(void) { - int printers = lp_servicenumber(PRINTERS_NAME); + return (bLoaded); +} - if (printers < 0) return; +/*************************************************************************** + Unload unused services. +***************************************************************************/ - pcap_printer_fn(lp_add_one_printer); +void lp_killunused(BOOL (*snumused) (int)) +{ + int i; + for (i = 0; i < iNumServices; i++) { + if (!VALID(i)) + continue; + + if (!snumused || !snumused(i)) { + ServicePtrs[i]->valid = False; + free_service(ServicePtrs[i]); + } + } } /*************************************************************************** -have we loaded a services file yet? + Unload a service. ***************************************************************************/ -BOOL lp_loaded(void) + +void lp_killservice(int iServiceIn) { - return(bLoaded); + if (VALID(iServiceIn)) { + ServicePtrs[iServiceIn]->valid = False; + free_service(ServicePtrs[iServiceIn]); + } } /*************************************************************************** -unload unused services + Save the curent values of all global and sDefault parameters into the + defaults union. This allows swat and testparm to show only the + changed (ie. non-default) parameters. ***************************************************************************/ -void lp_killunused(BOOL (*snumused)(int )) + +static void lp_save_defaults(void) { - int i; - for (i=0;i<iNumServices;i++) - if (VALID(i) && !snumused(i)) - { - iSERVICE(i).valid = False; - free_service(pSERVICE(i)); - } + int i; + for (i = 0; parm_table[i].label; i++) { + if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr) + continue; + switch (parm_table[i].type) { + case P_LIST: + lp_list_copy(&(parm_table[i].def.lvalue), + *(char ***)parm_table[i].ptr); + break; + case P_STRING: + case P_USTRING: + parm_table[i].def.svalue = + strdup(*(char **)parm_table[i].ptr); + break; + case P_GSTRING: + case P_UGSTRING: + parm_table[i].def.svalue = + strdup((char *)parm_table[i].ptr); + break; + case P_BOOL: + case P_BOOLREV: + parm_table[i].def.bvalue = + *(BOOL *)parm_table[i].ptr; + break; + case P_CHAR: + parm_table[i].def.cvalue = + *(char *)parm_table[i].ptr; + break; + case P_INTEGER: + case P_OCTAL: + case P_ENUM: + parm_table[i].def.ivalue = + *(int *)parm_table[i].ptr; + break; + case P_SEP: + break; + } + } + defaults_saved = True; } +/******************************************************************* + Set the server type we will announce as via nmbd. +********************************************************************/ + +static void set_server_role(void) +{ + server_role = ROLE_STANDALONE; + + switch (lp_security()) { + case SEC_SHARE: + { + if (lp_domain_logons()) { + DEBUG(0, + ("Server's Role (logon server) conflicts with share-level security\n")); + } + break; + } + case SEC_SERVER: + case SEC_DOMAIN: + case SEC_ADS: + { + if (lp_domain_logons()) { + server_role = ROLE_DOMAIN_BDC; + break; + } + server_role = ROLE_DOMAIN_MEMBER; + break; + } + case SEC_USER: + { + if (lp_domain_logons()) { + server_role = ROLE_DOMAIN_PDC; + break; + } + break; + } + default: + { + DEBUG(0, + ("Server's Role undefined due to unknown security mode\n")); + } + } +} + + /*************************************************************************** Load the services array from the services file. Return True on success, False on failure. ***************************************************************************/ -BOOL lp_load(char *pszFname,BOOL global_only) +BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults, + BOOL add_ipc) { - pstring n2; - BOOL bRetval; - - add_to_file_list(pszFname); + pstring n2; + BOOL bRetval; + + pstrcpy(n2, pszFname); + standard_sub_basic(current_user_info.smb_name, n2); + + add_to_file_list(pszFname, n2); + + bRetval = False; - bRetval = False; + bInGlobalSection = True; + bGlobalOnly = global_only; - bInGlobalSection = True; - bGlobalOnly = global_only; - - init_globals(); - - strcpy(n2,pszFname); - standard_sub_basic(n2); + init_globals(); - /* We get sections first, so have to start 'behind' to make up */ - iServiceIndex = -1; - bRetval = pm_process(n2, do_section, do_parameter); - - /* finish up the last section */ - DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval))); - if (bRetval) - if (iServiceIndex >= 0) - bRetval = service_ok(iServiceIndex); + if (save_defaults) + { + init_locals(); + lp_save_defaults(); + } + + /* We get sections first, so have to start 'behind' to make up */ + iServiceIndex = -1; + bRetval = pm_process(n2, do_section, do_parameter); - lp_add_auto_services(lp_auto_services()); - if (lp_load_printers()) - lp_add_all_printers(); + /* finish up the last section */ + DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval))); + if (bRetval) + if (iServiceIndex >= 0) + bRetval = service_ok(iServiceIndex); - lp_add_ipc(); + lp_add_auto_services(lp_auto_services()); + + if (add_ipc) { + lp_add_ipc("IPC$", True); + lp_add_ipc("ADMIN$", False); + } + + set_server_role(); + set_default_server_announce_type(); + + bLoaded = True; + + /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */ + /* if bWINSsupport is true and we are in the client */ + if (in_client && Globals.bWINSsupport) { + string_set(&Globals.szWINSserver, "127.0.0.1"); + } - bLoaded = True; + init_iconv(); - return (bRetval); + return (bRetval); } /*************************************************************************** +reset the max number of services +***************************************************************************/ +void lp_resetnumservices(void) +{ + iNumServices = 0; +} + +/*************************************************************************** return the max number of services ***************************************************************************/ int lp_numservices(void) { - return(iNumServices); + return (iNumServices); } /*************************************************************************** Display the contents of the services array in human-readable form. ***************************************************************************/ -void lp_dump(void) +void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint) { - int iService; + int iService; - dump_globals(); - - dump_a_service(&sDefault); - - for (iService = 0; iService < iNumServices; iService++) - { - if (VALID(iService)) - { - if (iSERVICE(iService).szService[0] == '\0') - break; - dump_a_service(pSERVICE(iService)); - } - } + if (show_defaults) + { + defaults_saved = False; + } + + dump_globals(f); + + dump_a_service(&sDefault, f); + + for (iService = 0; iService < maxtoprint; iService++) + lp_dump_one(f, show_defaults, iService); +} + +/*************************************************************************** +Display the contents of one service in human-readable form. +***************************************************************************/ +void lp_dump_one(FILE * f, BOOL show_defaults, int snum) +{ + if (VALID(snum)) + { + if (ServicePtrs[snum]->szService[0] == '\0') + return; + dump_a_service(ServicePtrs[snum], f); + } } + /*************************************************************************** Return the number of the service with the given name, or -1 if it doesn't exist. Note that this is a DIFFERENT ANIMAL from the internal function getservicebyname()! This works ONLY if all services have been loaded, and does not copy the found service. ***************************************************************************/ -int lp_servicenumber(char *pszServiceName) +int lp_servicenumber(const char *pszServiceName) { - int iService; + int iService; + fstring serviceName; + + + for (iService = iNumServices - 1; iService >= 0; iService--) + { + if (VALID(iService) && ServicePtrs[iService]->szService) + { + /* + * The substitution here is used to support %U is + * service names + */ + fstrcpy(serviceName, ServicePtrs[iService]->szService); + standard_sub_basic(current_user_info.smb_name, serviceName); + if (strequal(serviceName, pszServiceName)) + break; + } + } - for (iService = iNumServices - 1; iService >= 0; iService--) - if (VALID(iService) && - strwicmp(iSERVICE(iService).szService, pszServiceName) == 0) - break; + if (iService < 0) + DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName)); - if (iService < 0) - DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName)); - - return (iService); + return (iService); +} + +/******************************************************************* + A useful volume label function. Returns a string in DOS codepage. +********************************************************************/ + +char *volume_label(int snum) +{ + char *ret = lp_volume(snum); + if (!*ret) + return lp_servicename(snum); + return (ret); +} + + +/******************************************************************* + Set the server type we will announce as via nmbd. +********************************************************************/ +static void set_default_server_announce_type(void) +{ + default_server_announce = 0; + default_server_announce |= SV_TYPE_WORKSTATION; + default_server_announce |= SV_TYPE_SERVER; + default_server_announce |= SV_TYPE_SERVER_UNIX; + default_server_announce |= SV_TYPE_PRINTQ_SERVER; + + switch (lp_announce_as()) + { + case ANNOUNCE_AS_NT_SERVER: + { + default_server_announce |= SV_TYPE_SERVER_NT; + /* fall through... */ + } + case ANNOUNCE_AS_NT_WORKSTATION: + { + default_server_announce |= SV_TYPE_NT; + break; + } + case ANNOUNCE_AS_WIN95: + { + default_server_announce |= SV_TYPE_WIN95_PLUS; + break; + } + case ANNOUNCE_AS_WFW: + { + default_server_announce |= SV_TYPE_WFW; + break; + } + default: + { + break; + } + } + + switch (lp_server_role()) + { + case ROLE_DOMAIN_MEMBER: + { + default_server_announce |= SV_TYPE_DOMAIN_MEMBER; + break; + } + case ROLE_DOMAIN_PDC: + { + default_server_announce |= SV_TYPE_DOMAIN_CTRL; + break; + } + case ROLE_DOMAIN_BDC: + { + default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL; + break; + } + case ROLE_STANDALONE: + default: + { + break; + } + } + + if (lp_time_server()) + { + default_server_announce |= SV_TYPE_TIME_SOURCE; + } + + if (lp_host_msdfs()) + { + default_server_announce |= SV_TYPE_DFS_SERVER; + } +} + +/*********************************************************** + returns role of Samba server +************************************************************/ + +int lp_server_role(void) +{ + return server_role; } +/*********************************************************** + If we are PDC then prefer us as DMB +************************************************************/ + +BOOL lp_domain_master(void) +{ + if (Globals.bDomainMaster == Auto) + { + return (lp_server_role() == ROLE_DOMAIN_PDC); + } + + return Globals.bDomainMaster; +} + +/*********************************************************** + If we are DMB then prefer us as LMB +************************************************************/ + +BOOL lp_preferred_master(void) +{ + if (Globals.bPreferredMaster == Auto) + { + return (lp_local_master() && lp_domain_master()); + } + + return Globals.bPreferredMaster; +} /******************************************************************* - get a workgroup - but map to standalone if '*' - ******************************************************************/ -char *my_workgroup(void) +remove a service +********************************************************************/ +void lp_remove_service(int snum) { - char *res = lp_workgroup(); - if (*res == '*') return("STANDALONE"); - return(res); + ServicePtrs[snum]->valid = False; } /******************************************************************* - a useful volume label function - ******************************************************************/ -char *volume_label(int snum) +copy a service. +********************************************************************/ +void lp_copy_service(int snum, char *new_name) +{ + char *oldname = lp_servicename(snum); + do_section(new_name); + if (snum >= 0) + { + snum = lp_servicenumber(new_name); + if (snum >= 0) + lp_do_parameter(snum, "copy", oldname); + } +} + + +/******************************************************************* + Get the default server type we will announce as via nmbd. +********************************************************************/ +int lp_default_server_announce(void) +{ + return default_server_announce; +} + +/******************************************************************* + Split the announce version into major and minor numbers. +********************************************************************/ +int lp_major_announce_version(void) +{ + static BOOL got_major = False; + static int major_version = DEFAULT_MAJOR_VERSION; + char *vers; + char *p; + + if (got_major) + return major_version; + + got_major = True; + if ((vers = lp_announce_version()) == NULL) + return major_version; + + if ((p = strchr_m(vers, '.')) == 0) + return major_version; + + *p = '\0'; + major_version = atoi(vers); + return major_version; +} + +int lp_minor_announce_version(void) +{ + static BOOL got_minor = False; + static int minor_version = DEFAULT_MINOR_VERSION; + char *vers; + char *p; + + if (got_minor) + return minor_version; + + got_minor = True; + if ((vers = lp_announce_version()) == NULL) + return minor_version; + + if ((p = strchr_m(vers, '.')) == 0) + return minor_version; + + p++; + minor_version = atoi(p); + return minor_version; +} + +/*********************************************************** + Set the global name resolution order (used in smbclient). +************************************************************/ + +void lp_set_name_resolve_order(char *new_order) +{ + Globals.szNameResolveOrder = new_order; +} + +char *lp_printername(int snum) +{ + char *ret = _lp_printername(snum); + if (ret == NULL || (ret != NULL && *ret == '\0')) + ret = lp_servicename(snum); + + return ret; +} + + +/*********************************************************** + List Parameters manipulation functions +***********************************************************/ + +#define P_LIST_ABS 16 /* P_LIST Allocation Block Size */ + +char **lp_list_make(char *string) +{ + char **list, **rlist; + char *str, *s; + int num, lsize; + pstring tok; + + if (!string || !*string) return NULL; + s = strdup(string); + if (!s) { + DEBUG(0,("lp_list_make: Unable to allocate memory")); + return NULL; + } + + num = lsize = 0; + list = NULL; + + str = s; + while (next_token(&str, tok, LIST_SEP, sizeof(pstring))) + { + if (num == lsize) { + lsize += P_LIST_ABS; + rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1))); + if (!rlist) { + DEBUG(0,("lp_list_make: Unable to allocate memory")); + lp_list_free(&list); + SAFE_FREE(s); + return NULL; + } + else list = rlist; + memset (&list[num], 0, ((sizeof(char**)) * (P_LIST_ABS +1))); + } + + list[num] = strdup(tok); + if (!list[num]) { + DEBUG(0,("lp_list_make: Unable to allocate memory")); + lp_list_free(&list); + SAFE_FREE(s); + return NULL; + } + + num++; + } + + SAFE_FREE(s); + return list; +} + +BOOL lp_list_copy(char ***dest, char **src) +{ + char **list, **rlist; + int num, lsize; + + *dest = NULL; + if (!src) return False; + + num = lsize = 0; + list = NULL; + + while (src[num]) + { + if (num == lsize) { + lsize += P_LIST_ABS; + rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1))); + if (!rlist) { + DEBUG(0,("lp_list_copy: Unable to allocate memory")); + lp_list_free(&list); + return False; + } + else list = rlist; + memset (&list[num], 0, ((sizeof(char **)) * (P_LIST_ABS +1))); + } + + list[num] = strdup(src[num]); + if (!list[num]) { + DEBUG(0,("lp_list_copy: Unable to allocate memory")); + lp_list_free(&list); + return False; + } + + num++; + } + + *dest = list; + return True; +} + +/* return true if all the elemnts of the list matches exactly */ +BOOL lp_list_compare(char **list1, char **list2) +{ + int num; + + if (!list1 || !list2) return (list1 == list2); + + for (num = 0; list1[num]; num++) { + if (!list2[num]) return False; + if (!strcsequal(list1[num], list2[num])) return False; + } + if (list2[num]) return False; /* if list2 has more elements than list1 fail */ + + return True; +} + +void lp_list_free(char ***list) +{ + char **tlist; + + if (!list || !*list) return; + tlist = *list; + for(; *tlist; tlist++) SAFE_FREE(*tlist); + SAFE_FREE(*list); +} + +BOOL lp_list_substitute(char **list, const char *pattern, const char *insert) +{ + char *p, *s, *t; + ssize_t ls, lp, li, ld, i, d; + + if (!list) return False; + if (!pattern) return False; + if (!insert) return False; + + lp = (ssize_t)strlen(pattern); + li = (ssize_t)strlen(insert); + ld = li -lp; + + while (*list) + { + s = *list; + ls = (ssize_t)strlen(s); + + while ((p = strstr(s, pattern))) + { + t = *list; + d = p -t; + if (ld) + { + t = (char *) malloc(ls +ld +1); + if (!t) { + DEBUG(0,("lp_list_substitute: Unable to allocate memory")); + return False; + } + memcpy(t, *list, d); + memcpy(t +d +li, p +lp, ls -d -lp +1); + SAFE_FREE(*list); + *list = t; + ls += ld; + s = t +d +li; + } + + for (i = 0; i < li; i++) { + switch (insert[i]) { + case '`': + case '"': + case '\'': + case ';': + case '$': + case '%': + case '\r': + case '\n': + t[d +i] = '_'; + break; + default: + t[d +i] = insert[i]; + } + } + } + + list++; + } + + return True; +} + +/**************************************************************** + Compatibility fn. for 2.2.2 code..... +*****************************************************************/ + +void get_private_directory(pstring privdir) +{ + pstrcpy (privdir, lp_private_dir()); +} + + +/**************************************************************** + Is netbios alias or name +*****************************************************************/ + +BOOL is_netbios_alias_or_name(const char *name) +{ + char **netbios_aliases = lp_netbios_aliases(); + + if (StrCaseCmp(name, global_myname) == 0) { + return True; + } + + for (netbios_aliases = lp_netbios_aliases(); + netbios_aliases && *netbios_aliases; + netbios_aliases++) { + if (StrCaseCmp(name, *netbios_aliases) == 0) { + return True; + } + } + + return False; +} + +/*********************************************************** + Allow daemons such as winbindd to fix their logfile name. +************************************************************/ + +void lp_set_logfile(const char *name) +{ + extern pstring debugf; + string_set(&Globals.szLogFile, name); + pstrcpy(debugf, name); +} + +/******************************************************************* + Return the NetBIOS called name. +********************************************************************/ + +const char *get_called_name(void) { - char *ret = lp_volume(snum); - if (!*ret) return(lp_servicename(snum)); - return(ret); + extern fstring local_machine; + return (*local_machine) ? local_machine : global_myname; } diff --git a/source3/param/params.c b/source3/param/params.c index b9d61382a1..bc93a1fedf 100644 --- a/source3/param/params.c +++ b/source3/param/params.c @@ -1,335 +1,599 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Parameter loading utlities - Copyright (C) Karl Auer 1993,1994 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/************************************************************************** -PARAMS.C - -Copyright (C) 1990, 1991, 1992, 1993, 1994 Karl Auer - -This module provides for streamlines retrieval of information from a -Windows-like parameter files. There is a function which will search for -all sections in the file and call a specified function with each. There is -a similar function which will call a specified function for all parameters -in a section. The idea is that you pass the addresses of suitable functions -to a single function in this module which will then enumerate all sections, -and within each section all parameters, to your program. - -Parameter files contain text lines (newline delimited) which consist of -either a section name in square brackets or a parameter name, delimited -from the parameter value by an equals sign. Blank lines or lines where the -first non-whitespace character is a colon are ignored. All whitespace in -section names and parameter names is compressed to single spaces. Leading -and trailing whitespace on parameter names and parameter values is stripped. - -Only the first equals sign in a parameter line is significant - parameter -values may contain equals signs, square brackets and semicolons. Internal -whitespace is retained in parameter values. Parameter names may not start -with a square bracket, an equals sign or a semicolon, for obvious reasons. - -A sample parameter file might look like this: - -[things] -this=1 -that=2 -[other things] -the other = 3 - -**************************************************************************/ +/* -------------------------------------------------------------------------- ** + * Microsoft Network Services for Unix, AKA., Andrew Tridgell's SAMBA. + * + * This module Copyright (C) 1990-1998 Karl Auer + * + * Rewritten almost completely by Christopher R. Hertel + * at the University of Minnesota, September, 1997. + * This module Copyright (C) 1997-1998 by the University of Minnesota + * -------------------------------------------------------------------------- ** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * -------------------------------------------------------------------------- ** + * + * Module name: params + * + * -------------------------------------------------------------------------- ** + * + * This module performs lexical analysis and initial parsing of a + * Windows-like parameter file. It recognizes and handles four token + * types: section-name, parameter-name, parameter-value, and + * end-of-file. Comments and line continuation are handled + * internally. + * + * The entry point to the module is function pm_process(). This + * function opens the source file, calls the Parse() function to parse + * the input, and then closes the file when either the EOF is reached + * or a fatal error is encountered. + * + * A sample parameter file might look like this: + * + * [section one] + * parameter one = value string + * parameter two = another value + * [section two] + * new parameter = some value or t'other + * + * The parameter file is divided into sections by section headers: + * section names enclosed in square brackets (eg. [section one]). + * Each section contains parameter lines, each of which consist of a + * parameter name and value delimited by an equal sign. Roughly, the + * syntax is: + * + * <file> :== { <section> } EOF + * + * <section> :== <section header> { <parameter line> } + * + * <section header> :== '[' NAME ']' + * + * <parameter line> :== NAME '=' VALUE '\n' + * + * Blank lines and comment lines are ignored. Comment lines are lines + * beginning with either a semicolon (';') or a pound sign ('#'). + * + * All whitespace in section names and parameter names is compressed + * to single spaces. Leading and trailing whitespace is stipped from + * both names and values. + * + * Only the first equals sign in a parameter line is significant. + * Parameter values may contain equals signs, square brackets and + * semicolons. Internal whitespace is retained in parameter values, + * with the exception of the '\r' character, which is stripped for + * historic reasons. Parameter names may not start with a left square + * bracket, an equal sign, a pound sign, or a semicolon, because these + * are used to identify other tokens. + * + * -------------------------------------------------------------------------- ** + */ #include "includes.h" -#include "smb.h" -#include "params.h" - -/* local variable pointing to passed filename */ -static char *pszParmFile = NULL; -extern int DEBUGLEVEL; - -/* local prototypes */ -static BOOL enumerate_parameters(FILE *infile, PM_PARMFUNC pfunc); -static BOOL enumerate_sections(FILE *infile, - PM_SECFUNC sfunc, PM_PARMFUNC pfunc); - -/* prototypes for local toolbox functions */ -static void trimleft(char *psz); -static void trimright(char *psz); -static void collapse_spaces(char *psz); -static int firstnonwhite(char *psz); - -/************************************************************************** -Identifies all parameters in the current section, calls the parameter -function for each. Ignores comment lines, stops and backs up in file when -a section is encountered. Returns True on success, False on error. -**************************************************************************/ -static BOOL enumerate_parameters(FILE *fileIn, PM_PARMFUNC pfunc) +/* -------------------------------------------------------------------------- ** + * Constants... + */ + +#define BUFR_INC 1024 + + +/* -------------------------------------------------------------------------- ** + * Variables... + * + * DEBUGLEVEL - The ubiquitous DEBUGLEVEL. This determines which DEBUG() + * messages will be produced. + * bufr - pointer to a global buffer. This is probably a kludge, + * but it was the nicest kludge I could think of (for now). + * bSize - The size of the global buffer <bufr>. + */ + +static char *bufr = NULL; +static int bSize = 0; + +/* we can't use FILE* due to the 256 fd limit - use this cheap hack + instead */ +typedef struct { + char *buf; + char *p; + size_t size; +} myFILE; + +static int mygetc(myFILE *f) { - pstring szBuf; - char *pszTemp; - BOOL bRetval; - long lFileOffset; - int cTemp; - BOOL bParmFound; - - bRetval = False; - bParmFound = False; - while (True) - { - /* first remember where we are */ - if ((lFileOffset = ftell(fileIn)) >= 0L) - { - /* then get and check a line */ - if (fgets_slash(szBuf, sizeof(szBuf)-1, fileIn) == NULL) - { - /* stop - return OK unless file error */ - bRetval = !ferror(fileIn); - if (!bRetval) - DEBUG(0,( "Read error on configuration file (enumerating parameters)!\n")); - break; - } - else - /* if first non-white is a '[', stop (new section) */ - if ((cTemp = firstnonwhite(szBuf)) == '[') - { - /* restore position to start of new section */ - if (fseek(fileIn, lFileOffset, SEEK_SET) < 0L) - { - DEBUG(0,( "Seek error on configuration file!\n")); - break; - } - - /* return success */ - bRetval = True; - break; - } - else - /* if it's a semicolon or line is blank, ignore the line */ - if (!cTemp || strchr(";#",cTemp)) - { - continue; - } - else - /* if no equals sign and line contains non-whitespace */ - /* then line is badly formed */ - if ((pszTemp = strchr(szBuf, '=')) == NULL) - { - DEBUG(0,( "Ignoring badly formed line: %s", szBuf)); - } - else - { - /* Note that we have found a parameter */ - bParmFound = True; - /* cut line at the equals sign */ - *pszTemp++ = '\0'; - /* trim leading and trailing space from both halves */ - trimright(szBuf); - trimleft(szBuf); - trimright(pszTemp); - trimleft(pszTemp); - /* process the parameter iff passed pointer not NULL */ - if (pfunc != NULL) - if (!pfunc(szBuf, pszTemp)) - break; - } - } - } - return (bRetval); + if (f->p >= f->buf+f->size) return EOF; + /* be sure to return chars >127 as positive values */ + return (int)( *(f->p++) & 0x00FF ); } +static void myfile_close(myFILE *f) +{ + if (!f) return; + SAFE_FREE(f->buf); + SAFE_FREE(f); +} -/*********************************************************************** -Close up s by n chars, at offset start. -***********************************************************************/ -static void closestr(char *s, int start, int n) +/* -------------------------------------------------------------------------- ** + * Functions... + */ + +static int EatWhitespace( myFILE *InFile ) + /* ------------------------------------------------------------------------ ** + * Scan past whitespace (see ctype(3C)) and return the first non-whitespace + * character, or newline, or EOF. + * + * Input: InFile - Input source. + * + * Output: The next non-whitespace character in the input stream. + * + * Notes: Because the config files use a line-oriented grammar, we + * explicitly exclude the newline character from the list of + * whitespace characters. + * - Note that both EOF (-1) and the nul character ('\0') are + * considered end-of-file markers. + * + * ------------------------------------------------------------------------ ** + */ + { + int c; + + for( c = mygetc( InFile ); isspace( c ) && ('\n' != c); c = mygetc( InFile ) ) + ; + return( c ); + } /* EatWhitespace */ + +static int EatComment( myFILE *InFile ) + /* ------------------------------------------------------------------------ ** + * Scan to the end of a comment. + * + * Input: InFile - Input source. + * + * Output: The character that marks the end of the comment. Normally, + * this will be a newline, but it *might* be an EOF. + * + * Notes: Because the config files use a line-oriented grammar, we + * explicitly exclude the newline character from the list of + * whitespace characters. + * - Note that both EOF (-1) and the nul character ('\0') are + * considered end-of-file markers. + * + * ------------------------------------------------------------------------ ** + */ + { + int c; + + for( c = mygetc( InFile ); ('\n'!=c) && (EOF!=c) && (c>0); c = mygetc( InFile ) ) + ; + return( c ); + } /* EatComment */ + +/***************************************************************************** + * Scan backards within a string to discover if the last non-whitespace + * character is a line-continuation character ('\\'). + * + * Input: line - A pointer to a buffer containing the string to be + * scanned. + * pos - This is taken to be the offset of the end of the + * string. This position is *not* scanned. + * + * Output: The offset of the '\\' character if it was found, or -1 to + * indicate that it was not. + * + *****************************************************************************/ + +static int Continuation(char *line, int pos ) { - char *src; - char *dest; - int len; + pos--; + while( (pos >= 0) && isspace((int)line[pos])) + pos--; - if (n > 0) - if ((src = dest = s) != NULL) + return (((pos >= 0) && ('\\' == line[pos])) ? pos : -1 ); +} + + +static BOOL Section( myFILE *InFile, BOOL (*sfunc)(char *) ) + /* ------------------------------------------------------------------------ ** + * Scan a section name, and pass the name to function sfunc(). + * + * Input: InFile - Input source. + * sfunc - Pointer to the function to be called if the section + * name is successfully read. + * + * Output: True if the section name was read and True was returned from + * <sfunc>. False if <sfunc> failed or if a lexical error was + * encountered. + * + * ------------------------------------------------------------------------ ** + */ + { + int c; + int i; + int end; + char *func = "params.c:Section() -"; + + i = 0; /* <i> is the offset of the next free byte in bufr[] and */ + end = 0; /* <end> is the current "end of string" offset. In most */ + /* cases these will be the same, but if the last */ + /* character written to bufr[] is a space, then <end> */ + /* will be one less than <i>. */ + + c = EatWhitespace( InFile ); /* We've already got the '['. Scan */ + /* past initial white space. */ + + while( (EOF != c) && (c > 0) ) + { + + /* Check that the buffer is big enough for the next character. */ + if( i > (bSize - 2) ) { - len = strlen(s); - if (start >= 0 && start < len - n) - { - src += start + n; - dest += start; - - while (*src) - *dest++ = *src++; - *dest = '\0'; - } + char *tb; + + tb = Realloc( bufr, bSize +BUFR_INC ); + if( NULL == tb ) + { + DEBUG(0, ("%s Memory re-allocation failure.", func) ); + return( False ); + } + bufr = tb; + bSize += BUFR_INC; } -} -/************************************************************************** -Identifies all sections in the parameter file, calls passed section_func() -for each, passing the section name, then calls enumerate_parameters(). -Returns True on success, False on failure. Note that the section and -parameter names will have all internal whitespace areas collapsed to a -single space for processing. -**************************************************************************/ -static BOOL enumerate_sections(FILE *fileIn, - PM_SECFUNC sfunc, PM_PARMFUNC pfunc) -{ - pstring szBuf; - BOOL bRetval; - BOOL bSectionFound; - - /* this makes sure we get include lines right */ - enumerate_parameters(fileIn, pfunc); - - bRetval = False; - bSectionFound = False; - while (True) - { - if (fgets_slash(szBuf, sizeof(szBuf)-1, fileIn) == NULL) + /* Handle a single character. */ + switch( c ) { - /* stop - return OK unless file error */ - bRetval = !ferror(fileIn); - if (!bRetval) - DEBUG(0,( "Read error on configuration file (enumerating sections)!\n")); - break; + case ']': /* Found the closing bracket. */ + bufr[end] = '\0'; + if( 0 == end ) /* Don't allow an empty name. */ + { + DEBUG(0, ("%s Empty section name in configuration file.\n", func )); + return( False ); + } + if( !sfunc(bufr) ) /* Got a valid name. Deal with it. */ + return( False ); + (void)EatComment( InFile ); /* Finish off the line. */ + return( True ); + + case '\n': /* Got newline before closing ']'. */ + i = Continuation( bufr, i ); /* Check for line continuation. */ + if( i < 0 ) + { + bufr[end] = '\0'; + DEBUG(0, ("%s Badly formed line in configuration file: %s\n", + func, bufr )); + return( False ); + } + end = ( (i > 0) && (' ' == bufr[i - 1]) ) ? (i - 1) : (i); + c = mygetc( InFile ); /* Continue with next line. */ + break; + + default: /* All else are a valid name chars. */ + if( isspace( c ) ) /* One space per whitespace region. */ + { + bufr[end] = ' '; + i = end + 1; + c = EatWhitespace( InFile ); + } + else /* All others copy verbatim. */ + { + bufr[i++] = c; + end = i; + c = mygetc( InFile ); + } } - else + } + + /* We arrive here if we've met the EOF before the closing bracket. */ + DEBUG(0, ("%s Unexpected EOF in the configuration file: %s\n", func, bufr )); + return( False ); + } /* Section */ + +static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(char *, char *), int c ) + /* ------------------------------------------------------------------------ ** + * Scan a parameter name and value, and pass these two fields to pfunc(). + * + * Input: InFile - The input source. + * pfunc - A pointer to the function that will be called to + * process the parameter, once it has been scanned. + * c - The first character of the parameter name, which + * would have been read by Parse(). Unlike a comment + * line or a section header, there is no lead-in + * character that can be discarded. + * + * Output: True if the parameter name and value were scanned and processed + * successfully, else False. + * + * Notes: This function is in two parts. The first loop scans the + * parameter name. Internal whitespace is compressed, and an + * equal sign (=) terminates the token. Leading and trailing + * whitespace is discarded. The second loop scans the parameter + * value. When both have been successfully identified, they are + * passed to pfunc() for processing. + * + * ------------------------------------------------------------------------ ** + */ + { + int i = 0; /* Position within bufr. */ + int end = 0; /* bufr[end] is current end-of-string. */ + int vstart = 0; /* Starting position of the parameter value. */ + char *func = "params.c:Parameter() -"; + + /* Read the parameter name. */ + while( 0 == vstart ) /* Loop until we've found the start of the value. */ + { + + if( i > (bSize - 2) ) /* Ensure there's space for next char. */ { - trimleft(szBuf); - trimright(szBuf); - if (szBuf[0] == '[') - { - closestr(szBuf, 0, 1); - if (strlen(szBuf) > 1) - if (szBuf[strlen(szBuf) - 1] == ']') - { - /* found a section - note the fact */ - bSectionFound = True; - /* remove trailing metabracket */ - szBuf[strlen(szBuf) - 1] = '\0'; - /* remove leading and trailing whitespace from name */ - trimleft(szBuf); - trimright(szBuf); - /* reduce all internal whitespace to one space */ - collapse_spaces(szBuf); - /* process it - stop if the processing fails */ - if (sfunc != NULL) - if (!sfunc(szBuf)) - break; - if (!enumerate_parameters(fileIn, pfunc)) - break; - } - } + char *tb; + + tb = Realloc( bufr, bSize + BUFR_INC ); + if( NULL == tb ) + { + DEBUG(0, ("%s Memory re-allocation failure.", func) ); + return( False ); + } + bufr = tb; + bSize += BUFR_INC; } - } - - return (bRetval); -} - -/************************************************************************** -Process the passed parameter file. - -Returns True if successful, else False. -**************************************************************************/ -BOOL pm_process(char *pszFileName, PM_SECFUNC sfunc, PM_PARMFUNC pfunc) -{ - FILE *fileIn; - BOOL bRetval; - bRetval = False; + switch( c ) + { + case '=': /* Equal sign marks end of param name. */ + if( 0 == end ) /* Don't allow an empty name. */ + { + DEBUG(0, ("%s Invalid parameter name in config. file.\n", func )); + return( False ); + } + bufr[end++] = '\0'; /* Mark end of string & advance. */ + i = end; /* New string starts here. */ + vstart = end; /* New string is parameter value. */ + bufr[i] = '\0'; /* New string is nul, for now. */ + break; + + case '\n': /* Find continuation char, else error. */ + i = Continuation( bufr, i ); + if( i < 0 ) + { + bufr[end] = '\0'; + DEBUG(1,("%s Ignoring badly formed line in configuration file: %s\n", + func, bufr )); + return( True ); + } + end = ( (i > 0) && (' ' == bufr[i - 1]) ) ? (i - 1) : (i); + c = mygetc( InFile ); /* Read past eoln. */ + break; + + case '\0': /* Shouldn't have EOF within param name. */ + case EOF: + bufr[i] = '\0'; + DEBUG(1,("%s Unexpected end-of-file at: %s\n", func, bufr )); + return( True ); + + default: + if( isspace( c ) ) /* One ' ' per whitespace region. */ + { + bufr[end] = ' '; + i = end + 1; + c = EatWhitespace( InFile ); + } + else /* All others verbatim. */ + { + bufr[i++] = c; + end = i; + c = mygetc( InFile ); + } + } + } - /* record the filename for use in error messages one day... */ - pszParmFile = pszFileName; + /* Now parse the value. */ + c = EatWhitespace( InFile ); /* Again, trim leading whitespace. */ + while( (EOF !=c) && (c > 0) ) + { - if (pszParmFile == NULL || strlen(pszParmFile) < 1) - DEBUG(0,( "No configuration filename specified!\n")); - else - if ((fileIn = fopen(pszParmFile, "r")) == NULL) - DEBUG(0,( "Unable to open configuration file \"%s\"!\n", pszParmFile)); - else + if( i > (bSize - 2) ) /* Make sure there's enough room. */ { - DEBUG(2,( "Processing configuration file \"%s\"\n", pszParmFile)); - bRetval = enumerate_sections(fileIn, sfunc, pfunc); - fclose(fileIn); + char *tb; + + tb = Realloc( bufr, bSize + BUFR_INC ); + if( NULL == tb ) + { + DEBUG(0, ("%s Memory re-allocation failure.", func) ); + return( False ); + } + bufr = tb; + bSize += BUFR_INC; } - if (!bRetval) - DEBUG(0,("pm_process retuned false\n")); - return (bRetval); -} - + switch( c ) + { + case '\r': /* Explicitly remove '\r' because the older */ + c = mygetc( InFile ); /* version called fgets_slash() which also */ + break; /* removes them. */ + + case '\n': /* Marks end of value unless there's a '\'. */ + i = Continuation( bufr, i ); + if( i < 0 ) + c = 0; + else + { + for( end = i; (end >= 0) && isspace((int)bufr[end]); end-- ) + ; + c = mygetc( InFile ); + } + break; + + default: /* All others verbatim. Note that spaces do */ + bufr[i++] = c; /* not advance <end>. This allows trimming */ + if( !isspace( c ) ) /* of whitespace at the end of the line. */ + end = i; + c = mygetc( InFile ); + break; + } + } + bufr[end] = '\0'; /* End of value. */ + + return( pfunc( bufr, &bufr[vstart] ) ); /* Pass name & value to pfunc(). */ + } /* Parameter */ + +static BOOL Parse( myFILE *InFile, + BOOL (*sfunc)(char *), + BOOL (*pfunc)(char *, char *) ) + /* ------------------------------------------------------------------------ ** + * Scan & parse the input. + * + * Input: InFile - Input source. + * sfunc - Function to be called when a section name is scanned. + * See Section(). + * pfunc - Function to be called when a parameter is scanned. + * See Parameter(). + * + * Output: True if the file was successfully scanned, else False. + * + * Notes: The input can be viewed in terms of 'lines'. There are four + * types of lines: + * Blank - May contain whitespace, otherwise empty. + * Comment - First non-whitespace character is a ';' or '#'. + * The remainder of the line is ignored. + * Section - First non-whitespace character is a '['. + * Parameter - The default case. + * + * ------------------------------------------------------------------------ ** + */ + { + int c; + + c = EatWhitespace( InFile ); + while( (EOF != c) && (c > 0) ) + { + switch( c ) + { + case '\n': /* Blank line. */ + c = EatWhitespace( InFile ); + break; + + case ';': /* Comment line. */ + case '#': + c = EatComment( InFile ); + break; + + case '[': /* Section Header. */ + if( !Section( InFile, sfunc ) ) + return( False ); + c = EatWhitespace( InFile ); + break; + + case '\\': /* Bogus backslash. */ + c = EatWhitespace( InFile ); + break; + + default: /* Parameter line. */ + if( !Parameter( InFile, pfunc, c ) ) + return( False ); + c = EatWhitespace( InFile ); + break; + } + } + return( True ); + } /* Parse */ + +static myFILE *OpenConfFile( char *FileName ) + /* ------------------------------------------------------------------------ ** + * Open a configuration file. + * + * Input: FileName - The pathname of the config file to be opened. + * + * Output: A pointer of type (char **) to the lines of the file + * + * ------------------------------------------------------------------------ ** + */ + { + char *func = "params.c:OpenConfFile() -"; + extern BOOL in_client; + int lvl = in_client?1:0; + myFILE *ret; + + ret = (myFILE *)malloc(sizeof(*ret)); + if (!ret) return NULL; + + ret->buf = file_load(FileName, &ret->size); + if( NULL == ret->buf ) + { + DEBUG( lvl, + ("%s Unable to open configuration file \"%s\":\n\t%s\n", + func, FileName, strerror(errno)) ); + SAFE_FREE(ret); + return NULL; + } + + ret->p = ret->buf; + return( ret ); + } /* OpenConfFile */ + +BOOL pm_process( char *FileName, + BOOL (*sfunc)(char *), + BOOL (*pfunc)(char *, char *) ) + /* ------------------------------------------------------------------------ ** + * Process the named parameter file. + * + * Input: FileName - The pathname of the parameter file to be opened. + * sfunc - A pointer to a function that will be called when + * a section name is discovered. + * pfunc - A pointer to a function that will be called when + * a parameter name and value are discovered. + * + * Output: TRUE if the file was successfully parsed, else FALSE. + * + * ------------------------------------------------------------------------ ** + */ + { + int result; + myFILE *InFile; + char *func = "params.c:pm_process() -"; + + InFile = OpenConfFile( FileName ); /* Open the config file. */ + if( NULL == InFile ) + return( False ); + + DEBUG( 3, ("%s Processing configuration file \"%s\"\n", func, FileName) ); + + if( NULL != bufr ) /* If we already have a buffer */ + result = Parse( InFile, sfunc, pfunc ); /* (recursive call), then just */ + /* use it. */ + + else /* If we don't have a buffer */ + { /* allocate one, then parse, */ + bSize = BUFR_INC; /* then free. */ + bufr = (char *)malloc( bSize ); + if( NULL == bufr ) + { + DEBUG(0,("%s memory allocation failure.\n", func)); + myfile_close(InFile); + return( False ); + } + result = Parse( InFile, sfunc, pfunc ); + SAFE_FREE( bufr ); + bufr = NULL; + bSize = 0; + } -/************************************************************************** -Strip all leading whitespace from a string. -**************************************************************************/ -static void trimleft(char *psz) -{ - char *pszDest; - - pszDest = psz; - if (psz != NULL) - { - while (*psz != '\0' && isspace(*psz)) - psz++; - while (*psz != '\0') - *pszDest++ = *psz++; - *pszDest = '\0'; - } -} + myfile_close(InFile); -/************************************************************************** -Strip all trailing whitespace from a string. -**************************************************************************/ -static void trimright(char *psz) -{ - char *pszTemp; - - if (psz != NULL && psz[0] != '\0') - { - pszTemp = psz + strlen(psz) - 1; - while (isspace(*pszTemp)) - *pszTemp-- = '\0'; - } -} + if( !result ) /* Generic failure. */ + { + DEBUG(0,("%s Failed. Error returned from params.c:parse().\n", func)); + return( False ); + } -/*********************************************************************** -Collapse each whitespace area in a string to a single space. -***********************************************************************/ -static void collapse_spaces(char *psz) -{ - while (*psz) - if (isspace(*psz)) - { - *psz++ = ' '; - trimleft(psz); - } - else - psz++; -} + return( True ); /* Generic success. */ + } /* pm_process */ -/************************************************************************** -Return the value of the first non-white character in the specified string. -The terminating NUL counts as non-white for the purposes of this function. -Note - no check for a NULL string! What would we return? -**************************************************************************/ -static int firstnonwhite(char *psz) -{ - while (isspace(*psz) && (*psz != '\0')) - psz++; - return (*psz); -} +/* -------------------------------------------------------------------------- */ |