From: Aaron Haslett Date: Mon, 30 Apr 2018 23:10:36 +0000 (+1200) Subject: param: Add non-global smb.cfg option (support 2 different smb.confs) X-Git-Tag: tevent-0.9.37~212 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5728867ddcc4487bde53a11cf865563b59624eb1;p=thirdparty%2Fsamba.git param: Add non-global smb.cfg option (support 2 different smb.confs) The default behaviour is that there is only a single global underlying LoadParm object. E.g. if you create 2 different LoadParm objects in python, they both modify the same underlying object. This patch adds a mechanism to override this and create a separate non-global LoadParm object. The use-case is the backup tool, where we want to manipulate 2 different smb.conf files (the one used to create the backup, and the smb.conf in the backup itself). Signed-off-by: Aaron Haslett Reviewed-by: Douglas Bagnall Reviewed-by: Andrew Bartlett --- diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 3b7f8053e4a..9684a52952b 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3148,7 +3148,8 @@ bool lpcfg_load_default(struct loadparm_context *lp_ctx) * * Return True on success, False on failure. */ -bool lpcfg_load(struct loadparm_context *lp_ctx, const char *filename) +static bool lpcfg_load_internal(struct loadparm_context *lp_ctx, + const char *filename, bool set_global) { char *n2; bool bRetval; @@ -3183,7 +3184,7 @@ bool lpcfg_load(struct loadparm_context *lp_ctx, const char *filename) for a missing smb.conf */ reload_charcnv(lp_ctx); - if (bRetval == true) { + if (bRetval == true && set_global) { /* set this up so that any child python tasks will find the right smb.conf */ setenv("SMB_CONF_PATH", filename, 1); @@ -3197,6 +3198,16 @@ bool lpcfg_load(struct loadparm_context *lp_ctx, const char *filename) return bRetval; } +bool lpcfg_load_no_global(struct loadparm_context *lp_ctx, const char *filename) +{ + return lpcfg_load_internal(lp_ctx, filename, false); +} + +bool lpcfg_load(struct loadparm_context *lp_ctx, const char *filename) +{ + return lpcfg_load_internal(lp_ctx, filename, true); +} + /** * Return the max number of services. */ diff --git a/source4/param/pyparam.c b/source4/param/pyparam.c index e7e908fcac3..11257c356aa 100644 --- a/source4/param/pyparam.c +++ b/source4/param/pyparam.c @@ -445,7 +445,52 @@ static PyGetSetDef py_lp_ctx_getset[] = { static PyObject *py_lp_ctx_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - return pytalloc_reference(type, loadparm_init_global(false)); + const char *kwnames[] = {"filename_for_non_global_lp", NULL}; + PyObject *lp_ctx; + const char *non_global_conf = NULL; + struct loadparm_context *ctx; + + if (!PyArg_ParseTupleAndKeywords(args, + kwargs, + "|s", + discard_const_p(char *, + kwnames), + &non_global_conf)) { + return NULL; + } + + /* + * by default, any LoadParm python objects map to a single global + * underlying object. The filename_for_non_global_lp arg overrides this + * default behaviour and creates a separate underlying LoadParm object. + */ + if (non_global_conf != NULL) { + bool ok; + ctx = loadparm_init(NULL); + if (ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + lp_ctx = pytalloc_reference(type, ctx); + if (lp_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ok = lpcfg_load_no_global( + PyLoadparmContext_AsLoadparmContext(lp_ctx), + non_global_conf); + if (!ok) { + PyErr_Format(PyExc_ValueError, + "Could not load non-global conf %s", + non_global_conf); + return NULL; + } + return lp_ctx; + } else{ + return pytalloc_reference(type, loadparm_init_global(false)); + } } static Py_ssize_t py_lp_ctx_len(PyObject *self)