docs-xml: deprecate "client schannel" and change the default to "yes"
[samba.git] / source3 / param / loadparm.c
index a2b827d12b2c993a6dc4f5052381f1d741fa39f1..9f79f132def3d087292f6294cd6779a86207cf24 100644 (file)
 #include "dbwrap/dbwrap_rbt.h"
 #include "../lib/util/bitmap.h"
 #include "librpc/gen_ndr/nbt.h"
+#include "source4/lib/tls/tls.h"
+#include "libcli/auth/ntlm_check.h"
 
 #ifdef HAVE_SYS_SYSCTL_H
 #include <sys/sysctl.h>
 #endif
 
-#ifdef HAVE_HTTPCONNECTENCRYPT
-#include <cups/http.h>
-#endif
-
 bool bLoaded = false;
 
 extern userdom_struct current_user_info;
@@ -97,8 +95,11 @@ static struct smbconf_csn conf_last_csn;
 static int config_backend = CONFIG_BACKEND_FILE;
 
 /* some helpful bits */
-#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
-#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
+#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \
+                       (ServicePtrs != NULL) && \
+                      (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid)
+#define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \
+                  ServicePtrs[i]->valid)
 
 #define USERSHARE_VALID 1
 #define USERSHARE_PENDING_DELETE 2
@@ -110,7 +111,7 @@ static bool defaults_saved = false;
 static struct loadparm_global Globals;
 
 /* This is a default service used to prime a services structure */
-static struct loadparm_service sDefault =
+static const struct loadparm_service _sDefault =
 {
        .valid = true,
        .autoloaded = false,
@@ -118,12 +119,11 @@ static struct loadparm_service sDefault =
        .usershare_last_mod = {0, 0},
        .szService = NULL,
        .path = NULL,
-       .username = NULL,
        .invalid_users = NULL,
        .valid_users = NULL,
        .admin_users = NULL,
-       .szCopy = NULL,
-       .szInclude = NULL,
+       .copy = NULL,
+       .include = NULL,
        .preexec = NULL,
        .postexec = NULL,
        .root_preexec = NULL,
@@ -168,7 +168,6 @@ static struct loadparm_service sDefault =
        .max_connections = 0,
        .default_case = CASE_LOWER,
        .printing = DEFAULT_PRINTING,
-       .oplock_contention_limit = 2,
        .csc_policy = 0,
        .block_size = 1024,
        .dfree_cache_time = 0,
@@ -183,7 +182,7 @@ static struct loadparm_service sDefault =
        .hide_unwriteable_files = false,
        .browseable = true,
        .access_based_share_enum = false,
-       .bAvailable = true,
+       .available = true,
        .read_only = true,
        .spotlight = false,
        .guest_only = false,
@@ -202,14 +201,13 @@ static struct loadparm_service sDefault =
        .oplocks = true,
        .kernel_oplocks = false,
        .level2_oplocks = true,
-       .only_user = false,
-       .mangled_names = true,
+       .mangled_names = MANGLED_NAMES_YES,
        .wide_links = false,
        .follow_symlinks = true,
        .sync_always = false,
        .strict_allocate = false,
        .strict_rename = false,
-       .strict_sync = false,
+       .strict_sync = true,
        .mangling_char = '~',
        .copymap = NULL,
        .delete_readonly = false,
@@ -231,7 +229,6 @@ static struct loadparm_service sDefault =
        .nt_acl_support = true,
        .force_unknown_acl_user = false,
        ._use_sendfile = false,
-       .profile_acls = false,
        .map_acl_inherit = false,
        .afs_share = false,
        .ea_support = false,
@@ -240,8 +237,8 @@ static struct loadparm_service sDefault =
        .acl_group_control = false,
        .acl_allow_execute_always = false,
        .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
-       .aio_read_size = 0,
-       .aio_write_size = 0,
+       .aio_read_size = 1,
+       .aio_write_size = 1,
        .map_readonly = MAP_READONLY_YES,
        .directory_name_cache_size = 100,
        .smb_encrypt = SMB_SIGNING_DEFAULT,
@@ -251,6 +248,12 @@ static struct loadparm_service sDefault =
        .dummy = ""
 };
 
+/*
+ * This is a copy of the default service structure. Service options in the
+ * global section would otherwise overwrite the initial default values.
+ */
+static struct loadparm_service sDefault;
+
 /* local variables */
 static struct loadparm_service **ServicePtrs = NULL;
 static int iNumServices = 0;
@@ -266,44 +269,6 @@ static void set_allowed_client_auth(void);
 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
 static void free_param_opts(struct parmlist_entry **popts);
 
-/* this is used to prevent lots of mallocs of size 1 */
-static const char null_string[] = "";
-
-/**
- Free a string value.
-**/
-
-static void string_free(char **s)
-{
-       if (!s || !(*s))
-               return;
-       if (*s == null_string)
-               *s = NULL;
-       TALLOC_FREE(*s);
-}
-
-/**
- Set a string value, deallocating any existing space, and allocing the space
- for the string
-**/
-
-static bool string_set(TALLOC_CTX *mem_ctx, char **dest,const char *src)
-{
-       string_free(dest);
-
-       if (!src) {
-               src = "";
-       }
-
-       (*dest) = talloc_strdup(mem_ctx, src);
-       if ((*dest) == NULL) {
-               DEBUG(0,("Out of memory in string_init\n"));
-               return false;
-       }
-
-       return true;
-}
-
 /**
  *  Function to return the default value for the maximum number of open
  *  file descriptors permitted.  This function tries to consult the
@@ -367,7 +332,7 @@ static void free_one_parameter_common(void *parm_ptr,
        if ((parm.type == P_STRING) ||
            (parm.type == P_USTRING))
        {
-               string_free((char**)parm_ptr);
+               lpcfg_string_free((char**)parm_ptr);
        } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
                TALLOC_FREE(*((char***)parm_ptr));
        }
@@ -441,8 +406,25 @@ static void free_parameters_by_snum(int snum)
  */
 static void free_global_parameters(void)
 {
+       uint32_t i;
+       struct parm_struct *parm;
+
        free_param_opts(&Globals.param_opt);
        free_parameters_by_snum(GLOBAL_SECTION_SNUM);
+
+       /* Reset references in the defaults because the context is going to be freed */
+       for (i=0; parm_table[i].label; i++) {
+               parm = &parm_table[i];
+               if ((parm->type == P_STRING) ||
+                   (parm->type == P_USTRING)) {
+                       if ((parm->def.svalue != NULL) &&
+                           (*(parm->def.svalue) != '\0')) {
+                               if (talloc_parent(parm->def.svalue) == Globals.ctx) {
+                                       parm->def.svalue = NULL;
+                               }
+                       }
+               }
+       }
        TALLOC_FREE(Globals.ctx);
 }
 
@@ -488,7 +470,7 @@ bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
                return false;
        }
 
-       DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
+       DLIST_ADD_END(stored_options, entry);
 
        return true;
 }
@@ -524,10 +506,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        if (!done_init) {
                /* The logfile can be set before this is invoked. Free it if so. */
-               if (Globals.logfile != NULL) {
-                       string_free(&Globals.logfile);
-                       Globals.logfile = NULL;
-               }
+               lpcfg_string_free(&Globals.logfile);
                done_init = true;
        } else {
                free_global_parameters();
@@ -550,13 +529,16 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
                if ((parm_table[i].type == P_STRING ||
                     parm_table[i].type == P_USTRING))
                {
-                       string_set(Globals.ctx, (char **)lp_parm_ptr(NULL, &parm_table[i]), "");
+                       lpcfg_string_set(
+                               Globals.ctx,
+                               (char **)lp_parm_ptr(NULL, &parm_table[i]),
+                               "");
                }
        }
 
 
-       string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
-       string_set(Globals.ctx, &sDefault.printjob_username, "%U");
+       lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
+       lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
 
        init_printer_values(lp_ctx, Globals.ctx, &sDefault);
 
@@ -565,36 +547,49 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        DEBUG(3, ("Initialising global parameters\n"));
 
        /* Must manually force to upper case here, as this does not go via the handler */
-       string_set(Globals.ctx, &Globals.netbios_name, myhostname_upper());
+       lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
+                        myhostname_upper());
 
-       string_set(Globals.ctx, &Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
-       string_set(Globals.ctx, &Globals.private_dir, get_dyn_PRIVATE_DIR());
+       lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
+                        get_dyn_SMB_PASSWD_FILE());
+       lpcfg_string_set(Globals.ctx, &Globals.private_dir,
+                        get_dyn_PRIVATE_DIR());
+       lpcfg_string_set(Globals.ctx, &Globals.binddns_dir,
+                        get_dyn_BINDDNS_DIR());
 
        /* use the new 'hash2' method by default, with a prefix of 1 */
-       string_set(Globals.ctx, &Globals.mangling_method, "hash2");
+       lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
        Globals.mangle_prefix = 1;
 
-       string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
+       lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
 
        /* using UTF8 by default allows us to support all chars */
-       string_set(Globals.ctx, &Globals.unix_charset, DEFAULT_UNIX_CHARSET);
+       lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
+                        DEFAULT_UNIX_CHARSET);
 
        /* Use codepage 850 as a default for the dos character set */
-       string_set(Globals.ctx, &Globals.dos_charset, DEFAULT_DOS_CHARSET);
+       lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
+                        DEFAULT_DOS_CHARSET);
 
        /*
         * Allow the default PASSWD_CHAT to be overridden in local.h.
         */
-       string_set(Globals.ctx, &Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
-
-       string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
-
-       string_set(Globals.ctx, &Globals.passwd_program, "");
-       string_set(Globals.ctx, &Globals.lock_directory, get_dyn_LOCKDIR());
-       string_set(Globals.ctx, &Globals.state_directory, get_dyn_STATEDIR());
-       string_set(Globals.ctx, &Globals.cache_directory, get_dyn_CACHEDIR());
-       string_set(Globals.ctx, &Globals.pid_directory, get_dyn_PIDDIR());
-       string_set(Globals.ctx, &Globals.nbt_client_socket_address, "0.0.0.0");
+       lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
+                        DEFAULT_PASSWD_CHAT);
+
+       lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
+
+       lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
+       lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
+                        get_dyn_LOCKDIR());
+       lpcfg_string_set(Globals.ctx, &Globals.state_directory,
+                        get_dyn_STATEDIR());
+       lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
+                        get_dyn_CACHEDIR());
+       lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
+                        get_dyn_PIDDIR());
+       lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
+                        "0.0.0.0");
        /*
         * By default support explicit binding to broadcast
         * addresses.
@@ -605,21 +600,27 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        if (s == NULL) {
                smb_panic("init_globals: ENOMEM");
        }
-       string_set(Globals.ctx, &Globals.server_string, s);
+       lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
        TALLOC_FREE(s);
 #ifdef DEVELOPER
-       string_set(Globals.ctx, &Globals.panic_action, "/bin/sleep 999999999");
+       lpcfg_string_set(Globals.ctx, &Globals.panic_action,
+                        "/bin/sleep 999999999");
 #endif
 
-       string_set(Globals.ctx, &Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
+       lpcfg_string_set(Globals.ctx, &Globals.socket_options,
+                        DEFAULT_SOCKET_OPTIONS);
 
-       string_set(Globals.ctx, &Globals.logon_drive, "");
+       lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
        /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
-       string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
-       string_set(Globals.ctx, &Globals.logon_path, "\\\\%N\\%U\\profile");
+       lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
+       lpcfg_string_set(Globals.ctx, &Globals.logon_path,
+                        "\\\\%N\\%U\\profile");
 
-       Globals.name_resolve_order = str_list_make_v3_const(NULL, "lmhosts wins host bcast", NULL);
-       string_set(Globals.ctx, &Globals.password_server, "*");
+       Globals.name_resolve_order =
+                       str_list_make_v3_const(Globals.ctx,
+                                              DEFAULT_NAME_RESOLVE_ORDER,
+                                              NULL);
+       lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
 
        Globals.algorithmic_rid_base = BASE_RID;
 
@@ -646,9 +647,11 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.server_min_protocol = PROTOCOL_LANMAN1;
        Globals._client_max_protocol = PROTOCOL_DEFAULT;
        Globals.client_min_protocol = PROTOCOL_CORE;
+       Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT;
+       Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT;
        Globals._security = SEC_AUTO;
        Globals.encrypt_passwords = true;
-       Globals.client_schannel = Auto;
+       Globals.client_schannel = true;
        Globals.winbind_sealed_pipes = true;
        Globals.require_strong_key = true;
        Globals.server_schannel = Auto;
@@ -660,7 +663,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.syslog = 1;
        Globals.syslog_only = false;
        Globals.timestamp_logs = true;
-       string_set(Globals.ctx, &Globals.log_level, "0");
+       lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
        Globals.debug_prefix_timestamp = false;
        Globals.debug_hires_timestamp = true;
        Globals.debug_pid = false;
@@ -676,9 +679,10 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
        Globals.nis_homedir = false;
 #ifdef WITH_NISPLUS_HOME
-       string_set(Globals.ctx, &Globals.homedir_map, "auto_home.org_dir");
+       lpcfg_string_set(Globals.ctx, &Globals.homedir_map,
+                        "auto_home.org_dir");
 #else
-       string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
+       lpcfg_string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
 #endif
 #endif
        Globals.time_server = false;
@@ -695,11 +699,14 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.restrict_anonymous = 0;
        Globals.client_lanman_auth = false;     /* Do NOT use the LanMan hash if it is available */
        Globals.client_plaintext_auth = false;  /* Do NOT use a plaintext password even if is requested by the server */
-       Globals.lanman_auth = false;    /* Do NOT use the LanMan hash, even if it is supplied */
-       Globals.ntlm_auth = true;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
+       Globals._lanman_auth = false;   /* Do NOT use the LanMan hash, even if it is supplied */
+       Globals.ntlm_auth = NTLM_AUTH_NTLMV2_ONLY;      /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
+       Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */
        Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
        /* Note, that we will also use NTLM2 session security (which is different), if it is available */
 
+       Globals.allow_dcerpc_auth_level_connect = false; /* we don't allow this by default */
+
        Globals.map_to_guest = 0;       /* By Default, "Never" */
        Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
        Globals.enhanced_browsing = true;
@@ -714,7 +721,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.reset_on_zero_vc = false;
        Globals.log_writeable_files_on_exit = false;
        Globals.create_krb5_conf = true;
-       Globals.winbindMaxDomainConnections = 1;
+       Globals.include_system_krb5_conf = true;
+       Globals._winbind_max_domain_connections = 1;
 
        /* hostname lookups can be very expensive and are broken on
           a large number of sites (tridge) */
@@ -723,14 +731,14 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.change_notify = true,
        Globals.kernel_change_notify = true,
 
-       string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
-       string_set(Globals.ctx, &Globals.ldap_suffix, "");
-       string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
-       string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
-       string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
-       string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
+       lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
+       lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
+       lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
+       lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
+       lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
+       lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
 
-       string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
+       lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
        Globals.ldap_ssl = LDAP_SSL_START_TLS;
        Globals.ldap_ssl_ads = false;
        Globals.ldap_deref = -1;
@@ -747,6 +755,9 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
 
+       Globals.ldap_server_require_strong_auth =
+               LDAP_SERVER_REQUIRE_STRONG_AUTH_YES;
+
        /* This is what we tell the afs client. in reality we set the token 
         * to never expire, though, when this runs out the afs client will 
         * forget the token. Set to 0 to get NEVERDATE.*/
@@ -780,17 +791,19 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.wins_dns_proxy = true;
 
        Globals.allow_trusted_domains = true;
-       string_set(Globals.ctx, &Globals.szIdmapBackend, "tdb");
+       lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
 
-       string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
-       string_set(Globals.ctx, &Globals.template_homedir, "/home/%D/%U");
-       string_set(Globals.ctx, &Globals.winbind_separator, "\\");
-       string_set(Globals.ctx, &Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
+       lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
+       lpcfg_string_set(Globals.ctx, &Globals.template_homedir,
+                        "/home/%D/%U");
+       lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
+       lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory,
+                        dyn_WINBINDD_SOCKET_DIR);
 
-       string_set(Globals.ctx, &Globals.cups_server, "");
-       string_set(Globals.ctx, &Globals.iprint_server, "");
+       lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
+       lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
 
-       string_set(Globals.ctx, &Globals._ctdbd_socket, "");
+       lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
 
        Globals.cluster_addresses = NULL;
        Globals.clustering = false;
@@ -804,7 +817,6 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.winbind_enum_users = false;
        Globals.winbind_enum_groups = false;
        Globals.winbind_use_default_domain = false;
-       Globals.winbind_trusted_domains_only = false;
        Globals.winbind_nested_groups = true;
        Globals.winbind_expand_groups = 0;
        Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
@@ -818,10 +830,10 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        Globals.name_cache_timeout = 660; /* In seconds */
 
-       Globals.use_spnego = true;
        Globals.client_use_spnego = true;
 
        Globals.client_signing = SMB_SIGNING_DEFAULT;
+       Globals._client_ipc_signing = SMB_SIGNING_DEFAULT;
        Globals.server_signing = SMB_SIGNING_DEFAULT;
 
        Globals.defer_sharing_violations = true;
@@ -836,9 +848,9 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        if (s == NULL) {
                smb_panic("init_globals: ENOMEM");
        }
-       string_set(Globals.ctx, &Globals.usershare_path, s);
+       lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
        TALLOC_FREE(s);
-       string_set(Globals.ctx, &Globals.usershare_template_share, "");
+       lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
        Globals.usershare_max_shares = 0;
        /* By default disallow sharing of directories not owned by the sharer. */
        Globals.usershare_owner_only = true;
@@ -852,37 +864,38 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        Globals.min_receivefile_size = 0;
 
-       Globals.map_untrusted_to_domain = false;
        Globals.multicast_dns_register = true;
 
        Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
        Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
        Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
        Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
-       Globals.smb2_leases = false;
+       Globals.smb2_leases = true;
 
-       string_set(Globals.ctx, &Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
+       lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
+                        get_dyn_NCALRPCDIR());
 
        Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
 
-       Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
+       Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
 
        Globals.tls_enabled = true;
+       Globals.tls_verify_peer = TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE;
 
-       string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
-       string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
-       string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
-       string_set(Globals.ctx, &Globals.tls_priority, "NORMAL:-VERS-SSL3.0");
+       lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
+       lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
+       lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
+       lpcfg_string_set(Globals.ctx, &Globals.tls_priority,
+                        "NORMAL:-VERS-SSL3.0");
 
-       string_set(Globals.ctx, &Globals.share_backend, "classic");
+       lpcfg_string_set(Globals.ctx, &Globals.share_backend, "classic");
 
        Globals._preferred_master = Auto;
 
        Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
 
-       string_set(Globals.ctx, &Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
-
-       string_set(Globals.ctx, &Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
+       lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
+                        get_dyn_NTP_SIGND_SOCKET_DIR());
 
        s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
        if (s == NULL) {
@@ -891,6 +904,10 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
        TALLOC_FREE(s);
 
+#ifdef MIT_KDC_PATH
+       Globals.mit_kdc_command = str_list_make_v3_const(NULL, MIT_KDC_PATH, NULL);
+#endif
+
        s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
        if (s == NULL) {
                smb_panic("init_globals: ENOMEM");
@@ -898,6 +915,13 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
        TALLOC_FREE(s);
 
+       s = talloc_asprintf(talloc_tos(), "%s/samba_gpoupdate", get_dyn_SCRIPTSBINDIR());
+       if (s == NULL) {
+               smb_panic("init_globals: ENOMEM");
+       }
+       Globals.gpo_update_command = str_list_make_v3_const(NULL, s, NULL);
+       TALLOC_FREE(s);
+
        s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
        if (s == NULL) {
                smb_panic("init_globals: ENOMEM");
@@ -921,6 +945,15 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        Globals.web_port = 901;
 
+       Globals.aio_max_threads = 100;
+
+       lpcfg_string_set(Globals.ctx,
+                        &Globals.rpc_server_dynamic_port_range,
+                        "49152-65535");
+       Globals.rpc_low_port = SERVER_TCP_LOW_PORT;
+       Globals.rpc_high_port = SERVER_TCP_HIGH_PORT;
+       Globals.prefork_children = 1;
+
        /* Now put back the settings that were set with lp_set_cmdline() */
        apply_lp_set_cmdline();
 }
@@ -937,7 +970,14 @@ static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
                return NULL;
        }
 
-       lp_ctx->sDefault = &sDefault;
+       lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
+       if (lp_ctx->sDefault == NULL) {
+               DBG_ERR("talloc_zero failed\n");
+               TALLOC_FREE(lp_ctx);
+               return NULL;
+       }
+
+       *lp_ctx->sDefault = _sDefault;
        lp_ctx->services = NULL; /* We do not want to access this directly */
        lp_ctx->bInGlobalSection = bInGlobalSection;
        lp_ctx->flags = flags_list;
@@ -1019,37 +1059,15 @@ char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK
 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
  char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
 
-static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
-                 winbindMaxDomainConnections)
-
 int lp_winbind_max_domain_connections(void)
 {
        if (lp_winbind_offline_logon() &&
-           lp_winbind_max_domain_connections_int() > 1) {
+           lp__winbind_max_domain_connections() > 1) {
                DEBUG(1, ("offline logons active, restricting max domain "
                          "connections to 1\n"));
                return 1;
        }
-       return MAX(1, lp_winbind_max_domain_connections_int());
-}
-
-int lp_cups_encrypt(void)
-{
-       int result = 0;
-#ifdef HAVE_HTTPCONNECTENCRYPT
-       switch (Globals.CupsEncrypt) {
-               case Auto:
-                       result = HTTP_ENCRYPT_REQUIRED;
-                       break;
-               case true:
-                       result = HTTP_ENCRYPT_ALWAYS;
-                       break;
-               case false:
-                       result = HTTP_ENCRYPT_NEVER;
-                       break;
-       }
-#endif
-       return result;
+       return MAX(1, lp__winbind_max_domain_connections());
 }
 
 /* These functions remain in source3/param for now */
@@ -1073,6 +1091,7 @@ static bool hash_a_service(const char *name, int number);
 static void free_service_byindex(int iService);
 static void show_parameter(int parmIndex);
 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
+static bool lp_parameter_value_is_valid(const char *parm_name, const char *val);
 
 /*
  * This is a helper function for parametrical options support.  It returns a
@@ -1092,6 +1111,79 @@ static struct parmlist_entry *get_parametrics(int snum, const char *type,
        }
 }
 
+static void discard_whitespace(char *str)
+{
+       size_t len = strlen(str);
+       size_t i = 0;
+
+       while (i < len) {
+               if (isspace(str[i])) {
+                       memmove(&str[i], &str[i+1], len-i);
+                       len -= 1;
+                       continue;
+               }
+               i += 1;
+       }
+}
+
+/**
+ * @brief Go through all global parametric parameters
+ *
+ * @param regex_str    A regular expression to scan param for
+ * @param max_matches   Max number of submatches the regexp expects
+ * @param cb           Function to call on match. Should return true
+ *                      when it wants wi_scan_global_parametrics to stop
+ *                      scanning
+ * @param private_data  Anonymous pointer passed to cb
+ *
+ * @return              0: success, regcomp/regexec return value on error.
+ *                      See "man regexec" for possible errors
+ */
+
+int lp_wi_scan_global_parametrics(
+       const char *regex_str, size_t max_matches,
+       bool (*cb)(const char *string, regmatch_t matches[],
+                  void *private_data),
+       void *private_data)
+{
+       struct parmlist_entry *data;
+       regex_t regex;
+       int ret;
+
+       ret = regcomp(&regex, regex_str, REG_ICASE);
+       if (ret != 0) {
+               return ret;
+       }
+
+       for (data = Globals.param_opt; data != NULL; data = data->next) {
+               size_t keylen = strlen(data->key);
+               char key[keylen+1];
+               regmatch_t matches[max_matches];
+               bool stop;
+
+               memcpy(key, data->key, sizeof(key));
+               discard_whitespace(key);
+
+               ret = regexec(&regex, key, max_matches, matches, 0);
+               if (ret == REG_NOMATCH) {
+                       continue;
+               }
+               if (ret != 0) {
+                       goto fail;
+               }
+
+               stop = cb(key, matches, private_data);
+               if (stop) {
+                       break;
+               }
+       }
+
+       ret = 0;
+fail:
+       regfree(&regex);
+       return ret;
+}
+
 
 #define MISSING_PARAMETER(name) \
     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
@@ -1195,6 +1287,22 @@ unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsi
 /* Return parametric option from a given service. Type is a part of option before ':' */
 /* Parametric option has following syntax: 'Type: option = value' */
 
+unsigned long long lp_parm_ulonglong(int snum, const char *type,
+                                    const char *option, unsigned long long def)
+{
+       struct parmlist_entry *data = get_parametrics(snum, type, option);
+
+       if (data && data->value && *data->value) {
+               return lp_ulonglong(data->value);
+       }
+
+       return def;
+}
+
+/* Return parametric option from a given service. Type is a part of option
+ * before ':' */
+/* Parametric option has following syntax: 'Type: option = value' */
+
 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
 {
        struct parmlist_entry *data = get_parametrics(snum, type, option);
@@ -1234,8 +1342,8 @@ static void free_param_opts(struct parmlist_entry **popts)
        }
        opt = *popts;
        while (opt != NULL) {
-               string_free(&opt->key);
-               string_free(&opt->value);
+               lpcfg_string_free(&opt->key);
+               lpcfg_string_free(&opt->value);
                TALLOC_FREE(opt->list);
                next_opt = opt->next;
                TALLOC_FREE(opt);
@@ -1259,7 +1367,7 @@ static void free_service(struct loadparm_service *pservice)
 
        free_parameters(pservice);
 
-       string_free(&pservice->szService);
+       lpcfg_string_free(&pservice->szService);
        TALLOC_FREE(pservice->copymap);
 
        free_param_opts(&pservice->param_opt);
@@ -1292,7 +1400,7 @@ static void free_service_byindex(int idx)
        }
 
        free_service(ServicePtrs[idx]);
-       talloc_free_children(ServicePtrs[idx]);
+       TALLOC_FREE(ServicePtrs[idx]);
 }
 
 /***************************************************************************
@@ -1303,7 +1411,6 @@ static void free_service_byindex(int idx)
 static int add_a_service(const struct loadparm_service *pservice, const char *name)
 {
        int i;
-       int num_to_alloc = iNumServices + 1;
        struct loadparm_service **tsp = NULL;
 
        /* it might already exist */
@@ -1314,26 +1421,37 @@ static int add_a_service(const struct loadparm_service *pservice, const char *na
                }
        }
 
-       /* if not, then create one */
-       i = iNumServices;
-       tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
-       if (tsp == NULL) {
-               DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
-               return (-1);
+       /* Re use empty slots if any before allocating new one.*/
+       for (i=0; i < iNumServices; i++) {
+               if (ServicePtrs[i] == NULL) {
+                       break;
+               }
        }
-       ServicePtrs = tsp;
-       ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service);
-       if (!ServicePtrs[iNumServices]) {
+       if (i == iNumServices) {
+               /* if not, then create one */
+               tsp = talloc_realloc(NULL, ServicePtrs,
+                                    struct loadparm_service *,
+                                    iNumServices + 1);
+               if (tsp == NULL) {
+                       DEBUG(0, ("add_a_service: failed to enlarge "
+                                 "ServicePtrs!\n"));
+                       return (-1);
+               }
+               ServicePtrs = tsp;
+               iNumServices++;
+       }
+       ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service);
+       if (!ServicePtrs[i]) {
                DEBUG(0,("add_a_service: out of memory!\n"));
                return (-1);
        }
-       iNumServices++;
 
        ServicePtrs[i]->valid = true;
 
        copy_service(ServicePtrs[i], pservice, NULL);
        if (name)
-               string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name);
+               lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
+                                name);
 
        DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
                i, ServicePtrs[i]->szService));
@@ -1422,7 +1540,8 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
        if (!(*(ServicePtrs[iDefaultService]->path))
            || strequal(ServicePtrs[iDefaultService]->path,
                        lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
-               string_set(ServicePtrs[i], &ServicePtrs[i]->path, pszHomedir);
+               lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
+                                pszHomedir);
        }
 
        if (!(*(ServicePtrs[i]->comment))) {
@@ -1430,7 +1549,8 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
                if (comment == NULL) {
                        return false;
                }
-               string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
+               lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
+                                comment);
                TALLOC_FREE(comment);
        }
 
@@ -1478,18 +1598,18 @@ static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
                return false;
        }
 
-       string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
-       string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
-       string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
-       string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
+       lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
+       lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
+       lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
        ServicePtrs[i]->max_connections = 0;
-       ServicePtrs[i]->bAvailable = true;
+       ServicePtrs[i]->available = true;
        ServicePtrs[i]->read_only = true;
        ServicePtrs[i]->guest_only = false;
        ServicePtrs[i]->administrative_share = true;
        ServicePtrs[i]->guest_ok = guest_ok;
        ServicePtrs[i]->printable = false;
        ServicePtrs[i]->browseable = sDefault.browseable;
+       ServicePtrs[i]->autoloaded = false;
 
        DEBUG(3, ("adding IPC service\n"));
 
@@ -1515,8 +1635,9 @@ bool lp_add_printer(const char *pszPrintername, int iDefaultService)
        /* entry (if/when the 'available' keyword is implemented!).    */
 
        /* the printer name is set to the service name. */
-       string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, pszPrintername);
-       string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
+       lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
+                        pszPrintername);
+       lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
 
        /* set the browseable flag from the gloabl default */
        ServicePtrs[i]->browseable = sDefault.browseable;
@@ -1596,9 +1717,11 @@ bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
  Turn the value given into the inverse boolean expression when
  the synonym is an invers boolean synonym.
 
- Return true if parm_name is a valid parameter name and
- in case it is an invers boolean synonym, if the val string could
- successfully be converted to the reverse bool.
+ Return true if
+ - parm_name is a valid parameter name and
+ - val is a valid value for this parameter and
+ - in case the parameter is an inverse boolean synonym, if the val
+   string could successfully be converted to the reverse bool.
  Return false in all other cases.
 **************************************************************************/
 
@@ -1609,6 +1732,7 @@ bool lp_canonicalize_parameter_with_value(const char *parm_name,
 {
        int num;
        bool inverse;
+       bool ret;
 
        if (!lp_parameter_is_valid(parm_name)) {
                *canon_parm = NULL;
@@ -1621,19 +1745,22 @@ bool lp_canonicalize_parameter_with_value(const char *parm_name,
                /* parametric option */
                *canon_parm = parm_name;
                *canon_val = val;
-       } else {
-               *canon_parm = parm_table[num].label;
-               if (inverse) {
-                       if (!lp_invert_boolean(val, canon_val)) {
-                               *canon_val = NULL;
-                               return false;
-                       }
-               } else {
-                       *canon_val = val;
+               return true;
+       }
+
+       *canon_parm = parm_table[num].label;
+       if (inverse) {
+               if (!lp_invert_boolean(val, canon_val)) {
+                       *canon_val = NULL;
+                       return false;
                }
+       } else {
+               *canon_val = val;
        }
 
-       return true;
+       ret = lp_parameter_value_is_valid(*canon_parm, *canon_val);
+
+       return ret;
 }
 
 /***************************************************************************
@@ -1761,6 +1888,77 @@ static void show_parameter(int parmIndex)
        printf("\n");
 }
 
+/*
+ * Check the value for a P_ENUM
+ */
+static bool check_enum_parameter(struct parm_struct *parm, const char *value)
+{
+       int i;
+
+       for (i = 0; parm->enum_list[i].name; i++) {
+               if (strwicmp(value, parm->enum_list[i].name) == 0) {
+                       return true;
+               }
+       }
+       return false;
+}
+
+/**************************************************************************
+ Check whether the given value is valid for the given parameter name.
+**************************************************************************/
+
+static bool lp_parameter_value_is_valid(const char *parm_name, const char *val)
+{
+       bool ret = false, tmp_bool;
+       int num = lpcfg_map_parameter(parm_name), tmp_int;
+       uint64_t tmp_int64 = 0;
+       struct parm_struct *parm;
+
+       /* parametric options (parameter names containing a colon) cannot
+          be checked and are therefore considered valid. */
+       if (strchr(parm_name, ':') != NULL) {
+               return true;
+       }
+
+       if (num >= 0) {
+               parm = &parm_table[num];
+               switch (parm->type) {
+                       case P_BOOL:
+                       case P_BOOLREV:
+                               ret = set_boolean(val, &tmp_bool);
+                               break;
+
+                       case P_INTEGER:
+                               ret = (sscanf(val, "%d", &tmp_int) == 1);
+                               break;
+
+                       case P_OCTAL:
+                               ret = (sscanf(val, "%o", &tmp_int) == 1);
+                               break;
+
+                       case P_ENUM:
+                               ret = check_enum_parameter(parm, val);
+                               break;
+
+                       case P_BYTES:
+                               if (conv_str_size_error(val, &tmp_int64) &&
+                                   tmp_int64 <= INT_MAX) {
+                                       ret = true;
+                               }
+                               break;
+
+                       case P_CHAR:
+                       case P_LIST:
+                       case P_STRING:
+                       case P_USTRING:
+                       case P_CMDLIST:
+                               ret = true;
+                               break;
+               }
+       }
+       return ret;
+}
+
 /***************************************************************************
  Show all parameter's name, type, [values,] and flags.
 ***************************************************************************/
@@ -1852,7 +2050,7 @@ int getservicebyname(const char *pszServiceName, struct loadparm_service *pservi
            (data.dptr != NULL) &&
            (data.dsize == sizeof(iService)))
        {
-               iService = *(int *)data.dptr;
+               memcpy(&iService, data.dptr, sizeof(iService));
        }
 
        TALLOC_FREE(canon_name);
@@ -2193,9 +2391,14 @@ bool lp_file_list_changed(void)
  **/
 static void init_iconv(void)
 {
-       global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
-                                                     lp_unix_charset(),
-                                                     true, global_iconv_handle);
+       struct smb_iconv_handle *ret = NULL;
+
+       ret = reinit_iconv_handle(NULL,
+                                 lp_dos_charset(),
+                                 lp_unix_charset());
+       if (ret == NULL) {
+               smb_panic("reinit_iconv_handle failed");
+       }
 }
 
 /***************************************************************************
@@ -2238,9 +2441,9 @@ bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *servic
        add_to_file_list(NULL, &file_lists, pszParmValue, fname);
 
        if (service == NULL) {
-               string_set(Globals.ctx, ptr, fname);
+               lpcfg_string_set(Globals.ctx, ptr, fname);
        } else {
-               string_set(service, ptr, fname);
+               lpcfg_string_set(service, ptr, fname);
        }
 
        if (file_exist(fname)) {
@@ -2656,7 +2859,7 @@ static void dump_copy_map(bool *pcopymap)
 
 bool lp_snum_ok(int iService)
 {
-       return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
+       return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available);
 }
 
 /***************************************************************************
@@ -2711,7 +2914,8 @@ void lp_add_one_printer(const char *name, const char *comment,
        if (lp_servicenumber(name) < 0) {
                lp_add_printer(name, printers);
                if ((i = lp_servicenumber(name)) >= 0) {
-                       string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
+                       lpcfg_string_set(ServicePtrs[i],
+                                        &ServicePtrs[i]->comment, comment);
                        ServicePtrs[i]->autoloaded = true;
                }
        }
@@ -2795,9 +2999,13 @@ static void lp_save_defaults(void)
                                break;
                        case P_STRING:
                        case P_USTRING:
-                               parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
+                               lpcfg_string_set(
+                                       Globals.ctx,
+                                       &parm_table[i].def.svalue,
+                                       *(char **)lp_parm_ptr(
+                                               NULL, &parm_table[i]));
                                if (parm_table[i].def.svalue == NULL) {
-                                       smb_panic("talloc_strdup failed");
+                                       smb_panic("lpcfg_string_set() failed");
                                }
                                break;
                        case P_BOOL:
@@ -3273,8 +3481,10 @@ 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_ex_mtime;
-       string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
-       string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
+       lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
+                        sharepath);
+       lpcfg_string_set(ServicePtrs[iService],
+                        &ServicePtrs[iService]->comment, comment);
 
        ret = iService;
 
@@ -3322,6 +3532,19 @@ static bool usershare_exists(int iService, struct timespec *last_mod)
        return true;
 }
 
+static bool usershare_directory_is_root(uid_t uid)
+{
+       if (uid == 0) {
+               return true;
+       }
+
+       if (uid_wrapper_enabled()) {
+               return true;
+       }
+
+       return false;
+}
+
 /***************************************************************************
  Load a usershare service by name. Returns a valid servicenumber or -1.
 ***************************************************************************/
@@ -3355,9 +3578,11 @@ int load_usershare_service(const char *servicename)
         */
 
 #ifdef S_ISVTX
-       if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
+       if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
+           !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
 #else
-       if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
+       if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
+           (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",
@@ -3642,6 +3867,7 @@ static bool lp_load_ex(const char *pszFname,
        bInGlobalSection = true;
        bGlobalOnly = global_only;
        bAllowIncludeRegistry = allow_include_registry;
+       sDefault = _sDefault;
 
        lp_ctx = setup_lp_context(talloc_tos());
 
@@ -3659,7 +3885,7 @@ static bool lp_load_ex(const char *pszFname,
                apply_lp_set_cmdline();
        }
 
-       lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
+       lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend);
 
        /* We get sections first, so have to start 'behind' to make up */
        iServiceIndex = -1;
@@ -3805,6 +4031,9 @@ bool lp_load_initial_only(const char *pszFname)
 
 /**
  * most common lp_load wrapper, loading only the globals
+ *
+ * If this is used in a daemon or client utility it should be called
+ * after processing popt.
  */
 bool lp_load_global(const char *file_name)
 {
@@ -4128,7 +4357,7 @@ const char *lp_printername(TALLOC_CTX *ctx, int snum)
 
 void lp_set_logfile(const char *name)
 {
-       string_set(Globals.ctx, &Globals.logfile, name);
+       lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
        debug_set_logfile(name);
 }
 
@@ -4218,20 +4447,9 @@ void set_use_sendfile(int snum, bool val)
                sDefault._use_sendfile = val;
 }
 
-/*******************************************************************
- Turn off storing DOS attributes if this share doesn't support it.
-********************************************************************/
-
-void set_store_dos_attributes(int snum, bool val)
-{
-       if (!LP_SNUM_OK(snum))
-               return;
-       ServicePtrs[(snum)]->store_dos_attributes = val;
-}
-
 void lp_set_mangling_method(const char *new_method)
 {
-       string_set(Globals.ctx, &Globals.mangling_method, new_method);
+       lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
 }
 
 /*******************************************************************
@@ -4267,7 +4485,8 @@ enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
        if (posix_default_lock_was_set) {
                return posix_cifsx_locktype;
        } else {
-               return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
+               return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
+                       POSIX_LOCK : WINDOWS_LOCK;
        }
 }
 
@@ -4296,19 +4515,13 @@ int lp_min_receive_file_size(void)
  even after a configuration file reload.
 ********************************************************************/
 
-static bool lp_widelinks_internal(int snum)
-{
-       return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->wide_links :
-                       sDefault.wide_links);
-}
-
 void widelinks_warning(int snum)
 {
        if (lp_allow_insecure_wide_links()) {
                return;
        }
 
-       if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
+       if (lp_unix_extensions() && lp_wide_links(snum)) {
                DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
                        "These parameters are incompatible. "
                        "Wide links will be disabled for this share.\n",
@@ -4329,7 +4542,7 @@ bool lp_widelinks(int snum)
                }
        }
 
-       return lp_widelinks_internal(snum);
+       return lp_wide_links(snum);
 }
 
 int lp_server_role(void)
@@ -4350,18 +4563,68 @@ int lp_client_max_protocol(void)
 {
        int client_max_protocol = lp__client_max_protocol();
        if (client_max_protocol == PROTOCOL_DEFAULT) {
-               return PROTOCOL_NT1;
+               return PROTOCOL_LATEST;
        }
        return client_max_protocol;
 }
 
-int lp_winbindd_max_protocol(void)
+int lp_client_ipc_min_protocol(void)
 {
-       int client_max_protocol = lp__client_max_protocol();
-       if (client_max_protocol == PROTOCOL_DEFAULT) {
+       int client_ipc_min_protocol = lp__client_ipc_min_protocol();
+       if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
+               client_ipc_min_protocol = lp_client_min_protocol();
+       }
+       if (client_ipc_min_protocol < PROTOCOL_NT1) {
+               return PROTOCOL_NT1;
+       }
+       return client_ipc_min_protocol;
+}
+
+int lp_client_ipc_max_protocol(void)
+{
+       int client_ipc_max_protocol = lp__client_ipc_max_protocol();
+       if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
                return PROTOCOL_LATEST;
        }
-       return client_max_protocol;
+       if (client_ipc_max_protocol < PROTOCOL_NT1) {
+               return PROTOCOL_NT1;
+       }
+       return client_ipc_max_protocol;
+}
+
+int lp_client_ipc_signing(void)
+{
+       int client_ipc_signing = lp__client_ipc_signing();
+       if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
+               return SMB_SIGNING_REQUIRED;
+       }
+       return client_ipc_signing;
+}
+
+int lp_rpc_low_port(void)
+{
+       return Globals.rpc_low_port;
+}
+
+int lp_rpc_high_port(void)
+{
+       return Globals.rpc_high_port;
+}
+
+/*
+ * Do not allow LanMan auth if unless NTLMv1 is also allowed
+ *
+ * This also ensures it is disabled if NTLM is totally disabled
+ */
+bool lp_lanman_auth(void)
+{
+       enum ntlm_auth_level ntlm_auth_level = lp_ntlm_auth();
+
+       if (ntlm_auth_level == NTLM_AUTH_ON) {
+               return lp__lanman_auth();
+       } else {
+               return false;
+       }
 }
 
 struct loadparm_global * get_globals(void)