#include "includes.h"
#include "printing.h"
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
#ifdef HAVE_HTTPCONNECTENCRYPT
#include <cups/http.h>
#endif
bool bWinbindOfflineLogon;
bool bWinbindNormalizeNames;
bool bWinbindRpcOnly;
+ bool bCreateKrb5Conf;
char *szIdmapBackend;
char *szIdmapAllocBackend;
char *szAddShareCommand;
char *szLdapGroupSuffix;
int ldap_ssl;
bool ldap_ssl_ads;
+ int ldap_follow_referral;
char *szLdapSuffix;
char *szLdapAdminDn;
int ldap_debug_level;
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 bMap_system;
bool bMap_hidden;
bool bMap_archive;
+ bool bStoreCreateTime;
bool bStoreDosAttributes;
bool bDmapiSupport;
bool bLocking;
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, /* bMap_system */
False, /* bMap_hidden */
True, /* bMap_archive */
+ False, /* bStoreCreateTime */
False, /* bStoreDosAttributes */
False, /* bDmapiSupport */
True, /* bLocking */
False, /* bDosFilemode */
True, /* bDosFiletimes */
False, /* bDosFiletimeResolution */
- False, /* bFakeDirCreateTimes */
True, /* bBlockingLocks */
False, /* bInheritPerms */
False, /* bInheritACLS */
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"},
/* 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},
.enum_list = NULL,
.flags = FLAG_ADVANCED,
},
+ {
+ .label = "store create time",
+ .type = P_BOOL,
+ .p_class = P_LOCAL,
+ .ptr = &sDefault.bStoreCreateTime,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
+ },
{
.label = "store dos attributes",
.type = P_BOOL,
.type = P_LIST,
.p_class = P_GLOBAL,
.ptr = &Globals.szInitLogonDelayedHosts,
+ .special = NULL,
+ .enum_list = NULL,
.flags = FLAG_ADVANCED,
},
.type = P_INTEGER,
.p_class = P_GLOBAL,
.ptr = &Globals.InitLogonDelay,
+ .special = NULL,
+ .enum_list = NULL,
.flags = FLAG_ADVANCED,
},
.flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
},
{
- .label = "access based share enum",
+ .label = "browsable",
.type = P_BOOL,
.p_class = P_LOCAL,
- .ptr = &sDefault.bAccessBasedShareEnum,
+ .ptr = &sDefault.bBrowseable,
.special = NULL,
.enum_list = NULL,
- .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
+ .flags = FLAG_HIDE,
},
{
- .label = "browsable",
+ .label = "access based share enum",
.type = P_BOOL,
.p_class = P_LOCAL,
- .ptr = &sDefault.bBrowseable,
+ .ptr = &sDefault.bAccessBasedShareEnum,
.special = NULL,
.enum_list = NULL,
- .flags = FLAG_HIDE,
+ .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
},
{
.label = "enhanced browsing",
.enum_list = NULL,
.flags = FLAG_ADVANCED,
},
+ {
+ .label = "ldap follow referral",
+ .type = P_ENUM,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.ldap_follow_referral,
+ .special = NULL,
+ .enum_list = enum_bool_auto,
+ .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",
.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 = "create krb5 conf",
+ .type = P_BOOL,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.bCreateKrb5Conf,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED,
+ },
{NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
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;
#endif
Globals.bUnixExtensions = True;
Globals.bResetOnZeroVC = False;
+ Globals.bCreateKrb5Conf = true;
/* hostname lookups can be very expensive and are broken on
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, "");
Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
Globals.ldap_delete_dn = False;
Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
+ Globals.ldap_follow_referral = Auto;
Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
Globals.ldap_page_size = LDAP_PAGE_SIZE;
#if 0
DEBUG(10, ("lp_string(%s)\n", s));
#endif
+ if (!s) {
+ return NULL;
+ }
ret = talloc_sub_basic(ctx,
get_current_username(),
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_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
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_follow_referral, &Globals.ldap_follow_referral)
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_LOCAL_BOOL(lp_print_ok, bPrint_ok)
FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
+FN_LOCAL_BOOL(lp_store_create_time, bStoreCreateTime)
FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
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)
{
int i;
+ if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
+ pszHomedir[0] == '\0') {
+ return false;
+ }
+
i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
if (i < 0)
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);
{
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)) {
- bool ret = pm_process(fname, do_section, do_parameter, NULL);
+ bool ret;
+ include_depth++;
+ ret = pm_process(fname, do_section, do_parameter, NULL);
+ include_depth--;
SAFE_FREE(fname);
return ret;
}
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 != '-') &&
home = get_user_home_dir(talloc_tos(), p);
- if (home && homes >= 0)
+ if (home && home[0] && homes >= 0)
lp_add_home(p, homes, p, home);
TALLOC_FREE(home);
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 ));
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;
}
}
/* 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 Globals.szSocketAddress;
}
+
+void lp_set_passdb_backend(const char *backend)
+{
+ string_set(&Globals.szPassdbBackend, backend);
+}