s3/loadparm: Fix severe HPUX compiler issue.
[samba.git] / source3 / param / loadparm.c
index 7b794020a1d26e0ccfca2c362d71583a6dc972a7..fa0577ba967015ebca320b8e43bdd745080b19f0 100644 (file)
 #include "includes.h"
 #include "printing.h"
 
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
 #ifdef HAVE_HTTPCONNECTENCRYPT
 #include <cups/http.h>
 #endif
@@ -199,6 +203,7 @@ struct global {
        bool bWinbindOfflineLogon;
        bool bWinbindNormalizeNames;
        bool bWinbindRpcOnly;
+       bool bCreateKrb5Conf;
        char *szIdmapBackend;
        char *szIdmapAllocBackend;
        char *szAddShareCommand;
@@ -255,6 +260,7 @@ struct global {
        char *szLdapGroupSuffix;
        int ldap_ssl;
        bool ldap_ssl_ads;
+       int ldap_ref_follow;
        char *szLdapSuffix;
        char *szLdapAdminDn;
        int ldap_debug_level;
@@ -351,6 +357,7 @@ struct global {
        int cups_connection_timeout;
        char *szSMBPerfcountModule;
        bool bMapUntrustedToDomain;
+       bool bFakeDirCreateTimes;
 };
 
 static struct global Globals;
@@ -362,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;
@@ -445,6 +452,7 @@ struct service {
        bool bMap_system;
        bool bMap_hidden;
        bool bMap_archive;
+       bool bStoreCreateTime;
        bool bStoreDosAttributes;
        bool bDmapiSupport;
        bool bLocking;
@@ -468,7 +476,6 @@ struct service {
        bool bDosFilemode;
        bool bDosFiletimes;
        bool bDosFiletimeResolution;
-       bool bFakeDirCreateTimes;
        bool bBlockingLocks;
        bool bInheritPerms;
        bool bInheritACLS;
@@ -506,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 */
@@ -589,6 +596,7 @@ static struct service sDefault = {
        False,                  /* bMap_system */
        False,                  /* bMap_hidden */
        True,                   /* bMap_archive */
+       False,                  /* bStoreCreateTime */
        False,                  /* bStoreDosAttributes */
        False,                  /* bDmapiSupport */
        True,                   /* bLocking */
@@ -612,7 +620,6 @@ static struct service sDefault = {
        False,                  /* bDosFilemode */
        True,                   /* bDosFiletimes */
        False,                  /* bDosFiletimeResolution */
-       False,                  /* bFakeDirCreateTimes */
        True,                   /* bBlockingLocks */
        False,                  /* bInheritPerms */
        False,                  /* bInheritACLS */
@@ -682,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"},
@@ -1039,7 +1049,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},
@@ -3063,6 +3073,15 @@ static struct parm_struct parm_table[] = {
                .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,
@@ -3256,6 +3275,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,
        },
 
@@ -3264,6 +3285,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,
 
        },
@@ -3352,22 +3375,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",
@@ -3648,6 +3671,15 @@ static struct parm_struct parm_table[] = {
                .enum_list      = NULL,
                .flags          = FLAG_ADVANCED,
        },
+       {
+               .label          = "ldap ref follow",
+               .type           = P_ENUM,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.ldap_ref_follow,
+               .special        = NULL,
+               .enum_list      = enum_bool_auto,
+               .flags          = FLAG_ADVANCED,
+       },
        {
                .label          = "ldap timeout",
                .type           = P_INTEGER,
@@ -3751,7 +3783,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",
@@ -4014,7 +4046,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",
@@ -4271,11 +4303,11 @@ static struct parm_struct parm_table[] = {
        {
                .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",
@@ -4575,6 +4607,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}
 };
@@ -4992,12 +5033,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, "");
@@ -5010,6 +5052,7 @@ static void init_globals(bool first_time_only)
        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_ref_follow = Auto;
        Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
        Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
        Globals.ldap_page_size = LDAP_PAGE_SIZE;
@@ -5140,6 +5183,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(),
@@ -5343,6 +5389,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)
@@ -5355,6 +5402,7 @@ 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_ref_follow, &Globals.ldap_ref_follow)
 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)
@@ -5559,6 +5607,7 @@ FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
 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)
@@ -5581,7 +5630,7 @@ FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
-FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
+FN_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)
@@ -6123,6 +6172,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)
@@ -6819,7 +6873,7 @@ static bool process_smbconf_service(struct smbconf_service *service)
                }
        }
        if (iServiceIndex >= 0) {
-               ret = service_ok(iServiceIndex);
+               return service_ok(iServiceIndex);
        }
        return true;
 }
@@ -6875,6 +6929,8 @@ 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;
@@ -6972,6 +7028,26 @@ static void add_to_file_list(const char *fname, const char *subfname)
        }
 }
 
+/**
+ * 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.
  */
@@ -6998,45 +7074,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 {
+                       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);
@@ -7776,6 +7858,7 @@ static void dump_globals(FILE *f)
 
        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))
@@ -7822,6 +7905,7 @@ static void dump_a_service(struct service *pService, FILE * f)
        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))) 
@@ -7898,6 +7982,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 != '-') &&
@@ -8063,7 +8148,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);
@@ -8293,29 +8378,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;
        }
 
@@ -8474,7 +8560,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;
@@ -8486,7 +8572,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;
                }
        }
@@ -8564,7 +8650,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 ));
@@ -8597,7 +8685,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 ));
@@ -8617,7 +8705,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;
        }
@@ -8681,7 +8769,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);
 
@@ -8694,7 +8782,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;
@@ -8711,13 +8799,13 @@ static bool usershare_exists(int iService, time_t *last_mod)
                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;
 }
 
@@ -8742,7 +8830,7 @@ int load_usershare_service(const char *servicename)
                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;
@@ -8754,9 +8842,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",
@@ -8825,9 +8913,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",
@@ -8952,21 +9040,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 */
 
@@ -9030,6 +9106,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();
@@ -9238,7 +9316,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. */
@@ -9250,7 +9328,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. */
@@ -9748,3 +9827,8 @@ const char *lp_socket_address(void)
        }
        return  Globals.szSocketAddress;
 }
+
+void lp_set_passdb_backend(const char *backend)
+{
+       string_set(&Globals.szPassdbBackend, backend);
+}