lib: Give lib/util/util_file.c its own header file
[samba.git] / source3 / param / loadparm.c
index 31819b3930cce714c26c3ece30c4c66c67bd795e..414d19d7439799c0e8a3246e7356b008baa9d825 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    Parameter loading functions
    Copyright (C) Karl Auer 1993-1998
@@ -41,7 +41,7 @@
  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
  * 4) If it's a global then initialise it in init_globals. If a local
  *    (ie. service) parameter then initialise it in the sDefault structure
- *  
+ *
  *
  * Notes:
  *   The configuration file is processed sequentially for speed. It is NOT
@@ -53,7 +53,9 @@
  *
  */
 
+#define LOADPARM_SUBSTITUTION_INTERNALS 1
 #include "includes.h"
+#include "lib/util/util_file.h"
 #include "system/filesys.h"
 #include "util_tdb.h"
 #include "lib/param/loadparm.h"
@@ -62,7 +64,7 @@
 #include "lib/smbconf/smbconf.h"
 #include "lib/smbconf/smbconf_init.h"
 
-#include "ads.h"
+#include "include/smb_ldap.h"
 #include "../librpc/gen_ndr/svcctl.h"
 #include "intl.h"
 #include "../libcli/smb/smb_signing.h"
 #include "dbwrap/dbwrap_rbt.h"
 #include "../lib/util/bitmap.h"
 #include "librpc/gen_ndr/nbt.h"
+#include "librpc/gen_ndr/dns.h"
 #include "source4/lib/tls/tls.h"
 #include "libcli/auth/ntlm_check.h"
+#include "lib/crypto/gnutls_helpers.h"
+#include "lib/util/string_wrappers.h"
+#include "auth/credentials/credentials.h"
+#include "source3/lib/substitute.h"
+#include "source3/librpc/gen_ndr/ads.h"
+#include "lib/util/time_basic.h"
+#include "libds/common/flags.h"
 
 #ifdef HAVE_SYS_SYSCTL_H
 #include <sys/sysctl.h>
 #endif
 
-bool bLoaded = false;
-
-extern userdom_struct current_user_info;
+bool b_loaded = false;
 
 /* the special value for the include parameter
  * to be interpreted not as a file name but to
@@ -160,7 +168,6 @@ static const struct loadparm_service _sDefault =
        .min_print_space = 0,
        .max_print_jobs = 1000,
        .max_reported_print_jobs = 0,
-       .write_cache_size = 0,
        .create_mask = 0744,
        .force_create_mode = 0,
        .directory_mask = 0755,
@@ -194,6 +201,7 @@ static const struct loadparm_service _sDefault =
        .map_hidden = false,
        .map_archive = true,
        .store_dos_attributes = true,
+       .smbd_max_xattr_size = 65536,
        .dmapi_support = false,
        .locking = true,
        .strict_locking = Auto,
@@ -236,18 +244,20 @@ static const struct loadparm_service _sDefault =
        .acl_map_full_control = true,
        .acl_group_control = false,
        .acl_allow_execute_always = false,
+       .acl_flag_inherited_canonicalization = true,
        .aio_read_size = 1,
        .aio_write_size = 1,
        .map_readonly = MAP_READONLY_NO,
-       .directory_name_cache_size = 100,
-       .smb_encrypt = SMB_SIGNING_DEFAULT,
-       .kernel_share_modes = true,
+       .server_smb_encrypt = SMB_ENCRYPTION_DEFAULT,
+       .kernel_share_modes = false,
        .durable_handles = true,
        .check_parent_directory_delete_on_close = false,
        .param_opt = NULL,
        .smbd_search_ask_sharemode = true,
        .smbd_getinfo_ask_sharemode = true,
-       .spotlight_backend = SPOTLIGHT_BACKEND_TRACKER,
+       .spotlight_backend = SPOTLIGHT_BACKEND_NOINDEX,
+       .honor_change_notify_privilege = false,
+       .volume_serial_number = -1,
        .dummy = ""
 };
 
@@ -495,7 +505,8 @@ static bool apply_lp_set_cmdline(void)
  Initialise the global parameter structure.
 ***************************************************************************/
 
-static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
+void loadparm_s3_init_globals(struct loadparm_context *lp_ctx,
+                             bool reinit_globals)
 {
        static bool done_init = false;
        char *s = NULL;
@@ -545,7 +556,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        init_printer_values(lp_ctx, Globals.ctx, &sDefault);
 
-       sDefault.ntvfs_handler = str_list_make_v3_const(NULL, "unixuid default", NULL);
+       sDefault.ntvfs_handler = str_list_make_v3_const(Globals.ctx, "unixuid default", NULL);
 
        DEBUG(3, ("Initialising global parameters\n"));
 
@@ -599,7 +610,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
         */
        Globals.nmbd_bind_explicit_broadcast = true;
 
-       s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
+       s = talloc_asprintf(Globals.ctx, "Samba %s", samba_version_string());
        if (s == NULL) {
                smb_panic("init_globals: ENOMEM");
        }
@@ -657,7 +668,10 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.client_schannel = true;
        Globals.winbind_sealed_pipes = true;
        Globals.require_strong_key = true;
+       Globals.reject_md5_servers = true;
        Globals.server_schannel = true;
+       Globals.server_schannel_require_seal = true;
+       Globals.reject_md5_clients = true;
        Globals.read_raw = true;
        Globals.write_raw = true;
        Globals.null_passwords = false;
@@ -669,6 +683,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
        Globals.debug_prefix_timestamp = false;
        Globals.debug_hires_timestamp = true;
+       Globals.debug_syslog_format = false;
        Globals.debug_pid = false;
        Globals.debug_uid = false;
        Globals.debug_class = false;
@@ -679,15 +694,6 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
        Globals.lm_announce = Auto;     /* = Auto: send only if LM clients found */
        Globals.lm_interval = 60;
-#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
-       Globals.nis_homedir = false;
-#ifdef WITH_NISPLUS_HOME
-       lpcfg_string_set(Globals.ctx, &Globals.homedir_map,
-                        "auto_home.org_dir");
-#else
-       lpcfg_string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
-#endif
-#endif
        Globals.time_server = false;
        Globals.bind_interfaces_only = false;
        Globals.unix_password_sync = false;
@@ -704,6 +710,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        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 = NTLM_AUTH_NTLMV2_ONLY;      /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
+       Globals.nt_hash_store = NT_HASH_STORE_ALWAYS;   /* Fill in NT hash when setting password */
        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 */
@@ -716,7 +723,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
        Globals.use_mmap = true;
        Globals.unicode = true;
-       Globals.unix_extensions = true;
+       Globals.smb1_unix_extensions = true;
        Globals.reset_on_zero_vc = false;
        Globals.log_writeable_files_on_exit = false;
        Globals.create_krb5_conf = true;
@@ -739,7 +746,6 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        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;
        Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
        Globals.ldap_delete_dn = false;
@@ -752,13 +758,13 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.ldap_debug_level = 0;
        Globals.ldap_debug_threshold = 10;
 
-       Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
+       Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SEAL;
 
        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 
+       /* 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.*/
        Globals.afs_token_lifetime = 604800;
        Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
@@ -788,6 +794,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.init_logon_delay = 100; /* 100 ms default delay */
 
        Globals.wins_dns_proxy = true;
+       Globals.dns_port = DNS_SERVICE_PORT;
 
        Globals.allow_trusted_domains = true;
        lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
@@ -821,7 +828,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
        Globals.winbind_refresh_tickets = false;
        Globals.winbind_offline_logon = false;
-       Globals.winbind_scan_trusted_domains = true;
+       Globals.winbind_scan_trusted_domains = false;
 
        Globals.idmap_cache_time = 86400 * 7; /* a week by default */
        Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
@@ -871,13 +878,14 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
        Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
        Globals.smb2_leases = true;
+       Globals.server_multi_channel_support = true;
 
        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 drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
+       Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc 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;
@@ -885,11 +893,10 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        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,
+       lpcfg_string_set(Globals.ctx,
+                        &Globals.tls_priority,
                         "NORMAL:-VERS-SSL3.0");
 
-       lpcfg_string_set(Globals.ctx, &Globals.share_backend, "classic");
-
        Globals._preferred_master = Auto;
 
        Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
@@ -934,8 +941,6 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
 
-       Globals.rndc_command = str_list_make_v3_const(NULL, "/usr/sbin/rndc", NULL);
-
        Globals.cldap_port = 389;
 
        Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
@@ -946,6 +951,10 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        Globals.kpasswd_port = 464;
 
+       Globals.kdc_enable_fast = true;
+
+       Globals.winbind_debug_traceid = true;
+
        Globals.aio_max_threads = 100;
 
        lpcfg_string_set(Globals.ctx,
@@ -957,6 +966,43 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.prefork_backoff_increment = 10;
        Globals.prefork_maximum_backoff = 120;
 
+       Globals.ldap_max_anonymous_request_size = 256000;
+       Globals.ldap_max_authenticated_request_size = 16777216;
+       Globals.ldap_max_search_request_size = 256000;
+
+       /* Async DNS query timeout (in seconds). */
+       Globals.async_dns_timeout = 10;
+
+       Globals.client_smb_encrypt = SMB_ENCRYPTION_DEFAULT;
+
+       Globals._client_use_kerberos = CRED_USE_KERBEROS_DESIRED;
+
+       Globals.client_protection = CRED_CLIENT_PROTECTION_DEFAULT;
+
+       Globals.winbind_use_krb5_enterprise_principals = true;
+
+       Globals.client_smb3_signing_algorithms =
+               str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
+       Globals.server_smb3_signing_algorithms =
+               str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
+
+       Globals.client_smb3_encryption_algorithms =
+               str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
+       Globals.server_smb3_encryption_algorithms =
+               str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
+
+       Globals.min_domain_uid = 1000;
+
+       /*
+        * By default allow smbd and winbindd to start samba-dcerpcd as
+        * a named-pipe helper.
+        */
+       Globals.rpc_start_on_demand_helpers = true;
+
+       Globals.ad_dc_functional_level = DS_DOMAIN_FUNCTION_2008_R2,
+
+       Globals.acl_claims_evaluation = ACL_CLAIMS_EVALUATION_AD_DC_ONLY;
+
        /* Now put back the settings that were set with lp_set_cmdline() */
        apply_lp_set_cmdline();
 }
@@ -994,7 +1040,11 @@ static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
  callers without affecting the source string.
 ********************************************************************/
 
-char *lp_string(TALLOC_CTX *ctx, const char *s)
+static char *loadparm_s3_global_substitution_fn(
+                       TALLOC_CTX *mem_ctx,
+                       const struct loadparm_substitution *lp_sub,
+                       const char *s,
+                       void *private_data)
 {
        char *ret;
 
@@ -1010,29 +1060,39 @@ char *lp_string(TALLOC_CTX *ctx, const char *s)
                return NULL;
        }
 
-       ret = talloc_sub_basic(ctx,
+       ret = talloc_sub_basic(mem_ctx,
                        get_current_username(),
-                       current_user_info.domain,
+                       get_current_user_info_domain(),
                        s);
        if (trim_char(ret, '\"', '\"')) {
                if (strchr(ret,'\"') != NULL) {
                        TALLOC_FREE(ret);
-                       ret = talloc_sub_basic(ctx,
+                       ret = talloc_sub_basic(mem_ctx,
                                        get_current_username(),
-                                       current_user_info.domain,
+                                       get_current_user_info_domain(),
                                        s);
                }
        }
        return ret;
 }
 
+static const struct loadparm_substitution s3_global_substitution = {
+       .substituted_string_fn = loadparm_s3_global_substitution_fn,
+};
+
+const struct loadparm_substitution *loadparm_s3_global_substitution(void)
+{
+       return &s3_global_substitution;
+}
+
 /*
    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) \
-char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
+#define FN_GLOBAL_SUBSTITUTED_STRING(fn_name,ptr) \
+char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub) \
+ {return lpcfg_substituted_string(ctx, lp_sub, *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : "");}
 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
  const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
 #define FN_GLOBAL_LIST(fn_name,ptr) \
@@ -1044,8 +1104,9 @@ char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globa
 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
  int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
 
-#define FN_LOCAL_STRING(fn_name,val) \
-char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
+#define FN_LOCAL_SUBSTITUTED_STRING(fn_name,val) \
+char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub, int i) \
+ {return lpcfg_substituted_string((ctx), lp_sub, (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
 #define FN_LOCAL_CONST_STRING(fn_name,val) \
  const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
 #define FN_LOCAL_LIST(fn_name,val) \
@@ -1077,7 +1138,7 @@ int lp_winbind_max_domain_connections(void)
 
 #include "lib/param/param_functions.c"
 
-FN_LOCAL_STRING(servicename, szService)
+FN_LOCAL_SUBSTITUTED_STRING(servicename, szService)
 FN_LOCAL_CONST_STRING(const_servicename, szService)
 
 /* These functions cannot be auto-generated */
@@ -1216,19 +1277,26 @@ static int lp_enum(const char *s,const struct enum_list *_enum)
 
 /* Return parametric option from a given service. Type is a part of option before ':' */
 /* Parametric option has following syntax: 'Type: option = value' */
-char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
+char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx,
+                                const struct loadparm_substitution *lp_sub,
+                                int snum,
+                                const char *type,
+                                const char *option,
+                                const char *def)
 {
        struct parmlist_entry *data = get_parametrics(snum, type, option);
 
+       SMB_ASSERT(lp_sub != NULL);
+
        if (data == NULL||data->value==NULL) {
                if (def) {
-                       return lp_string(ctx, def);
+                       return lpcfg_substituted_string(mem_ctx, lp_sub, def);
                } else {
                        return NULL;
                }
        }
 
-       return lp_string(ctx, data->value);
+       return lpcfg_substituted_string(mem_ctx, lp_sub, data->value);
 }
 
 /* Return parametric option from a given service. Type is a part of option before ':' */
@@ -1386,7 +1454,7 @@ static void free_service(struct loadparm_service *pservice)
 
 static void free_service_byindex(int idx)
 {
-       if ( !LP_SNUM_OK(idx) ) 
+       if ( !LP_SNUM_OK(idx) )
                return;
 
        ServicePtrs[idx]->valid = false;
@@ -1407,8 +1475,8 @@ static void free_service_byindex(int idx)
 }
 
 /***************************************************************************
- Add a new service to the services array initialising it with the given 
- service. 
+ Add a new service to the services array initialising it with the given
+ service.
 ***************************************************************************/
 
 static int add_a_service(const struct loadparm_service *pservice, const char *name)
@@ -1456,7 +1524,7 @@ static int add_a_service(const struct loadparm_service *pservice, const char *na
                lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
                                 name);
 
-       DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
+       DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
                i, ServicePtrs[i]->szService));
 
        if (!hash_a_service(ServicePtrs[i]->szService, i)) {
@@ -1528,6 +1596,8 @@ static bool hash_a_service(const char *name, int idx)
 bool lp_add_home(const char *pszHomename, int iDefaultService,
                 const char *user, const char *pszHomedir)
 {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        int i;
        char *global_path;
 
@@ -1541,7 +1611,7 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
        if (i < 0)
                return false;
 
-       global_path = lp_path(talloc_tos(), GLOBAL_SECTION_SNUM);
+       global_path = lp_path(talloc_tos(), lp_sub, GLOBAL_SECTION_SNUM);
        if (!(*(ServicePtrs[iDefaultService]->path))
            || strequal(ServicePtrs[iDefaultService]->path, global_path)) {
                lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
@@ -1566,7 +1636,7 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
 
        ServicePtrs[i]->autoloaded = true;
 
-       DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
+       DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
               user, ServicePtrs[i]->path ));
 
        return true;
@@ -1644,7 +1714,7 @@ bool lp_add_printer(const char *pszPrintername, int iDefaultService)
                         pszPrintername);
        lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
 
-       /* set the browseable flag from the gloabl default */
+       /* set the browseable flag from the global default */
        ServicePtrs[i]->browseable = sDefault.browseable;
 
        /* Printers cannot be read_only. */
@@ -1720,7 +1790,7 @@ bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
 /**************************************************************************
  Determine the canonical name for a parameter.
  Turn the value given into the inverse boolean expression when
- the synonym is an invers boolean synonym.
+ the synonym is an inverse boolean synonym.
 
  Return true if
  - parm_name is a valid parameter name and
@@ -1781,7 +1851,7 @@ static int map_parameter_canonical(const char *pszParmName, bool *inverse)
 
        parm_num = lpcfg_map_parameter(pszParmName);
        if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
-               /* invalid, parametric or no canidate for synonyms ... */
+               /* invalid, parametric or no candidate for synonyms ... */
                goto done;
        }
 
@@ -2086,7 +2156,7 @@ struct loadparm_service *lp_servicebynum(int snum)
        return ServicePtrs[snum];
 }
 
-struct loadparm_service *lp_default_loadparm_service()
+struct loadparm_service *lp_default_loadparm_service(void)
 {
        return &sDefault;
 }
@@ -2347,30 +2417,47 @@ bool lp_file_list_changed(void)
                                return true;
                        }
                } else {
-                       time_t mod_time;
+                       struct timespec mod_time = {
+                               .tv_sec = 0,
+                       };
+                       struct timeval_buf tbuf = {
+                               .buf = {0},
+                       };
                        char *n2 = NULL;
+                       struct stat sb = {0};
+                       int rc;
 
                        n2 = talloc_sub_basic(talloc_tos(),
                                              get_current_username(),
-                                             current_user_info.domain,
+                                             get_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);
+                                    f->name, n2,
+                                    timespec_string_buf(&f->modtime,
+                                                        true,
+                                                        &tbuf)));
+
+                       rc = stat(n2, &sb);
+                       if (rc == 0) {
+                               mod_time = get_mtimespec(&sb);
+                       }
 
-                       if (mod_time &&
-                           ((f->modtime != mod_time) ||
+                       if (mod_time.tv_sec > 0 &&
+                           ((timespec_compare(&mod_time, &f->modtime) != 0) ||
                             (f->subfname == NULL) ||
                             (strcmp(n2, f->subfname) != 0)))
                        {
+                               f->modtime = mod_time;
+
                                DEBUGADD(6,
                                         ("file %s modified: %s\n", n2,
-                                         ctime(&mod_time)));
-                               f->modtime = mod_time;
+                                         timespec_string_buf(&f->modtime,
+                                                             true,
+                                                             &tbuf)));
+
                                TALLOC_FREE(f->subfname);
                                f->subfname = talloc_strdup(f, n2);
                                if (f->subfname == NULL) {
@@ -2440,7 +2527,7 @@ bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *servic
        }
 
        fname = talloc_sub_basic(talloc_tos(), get_current_username(),
-                                current_user_info.domain,
+                                get_current_user_info_domain(),
                                 pszParmValue);
 
        add_to_file_list(NULL, &file_lists, pszParmValue, fname);
@@ -2565,7 +2652,7 @@ const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
        if (Globals._ldap_machine_suffix[0])
                return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
 
-       return lp_string(ctx, Globals.ldap_suffix);
+       return talloc_strdup(ctx, Globals.ldap_suffix);
 }
 
 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
@@ -2573,7 +2660,7 @@ const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
        if (Globals._ldap_user_suffix[0])
                return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
 
-       return lp_string(ctx, Globals.ldap_suffix);
+       return talloc_strdup(ctx, Globals.ldap_suffix);
 }
 
 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
@@ -2581,7 +2668,7 @@ const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
        if (Globals._ldap_group_suffix[0])
                return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
 
-       return lp_string(ctx, Globals.ldap_suffix);
+       return talloc_strdup(ctx, Globals.ldap_suffix);
 }
 
 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
@@ -2589,7 +2676,7 @@ const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
        if (Globals._ldap_idmap_suffix[0])
                return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
 
-       return lp_string(ctx, Globals.ldap_suffix);
+       return talloc_strdup(ctx, Globals.ldap_suffix);
 }
 
 /**
@@ -2680,24 +2767,6 @@ static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmVa
        return false;
 }
 
-bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
-{
-       bool ret;
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct loadparm_context *lp_ctx;
-
-       lp_ctx = setup_lp_context(frame);
-       if (lp_ctx == NULL) {
-               TALLOC_FREE(frame);
-               return false;
-       }
-
-       ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
-
-       TALLOC_FREE(frame);
-       return ret;
-}
-
 /***************************************************************************
  Process a parameter.
 ***************************************************************************/
@@ -2718,6 +2787,38 @@ static bool do_parameter(const char *pszParmName, const char *pszParmValue,
        }
 }
 
+
+static const char *ad_dc_req_vfs_mods[] = {"dfs_samba4", "acl_xattr", NULL};
+
+/*
+ * check that @vfs_objects includes all vfs modules required by an AD DC.
+ */
+static bool check_ad_dc_required_mods(const char **vfs_objects)
+{
+       int i;
+       int j;
+       int got_req;
+
+       for (i = 0; ad_dc_req_vfs_mods[i] != NULL; i++) {
+               got_req = false;
+               for (j = 0; vfs_objects[j] != NULL; j++) {
+                       if (!strwicmp(ad_dc_req_vfs_mods[i], vfs_objects[j])) {
+                               got_req = true;
+                               break;
+                       }
+               }
+               if (!got_req) {
+                       DEBUG(0, ("vfs objects specified without required AD "
+                                 "DC module: %s\n", ad_dc_req_vfs_mods[i]));
+                       return false;
+               }
+       }
+
+       DEBUG(6, ("vfs objects specified with all required AD DC modules\n"));
+       return true;
+}
+
+
 /***************************************************************************
  Initialize any local variables in the sDefault table, after parsing a
  [globals] section.
@@ -2737,7 +2838,10 @@ static void init_locals(void)
         */
        if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
                const char **vfs_objects = lp_vfs_objects(-1);
-               if (!vfs_objects || !vfs_objects[0]) {
+               if (vfs_objects != NULL) {
+                       /* ignore return, only warn if modules are missing */
+                       check_ad_dc_required_mods(vfs_objects);
+               } else {
                        if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
                                lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
                        } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
@@ -2790,7 +2894,7 @@ bool lp_do_section(const char *pszSectionName, void *userdata)
        /* if we have a current service, tidy it up before moving on */
        bRetval = true;
 
-       if (iServiceIndex >= 0)
+       if ((iServiceIndex >= 0) && (ServicePtrs[iServiceIndex] != NULL))
                bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
 
        /* if all is still well, move to the next record in the services array */
@@ -2870,7 +2974,7 @@ bool lp_snum_ok(int iService)
  Auto-load some home services.
 ***************************************************************************/
 
-static void lp_add_auto_services(char *str)
+static void lp_add_auto_services(const char *str)
 {
        char *s;
        char *p;
@@ -2931,7 +3035,7 @@ void lp_add_one_printer(const char *name, const char *comment,
 
 bool lp_loaded(void)
 {
-       return (bLoaded);
+       return (b_loaded);
 }
 
 /***************************************************************************
@@ -2978,7 +3082,7 @@ void lp_killservice(int iServiceIn)
 }
 
 /***************************************************************************
- Save the curent values of all global and sDefault parameters into the 
+ Save the current values of all global and sDefault parameters into the
  defaults union. This allows testparm to show only the
  changed (ie. non-default) parameters.
 ***************************************************************************/
@@ -3047,7 +3151,7 @@ static void lp_save_defaults(void)
 }
 
 /***********************************************************
- If we should send plaintext/LANMAN passwords in the clinet
+ If we should send plaintext/LANMAN passwords in the client
 ************************************************************/
 
 static void set_allowed_client_auth(void)
@@ -3332,6 +3436,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        char *canon_name = NULL;
        bool added_service = false;
        int ret = -1;
+       NTSTATUS status;
 
        /* Ensure share name doesn't contain invalid characters. */
        if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
@@ -3355,6 +3460,11 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
           open and fstat. Ensure this isn't a symlink link. */
 
        if (sys_lstat(fname, &lsbuf, false) != 0) {
+               if (errno == ENOENT) {
+                       /* Unknown share requested. Just ignore. */
+                       goto out;
+               }
+               /* Only log messages for meaningful problems. */
                DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
                        fname, strerror(errno) ));
                goto out;
@@ -3368,7 +3478,6 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
 
        {
                TDB_DATA data;
-               NTSTATUS status;
 
                status = dbwrap_fetch_bystring(ServiceHash, canon_name,
                                               canon_name, &data);
@@ -3465,7 +3574,8 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        }
 
        /* Write the ACL of the new/modified share. */
-       if (!set_share_security(canon_name, psd)) {
+       status = set_share_security(canon_name, psd);
+       if (!NT_STATUS_IS_OK(status)) {
                 DEBUG(0, ("process_usershare_file: Failed to set share "
                        "security for user share %s\n",
                        canon_name ));
@@ -3560,6 +3670,11 @@ int load_usershare_service(const char *servicename)
        int max_user_shares = Globals.usershare_max_shares;
        int snum_template = -1;
 
+       if (servicename[0] == '\0') {
+               /* Invalid service name. */
+               return -1;
+       }
+
        if (*usersharepath == 0 ||  max_user_shares == 0) {
                return -1;
        }
@@ -3765,13 +3880,15 @@ int load_usershare_shares(struct smbd_server_connection *sconn,
        tmp_ctx = talloc_stackframe();
        for (iService = iNumServices - 1; iService >= 0; iService--) {
                if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
+                       const struct loadparm_substitution *lp_sub =
+                               loadparm_s3_global_substitution();
                        char *servname;
 
                        if (snumused && snumused(sconn, iService)) {
                                continue;
                        }
 
-                       servname = lp_servicename(tmp_ctx, iService);
+                       servname = lp_servicename(tmp_ctx, lp_sub, iService);
 
                        /* Remove from the share ACL db. */
                        DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
@@ -3863,6 +3980,7 @@ static bool lp_load_ex(const char *pszFname,
        bool bRetval;
        TALLOC_CTX *frame = talloc_stackframe();
        struct loadparm_context *lp_ctx;
+       int max_protocol, min_protocol;
 
        DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
 
@@ -3873,7 +3991,7 @@ static bool lp_load_ex(const char *pszFname,
 
        lp_ctx = setup_lp_context(talloc_tos());
 
-       init_globals(lp_ctx, reinit_globals);
+       loadparm_s3_init_globals(lp_ctx, reinit_globals);
 
        free_file_list();
 
@@ -3894,7 +4012,7 @@ static bool lp_load_ex(const char *pszFname,
 
        if (lp_config_backend_is_file()) {
                n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
-                                       current_user_info.domain,
+                                       get_current_user_info_domain(),
                                        pszFname);
                if (!n2) {
                        smb_panic("lp_load_ex: out of memory");
@@ -3927,7 +4045,7 @@ static bool lp_load_ex(const char *pszFname,
                        /* start over */
                        DEBUG(1, ("lp_load_ex: changing to config backend "
                                  "registry\n"));
-                       init_globals(lp_ctx, true);
+                       loadparm_s3_init_globals(lp_ctx, true);
 
                        TALLOC_FREE(lp_ctx);
 
@@ -3956,7 +4074,9 @@ static bool lp_load_ex(const char *pszFname,
        }
 
        {
-               char *serv = lp_auto_services(talloc_tos());
+               const struct loadparm_substitution *lp_sub =
+                       loadparm_s3_global_substitution();
+               char *serv = lp_auto_services(talloc_tos(), lp_sub);
                lp_add_auto_services(serv);
                TALLOC_FREE(serv);
        }
@@ -3977,7 +4097,7 @@ static bool lp_load_ex(const char *pszFname,
                          lp_password_server()));
        }
 
-       bLoaded = true;
+       b_loaded = true;
 
        /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
        /* if we_are_a_wins_server is true and we are in the client            */
@@ -4001,6 +4121,19 @@ static bool lp_load_ex(const char *pszFname,
 
        bAllowIncludeRegistry = true;
 
+       /* Check if command line max protocol < min protocol, if so
+        * report a warning to the user.
+        */
+       max_protocol = lp_client_max_protocol();
+       min_protocol = lp_client_min_protocol();
+       if (max_protocol < min_protocol) {
+               const char *max_protocolp, *min_protocolp;
+               max_protocolp = lpcfg_get_smb_protocol(max_protocol);
+               min_protocolp = lpcfg_get_smb_protocol(min_protocol);
+               DBG_ERR("Max protocol %s is less than min protocol %s.\n",
+                       max_protocolp, min_protocolp);
+       }
+
        TALLOC_FREE(frame);
        return (bRetval);
 }
@@ -4195,7 +4328,7 @@ int lp_servicenumber(const char *pszServiceName)
                         */
                        fstrcpy(serviceName, ServicePtrs[iService]->szService);
                        standard_sub_basic(get_current_username(),
-                                          current_user_info.domain,
+                                          get_current_user_info_domain(),
                                           serviceName,sizeof(serviceName));
                        if (strequal(serviceName, pszServiceName)) {
                                break;
@@ -4234,17 +4367,19 @@ int lp_servicenumber(const char *pszServiceName)
 }
 
 /*******************************************************************
- A useful volume label function. 
+ A useful volume label function.
 ********************************************************************/
 
 const char *volume_label(TALLOC_CTX *ctx, int snum)
 {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        char *ret;
-       const char *label = lp_volume(ctx, snum);
+       const char *label = lp_volume(ctx, lp_sub, snum);
        size_t end = 32;
 
        if (!*label) {
-               label = lp_servicename(ctx, snum);
+               label = lp_servicename(ctx, lp_sub, snum);
        }
 
        /*
@@ -4277,7 +4412,7 @@ const char *volume_label(TALLOC_CTX *ctx, int snum)
                }
        }
 
-       /* This returns a max of 33 byte guarenteed null terminated string. */
+       /* This returns a max of 33 byte guaranteed null terminated string. */
        ret = talloc_strndup(ctx, label, end);
        if (!ret) {
                return "";
@@ -4296,8 +4431,8 @@ int lp_default_server_announce(void)
        default_server_announce |= SV_TYPE_SERVER;
        default_server_announce |= SV_TYPE_SERVER_UNIX;
 
-       /* note that the flag should be set only if we have a 
-          printer service but nmbd doesn't actually load the 
+       /* note that the flag should be set only if we have a
+          printer service but nmbd doesn't actually load the
           services so we can't tell   --jerry */
 
        default_server_announce |= SV_TYPE_PRINTQ_SERVER;
@@ -4310,6 +4445,7 @@ int lp_default_server_announce(void)
                        default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
                        break;
                case ROLE_DOMAIN_PDC:
+               case ROLE_IPA_DC:
                        default_server_announce |= SV_TYPE_DOMAIN_CTRL;
                        break;
                case ROLE_DOMAIN_BDC:
@@ -4335,7 +4471,8 @@ int lp_default_server_announce(void)
 bool lp_domain_master(void)
 {
        if (Globals._domain_master == Auto)
-               return (lp_server_role() == ROLE_DOMAIN_PDC);
+               return (lp_server_role() == ROLE_DOMAIN_PDC ||
+                       lp_server_role() == ROLE_IPA_DC);
 
        return (bool)Globals._domain_master;
 }
@@ -4375,9 +4512,12 @@ void lp_remove_service(int snum)
        ServicePtrs[snum]->valid = false;
 }
 
-const char *lp_printername(TALLOC_CTX *ctx, int snum)
+const char *lp_printername(TALLOC_CTX *ctx,
+                          const struct loadparm_substitution *lp_sub,
+                          int snum)
 {
-       const char *ret = lp__printername(ctx, snum);
+       const char *ret = lp__printername(ctx, lp_sub, snum);
+
        if (ret == NULL || *ret == '\0') {
                ret = lp_const_servicename(snum);
        }
@@ -4450,26 +4590,6 @@ uint32_t lp_get_spoolss_state( void )
        return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
 }
 
-/*******************************************************************
- Ensure we don't use sendfile if server smb signing is active.
-********************************************************************/
-
-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 (get_Protocol() < PROTOCOL_NT1) {
-               return false;
-       }
-       if (signing_state) {
-               sign_active = smb_signing_is_active(signing_state);
-       }
-       return (lp__use_sendfile(snum) &&
-                       (get_remote_arch() != RA_WIN95) &&
-                       !sign_active);
-}
-
 /*******************************************************************
  Turn off sendfile if we find the underlying OS doesn't support it.
 ********************************************************************/
@@ -4556,18 +4676,27 @@ void widelinks_warning(int snum)
                return;
        }
 
-       if (lp_unix_extensions() && lp_wide_links(snum)) {
-               DBG_ERR("Share '%s' has wide links and unix extensions enabled. "
+       if (lp_wide_links(snum)) {
+               if (lp_smb1_unix_extensions()) {
+                       DBG_ERR("Share '%s' has wide links and SMB1 unix "
+                       "extensions enabled. "
                        "These parameters are incompatible. "
                        "Wide links will be disabled for this share.\n",
                         lp_const_servicename(snum));
+               } else if (lp_smb3_unix_extensions(snum)) {
+                       DBG_ERR("Share '%s' has wide links and SMB3 Unix "
+                               "extensions enabled. "
+                               "These parameters are incompatible. "
+                               "Wide links will be disabled for this share.\n",
+                               lp_const_servicename(snum));
+               }
        }
 }
 
 bool lp_widelinks(int snum)
 {
        /* wide links is always incompatible with unix extensions */
-       if (lp_unix_extensions()) {
+       if (lp_smb1_unix_extensions() || lp_smb3_unix_extensions(snum)) {
                /*
                 * Unless we have "allow insecure widelinks"
                 * turned on.
@@ -4636,6 +4765,16 @@ int lp_client_ipc_signing(void)
        return client_ipc_signing;
 }
 
+enum credentials_use_kerberos lp_client_use_kerberos(void)
+{
+       if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
+               return CRED_USE_KERBEROS_REQUIRED;
+       }
+
+       return lp__client_use_kerberos();
+}
+
+
 int lp_rpc_low_port(void)
 {
        return Globals.rpc_low_port;
@@ -4675,3 +4814,25 @@ unsigned int * get_flags(void)
 
        return flags_list;
 }
+
+enum samba_weak_crypto lp_weak_crypto(void)
+{
+       if (Globals.weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
+               Globals.weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
+
+               if (samba_gnutls_weak_crypto_allowed()) {
+                       Globals.weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
+               }
+       }
+
+       return Globals.weak_crypto;
+}
+
+uint32_t lp_get_async_dns_timeout(void)
+{
+       /*
+        * Clamp minimum async dns timeout to 1 second
+        * as per the man page.
+        */
+       return MAX(Globals.async_dns_timeout, 1);
+}