s3: make passdb backend defaults to tdbsam
[ira/wip.git] / source3 / param / loadparm.c
index 1191c3d3aa690905a0a7b11f79d0ebb61b0cc174..57fdb6e044f72bedcfba2ae7b6d4d0c9651afff3 100644 (file)
 #include "includes.h"
 #include "printing.h"
 
+#ifdef HAVE_HTTPCONNECTENCRYPT
+#include <cups/http.h>
+#endif
+
 bool bLoaded = False;
 
 extern enum protocol_types Protocol;
@@ -94,8 +98,6 @@ static int config_backend = CONFIG_BACKEND_FILE;
 #define USERSHARE_VALID 1
 #define USERSHARE_PENDING_DELETE 2
 
-extern int extra_time_offset;
-
 static bool defaults_saved = False;
 
 struct param_opt_struct {
@@ -121,6 +123,8 @@ struct global {
        char *szDeletePrinterCommand;
        char *szOs2DriverMap;
        char *szLockDir;
+       char *szStateDir;
+       char *szCacheDir;
        char *szPidDir;
        char *szRootdir;
        char *szDefaultService;
@@ -250,12 +254,14 @@ struct global {
        char *szLdapIdmapSuffix;
        char *szLdapGroupSuffix;
        int ldap_ssl;
+       bool ldap_ssl_ads;
        char *szLdapSuffix;
        char *szLdapAdminDn;
        int ldap_debug_level;
        int ldap_debug_threshold;
        int iAclCompat;
        char *szCupsServer;
+       int CupsEncrypt;
        char *szIPrintServer;
        char *ctdbdSocket;
        char **szClusterAddresses;
@@ -322,7 +328,8 @@ struct global {
        bool bHostnameLookups;
        bool bUnixExtensions;
        bool bDisableNetbios;
-       bool bUseKerberosKeytab;
+       char * szDedicatedKeytabFile;
+       int  iKerberosMethod;
        bool bDeferSharingViolations;
        bool bEnablePrivileges;
        bool bASUSupport;
@@ -342,6 +349,9 @@ struct global {
        int iminreceivefile;
        struct param_opt_struct *param_opt;
        int cups_connection_timeout;
+       char *szSMBPerfcountModule;
+       bool bMapUntrustedToDomain;
+       bool bFakeDirCreateTimes;
 };
 
 static struct global Globals;
@@ -353,7 +363,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;
@@ -425,6 +435,7 @@ struct service {
        bool bHideUnReadable;
        bool bHideUnWriteableFiles;
        bool bBrowseable;
+       bool bAccessBasedShareEnum;
        bool bAvailable;
        bool bRead_only;
        bool bNo_set_dir;
@@ -458,7 +469,6 @@ struct service {
        bool bDosFilemode;
        bool bDosFiletimes;
        bool bDosFiletimeResolution;
-       bool bFakeDirCreateTimes;
        bool bBlockingLocks;
        bool bInheritPerms;
        bool bInheritACLS;
@@ -496,7 +506,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 */
@@ -568,6 +578,7 @@ static struct service sDefault = {
        False,                  /* bHideUnReadable */
        False,                  /* bHideUnWriteableFiles */
        True,                   /* bBrowseable */
+       False,                  /* bAccessBasedShareEnum */
        True,                   /* bAvailable */
        True,                   /* bRead_only */
        True,                   /* bNo_set_dir */
@@ -601,7 +612,6 @@ static struct service sDefault = {
        False,                  /* bDosFilemode */
        True,                   /* bDosFiletimes */
        False,                  /* bDosFiletimeResolution */
-       False,                  /* bFakeDirCreateTimes */
        True,                   /* bBlockingLocks */
        False,                  /* bInheritPerms */
        False,                  /* bInheritACLS */
@@ -669,7 +679,12 @@ static void set_server_role(void);
 static void set_default_server_announce_type(void);
 static void set_allowed_client_auth(void);
 
+static void *lp_local_ptr(struct service *service, void *ptr);
+
+static void add_to_file_list(const char *fname, const char *subfname);
+
 static const struct enum_list enum_protocol[] = {
+       {PROTOCOL_SMB2, "SMB2"},
        {PROTOCOL_NT1, "NT1"},
        {PROTOCOL_LANMAN2, "LANMAN2"},
        {PROTOCOL_LANMAN1, "LANMAN1"},
@@ -718,24 +733,17 @@ static const struct enum_list enum_ldap_sasl_wrapping[] = {
 
 static const struct enum_list enum_ldap_ssl[] = {
        {LDAP_SSL_OFF, "no"},
-       {LDAP_SSL_OFF, "No"},
        {LDAP_SSL_OFF, "off"},
-       {LDAP_SSL_OFF, "Off"},
        {LDAP_SSL_START_TLS, "start tls"},
-       {LDAP_SSL_START_TLS, "Start_tls"},
+       {LDAP_SSL_START_TLS, "start_tls"},
        {-1, NULL}
 };
 
 static const struct enum_list enum_ldap_passwd_sync[] = {
        {LDAP_PASSWD_SYNC_OFF, "no"},
-       {LDAP_PASSWD_SYNC_OFF, "No"},
        {LDAP_PASSWD_SYNC_OFF, "off"},
-       {LDAP_PASSWD_SYNC_OFF, "Off"},
-       {LDAP_PASSWD_SYNC_ON, "Yes"},
        {LDAP_PASSWD_SYNC_ON, "yes"},
        {LDAP_PASSWD_SYNC_ON, "on"},
-       {LDAP_PASSWD_SYNC_ON, "On"},
-       {LDAP_PASSWD_SYNC_ONLY, "Only"},
        {LDAP_PASSWD_SYNC_ONLY, "only"},
        {-1, NULL}
 };
@@ -773,6 +781,8 @@ static const struct enum_list enum_case[] = {
        {-1, NULL}
 };
 
+
+
 static const struct enum_list enum_bool_auto[] = {
        {False, "No"},
        {False, "False"},
@@ -864,9 +874,20 @@ static const struct enum_list enum_config_backend[] = {
        {-1, NULL}
 };
 
+/* ADS kerberos ticket verification options */
+
+static const struct enum_list enum_kerberos_method[] = {
+       {KERBEROS_VERIFY_SECRETS, "default"},
+       {KERBEROS_VERIFY_SECRETS, "secrets only"},
+       {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
+       {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
+       {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
+       {-1, NULL}
+};
+
 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
  *
- * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
+ * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
  * screen in SWAT. This is used to exclude parameters as well as to squash all
  * parameters that have been duplicated by pseudonyms.
  *
@@ -875,7 +896,7 @@ static const struct enum_list enum_config_backend[] = {
  *      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
@@ -1020,7 +1041,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},
@@ -1748,14 +1769,33 @@ static struct parm_struct parm_table[] = {
                .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
        },
        {
-               .label          = "use kerberos keytab",
-               .type           = P_BOOL,
+               .label          = "dedicated keytab file",
+               .type           = P_STRING,
                .p_class        = P_GLOBAL,
-               .ptr            = &Globals.bUseKerberosKeytab,
+               .ptr            = &Globals.szDedicatedKeytabFile,
                .special        = NULL,
                .enum_list      = NULL,
                .flags          = FLAG_ADVANCED,
        },
+       {
+               .label          = "kerberos method",
+               .type           = P_ENUM,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.iKerberosMethod,
+               .special        = NULL,
+               .enum_list      = enum_kerberos_method,
+               .flags          = FLAG_ADVANCED,
+       },
+       {
+               .label          = "map untrusted to domain",
+               .type           = P_BOOL,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.bMapUntrustedToDomain,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
+       },
+
 
        {N_("Logging Options"), P_SEP, P_SEPARATOR},
 
@@ -2597,6 +2637,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,
@@ -3312,6 +3362,15 @@ static struct parm_struct parm_table[] = {
                .enum_list      = NULL,
                .flags          = FLAG_HIDE,
        },
+       {
+               .label          = "access based share enum",
+               .type           = P_BOOL,
+               .p_class        = P_LOCAL,
+               .ptr            = &sDefault.bAccessBasedShareEnum,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
+       },
        {
                .label          = "enhanced browsing",
                .type           = P_BOOL,
@@ -3487,7 +3546,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &sDefault.bShareModes,
                .special        = NULL,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
+               .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
        },
 
        {N_("Ldap Options"), P_SEP, P_SEPARATOR},
@@ -3582,6 +3641,15 @@ static struct parm_struct parm_table[] = {
                .enum_list      = enum_ldap_ssl,
                .flags          = FLAG_ADVANCED,
        },
+       {
+               .label          = "ldap ssl ads",
+               .type           = P_BOOL,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.ldap_ssl_ads,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_ADVANCED,
+       },
        {
                .label          = "ldap timeout",
                .type           = P_INTEGER,
@@ -3685,7 +3753,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",
@@ -3723,6 +3791,24 @@ static struct parm_struct parm_table[] = {
                .enum_list      = NULL,
                .flags          = FLAG_HIDE,
        },
+       {
+               .label          = "state directory",
+               .type           = P_STRING,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.szStateDir,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_ADVANCED,
+       },
+       {
+               .label          = "cache directory",
+               .type           = P_STRING,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.szCacheDir,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_ADVANCED,
+       },
        {
                .label          = "pid directory",
                .type           = P_STRING,
@@ -3930,7 +4016,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",
@@ -4187,11 +4273,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",
@@ -4202,6 +4288,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},
 
@@ -4563,7 +4658,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;
@@ -4571,15 +4666,99 @@ 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
+
+       return MIN(sysctl_max, rlimit_max);
+}
 
 /**
- * Free the allocated data for one parameter for a given share.
+ * Common part of freeing allocated data for one parameter.
  */
-static void free_parameter(int snum, struct parm_struct parm)
+static void free_one_parameter_common(void *parm_ptr,
+                                     struct parm_struct parm)
+{
+       if ((parm.type == P_STRING) ||
+           (parm.type == P_USTRING))
+       {
+               string_free((char**)parm_ptr);
+       } else if (parm.type == P_LIST) {
+               TALLOC_FREE(*((char***)parm_ptr));
+       }
+}
+
+/**
+ * Free the allocated data for one parameter for a share
+ * given as a service struct.
+ */
+static void free_one_parameter(struct service *service,
+                              struct parm_struct parm)
 {
        void *parm_ptr;
 
-       if (parm.ptr == NULL); {
+       if (parm.p_class != P_LOCAL) {
+               return;
+       }
+
+       parm_ptr = lp_local_ptr(service, parm.ptr);
+
+       free_one_parameter_common(parm_ptr, parm);
+}
+
+/**
+ * Free the allocated parameter data of a share given
+ * as a service struct.
+ */
+static void free_parameters(struct service *service)
+{
+       uint32_t i;
+
+       for (i=0; parm_table[i].label; i++) {
+               free_one_parameter(service, parm_table[i]);
+       }
+}
+
+/**
+ * Free the allocated data for one parameter for a given share
+ * specified by an snum.
+ */
+static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
+{
+       void *parm_ptr;
+
+       if (parm.ptr == NULL) {
                return;
        }
 
@@ -4588,27 +4767,22 @@ static void free_parameter(int snum, struct parm_struct parm)
        } else if (parm.p_class != P_LOCAL) {
                return;
        } else {
-               parm_ptr = lp_local_ptr(snum, parm.ptr);
+               parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
        }
 
-       if ((parm.type == P_STRING) ||
-           (parm.type == P_USTRING))
-       {
-               string_free((char**)parm_ptr);
-       } else if (parm.type == P_LIST) {
-               TALLOC_FREE(*((char***)parm_ptr));
-       }
+       free_one_parameter_common(parm_ptr, parm);
 }
 
 /**
- * Free the allocated parameter data for a share.
+ * Free the allocated parameter data for a share specified
+ * by an snum.
  */
-static void free_parameters(int snum)
+static void free_parameters_by_snum(int snum)
 {
        uint32_t i;
 
        for (i=0; parm_table[i].label; i++) {
-               free_parameter(snum, parm_table[i]);
+               free_one_parameter_by_snum(snum, parm_table[i]);
        }
 }
 
@@ -4617,7 +4791,7 @@ static void free_parameters(int snum)
  */
 static void free_global_parameters(void)
 {
-       free_parameters(GLOBAL_SECTION_SNUM);
+       free_parameters_by_snum(GLOBAL_SECTION_SNUM);
 }
 
 /***************************************************************************
@@ -4701,11 +4875,13 @@ static void init_globals(bool first_time_only)
        string_set(&Globals.szWorkgroup, lp_workgroup());
 
        string_set(&Globals.szPasswdProgram, "");
-       string_set(&Globals.szPidDir, get_dyn_PIDDIR());
        string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
+       string_set(&Globals.szStateDir, get_dyn_STATEDIR());
+       string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
+       string_set(&Globals.szPidDir, get_dyn_PIDDIR());
        string_set(&Globals.szSocketAddress, "0.0.0.0");
 
-       if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
+       if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
                smb_panic("init_globals: ENOMEM");
        }
        string_set(&Globals.szServerString, s);
@@ -4750,7 +4926,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;
@@ -4823,7 +4999,7 @@ static void init_globals(bool first_time_only)
           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, "");
@@ -4831,7 +5007,8 @@ static void init_globals(bool first_time_only)
        string_set(&Globals.szLdapIdmapSuffix, "");
 
        string_set(&Globals.szLdapAdminDn, "");
-       Globals.ldap_ssl = LDAP_SSL_ON;
+       Globals.ldap_ssl = LDAP_SSL_START_TLS;
+       Globals.ldap_ssl_ads = False;
        Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
        Globals.ldap_delete_dn = False;
        Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
@@ -4899,7 +5076,7 @@ static void init_globals(bool first_time_only)
        Globals.bWinbindTrustedDomainsOnly = False;
        Globals.bWinbindNestedGroups = True;
        Globals.winbind_expand_groups = 1;
-       Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
+       Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
        Globals.bWinbindRefreshTickets = False;
        Globals.bWinbindOfflineLogon = False;
 
@@ -4942,6 +5119,8 @@ static void init_globals(bool first_time_only)
        Globals.bRegistryShares = False;
 
        Globals.iminreceivefile = 0;
+
+       Globals.bMapUntrustedToDomain = false;
 }
 
 /*******************************************************************
@@ -4981,8 +5160,8 @@ static char *lp_string(const char *s)
 }
 
 /*
-   In this section all the functions that are used to access the 
-   parameters from the rest of the program are defined 
+   In this section all the functions that are used to access the
+   parameters from the rest of the program are defined
 */
 
 #define FN_GLOBAL_STRING(fn_name,ptr) \
@@ -5034,6 +5213,27 @@ FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
+/* If lp_statedir() and lp_cachedir() are explicitely set during the
+ * build process or in smb.conf, we use that value.  Otherwise they
+ * default to the value of lp_lockdir(). */
+char *lp_statedir(void) {
+       if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
+           (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
+               return(lp_string(*(char **)(&Globals.szStateDir) ?
+                   *(char **)(&Globals.szStateDir) : ""));
+       else
+               return(lp_string(*(char **)(&Globals.szLockDir) ?
+                   *(char **)(&Globals.szLockDir) : ""));
+}
+char *lp_cachedir(void) {
+       if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
+           (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
+               return(lp_string(*(char **)(&Globals.szCacheDir) ?
+                   *(char **)(&Globals.szCacheDir) : ""));
+       else
+               return(lp_string(*(char **)(&Globals.szLockDir) ?
+                   *(char **)(&Globals.szLockDir) : ""));
+}
 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
@@ -5041,6 +5241,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)
@@ -5063,7 +5264,6 @@ FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
-FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
@@ -5156,6 +5356,7 @@ FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
+FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
@@ -5218,6 +5419,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)
@@ -5234,7 +5436,8 @@ FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
-FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
+FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
+FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
@@ -5287,6 +5490,23 @@ 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)
@@ -5332,6 +5552,7 @@ FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
+FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
 FN_LOCAL_BOOL(lp_readonly, bRead_only)
 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
@@ -5362,7 +5583,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)
@@ -5418,7 +5639,6 @@ FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrappi
 
 static int map_parameter(const char *pszParmName);
 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
-static bool set_boolean(bool *pb, const char *pszParmValue);
 static const char *get_boolean(bool bool_value);
 static int getservicebyname(const char *pszServiceName,
                            struct service *pserviceDest);
@@ -5532,7 +5752,7 @@ static bool lp_bool(const char *s)
                return False;
        }
        
-       if (!set_boolean(&ret,s)) {
+       if (!set_boolean(s, &ret)) {
                DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
                return False;
        }
@@ -5616,7 +5836,7 @@ const char **lp_parm_string_list(int snum, const char *type, const char *option,
                return (const char **)def;
                
        if (data->list==NULL) {
-               data->list = str_list_make(NULL, data->value, NULL);
+               data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
        }
 
        return (const char **)data->list;
@@ -5729,7 +5949,7 @@ static void free_service(struct service *pservice)
                DEBUG(5, ("free_service: Freeing service %s\n",
                       pservice->szService));
 
-       free_parameters(getservicebyname(pservice->szService, NULL));
+       free_parameters(pservice);
 
        string_free(&pservice->szService);
        bitmap_free(pservice->copymap);
@@ -5927,6 +6147,7 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
        /* set the browseable flag from the global default */
 
        ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
+       ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
 
        ServicePtrs[i]->autoloaded = True;
 
@@ -6314,49 +6535,13 @@ void show_parameter_list(void)
        }
 }
 
-/***************************************************************************
- Set a boolean variable from the text value stored in the passed string.
- Returns True in success, False if the passed string does not correctly 
- represent a boolean.
-***************************************************************************/
-
-static bool set_boolean(bool *pb, const char *pszParmValue)
-{
-       bool bRetval;
-       bool value;
-
-       bRetval = True;
-       value = False;
-       if (strwicmp(pszParmValue, "yes") == 0 ||
-           strwicmp(pszParmValue, "true") == 0 ||
-           strwicmp(pszParmValue, "1") == 0)
-               value = True;
-       else if (strwicmp(pszParmValue, "no") == 0 ||
-                   strwicmp(pszParmValue, "False") == 0 ||
-                   strwicmp(pszParmValue, "0") == 0)
-               value = False;
-       else {
-               DEBUG(2,
-                     ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
-                      pszParmValue));
-               bRetval = False;
-       }
-
-       if ((pb != NULL) && (bRetval != False)) {
-               *pb = value;
-       }
-
-       return (bRetval);
-}
-
-
 /***************************************************************************
  Check if a given string correctly represents a boolean value.
 ***************************************************************************/
 
 bool lp_string_is_valid_boolean(const char *parm_value)
 {
-       return set_boolean(NULL, parm_value);
+       return set_boolean(parm_value, NULL);
 }
 
 /***************************************************************************
@@ -6381,7 +6566,7 @@ bool lp_invert_boolean(const char *str, const char **inverse_str)
 {
        bool val;
 
-       if (!set_boolean(&val, str)) {
+       if (!set_boolean(str, &val)) {
                return False;
        }
 
@@ -6399,7 +6584,7 @@ bool lp_canonicalize_boolean(const char *str, const char**canon_str)
 {
        bool val;
 
-       if (!set_boolean(&val, str)) {
+       if (!set_boolean(str, &val)) {
                return False;
        }
 
@@ -6529,7 +6714,7 @@ static void copy_service(struct service *pserviceDest, struct service *pserviceS
                                        break;
                                case P_LIST:
                                        TALLOC_FREE(*((char ***)dest_ptr));
-                                       str_list_copy(NULL, (char ***)dest_ptr,
+                                       *((char ***)dest_ptr) = str_list_copy(NULL, 
                                                      *(const char ***)src_ptr);
                                        break;
                                default:
@@ -6606,7 +6791,7 @@ static struct smbconf_ctx *lp_smbconf_ctx(void)
                werr = smbconf_init(NULL, &conf_ctx, "registry:");
                if (!W_ERROR_IS_OK(werr)) {
                        DEBUG(1, ("error initializing registry configuration: "
-                                 "%s\n", dos_errstr(werr)));
+                                 "%s\n", win_errstr(werr)));
                        conf_ctx = NULL;
                }
        }
@@ -6635,13 +6820,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;
@@ -6653,19 +6841,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;
        }
@@ -6683,7 +6870,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;
@@ -6722,6 +6926,10 @@ done:
        return ret;
 }
 
+#define MAX_INCLUDE_DEPTH 100
+
+static uint8_t include_depth;
+
 static struct file_lists {
        struct file_lists *next;
        char *name;
@@ -6768,6 +6976,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.
  */
@@ -6794,45 +7022,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);
@@ -6896,7 +7130,7 @@ static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
 {
        TALLOC_FREE(Globals.szNetbiosAliases);
-       Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
+       Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
        return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
 }
 
@@ -6909,12 +7143,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));
@@ -6930,8 +7174,11 @@ static bool handle_include(int snum, const char *pszParmValue, char **ptr)
 
        string_set(ptr, fname);
 
-       if (file_exist(fname, NULL)) {
-               bool ret = pm_process(fname, do_section, do_parameter, NULL);
+       if (file_exist(fname)) {
+               bool ret;
+               include_depth++;
+               ret = pm_process(fname, do_section, do_parameter, NULL);
+               include_depth--;
                SAFE_FREE(fname);
                return ret;
        }
@@ -7191,14 +7438,24 @@ static void init_copymap(struct service *pservice)
                        bitmap_set(pservice->copymap, i);
 }
 
+/***************************************************************************
+ Return the local pointer to a parameter given a service struct and the
+ pointer into the default structure.
+***************************************************************************/
+
+static void *lp_local_ptr(struct service *service, void *ptr)
+{
+       return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
+}
+
 /***************************************************************************
  Return the local pointer to a parameter given the service number and the 
  pointer into the default structure.
 ***************************************************************************/
 
-void *lp_local_ptr(int snum, void *ptr)
+void *lp_local_ptr_by_snum(int snum, void *ptr)
 {
-       return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
+       return lp_local_ptr(ServicePtrs[snum], ptr);
 }
 
 /***************************************************************************
@@ -7250,7 +7507,7 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                               pszParmName));
                        return (True);
                }
-               parm_ptr = lp_local_ptr(snum, def_ptr);
+               parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
        }
 
        if (snum >= 0) {
@@ -7298,8 +7555,8 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
 
                case P_LIST:
                        TALLOC_FREE(*((char ***)parm_ptr));
-                       *(char ***)parm_ptr = str_list_make(
-                               NULL, pszParmValue, NULL);
+                       *(char ***)parm_ptr = str_list_make_v3(
+                               talloc_autofree_context(), pszParmValue, NULL);
                        break;
 
                case P_STRING:
@@ -7423,7 +7680,7 @@ static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
                        return (*((char *)ptr1) == *((char *)ptr2));
 
                case P_LIST:
-                       return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
+                       return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
 
                case P_STRING:
                case P_USTRING:
@@ -7512,8 +7769,8 @@ static bool is_default(int i)
                return False;
        switch (parm_table[i].type) {
                case P_LIST:
-                       return str_list_compare (parm_table[i].def.lvalue, 
-                                               *(char ***)parm_table[i].ptr);
+                       return str_list_equal((const char **)parm_table[i].def.lvalue, 
+                                               *(const char ***)parm_table[i].ptr);
                case P_STRING:
                case P_USTRING:
                        return strequal(parm_table[i].def.svalue,
@@ -7549,6 +7806,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))
@@ -7595,6 +7853,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))) 
@@ -7671,6 +7930,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 != '-') &&
@@ -7927,9 +8187,8 @@ static void lp_save_defaults(void)
                        continue;
                switch (parm_table[i].type) {
                        case P_LIST:
-                               str_list_copy(
-                                       NULL, &(parm_table[i].def.lvalue),
-                                       *(const char ***)parm_table[i].ptr);
+                               parm_table[i].def.lvalue = str_list_copy(
+                                       NULL, *(const char ***)parm_table[i].ptr);
                                break;
                        case P_STRING:
                        case P_USTRING:
@@ -8067,29 +8326,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;
        }
 
@@ -8248,7 +8508,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;
@@ -8260,7 +8520,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;
                }
        }
@@ -8338,7 +8598,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 ));
@@ -8371,7 +8633,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 ));
@@ -8386,12 +8648,12 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
                return -1;
        }
 
-       lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
+       lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
 
        close(fd);
        if (lines == NULL) {
                DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
-                       fname, (unsigned int)sbuf.st_uid ));
+                       fname, (unsigned int)sbuf.st_ex_uid ));
                SAFE_FREE(fname);
                return -1;
        }
@@ -8401,7 +8663,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        /* Should we allow printers to be shared... ? */
        ctx = talloc_init("usershare_sd_xctx");
        if (!ctx) {
-               file_lines_free(lines);
+               TALLOC_FREE(lines);
                return 1;
        }
 
@@ -8409,11 +8671,11 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
                        iService, lines, numlines, &sharepath,
                        &comment, &psd, &guest_ok) != USERSHARE_OK) {
                talloc_destroy(ctx);
-               file_lines_free(lines);
+               TALLOC_FREE(lines);
                return -1;
        }
 
-       file_lines_free(lines);
+       TALLOC_FREE(lines);
 
        /* Everything ok - add the service possibly using a template. */
        if (iService < 0) {
@@ -8455,7 +8717,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);
 
@@ -8468,7 +8730,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;
@@ -8485,13 +8747,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;
 }
 
@@ -8516,7 +8778,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;
@@ -8528,9 +8790,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",
@@ -8599,9 +8861,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",
@@ -8726,21 +8988,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 */
 
@@ -8804,6 +9054,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();
@@ -9012,7 +9264,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. */
@@ -9024,7 +9276,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. */
@@ -9384,10 +9637,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 )
@@ -9414,15 +9663,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;
+               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);
 }
 
 /*******************************************************************
@@ -9506,3 +9760,18 @@ int lp_min_receive_file_size(void)
        }
        return MIN(Globals.iminreceivefile, BUFFER_SIZE);
 }
+
+/*******************************************************************
+ If socket address is an empty character string, it is necessary to 
+ define it as "0.0.0.0". 
+********************************************************************/
+
+const char *lp_socket_address(void)
+{
+       char *sock_addr = Globals.szSocketAddress;
+       
+       if (sock_addr[0] == '\0'){
+               string_set(&Globals.szSocketAddress, "0.0.0.0");
+       }
+       return  Globals.szSocketAddress;
+}