#include "lib/param/s3_param.h"
#include "lib/util/bitmap.h"
#include "libcli/smb/smb_constants.h"
+#include "tdb.h"
#define standard_sub_basic talloc_strdup
static bool do_parameter(const char *, const char *, void *);
static bool defaults_saved = false;
-#define LOADPARM_EXTRA_GLOBALS \
- struct parmlist_entry *param_opt; \
- char *realm_original; \
- int iminreceivefile; \
- char *szPrintcapname; \
- int CupsEncrypt; \
- int iPreferredMaster; \
- char *szLdapMachineSuffix; \
- char *szLdapUserSuffix; \
- char *szLdapIdmapSuffix; \
- char *szLdapGroupSuffix; \
- char *szIdmapUID; \
- char *szIdmapGID; \
- char *szIdmapBackend; \
- int winbindMaxDomainConnections; \
- int ismb2_max_credits; \
- char *tls_keyfile; \
- char *tls_certfile; \
- char *tls_cafile; \
- char *tls_crlfile; \
- char *tls_dhpfile;
-
#include "lib/param/param_global.h"
-#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
-
-/* we don't need a special handler for "dos charset" and "unix charset" */
-#define handle_dos_charset NULL
-#define handle_charset NULL
-
-/* these are parameter handlers which are not needed in the
- * non-source3 code
- */
-#define handle_netbios_aliases NULL
-#define handle_printing NULL
-#define handle_ldap_debug_level NULL
-#define handle_idmap_backend NULL
-#define handle_idmap_uid NULL
-#define handle_idmap_gid NULL
-
-#ifndef N_
-#define N_(x) x
-#endif
-
-/* prototypes for the special type handlers */
-static bool handle_include(struct loadparm_context *lp_ctx, int unused,
- const char *pszParmValue, char **ptr);
-static bool handle_realm(struct loadparm_context *lp_ctx, int unused,
- const char *pszParmValue, char **ptr);
-static bool handle_copy(struct loadparm_context *lp_ctx, int unused,
- const char *pszParmValue, char **ptr);
-static bool handle_debug_list(struct loadparm_context *lp_ctx, int unused,
- const char *pszParmValue, char **ptr);
-static bool handle_logfile(struct loadparm_context *lp_ctx, int unused,
- const char *pszParmValue, char **ptr);
-
-#include "lib/param/param_table.c"
-
-/* local variables */
-struct loadparm_context {
- const char *szConfigFile;
- struct loadparm_global *globals;
- struct loadparm_service **services;
- struct loadparm_service *sDefault;
- struct smb_iconv_handle *iconv_handle;
- int iNumServices;
- struct loadparm_service *currentService;
- bool bInGlobalSection;
- struct file_lists {
- struct file_lists *next;
- char *name;
- char *subfname;
- time_t modtime;
- } *file_lists;
- unsigned int flags[NUMPARAMETERS];
- bool loaded;
- bool refuse_free;
- bool global; /* Is this the global context, which may set
- * global variables such as debug level etc? */
- const struct loadparm_s3_helpers *s3_fns;
-};
-
+#define NUMPARAMETERS (num_parameters())
struct loadparm_service *lpcfg_default_service(struct loadparm_context *lp_ctx)
{
* callers without affecting the source string.
*/
-static const char *lp_string(const char *s)
+static const char *lpcfg_string(const char *s)
{
#if 0 /* until REWRITE done to make thread-safe */
size_t len = s ? strlen(s) : 0;
present all the time? */
#if 0
- DEBUG(10, ("lp_string(%s)\n", s));
+ DEBUG(10, ("lpcfg_string(%s)\n", s));
#endif
#if 0 /* until REWRITE done to make thread-safe */
#define lpcfg_global_service(i) global_loadparm_context->services[i]
#define FN_GLOBAL_STRING(fn_name,var_name) \
- _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {\
+ _PUBLIC_ char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx, TALLOC_CTX *ctx) {\
if (lp_ctx == NULL) return NULL; \
if (lp_ctx->s3_fns) { \
- smb_panic( __location__ ": " #fn_name " not implemented because it is an allocated and substiuted string"); \
+ return lp_ctx->globals->var_name ? lp_ctx->s3_fns->lp_string(ctx, lp_ctx->globals->var_name) : talloc_strdup(ctx, ""); \
} \
- return lp_ctx->globals->var_name ? lp_string(lp_ctx->globals->var_name) : ""; \
+ return lp_ctx->globals->var_name ? talloc_strdup(ctx, lpcfg_string(lp_ctx->globals->var_name)) : talloc_strdup(ctx, ""); \
}
#define FN_GLOBAL_CONST_STRING(fn_name,var_name) \
_PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
if (lp_ctx == NULL) return NULL; \
- if (lp_ctx->s3_fns) { \
- SMB_ASSERT(lp_ctx->s3_fns->fn_name); \
- return lp_ctx->s3_fns->fn_name(); \
- } \
- return lp_ctx->globals->var_name ? lp_string(lp_ctx->globals->var_name) : ""; \
+ return lp_ctx->globals->var_name ? lpcfg_string(lp_ctx->globals->var_name) : ""; \
}
#define FN_GLOBAL_LIST(fn_name,var_name) \
_PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
if (lp_ctx == NULL) return NULL; \
- if (lp_ctx->s3_fns) { \
- SMB_ASSERT(lp_ctx->s3_fns->fn_name); \
- return lp_ctx->s3_fns->fn_name(); \
- } \
return lp_ctx->globals->var_name; \
}
#define FN_GLOBAL_BOOL(fn_name,var_name) \
_PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {\
if (lp_ctx == NULL) return false; \
- if (lp_ctx->s3_fns) { \
- SMB_ASSERT(lp_ctx->s3_fns->fn_name); \
- return lp_ctx->s3_fns->fn_name(); \
- } \
return lp_ctx->globals->var_name; \
}
#define FN_GLOBAL_INTEGER(fn_name,var_name) \
_PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
- if (lp_ctx->s3_fns) { \
- SMB_ASSERT(lp_ctx->s3_fns->fn_name); \
- return lp_ctx->s3_fns->fn_name(); \
- } \
return lp_ctx->globals->var_name; \
}
* loadparm_service is shared and lpcfg_service() checks the ->s3_fns
* hook */
#define FN_LOCAL_STRING(fn_name,val) \
+ _PUBLIC_ char *lpcfg_ ## fn_name(struct loadparm_service *service, \
+ struct loadparm_service *sDefault, TALLOC_CTX *ctx) { \
+ return(talloc_strdup(ctx, lpcfg_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)))); \
+ }
+
+#define FN_LOCAL_CONST_STRING(fn_name,val) \
_PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_service *service, \
struct loadparm_service *sDefault) { \
- return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val))); \
+ return((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)); \
}
-#define FN_LOCAL_CONST_STRING(fn_name,val) FN_LOCAL_STRING(fn_name, val)
-
#define FN_LOCAL_LIST(fn_name,val) \
_PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_service *service, \
struct loadparm_service *sDefault) {\
FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
/* local prototypes */
-static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
+static struct loadparm_service *lpcfg_getservicebyname(struct loadparm_context *lp_ctx,
const char *pszServiceName);
-static void copy_service(struct loadparm_service *pserviceDest,
- struct loadparm_service *pserviceSource,
- struct bitmap *pcopymapDest);
static bool lpcfg_service_ok(struct loadparm_service *service);
static bool do_section(const char *pszSectionName, void *);
-static void init_copymap(struct loadparm_service *pservice);
/* This is a helper function for parametrical options support. */
/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
return NULL;
if (lp_ctx->s3_fns) {
- return lp_ctx->s3_fns->get_parametric(service, type, option);
+ return lp_ctx->s3_fns->get_parametric(service, type, option, NULL);
}
data = (service == NULL ? lp_ctx->globals->param_opt : service->param_opt);
/**
* convenience routine to return int parameters.
*/
-static int lp_int(const char *s)
+int lp_int(const char *s)
{
- if (!s) {
+ if (!s || !*s) {
DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
return -1;
}
/**
* convenience routine to return unsigned long parameters.
*/
-static unsigned long lp_ulong(const char *s)
+unsigned long lp_ulong(const char *s)
{
- if (!s) {
+ if (!s || !*s) {
DEBUG(0,("lp_ulong(%s): is called with NULL!\n",s));
return -1;
}
/**
* convenience routine to return boolean parameters.
*/
-static bool lp_bool(const char *s)
+bool lp_bool(const char *s)
{
bool ret = false;
- if (!s) {
+ if (!s || !*s) {
DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
return false;
}
return ret;
}
-
/**
* Return parametric option from a given service. Type is a part of option before ':'
* Parametric option has following syntax: 'Type: option = value'
const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
if (value)
- return lp_string(value);
+ return lpcfg_string(value);
return NULL;
}
}
-/**
- * Initialise a service to the defaults.
- */
-
-static struct loadparm_service *init_service(TALLOC_CTX *mem_ctx, struct loadparm_service *sDefault)
-{
- struct loadparm_service *pservice =
- talloc_zero(mem_ctx, struct loadparm_service);
- copy_service(pservice, sDefault, NULL);
- return pservice;
-}
-
/**
* Set a string value, deallocating any existing space, and allocing the space
* for the string
*/
-static bool lpcfg_string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
+bool lpcfg_string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
{
talloc_free(*dest);
const char *name)
{
int i;
- struct loadparm_service tservice;
int num_to_alloc = lp_ctx->iNumServices + 1;
struct parmlist_entry *data, *pdata;
pservice = lp_ctx->sDefault;
}
- tservice = *pservice;
-
/* it might already exist */
if (name) {
- struct loadparm_service *service = getservicebyname(lp_ctx,
+ struct loadparm_service *service = lpcfg_getservicebyname(lp_ctx,
name);
if (service != NULL) {
/* Clean all parametric options for service */
lp_ctx->iNumServices++;
}
- lp_ctx->services[i] = init_service(lp_ctx->services, lp_ctx->sDefault);
+ lp_ctx->services[i] = talloc_zero(lp_ctx->services, struct loadparm_service);
if (lp_ctx->services[i] == NULL) {
DEBUG(0,("lpcfg_add_service: out of memory!\n"));
return NULL;
}
- copy_service(lp_ctx->services[i], &tservice, NULL);
+ copy_service(lp_ctx->services[i], pservice, NULL);
if (name != NULL)
lpcfg_string_set(lp_ctx->services[i], &lp_ctx->services[i]->szService, name);
return lp_ctx->services[i];
|| strequal(default_service->path, lp_ctx->sDefault->path)) {
service->path = talloc_strdup(service, pszHomedir);
} else {
- service->path = string_sub_talloc(service, lpcfg_path(default_service, lp_ctx->sDefault), "%H", pszHomedir);
+ service->path = string_sub_talloc(service, lpcfg_path(default_service, lp_ctx->sDefault, service), "%H", pszHomedir);
}
if (!(*(service->comment))) {
* Find a service by name. Otherwise works like get_service.
*/
-static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
+static struct loadparm_service *lpcfg_getservicebyname(struct loadparm_context *lp_ctx,
const char *pszServiceName)
{
int iService;
return NULL;
}
+/**
+ * Add a parametric option to a parmlist_entry,
+ * replacing old value, if already present.
+ */
+void set_param_opt(TALLOC_CTX *mem_ctx,
+ struct parmlist_entry **opt_list,
+ const char *opt_name,
+ const char *opt_value,
+ unsigned priority)
+{
+ struct parmlist_entry *new_opt, *opt;
+ bool not_added;
+
+ opt = *opt_list;
+ not_added = true;
+
+ /* Traverse destination */
+ while (opt) {
+ /* If we already have same option, override it */
+ if (strwicmp(opt->key, opt_name) == 0) {
+ if ((opt->priority & FLAG_CMDLINE) &&
+ !(priority & FLAG_CMDLINE)) {
+ /* it's been marked as not to be
+ overridden */
+ return;
+ }
+ TALLOC_FREE(opt->value);
+ TALLOC_FREE(opt->list);
+ opt->value = talloc_strdup(opt, opt_value);
+ opt->priority = priority;
+ not_added = false;
+ break;
+ }
+ 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);
+ }
+}
+
/**
* Copy a service structure to another.
* If pcopymapDest is NULL then copy all fields
*/
-static void copy_service(struct loadparm_service *pserviceDest,
- struct loadparm_service *pserviceSource,
- struct bitmap *pcopymapDest)
+void copy_service(struct loadparm_service *pserviceDest,
+ const struct loadparm_service *pserviceSource,
+ struct bitmap *pcopymapDest)
{
int i;
bool bcopyall = (pcopymapDest == NULL);
- struct parmlist_entry *data, *pdata, *paramo;
- bool not_added;
+ struct parmlist_entry *data;
for (i = 0; parm_table[i].label; i++)
if (parm_table[i].p_class == P_LOCAL &&
(bcopyall || bitmap_query(pcopymapDest, i))) {
- void *src_ptr =
- ((char *)pserviceSource) + parm_table[i].offset;
+ const void *src_ptr =
+ ((const char *)pserviceSource) + parm_table[i].offset;
void *dest_ptr =
((char *)pserviceDest) + parm_table[i].offset;
switch (parm_table[i].type) {
case P_BOOL:
case P_BOOLREV:
- *(bool *)dest_ptr = *(bool *)src_ptr;
+ *(bool *)dest_ptr = *(const bool *)src_ptr;
break;
case P_INTEGER:
case P_BYTES:
case P_OCTAL:
case P_ENUM:
- *(int *)dest_ptr = *(int *)src_ptr;
+ *(int *)dest_ptr = *(const int *)src_ptr;
break;
case P_CHAR:
- *(char *)dest_ptr = *(char *)src_ptr;
+ *(char *)dest_ptr = *(const char *)src_ptr;
break;
case P_STRING:
lpcfg_string_set(pserviceDest,
(char **)dest_ptr,
- *(char **)src_ptr);
+ *(const char * const *)src_ptr);
break;
case P_USTRING:
lpcfg_string_set_upper(pserviceDest,
(char **)dest_ptr,
- *(char **)src_ptr);
+ *(const char * const *)src_ptr);
break;
+ case P_CMDLIST:
case P_LIST:
- *(const char ***)dest_ptr = (const char **)str_list_copy(pserviceDest,
- *(const char ***)src_ptr);
+ TALLOC_FREE(*((char ***)dest_ptr));
+ *(const char * const **)dest_ptr = (const char * const *)str_list_copy(pserviceDest,
+ *(const char * * const *)src_ptr);
break;
default:
break;
pserviceSource->copymap);
}
- data = pserviceSource->param_opt;
- while (data) {
- not_added = true;
- pdata = pserviceDest->param_opt;
- /* Traverse destination */
- while (pdata) {
- /* If we already have same option, override it */
- if (strcmp(pdata->key, data->key) == 0) {
- talloc_free(pdata->value);
- pdata->value = talloc_strdup(pdata,
- data->value);
- not_added = false;
- break;
- }
- pdata = pdata->next;
- }
- if (not_added) {
- paramo = talloc_zero(pserviceDest, struct parmlist_entry);
- if (paramo == NULL)
- smb_panic("OOM");
- paramo->key = talloc_strdup(paramo, data->key);
- paramo->value = talloc_strdup(paramo, data->value);
- DLIST_ADD(pserviceDest->param_opt, paramo);
- }
- data = data->next;
+ for (data = pserviceSource->param_opt; data != NULL; data = data->next) {
+ set_param_opt(pserviceDest, &pserviceDest->param_opt,
+ data->key, data->value, data->priority);
}
}
it's date and needs to be reloaded.
********************************************************************/
-static void add_to_file_list(struct loadparm_context *lp_ctx,
+void add_to_file_list(TALLOC_CTX *mem_ctx, struct file_lists **list,
const char *fname, const char *subfname)
{
- struct file_lists *f = lp_ctx->file_lists;
+ struct file_lists *f = *list;
while (f) {
if (f->name && !strcmp(f->name, fname))
}
if (!f) {
- f = talloc(lp_ctx, struct file_lists);
+ f = talloc(mem_ctx, struct file_lists);
if (!f)
- return;
- f->next = lp_ctx->file_lists;
+ goto fail;
+ f->next = *list;
f->name = talloc_strdup(f, fname);
if (!f->name) {
- talloc_free(f);
- return;
+ TALLOC_FREE(f);
+ goto fail;
}
f->subfname = talloc_strdup(f, subfname);
if (!f->subfname) {
- talloc_free(f);
- return;
+ TALLOC_FREE(f);
+ goto fail;
}
- lp_ctx->file_lists = f;
+ *list = f;
f->modtime = file_modtime(subfname);
} else {
time_t t = file_modtime(subfname);
if (t)
f->modtime = t;
}
+ return;
+
+fail:
+ DEBUG(0, ("Unable to add file to file list: %s\n", fname));
+
}
/*******************************************************************
return false;
}
+/*
+ * set the value for a P_ENUM
+ */
+bool lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
+ int *ptr )
+{
+ int i;
+
+ for (i = 0; parm->enum_list[i].name; i++) {
+ if ( strequal(pszParmValue, parm->enum_list[i].name)) {
+ *ptr = parm->enum_list[i].value;
+ return true;
+ }
+ }
+ DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
+ pszParmValue, parm->label));
+ return false;
+}
+
+
/***************************************************************************
Handle the "realm" parameter
***************************************************************************/
-static bool handle_realm(struct loadparm_context *lp_ctx, int unused,
- const char *pszParmValue, char **ptr)
+bool handle_realm(struct loadparm_context *lp_ctx, int unused,
+ const char *pszParmValue, char **ptr)
{
- lpcfg_string_set(lp_ctx, ptr, pszParmValue);
+ char *upper;
+ char *lower;
- talloc_free(lp_ctx->globals->realm);
- talloc_free(lp_ctx->globals->dnsdomain);
+ upper = strupper_talloc(lp_ctx, pszParmValue);
+ if (upper == NULL) {
+ return false;
+ }
- lp_ctx->globals->realm = strupper_talloc(lp_ctx, pszParmValue);
- lp_ctx->globals->dnsdomain = strlower_talloc(lp_ctx, pszParmValue);
+ lower = strlower_talloc(lp_ctx, pszParmValue);
+ if (lower == NULL) {
+ TALLOC_FREE(upper);
+ return false;
+ }
+
+ if (lp_ctx->s3_fns != NULL) {
+ lp_ctx->s3_fns->lp_string_set(ptr, pszParmValue);
+ lp_ctx->s3_fns->lp_string_set(&lp_ctx->globals->realm, upper);
+ lp_ctx->s3_fns->lp_string_set(&lp_ctx->globals->dnsdomain, lower);
+ } else {
+ lpcfg_string_set(lp_ctx, ptr, pszParmValue);
+ lpcfg_string_set(lp_ctx, &lp_ctx->globals->realm, upper);
+ lpcfg_string_set(lp_ctx, &lp_ctx->globals->dnsdomain, lower);
+ }
return true;
}
Handle the include operation.
***************************************************************************/
-static bool handle_include(struct loadparm_context *lp_ctx, int unused,
+bool handle_include(struct loadparm_context *lp_ctx, int unused,
const char *pszParmValue, char **ptr)
{
- char *fname = standard_sub_basic(lp_ctx, pszParmValue);
+ char *fname;
- add_to_file_list(lp_ctx, pszParmValue, fname);
+ if (lp_ctx->s3_fns) {
+ return lp_ctx->s3_fns->lp_include(lp_ctx, unused, pszParmValue, ptr);
+ }
+
+ fname = standard_sub_basic(lp_ctx, pszParmValue);
+
+ add_to_file_list(lp_ctx, &lp_ctx->file_lists, pszParmValue, fname);
lpcfg_string_set(lp_ctx, ptr, fname);
Handle the interpretation of the copy parameter.
***************************************************************************/
-static bool handle_copy(struct loadparm_context *lp_ctx, int unused,
+bool handle_copy(struct loadparm_context *lp_ctx, int snum,
const char *pszParmValue, char **ptr)
{
bool bRetval;
- struct loadparm_service *serviceTemp;
-
- lpcfg_string_set(lp_ctx, ptr, pszParmValue);
+ struct loadparm_service *serviceTemp = NULL;
+ struct loadparm_service *current = NULL;
bRetval = false;
DEBUG(3, ("Copying service from service %s\n", pszParmValue));
- if ((serviceTemp = getservicebyname(lp_ctx, pszParmValue)) != NULL) {
- if (serviceTemp == lp_ctx->currentService) {
+ serviceTemp = lpcfg_getservicebyname(lp_ctx, pszParmValue);
+ if (lp_ctx->s3_fns != NULL) {
+ current = lp_ctx->s3_fns->get_servicebynum(snum);
+ } else {
+ current = lp_ctx->currentService;
+ }
+
+ if (current == NULL) {
+ DEBUG(0, ("Unable to copy service - invalid service destination"));
+ return false;
+ }
+
+ if (serviceTemp != NULL) {
+ if (serviceTemp == current) {
DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
} else {
- copy_service(lp_ctx->currentService,
+ copy_service(current,
serviceTemp,
- lp_ctx->currentService->copymap);
+ current->copymap);
+ lpcfg_string_set(current, ptr, pszParmValue);
+
bRetval = true;
}
} else {
return bRetval;
}
-static bool handle_debug_list(struct loadparm_context *lp_ctx, int unused,
+bool handle_debug_list(struct loadparm_context *lp_ctx, int unused,
const char *pszParmValue, char **ptr)
{
+ if (lp_ctx->s3_fns != NULL) {
+ lp_ctx->s3_fns->lp_string_set(ptr, pszParmValue);
+ } else {
+ lpcfg_string_set(lp_ctx, ptr, pszParmValue);
+ }
+
+ return debug_parse_levels(pszParmValue);
+}
- lpcfg_string_set(lp_ctx, ptr, pszParmValue);
- if (lp_ctx->global) {
- return debug_parse_levels(pszParmValue);
+bool handle_logfile(struct loadparm_context *lp_ctx, int unused,
+ const char *pszParmValue, char **ptr)
+{
+ if (lp_ctx->s3_fns != NULL) {
+ lp_ctx->s3_fns->lp_string_set(ptr, pszParmValue);
+ } else {
+ debug_set_logfile(pszParmValue);
+ lpcfg_string_set(lp_ctx, ptr, pszParmValue);
}
+
return true;
}
-static bool handle_logfile(struct loadparm_context *lp_ctx, int unused,
+/*
+ * These special charset handling methods only run in the source3 code.
+ */
+
+bool handle_charset(struct loadparm_context *lp_ctx, int snum,
const char *pszParmValue, char **ptr)
{
- debug_set_logfile(pszParmValue);
- if (lp_ctx->global) {
- lpcfg_string_set(lp_ctx, ptr, pszParmValue);
+ if (lp_ctx->s3_fns) {
+ if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
+ lp_ctx->s3_fns->lp_string_set(ptr, pszParmValue);
+ global_iconv_handle = smb_iconv_handle_reinit(NULL,
+ lpcfg_dos_charset(lp_ctx),
+ lpcfg_unix_charset(lp_ctx),
+ true, global_iconv_handle);
+ }
+
+ return true;
+ }
+ return lpcfg_string_set(lp_ctx, ptr, pszParmValue);
+
+}
+
+bool handle_dos_charset(struct loadparm_context *lp_ctx, int snum,
+ const char *pszParmValue, char **ptr)
+{
+ bool is_utf8 = false;
+ size_t len = strlen(pszParmValue);
+
+ if (lp_ctx->s3_fns) {
+ if (len == 4 || len == 5) {
+ /* Don't use StrCaseCmp here as we don't want to
+ initialize iconv. */
+ if ((toupper_m(pszParmValue[0]) == 'U') &&
+ (toupper_m(pszParmValue[1]) == 'T') &&
+ (toupper_m(pszParmValue[2]) == 'F')) {
+ if (len == 4) {
+ if (pszParmValue[3] == '8') {
+ is_utf8 = true;
+ }
+ } else {
+ if (pszParmValue[3] == '-' &&
+ pszParmValue[4] == '8') {
+ is_utf8 = true;
+ }
+ }
+ }
+ }
+
+ if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
+ 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;
+ }
+ lp_ctx->s3_fns->lp_string_set(ptr, pszParmValue);
+ global_iconv_handle = smb_iconv_handle_reinit(NULL,
+ lpcfg_dos_charset(lp_ctx),
+ lpcfg_unix_charset(lp_ctx),
+ true, global_iconv_handle);
+ }
+ return true;
+ }
+
+ return lpcfg_string_set(lp_ctx, ptr, pszParmValue);
+}
+
+bool handle_printing(struct loadparm_context *lp_ctx, int snum,
+ 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_set_enum_parm(&parm_table[parm_num], pszParmValue, (int*)ptr)) {
+ return false;
+ }
+
+ if (lp_ctx->s3_fns) {
+ if ( snum < 0 ) {
+ s = lp_ctx->sDefault;
+ lp_ctx->s3_fns->init_printer_values(lp_ctx->globals->ctx, s);
+ } else {
+ s = lp_ctx->services[snum];
+ lp_ctx->s3_fns->init_printer_values(s, s);
+ }
+ }
+
+ return true;
+}
+
+bool handle_ldap_debug_level(struct loadparm_context *lp_ctx, int snum, const char *pszParmValue, char **ptr)
+{
+ lp_ctx->globals->ldap_debug_level = lp_int(pszParmValue);
+
+ if (lp_ctx->s3_fns) {
+ lp_ctx->s3_fns->init_ldap_debugging();
}
return true;
}
+bool handle_netbios_aliases(struct loadparm_context *lp_ctx, int snum, 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);
+
+ if (lp_ctx->s3_fns) {
+ return lp_ctx->s3_fns->set_netbios_aliases(lp_ctx->globals->netbios_aliases);
+ }
+ return true;
+}
+
+/*
+ * idmap related parameters
+ */
+
+bool handle_idmap_backend(struct loadparm_context *lp_ctx, int snum, const char *pszParmValue, char **ptr)
+{
+ if (lp_ctx->s3_fns) {
+ return lp_ctx->s3_fns->lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
+ }
+
+ return lpcfg_string_set(lp_ctx, ptr, pszParmValue);
+}
+
+bool handle_idmap_uid(struct loadparm_context *lp_ctx, int snum, const char *pszParmValue, char **ptr)
+{
+ if (lp_ctx->s3_fns) {
+ return lp_ctx->s3_fns->lp_do_parameter(snum, "idmap config * : range", pszParmValue);
+ }
+
+ return lpcfg_string_set(lp_ctx, ptr, pszParmValue);
+}
+
+bool handle_idmap_gid(struct loadparm_context *lp_ctx, int snum, const char *pszParmValue, char **ptr)
+{
+ if (lp_ctx->s3_fns) {
+ return lp_ctx->s3_fns->lp_do_parameter(snum, "idmap config * : range", pszParmValue);
+ }
+
+ return lpcfg_string_set(lp_ctx, ptr, pszParmValue);
+}
+
/***************************************************************************
Initialise a copymap.
***************************************************************************/
-static void init_copymap(struct loadparm_service *pservice)
+void init_copymap(struct loadparm_service *pservice)
{
int i;
const char *pszParmName,
const char *pszParmValue, int flags)
{
- struct parmlist_entry *paramo, *data;
+ struct parmlist_entry **data;
char *name;
TALLOC_CTX *mem_ctx;
if (!name) return false;
if (service == NULL) {
- data = lp_ctx->globals->param_opt;
+ data = &lp_ctx->globals->param_opt;
mem_ctx = lp_ctx->globals;
} else {
- data = service->param_opt;
+ data = &service->param_opt;
mem_ctx = service;
}
- /* Traverse destination */
- for (paramo=data; paramo; paramo=paramo->next) {
- /* If we already have the option set, override it unless
- it was a command line option and the new one isn't */
- if (strcmp(paramo->key, name) == 0) {
- if ((paramo->priority & FLAG_CMDLINE) &&
- !(flags & FLAG_CMDLINE)) {
- talloc_free(name);
- return true;
- }
-
- talloc_free(paramo->value);
- paramo->value = talloc_strdup(paramo, pszParmValue);
- paramo->priority = flags;
- talloc_free(name);
- return true;
- }
- }
-
- paramo = talloc_zero(mem_ctx, struct parmlist_entry);
- if (!paramo)
- smb_panic("OOM");
- paramo->key = talloc_strdup(paramo, name);
- paramo->value = talloc_strdup(paramo, pszParmValue);
- paramo->priority = flags;
- if (service == NULL) {
- DLIST_ADD(lp_ctx->globals->param_opt, paramo);
- } else {
- DLIST_ADD(service->param_opt, paramo);
- }
+ set_param_opt(mem_ctx, data, name, pszParmValue, flags);
talloc_free(name);
}
case P_CMDLIST:
- *(const char ***)parm_ptr = (const char **)str_list_make(mem_ctx,
- pszParmValue, NULL);
+ *(const char * const **)parm_ptr
+ = (const char * const *)str_list_make(mem_ctx,
+ pszParmValue, NULL);
break;
case P_LIST:
{
pszParmName, pszParmValue));
return false;
}
- *(const char ***)parm_ptr = (const char **) new_list;
+ *(const char * const **)parm_ptr = (const char * const *) new_list;
break;
}
}
break;
case P_ENUM:
- for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
- if (strequal
- (pszParmValue,
- parm_table[parmnum].enum_list[i].name)) {
- *(int *)parm_ptr =
- parm_table[parmnum].
- enum_list[i].value;
- break;
- }
- }
- if (!parm_table[parmnum].enum_list[i].name) {
- DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
- pszParmValue, pszParmName));
+ if (!lp_set_enum_parm(&parm_table[parmnum], pszParmValue, (int*)parm_ptr)) {
return false;
}
break;
int parmnum;
int i;
+ while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
+
if (lp_ctx->s3_fns) {
return lp_ctx->s3_fns->set_cmdline(pszParmName, pszParmValue);
}
parmnum = lpcfg_map_parameter(pszParmName);
- while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
-
-
if (parmnum < 0 && strchr(pszParmName, ':')) {
/* set a parametric option */
return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName,
switch (parm_table[i].type) {
case P_CMDLIST:
case P_LIST:
- return str_list_equal((const char **)parm_table[i].def.lvalue,
+ return str_list_equal((const char * const *)parm_table[i].def.lvalue,
(const char **)def_ptr);
case P_STRING:
case P_USTRING:
talloc_set_destructor(lp_ctx, lpcfg_destructor);
lp_ctx->bInGlobalSection = true;
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->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
+ lp_ctx->flags = talloc_zero_array(lp_ctx, unsigned int, NUMPARAMETERS);
lp_ctx->sDefault->iMaxPrintJobs = 1000;
lp_ctx->sDefault->bAvailable = true;
lpcfg_do_global_parameter(lp_ctx, "ReadRaw", "True");
lpcfg_do_global_parameter(lp_ctx, "WriteRaw", "True");
lpcfg_do_global_parameter(lp_ctx, "NullPasswords", "False");
+ lpcfg_do_global_parameter(lp_ctx, "old password allowed period", "60");
lpcfg_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
lpcfg_do_global_parameter(lp_ctx, "TimeServer", "False");
lpcfg_do_global_parameter(lp_ctx, "enable privileges", "True");
- lpcfg_do_global_parameter(lp_ctx, "smb2 max write", "1048576");
+ lpcfg_do_global_parameter_var(lp_ctx, "smb2 max write", "%u", DEFAULT_SMB2_MAX_WRITE);
lpcfg_do_global_parameter(lp_ctx, "passdb backend", "tdbsam");
lpcfg_do_global_parameter(lp_ctx, "mangled names", "True");
- lpcfg_do_global_parameter(lp_ctx, "smb2 max credits", "8192");
+ lpcfg_do_global_parameter_var(lp_ctx, "smb2 max credits", "%u", DEFAULT_SMB2_MAX_CREDITS);
lpcfg_do_global_parameter(lp_ctx, "ldap ssl", "start tls");
lpcfg_do_global_parameter(lp_ctx, "lpq cache time", "30");
- lpcfg_do_global_parameter(lp_ctx, "smb2 max trans", "1048576");
+ lpcfg_do_global_parameter_var(lp_ctx, "smb2 max trans", "%u", DEFAULT_SMB2_MAX_TRANSACT);
- lpcfg_do_global_parameter(lp_ctx, "smb2 max read", "1048576");
+ lpcfg_do_global_parameter_var(lp_ctx, "smb2 max read", "%u", DEFAULT_SMB2_MAX_READ);
lpcfg_do_global_parameter(lp_ctx, "durable handles", "yes");
return NULL;
}
loadparm_context->s3_fns = s3_fns;
+ loadparm_context->globals = s3_fns->globals;
return loadparm_context;
}
static bool lpcfg_update(struct loadparm_context *lp_ctx)
{
struct debug_settings settings;
- lpcfg_add_auto_services(lp_ctx, lpcfg_auto_services(lp_ctx));
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(lp_ctx);
+ if (tmp_ctx == NULL) {
+ return false;
+ }
+
+ lpcfg_add_auto_services(lp_ctx, lpcfg_auto_services(lp_ctx, tmp_ctx));
if (!lp_ctx->globals->wins_server_list && lp_ctx->globals->we_are_a_wins_server) {
lpcfg_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
}
if (!lp_ctx->global) {
+ TALLOC_FREE(tmp_ctx);
return true;
}
unsetenv("SOCKET_TESTNONBLOCK");
}
+ TALLOC_FREE(tmp_ctx);
return true;
}
n2 = standard_sub_basic(lp_ctx, lp_ctx->szConfigFile);
DEBUG(2, ("lpcfg_load: refreshing parameters from %s\n", n2));
- add_to_file_list(lp_ctx, lp_ctx->szConfigFile, n2);
+ add_to_file_list(lp_ctx, &lp_ctx->file_lists, lp_ctx->szConfigFile, n2);
/* We get sections first, so have to start 'behind' to make up */
lp_ctx->currentService = NULL;
const char *lpcfg_servicename(const struct loadparm_service *service)
{
- return lp_string((const char *)service->szService);
+ return lpcfg_string((const char *)service->szService);
}
/**
const char *lpcfg_volume_label(struct loadparm_service *service, struct loadparm_service *sDefault)
{
const char *ret;
- ret = lp_string((const char *)((service != NULL && service->volume != NULL) ?
+ ret = lpcfg_string((const char *)((service != NULL && service->volume != NULL) ?
service->volume : sDefault->volume));
if (!*ret)
return lpcfg_servicename(service);
const char *lpcfg_printername(struct loadparm_service *service, struct loadparm_service *sDefault)
{
const char *ret;
- ret = lp_string((const char *)((service != NULL && service->_printername != NULL) ?
+ ret = lpcfg_string((const char *)((service != NULL && service->_printername != NULL) ?
service->_printername : sDefault->_printername));
if (ret == NULL || (ret != NULL && *ret == '\0'))
ret = lpcfg_servicename(service);
_PUBLIC_ char *lpcfg_tls_keyfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
{
- return lpcfg_private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_keyfile);
+ return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_keyfile(lp_ctx));
}
_PUBLIC_ char *lpcfg_tls_certfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
{
- return lpcfg_private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_certfile);
+ return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_certfile(lp_ctx));
}
_PUBLIC_ char *lpcfg_tls_cafile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
{
- return lpcfg_private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_cafile);
+ return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_cafile(lp_ctx));
}
_PUBLIC_ char *lpcfg_tls_crlfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
{
- return lpcfg_private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_crlfile);
+ return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_crlfile(lp_ctx));
}
_PUBLIC_ char *lpcfg_tls_dhpfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
{
- return lpcfg_private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_dhpfile);
+ return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_dhpfile(lp_ctx));
}
struct gensec_settings *lpcfg_gensec_settings(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
return allowed;
}
+
+int lpcfg_tdb_hash_size(struct loadparm_context *lp_ctx, const char *name)
+{
+ const char *base;
+
+ if (name == NULL) {
+ return 0;
+ }
+
+ base = strrchr_m(name, '/');
+ if (base != NULL) {
+ base += 1;
+ } else {
+ base = name;
+ }
+ return lpcfg_parm_int(lp_ctx, NULL, "tdb_hashsize", base, 0);
+
+}
+
+int lpcfg_tdb_flags(struct loadparm_context *lp_ctx, int tdb_flags)
+{
+ if (!lpcfg_use_mmap(lp_ctx)) {
+ tdb_flags |= TDB_NOMMAP;
+ }
+ return tdb_flags;
+}