*
*/
+#define LOADPARM_SUBSTITUTION_INTERNALS 1
#include "includes.h"
#include "system/filesys.h"
#include "util_tdb.h"
.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,
.oplocks = true,
.kernel_oplocks = false,
.level2_oplocks = true,
- .mangled_names = MANGLED_NAMES_YES,
+ .mangled_names = MANGLED_NAMES_ILLEGAL,
.wide_links = false,
.follow_symlinks = true,
.sync_always = false,
.acl_map_full_control = true,
.acl_group_control = false,
.acl_allow_execute_always = false,
- .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
.aio_read_size = 1,
.aio_write_size = 1,
.map_readonly = MAP_READONLY_NO,
.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,
.dummy = ""
};
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"));
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.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.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,
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;
+}
+
+char *lp_string(TALLOC_CTX *ctx, const char *s)
+{
+ return lpcfg_substituted_string(ctx, &s3_global_substitution, s);
+}
+
/*
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_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) \
/* 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 (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,
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);
}
/**
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))) {
{
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 ));
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"));
}
{
- 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);
}
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);
}
- /* 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);
}