#include "includes.h"
#include "printing.h"
+#ifdef HAVE_HTTPCONNECTENCRYPT
+#include <cups/http.h>
+#endif
+
bool bLoaded = False;
extern enum protocol_types Protocol;
#define USERSHARE_VALID 1
#define USERSHARE_PENDING_DELETE 2
-extern int extra_time_offset;
-
static bool defaults_saved = False;
struct param_opt_struct {
char *szDeletePrinterCommand;
char *szOs2DriverMap;
char *szLockDir;
+ char *szStateDir;
+ char *szCacheDir;
char *szPidDir;
char *szRootdir;
char *szDefaultService;
char *szLdapIdmapSuffix;
char *szLdapGroupSuffix;
int ldap_ssl;
+ bool ldap_ssl_ads;
char *szLdapSuffix;
char *szLdapAdminDn;
int ldap_debug_level;
int ldap_debug_threshold;
int iAclCompat;
char *szCupsServer;
+ int CupsEncrypt;
char *szIPrintServer;
char *ctdbdSocket;
char **szClusterAddresses;
bool bHostnameLookups;
bool bUnixExtensions;
bool bDisableNetbios;
- bool bUseKerberosKeytab;
+ char * szDedicatedKeytabFile;
+ int iKerberosMethod;
bool bDeferSharingViolations;
bool bEnablePrivileges;
bool bASUSupport;
int iminreceivefile;
struct param_opt_struct *param_opt;
int cups_connection_timeout;
+ char *szSMBPerfcountModule;
+ bool bMapUntrustedToDomain;
+ bool bFakeDirCreateTimes;
};
static struct global Globals;
bool valid;
bool autoloaded;
int usershare;
- time_t usershare_last_mod;
+ struct timespec usershare_last_mod;
char *szService;
char *szPath;
char *szUsername;
bool bHideUnReadable;
bool bHideUnWriteableFiles;
bool bBrowseable;
+ bool bAccessBasedShareEnum;
bool bAvailable;
bool bRead_only;
bool bNo_set_dir;
bool bDosFilemode;
bool bDosFiletimes;
bool bDosFiletimeResolution;
- bool bFakeDirCreateTimes;
bool bBlockingLocks;
bool bInheritPerms;
bool bInheritACLS;
True, /* valid */
False, /* not autoloaded */
0, /* not a usershare */
- (time_t)0, /* No last mod time */
+ {0, }, /* No last mod time */
NULL, /* szService */
NULL, /* szPath */
NULL, /* szUsername */
False, /* bHideUnReadable */
False, /* bHideUnWriteableFiles */
True, /* bBrowseable */
+ False, /* bAccessBasedShareEnum */
True, /* bAvailable */
True, /* bRead_only */
True, /* bNo_set_dir */
False, /* bDosFilemode */
True, /* bDosFiletimes */
False, /* bDosFiletimeResolution */
- False, /* bFakeDirCreateTimes */
True, /* bBlockingLocks */
False, /* bInheritPerms */
False, /* bInheritACLS */
static void set_default_server_announce_type(void);
static void set_allowed_client_auth(void);
+static void *lp_local_ptr(struct service *service, void *ptr);
+
+static void add_to_file_list(const char *fname, const char *subfname);
+
static const struct enum_list enum_protocol[] = {
+ {PROTOCOL_SMB2, "SMB2"},
{PROTOCOL_NT1, "NT1"},
{PROTOCOL_LANMAN2, "LANMAN2"},
{PROTOCOL_LANMAN1, "LANMAN1"},
static const struct enum_list enum_ldap_ssl[] = {
{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"},
+ {LDAP_SSL_START_TLS, "start_tls"},
{-1, NULL}
};
static const struct enum_list enum_ldap_passwd_sync[] = {
{LDAP_PASSWD_SYNC_OFF, "no"},
- {LDAP_PASSWD_SYNC_OFF, "No"},
{LDAP_PASSWD_SYNC_OFF, "off"},
- {LDAP_PASSWD_SYNC_OFF, "Off"},
- {LDAP_PASSWD_SYNC_ON, "Yes"},
{LDAP_PASSWD_SYNC_ON, "yes"},
{LDAP_PASSWD_SYNC_ON, "on"},
- {LDAP_PASSWD_SYNC_ON, "On"},
- {LDAP_PASSWD_SYNC_ONLY, "Only"},
{LDAP_PASSWD_SYNC_ONLY, "only"},
{-1, NULL}
};
{-1, NULL}
};
+
+
static const struct enum_list enum_bool_auto[] = {
{False, "No"},
{False, "False"},
{-1, NULL}
};
+/* ADS kerberos ticket verification options */
+
+static const struct enum_list enum_kerberos_method[] = {
+ {KERBEROS_VERIFY_SECRETS, "default"},
+ {KERBEROS_VERIFY_SECRETS, "secrets only"},
+ {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
+ {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
+ {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
+ {-1, NULL}
+};
+
/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
*
- * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
+ * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
* screen in SWAT. This is used to exclude parameters as well as to squash all
* parameters that have been duplicated by pseudonyms.
*
* Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
* respective views.
*
- * NOTE2: Handling of duplicated (synonym) paramters:
+ * NOTE2: Handling of duplicated (synonym) parameters:
* Only the first occurance of a parameter should be enabled by FLAG_BASIC
* and/or FLAG_ADVANCED. All duplicates following the first mention should be
* set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
.ptr = &Globals.ConfigBackend,
.special = NULL,
.enum_list = enum_config_backend,
- .flags = FLAG_ADVANCED,
+ .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
},
{N_("Security Options"), P_SEP, P_SEPARATOR},
.flags = FLAG_ADVANCED | FLAG_GLOBAL,
},
{
- .label = "use kerberos keytab",
- .type = P_BOOL,
+ .label = "dedicated keytab file",
+ .type = P_STRING,
.p_class = P_GLOBAL,
- .ptr = &Globals.bUseKerberosKeytab,
+ .ptr = &Globals.szDedicatedKeytabFile,
.special = NULL,
.enum_list = NULL,
.flags = FLAG_ADVANCED,
},
+ {
+ .label = "kerberos method",
+ .type = P_ENUM,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.iKerberosMethod,
+ .special = NULL,
+ .enum_list = enum_kerberos_method,
+ .flags = FLAG_ADVANCED,
+ },
+ {
+ .label = "map untrusted to domain",
+ .type = P_BOOL,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.bMapUntrustedToDomain,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED | FLAG_GLOBAL,
+ },
+
{N_("Logging Options"), P_SEP, P_SEPARATOR},
.flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
},
{
+ .label = "cups encrypt",
+ .type = P_ENUM,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.CupsEncrypt,
+ .special = NULL,
+ .enum_list = enum_bool_auto,
+ .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
+ },
+ {
+
.label = "cups connection timeout",
.type = P_INTEGER,
.p_class = P_GLOBAL,
.enum_list = NULL,
.flags = FLAG_HIDE,
},
+ {
+ .label = "access based share enum",
+ .type = P_BOOL,
+ .p_class = P_LOCAL,
+ .ptr = &sDefault.bAccessBasedShareEnum,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
+ },
{
.label = "enhanced browsing",
.type = P_BOOL,
.ptr = &sDefault.bShareModes,
.special = NULL,
.enum_list = NULL,
- .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
+ .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
},
{N_("Ldap Options"), P_SEP, P_SEPARATOR},
.enum_list = enum_ldap_ssl,
.flags = FLAG_ADVANCED,
},
+ {
+ .label = "ldap ssl ads",
+ .type = P_BOOL,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.ldap_ssl_ads,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED,
+ },
{
.label = "ldap timeout",
.type = P_INTEGER,
.ptr = &Globals.szConfigFile,
.special = NULL,
.enum_list = NULL,
- .flags = FLAG_HIDE,
+ .flags = FLAG_HIDE|FLAG_META,
},
{
.label = "preload",
.enum_list = NULL,
.flags = FLAG_HIDE,
},
+ {
+ .label = "state directory",
+ .type = P_STRING,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.szStateDir,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED,
+ },
+ {
+ .label = "cache directory",
+ .type = P_STRING,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.szCacheDir,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED,
+ },
{
.label = "pid directory",
.type = P_STRING,
.ptr = &sDefault.szInclude,
.special = handle_include,
.enum_list = NULL,
- .flags = FLAG_HIDE,
+ .flags = FLAG_HIDE|FLAG_META,
},
{
.label = "preexec",
{
.label = "fake directory create times",
.type = P_BOOL,
- .p_class = P_LOCAL,
- .ptr = &sDefault.bFakeDirCreateTimes,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.bFakeDirCreateTimes,
.special = NULL,
.enum_list = NULL,
- .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
+ .flags = FLAG_ADVANCED | FLAG_GLOBAL,
},
{
.label = "panic action",
.enum_list = NULL,
.flags = FLAG_ADVANCED,
},
+ {
+ .label = "perfcount module",
+ .type = P_STRING,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.szSMBPerfcountModule,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED,
+ },
{N_("VFS module options"), P_SEP, P_SEPARATOR},
string_set(&pService->szLpqcommand, "vlp lpq %p");
string_set(&pService->szLprmcommand, "vlp lprm %p %j");
string_set(&pService->szLppausecommand, "vlp lppause %p %j");
- string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
+ string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
break;
}
}
+/**
+ * Function to return the default value for the maximum number of open
+ * file descriptors permitted. This function tries to consult the
+ * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
+ * the smaller of those.
+ */
+static int max_open_files(void)
+{
+ int sysctl_max = MAX_OPEN_FILES;
+ int rlimit_max = MAX_OPEN_FILES;
+
+#ifdef HAVE_SYSCTLBYNAME
+ {
+ size_t size = sizeof(sysctl_max);
+ sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
+ 0);
+ }
+#endif
+
+#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
+ {
+ struct rlimit rl;
+
+ ZERO_STRUCT(rl);
+
+ if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
+ rlimit_max = rl.rlim_cur;
+
+#if defined(RLIM_INFINITY)
+ if(rl.rlim_cur == RLIM_INFINITY)
+ rlimit_max = MAX_OPEN_FILES;
+ }
+#endif
+#endif
+
+ return MIN(sysctl_max, rlimit_max);
+}
/**
- * Free the allocated data for one parameter for a given share.
+ * Common part of freeing allocated data for one parameter.
*/
-static void free_parameter(int snum, struct parm_struct parm)
+static void free_one_parameter_common(void *parm_ptr,
+ struct parm_struct parm)
+{
+ if ((parm.type == P_STRING) ||
+ (parm.type == P_USTRING))
+ {
+ string_free((char**)parm_ptr);
+ } else if (parm.type == P_LIST) {
+ TALLOC_FREE(*((char***)parm_ptr));
+ }
+}
+
+/**
+ * Free the allocated data for one parameter for a share
+ * given as a service struct.
+ */
+static void free_one_parameter(struct service *service,
+ struct parm_struct parm)
{
void *parm_ptr;
- if (parm.ptr == NULL); {
+ if (parm.p_class != P_LOCAL) {
+ return;
+ }
+
+ parm_ptr = lp_local_ptr(service, parm.ptr);
+
+ free_one_parameter_common(parm_ptr, parm);
+}
+
+/**
+ * Free the allocated parameter data of a share given
+ * as a service struct.
+ */
+static void free_parameters(struct service *service)
+{
+ uint32_t i;
+
+ for (i=0; parm_table[i].label; i++) {
+ free_one_parameter(service, parm_table[i]);
+ }
+}
+
+/**
+ * Free the allocated data for one parameter for a given share
+ * specified by an snum.
+ */
+static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
+{
+ void *parm_ptr;
+
+ if (parm.ptr == NULL) {
return;
}
} else if (parm.p_class != P_LOCAL) {
return;
} else {
- parm_ptr = lp_local_ptr(snum, parm.ptr);
+ parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
}
- if ((parm.type == P_STRING) ||
- (parm.type == P_USTRING))
- {
- string_free((char**)parm_ptr);
- } else if (parm.type == P_LIST) {
- TALLOC_FREE(*((char***)parm_ptr));
- }
+ free_one_parameter_common(parm_ptr, parm);
}
/**
- * Free the allocated parameter data for a share.
+ * Free the allocated parameter data for a share specified
+ * by an snum.
*/
-static void free_parameters(int snum)
+static void free_parameters_by_snum(int snum)
{
uint32_t i;
for (i=0; parm_table[i].label; i++) {
- free_parameter(snum, parm_table[i]);
+ free_one_parameter_by_snum(snum, parm_table[i]);
}
}
*/
static void free_global_parameters(void)
{
- free_parameters(GLOBAL_SECTION_SNUM);
+ free_parameters_by_snum(GLOBAL_SECTION_SNUM);
}
/***************************************************************************
string_set(&Globals.szWorkgroup, lp_workgroup());
string_set(&Globals.szPasswdProgram, "");
- string_set(&Globals.szPidDir, get_dyn_PIDDIR());
string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
+ string_set(&Globals.szStateDir, get_dyn_STATEDIR());
+ string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
+ string_set(&Globals.szPidDir, get_dyn_PIDDIR());
string_set(&Globals.szSocketAddress, "0.0.0.0");
- if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
+ if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
smb_panic("init_globals: ENOMEM");
}
string_set(&Globals.szServerString, s);
Globals.getwd_cache = true;
Globals.bLargeReadwrite = True;
Globals.max_log_size = 5000;
- Globals.max_open_files = MAX_OPEN_FILES;
+ 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;
a large number of sites (tridge) */
Globals.bHostnameLookups = False;
- string_set(&Globals.szPassdbBackend, "smbpasswd");
+ string_set(&Globals.szPassdbBackend, "tdbsam");
string_set(&Globals.szLdapSuffix, "");
string_set(&Globals.szLdapMachineSuffix, "");
string_set(&Globals.szLdapUserSuffix, "");
string_set(&Globals.szLdapIdmapSuffix, "");
string_set(&Globals.szLdapAdminDn, "");
- Globals.ldap_ssl = LDAP_SSL_ON;
+ Globals.ldap_ssl = LDAP_SSL_START_TLS;
+ Globals.ldap_ssl_ads = False;
Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
Globals.ldap_delete_dn = False;
Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
Globals.bWinbindTrustedDomainsOnly = False;
Globals.bWinbindNestedGroups = True;
Globals.winbind_expand_groups = 1;
- Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
+ Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
Globals.bWinbindRefreshTickets = False;
Globals.bWinbindOfflineLogon = False;
Globals.bRegistryShares = False;
Globals.iminreceivefile = 0;
+
+ Globals.bMapUntrustedToDomain = false;
}
/*******************************************************************
}
/*
- In this section all the functions that are used to access the
- parameters from the rest of the program are defined
+ In this section all the functions that are used to access the
+ parameters from the rest of the program are defined
*/
#define FN_GLOBAL_STRING(fn_name,ptr) \
FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
+/* If lp_statedir() and lp_cachedir() are explicitely set during the
+ * build process or in smb.conf, we use that value. Otherwise they
+ * default to the value of lp_lockdir(). */
+char *lp_statedir(void) {
+ if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
+ (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
+ return(lp_string(*(char **)(&Globals.szStateDir) ?
+ *(char **)(&Globals.szStateDir) : ""));
+ else
+ return(lp_string(*(char **)(&Globals.szLockDir) ?
+ *(char **)(&Globals.szLockDir) : ""));
+}
+char *lp_cachedir(void) {
+ if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
+ (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
+ return(lp_string(*(char **)(&Globals.szCacheDir) ?
+ *(char **)(&Globals.szCacheDir) : ""));
+ else
+ return(lp_string(*(char **)(&Globals.szLockDir) ?
+ *(char **)(&Globals.szLockDir) : ""));
+}
FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
+FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
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_ldap_suffix, &Globals.szLdapSuffix)
FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
+FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
+FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
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_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
+FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
+int lp_cups_encrypt(void)
+{
+#ifdef HAVE_HTTPCONNECTENCRYPT
+ switch (Globals.CupsEncrypt) {
+ case Auto:
+ Globals.CupsEncrypt = HTTP_ENCRYPT_REQUIRED;
+ break;
+ case True:
+ Globals.CupsEncrypt = HTTP_ENCRYPT_ALWAYS;
+ break;
+ case False:
+ Globals.CupsEncrypt = HTTP_ENCRYPT_NEVER;
+ break;
+ }
+#endif
+ return Globals.CupsEncrypt;
+}
FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
FN_LOCAL_BOOL(lp_browseable, bBrowseable)
+FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
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_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_GLOBAL_BOOL(lp_fake_dir_create_times, &Globals.bFakeDirCreateTimes)
FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
static int map_parameter(const char *pszParmName);
static int map_parameter_canonical(const char *pszParmName, bool *inverse);
-static bool set_boolean(bool *pb, const char *pszParmValue);
static const char *get_boolean(bool bool_value);
static int getservicebyname(const char *pszServiceName,
struct service *pserviceDest);
return False;
}
- if (!set_boolean(&ret,s)) {
+ if (!set_boolean(s, &ret)) {
DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
return False;
}
return (const char **)def;
if (data->list==NULL) {
- data->list = str_list_make(NULL, data->value, NULL);
+ data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
}
return (const char **)data->list;
DEBUG(5, ("free_service: Freeing service %s\n",
pservice->szService));
- free_parameters(getservicebyname(pservice->szService, NULL));
+ free_parameters(pservice);
string_free(&pservice->szService);
bitmap_free(pservice->copymap);
/* set the browseable flag from the global default */
ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
+ ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
ServicePtrs[i]->autoloaded = True;
}
}
-/***************************************************************************
- Set a boolean variable from the text value stored in the passed string.
- Returns True in success, False if the passed string does not correctly
- represent a boolean.
-***************************************************************************/
-
-static bool set_boolean(bool *pb, const char *pszParmValue)
-{
- bool bRetval;
- bool value;
-
- bRetval = True;
- value = False;
- if (strwicmp(pszParmValue, "yes") == 0 ||
- strwicmp(pszParmValue, "true") == 0 ||
- strwicmp(pszParmValue, "1") == 0)
- value = True;
- else if (strwicmp(pszParmValue, "no") == 0 ||
- strwicmp(pszParmValue, "False") == 0 ||
- strwicmp(pszParmValue, "0") == 0)
- value = False;
- else {
- DEBUG(2,
- ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
- pszParmValue));
- bRetval = False;
- }
-
- if ((pb != NULL) && (bRetval != False)) {
- *pb = value;
- }
-
- return (bRetval);
-}
-
-
/***************************************************************************
Check if a given string correctly represents a boolean value.
***************************************************************************/
bool lp_string_is_valid_boolean(const char *parm_value)
{
- return set_boolean(NULL, parm_value);
+ return set_boolean(parm_value, NULL);
}
/***************************************************************************
{
bool val;
- if (!set_boolean(&val, str)) {
+ if (!set_boolean(str, &val)) {
return False;
}
{
bool val;
- if (!set_boolean(&val, str)) {
+ if (!set_boolean(str, &val)) {
return False;
}
break;
case P_LIST:
TALLOC_FREE(*((char ***)dest_ptr));
- str_list_copy(NULL, (char ***)dest_ptr,
+ *((char ***)dest_ptr) = str_list_copy(NULL,
*(const char ***)src_ptr);
break;
default:
werr = smbconf_init(NULL, &conf_ctx, "registry:");
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, ("error initializing registry configuration: "
- "%s\n", dos_errstr(werr)));
+ "%s\n", win_errstr(werr)));
conf_ctx = NULL;
}
}
return false;
}
}
+ if (iServiceIndex >= 0) {
+ return service_ok(iServiceIndex);
+ }
return true;
}
-/*
- * process_registry_globals
+/**
+ * load a service from registry and activate it
*/
-static bool process_registry_globals(void)
+bool process_registry_service(const char *service_name)
{
WERROR werr;
struct smbconf_service *service = NULL;
goto done;
}
- ret = do_parameter("registry shares", "yes", NULL);
- if (!ret) {
- goto done;
- }
+ DEBUG(5, ("process_registry_service: service name %s\n", service_name));
- if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
- /* nothing to read from the registry yet but make sure lp_load
- * doesn't return false */
+ if (!smbconf_share_exists(conf_ctx, service_name)) {
+ /*
+ * Registry does not contain data for this service (yet),
+ * but make sure lp_load doesn't return false.
+ */
ret = true;
goto done;
}
- werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
+ werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
return ret;
}
-static bool process_registry_shares(void)
+/*
+ * process_registry_globals
+ */
+static bool process_registry_globals(void)
+{
+ bool ret;
+
+ add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
+
+ ret = do_parameter("registry shares", "yes", NULL);
+ if (!ret) {
+ return ret;
+ }
+
+ return process_registry_service(GLOBAL_NAME);
+}
+
+bool process_registry_shares(void)
{
WERROR werr;
uint32_t count;
return ret;
}
+#define MAX_INCLUDE_DEPTH 100
+
+static uint8_t include_depth;
+
static struct file_lists {
struct file_lists *next;
char *name;
}
}
+/**
+ * Free the file lists
+ */
+static void free_file_list(void)
+{
+ struct file_lists *f;
+ struct file_lists *next;
+
+ f = file_lists;
+ while( f ) {
+ next = f->next;
+ SAFE_FREE( f->name );
+ SAFE_FREE( f->subfname );
+ SAFE_FREE( f );
+ f = next;
+ }
+ file_lists = NULL;
+}
+
+
/**
* Utility function for outsiders to check if we're running on registry.
*/
DEBUG(6, ("lp_file_list_changed()\n"));
- if (lp_config_backend_is_registry()) {
- struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
-
- if (conf_ctx == NULL) {
- return false;
- }
- if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
- DEBUGADD(6, ("registry config changed\n"));
- return true;
- }
- }
-
while (f) {
char *n2 = NULL;
time_t mod_time;
- n2 = alloc_sub_basic(get_current_username(),
- current_user_info.domain,
- f->name);
- if (!n2) {
- return false;
- }
- 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 = n2; /* Passing ownership of
- return from alloc_sub_basic
- above. */
- return true;
+ if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
+ struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
+
+ if (conf_ctx == NULL) {
+ return false;
+ }
+ if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
+ NULL))
+ {
+ DEBUGADD(6, ("registry config changed\n"));
+ return true;
+ }
+ } else {
+ n2 = alloc_sub_basic(get_current_username(),
+ current_user_info.domain,
+ f->name);
+ if (!n2) {
+ return false;
+ }
+ 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 = n2; /* Passing ownership of
+ return from alloc_sub_basic
+ above. */
+ return true;
+ }
+ SAFE_FREE(n2);
}
- SAFE_FREE(n2);
f = f->next;
}
return (False);
static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
{
TALLOC_FREE(Globals.szNetbiosAliases);
- Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
+ Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
}
{
char *fname;
+ if (include_depth >= MAX_INCLUDE_DEPTH) {
+ DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
+ include_depth));
+ return false;
+ }
+
if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
if (!bAllowIncludeRegistry) {
return true;
}
if (bInGlobalSection) {
- return process_registry_globals();
+ bool ret;
+ include_depth++;
+ ret = process_registry_globals();
+ include_depth--;
+ return ret;
} else {
DEBUG(1, ("\"include = registry\" only effective "
"in %s section\n", GLOBAL_NAME));
string_set(ptr, fname);
- if (file_exist(fname, NULL)) {
- bool ret = pm_process(fname, do_section, do_parameter, NULL);
+ if (file_exist(fname)) {
+ bool ret;
+ include_depth++;
+ ret = pm_process(fname, do_section, do_parameter, NULL);
+ include_depth--;
SAFE_FREE(fname);
return ret;
}
bitmap_set(pservice->copymap, i);
}
+/***************************************************************************
+ Return the local pointer to a parameter given a service struct and the
+ pointer into the default structure.
+***************************************************************************/
+
+static void *lp_local_ptr(struct service *service, void *ptr)
+{
+ return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
+}
+
/***************************************************************************
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)
+void *lp_local_ptr_by_snum(int snum, void *ptr)
{
- return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
+ return lp_local_ptr(ServicePtrs[snum], ptr);
}
/***************************************************************************
pszParmName));
return (True);
}
- parm_ptr = lp_local_ptr(snum, def_ptr);
+ parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
}
if (snum >= 0) {
case P_LIST:
TALLOC_FREE(*((char ***)parm_ptr));
- *(char ***)parm_ptr = str_list_make(
- NULL, pszParmValue, NULL);
+ *(char ***)parm_ptr = str_list_make_v3(
+ talloc_autofree_context(), pszParmValue, NULL);
break;
case P_STRING:
return (*((char *)ptr1) == *((char *)ptr2));
case P_LIST:
- return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
+ return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
case P_STRING:
case P_USTRING:
return False;
switch (parm_table[i].type) {
case P_LIST:
- return str_list_compare (parm_table[i].def.lvalue,
- *(char ***)parm_table[i].ptr);
+ return str_list_equal((const char **)parm_table[i].def.lvalue,
+ *(const char ***)parm_table[i].ptr);
case P_STRING:
case P_USTRING:
return strequal(parm_table[i].def.svalue,
for (i = 0; parm_table[i].label; i++)
if (parm_table[i].p_class == P_GLOBAL &&
+ !(parm_table[i].flags & FLAG_META) &&
parm_table[i].ptr &&
(i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
if (defaults_saved && is_default(i))
for (i = 0; parm_table[i].label; i++) {
if (parm_table[i].p_class == P_LOCAL &&
+ !(parm_table[i].flags & FLAG_META) &&
parm_table[i].ptr &&
(*parm_table[i].label != '-') &&
(i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
for (i = 0; parm_table[i].label; i++) {
if (strwicmp(parm_table[i].label, parm_name) == 0 &&
+ !(parm_table[i].flags & FLAG_META) &&
(parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
parm_table[i].ptr &&
(*parm_table[i].label != '-') &&
continue;
switch (parm_table[i].type) {
case P_LIST:
- str_list_copy(
- NULL, &(parm_table[i].def.lvalue),
- *(const char ***)parm_table[i].ptr);
+ parm_table[i].def.lvalue = str_list_copy(
+ NULL, *(const char ***)parm_table[i].ptr);
break;
case P_STRING:
case P_USTRING:
get their sorry ass fired.
***************************************************************************/
-static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
+static bool check_usershare_stat(const char *fname,
+ const SMB_STRUCT_STAT *psbuf)
{
- if (!S_ISREG(psbuf->st_mode)) {
+ if (!S_ISREG(psbuf->st_ex_mode)) {
DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
"not a regular file\n",
- fname, (unsigned int)psbuf->st_uid ));
+ fname, (unsigned int)psbuf->st_ex_uid ));
return False;
}
/* Ensure this doesn't have the other write bit set. */
- if (psbuf->st_mode & S_IWOTH) {
+ if (psbuf->st_ex_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 ));
+ fname, (unsigned int)psbuf->st_ex_uid ));
return False;
}
/* Should be 10k or less. */
- if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
+ if (psbuf->st_ex_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 ));
+ fname, (unsigned int)psbuf->st_ex_uid,
+ (unsigned int)psbuf->st_ex_size ));
return False;
}
sys_closedir(dp);
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
servicename, sharepath ));
return USERSHARE_PATH_NOT_DIRECTORY;
if (lp_usershare_owner_only()) {
/* root can share anything. */
- if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
+ if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
return USERSHARE_PATH_NOT_ALLOWED;
}
}
TALLOC_FREE(canon_name);
}
- if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
+ if (iService != -1 &&
+ timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
+ &lsbuf.st_ex_mtime) == 0) {
/* Nothing changed - Mark valid and return. */
DEBUG(10,("process_usershare_file: service %s not changed.\n",
service_name ));
}
/* Is it the same dev/inode as was lstated ? */
- if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
+ if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_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;
}
- lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
+ lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
close(fd);
if (lines == NULL) {
DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
- fname, (unsigned int)sbuf.st_uid ));
+ fname, (unsigned int)sbuf.st_ex_uid ));
SAFE_FREE(fname);
return -1;
}
/* Should we allow printers to be shared... ? */
ctx = talloc_init("usershare_sd_xctx");
if (!ctx) {
- file_lines_free(lines);
+ TALLOC_FREE(lines);
return 1;
}
iService, lines, numlines, &sharepath,
&comment, &psd, &guest_ok) != USERSHARE_OK) {
talloc_destroy(ctx);
- file_lines_free(lines);
+ TALLOC_FREE(lines);
return -1;
}
- file_lines_free(lines);
+ TALLOC_FREE(lines);
/* Everything ok - add the service possibly using a template. */
if (iService < 0) {
}
/* And note when it was loaded. */
- ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
+ ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
string_set(&ServicePtrs[iService]->szPath, sharepath);
string_set(&ServicePtrs[iService]->comment, comment);
Checks if a usershare entry has been modified since last load.
***************************************************************************/
-static bool usershare_exists(int iService, time_t *last_mod)
+static bool usershare_exists(int iService, struct timespec *last_mod)
{
SMB_STRUCT_STAT lsbuf;
const char *usersharepath = Globals.szUsersharePath;
return false;
}
- if (!S_ISREG(lsbuf.st_mode)) {
+ if (!S_ISREG(lsbuf.st_ex_mode)) {
SAFE_FREE(fname);
return false;
}
SAFE_FREE(fname);
- *last_mod = lsbuf.st_mtime;
+ *last_mod = lsbuf.st_ex_mtime;
return true;
}
return -1;
}
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
DEBUG(0,("load_usershare_service: %s is not a directory.\n",
usersharepath ));
return -1;
*/
#ifdef S_ISVTX
- if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
+ if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
#else
- if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
+ if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_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",
*/
#ifdef S_ISVTX
- if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
+ if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
#else
- if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
+ if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_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",
void gfree_loadparm(void)
{
- struct file_lists *f;
- struct file_lists *next;
int i;
- /* 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;
- }
- file_lists = NULL;
+ free_file_list();
/* Free resources allocated to services */
init_globals(! initialize_globals);
debug_init();
+ free_file_list();
+
if (save_defaults) {
init_locals();
lp_save_defaults();
}
if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
- time_t last_mod;
+ struct timespec last_mod;
if (!usershare_exists(iService, &last_mod)) {
/* Remove the share security tdb entry for it. */
}
/* Has it been modified ? If so delete and reload. */
- if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
+ if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
+ &last_mod) < 0) {
/* Remove it from the array. */
free_service_byindex(iService);
/* and now reload it. */
return PRINTCAP_NAME;
}
-/*******************************************************************
- Ensure we don't use sendfile if server smb signing is active.
-********************************************************************/
-
static uint32 spoolss_state;
bool lp_disable_spoolss( void )
Ensure we don't use sendfile if server smb signing is active.
********************************************************************/
-bool lp_use_sendfile(int snum)
+bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
{
+ bool sign_active = false;
+
/* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
if (Protocol < PROTOCOL_NT1) {
- return False;
+ return false;
+ }
+ if (signing_state) {
+ sign_active = smb_signing_is_active(signing_state);
}
return (_lp_use_sendfile(snum) &&
(get_remote_arch() != RA_WIN95) &&
- !srv_is_signing_active());
+ !sign_active);
}
/*******************************************************************
}
return MIN(Globals.iminreceivefile, BUFFER_SIZE);
}
+
+/*******************************************************************
+ If socket address is an empty character string, it is necessary to
+ define it as "0.0.0.0".
+********************************************************************/
+
+const char *lp_socket_address(void)
+{
+ char *sock_addr = Globals.szSocketAddress;
+
+ if (sock_addr[0] == '\0'){
+ string_set(&Globals.szSocketAddress, "0.0.0.0");
+ }
+ return Globals.szSocketAddress;
+}