[PATCH] Fix Bug 5917 - Samba does not work on site with Read Only Domain Controller
Volker Lendecke
Volker.Lendecke at SerNet.DE
Wed Sep 4 12:41:16 CEST 2013
On Tue, Sep 03, 2013 at 02:25:57PM -0700, Jeremy Allison wrote:
> On Wed, Sep 04, 2013 at 09:17:42AM +1200, Andrew Bartlett wrote:
> >
> > Thanks. While we are looking at additional changes, any chance of
> > changing this (for master) to use talloc?
> >
> > malloc()/free() is so 1990's ;-)
>
> Yeah, but this sits on top of gencache_XX, which is a
> bigger change from malloc->talloc than I want to bite
> off right now :-).
Here's a patchset that might be the basis for that. It also
fixes panics in two gencache error paths.
Please review&push.
Thanks,
Volker
--
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
*****************************************************************
visit us on it-sa:IT security exhibitions in Nürnberg, Germany
October 8th - 10th 2013, hall 12, booth 333
free tickets available via code 270691 on: www.it-sa.de/gutschein
******************************************************************
-------------- next part --------------
From 223f22a8cb666967bc5f3f9d3bb30e9889e127a4 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 4 Sep 2013 08:22:08 +0200
Subject: [PATCH 1/6] torture3: Fix a const warning
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/torture/torture.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 2d1a107..2d7e87f 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -8496,7 +8496,7 @@ static bool run_local_string_to_sid(int dummy) {
return true;
}
-static bool sid_to_string_test(char *expected) {
+static bool sid_to_string_test(const char *expected) {
char *str;
bool res = true;
struct dom_sid sid;
--
1.7.9.5
From bb0f88e73f09cf7b95b2acee39e6fceb58677504 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 4 Sep 2013 08:22:43 +0200
Subject: [PATCH 2/6] lib: Add "mem_ctx" to gencache_get_data_blob
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/include/proto.h | 3 ++-
source3/lib/gencache.c | 13 +++++++++----
source3/libsmb/dsgetdcname.c | 2 +-
source3/torture/torture.c | 4 ++--
source3/utils/net_cache.c | 2 +-
5 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 078d039..5985d23 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -112,7 +112,8 @@ bool gencache_parse(const char *keystr,
void (*parser)(time_t timeout, DATA_BLOB blob,
void *private_data),
void *private_data);
-bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
+bool gencache_get_data_blob(const char *keystr, TALLOC_CTX *mem_ctx,
+ DATA_BLOB *blob,
time_t *timeout, bool *was_expired);
bool gencache_stabilize(void);
bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout);
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 08adf21..7d89c7d 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -368,7 +368,8 @@ bool gencache_del(const char *keystr)
* element.
*/
- exists = gencache_get_data_blob(keystr, &value, NULL, &was_expired);
+ exists = gencache_get_data_blob(keystr, NULL, &value, NULL,
+ &was_expired);
if (!exists && was_expired) {
/*
@@ -469,6 +470,7 @@ bool gencache_parse(const char *keystr,
}
struct gencache_get_data_blob_state {
+ TALLOC_CTX *mem_ctx;
DATA_BLOB *blob;
time_t timeout;
bool result;
@@ -491,7 +493,8 @@ static void gencache_get_data_blob_parser(time_t timeout, DATA_BLOB blob,
return;
}
- *state->blob = data_blob(blob.data, blob.length);
+ *state->blob = data_blob_talloc(state->mem_ctx, blob.data,
+ blob.length);
if (state->blob->data == NULL) {
state->result = false;
return;
@@ -511,13 +514,15 @@ static void gencache_get_data_blob_parser(time_t timeout, DATA_BLOB blob,
* @retval False for failure
**/
-bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
+bool gencache_get_data_blob(const char *keystr, TALLOC_CTX *mem_ctx,
+ DATA_BLOB *blob,
time_t *timeout, bool *was_expired)
{
struct gencache_get_data_blob_state state;
bool expired = false;
state.result = false;
+ state.mem_ctx = mem_ctx;
state.blob = blob;
if (!gencache_parse(keystr, gencache_get_data_blob_parser, &state)) {
@@ -705,7 +710,7 @@ bool gencache_get(const char *keystr, char **value, time_t *ptimeout)
DATA_BLOB blob;
bool ret = False;
- ret = gencache_get_data_blob(keystr, &blob, ptimeout, NULL);
+ ret = gencache_get_data_blob(keystr, NULL, &blob, ptimeout, NULL);
if (!ret) {
return false;
}
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index 6818b01..a65a0ab 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -334,7 +334,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- if (!gencache_get_data_blob(key, &blob, NULL, NULL)) {
+ if (!gencache_get_data_blob(key, NULL, &blob, NULL, NULL)) {
return NT_STATUS_NOT_FOUND;
}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 2d7e87f..15bb8f3 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -8172,7 +8172,7 @@ static bool run_local_gencache(int dummy)
return False;
}
- if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
+ if (!gencache_get_data_blob("foo", NULL, &blob, NULL, NULL)) {
d_printf("%s: gencache_get_data_blob() failed\n", __location__);
return False;
}
@@ -8196,7 +8196,7 @@ static bool run_local_gencache(int dummy)
return False;
}
- if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
+ if (gencache_get_data_blob("foo", NULL, &blob, NULL, NULL)) {
d_printf("%s: gencache_get_data_blob() on deleted entry "
"succeeded\n", __location__);
return False;
diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c
index afcb7a1..4de3a6c 100644
--- a/source3/utils/net_cache.c
+++ b/source3/utils/net_cache.c
@@ -242,7 +242,7 @@ static int net_cache_get(struct net_context *c, int argc, const char **argv)
return -1;
}
- if (gencache_get_data_blob(keystr, &value, &timeout, NULL)) {
+ if (gencache_get_data_blob(keystr, NULL, &value, &timeout, NULL)) {
print_cache_entry(keystr, value, timeout, NULL);
data_blob_free(&value);
return 0;
--
1.7.9.5
From 42139be7bf5e86842ffb3ab7c6882fee018b1bcb Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 4 Sep 2013 08:44:50 +0200
Subject: [PATCH 3/6] torture3: Test getting a blob as a string
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/torture/torture.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 15bb8f3..b18dd99 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -8123,6 +8123,7 @@ static bool run_local_gencache(int dummy)
char *val;
time_t tm;
DATA_BLOB blob;
+ char v;
if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
d_printf("%s: gencache_set() failed\n", __location__);
@@ -8202,6 +8203,20 @@ static bool run_local_gencache(int dummy)
return False;
}
+ v = 1;
+ blob.data = (uint8_t *)&v;
+ blob.length = sizeof(v);
+
+ if (!gencache_set_data_blob("blob", &blob, tm)) {
+ d_printf("%s: gencache_set_data_blob() failed\n",
+ __location__);
+ return false;
+ }
+ if (gencache_get("blob", &val, &tm)) {
+ d_printf("%s: gencache_get succeeded\n", __location__);
+ return false;
+ }
+
return True;
}
--
1.7.9.5
From d10a4286b955b0d7178b11bcb99b6eeaae4a30ac Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 4 Sep 2013 08:46:34 +0200
Subject: [PATCH 4/6] gencache: Fix SAFE_FREE vs data_blob_free
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/lib/gencache.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 7d89c7d..0d5d9e8 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -715,12 +715,12 @@ bool gencache_get(const char *keystr, char **value, time_t *ptimeout)
return false;
}
if ((blob.data == NULL) || (blob.length == 0)) {
- SAFE_FREE(blob.data);
+ data_blob_free(&blob);
return false;
}
if (blob.data[blob.length-1] != '\0') {
/* Not NULL terminated, can't be a string */
- SAFE_FREE(blob.data);
+ data_blob_free(&blob);
return false;
}
if (value) {
--
1.7.9.5
From 3434df0f83e717a113ddae1f24ab9907dbce1531 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 4 Sep 2013 08:56:23 +0200
Subject: [PATCH 5/6] lib: Add a "mem_ctx" arg to gencache_get (unused so far)
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/auth/user_util.c | 2 +-
source3/include/proto.h | 3 ++-
source3/lib/gencache.c | 3 ++-
source3/lib/idmap_cache.c | 8 ++++----
source3/lib/wins_srv.c | 2 +-
source3/libads/sitename_cache.c | 2 +-
source3/libsmb/conncache.c | 2 +-
source3/libsmb/namecache.c | 4 ++--
source3/libsmb/namequery.c | 4 ++--
source3/libsmb/trustdom_cache.c | 4 ++--
source3/passdb/account_pol.c | 2 +-
source3/rpc_server/spoolss/srv_spoolss_nt.c | 3 ++-
source3/torture/torture.c | 8 ++++----
source3/winbindd/winbindd_cm.c | 2 +-
14 files changed, 26 insertions(+), 23 deletions(-)
diff --git a/source3/auth/user_util.c b/source3/auth/user_util.c
index 082c885..b52f1dd 100644
--- a/source3/auth/user_util.c
+++ b/source3/auth/user_util.c
@@ -96,7 +96,7 @@ static bool fetch_map_from_gencache(TALLOC_CTX *ctx,
if (key == NULL) {
return false;
}
- found = gencache_get(key, &value, NULL);
+ found = gencache_get(key, NULL, &value, NULL);
TALLOC_FREE(key);
if (!found) {
return false;
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 5985d23..811fe4f 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -107,7 +107,8 @@ struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_S
bool gencache_set(const char *keystr, const char *value, time_t timeout);
bool gencache_del(const char *keystr);
-bool gencache_get(const char *keystr, char **valstr, time_t *timeout);
+bool gencache_get(const char *keystr, TALLOC_CTX *mem_ctx, char **value,
+ time_t *ptimeout);
bool gencache_parse(const char *keystr,
void (*parser)(time_t timeout, DATA_BLOB blob,
void *private_data),
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 0d5d9e8..1ecaad5 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -705,7 +705,8 @@ static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
* @retval False for failure
**/
-bool gencache_get(const char *keystr, char **value, time_t *ptimeout)
+bool gencache_get(const char *keystr, TALLOC_CTX *mem_ctx, char **value,
+ time_t *ptimeout)
{
DATA_BLOB blob;
bool ret = False;
diff --git a/source3/lib/idmap_cache.c b/source3/lib/idmap_cache.c
index edf37a8..627ced3 100644
--- a/source3/lib/idmap_cache.c
+++ b/source3/lib/idmap_cache.c
@@ -48,7 +48,7 @@ bool idmap_cache_find_sid2unixid(const struct dom_sid *sid, struct unixid *id,
if (key == NULL) {
return false;
}
- ret = gencache_get(key, &value, &timeout);
+ ret = gencache_get(key, NULL, &value, &timeout);
if (!ret) {
goto done;
}
@@ -209,7 +209,7 @@ bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired)
if (key == NULL) {
return false;
}
- ret = gencache_get(key, &value, &timeout);
+ ret = gencache_get(key, NULL, &value, &timeout);
TALLOC_FREE(key);
if (!ret) {
return false;
@@ -246,7 +246,7 @@ bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired)
if (key == NULL) {
return false;
}
- ret = gencache_get(key, &value, &timeout);
+ ret = gencache_get(key, NULL, &value, &timeout);
TALLOC_FREE(key);
if (!ret) {
return false;
@@ -431,7 +431,7 @@ static bool idmap_cache_del_xid(char t, int xid)
time_t timeout;
bool ret = true;
- if (!gencache_get(key, &sid_str, &timeout)) {
+ if (!gencache_get(key, NULL, &sid_str, &timeout)) {
DEBUG(3, ("no entry: %s\n", key));
ret = false;
goto done;
diff --git a/source3/lib/wins_srv.c b/source3/lib/wins_srv.c
index fb5587f..6f7d5b3 100644
--- a/source3/lib/wins_srv.c
+++ b/source3/lib/wins_srv.c
@@ -101,7 +101,7 @@ bool wins_srv_is_dead(struct in_addr wins_ip, struct in_addr src_ip)
/* If the key exists then the WINS server has been marked as dead */
- result = gencache_get(keystr, NULL, NULL);
+ result = gencache_get(keystr, NULL, NULL, NULL);
SAFE_FREE(keystr);
DEBUG(4, ("wins_srv_is_dead: %s is %s\n", inet_ntoa(wins_ip),
diff --git a/source3/libads/sitename_cache.c b/source3/libads/sitename_cache.c
index cb1bae5..b0c4423 100644
--- a/source3/libads/sitename_cache.c
+++ b/source3/libads/sitename_cache.c
@@ -95,7 +95,7 @@ char *sitename_fetch(const char *realm)
key = sitename_key(query_realm);
- ret = gencache_get( key, &sitename, &timeout );
+ ret = gencache_get( key, NULL, &sitename, &timeout );
SAFE_FREE(key);
if ( !ret ) {
DEBUG(5,("sitename_fetch: No stored sitename for %s\n",
diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c
index 6635318..dfc2f47 100644
--- a/source3/libsmb/conncache.c
+++ b/source3/libsmb/conncache.c
@@ -143,7 +143,7 @@ NTSTATUS check_negative_conn_cache( const char *domain, const char *server)
if (key == NULL)
goto done;
- if (gencache_get(key, &value, NULL))
+ if (gencache_get(key, NULL, &value, NULL))
result = negative_conn_cache_valuedecode(value);
done:
DEBUG(9,("check_negative_conn_cache returning result %d for domain %s "
diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c
index 8571dfa..ebd51fd 100644
--- a/source3/libsmb/namecache.c
+++ b/source3/libsmb/namecache.c
@@ -156,7 +156,7 @@ bool namecache_fetch(const char *name,
return False;
}
- if (!gencache_get(key, &value, &timeout)) {
+ if (!gencache_get(key, NULL, &value, &timeout)) {
DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type));
SAFE_FREE(key);
return False;
@@ -294,7 +294,7 @@ bool namecache_status_fetch(const char *keyname,
if (!key)
return False;
- if (!gencache_get(key, &value, &timeout)) {
+ if (!gencache_get(key, NULL, &value, &timeout)) {
DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n",
key));
SAFE_FREE(key);
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index d86c0ed..15c7cac 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -183,7 +183,7 @@ char *saf_fetch( const char *domain )
return NULL;
}
- ret = gencache_get( key, &server, &timeout );
+ ret = gencache_get( key, NULL, &server, &timeout );
TALLOC_FREE( key );
@@ -199,7 +199,7 @@ char *saf_fetch( const char *domain )
return NULL;
}
- ret = gencache_get( key, &server, &timeout );
+ ret = gencache_get( key, NULL, &server, &timeout );
TALLOC_FREE( key );
diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c
index dadc751..81b366a 100644
--- a/source3/libsmb/trustdom_cache.c
+++ b/source3/libsmb/trustdom_cache.c
@@ -160,7 +160,7 @@ bool trustdom_cache_fetch(const char* name, struct dom_sid* sid)
if (!key)
return False;
- if (!gencache_get(key, &value, &timeout)) {
+ if (!gencache_get(key, NULL, &value, &timeout)) {
DEBUG(5, ("no entry for trusted domain %s found.\n", name));
SAFE_FREE(key);
return False;
@@ -191,7 +191,7 @@ uint32 trustdom_cache_fetch_timestamp( void )
time_t timeout;
uint32 timestamp;
- if (!gencache_get(TDOMTSKEY, &value, &timeout)) {
+ if (!gencache_get(TDOMTSKEY, NULL, &value, &timeout)) {
DEBUG(5, ("no timestamp for trusted domain cache located.\n"));
SAFE_FREE(value);
return 0;
diff --git a/source3/passdb/account_pol.c b/source3/passdb/account_pol.c
index c94df29..14ff946 100644
--- a/source3/passdb/account_pol.c
+++ b/source3/passdb/account_pol.c
@@ -446,7 +446,7 @@ bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value)
goto done;
}
- if (gencache_get(cache_key, &cache_value, NULL)) {
+ if (gencache_get(cache_key, NULL, &cache_value, NULL)) {
uint32 tmp = strtoul(cache_value, NULL, 10);
*value = tmp;
ret = True;
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index a094b49..37f11c7 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -630,7 +630,8 @@ static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx,
cache_key = talloc_asprintf(talloc_tos(), "PRINTERNAME/%s",
aprinter);
- if ((cache_key != NULL) && gencache_get(cache_key, &tmp, NULL)) {
+ if ((cache_key != NULL) &&
+ gencache_get(cache_key, NULL, &tmp, NULL)) {
found = (strcmp(tmp, printer_not_found) != 0);
if (!found) {
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index b18dd99..f2446d1 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -8130,12 +8130,12 @@ static bool run_local_gencache(int dummy)
return False;
}
- if (!gencache_get("foo", NULL, NULL)) {
+ if (!gencache_get("foo", NULL, NULL, NULL)) {
d_printf("%s: gencache_get() failed\n", __location__);
return False;
}
- if (!gencache_get("foo", &val, &tm)) {
+ if (!gencache_get("foo", NULL, &val, &tm)) {
d_printf("%s: gencache_get() failed\n", __location__);
return False;
}
@@ -8159,7 +8159,7 @@ static bool run_local_gencache(int dummy)
return False;
}
- if (gencache_get("foo", &val, &tm)) {
+ if (gencache_get("foo", NULL, &val, &tm)) {
d_printf("%s: gencache_get() on deleted entry "
"succeeded\n", __location__);
return False;
@@ -8212,7 +8212,7 @@ static bool run_local_gencache(int dummy)
__location__);
return false;
}
- if (gencache_get("blob", &val, &tm)) {
+ if (gencache_get("blob", NULL, &val, &tm)) {
d_printf("%s: gencache_get succeeded\n", __location__);
return false;
}
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 4de9166..0b8308a 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -1512,7 +1512,7 @@ bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
if (key == NULL) {
goto done;
}
- if (!gencache_get(key, &value, NULL)) {
+ if (!gencache_get(key, NULL, &value, NULL)) {
goto done;
}
p = strchr(value, ' ');
--
1.7.9.5
From 320d82e4809b77cd4b420478376a622475a78dc0 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 4 Sep 2013 08:57:59 +0200
Subject: [PATCH 6/6] lib: Use "mem_ctx" arg in gencache_get
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/lib/gencache.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 1ecaad5..35f5d1b 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -711,7 +711,7 @@ bool gencache_get(const char *keystr, TALLOC_CTX *mem_ctx, char **value,
DATA_BLOB blob;
bool ret = False;
- ret = gencache_get_data_blob(keystr, NULL, &blob, ptimeout, NULL);
+ ret = gencache_get_data_blob(keystr, mem_ctx, &blob, ptimeout, NULL);
if (!ret) {
return false;
}
@@ -725,6 +725,10 @@ bool gencache_get(const char *keystr, TALLOC_CTX *mem_ctx, char **value,
return false;
}
if (value) {
+ if (mem_ctx) {
+ *value = talloc_move(mem_ctx, (char **)&blob.data);
+ return true;
+ }
*value = SMB_STRDUP((char *)blob.data);
data_blob_free(&blob);
if (*value == NULL) {
--
1.7.9.5
More information about the samba-technical
mailing list