*
*/
+#define LOADPARM_SUBSTITUTION_INTERNALS 1
#include "includes.h"
#include "system/filesys.h"
#include "util_tdb.h"
#include "../lib/util/bitmap.h"
#include "librpc/gen_ndr/nbt.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"
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
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,
.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,
.max_connections = 0,
.default_case = CASE_LOWER,
.printing = DEFAULT_PRINTING,
- .oplock_contention_limit = 2,
.csc_policy = 0,
.block_size = 1024,
.dfree_cache_time = 0,
.map_system = false,
.map_hidden = false,
.map_archive = true,
- .store_dos_attributes = false,
+ .store_dos_attributes = true,
+ .smbd_max_xattr_size = 65536,
.dmapi_support = false,
.locking = true,
.strict_locking = Auto,
.oplocks = true,
.kernel_oplocks = false,
.level2_oplocks = true,
- .mangled_names = true,
+ .mangled_names = MANGLED_NAMES_ILLEGAL,
.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,
.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,
+ .ea_support = true,
.acl_check_permissions = true,
.acl_map_full_control = true,
.acl_group_control = false,
.acl_allow_execute_always = false,
- .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
- .aio_read_size = 0,
- .aio_write_size = 0,
- .map_readonly = MAP_READONLY_YES,
+ .aio_read_size = 1,
+ .aio_write_size = 1,
+ .map_readonly = MAP_READONLY_NO,
.directory_name_cache_size = 100,
- .smb_encrypt = SMB_SIGNING_DEFAULT,
+ .server_smb_encrypt = SMB_ENCRYPTION_DEFAULT,
.kernel_share_modes = true,
.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_NOINDEX,
+ .honor_change_notify_privilege = false,
.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;
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"));
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 */
lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
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);
+ 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;
Globals._disable_spoolss = false;
Globals.max_smbd_processes = 0;/* no limit specified */
Globals.username_level = 0;
- Globals.deadtime = 0;
+ Globals.deadtime = 10080;
Globals.getwd_cache = true;
Globals.large_readwrite = true;
Globals.max_log_size = 5000;
Globals.max_open_files = max_open_files();
Globals.server_max_protocol = PROTOCOL_SMB3_11;
- Globals.server_min_protocol = PROTOCOL_LANMAN1;
+ Globals.server_min_protocol = PROTOCOL_SMB2_02;
Globals._client_max_protocol = PROTOCOL_DEFAULT;
- Globals.client_min_protocol = PROTOCOL_CORE;
+ Globals.client_min_protocol = PROTOCOL_SMB2_02;
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;
+ Globals.server_schannel = true;
Globals.read_raw = true;
Globals.write_raw = true;
Globals.null_passwords = false;
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;
Globals.nt_status_support = true; /* Use NT status by default. */
Globals.smbd_profiling_level = 0;
Globals.stat_cache = true; /* use stat cache by default */
- Globals.max_stat_cache_size = 256; /* 256k by default */
+ Globals.max_stat_cache_size = 512; /* 512k by default */
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 = false; /* Do NOT 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.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
Globals.enhanced_browsing = true;
Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
-#ifdef MMAP_BLACKLIST
- Globals.use_mmap = false;
-#else
Globals.use_mmap = true;
-#endif
Globals.unicode = true;
Globals.unix_extensions = true;
Globals.reset_on_zero_vc = false;
Globals.log_writeable_files_on_exit = false;
Globals.create_krb5_conf = true;
+ Globals.include_system_krb5_conf = true;
Globals._winbind_max_domain_connections = 1;
/* hostname lookups can be very expensive and are broken on
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;
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);
Globals.winbind_refresh_tickets = false;
Globals.winbind_offline_logon = false;
+ Globals.winbind_scan_trusted_domains = true;
Globals.idmap_cache_time = 86400 * 7; /* a week by default */
Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
Globals.name_cache_timeout = 660; /* In seconds */
- Globals.use_spnego = true;
Globals.client_use_spnego = true;
Globals.client_signing = SMB_SIGNING_DEFAULT;
Globals.min_receivefile_size = 0;
- Globals.map_untrusted_to_domain = false;
Globals.multicast_dns_register = true;
Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
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;
+ Globals.dns_zone_scavenging = false;
lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
get_dyn_NTP_SIGND_SOCKET_DIR());
- lpcfg_string_set(Globals.ctx,
- &Globals.winbindd_privileged_socket_directory,
- get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
-
s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
if (s == NULL) {
smb_panic("init_globals: ENOMEM");
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");
Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
TALLOC_FREE(s);
+ s = talloc_asprintf(talloc_tos(), "%s/samba-gpupdate", 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);
+
+ Globals.apply_group_policies = false;
+
s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
if (s == NULL) {
smb_panic("init_globals: ENOMEM");
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;
Globals.kpasswd_port = 464;
- 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 = 4;
+ 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;
+
/* Now put back the settings that were set with lp_set_cmdline() */
apply_lp_set_cmdline();
}
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;
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;
return NULL;
}
- ret = talloc_sub_basic(ctx,
+ ret = talloc_sub_basic(mem_ctx,
get_current_username(),
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,
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) \
#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) \
#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 */
/* 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 ':' */
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;
if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
pszHomedir[0] == '\0') {
if (i < 0)
return false;
+ global_path = lp_path(talloc_tos(), lp_sub, GLOBAL_SECTION_SNUM);
if (!(*(ServicePtrs[iDefaultService]->path))
- || strequal(ServicePtrs[iDefaultService]->path,
- lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
+ || strequal(ServicePtrs[iDefaultService]->path, global_path)) {
lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
pszHomedir);
}
+ TALLOC_FREE(global_path);
if (!(*(ServicePtrs[i]->comment))) {
char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
ServicePtrs[i]->guest_ok = guest_ok;
ServicePtrs[i]->printable = false;
ServicePtrs[i]->browseable = sDefault.browseable;
- ServicePtrs[i]->autoloaded = true;
+ ServicePtrs[i]->autoloaded = false;
DEBUG(3, ("adding IPC service\n"));
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.
**************************************************************************/
{
int num;
bool inverse;
+ bool ret;
if (!lp_parameter_is_valid(parm_name)) {
*canon_parm = NULL;
*canon_val = val;
}
- return true;
+ ret = lp_parameter_value_is_valid(*canon_parm, *canon_val);
+
+ return ret;
}
/***************************************************************************
static void show_parameter(int parmIndex)
{
- int enumIndex, flagIndex;
- int parmIndex2;
+ size_t enumIndex, flagIndex;
+ size_t parmIndex2;
bool hadFlag;
bool hadSyn;
bool inverse;
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) {
**/
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");
+ }
}
/***************************************************************************
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)
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)
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)
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);
}
/**
}
}
+
+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.
*/
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)) {
bool bRetval;
bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
(strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
- bRetval = false;
/* if we were in a global section then do the local inits */
if (bInGlobalSection && !isglobal)
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;
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))) {
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;
{
TDB_DATA data;
- NTSTATUS status;
status = dbwrap_fetch_bystring(ServiceHash, canon_name,
canon_name, &data);
}
/* 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 ));
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.
***************************************************************************/
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;
}
*/
#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",
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",
bool bRetval;
TALLOC_CTX *frame = talloc_stackframe();
struct loadparm_context *lp_ctx;
-
- bRetval = false;
+ int max_protocol, min_protocol;
DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
bInGlobalSection = true;
bGlobalOnly = global_only;
bAllowIncludeRegistry = allow_include_registry;
+ sDefault = _sDefault;
lp_ctx = setup_lp_context(talloc_tos());
}
{
- 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);
}
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);
}
false, /* global_only */
true, /* save_defaults */
false, /* add_ipc */
- false, /* reinit_globals */
+ true, /* reinit_globals */
true, /* allow_include_registry */
true); /* load_all_shares*/
}
fprintf(f,"\n");
lp_dump_one(f, show_defaults, iService);
}
+ TALLOC_FREE(lp_ctx);
}
/***************************************************************************
if (!usershare_exists(iService, &last_mod)) {
/* Remove the share security tdb entry for it. */
- delete_share_security(lp_servicename(talloc_tos(), iService));
+ delete_share_security(lp_const_servicename(iService));
/* Remove it from the array. */
free_service_byindex(iService);
/* Doesn't exist anymore. */
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);
}
- /* This returns a 33 byte guarenteed null terminated string. */
- ret = talloc_strndup(ctx, label, 32);
+ /*
+ * Volume label can be a max of 32 bytes. Make sure to truncate
+ * it at a codepoint boundary if it's longer than 32 and contains
+ * multibyte characters. Windows insists on a volume label being
+ * a valid mb sequence, and errors out if not.
+ */
+ if (strlen(label) > 32) {
+ /*
+ * A MB char can be a max of 5 bytes, thus
+ * we should have a valid mb character at a
+ * minimum position of (32-5) = 27.
+ */
+ while (end >= 27) {
+ /*
+ * Check if a codepoint starting from next byte
+ * is valid. If yes, then the current byte is the
+ * end of a MB or ascii sequence and the label can
+ * be safely truncated here. If not, keep going
+ * backwards till a valid codepoint is found.
+ */
+ size_t len = 0;
+ const char *s = &label[end];
+ codepoint_t c = next_codepoint(s, &len);
+ if (c != INVALID_CODEPOINT) {
+ break;
+ }
+ end--;
+ }
+ }
+
+ /* This returns a max of 33 byte guarenteed null terminated string. */
+ ret = talloc_strndup(ctx, label, end);
if (!ret) {
return "";
- }
+ }
return ret;
}
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);
}
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.
********************************************************************/
}
if (lp_unix_extensions() && lp_wide_links(snum)) {
- DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
+ DBG_ERR("Share '%s' has wide links and unix extensions enabled. "
"These parameters are incompatible. "
"Wide links will be disabled for this share.\n",
- lp_servicename(talloc_tos(), snum) ));
+ lp_const_servicename(snum));
}
}
{
int client_max_protocol = lp__client_max_protocol();
if (client_max_protocol == PROTOCOL_DEFAULT) {
- return PROTOCOL_NT1;
+ return PROTOCOL_LATEST;
}
return client_max_protocol;
}
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;
+}
+
+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)
{
return &Globals;
return flags_list;
}
+
+enum samba_weak_crypto lp_weak_crypto()
+{
+ 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);
+}