BOOL in_client = False; /* Not in the client by default */
BOOL bLoaded = False;
-extern userdom_struct current_user_info;
extern pstring user_socket_options;
extern enum protocol_types Protocol;
+extern userdom_struct current_user_info;
#ifndef GLOBAL_NAME
#define GLOBAL_NAME "global"
#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
-int keepalive = DEFAULT_KEEPALIVE;
+#define USERSHARE_VALID 1
+#define USERSHARE_PENDING_DELETE 2
+
BOOL use_getwd_cache = True;
extern int extra_time_offset;
/*
* This structure describes global (ie., server-wide) parameters.
*/
-typedef struct
-{
+typedef struct {
char *smb_ports;
char *dos_charset;
char *unix_charset;
char *display_charset;
char *szPrintcapname;
+ char *szAddPortCommand;
char *szEnumPortsCommand;
char *szAddPrinterCommand;
char *szDeletePrinterCommand;
char *szGetQuota;
char *szSetQuota;
char *szMsgCommand;
- char *szHostsEquiv;
char *szServerString;
char *szAutoServices;
char *szPasswdProgram;
char *szConfigFile;
char *szSMBPasswdFile;
char *szPrivateDir;
- char **szPassdbBackend;
+ char *szPassdbBackend;
char **szPreloadModules;
char *szPasswordServer;
char *szSocketOptions;
char *szUsernameMapScript;
char *szCheckPasswordScript;
char *szWINSHook;
- char *szWINSPartners;
char *szUtmpDir;
char *szWtmpDir;
BOOL bUtmp;
char *szIdmapUID;
char *szIdmapGID;
- BOOL bEnableRidAlgorithm;
+ BOOL bPassdbExpandExplicit;
int AlgorithmicRidBase;
char *szTemplateHomedir;
char *szTemplateShell;
BOOL bWinbindUseDefaultDomain;
BOOL bWinbindTrustedDomainsOnly;
BOOL bWinbindNestedGroups;
- char **szIdmapBackend;
+ BOOL bWinbindRefreshTickets;
+ BOOL bWinbindOfflineLogon;
+ BOOL bWinbindNormalizeNames;
+ BOOL bWinbindRpcOnly;
+ char **szIdmapDomains;
+ char **szIdmapBackend; /* deprecated */
+ char *szIdmapAllocBackend;
char *szAddShareCommand;
char *szChangeShareCommand;
char *szDeleteShareCommand;
char *szGuestaccount;
char *szManglingMethod;
char **szServicesList;
+ char *szUsersharePath;
+ char *szUsershareTemplateShare;
+ char **szUsersharePrefixAllowList;
+ char **szUsersharePrefixDenyList;
int mangle_prefix;
int max_log_size;
char *szLogLevel;
int max_xmit;
int max_mux;
int max_open_files;
+ int open_files_db_hash_size;
int pwordlevel;
int unamelevel;
int deadtime;
int lm_interval;
int announce_as; /* This is initialised in init_globals */
int machine_password_timeout;
- int change_notify_timeout;
int map_to_guest;
int oplock_break_wait_time;
int winbind_cache_time;
int winbind_max_idle_children;
char **szWinbindNssInfo;
- int iLockSpinCount;
int iLockSpinTime;
char *szLdapMachineSuffix;
char *szLdapUserSuffix;
char *szLdapIdmapSuffix;
char *szLdapGroupSuffix;
-#ifdef WITH_LDAP_SAMCONFIG
- int ldap_port;
- char *szLdapServer;
-#endif
int ldap_ssl;
char *szLdapSuffix;
char *szLdapAdminDn;
- char *szAclCompat;
+ int iAclCompat;
char *szCupsServer;
char *szIPrintServer;
int ldap_passwd_sync;
BOOL bClientNTLMv2Auth;
BOOL bClientPlaintextAuth;
BOOL bClientUseSpnego;
+ BOOL bDebugPrefixTimestamp;
BOOL bDebugHiresTimestamp;
BOOL bDebugPid;
BOOL bDebugUid;
+ BOOL bEnableCoreFiles;
BOOL bHostMSDfs;
BOOL bUseMmap;
BOOL bHostnameLookups;
BOOL bUnixExtensions;
BOOL bDisableNetbios;
- BOOL bKernelChangeNotify;
BOOL bUseKerberosKeytab;
BOOL bDeferSharingViolations;
BOOL bEnablePrivileges;
BOOL bASUSupport;
+ BOOL bUsershareOwnerOnly;
+ BOOL bUsershareAllowGuests;
+ BOOL bRegistryShares;
int restrict_anonymous;
int name_cache_timeout;
int client_signing;
int server_signing;
+ int iUsershareMaxShares;
+ int iIdmapCacheTime;
+ int iIdmapNegativeCacheTime;
+
BOOL bResetOnZeroVC;
+ int iKeepalive;
param_opt_struct *param_opt;
-}
-global;
+} global;
static global Globals;
/*
* This structure describes a single service.
*/
-typedef struct
-{
+typedef struct {
BOOL valid;
BOOL autoloaded;
+ int usershare;
+ time_t usershare_last_mod;
char *szService;
char *szPath;
char *szUsername;
char *szQueuepausecommand;
char *szQueueresumecommand;
char *szPrintername;
+ char *szPrintjobUsername;
char *szDontdescend;
char **szHostsallow;
char **szHostsdeny;
char *fstype;
char **szVfsObjects;
char *szMSDfsProxy;
- char *szAioWriteBehind;
char *szDfree;
int iMinPrintSpace;
int iMaxPrintJobs;
BOOL bMap_hidden;
BOOL bMap_archive;
BOOL bStoreDosAttributes;
+ BOOL bDmapiSupport;
BOOL bLocking;
int iStrictLocking;
BOOL bPosixLocking;
BOOL bAclCheckPermissions;
BOOL bAclMapFullControl;
BOOL bAclGroupControl;
+ BOOL bChangeNotify;
+ BOOL bKernelChangeNotify;
int iallocation_roundup_size;
int iAioReadSize;
int iAioWriteSize;
param_opt_struct *param_opt;
char dummy[3]; /* for alignment */
-}
-service;
+} service;
/* This is a default service used to prime a services structure */
static service sDefault = {
True, /* valid */
False, /* not autoloaded */
+ 0, /* not a usershare */
+ (time_t)0, /* No last mod time */
NULL, /* szService */
NULL, /* szPath */
NULL, /* szUsername */
NULL, /* szQueuepausecommand */
NULL, /* szQueueresumecommand */
NULL, /* szPrintername */
+ NULL, /* szPrintjobUsername */
NULL, /* szDontdescend */
NULL, /* szHostsallow */
NULL, /* szHostsdeny */
NULL, /* fstype */
NULL, /* vfs objects */
NULL, /* szMSDfsProxy */
- NULL, /* szAioWriteBehind */
NULL, /* szDfree */
0, /* iMinPrintSpace */
1000, /* iMaxPrintJobs */
False, /* bMap_hidden */
True, /* bMap_archive */
False, /* bStoreDosAttributes */
+ False, /* bDmapiSupport */
True, /* bLocking */
- True, /* iStrictLocking */
+ Auto, /* iStrictLocking */
True, /* bPosixLocking */
True, /* bShareModes */
True, /* bOpLocks */
False, /* bInheritOwner */
False, /* bMSDfsRoot */
False, /* bUseClientDriver */
- False, /* bDefaultDevmode */
+ True, /* bDefaultDevmode */
False, /* bForcePrintername */
True, /* bNTAclSupport */
False, /* bForceUnknownAclUser */
True, /* bAclCheckPermissions */
True, /* bAclMapFullControl */
False, /* bAclGroupControl */
+ True, /* bChangeNotify */
+ True, /* bKernelChangeNotify */
SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
0, /* iAioReadSize */
0, /* iAioWriteSize */
static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
-static BOOL handle_acl_compatibility( int snum, const char *pszParmValue, char **ptr);
static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
static void set_server_role(void);
};
static const struct enum_list enum_ldap_ssl[] = {
-#ifdef WITH_LDAP_SAMCONFIG
- {LDAP_SSL_ON, "Yes"},
- {LDAP_SSL_ON, "yes"},
- {LDAP_SSL_ON, "on"},
- {LDAP_SSL_ON, "On"},
-#endif
{LDAP_SSL_OFF, "no"},
{LDAP_SSL_OFF, "No"},
{LDAP_SSL_OFF, "off"},
{-1, NULL}
};
+/* ACL compatibility options. */
+static const struct enum_list enum_acl_compat_vals[] = {
+ { ACL_COMPAT_AUTO, "auto" },
+ { ACL_COMPAT_WINNT, "winnt" },
+ { ACL_COMPAT_WIN2K, "win2k" },
+ { -1, NULL}
+};
/*
Do you want session setups at user level security with a invalid
{"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
{"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
{"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
- {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED},
{"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
{"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
{"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
{"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
{"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
{"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
- {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
+ {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
{"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
{"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
{"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
{"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
{"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
{"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
{"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
{"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
{"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
{"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
{"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
+ {"debug prefix timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugPrefixTimestamp, NULL, NULL, FLAG_ADVANCED},
{"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
{"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
{"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
+ {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
{N_("Protocol Options"), P_SEP, P_SEPARATOR},
{"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
{"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED},
{"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED},
- {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
{"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
{"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
{"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
{"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
{"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED},
- {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"acl compatibility", P_ENUM, P_GLOBAL, &Globals.iAclCompat, NULL, enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
{"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{N_("Tuning Options"), P_SEP, P_SEPARATOR},
{"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_ADVANCED},
{"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
{"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
- {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED},
- {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED},
+ {"keepalive", P_INTEGER, P_GLOBAL, &Globals.iKeepalive, NULL, NULL, FLAG_ADVANCED},
+ {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
+ {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
{"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
{"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
{"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
{"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
{"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+ {"open files database hash size", P_INTEGER, P_GLOBAL, &Globals.open_files_db_hash_size, NULL, NULL, FLAG_ADVANCED},
{"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
{"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
{"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+ {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED},
{"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
{"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
{"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
{"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
{"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
{"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+ {"printjob username", P_STRING, P_LOCAL, &sDefault.szPrintjobUsername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
{N_("Filename Handling"), P_SEP, P_SEPARATOR},
{"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
{"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
{"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
{"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+
{N_("Domain Options"), P_SEP, P_SEPARATOR},
{"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
{"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
{"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
- {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
{N_("Locking Options"), P_SEP, P_SEPARATOR},
{"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
{"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
{"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
{"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{N_("Ldap Options"), P_SEP, P_SEPARATOR},
-#ifdef WITH_LDAP_SAMCONFIG
- {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, FLAG_ADVANCED},
- {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, FLAG_ADVANCED},
-#endif
{"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
{"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
{"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
{"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
{"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"registry shares", P_BOOL, P_GLOBAL, &Globals.bRegistryShares, NULL, NULL, FLAG_ADVANCED},
+ {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
+ {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
+ {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED},
+ {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
+ {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED},
+ {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED},
+ {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
{"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
{"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{N_("Winbind options"), P_SEP, P_SEPARATOR},
- {"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_DEPRECATED},
- {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED},
- {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED},
- {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE},
- {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED},
- {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE},
+ {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
+ {"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED},
+ {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED },
+ {"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED},
+ {"idmap cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapCacheTime, NULL, NULL, FLAG_ADVANCED},
+ {"idmap negative cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeCacheTime, NULL, NULL, FLAG_ADVANCED},
+ {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED },
+ {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE },
+ {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED },
+ {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE },
{"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
{"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
{"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
{"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
{"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
{"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
- {"winbind max idle children", P_INTEGER, P_GLOBAL, &Globals.winbind_max_idle_children, NULL, NULL, FLAG_ADVANCED},
{"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
+ {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
+ {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
+ {"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
+ {"winbind rpc only", P_BOOL, P_GLOBAL, &Globals.bWinbindRpcOnly, NULL, NULL, FLAG_ADVANCED},
{NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
Initialise the global parameter structure.
***************************************************************************/
-static void init_globals(void)
+static void init_globals(BOOL first_time_only)
{
static BOOL done_init = False;
pstring s;
+ /* If requested to initialize only once and we've already done it... */
+ if (first_time_only && done_init) {
+ /* ... then we have nothing more to do */
+ return;
+ }
+
if (!done_init) {
int i;
string_set((char **)parm_table[i].ptr, "");
string_set(&sDefault.fstype, FSTYPE_STRING);
+ string_set(&sDefault.szPrintjobUsername, "%U");
init_printer_values(&sDefault);
Globals.bLargeReadwrite = True;
Globals.max_log_size = 5000;
Globals.max_open_files = MAX_OPEN_FILES;
+ Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
Globals.maxprotocol = PROTOCOL_NT1;
Globals.minprotocol = PROTOCOL_CORE;
Globals.security = SEC_USER;
Globals.bSyslogOnly = False;
Globals.bTimestampLogs = True;
string_set(&Globals.szLogLevel, "0");
+ Globals.bDebugPrefixTimestamp = False;
Globals.bDebugHiresTimestamp = False;
Globals.bDebugPid = False;
Globals.bDebugUid = False;
+ Globals.bEnableCoreFiles = True;
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.bKernelChangeNotify = True; /* On if we have it. */
Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
Globals.lm_interval = 60;
Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
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.iMaxStatCacheSize = 0; /* unlimited size in kb by default. */
+ Globals.iMaxStatCacheSize = 1024; /* one Meg by default. */
Globals.restrict_anonymous = 0;
Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
Globals.map_to_guest = 0; /* By Default, "Never" */
Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
Globals.enhanced_browsing = True;
- Globals.iLockSpinCount = 3; /* Try 3 times. */
- Globals.iLockSpinTime = 10; /* usec. */
+ Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
#ifdef MMAP_BLACKLIST
Globals.bUseMmap = False;
#else
a large number of sites (tridge) */
Globals.bHostnameLookups = False;
- str_list_free(&Globals.szPassdbBackend);
-#ifdef WITH_LDAP_SAMCONFIG
- string_set(&Globals.szLdapServer, "localhost");
- Globals.ldap_port = 636;
- Globals.szPassdbBackend = str_list_make("ldapsam_compat", NULL);
-#else
- Globals.szPassdbBackend = str_list_make("smbpasswd", NULL);
-#endif /* WITH_LDAP_SAMCONFIG */
+ string_set(&Globals.szPassdbBackend, "smbpasswd");
string_set(&Globals.szLdapSuffix, "");
string_set(&Globals.szLdapMachineSuffix, "");
string_set(&Globals.szLdapUserSuffix, "");
string_set(&Globals.szTemplateShell, "/bin/false");
string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
string_set(&Globals.szWinbindSeparator, "\\");
- string_set(&Globals.szAclCompat, "");
+
string_set(&Globals.szCupsServer, "");
string_set(&Globals.szIPrintServer, "");
Globals.winbind_cache_time = 300; /* 5 minutes */
- Globals.bWinbindEnumUsers = True;
- Globals.bWinbindEnumGroups = True;
+ Globals.bWinbindEnumUsers = False;
+ Globals.bWinbindEnumGroups = False;
Globals.bWinbindUseDefaultDomain = False;
Globals.bWinbindTrustedDomainsOnly = False;
- Globals.bWinbindNestedGroups = False;
- Globals.winbind_max_idle_children = 3;
- Globals.szWinbindNssInfo = str_list_make("template", NULL);
+ Globals.bWinbindNestedGroups = True;
+ Globals.bWinbindRefreshTickets = False;
+ Globals.bWinbindOfflineLogon = False;
+
+ Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
+ Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
- Globals.bEnableRidAlgorithm = True;
+ Globals.bPassdbExpandExplicit = False;
Globals.name_cache_timeout = 660; /* In seconds */
Globals.bDeferSharingViolations = True;
string_set(&Globals.smb_ports, SMB_PORTS);
- /* don't enable privileges by default since Domain
- Admins can then assign thr rights to perform certain
- operations as root */
-
- Globals.bEnablePrivileges = False;
-
- Globals.bASUSupport = True;
+ Globals.bEnablePrivileges = True;
+ Globals.bHostMSDfs = True;
+ Globals.bASUSupport = False;
- Globals.szServicesList = str_list_make( "Spooler NETLOGON", NULL );
+ /* User defined shares. */
+ pstrcpy(s, dyn_LOCKDIR);
+ pstrcat(s, "/usershares");
+ string_set(&Globals.szUsersharePath, s);
+ string_set(&Globals.szUsershareTemplateShare, "");
+ Globals.iUsershareMaxShares = 0;
+ /* By default disallow sharing of directories not owned by the sharer. */
+ Globals.bUsershareOwnerOnly = True;
+ /* By default disallow guest access to usershares. */
+ Globals.bUsershareAllowGuests = False;
+
+ Globals.iKeepalive = DEFAULT_KEEPALIVE;
+
+ /* By default no shares out of the registry */
+ Globals.bRegistryShares = False;
}
static TALLOC_CTX *lp_talloc;
Free up temporary memory - called from the main loop.
********************************************************************/
-void lp_talloc_free(void)
+void lp_TALLOC_FREE(void)
{
if (!lp_talloc)
return;
- talloc_free(lp_talloc);
+ TALLOC_FREE(lp_talloc);
lp_talloc = NULL;
}
+TALLOC_CTX *tmp_talloc_ctx(void)
+{
+ if (lp_talloc == NULL) {
+ lp_talloc = talloc_init("tmp_talloc_ctx");
+ }
+
+ if (lp_talloc == NULL) {
+ smb_panic("Could not create temporary talloc context\n");
+ }
+
+ return lp_talloc;
+}
+
/*******************************************************************
Convenience routine to grab string parameters into temporary memory
and run standard_sub_basic on them. The buffers can be written to by
if (!lp_talloc)
lp_talloc = talloc_init("lp_talloc");
- tmpstr = alloc_sub_basic(get_current_username(), s);
+ tmpstr = alloc_sub_basic(get_current_username(),
+ current_user_info.domain, s);
if (trim_char(tmpstr, '\"', '\"')) {
if (strchr(tmpstr,'\"') != NULL) {
SAFE_FREE(tmpstr);
- tmpstr = alloc_sub_basic(get_current_username(),s);
+ tmpstr = alloc_sub_basic(get_current_username(),
+ current_user_info.domain, s);
}
}
ret = talloc_strdup(lp_talloc, tmpstr);
const char **fn_name(int i) {return(const char **)(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)? ServicePtrs[(i)]->val : sDefault.val);}
-#define FN_LOCAL_CHAR(fn_name,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)? ServicePtrs[(i)]->val : sDefault.val);}
+#define FN_LOCAL_PARM_BOOL(fn_name,val) \
+ BOOL fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
+#define FN_LOCAL_PARM_INTEGER(fn_name,val) \
+ int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
+#define FN_LOCAL_PARM_STRING(fn_name,val) \
+ char *fn_name(const struct share_params *p) {return(lp_string((LP_SNUM_OK(p->service) && ServicePtrs[(p->service)]->val) ? ServicePtrs[(p->service)]->val : sDefault.val));}
+#define FN_LOCAL_CHAR(fn_name,val) \
+ char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
+
FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
+FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
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_msg_command, &Globals.szMsgCommand)
FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
-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_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_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
+/* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
+ * lp_passdb_backend() should be replace by the this macro again after
+ * some releases.
+ * */
+const char *lp_passdb_backend(void)
+{
+ char *delim, *quote;
+
+ delim = strchr( Globals.szPassdbBackend, ' ');
+ /* no space at all */
+ if (delim == NULL) {
+ goto out;
+ }
+
+ quote = strchr(Globals.szPassdbBackend, '"');
+ /* no quote char or non in the first part */
+ if (quote == NULL || quote > delim) {
+ *delim = '\0';
+ goto warn;
+ }
+
+ quote = strchr(quote+1, '"');
+ if (quote == NULL) {
+ DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
+ goto out;
+ } else if (*(quote+1) == '\0') {
+ /* space, fitting quote char, and one backend only */
+ goto out;
+ } else {
+ /* terminate string after the fitting quote char */
+ *(quote+1) = '\0';
+ }
+
+warn:
+ DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
+ "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
+ "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
+ "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
+
+out:
+ return Globals.szPassdbBackend;
+}
FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
-FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
-FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat)
+FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
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)
FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
+FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
+FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
+FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
+FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
+
+FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
+FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
+FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
+FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
+FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
+FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
+FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
-
-FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend)
-FN_GLOBAL_BOOL(lp_enable_rid_algorithm, &Globals.bEnableRidAlgorithm)
-
-#ifdef WITH_LDAP_SAMCONFIG
-FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
-FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
-#endif
FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
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)
+FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
+FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
+FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
+FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
+FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
+FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
+FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
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_enable_core_files, &Globals.bEnableCoreFiles)
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_use_spnego, &Globals.bUseSpnego)
FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
-FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
+FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
+FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
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_open_files_db_hash_size, &Globals.open_files_db_hash_size)
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_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_map_to_guest, &Globals.map_to_guest)
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_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
+FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
+
FN_LOCAL_STRING(lp_preexec, szPreExec)
FN_LOCAL_STRING(lp_postexec, szPostExec)
FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
static FN_LOCAL_STRING(_lp_printername, szPrintername)
+FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
FN_LOCAL_STRING(lp_magicscript, szMagicScript)
FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
static FN_LOCAL_STRING(lp_volume, volume)
-FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
+FN_LOCAL_PARM_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_BOOL(lp_msdfs_root, bMSDfsRoot)
-FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
FN_LOCAL_STRING(lp_dfree_command, szDfree)
FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
-FN_LOCAL_BOOL(lp_locking, bLocking)
-FN_LOCAL_INTEGER(lp_strict_locking, iStrictLocking)
-FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
+FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
+FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
+FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
+FN_LOCAL_PARM_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_PARM_BOOL(lp_manglednames, bMangledNames)
FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
FN_LOCAL_CHAR(lp_magicchar, magic_char)
FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
-FN_GLOBAL_INTEGER(lp_winbind_max_idle_children, &Globals.winbind_max_idle_children)
FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
service * pserviceDest);
static void copy_service(service * pserviceDest,
service * pserviceSource, BOOL *pcopymapDest);
-static BOOL service_ok(int iService);
static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
static BOOL do_section(const char *pszSectionName);
static void init_copymap(service * pservice);
}
+#define MISSING_PARAMETER(name) \
+ DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
+
/*******************************************************************
convenience routine to return int parameters.
********************************************************************/
static int lp_int(const char *s)
{
- if (!s) {
- DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
+ if (!s || !*s) {
+ MISSING_PARAMETER(lp_int);
return (-1);
}
- return atoi(s);
+ return (int)strtol(s, NULL, 0);
}
/*******************************************************************
convenience routine to return unsigned long parameters.
********************************************************************/
-static int lp_ulong(const char *s)
+static unsigned long lp_ulong(const char *s)
{
- if (!s) {
- DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
- return (-1);
+ if (!s || !*s) {
+ MISSING_PARAMETER(lp_ulong);
+ return (0);
}
- return strtoul(s, NULL, 10);
+ return strtoul(s, NULL, 0);
}
/*******************************************************************
{
BOOL ret = False;
- if (!s) {
- DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
+ if (!s || !*s) {
+ MISSING_PARAMETER(lp_bool);
return False;
}
{
int i;
- if (!s || !_enum) {
- DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
+ if (!s || !*s || !_enum) {
+ MISSING_PARAMETER(lp_enum);
return (-1);
}
return (-1);
}
+#undef MISSING_PARAMETER
/* DO NOT USE lp_parm_string ANYMORE!!!!
* use lp_parm_const_string or lp_parm_talloc_string
* lp_parm_string is only used to let old modules find this symbol
*/
#undef lp_parm_string
+ char *lp_parm_string(const char *servicename, const char *type, const char *option);
char *lp_parm_string(const char *servicename, const char *type, const char *option)
{
return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
service **tsp;
int *tinvalid;
- tsp = SMB_REALLOC_ARRAY(ServicePtrs, service *, num_to_alloc);
+ tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
if (tsp == NULL) {
DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
return (-1);
iNumServices++;
/* enlarge invalid_services here for now... */
- tinvalid = SMB_REALLOC_ARRAY(invalid_services, int,
+ tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
num_to_alloc);
if (tinvalid == NULL) {
DEBUG(0,("add_a_service: failed to enlarge "
}
/***************************************************************************
- Convert a string to uppercase and remove whitespaces.
+ Canonicalize by converting to lowercase.
***************************************************************************/
static char *canonicalize_servicename(const char *src)
}
fstrcpy( canon, src );
- strupper_m( canon );
+ strlower_m( canon );
return canon;
}
string_set(&ServicePtrs[i]->comment, comment);
}
- /* set the browseable flag from the gloabl default */
+ /* set the browseable flag from the global default */
ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
int lp_add_service(const char *pszService, int iDefaultService)
{
+ if (iDefaultService < 0) {
+ return add_a_service(&sDefault, pszService);
+ }
+
return (add_a_service(ServicePtrs[iDefaultService], pszService));
}
incomplete or faulty, else True.
***************************************************************************/
-static BOOL service_ok(int iService)
+BOOL service_ok(int iService)
{
BOOL bRetval;
}
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());
+ strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
+ ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
+ ) {
+ DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
+ ServicePtrs[iService]->szService));
+ ServicePtrs[iService]->bAvailable = False;
}
- /* If a service is flagged unavailable, log the fact at level 0. */
+ /* If a service is flagged unavailable, log the fact at level 1. */
if (!ServicePtrs[iService]->bAvailable)
DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
ServicePtrs[iService]->szService));
time_t mod_time;
pstrcpy(n2, f->name);
- standard_sub_basic( get_current_username(), n2, sizeof(n2) );
+ standard_sub_basic( get_current_username(),
+ current_user_info.domain,
+ n2, sizeof(n2) );
DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
f->name, n2, ctime(&f->modtime)));
pstrcpy(netbios_name, pszParmValue);
- standard_sub_basic(get_current_username(), netbios_name,sizeof(netbios_name));
+ standard_sub_basic(get_current_username(), current_user_info.domain,
+ netbios_name, sizeof(netbios_name));
ret = set_global_myname(netbios_name);
string_set(&Globals.szNetbiosName,global_myname());
pstring fname;
pstrcpy(fname, pszParmValue);
- standard_sub_basic(get_current_username(), fname,sizeof(fname));
+ standard_sub_basic(get_current_username(), current_user_info.domain,
+ fname,sizeof(fname));
add_to_file_list(pszParmValue, fname);
{
uint32 low, high;
- if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
+ if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
return False;
/* Parse OK */
{
uint32 low, high;
- if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
+ if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
return False;
/* Parse OK */
Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
***************************************************************************/
-static char* append_ldap_suffix( const char *str )
+static const char *append_ldap_suffix( const char *str )
{
- char *suffix_string;
+ const char *suffix_string;
if (!lp_talloc)
suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
if ( !suffix_string ) {
DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
- return NULL;
+ return "";
}
return suffix_string;
}
-char *lp_ldap_machine_suffix(void)
+const char *lp_ldap_machine_suffix(void)
{
if (Globals.szLdapMachineSuffix[0])
return append_ldap_suffix(Globals.szLdapMachineSuffix);
return lp_string(Globals.szLdapSuffix);
}
-char *lp_ldap_user_suffix(void)
+const char *lp_ldap_user_suffix(void)
{
if (Globals.szLdapUserSuffix[0])
return append_ldap_suffix(Globals.szLdapUserSuffix);
return lp_string(Globals.szLdapSuffix);
}
-char *lp_ldap_group_suffix(void)
+const char *lp_ldap_group_suffix(void)
{
if (Globals.szLdapGroupSuffix[0])
return append_ldap_suffix(Globals.szLdapGroupSuffix);
return lp_string(Globals.szLdapSuffix);
}
-char *lp_ldap_idmap_suffix(void)
+const char *lp_ldap_idmap_suffix(void)
{
if (Globals.szLdapIdmapSuffix[0])
return append_ldap_suffix(Globals.szLdapIdmapSuffix);
return lp_string(Globals.szLdapSuffix);
}
-/***************************************************************************
-***************************************************************************/
-
-static BOOL handle_acl_compatibility(int snum, const char *pszParmValue, char **ptr)
-{
- if (strequal(pszParmValue, "auto"))
- string_set(ptr, "");
- else if (strequal(pszParmValue, "winnt"))
- string_set(ptr, "winnt");
- else if (strequal(pszParmValue, "win2k"))
- string_set(ptr, "win2k");
- else
- return False;
-
- return True;
-}
-
/****************************************************************************
set the value for a P_ENUM
***************************************************************************/
parm_ptr =
((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
&sDefault);
- }
- if (snum >= 0) {
if (!ServicePtrs[snum]->copymap)
init_copymap(ServicePtrs[snum]);
switch (parm_table[parmnum].type)
{
case P_BOOL:
- set_boolean((BOOL *)parm_ptr, pszParmValue);
+ *(BOOL *)parm_ptr = lp_bool(pszParmValue);
break;
case P_BOOLREV:
- set_boolean((BOOL *)parm_ptr, pszParmValue);
- *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
+ *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
break;
case P_INTEGER:
- *(int *)parm_ptr = atoi(pszParmValue);
+ *(int *)parm_ptr = lp_int(pszParmValue);
break;
case P_CHAR:
BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
{
- service * pService = ServicePtrs[snum];
- int i, result = False;
+ int i;
+ BOOL result = False;
parm_class p_class;
unsigned flag = 0;
+ fstring local_parm_name;
+ char *parm_opt;
+ const char *parm_opt_value;
+
+ /* check for parametrical option */
+ fstrcpy( local_parm_name, parm_name);
+ parm_opt = strchr( local_parm_name, ':');
+
+ if (parm_opt) {
+ *parm_opt = '\0';
+ parm_opt++;
+ if (strlen(parm_opt)) {
+ parm_opt_value = lp_parm_const_string( snum,
+ local_parm_name, parm_opt, NULL);
+ if (parm_opt_value) {
+ printf( "%s\n", parm_opt_value);
+ result = True;
+ }
+ }
+ return result;
+ }
+ /* check for a key and print the value */
if (isGlobal) {
p_class = P_GLOBAL;
flag = FLAG_GLOBAL;
} else
p_class = P_LOCAL;
-
+
for (i = 0; parm_table[i].label; i++) {
if (strwicmp(parm_table[i].label, parm_name) == 0 &&
(parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
{
void *ptr;
- if (isGlobal)
+ if (isGlobal) {
ptr = parm_table[i].ptr;
- else
+ } else {
+ service * pService = ServicePtrs[snum];
ptr = ((char *)pService) +
PTR_DIFF(parm_table[i].ptr, &sDefault);
+ }
print_parameter(&parm_table[i],
ptr, f);
}
/***************************************************************************
- Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
+ Return info about the next parameter in a service.
+ snum==GLOBAL_SECTION_SNUM gives the globals.
Return NULL when out of parameters.
***************************************************************************/
if (!VALID(i))
continue;
- /* don't kill autoloaded services */
- if ( ServicePtrs[i]->autoloaded )
+ /* don't kill autoloaded or usershare services */
+ if ( ServicePtrs[i]->autoloaded ||
+ ServicePtrs[i]->usershare == USERSHARE_VALID) {
continue;
+ }
if (!snumused || !snumused(i)) {
free_service_byindex(i);
Set the server type we will announce as via nmbd.
********************************************************************/
+static const struct srv_role_tab {
+ uint32 role;
+ const char *role_str;
+} srv_role_tab [] = {
+ { ROLE_STANDALONE, "ROLE_STANDALONE" },
+ { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
+ { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
+ { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
+ { 0, NULL }
+};
+
+const char* server_role_str(uint32 role)
+{
+ int i = 0;
+ for (i=0; srv_role_tab[i].role_str; i++) {
+ if (role == srv_role_tab[i].role) {
+ return srv_role_tab[i].role_str;
+ }
+ }
+ return NULL;
+}
+
static void set_server_role(void)
{
server_role = ROLE_STANDALONE;
case SEC_SERVER:
if (lp_domain_logons())
DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
- server_role = ROLE_DOMAIN_MEMBER;
+ /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
+ server_role = ROLE_STANDALONE;
break;
case SEC_DOMAIN:
if (lp_domain_logons()) {
break;
}
- DEBUG(10, ("set_server_role: role = "));
-
- switch(server_role) {
- case ROLE_STANDALONE:
- DEBUGADD(10, ("ROLE_STANDALONE\n"));
- break;
- case ROLE_DOMAIN_MEMBER:
- DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
- break;
- case ROLE_DOMAIN_BDC:
- DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
- break;
- case ROLE_DOMAIN_PDC:
- DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
- break;
- }
+ DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
}
/***********************************************************
If we should send plaintext/LANMAN passwords in the clinet
************************************************************/
+
static void set_allowed_client_auth(void)
{
if (Globals.bClientNTLMv2Auth) {
}
}
+/***************************************************************************
+ JRA.
+ The following code allows smbd to read a user defined share file.
+ Yes, this is my intent. Yes, I'm comfortable with that...
+
+ THE FOLLOWING IS SECURITY CRITICAL CODE.
+
+ It washes your clothes, it cleans your house, it guards you while you sleep...
+ Do not f%^k with it....
+***************************************************************************/
+
+#define MAX_USERSHARE_FILE_SIZE (10*1024)
+
+/***************************************************************************
+ Check allowed stat state of a usershare file.
+ Ensure we print out who is dicking with us so the admin can
+ get their sorry ass fired.
+***************************************************************************/
+
+static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
+{
+ if (!S_ISREG(psbuf->st_mode)) {
+ DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
+ "not a regular file\n",
+ fname, (unsigned int)psbuf->st_uid ));
+ return False;
+ }
+
+ /* Ensure this doesn't have the other write bit set. */
+ if (psbuf->st_mode & S_IWOTH) {
+ DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
+ "public write. Refusing to allow as a usershare file.\n",
+ fname, (unsigned int)psbuf->st_uid ));
+ return False;
+ }
+
+ /* Should be 10k or less. */
+ if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
+ DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
+ "too large (%u) to be a user share file.\n",
+ fname, (unsigned int)psbuf->st_uid,
+ (unsigned int)psbuf->st_size ));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
+ Parse the contents of a usershare file.
+***************************************************************************/
+
+enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
+ SMB_STRUCT_STAT *psbuf,
+ const char *servicename,
+ int snum,
+ char **lines,
+ int numlines,
+ pstring sharepath,
+ pstring comment,
+ SEC_DESC **ppsd,
+ BOOL *pallow_guest)
+{
+ const char **prefixallowlist = lp_usershare_prefix_allow_list();
+ const char **prefixdenylist = lp_usershare_prefix_deny_list();
+ int us_vers;
+ SMB_STRUCT_DIR *dp;
+ SMB_STRUCT_STAT sbuf;
+
+ *pallow_guest = False;
+
+ if (numlines < 4) {
+ return USERSHARE_MALFORMED_FILE;
+ }
+
+ if (strcmp(lines[0], "#VERSION 1") == 0) {
+ us_vers = 1;
+ } else if (strcmp(lines[0], "#VERSION 2") == 0) {
+ us_vers = 2;
+ if (numlines < 5) {
+ return USERSHARE_MALFORMED_FILE;
+ }
+ } else {
+ return USERSHARE_BAD_VERSION;
+ }
+
+ if (strncmp(lines[1], "path=", 5) != 0) {
+ return USERSHARE_MALFORMED_PATH;
+ }
+
+ pstrcpy(sharepath, &lines[1][5]);
+ trim_string(sharepath, " ", " ");
+
+ if (strncmp(lines[2], "comment=", 8) != 0) {
+ return USERSHARE_MALFORMED_COMMENT_DEF;
+ }
+
+ pstrcpy(comment, &lines[2][8]);
+ trim_string(comment, " ", " ");
+ trim_char(comment, '"', '"');
+
+ if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
+ return USERSHARE_MALFORMED_ACL_DEF;
+ }
+
+ if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
+ return USERSHARE_ACL_ERR;
+ }
+
+ if (us_vers == 2) {
+ if (strncmp(lines[4], "guest_ok=", 9) != 0) {
+ return USERSHARE_MALFORMED_ACL_DEF;
+ }
+ if (lines[4][9] == 'y') {
+ *pallow_guest = True;
+ }
+ }
+
+ if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
+ /* Path didn't change, no checks needed. */
+ return USERSHARE_OK;
+ }
+
+ /* The path *must* be absolute. */
+ if (sharepath[0] != '/') {
+ DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
+ servicename, sharepath));
+ return USERSHARE_PATH_NOT_ABSOLUTE;
+ }
+
+ /* If there is a usershare prefix deny list ensure one of these paths
+ doesn't match the start of the user given path. */
+ if (prefixdenylist) {
+ int i;
+ for ( i=0; prefixdenylist[i]; i++ ) {
+ DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
+ servicename, i, prefixdenylist[i], sharepath ));
+ if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
+ DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
+ "usershare prefix deny list entries.\n",
+ servicename, sharepath));
+ return USERSHARE_PATH_IS_DENIED;
+ }
+ }
+ }
+
+ /* If there is a usershare prefix allow list ensure one of these paths
+ does match the start of the user given path. */
+
+ if (prefixallowlist) {
+ int i;
+ for ( i=0; prefixallowlist[i]; i++ ) {
+ DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
+ servicename, i, prefixallowlist[i], sharepath ));
+ if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
+ break;
+ }
+ }
+ if (prefixallowlist[i] == NULL) {
+ DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
+ "usershare prefix allow list entries.\n",
+ servicename, sharepath));
+ return USERSHARE_PATH_NOT_ALLOWED;
+ }
+ }
+
+ /* Ensure this is pointing to a directory. */
+ dp = sys_opendir(sharepath);
+
+ if (!dp) {
+ DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
+ servicename, sharepath));
+ return USERSHARE_PATH_NOT_DIRECTORY;
+ }
+
+ /* Ensure the owner of the usershare file has permission to share
+ this directory. */
+
+ if (sys_stat(sharepath, &sbuf) == -1) {
+ DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
+ servicename, sharepath, strerror(errno) ));
+ sys_closedir(dp);
+ return USERSHARE_POSIX_ERR;
+ }
+
+ sys_closedir(dp);
+
+ if (!S_ISDIR(sbuf.st_mode)) {
+ DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
+ servicename, sharepath ));
+ return USERSHARE_PATH_NOT_DIRECTORY;
+ }
+
+ /* Check if sharing is restricted to owner-only. */
+ /* psbuf is the stat of the usershare definition file,
+ sbuf is the stat of the target directory to be shared. */
+
+ if (lp_usershare_owner_only()) {
+ /* root can share anything. */
+ if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
+ return USERSHARE_PATH_NOT_ALLOWED;
+ }
+ }
+
+ return USERSHARE_OK;
+}
+
+/***************************************************************************
+ Deal with a usershare file.
+ Returns:
+ >= 0 - snum
+ -1 - Bad name, invalid contents.
+ - service name already existed and not a usershare, problem
+ with permissions to share directory etc.
+***************************************************************************/
+
+static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
+{
+ SMB_STRUCT_STAT sbuf;
+ SMB_STRUCT_STAT lsbuf;
+ pstring fname;
+ pstring sharepath;
+ pstring comment;
+ fstring service_name;
+ char **lines = NULL;
+ int numlines = 0;
+ int fd = -1;
+ int iService = -1;
+ TALLOC_CTX *ctx = NULL;
+ SEC_DESC *psd = NULL;
+ BOOL guest_ok = False;
+
+ /* Ensure share name doesn't contain invalid characters. */
+ if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
+ DEBUG(0,("process_usershare_file: share name %s contains "
+ "invalid characters (any of %s)\n",
+ file_name, INVALID_SHARENAME_CHARS ));
+ return -1;
+ }
+
+ fstrcpy(service_name, file_name);
+
+ pstrcpy(fname, dir_name);
+ pstrcat(fname, "/");
+ pstrcat(fname, file_name);
+
+ /* Minimize the race condition by doing an lstat before we
+ open and fstat. Ensure this isn't a symlink link. */
+
+ if (sys_lstat(fname, &lsbuf) != 0) {
+ DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
+ fname, strerror(errno) ));
+ return -1;
+ }
+
+ /* This must be a regular file, not a symlink, directory or
+ other strange filetype. */
+ if (!check_usershare_stat(fname, &lsbuf)) {
+ return -1;
+ }
+
+ /* See if there is already a servicenum for this name. */
+ /* tdb_fetch_int32 returns -1 if not found. */
+ iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
+
+ if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
+ /* Nothing changed - Mark valid and return. */
+ DEBUG(10,("process_usershare_file: service %s not changed.\n",
+ service_name ));
+ ServicePtrs[iService]->usershare = USERSHARE_VALID;
+ return iService;
+ }
+
+ /* Try and open the file read only - no symlinks allowed. */
+#ifdef O_NOFOLLOW
+ fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
+#else
+ fd = sys_open(fname, O_RDONLY, 0);
+#endif
+
+ if (fd == -1) {
+ DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
+ fname, strerror(errno) ));
+ return -1;
+ }
+
+ /* Now fstat to be *SURE* it's a regular file. */
+ if (sys_fstat(fd, &sbuf) != 0) {
+ close(fd);
+ DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
+ fname, strerror(errno) ));
+ return -1;
+ }
+
+ /* Is it the same dev/inode as was lstated ? */
+ if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
+ close(fd);
+ DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
+ "Symlink spoofing going on ?\n", fname ));
+ return -1;
+ }
+
+ /* This must be a regular file, not a symlink, directory or
+ other strange filetype. */
+ if (!check_usershare_stat(fname, &sbuf)) {
+ return -1;
+ }
+
+ lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
+
+ close(fd);
+ if (lines == NULL) {
+ DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
+ fname, (unsigned int)sbuf.st_uid ));
+ return -1;
+ }
+
+ /* Should we allow printers to be shared... ? */
+ ctx = talloc_init("usershare_sd_xctx");
+ if (!ctx) {
+ file_lines_free(lines);
+ return 1;
+ }
+
+ if (parse_usershare_file(ctx, &sbuf, service_name,
+ iService, lines, numlines, sharepath,
+ comment, &psd, &guest_ok) != USERSHARE_OK) {
+ talloc_destroy(ctx);
+ file_lines_free(lines);
+ return -1;
+ }
+
+ file_lines_free(lines);
+
+ /* Everything ok - add the service possibly using a template. */
+ if (iService < 0) {
+ const service *sp = &sDefault;
+ if (snum_template != -1) {
+ sp = ServicePtrs[snum_template];
+ }
+
+ if ((iService = add_a_service(sp, service_name)) < 0) {
+ DEBUG(0, ("process_usershare_file: Failed to add "
+ "new service %s\n", service_name));
+ talloc_destroy(ctx);
+ return -1;
+ }
+
+ /* Read only is controlled by usershare ACL below. */
+ ServicePtrs[iService]->bRead_only = False;
+ }
+
+ /* Write the ACL of the new/modified share. */
+ if (!set_share_security(service_name, psd)) {
+ DEBUG(0, ("process_usershare_file: Failed to set share "
+ "security for user share %s\n",
+ service_name ));
+ lp_remove_service(iService);
+ talloc_destroy(ctx);
+ return -1;
+ }
+
+ talloc_destroy(ctx);
+
+ /* If from a template it may be marked invalid. */
+ ServicePtrs[iService]->valid = True;
+
+ /* Set the service as a valid usershare. */
+ ServicePtrs[iService]->usershare = USERSHARE_VALID;
+
+ /* Set guest access. */
+ if (lp_usershare_allow_guests()) {
+ ServicePtrs[iService]->bGuest_ok = guest_ok;
+ }
+
+ /* And note when it was loaded. */
+ ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
+ string_set(&ServicePtrs[iService]->szPath, sharepath);
+ string_set(&ServicePtrs[iService]->comment, comment);
+
+ return iService;
+}
+
+/***************************************************************************
+ Checks if a usershare entry has been modified since last load.
+***************************************************************************/
+
+static BOOL usershare_exists(int iService, time_t *last_mod)
+{
+ SMB_STRUCT_STAT lsbuf;
+ const char *usersharepath = Globals.szUsersharePath;
+ pstring fname;
+
+ pstrcpy(fname, usersharepath);
+ pstrcat(fname, "/");
+ pstrcat(fname, ServicePtrs[iService]->szService);
+
+ if (sys_lstat(fname, &lsbuf) != 0) {
+ return False;
+ }
+
+ if (!S_ISREG(lsbuf.st_mode)) {
+ return False;
+ }
+
+ *last_mod = lsbuf.st_mtime;
+ return True;
+}
+
+/***************************************************************************
+ Load a usershare service by name. Returns a valid servicenumber or -1.
+***************************************************************************/
+
+int load_usershare_service(const char *servicename)
+{
+ SMB_STRUCT_STAT sbuf;
+ const char *usersharepath = Globals.szUsersharePath;
+ int max_user_shares = Globals.iUsershareMaxShares;
+ int snum_template = -1;
+
+ if (*usersharepath == 0 || max_user_shares == 0) {
+ return -1;
+ }
+
+ if (sys_stat(usersharepath, &sbuf) != 0) {
+ DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
+ usersharepath, strerror(errno) ));
+ return -1;
+ }
+
+ if (!S_ISDIR(sbuf.st_mode)) {
+ DEBUG(0,("load_usershare_service: %s is not a directory.\n",
+ usersharepath ));
+ return -1;
+ }
+
+ /*
+ * This directory must be owned by root, and have the 't' bit set.
+ * It also must not be writable by "other".
+ */
+
+#ifdef S_ISVTX
+ if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
+#else
+ if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
+#endif
+ DEBUG(0,("load_usershare_service: directory %s is not owned by root "
+ "or does not have the sticky bit 't' set or is writable by anyone.\n",
+ usersharepath ));
+ return -1;
+ }
+
+ /* Ensure the template share exists if it's set. */
+ if (Globals.szUsershareTemplateShare[0]) {
+ /* We can't use lp_servicenumber here as we are recommending that
+ template shares have -valid=False set. */
+ for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
+ if (ServicePtrs[snum_template]->szService &&
+ strequal(ServicePtrs[snum_template]->szService,
+ Globals.szUsershareTemplateShare)) {
+ break;
+ }
+ }
+
+ if (snum_template == -1) {
+ DEBUG(0,("load_usershare_service: usershare template share %s "
+ "does not exist.\n",
+ Globals.szUsershareTemplateShare ));
+ return -1;
+ }
+ }
+
+ return process_usershare_file(usersharepath, servicename, snum_template);
+}
+
+/***************************************************************************
+ Load all user defined shares from the user share directory.
+ We only do this if we're enumerating the share list.
+ This is the function that can delete usershares that have
+ been removed.
+***************************************************************************/
+
+int load_usershare_shares(void)
+{
+ SMB_STRUCT_DIR *dp;
+ SMB_STRUCT_STAT sbuf;
+ SMB_STRUCT_DIRENT *de;
+ int num_usershares = 0;
+ int max_user_shares = Globals.iUsershareMaxShares;
+ unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
+ unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
+ unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
+ int iService;
+ int snum_template = -1;
+ const char *usersharepath = Globals.szUsersharePath;
+ int ret = lp_numservices();
+
+ if (max_user_shares == 0 || *usersharepath == '\0') {
+ return lp_numservices();
+ }
+
+ if (sys_stat(usersharepath, &sbuf) != 0) {
+ DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
+ usersharepath, strerror(errno) ));
+ return ret;
+ }
+
+ /*
+ * This directory must be owned by root, and have the 't' bit set.
+ * It also must not be writable by "other".
+ */
+
+#ifdef S_ISVTX
+ if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
+#else
+ if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
+#endif
+ DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
+ "or does not have the sticky bit 't' set or is writable by anyone.\n",
+ usersharepath ));
+ return ret;
+ }
+
+ /* Ensure the template share exists if it's set. */
+ if (Globals.szUsershareTemplateShare[0]) {
+ /* We can't use lp_servicenumber here as we are recommending that
+ template shares have -valid=False set. */
+ for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
+ if (ServicePtrs[snum_template]->szService &&
+ strequal(ServicePtrs[snum_template]->szService,
+ Globals.szUsershareTemplateShare)) {
+ break;
+ }
+ }
+
+ if (snum_template == -1) {
+ DEBUG(0,("load_usershare_shares: usershare template share %s "
+ "does not exist.\n",
+ Globals.szUsershareTemplateShare ));
+ return ret;
+ }
+ }
+
+ /* Mark all existing usershares as pending delete. */
+ for (iService = iNumServices - 1; iService >= 0; iService--) {
+ if (VALID(iService) && ServicePtrs[iService]->usershare) {
+ ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
+ }
+ }
+
+ dp = sys_opendir(usersharepath);
+ if (!dp) {
+ DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
+ usersharepath, strerror(errno) ));
+ return ret;
+ }
+
+ for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
+ (de = sys_readdir(dp));
+ num_dir_entries++ ) {
+ int r;
+ const char *n = de->d_name;
+
+ /* Ignore . and .. */
+ if (*n == '.') {
+ if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
+ continue;
+ }
+ }
+
+ if (n[0] == ':') {
+ /* Temporary file used when creating a share. */
+ num_tmp_dir_entries++;
+ }
+
+ /* Allow 20% tmp entries. */
+ if (num_tmp_dir_entries > allowed_tmp_entries) {
+ DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
+ "in directory %s\n",
+ num_tmp_dir_entries, usersharepath));
+ break;
+ }
+
+ r = process_usershare_file(usersharepath, n, snum_template);
+ if (r == 0) {
+ /* Update the services count. */
+ num_usershares++;
+ if (num_usershares >= max_user_shares) {
+ DEBUG(0,("load_usershare_shares: max user shares reached "
+ "on file %s in directory %s\n",
+ n, usersharepath ));
+ break;
+ }
+ } else if (r == -1) {
+ num_bad_dir_entries++;
+ }
+
+ /* Allow 20% bad entries. */
+ if (num_bad_dir_entries > allowed_bad_entries) {
+ DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
+ "in directory %s\n",
+ num_bad_dir_entries, usersharepath));
+ break;
+ }
+
+ /* Allow 20% bad entries. */
+ if (num_dir_entries > max_user_shares + allowed_bad_entries) {
+ DEBUG(0,("load_usershare_shares: too many total entries (%u) "
+ "in directory %s\n",
+ num_dir_entries, usersharepath));
+ break;
+ }
+ }
+
+ sys_closedir(dp);
+
+ /* Sweep through and delete any non-refreshed usershares that are
+ not currently in use. */
+ for (iService = iNumServices - 1; iService >= 0; iService--) {
+ if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
+ if (conn_snum_used(iService)) {
+ continue;
+ }
+ /* Remove from the share ACL db. */
+ DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
+ lp_servicename(iService) ));
+ delete_share_security(snum2params_static(iService));
+ free_service_byindex(iService);
+ }
+ }
+
+ return lp_numservices();
+}
+
+/********************************************************
+ Destroy global resources allocated in this file
+********************************************************/
+
+void gfree_loadparm(void)
+{
+ struct file_lists *f;
+ struct file_lists *next;
+ int i;
+
+ lp_TALLOC_FREE();
+
+ /* Free the file lists */
+
+ f = file_lists;
+ while( f ) {
+ next = f->next;
+ SAFE_FREE( f->name );
+ SAFE_FREE( f->subfname );
+ SAFE_FREE( f );
+ f = next;
+ }
+
+ /* Free resources allocated to services */
+
+ for ( i = 0; i < iNumServices; i++ ) {
+ if ( VALID(i) ) {
+ free_service_byindex(i);
+ }
+ }
+
+ SAFE_FREE( ServicePtrs );
+ iNumServices = 0;
+
+ /* Now release all resources allocated to global
+ parameters and the default service */
+
+ for (i = 0; parm_table[i].label; i++)
+ {
+ if ( parm_table[i].type == P_STRING
+ || parm_table[i].type == P_USTRING )
+ {
+ string_free( (char**)parm_table[i].ptr );
+ }
+ else if (parm_table[i].type == P_LIST) {
+ str_list_free( (char***)parm_table[i].ptr );
+ }
+ }
+}
+
/***************************************************************************
Load the services array from the services file. Return True on success,
False on failure.
***************************************************************************/
-BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
- BOOL add_ipc)
+BOOL lp_load(const char *pszFname,
+ BOOL global_only,
+ BOOL save_defaults,
+ BOOL add_ipc,
+ BOOL initialize_globals)
{
pstring n2;
BOOL bRetval;
pstrcpy(n2, pszFname);
- standard_sub_basic( get_current_username(), n2,sizeof(n2) );
+ standard_sub_basic( get_current_username(), current_user_info.domain,
+ n2,sizeof(n2) );
add_to_file_list(pszFname, n2);
bInGlobalSection = True;
bGlobalOnly = global_only;
- init_globals();
+ init_globals(! initialize_globals);
debug_init();
if (save_defaults) {
int iService;
fstring serviceName;
- if (!pszServiceName)
+ if (!pszServiceName) {
return GLOBAL_SECTION_SNUM;
+ }
for (iService = iNumServices - 1; iService >= 0; iService--) {
if (VALID(iService) && ServicePtrs[iService]->szService) {
* service names
*/
fstrcpy(serviceName, ServicePtrs[iService]->szService);
- standard_sub_basic(get_current_username(), serviceName,sizeof(serviceName));
- if (strequal(serviceName, pszServiceName))
+ standard_sub_basic(get_current_username(),
+ current_user_info.domain,
+ serviceName,sizeof(serviceName));
+ if (strequal(serviceName, pszServiceName)) {
break;
+ }
+ }
+ }
+
+ if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
+ time_t last_mod;
+
+ if (!usershare_exists(iService, &last_mod)) {
+ /* Remove the share security tdb entry for it. */
+ delete_share_security(snum2params_static(iService));
+ /* Remove it from the array. */
+ free_service_byindex(iService);
+ /* Doesn't exist anymore. */
+ return GLOBAL_SECTION_SNUM;
+ }
+
+ /* Has it been modified ? If so delete and reload. */
+ if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
+ /* Remove it from the array. */
+ free_service_byindex(iService);
+ /* and now reload it. */
+ iService = load_usershare_service(pszServiceName);
}
}
return (iService);
}
+BOOL share_defined(const char *service_name)
+{
+ return (lp_servicenumber(service_name) != -1);
+}
+
+struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
+ const char *sharename)
+{
+ struct share_params *result;
+ char *sname;
+ int snum;
+
+ if (!(sname = SMB_STRDUP(sharename))) {
+ return NULL;
+ }
+
+ snum = find_service(sname);
+ SAFE_FREE(sname);
+
+ if (snum < 0) {
+ return NULL;
+ }
+
+ if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
+
+ result->service = snum;
+ return result;
+}
+
+struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
+{
+ struct share_iterator *result;
+
+ if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
+
+ result->next_id = 0;
+ return result;
+}
+
+struct share_params *next_share(struct share_iterator *list)
+{
+ struct share_params *result;
+
+ while (!lp_snum_ok(list->next_id) &&
+ (list->next_id < lp_numservices())) {
+ list->next_id += 1;
+ }
+
+ if (list->next_id >= lp_numservices()) {
+ return NULL;
+ }
+
+ if (!(result = TALLOC_P(list, struct share_params))) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
+
+ result->service = list->next_id;
+ list->next_id += 1;
+ return result;
+}
+
+struct share_params *next_printer(struct share_iterator *list)
+{
+ struct share_params *result;
+
+ while ((result = next_share(list)) != NULL) {
+ if (lp_print_ok(result->service)) {
+ break;
+ }
+ }
+ return result;
+}
+
+/*
+ * This is a hack for a transition period until we transformed all code from
+ * service numbers to struct share_params.
+ */
+
+struct share_params *snum2params_static(int snum)
+{
+ static struct share_params result;
+ result.service = snum;
+ return &result;
+}
+
/*******************************************************************
A useful volume label function.
********************************************************************/
-char *volume_label(int snum)
+const char *volume_label(int snum)
{
- char *ret = lp_volume(snum);
- if (!*ret)
- return lp_servicename(snum);
- return (ret);
+ char *ret;
+ const char *label = lp_volume(snum);
+ if (!*label) {
+ label = lp_servicename(snum);
+ }
+
+ /* This returns a 33 byte guarenteed null terminated string. */
+ ret = talloc_strndup(main_loop_talloc_get(), label, 32);
+ if (!ret) {
+ return "";
+ }
+ return ret;
}
-
/*******************************************************************
Set the server type we will announce as via nmbd.
********************************************************************/
}
-/****************************************************************
- Compatibility fn. for 2.2.2 code.....
-*****************************************************************/
-
-void get_private_directory(pstring privdir)
-{
- pstrcpy (privdir, lp_private_dir());
-}
-
/***********************************************************
Allow daemons such as winbindd to fix their logfile name.
************************************************************/
{
posix_pathnames = True;
}
+
+/*******************************************************************
+ Global state for POSIX lock processing - CIFS unix extensions.
+********************************************************************/
+
+BOOL posix_default_lock_was_set;
+static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
+
+enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
+{
+ if (posix_default_lock_was_set) {
+ return posix_cifsx_locktype;
+ } else {
+ return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
+ }
+}
+
+/*******************************************************************
+********************************************************************/
+
+void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
+{
+ posix_default_lock_was_set = True;
+ posix_cifsx_locktype = val;
+}