#include "lib/util/bitmap.h"
#include "libcli/smb/smb_constants.h"
#include "tdb.h"
+#include "librpc/gen_ndr/nbt.h"
+#include "libds/common/roles.h"
+#include "lib/util/samba_util.h"
+#include "libcli/auth/ntlm_check.h"
+
+#ifdef HAVE_HTTPCONNECTENCRYPT
+#include <cups/http.h>
+#endif
#define standard_sub_basic talloc_strdup
struct loadparm_service *lpcfg_default_service(struct loadparm_context *lp_ctx)
{
- if (lp_ctx->s3_fns) {
- return lp_ctx->s3_fns->get_default_loadparm_service();
- }
return lp_ctx->sDefault;
}
+int lpcfg_rpc_low_port(struct loadparm_context *lp_ctx)
+{
+ return lp_ctx->globals->rpc_low_port;
+}
+
+int lpcfg_rpc_high_port(struct loadparm_context *lp_ctx)
+{
+ return lp_ctx->globals->rpc_high_port;
+}
+
/**
* Convenience routine to grab string parameters into temporary memory
* and run standard_sub_basic on them.
/* this global context supports the lp_*() function varients */
static struct loadparm_context *global_loadparm_context;
-#define lpcfg_default_service global_loadparm_context->sDefault
-#define lpcfg_global_service(i) global_loadparm_context->services[i]
-
#define FN_GLOBAL_STRING(fn_name,var_name) \
_PUBLIC_ char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx, TALLOC_CTX *ctx) {\
if (lp_ctx == NULL) return NULL; \
#define FN_LOCAL_PARM_INTEGER(fn_name, val) FN_LOCAL_INTEGER(fn_name, val)
-#define FN_LOCAL_PARM_CHAR(fn_name,val) \
+#define FN_LOCAL_CHAR(fn_name,val) \
_PUBLIC_ char lpcfg_ ## fn_name(struct loadparm_service *service, \
struct loadparm_service *sDefault) { \
return((service != NULL)? service->val : sDefault->val); \
}
+#define FN_LOCAL_PARM_CHAR(fn_name,val) FN_LOCAL_CHAR(fn_name, val)
+
#include "lib/param/param_functions.c"
/* These functions cannot be auto-generated */
const char *type, const char *option,
struct parmlist_entry *global_opts)
{
- char* param_key;
+ size_t type_len = strlen(type);
+ size_t option_len = strlen(option);
+ char param_key[type_len + option_len + 2];
struct parmlist_entry *data = NULL;
- TALLOC_CTX *mem_ctx = talloc_stackframe();
- param_key = talloc_asprintf(mem_ctx, "%s:%s", type, option);
- if (param_key == NULL) {
- DEBUG(0,("asprintf failed!\n"));
- TALLOC_FREE(mem_ctx);
- return NULL;
- }
+ snprintf(param_key, sizeof(param_key), "%s:%s", type, option);
/*
* Try to fetch the option from the data.
data = service->param_opt;
while (data != NULL) {
if (strwicmp(data->key, param_key) == 0) {
- TALLOC_FREE(mem_ctx);
return data;
}
data = data->next;
data = global_opts;
while (data != NULL) {
if (strwicmp(data->key, param_key) == 0) {
- TALLOC_FREE(mem_ctx);
return data;
}
data = data->next;
}
-
- TALLOC_FREE(mem_ctx);
-
return NULL;
-
-
}
const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx,
return strtoul(s, NULL, 0);
}
+/**
+ * convenience routine to return unsigned long long parameters.
+ */
+unsigned long long lp_ulonglong(const char *s)
+{
+
+ if (!s || !*s) {
+ DEBUG(0, ("lp_ulonglong(%s): is called with NULL!\n", s));
+ return -1;
+ }
+
+ return strtoull(s, NULL, 0);
+}
+
/**
* convenience routine to return unsigned long parameters.
*/
{
const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
- if (value != NULL)
- return (const char **)str_list_make(mem_ctx, value, separator);
+ if (value != NULL) {
+ char **l = str_list_make(mem_ctx, value, separator);
+ return discard_const_p(const char *, l);
+ }
return NULL;
}
return default_v;
}
+/**
+ * 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 lpcfg_parm_ulonglong(struct loadparm_context *lp_ctx,
+ struct loadparm_service *service,
+ const char *type, const char *option,
+ unsigned long long default_v)
+{
+ const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
+
+ if (value) {
+ return lp_ulonglong(value);
+ }
+
+ return default_v;
+}
+
long lpcfg_parm_long(struct loadparm_context *lp_ctx,
struct loadparm_service *service, const char *type,
const char *option, long default_v)
}
+/* this is used to prevent lots of mallocs of size 1 */
+static const char lpcfg_string_empty[] = "";
+
+/**
+ Free a string value.
+**/
+void lpcfg_string_free(char **s)
+{
+ if (s == NULL) {
+ return;
+ }
+ if (*s == lpcfg_string_empty) {
+ *s = NULL;
+ return;
+ }
+ TALLOC_FREE(*s);
+}
+
/**
* Set a string value, deallocating any existing space, and allocing the space
* for the string
*/
bool lpcfg_string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
{
- talloc_free(*dest);
+ lpcfg_string_free(dest);
- if (src == NULL)
- src = "";
+ if ((src == NULL) || (*src == '\0')) {
+ *dest = discard_const_p(char, lpcfg_string_empty);
+ return true;
+ }
*dest = talloc_strdup(mem_ctx, src);
if ((*dest) == NULL) {
*/
bool lpcfg_string_set_upper(TALLOC_CTX *mem_ctx, char **dest, const char *src)
{
- talloc_free(*dest);
+ lpcfg_string_free(dest);
- if (src == NULL)
- src = "";
+ if ((src == NULL) || (*src == '\0')) {
+ *dest = discard_const_p(char, lpcfg_string_empty);
+ return true;
+ }
*dest = strupper_talloc(mem_ctx, src);
if ((*dest) == NULL) {
int num_to_alloc = lp_ctx->iNumServices + 1;
struct parmlist_entry *data, *pdata;
+ if (lp_ctx->s3_fns != NULL) {
+ smb_panic("Add a service should not be called on an s3 loadparm ctx");
+ }
+
if (pservice == NULL) {
pservice = lp_ctx->sDefault;
}
if (!(*(service->comment))) {
service->comment = talloc_asprintf(service, "Home directory of %s", user);
}
- service->bAvailable = default_service->bAvailable;
+ service->available = default_service->available;
service->browseable = default_service->browseable;
DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n",
*/
struct parm_struct *lpcfg_parm_struct(struct loadparm_context *lp_ctx, const char *name)
{
- int parmnum;
+ int num = lpcfg_map_parameter(name);
- if (lp_ctx->s3_fns) {
- return lp_ctx->s3_fns->get_parm_struct(name);
+ if (num < 0) {
+ return NULL;
}
- parmnum = lpcfg_map_parameter(name);
- if (parmnum == -1) return NULL;
- return &parm_table[parmnum];
+ return &parm_table[num];
}
/**
unsigned priority)
{
struct parmlist_entry *new_opt, *opt;
- bool not_added;
opt = *opt_list;
- not_added = true;
/* Traverse destination */
while (opt) {
overridden */
return;
}
- TALLOC_FREE(opt->value);
TALLOC_FREE(opt->list);
- opt->value = talloc_strdup(opt, opt_value);
+ lpcfg_string_set(opt, &opt->value, opt_value);
opt->priority = priority;
- not_added = false;
- break;
+ return;
}
opt = opt->next;
}
- if (not_added) {
- new_opt = talloc(mem_ctx, struct parmlist_entry);
- if (new_opt == NULL) {
- smb_panic("OOM");
- }
- new_opt->key = talloc_strdup(new_opt, opt_name);
- if (new_opt->key == NULL) {
- smb_panic("talloc_strdup failed");
- }
-
- new_opt->value = talloc_strdup(new_opt, opt_value);
- if (new_opt->value == NULL) {
- smb_panic("talloc_strdup failed");
- }
-
- new_opt->list = NULL;
- new_opt->priority = priority;
- DLIST_ADD(*opt_list, new_opt);
+ new_opt = talloc_pooled_object(
+ mem_ctx, struct parmlist_entry,
+ 2, strlen(opt_name) + 1 + strlen(opt_value) + 1);
+ if (new_opt == NULL) {
+ smb_panic("OOM");
}
+ new_opt->key = NULL;
+ lpcfg_string_set(new_opt, &new_opt->key, opt_name);
+ new_opt->value = NULL;
+ lpcfg_string_set(new_opt, &new_opt->value, opt_value);
+
+ new_opt->list = NULL;
+ new_opt->priority = priority;
+ DLIST_ADD(*opt_list, new_opt);
}
/**
case P_CMDLIST:
case P_LIST:
TALLOC_FREE(*((char ***)dest_ptr));
- *(const char * const **)dest_ptr = (const char * const *)str_list_copy(pserviceDest,
- *(const char * * const *)src_ptr);
+ *(char ***)dest_ptr = str_list_copy(pserviceDest,
+ *discard_const_p(const char **, src_ptr));
break;
default:
break;
{
DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
service->szService));
- service->bAvailable = false;
+ service->available = false;
}
- /* If a service is flagged unavailable, log the fact at level 0. */
- if (!service->bAvailable)
+ if (!service->available)
DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
service->szService));
f->modtime = mod_time;
talloc_free(f->subfname);
f->subfname = talloc_strdup(f, n2);
+ TALLOC_FREE(n2);
return true;
}
+ TALLOC_FREE(n2);
}
return false;
}
int i;
for (i = 0; parm->enum_list[i].name; i++) {
- if ( strequal(pszParmValue, parm->enum_list[i].name)) {
+ if (strwicmp(pszParmValue, parm->enum_list[i].name) == 0) {
*ptr = parm->enum_list[i].value;
return true;
}
return false;
}
- lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
+ lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->realm_original, pszParmValue);
lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->realm, upper);
lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->dnsdomain, lower);
const char *pszParmValue, char **ptr)
{
char *fname;
+ const char *substitution_variable_substring;
+ char next_char;
if (lp_ctx->s3_fns) {
return lp_ctx->s3_fns->lp_include(lp_ctx, service, pszParmValue, ptr);
if (file_exist(fname))
return pm_process(fname, do_section, lpcfg_do_parameter, lp_ctx);
+ /*
+ * If the file doesn't exist, we check that it isn't due to variable
+ * substitution
+ */
+ substitution_variable_substring = strchr(fname, '%');
+
+ if (substitution_variable_substring != NULL) {
+ next_char = substitution_variable_substring[1];
+ if ((next_char >= 'a' && next_char <= 'z')
+ || (next_char >= 'A' && next_char <= 'Z')) {
+ DEBUG(2, ("Tried to load %s but variable substitution in "
+ "filename, ignoring file.\n", fname));
+ return true;
+ }
+ }
+
DEBUG(2, ("Can't find include file %s\n", fname));
return false;
serviceTemp = lpcfg_getservicebyname(lp_ctx, pszParmValue);
if (service == NULL) {
- DEBUG(0, ("Unable to copy service - invalid service destination"));
+ DEBUG(0, ("Unable to copy service - invalid service destination.\n"));
return false;
}
{
if (lp_ctx->s3_fns) {
if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
- global_iconv_handle = smb_iconv_handle_reinit(NULL,
- lpcfg_dos_charset(lp_ctx),
- lpcfg_unix_charset(lp_ctx),
- true, global_iconv_handle);
+ struct smb_iconv_handle *ret = NULL;
+
+ ret = reinit_iconv_handle(NULL,
+ lpcfg_dos_charset(lp_ctx),
+ lpcfg_unix_charset(lp_ctx));
+ if (ret == NULL) {
+ smb_panic("reinit_iconv_handle failed");
+ }
}
}
}
if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
+ struct smb_iconv_handle *ret = NULL;
if (is_utf8) {
DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
"be UTF8, using (default value) %s instead.\n",
DEFAULT_DOS_CHARSET));
pszParmValue = DEFAULT_DOS_CHARSET;
}
- global_iconv_handle = smb_iconv_handle_reinit(NULL,
- lpcfg_dos_charset(lp_ctx),
- lpcfg_unix_charset(lp_ctx),
- true, global_iconv_handle);
+ ret = reinit_iconv_handle(NULL,
+ lpcfg_dos_charset(lp_ctx),
+ lpcfg_unix_charset(lp_ctx));
+ if (ret == NULL) {
+ smb_panic("reinit_iconv_handle failed");
+ }
}
}
const char *pszParmValue, char **ptr)
{
static int parm_num = -1;
- struct loadparm_service *s;
if (parm_num == -1) {
parm_num = lpcfg_map_parameter("printing");
if (lp_ctx->s3_fns) {
if (service == NULL) {
- s = lp_ctx->sDefault;
- lp_ctx->s3_fns->init_printer_values(lp_ctx->globals->ctx, s);
+ init_printer_values(lp_ctx, lp_ctx->globals->ctx, lp_ctx->sDefault);
} else {
- s = service;
- lp_ctx->s3_fns->init_printer_values(s, s);
+ init_printer_values(lp_ctx, service, service);
}
}
const char *pszParmValue, char **ptr)
{
TALLOC_FREE(lp_ctx->globals->netbios_aliases);
- lp_ctx->globals->netbios_aliases = (const char **)str_list_make_v3(lp_ctx->globals->ctx,
- pszParmValue, NULL);
+ lp_ctx->globals->netbios_aliases = str_list_make_v3_const(lp_ctx->globals->ctx,
+ pszParmValue, NULL);
if (lp_ctx->s3_fns) {
return lp_ctx->s3_fns->set_netbios_aliases(lp_ctx->globals->netbios_aliases);
if (parm_num == -1) {
parm_num = lpcfg_map_parameter("smb ports");
+ if (parm_num == -1) {
+ return false;
+ }
}
if(!set_variable_helper(lp_ctx->globals->ctx, parm_num, ptr, "smb ports",
return true;
}
+bool handle_rpc_server_dynamic_port_range(struct loadparm_context *lp_ctx,
+ struct loadparm_service *service,
+ const char *pszParmValue,
+ char **ptr)
+{
+ int low_port = -1, high_port = -1;
+ int rc;
+
+ if (pszParmValue == NULL || pszParmValue[0] == '\0') {
+ return false;
+ }
+
+ rc = sscanf(pszParmValue, "%d - %d", &low_port, &high_port);
+ if (rc != 2) {
+ return false;
+ }
+
+ if (low_port > high_port) {
+ return false;
+ }
+
+ if (low_port < SERVER_TCP_PORT_MIN|| high_port > SERVER_TCP_PORT_MAX) {
+ return false;
+ }
+
+ lp_ctx->globals->rpc_low_port = low_port;
+ lp_ctx->globals->rpc_high_port = high_port;
+
+ return true;
+}
+
+bool handle_smb2_max_credits(struct loadparm_context *lp_ctx,
+ struct loadparm_service *service,
+ const char *pszParmValue, char **ptr)
+{
+ int value = lp_int(pszParmValue);
+
+ if (value <= 0) {
+ value = DEFAULT_SMB2_MAX_CREDITS;
+ }
+
+ *(int *)ptr = value;
+
+ return true;
+}
+
+bool handle_cups_encrypt(struct loadparm_context *lp_ctx,
+ struct loadparm_service *service,
+ const char *pszParmValue, char **ptr)
+{
+ int result = 0;
+#ifdef HAVE_HTTPCONNECTENCRYPT
+ int value = lp_int(pszParmValue);
+
+ switch (value) {
+ case Auto:
+ result = HTTP_ENCRYPT_REQUIRED;
+ break;
+ case true:
+ result = HTTP_ENCRYPT_ALWAYS;
+ break;
+ case false:
+ result = HTTP_ENCRYPT_NEVER;
+ break;
+ default:
+ result = 0;
+ break;
+ }
+#endif
+ *(int *)ptr = result;
+
+ return true;
+}
+
/***************************************************************************
Initialise a copymap.
***************************************************************************/
+/**
+ * Initializes service copymap
+ * Note: pservice *must* be valid TALLOC_CTX
+ */
void init_copymap(struct loadparm_service *pservice)
{
int i;
TALLOC_FREE(pservice->copymap);
- pservice->copymap = bitmap_talloc(NULL, num_parameters());
- if (!pservice->copymap)
+ pservice->copymap = bitmap_talloc(pservice, num_parameters());
+ if (!pservice->copymap) {
DEBUG(0,
("Couldn't allocate copymap!! (size %d)\n",
(int)num_parameters()));
- else
- for (i = 0; i < num_parameters(); i++)
+ } else {
+ for (i = 0; i < num_parameters(); i++) {
bitmap_set(pservice->copymap, i);
+ }
+ }
}
/**
case P_CMDLIST:
TALLOC_FREE(*(char ***)parm_ptr);
- *(const char * const **)parm_ptr
- = (const char * const *)str_list_make_v3(mem_ctx,
- pszParmValue, NULL);
+ *(char ***)parm_ptr = str_list_make_v3(mem_ctx,
+ pszParmValue, NULL);
break;
case P_LIST:
pszParmName, pszParmValue));
return false;
}
- *(const char * const **)parm_ptr = (const char * const *) new_list;
+ *(char ***)parm_ptr = new_list;
break;
}
}
}
break;
- case P_SEP:
- break;
}
return true;
}
-bool set_variable(TALLOC_CTX *mem_ctx, struct loadparm_service *service, int parmnum, void *parm_ptr,
+bool handle_name_resolve_order(struct loadparm_context *lp_ctx,
+ struct loadparm_service *service,
+ const char *pszParmValue, char **ptr)
+{
+ const char **valid_values = NULL;
+ const char **values_to_set = NULL;
+ int i;
+ bool value_is_valid = false;
+ valid_values = str_list_make_v3_const(NULL,
+ DEFAULT_NAME_RESOLVE_ORDER,
+ NULL);
+ if (valid_values == NULL) {
+ DBG_ERR("OOM: failed to make string list from %s\n",
+ DEFAULT_NAME_RESOLVE_ORDER);
+ goto out;
+ }
+ values_to_set = str_list_make_v3_const(lp_ctx->globals->ctx,
+ pszParmValue,
+ NULL);
+ if (values_to_set == NULL) {
+ DBG_ERR("OOM: failed to make string list from %s\n",
+ pszParmValue);
+ goto out;
+ }
+ TALLOC_FREE(lp_ctx->globals->name_resolve_order);
+ for (i = 0; values_to_set[i] != NULL; i++) {
+ value_is_valid = str_list_check(valid_values, values_to_set[i]);
+ if (!value_is_valid) {
+ DBG_ERR("WARNING: Ignoring invalid list value '%s' "
+ "for parameter 'name resolve order'\n",
+ values_to_set[i]);
+ break;
+ }
+ }
+out:
+ if (value_is_valid) {
+ lp_ctx->globals->name_resolve_order = values_to_set;
+ } else {
+ TALLOC_FREE(values_to_set);
+ }
+ TALLOC_FREE(valid_values);
+ return value_is_valid;
+}
+
+static bool set_variable(TALLOC_CTX *mem_ctx, struct loadparm_service *service,
+ int parmnum, void *parm_ptr,
const char *pszParmName, const char *pszParmValue,
struct loadparm_context *lp_ctx, bool on_globals)
{
if (parm_table[parmnum].special) {
ok = parm_table[parmnum].special(lp_ctx, service, pszParmValue,
(char **)parm_ptr);
- if (!ok) {
- return false;
- }
- goto mark_non_default;
+ } else {
+ ok = set_variable_helper(mem_ctx, parmnum, parm_ptr,
+ pszParmName, pszParmValue);
}
- ok = set_variable_helper(mem_ctx, parmnum, parm_ptr, pszParmName, pszParmValue);
-
if (!ok) {
return false;
}
-mark_non_default:
if (on_globals && (lp_ctx->flags[parmnum] & FLAG_DEFAULT)) {
lp_ctx->flags[parmnum] &= ~FLAG_DEFAULT;
/* we have to also unset FLAG_DEFAULT on aliases */
/* reset the CMDLINE flag in case this has been called before */
lp_ctx->flags[parmnum] &= ~FLAG_CMDLINE;
- if (lp_ctx->s3_fns != NULL) {
- if (!lp_ctx->s3_fns->lp_do_parameter(-1, pszParmName, pszParmValue)) {
- return false;
- }
- } else {
- if (!lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) {
- return false;
- }
+ if (!lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) {
+ return false;
}
lp_ctx->flags[parmnum] |= FLAG_CMDLINE;
fprintf(f, "%s", *(char **)ptr);
}
break;
- case P_SEP:
- break;
}
}
p2 = NULL;
return (p1 == p2 || strequal(p1, p2));
}
- case P_SEP:
- break;
}
return false;
}
* Determine if a particular base parameter is currently set to the default value.
*/
-bool is_default(void *base_structure, int i)
+static bool is_default(void *base_structure, int i)
{
void *def_ptr = ((char *)base_structure) + parm_table[i].offset;
switch (parm_table[i].type) {
case P_CMDLIST:
case P_LIST:
return str_list_equal((const char * const *)parm_table[i].def.lvalue,
- *(const char ***)def_ptr);
+ *(const char * const **)def_ptr);
case P_STRING:
case P_USTRING:
return strequal(parm_table[i].def.svalue,
case P_ENUM:
return parm_table[i].def.ivalue ==
*(int *)def_ptr;
- case P_SEP:
- break;
}
return false;
}
*Display the contents of the global structure.
*/
-static void dump_globals(struct loadparm_context *lp_ctx, FILE *f,
+void lpcfg_dump_globals(struct loadparm_context *lp_ctx, FILE *f,
bool show_defaults)
{
int i;
fprintf(f, "# Global parameters\n[global]\n");
- for (i = 0; parm_table[i].label; i++)
- if (parm_table[i].p_class == P_GLOBAL &&
- (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
- if (!show_defaults) {
- if (lp_ctx->flags && (lp_ctx->flags[i] & FLAG_DEFAULT)) {
- continue;
- }
+ for (i = 0; parm_table[i].label; i++) {
+ if (parm_table[i].p_class != P_GLOBAL) {
+ continue;
+ }
- if (is_default(lp_ctx->globals, i)) {
- continue;
- }
+ if (parm_table[i].flags & FLAG_SYNONYM) {
+ continue;
+ }
+
+ if (!show_defaults) {
+ if (lp_ctx->flags && (lp_ctx->flags[i] & FLAG_DEFAULT)) {
+ continue;
+ }
+
+ if (is_default(lp_ctx->globals, i)) {
+ continue;
}
+ }
- fprintf(f, "\t%s = ", parm_table[i].label);
- lpcfg_print_parameter(&parm_table[i], lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[i]), f);
- fprintf(f, "\n");
+ fprintf(f, "\t%s = ", parm_table[i].label);
+ lpcfg_print_parameter(&parm_table[i], lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[i]), f);
+ fprintf(f, "\n");
}
if (lp_ctx->globals->param_opt != NULL) {
for (data = lp_ctx->globals->param_opt; data;
fprintf(f, "\n[%s]\n", pService->szService);
for (i = 0; parm_table[i].label; i++) {
- if (parm_table[i].p_class == P_LOCAL &&
- (*parm_table[i].label != '-') &&
- (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
- {
- if (pService == sDefault) {
+ if (parm_table[i].p_class != P_LOCAL) {
+ continue;
+ }
+
+ if (parm_table[i].flags & FLAG_SYNONYM) {
+ continue;
+ }
+
+ if (*parm_table[i].label == '-') {
+ continue;
+ }
+
+ if (pService == sDefault) {
+ if (!show_defaults) {
if (flags && (flags[i] & FLAG_DEFAULT)) {
continue;
}
- if (!show_defaults) {
- if (is_default(sDefault, i)) {
- continue;
- }
- }
- } else {
- if (lpcfg_equal_parameter(parm_table[i].type,
- ((char *)pService) +
- parm_table[i].offset,
- ((char *)sDefault) +
- parm_table[i].offset))
+
+ if (is_default(sDefault, i)) {
continue;
+ }
+ }
+ } else {
+ bool equal;
+
+ equal = lpcfg_equal_parameter(parm_table[i].type,
+ ((char *)pService) +
+ parm_table[i].offset,
+ ((char *)sDefault) +
+ parm_table[i].offset);
+ if (equal) {
+ continue;
}
-
- fprintf(f, "\t%s = ", parm_table[i].label);
- lpcfg_print_parameter(&parm_table[i],
- ((char *)pService) + parm_table[i].offset, f);
- fprintf(f, "\n");
}
+
+ fprintf(f, "\t%s = ", parm_table[i].label);
+ lpcfg_print_parameter(&parm_table[i],
+ ((char *)pService) + parm_table[i].offset, f);
+ fprintf(f, "\n");
}
if (pService->param_opt != NULL) {
for (data = pService->param_opt; data; data = data->next) {
return;
}
+/***************************************************************************
+ Initialise the sDefault parameter structure for the printer values.
+***************************************************************************/
+
+void init_printer_values(struct loadparm_context *lp_ctx, TALLOC_CTX *ctx,
+ struct loadparm_service *pService)
+{
+ /* choose defaults depending on the type of printing */
+ switch (pService->printing) {
+ case PRINT_BSD:
+ case PRINT_AIX:
+ case PRINT_LPRNT:
+ case PRINT_LPROS2:
+ lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
+ lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
+ lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
+ break;
+
+ case PRINT_LPRNG:
+ case PRINT_PLP:
+ lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
+ lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
+ lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
+ lpcfg_string_set(ctx, &pService->queuepause_command, "lpc stop '%p'");
+ lpcfg_string_set(ctx, &pService->queueresume_command, "lpc start '%p'");
+ lpcfg_string_set(ctx, &pService->lppause_command, "lpc hold '%p' %j");
+ lpcfg_string_set(ctx, &pService->lpresume_command, "lpc release '%p' %j");
+ break;
+
+ case PRINT_CUPS:
+ case PRINT_IPRINT:
+ /* set the lpq command to contain the destination printer
+ name only. This is used by cups_queue_get() */
+ lpcfg_string_set(ctx, &pService->lpq_command, "%p");
+ lpcfg_string_set(ctx, &pService->lprm_command, "");
+ lpcfg_string_set(ctx, &pService->print_command, "");
+ lpcfg_string_set(ctx, &pService->lppause_command, "");
+ lpcfg_string_set(ctx, &pService->lpresume_command, "");
+ lpcfg_string_set(ctx, &pService->queuepause_command, "");
+ lpcfg_string_set(ctx, &pService->queueresume_command, "");
+ break;
+
+ case PRINT_SYSV:
+ case PRINT_HPUX:
+ lpcfg_string_set(ctx, &pService->lpq_command, "lpstat -o%p");
+ lpcfg_string_set(ctx, &pService->lprm_command, "cancel %p-%j");
+ lpcfg_string_set(ctx, &pService->print_command, "lp -c -d%p %s; rm %s");
+ lpcfg_string_set(ctx, &pService->queuepause_command, "disable %p");
+ lpcfg_string_set(ctx, &pService->queueresume_command, "enable %p");
+#ifndef HPUX
+ lpcfg_string_set(ctx, &pService->lppause_command, "lp -i %p-%j -H hold");
+ lpcfg_string_set(ctx, &pService->lpresume_command, "lp -i %p-%j -H resume");
+#endif /* HPUX */
+ break;
+
+ case PRINT_QNX:
+ lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P%p");
+ lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P%p %j");
+ lpcfg_string_set(ctx, &pService->print_command, "lp -r -P%p %s");
+ break;
+
+#if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
+
+ case PRINT_TEST:
+ case PRINT_VLP: {
+ const char *tdbfile;
+ TALLOC_CTX *tmp_ctx = talloc_new(ctx);
+ const char *tmp;
+
+ tmp = lpcfg_parm_string(lp_ctx, NULL, "vlp", "tdbfile");
+ if (tmp == NULL) {
+ tmp = "/tmp/vlp.tdb";
+ }
+
+ tdbfile = talloc_asprintf(tmp_ctx, "tdbfile=%s", tmp);
+ if (tdbfile == NULL) {
+ tdbfile="tdbfile=/tmp/vlp.tdb";
+ }
+
+ tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
+ tdbfile);
+ lpcfg_string_set(ctx, &pService->print_command,
+ tmp ? tmp : "vlp print %p %s");
+
+ tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
+ tdbfile);
+ lpcfg_string_set(ctx, &pService->lpq_command,
+ tmp ? tmp : "vlp lpq %p");
+
+ tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
+ tdbfile);
+ lpcfg_string_set(ctx, &pService->lprm_command,
+ tmp ? tmp : "vlp lprm %p %j");
+
+ tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
+ tdbfile);
+ lpcfg_string_set(ctx, &pService->lppause_command,
+ tmp ? tmp : "vlp lppause %p %j");
+
+ tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
+ tdbfile);
+ lpcfg_string_set(ctx, &pService->lpresume_command,
+ tmp ? tmp : "vlp lpresume %p %j");
+
+ tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
+ tdbfile);
+ lpcfg_string_set(ctx, &pService->queuepause_command,
+ tmp ? tmp : "vlp queuepause %p");
+
+ tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
+ tdbfile);
+ lpcfg_string_set(ctx, &pService->queueresume_command,
+ tmp ? tmp : "vlp queueresume %p");
+ TALLOC_FREE(tmp_ctx);
+
+ break;
+ }
+#endif /* DEVELOPER */
+
+ }
+}
/**
* Unload unused services.
bool (*snumused) (struct smbsrv_connection *, int))
{
int i;
+
+ if (lp_ctx->s3_fns != NULL) {
+ smb_panic("Cannot be used from an s3 loadparm ctx");
+ }
+
for (i = 0; i < lp_ctx->iNumServices; i++) {
if (lp_ctx->services[i] == NULL)
continue;
lp_ctx->globals = talloc_zero(lp_ctx, struct loadparm_global);
/* This appears odd, but globals in s3 isn't a pointer */
lp_ctx->globals->ctx = lp_ctx->globals;
+ lp_ctx->globals->rpc_low_port = SERVER_TCP_LOW_PORT;
+ lp_ctx->globals->rpc_high_port = SERVER_TCP_HIGH_PORT;
lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
lp_ctx->flags = talloc_zero_array(lp_ctx, unsigned int, num_parameters());
- lp_ctx->sDefault->iMaxPrintJobs = 1000;
- lp_ctx->sDefault->bAvailable = true;
+ lp_ctx->sDefault->max_print_jobs = 1000;
+ lp_ctx->sDefault->available = true;
lp_ctx->sDefault->browseable = true;
lp_ctx->sDefault->read_only = true;
lp_ctx->sDefault->map_archive = true;
if ((parm_table[i].type == P_STRING ||
parm_table[i].type == P_USTRING) &&
!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
+ TALLOC_CTX *parent_mem;
char **r;
if (parm_table[i].p_class == P_LOCAL) {
+ parent_mem = lp_ctx->sDefault;
r = (char **)(((char *)lp_ctx->sDefault) + parm_table[i].offset);
} else {
+ parent_mem = lp_ctx->globals;
r = (char **)(((char *)lp_ctx->globals) + parm_table[i].offset);
}
- *r = talloc_strdup(lp_ctx, "");
+ lpcfg_string_set(parent_mem, r, "");
}
}
myname = get_myname(lp_ctx);
lpcfg_do_global_parameter(lp_ctx, "netbios name", myname);
talloc_free(myname);
- lpcfg_do_global_parameter(lp_ctx, "name resolve order", "lmhosts wins host bcast");
+ lpcfg_do_global_parameter(lp_ctx,
+ "name resolve order",
+ DEFAULT_NAME_RESOLVE_ORDER);
lpcfg_do_global_parameter(lp_ctx, "fstype", "NTFS");
lpcfg_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
lpcfg_do_global_parameter(lp_ctx, "max connections", "0");
- lpcfg_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver");
+ lpcfg_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper wkssvc rpcecho samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver");
lpcfg_do_global_parameter(lp_ctx, "server services", "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns");
lpcfg_do_global_parameter(lp_ctx, "kccsrv:samba_kcc", "true");
/* the winbind method for domain controllers is for both RODC
lpcfg_do_global_parameter(lp_ctx, "server min protocol", "LANMAN1");
lpcfg_do_global_parameter(lp_ctx, "server max protocol", "SMB3");
lpcfg_do_global_parameter(lp_ctx, "client min protocol", "CORE");
- lpcfg_do_global_parameter(lp_ctx, "client max protocol", "NT1");
+ lpcfg_do_global_parameter(lp_ctx, "client max protocol", "default");
+ lpcfg_do_global_parameter(lp_ctx, "client ipc min protocol", "default");
+ lpcfg_do_global_parameter(lp_ctx, "client ipc max protocol", "default");
lpcfg_do_global_parameter(lp_ctx, "security", "AUTO");
lpcfg_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
lpcfg_do_global_parameter(lp_ctx, "ReadRaw", "True");
lpcfg_do_global_parameter(lp_ctx, "ClientLanManAuth", "False");
lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True");
lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False");
- lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "True");
+ lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "ntlmv2-only");
+ lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False");
lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False");
+ lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "False");
+
lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True");
lpcfg_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
lpcfg_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
lpcfg_do_global_parameter(lp_ctx, "require strong key", "True");
lpcfg_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
- lpcfg_do_global_parameter(lp_ctx, "winbindd privileged socket directory", dyn_WINBINDD_PRIVILEGED_SOCKET_DIR);
lpcfg_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR);
lpcfg_do_global_parameter_var(lp_ctx, "dns update command", "%s/samba_dnsupdate", dyn_SCRIPTSBINDIR);
lpcfg_do_global_parameter_var(lp_ctx, "spn update command", "%s/samba_spnupdate", dyn_SCRIPTSBINDIR);
lpcfg_do_global_parameter_var(lp_ctx, "samba kcc command",
"%s/samba_kcc", dyn_SCRIPTSBINDIR);
+#ifdef MIT_KDC_PATH
+ lpcfg_do_global_parameter_var(lp_ctx,
+ "mit kdc command",
+ MIT_KDC_PATH);
+#endif
lpcfg_do_global_parameter(lp_ctx, "template shell", "/bin/false");
lpcfg_do_global_parameter(lp_ctx, "template homedir", "/home/%D/%U");
lpcfg_do_global_parameter(lp_ctx, "client signing", "default");
+ lpcfg_do_global_parameter(lp_ctx, "client ipc signing", "default");
lpcfg_do_global_parameter(lp_ctx, "server signing", "default");
lpcfg_do_global_parameter(lp_ctx, "use spnego", "True");
lpcfg_do_global_parameter(lp_ctx, "use mmap", "True");
lpcfg_do_global_parameter(lp_ctx, "smb ports", "445 139");
- lpcfg_do_global_parameter(lp_ctx, "nbt port", "137");
- lpcfg_do_global_parameter(lp_ctx, "dgram port", "138");
+ lpcfg_do_global_parameter_var(lp_ctx, "nbt port", "%d", NBT_NAME_SERVICE_PORT);
+ lpcfg_do_global_parameter_var(lp_ctx, "dgram port", "%d", NBT_DGRAM_SERVICE_PORT);
lpcfg_do_global_parameter(lp_ctx, "cldap port", "389");
lpcfg_do_global_parameter(lp_ctx, "krb5 port", "88");
lpcfg_do_global_parameter(lp_ctx, "kpasswd port", "464");
lpcfg_do_global_parameter(lp_ctx, "min wins ttl", "21600");
lpcfg_do_global_parameter(lp_ctx, "tls enabled", "True");
+ lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "as_strict_as_possible");
lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
+ lpcfg_do_global_parameter(lp_ctx, "tls priority", "NORMAL:-VERS-SSL3.0");
lpcfg_do_global_parameter(lp_ctx, "prefork children:smb", "4");
lpcfg_do_global_parameter(lp_ctx, "rndc command", "/usr/sbin/rndc");
lpcfg_do_global_parameter(lp_ctx, "guest account", GUEST_ACCOUNT);
+ lpcfg_do_global_parameter(lp_ctx, "map untrusted to domain", "auto");
+
lpcfg_do_global_parameter(lp_ctx, "client schannel", "auto");
lpcfg_do_global_parameter(lp_ctx, "smb encrypt", "default");
lpcfg_do_global_parameter(lp_ctx, "keepalive", "300");
+ lpcfg_do_global_parameter(lp_ctx, "smbd profiling level", "off");
+
lpcfg_do_global_parameter(lp_ctx, "winbind cache time", "300");
lpcfg_do_global_parameter(lp_ctx, "level2 oplocks", "yes");
lpcfg_do_global_parameter(lp_ctx, "allocation roundup size", "1048576");
- lpcfg_do_global_parameter(lp_ctx, "ldap page size", "1024");
+ lpcfg_do_global_parameter(lp_ctx, "ldap page size", "1000");
lpcfg_do_global_parameter(lp_ctx, "kernel share modes", "yes");
lpcfg_do_global_parameter(lp_ctx, "strict locking", "Auto");
+ lpcfg_do_global_parameter(lp_ctx, "strict sync", "yes");
+
lpcfg_do_global_parameter(lp_ctx, "map readonly", "yes");
lpcfg_do_global_parameter(lp_ctx, "allow trusted domains", "yes");
lpcfg_do_global_parameter(lp_ctx, "ldap debug threshold", "10");
+ lpcfg_do_global_parameter(lp_ctx, "client ldap sasl wrapping", "sign");
+
+ lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "yes");
+
lpcfg_do_global_parameter(lp_ctx, "follow symlinks", "yes");
lpcfg_do_global_parameter(lp_ctx, "machine password timeout", "604800");
lpcfg_do_global_parameter(lp_ctx, "ldap connection timeout", "2");
- lpcfg_do_global_parameter(lp_ctx, "winbind expand groups", "1");
+ lpcfg_do_global_parameter(lp_ctx, "winbind expand groups", "0");
lpcfg_do_global_parameter(lp_ctx, "stat cache", "yes");
lpcfg_do_global_parameter(lp_ctx, "printjob username", "%U");
+ lpcfg_do_global_parameter(lp_ctx, "aio max threads", "100");
+
+ lpcfg_do_global_parameter(lp_ctx, "smb2 leases", "yes");
+
+ lpcfg_do_global_parameter(lp_ctx, "kerberos encryption types", "all");
+
+ lpcfg_do_global_parameter(lp_ctx,
+ "rpc server dynamic port range",
+ "49152-65535");
+
for (i = 0; parm_table[i].label; i++) {
if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
lp_ctx->flags[i] |= FLAG_DEFAULT;
}
}
-
return lp_ctx;
}
ZERO_STRUCT(settings);
/* Add any more debug-related smb.conf parameters created in
* future here */
- settings.syslog = lp_ctx->globals->syslog;
- settings.syslog_only = lp_ctx->globals->syslog_only;
settings.timestamp_logs = lp_ctx->globals->timestamp_logs;
settings.debug_prefix_timestamp = lp_ctx->globals->debug_prefix_timestamp;
settings.debug_hires_timestamp = lp_ctx->globals->debug_hires_timestamp;
settings.debug_pid = lp_ctx->globals->debug_pid;
settings.debug_uid = lp_ctx->globals->debug_uid;
settings.debug_class = lp_ctx->globals->debug_class;
- debug_set_settings(&settings);
+ debug_set_settings(&settings, lp_ctx->globals->logging,
+ lp_ctx->globals->syslog,
+ lp_ctx->globals->syslog_only);
/* FIXME: This is a bit of a hack, but we can't use a global, since
* not everything that uses lp also uses the socket library */
return;
}
- dump_globals(lp_ctx, f, show_defaults);
+ lpcfg_dump_globals(lp_ctx, f, show_defaults);
lpcfg_dump_a_service(lp_ctx->sDefault, lp_ctx->sDefault, f, lp_ctx->flags, show_defaults);
*/
int lpcfg_maxprintjobs(struct loadparm_service *service, struct loadparm_service *sDefault)
{
- int maxjobs = (service != NULL) ? service->iMaxPrintJobs : sDefault->iMaxPrintJobs;
+ int maxjobs = lpcfg_max_print_jobs(service, sDefault);
+
if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
maxjobs = PRINT_MAX_JOBID - 1;
_PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx)
{
- struct smb_iconv_handle *old_ic = lp_ctx->iconv_handle;
if (!lp_ctx->global) {
return;
}
- if (old_ic == NULL) {
- old_ic = global_iconv_handle;
+ lp_ctx->iconv_handle =
+ reinit_iconv_handle(lp_ctx,
+ lpcfg_dos_charset(lp_ctx),
+ lpcfg_unix_charset(lp_ctx));
+ if (lp_ctx->iconv_handle == NULL) {
+ smb_panic("reinit_iconv_handle failed");
}
- lp_ctx->iconv_handle = smb_iconv_handle_reinit_lp(lp_ctx, lp_ctx, old_ic);
- global_iconv_handle = lp_ctx->iconv_handle;
}
_PUBLIC_ char *lpcfg_tls_keyfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
lpcfg__security(lp_ctx));
}
+int lpcfg_client_max_protocol(struct loadparm_context *lp_ctx)
+{
+ int client_max_protocol = lpcfg__client_max_protocol(lp_ctx);
+ if (client_max_protocol == PROTOCOL_DEFAULT) {
+ return PROTOCOL_LATEST;
+ }
+ return client_max_protocol;
+}
+
+int lpcfg_client_ipc_min_protocol(struct loadparm_context *lp_ctx)
+{
+ int client_ipc_min_protocol = lpcfg__client_ipc_min_protocol(lp_ctx);
+ if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
+ client_ipc_min_protocol = lpcfg_client_min_protocol(lp_ctx);
+ }
+ if (client_ipc_min_protocol < PROTOCOL_NT1) {
+ return PROTOCOL_NT1;
+ }
+ return client_ipc_min_protocol;
+}
+
+int lpcfg_client_ipc_max_protocol(struct loadparm_context *lp_ctx)
+{
+ int client_ipc_max_protocol = lpcfg__client_ipc_max_protocol(lp_ctx);
+ if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
+ return PROTOCOL_LATEST;
+ }
+ if (client_ipc_max_protocol < PROTOCOL_NT1) {
+ return PROTOCOL_NT1;
+ }
+ return client_ipc_max_protocol;
+}
+
+int lpcfg_client_ipc_signing(struct loadparm_context *lp_ctx)
+{
+ int client_ipc_signing = lpcfg__client_ipc_signing(lp_ctx);
+ if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
+ return SMB_SIGNING_REQUIRED;
+ }
+ return client_ipc_signing;
+}
+
bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandatory)
{
bool allowed = true;
case SMB_SIGNING_REQUIRED:
*mandatory = true;
break;
+ case SMB_SIGNING_DESIRED:
case SMB_SIGNING_IF_REQUIRED:
break;
- case SMB_SIGNING_DEFAULT:
case SMB_SIGNING_OFF:
allowed = false;
break;
+ case SMB_SIGNING_DEFAULT:
+ case SMB_SIGNING_IPC_DEFAULT:
+ smb_panic(__location__);
+ break;
}
return allowed;
}
return tdb_flags;
}
+
+/*
+ * Do not allow LanMan auth if unless NTLMv1 is also allowed
+ *
+ * This also ensures it is disabled if NTLM is totally disabled
+ */
+bool lpcfg_lanman_auth(struct loadparm_context *lp_ctx)
+{
+ enum ntlm_auth_level ntlm_auth_level = lpcfg_ntlm_auth(lp_ctx);
+
+ if (ntlm_auth_level == NTLM_AUTH_ON) {
+ return lpcfg__lanman_auth(lp_ctx);
+ } else {
+ return false;
+ }
+}