summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/util/charset/charcnv.c40
-rw-r--r--lib/util/charset/charset.h9
-rw-r--r--lib/util/charset/util_unistr.c3
-rw-r--r--librpc/ndr/ndr.c6
-rwxr-xr-xpidl/tests/ndr_string.pl12
-rw-r--r--source4/param/loadparm.c12
-rw-r--r--source4/param/param.h5
-rw-r--r--source4/param/util.c12
-rw-r--r--source4/scripting/python/modules.h3
9 files changed, 69 insertions, 33 deletions
diff --git a/lib/util/charset/charcnv.c b/lib/util/charset/charcnv.c
index a479f44426..efdb3ed2b3 100644
--- a/lib/util/charset/charcnv.c
+++ b/lib/util/charset/charcnv.c
@@ -39,6 +39,7 @@
*/
struct smb_iconv_convenience {
+ TALLOC_CTX *child_ctx;
const char *unix_charset;
const char *dos_charset;
bool native_iconv;
@@ -83,22 +84,45 @@ static int close_iconv_convenience(struct smb_iconv_convenience *data)
return 0;
}
-_PUBLIC_ struct smb_iconv_convenience *smb_iconv_convenience_init(TALLOC_CTX *mem_ctx,
- const char *dos_charset,
- const char *unix_charset,
- bool native_iconv)
+/*
+ the old_ic is passed in here as the smb_iconv_convenience structure
+ is used as a global pointer in some places (eg. python modules). We
+ don't want to invalidate those global pointers, but we do want to
+ update them with the right charset information when loadparm
+ runs. To do that we need to re-use the structure pointer, but
+ re-fill the elements in the structure with the updated values
+ */
+_PUBLIC_ struct smb_iconv_convenience *smb_iconv_convenience_reinit(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset,
+ bool native_iconv,
+ struct smb_iconv_convenience *old_ic)
{
- struct smb_iconv_convenience *ret = talloc_zero(mem_ctx,
- struct smb_iconv_convenience);
+ struct smb_iconv_convenience *ret;
+ if (old_ic != NULL) {
+ ret = old_ic;
+ close_iconv_convenience(ret);
+ talloc_free(ret->child_ctx);
+ ZERO_STRUCTP(ret);
+ } else {
+ ret = talloc_zero(mem_ctx, struct smb_iconv_convenience);
+ }
if (ret == NULL) {
return NULL;
}
+ /* we use a child context to allow us to free all ptrs without
+ freeing the structure itself */
+ ret->child_ctx = talloc_new(ret);
+ if (ret->child_ctx == NULL) {
+ return NULL;
+ }
+
talloc_set_destructor(ret, close_iconv_convenience);
- ret->dos_charset = talloc_strdup(ret, dos_charset);
- ret->unix_charset = talloc_strdup(ret, unix_charset);
+ ret->dos_charset = talloc_strdup(ret->child_ctx, dos_charset);
+ ret->unix_charset = talloc_strdup(ret->child_ctx, unix_charset);
ret->native_iconv = native_iconv;
return ret;
diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h
index 2c8aa41ad5..cc57b3eb54 100644
--- a/lib/util/charset/charset.h
+++ b/lib/util/charset/charset.h
@@ -163,10 +163,11 @@ codepoint_t tolower_m(codepoint_t val);
int codepoint_cmpi(codepoint_t c1, codepoint_t c2);
/* Iconv convenience functions */
-struct smb_iconv_convenience *smb_iconv_convenience_init(TALLOC_CTX *mem_ctx,
- const char *dos_charset,
- const char *unix_charset,
- bool native_iconv);
+struct smb_iconv_convenience *smb_iconv_convenience_reinit(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset,
+ bool native_iconv,
+ struct smb_iconv_convenience *old_ic);
bool convert_string_convenience(struct smb_iconv_convenience *ic,
charset_t from, charset_t to,
diff --git a/lib/util/charset/util_unistr.c b/lib/util/charset/util_unistr.c
index f8207261c5..520ce05468 100644
--- a/lib/util/charset/util_unistr.c
+++ b/lib/util/charset/util_unistr.c
@@ -26,7 +26,8 @@ struct smb_iconv_convenience *global_iconv_convenience = NULL;
static inline struct smb_iconv_convenience *get_iconv_convenience(void)
{
if (global_iconv_convenience == NULL)
- global_iconv_convenience = smb_iconv_convenience_init(talloc_autofree_context(), "ASCII", "UTF-8", true);
+ global_iconv_convenience = smb_iconv_convenience_reinit(talloc_autofree_context(),
+ "ASCII", "UTF-8", true, NULL);
return global_iconv_convenience;
}
diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
index 4d763e0ead..90be787526 100644
--- a/librpc/ndr/ndr.c
+++ b/librpc/ndr/ndr.c
@@ -260,7 +260,8 @@ _PUBLIC_ void ndr_print_function_debug(ndr_print_function_t fn, const char *name
* this all the way down
*/
#if _SAMBA_BUILD_ == 4
- ndr->iconv_convenience = smb_iconv_convenience_init(talloc_autofree_context(), "ASCII", "UTF-8", true);
+ ndr->iconv_convenience = smb_iconv_convenience_reinit(talloc_autofree_context(),
+ "ASCII", "UTF-8", true, NULL);
#endif
fn(ndr, name, flags, ptr);
@@ -289,7 +290,8 @@ _PUBLIC_ char *ndr_print_struct_string(TALLOC_CTX *mem_ctx, ndr_print_fn_t fn, c
* this all the way down
*/
#if _SAMBA_BUILD_ == 4
- ndr->iconv_convenience = smb_iconv_convenience_init(talloc_autofree_context(), "ASCII", "UTF-8", true);
+ ndr->iconv_convenience = smb_iconv_convenience_reinit(talloc_autofree_context(),
+ "ASCII", "UTF-8", true, NULL);
#endif
fn(ndr, name, ptr);
diff --git a/pidl/tests/ndr_string.pl b/pidl/tests/ndr_string.pl
index 7b76c7b295..e00dd01c8e 100755
--- a/pidl/tests/ndr_string.pl
+++ b/pidl/tests/ndr_string.pl
@@ -15,7 +15,7 @@ test_samba4_ndr("string-pull-empty",
uint8_t data[] = { 0x00, 0x00, 0x00, 0x00 };
DATA_BLOB b = { data, 4 };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
r.in.data = NULL;
@@ -38,7 +38,7 @@ test_samba4_ndr("string-ascii-pull",
\'f\', \'o\', \'o\', 0 };
DATA_BLOB b = { data, 8 };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
r.in.data = NULL;
@@ -75,7 +75,7 @@ test_samba4_ndr("string-wchar-fixed-array-01",
};
DATA_BLOB b = { data, sizeof(data) };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
struct TestStringStruct str;
r.in.str = &str;
@@ -121,7 +121,7 @@ test_samba4_ndr("string-wchar-fixed-array-02",
};
DATA_BLOB b = { data, sizeof(data) };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
struct TestStringStruct str;
r.in.str = &str;
@@ -153,7 +153,7 @@ test_samba4_ndr("string-wchar-fixed-array-03",
};
DATA_BLOB b = { data, sizeof(data) };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
struct TestStringStruct str;
r.in.str = &str;
@@ -175,7 +175,7 @@ test_samba4_ndr("string-out",
\'f\', \'o\', \'o\', 0 };
DATA_BLOB b = { data, 8 };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
char *str = NULL;
r.out.data = &str;
diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c
index 46bbceb862..2bee0fbd86 100644
--- a/source4/param/loadparm.c
+++ b/source4/param/loadparm.c
@@ -2692,8 +2692,8 @@ struct smb_iconv_convenience *lp_iconv_convenience(struct loadparm_context *lp_c
if (lp_ctx == NULL) {
static struct smb_iconv_convenience *fallback_ic = NULL;
if (fallback_ic == NULL)
- fallback_ic = smb_iconv_convenience_init(talloc_autofree_context(),
- "CP850", "UTF8", true);
+ fallback_ic = smb_iconv_convenience_reinit(talloc_autofree_context(),
+ "CP850", "UTF8", true, NULL);
return fallback_ic;
}
return lp_ctx->iconv_convenience;
@@ -2701,8 +2701,12 @@ struct smb_iconv_convenience *lp_iconv_convenience(struct loadparm_context *lp_c
_PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx)
{
- talloc_unlink(lp_ctx, lp_ctx->iconv_convenience);
- global_iconv_convenience = lp_ctx->iconv_convenience = smb_iconv_convenience_init_lp(lp_ctx, lp_ctx);
+ struct smb_iconv_convenience *old_ic = lp_ctx->iconv_convenience;
+ if (old_ic == NULL) {
+ old_ic = global_iconv_convenience;
+ }
+ lp_ctx->iconv_convenience = smb_iconv_convenience_reinit_lp(lp_ctx, lp_ctx, old_ic);
+ global_iconv_convenience = lp_ctx->iconv_convenience;
}
void lp_smbcli_options(struct loadparm_context *lp_ctx,
diff --git a/source4/param/param.h b/source4/param/param.h
index f72fa76174..5435941f2b 100644
--- a/source4/param/param.h
+++ b/source4/param/param.h
@@ -438,8 +438,9 @@ bool run_init_functions(init_module_fn *fns);
init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *subsystem);
const char *lp_messaging_path(TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx);
-struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx,
- struct loadparm_context *lp_ctx);
+struct smb_iconv_convenience *smb_iconv_convenience_reinit_lp(TALLOC_CTX *mem_ctx,
+ struct loadparm_context *lp_ctx,
+ struct smb_iconv_convenience *old_ic);
const char *lp_sam_name(struct loadparm_context *lp_ctx);
diff --git a/source4/param/util.c b/source4/param/util.c
index d9d4eb5e2b..bbe4c87293 100644
--- a/source4/param/util.c
+++ b/source4/param/util.c
@@ -299,12 +299,14 @@ const char *lp_messaging_path(TALLOC_CTX *mem_ctx,
return smbd_tmp_path(mem_ctx, lp_ctx, "messaging");
}
-struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx,
- struct loadparm_context *lp_ctx)
+struct smb_iconv_convenience *smb_iconv_convenience_reinit_lp(TALLOC_CTX *mem_ctx,
+ struct loadparm_context *lp_ctx,
+ struct smb_iconv_convenience *old_ic)
{
- return smb_iconv_convenience_init(mem_ctx, lp_dos_charset(lp_ctx),
- lp_unix_charset(lp_ctx),
- lp_parm_bool(lp_ctx, NULL, "iconv", "native", true));
+ return smb_iconv_convenience_reinit(mem_ctx, lp_dos_charset(lp_ctx),
+ lp_unix_charset(lp_ctx),
+ lp_parm_bool(lp_ctx, NULL, "iconv", "native", true),
+ old_ic);
}
diff --git a/source4/scripting/python/modules.h b/source4/scripting/python/modules.h
index 4d1067cdd4..c73cfff19c 100644
--- a/source4/scripting/python/modules.h
+++ b/source4/scripting/python/modules.h
@@ -23,6 +23,7 @@
void py_load_samba_modules(void);
bool py_update_path(const char *bindir);
-#define py_iconv_convenience(mem_ctx) smb_iconv_convenience_init(mem_ctx, "ASCII", PyUnicode_GetDefaultEncoding(), true)
+#define py_iconv_convenience(mem_ctx) smb_iconv_convenience_reinit(mem_ctx, "ASCII", \
+ PyUnicode_GetDefaultEncoding(), true, NULL)
#endif /* __SAMBA_PYTHON_MODULES_H__ */