s3: Remove some pointless uses of string_sid_talloc
[ira/wip.git] / source3 / param / loadparm.c
index bc7d9974f44bbe2822c2627d671a29bb34d9c230..bd70ee1828d69f48e18a0d422fb0199865dfb23e 100644 (file)
    Copyright (C) Stefan (metze) Metzmacher 2002
    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
    Copyright (C) Michael Adam 2008
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 #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 bLoaded = False;
 
-extern enum protocol_types Protocol;
 extern userdom_struct current_user_info;
 
 #ifndef GLOBAL_NAME
@@ -195,6 +202,7 @@ struct global {
        bool bWinbindOfflineLogon;
        bool bWinbindNormalizeNames;
        bool bWinbindRpcOnly;
+       bool bCreateKrb5Conf;
        char *szIdmapBackend;
        char *szIdmapAllocBackend;
        char *szAddShareCommand;
@@ -251,16 +259,20 @@ struct global {
        char *szLdapGroupSuffix;
        int ldap_ssl;
        bool ldap_ssl_ads;
+       int ldap_deref;
+       int ldap_follow_referral;
        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 clustering;
+       int ctdb_timeout;
        int ldap_passwd_sync;
        int ldap_replication_sleep;
        int ldap_timeout; /* This is initialised in init_globals */
@@ -344,6 +356,8 @@ struct global {
        int iminreceivefile;
        struct param_opt_struct *param_opt;
        int cups_connection_timeout;
+       char *szSMBPerfcountModule;
+       bool bMapUntrustedToDomain;
 };
 
 static struct global Globals;
@@ -355,7 +369,7 @@ struct service {
        bool valid;
        bool autoloaded;
        int usershare;
-       time_t usershare_last_mod;
+       struct timespec usershare_last_mod;
        char *szService;
        char *szPath;
        char *szUsername;
@@ -499,7 +513,7 @@ static struct service sDefault = {
        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 */
@@ -675,7 +689,10 @@ 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"},
@@ -730,6 +747,20 @@ static const struct enum_list enum_ldap_ssl[] = {
        {-1, NULL}
 };
 
+/* LDAP Dereferencing Alias types */
+#define SAMBA_LDAP_DEREF_NEVER         0
+#define SAMBA_LDAP_DEREF_SEARCHING     1
+#define SAMBA_LDAP_DEREF_FINDING       2
+#define SAMBA_LDAP_DEREF_ALWAYS                3
+
+static const struct enum_list enum_ldap_deref[] = {
+       {SAMBA_LDAP_DEREF_NEVER, "never"},
+       {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
+       {SAMBA_LDAP_DEREF_FINDING, "finding"},
+       {SAMBA_LDAP_DEREF_ALWAYS, "always"},
+       {-1, "auto"}
+};
+
 static const struct enum_list enum_ldap_passwd_sync[] = {
        {LDAP_PASSWD_SYNC_OFF, "no"},
        {LDAP_PASSWD_SYNC_OFF, "off"},
@@ -772,6 +803,8 @@ static const struct enum_list enum_case[] = {
        {-1, NULL}
 };
 
+
+
 static const struct enum_list enum_bool_auto[] = {
        {False, "No"},
        {False, "False"},
@@ -876,7 +909,7 @@ static const struct enum_list enum_kerberos_method[] = {
 
 /* 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.
  *
@@ -885,7 +918,7 @@ static const struct enum_list enum_kerberos_method[] = {
  *      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
@@ -1030,7 +1063,7 @@ static struct parm_struct parm_table[] = {
                .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},
@@ -1775,6 +1808,15 @@ static struct parm_struct parm_table[] = {
                .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},
@@ -2476,7 +2518,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &sDefault.iWriteCacheSize,
                .special        = NULL,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
+               .flags          = FLAG_ADVANCED | FLAG_SHARE,
        },
        {
                .label          = "name cache timeout",
@@ -2514,6 +2556,15 @@ static struct parm_struct parm_table[] = {
                .enum_list      = NULL,
                .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
        },
+       {
+               .label          = "ctdb timeout",
+               .type           = P_INTEGER,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.ctdb_timeout,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
+       },
 
        {N_("Printing Options"), P_SEP, P_SEPARATOR},
 
@@ -2617,6 +2668,16 @@ static struct parm_struct parm_table[] = {
                .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,
@@ -3228,6 +3289,8 @@ static struct parm_struct parm_table[] = {
                .type           = P_LIST,
                .p_class        = P_GLOBAL,
                .ptr            = &Globals.szInitLogonDelayedHosts,
+               .special        = NULL,
+               .enum_list      = NULL,
                .flags          = FLAG_ADVANCED,
        },
 
@@ -3236,6 +3299,8 @@ static struct parm_struct parm_table[] = {
                .type           = P_INTEGER,
                .p_class        = P_GLOBAL,
                .ptr            = &Globals.InitLogonDelay,
+               .special        = NULL,
+               .enum_list      = NULL,
                .flags          = FLAG_ADVANCED,
 
        },
@@ -3324,22 +3389,22 @@ static struct parm_struct parm_table[] = {
                .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",
@@ -3620,6 +3685,24 @@ static struct parm_struct parm_table[] = {
                .enum_list      = NULL,
                .flags          = FLAG_ADVANCED,
        },
+       {
+               .label          = "ldap deref",
+               .type           = P_ENUM,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.ldap_deref,
+               .special        = NULL,
+               .enum_list      = enum_ldap_deref,
+               .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,
@@ -3723,7 +3806,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &Globals.szConfigFile,
                .special        = NULL,
                .enum_list      = NULL,
-               .flags          = FLAG_HIDE,
+               .flags          = FLAG_HIDE|FLAG_META,
        },
        {
                .label          = "preload",
@@ -3986,7 +4069,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &sDefault.szInclude,
                .special        = handle_include,
                .enum_list      = NULL,
-               .flags          = FLAG_HIDE,
+               .flags          = FLAG_HIDE|FLAG_META,
        },
        {
                .label          = "preexec",
@@ -4247,7 +4330,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &sDefault.bFakeDirCreateTimes,
                .special        = NULL,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
+               .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
        },
        {
                .label          = "panic action",
@@ -4258,6 +4341,15 @@ static struct parm_struct parm_table[] = {
                .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},
 
@@ -4538,6 +4630,15 @@ static struct parm_struct parm_table[] = {
                .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}
 };
@@ -4619,7 +4720,7 @@ static void init_printer_values(struct service *pService)
                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;
@@ -4627,6 +4728,59 @@ static void init_printer_values(struct service *pService)
 
        }
 }
+/**
+ *  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
+
+       if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
+               DEBUG(2,("max_open_files: sysctl_max (%d) below "
+                       "minimum Windows limit (%d)\n",
+                       sysctl_max,
+                       MIN_OPEN_FILES_WINDOWS));
+               sysctl_max = MIN_OPEN_FILES_WINDOWS;
+       }
+
+       if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
+               DEBUG(2,("rlimit_max: rlimit_max (%d) below "
+                       "minimum Windows limit (%d)\n",
+                       rlimit_max,
+                       MIN_OPEN_FILES_WINDOWS));
+               rlimit_max = MIN_OPEN_FILES_WINDOWS;
+       }
+
+       return MIN(sysctl_max, rlimit_max);
+}
 
 /**
  * Common part of freeing allocated data for one parameter.
@@ -4850,7 +5004,7 @@ static void init_globals(bool first_time_only)
        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;
@@ -4869,7 +5023,7 @@ static void init_globals(bool first_time_only)
        Globals.bTimestampLogs = True;
        string_set(&Globals.szLogLevel, "0");
        Globals.bDebugPrefixTimestamp = False;
-       Globals.bDebugHiresTimestamp = False;
+       Globals.bDebugHiresTimestamp = true;
        Globals.bDebugPid = False;
        Globals.bDebugUid = False;
        Globals.bDebugClass = False;
@@ -4918,12 +5072,13 @@ static void init_globals(bool first_time_only)
 #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, "");
@@ -4933,9 +5088,11 @@ static void init_globals(bool first_time_only)
        string_set(&Globals.szLdapAdminDn, "");
        Globals.ldap_ssl = LDAP_SSL_START_TLS;
        Globals.ldap_ssl_ads = False;
+       Globals.ldap_deref = -1;
        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;
@@ -4991,6 +5148,7 @@ static void init_globals(bool first_time_only)
        string_set(&Globals.ctdbdSocket, "");
        Globals.szClusterAddresses = NULL;
        Globals.clustering = False;
+       Globals.ctdb_timeout = 0;
 
        Globals.winbind_cache_time = 300;       /* 5 minutes */
        Globals.winbind_reconnect_delay = 30;   /* 30 seconds */
@@ -5043,6 +5201,8 @@ static void init_globals(bool first_time_only)
        Globals.bRegistryShares = False;
 
        Globals.iminreceivefile = 0;
+
+       Globals.bMapUntrustedToDomain = false;
 }
 
 /*******************************************************************
@@ -5064,6 +5224,9 @@ static char *lp_string(const char *s)
 #if 0
        DEBUG(10, ("lp_string(%s)\n", s));
 #endif
+       if (!s) {
+               return NULL;
+       }
 
        ret = talloc_sub_basic(ctx,
                        get_current_username(),
@@ -5163,6 +5326,7 @@ FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
 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)
@@ -5266,6 +5430,7 @@ 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_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)
@@ -5278,6 +5443,8 @@ 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_deref, &Globals.ldap_deref)
+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)
@@ -5340,6 +5507,7 @@ FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
 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)
@@ -5410,11 +5578,29 @@ FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
 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_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
+FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
@@ -5570,16 +5756,16 @@ static struct param_opt_struct *get_parametrics(int snum, const char *type,
        bool global_section = False;
        char* param_key;
         struct param_opt_struct *data;
-       
+
        if (snum >= iNumServices) return NULL;
-       
+
        if (snum < 0) { 
                data = Globals.param_opt;
                global_section = True;
        } else {
                data = ServicePtrs[snum]->param_opt;
        }
-    
+
        if (asprintf(&param_key, "%s:%s", type, option) == -1) {
                DEBUG(0,("asprintf failed!\n"));
                return NULL;
@@ -5607,7 +5793,7 @@ static struct param_opt_struct *get_parametrics(int snum, const char *type,
        }
 
        string_free(&param_key);
-       
+
        return NULL;
 }
 
@@ -5654,7 +5840,7 @@ static bool lp_bool(const char *s)
                MISSING_PARAMETER(lp_bool);
                return False;
        }
-       
+
        if (!set_boolean(s, &ret)) {
                DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
                return False;
@@ -5674,7 +5860,7 @@ static int lp_enum(const char *s,const struct enum_list *_enum)
                MISSING_PARAMETER(lp_enum);
                return (-1);
        }
-       
+
        for (i=0; _enum[i].name; i++) {
                if (strequal(_enum[i].name,s))
                        return _enum[i].value;
@@ -5704,7 +5890,7 @@ static int lp_enum(const char *s,const struct enum_list *_enum)
 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
 {
        struct param_opt_struct *data = get_parametrics(snum, type, option);
-       
+
        if (data == NULL||data->value==NULL) {
                if (def) {
                        return lp_string(def);
@@ -5721,10 +5907,10 @@ char *lp_parm_talloc_string(int snum, const char *type, const char *option, cons
 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
 {
        struct param_opt_struct *data = get_parametrics(snum, type, option);
-       
+
        if (data == NULL||data->value==NULL)
                return def;
-               
+
        return data->value;
 }
 
@@ -5737,7 +5923,7 @@ const char **lp_parm_string_list(int snum, const char *type, const char *option,
 
        if (data == NULL||data->value==NULL)
                return (const char **)def;
-               
+
        if (data->list==NULL) {
                data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
        }
@@ -5751,7 +5937,7 @@ const char **lp_parm_string_list(int snum, const char *type, const char *option,
 int lp_parm_int(int snum, const char *type, const char *option, int def)
 {
        struct param_opt_struct *data = get_parametrics(snum, type, option);
-       
+
        if (data && data->value && *data->value)
                return lp_int(data->value);
 
@@ -5764,7 +5950,7 @@ int lp_parm_int(int snum, const char *type, const char *option, int def)
 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
 {
        struct param_opt_struct *data = get_parametrics(snum, type, option);
-       
+
        if (data && data->value && *data->value)
                return lp_ulong(data->value);
 
@@ -5777,7 +5963,7 @@ unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsi
 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
 {
        struct param_opt_struct *data = get_parametrics(snum, type, option);
-       
+
        if (data && data->value && *data->value)
                return lp_bool(data->value);
 
@@ -5791,7 +5977,7 @@ int lp_parm_enum(int snum, const char *type, const char *option,
                 const struct enum_list *_enum, int def)
 {
        struct param_opt_struct *data = get_parametrics(snum, type, option);
-       
+
        if (data && data->value && *data->value && _enum)
                return lp_enum(data->value, _enum);
 
@@ -5881,7 +6067,7 @@ static void free_service_byindex(int idx)
        if (ServicePtrs[idx]->szService) {
                char *canon_name = canonicalize_servicename(
                        ServicePtrs[idx]->szService );
-               
+
                dbwrap_delete_bystring(ServiceHash, canon_name );
                TALLOC_FREE(canon_name);
        }
@@ -5923,7 +6109,7 @@ static int add_a_service(const struct service *pservice, const char *name)
        if (i == iNumServices) {
                struct service **tsp;
                int *tinvalid;
-               
+
                tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
                if (tsp == NULL) {
                        DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
@@ -5956,14 +6142,14 @@ static int add_a_service(const struct service *pservice, const char *name)
        copy_service(ServicePtrs[i], &tservice, NULL);
        if (name)
                string_set(&ServicePtrs[i]->szService, name);
-               
+
        DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
                i, ServicePtrs[i]->szService));
 
        if (!hash_a_service(ServicePtrs[i]->szService, i)) {
                return (-1);
        }
-               
+
        return (i);
 }
 
@@ -6028,6 +6214,11 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
 {
        int i;
 
+       if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
+                       pszHomedir[0] == '\0') {
+               return false;
+       }
+
        i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
 
        if (i < 0)
@@ -6141,7 +6332,7 @@ bool lp_add_printer(const char *pszPrintername, int iDefaultService)
        ServicePtrs[i]->bOpLocks = False;
        /* Printer services must be printable. */
        ServicePtrs[i]->bPrint_ok = True;
-       
+
        DEBUG(3, ("adding printer service %s\n", pszPrintername));
 
        return (True);
@@ -6631,7 +6822,7 @@ static void copy_service(struct service *pserviceDest, struct service *pserviceS
                        bitmap_copy(pserviceDest->copymap,
                                    pserviceSource->copymap);
        }
-       
+
        data = pserviceSource->param_opt;
        while (data) {
                set_param_opt(&pserviceDest->param_opt, data->key, data->value);
@@ -6723,13 +6914,16 @@ static bool process_smbconf_service(struct smbconf_service *service)
                        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;
@@ -6741,19 +6935,18 @@ static bool process_registry_globals(void)
                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;
        }
@@ -6771,7 +6964,24 @@ 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;
@@ -6810,6 +7020,10 @@ done:
        return ret;
 }
 
+#define MAX_INCLUDE_DEPTH 100
+
+static uint8_t include_depth;
+
 static struct file_lists {
        struct file_lists *next;
        char *name;
@@ -6844,6 +7058,7 @@ static void add_to_file_list(const char *fname, const char *subfname)
                }
                f->subfname = SMB_STRDUP(subfname);
                if (!f->subfname) {
+                       SAFE_FREE(f->name);
                        SAFE_FREE(f);
                        return;
                }
@@ -6854,8 +7069,29 @@ static void add_to_file_list(const char *fname, const char *subfname)
                if (t)
                        f->modtime = t;
        }
+       return;
+}
+
+/**
+ * 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.
  */
@@ -6882,45 +7118,51 @@ bool lp_file_list_changed(void)
 
        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 {
+                       char *n2 = NULL;
+                       n2 = talloc_sub_basic(talloc_tos(),
+                                             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 = SMB_STRDUP(n2);
+                               TALLOC_FREE(n2);
+                               return true;
+                       }
+                       TALLOC_FREE(n2);
                }
-               SAFE_FREE(n2);
                f = f->next;
        }
        return (False);
@@ -6936,12 +7178,12 @@ bool lp_file_list_changed(void)
 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
 {
        bool ret;
-       char *netbios_name = alloc_sub_basic(get_current_username(),
-                                       current_user_info.domain,
-                                       pszParmValue);
+       char *netbios_name = talloc_sub_basic(
+               talloc_tos(), get_current_username(), current_user_info.domain,
+               pszParmValue);
 
        ret = set_global_myname(netbios_name);
-       SAFE_FREE(netbios_name);
+       TALLOC_FREE(netbios_name);
        string_set(&Globals.szNetbiosName,global_myname());
 
        DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
@@ -6964,17 +7206,17 @@ static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
 {
        bool ret;
-       
+
        ret = set_global_myworkgroup(pszParmValue);
        string_set(&Globals.szWorkgroup,lp_workgroup());
-       
+
        return ret;
 }
 
 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
 {
        bool ret;
-       
+
        ret = set_global_scope(pszParmValue);
        string_set(&Globals.szNetbiosScope,global_scope());
 
@@ -6997,12 +7239,22 @@ static bool handle_include(int snum, const char *pszParmValue, char **ptr)
 {
        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));
@@ -7010,22 +7262,25 @@ static bool handle_include(int snum, const char *pszParmValue, char **ptr)
                }
        }
 
-       fname = alloc_sub_basic(get_current_username(),
-                               current_user_info.domain,
-                               pszParmValue);
+       fname = talloc_sub_basic(talloc_tos(), get_current_username(),
+                                current_user_info.domain,
+                                pszParmValue);
 
        add_to_file_list(pszParmValue, fname);
 
        string_set(ptr, fname);
 
        if (file_exist(fname)) {
-               bool ret = pm_process(fname, do_section, do_parameter, NULL);
-               SAFE_FREE(fname);
+               bool ret;
+               include_depth++;
+               ret = pm_process(fname, do_section, do_parameter, NULL);
+               include_depth--;
+               TALLOC_FREE(fname);
                return ret;
        }
 
        DEBUG(2, ("Can't find include file %s\n", fname));
-       SAFE_FREE(fname);
+       TALLOC_FREE(fname);
        return true;
 }
 
@@ -7642,11 +7897,12 @@ static void dump_globals(FILE *f)
 {
        int i;
        struct param_opt_struct *data;
-       
+
        fprintf(f, "[global]\n");
 
        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))
@@ -7686,18 +7942,18 @@ static void dump_a_service(struct service *pService, FILE * f)
 {
        int i;
        struct param_opt_struct *data;
-       
+
        if (pService != &sDefault)
                fprintf(f, "[%s]\n", pService->szService);
 
        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))) 
                {
-               
                        int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
 
                        if (pService == &sDefault) {
@@ -7769,6 +8025,7 @@ bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
 
        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 != '-') &&
@@ -7833,7 +8090,7 @@ struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
                            && (parm_table[*i].ptr ==
                                parm_table[(*i) - 1].ptr))
                                continue;
-                       
+
                        if (is_default(*i) && !allparameters)
                                continue;
 
@@ -7934,7 +8191,7 @@ static void lp_add_auto_services(char *str)
 
                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);
@@ -8164,29 +8421,30 @@ static void set_allowed_client_auth(void)
  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;
        }
 
@@ -8336,7 +8594,7 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
        /* Ensure the owner of the usershare file has permission to share
           this directory. */
 
-       if (sys_stat(sharepath, &sbuf) == -1) {
+       if (sys_stat(sharepath, &sbuf, false) == -1) {
                DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
                        servicename, sharepath, strerror(errno) ));
                sys_closedir(dp);
@@ -8345,7 +8603,7 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
 
        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;
@@ -8357,7 +8615,7 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
 
        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;
                }
        }
@@ -8408,7 +8666,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        /* 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) {
+       if (sys_lstat(fname, &lsbuf, false) != 0) {
                DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
                        fname, strerror(errno) ));
                SAFE_FREE(fname);
@@ -8435,7 +8693,9 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
                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 ));
@@ -8459,7 +8719,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        }
 
        /* Now fstat to be *SURE* it's a regular file. */
-       if (sys_fstat(fd, &sbuf) != 0) {
+       if (sys_fstat(fd, &sbuf, false) != 0) {
                close(fd);
                DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
                        fname, strerror(errno) ));
@@ -8468,7 +8728,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        }
 
        /* 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 ));
@@ -8488,7 +8748,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        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;
        }
@@ -8552,7 +8812,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        }
 
        /* 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);
 
@@ -8565,7 +8825,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
  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;
@@ -8577,18 +8837,18 @@ static bool usershare_exists(int iService, time_t *last_mod)
                return false;
        }
 
-       if (sys_lstat(fname, &lsbuf) != 0) {
+       if (sys_lstat(fname, &lsbuf, false) != 0) {
                SAFE_FREE(fname);
                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;
 }
 
@@ -8607,13 +8867,13 @@ int load_usershare_service(const char *servicename)
                return -1;
        }
 
-       if (sys_stat(usersharepath, &sbuf) != 0) {
+       if (sys_stat(usersharepath, &sbuf, false) != 0) {
                DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
                        usersharepath, strerror(errno) ));
                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;
@@ -8625,9 +8885,9 @@ int load_usershare_service(const char *servicename)
         */
 
 #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",
@@ -8684,7 +8944,7 @@ int load_usershare_shares(void)
                return lp_numservices();
        }
 
-       if (sys_stat(usersharepath, &sbuf) != 0) {
+       if (sys_stat(usersharepath, &sbuf, false) != 0) {
                DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
                        usersharepath, strerror(errno) ));
                return ret;
@@ -8696,9 +8956,9 @@ int load_usershare_shares(void)
         */
 
 #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",
@@ -8823,21 +9083,9 @@ int load_usershare_shares(void)
 
 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 */
 
@@ -8901,6 +9149,8 @@ bool lp_load_ex(const char *pszFname,
        init_globals(! initialize_globals);
        debug_init();
 
+       free_file_list();
+
        if (save_defaults) {
                init_locals();
                lp_save_defaults();
@@ -8912,7 +9162,7 @@ bool lp_load_ex(const char *pszFname,
        iServiceIndex = -1;
 
        if (lp_config_backend_is_file()) {
-               n2 = alloc_sub_basic(get_current_username(),
+               n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
                                        current_user_info.domain,
                                        pszFname);
                if (!n2) {
@@ -8922,7 +9172,7 @@ bool lp_load_ex(const char *pszFname,
                add_to_file_list(pszFname, n2);
 
                bRetval = pm_process(n2, do_section, do_parameter, NULL);
-               SAFE_FREE(n2);
+               TALLOC_FREE(n2);
 
                /* finish up the last section */
                DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
@@ -9087,11 +9337,11 @@ int lp_servicenumber(const char *pszServiceName)
 {
        int iService;
         fstring serviceName;
-        
+
         if (!pszServiceName) {
                return GLOBAL_SECTION_SNUM;
        }
-        
+
        for (iService = iNumServices - 1; iService >= 0; iService--) {
                if (VALID(iService) && ServicePtrs[iService]->szService) {
                        /*
@@ -9109,7 +9359,7 @@ int lp_servicenumber(const char *pszServiceName)
        }
 
        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. */
@@ -9121,7 +9371,8 @@ int lp_servicenumber(const char *pszServiceName)
                }
 
                /* 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. */
@@ -9240,7 +9491,7 @@ const char *volume_label(int snum)
        if (!*label) {
                label = lp_servicename(snum);
        }
-               
+
        /* This returns a 33 byte guarenteed null terminated string. */
        ret = talloc_strndup(talloc_tos(), label, 32);
        if (!ret) {
@@ -9481,10 +9732,6 @@ const char *lp_printcapname(void)
        return PRINTCAP_NAME;
 }
 
-/*******************************************************************
- Ensure we don't use sendfile if server smb signing is active.
-********************************************************************/
-
 static uint32 spoolss_state;
 
 bool lp_disable_spoolss( void )
@@ -9511,15 +9758,20 @@ uint32 lp_get_spoolss_state( 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;
+       if (get_Protocol() < PROTOCOL_NT1) {
+               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);
 }
 
 /*******************************************************************
@@ -9612,9 +9864,14 @@ int lp_min_receive_file_size(void)
 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;
 }
+
+void lp_set_passdb_backend(const char *backend)
+{
+       string_set(&Globals.szPassdbBackend, backend);
+}