[PATCH] Fix Bug 5917 - Samba does not work on site with Read Only Domain Controller

Volker Lendecke Volker.Lendecke at SerNet.DE
Thu Sep 5 11:50:21 CEST 2013


+1

Volker

On Wed, Sep 04, 2013 at 03:25:13PM -0700, Jeremy Allison wrote:
> On Wed, Sep 04, 2013 at 12:52:57PM -0700, Jeremy Allison wrote:
> > On Wed, Sep 04, 2013 at 12:45:06PM -0700, Jeremy Allison wrote:
> > > On Wed, Sep 04, 2013 at 09:35:43PM +0200, Volker Lendecke wrote:
> > > > On Wed, Sep 04, 2013 at 10:42:26AM -0700, Jeremy Allison wrote:
> > > > > It leaves gencache_get() as a mixed interface, sometimes
> > > > > returning a talloced value, sometimes a malloced.
> > > > 
> > > > I know. We could rename gencache_get to gencache_get_malloc
> > > > in one run and make gencache_get always talloc.
> > > 
> > > That works. But I'm also working on fixing the code
> > > so that gencache_get() always uses talloc, and fixing
> > > the callers :-).
> > 
> > FYI. In doing this I've found at least one memory
> > leak where we aren't freeing the return from gencache_get() :-).
> 
> Ok, here is your patchset reviewed by me with the last
> patch revised to fix gencache_get to never return malloced
> memory, and two extra patches that fix saf_fetch() and
> sitename_fetch() and callers to use a talloc context.
> 
> It removes all malloc/free from the gencache.c code
> and it's callers (except for the internal interface
> with tdb which still uses malloc).
> 
> Review and push if you're happy !
> 
> Jeremy.

> >From 87f81e15f5fc1f3aa29e1f74ae5590c75fb6571d 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/8] torture3: Fix a const warning
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> Reviewed-by: Jeremy Allison <jra 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.8.4
> 
> 
> >From 48cb8aa199193a64a5fc9f2202c64e2d4153c0ce 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/8] lib: Add "mem_ctx" to gencache_get_data_blob
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> Reviewed-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/include/proto.h      |  3 ++-
>  source3/lib/gencache.c       | 13 +++++++++----
>  source3/libsmb/dsgetdcname.c |  3 ++-
>  source3/torture/torture.c    |  4 ++--
>  source3/utils/net_cache.c    |  2 +-
>  5 files changed, 16 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..4f2aa63 100644
> --- a/source3/libsmb/dsgetdcname.c
> +++ b/source3/libsmb/dsgetdcname.c
> @@ -334,12 +334,13 @@ 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;
>  	}
>  
>  	info = talloc_zero(mem_ctx, struct netr_DsRGetDCNameInfo);
>  	if (!info) {
> +		data_blob_free(&blob);
>  		return NT_STATUS_NO_MEMORY;
>  	}
>  
> 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.8.4
> 
> 
> >From 3ea704727ac44a7168a7a63036cd05936c6d614d 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/8] torture3: Test getting a blob as a string
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> Reviewed-by: Jeremy Allison <jra 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.8.4
> 
> 
> >From 360e2124499b0caa791d36fea66df7253618975d 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/8] gencache: Fix SAFE_FREE vs data_blob_free
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> Reviewed-by: Jeremy Allison <jra 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.8.4
> 
> 
> >From 88ec88f5c2ac5f2f544ee49b82dc20dae58e7bcc 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/8] lib: Add a "mem_ctx" arg to gencache_get (unused so far)
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> Reviewed-by: Jeremy Allison <jra 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.8.4
> 
> 
> >From 40b4c71fd38278203fdbfce949dedf8b34050e01 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Wed, 4 Sep 2013 13:39:31 -0700
> Subject: [PATCH 6/8] Add a talloc context to saf_fetch().
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/include/proto.h         |  2 +-
>  source3/libsmb/namequery.c      | 10 +++++-----
>  source3/winbindd/winbindd_ads.c |  4 +++-
>  source3/winbindd/winbindd_cm.c  | 12 +++++++-----
>  4 files changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/source3/include/proto.h b/source3/include/proto.h
> index 811fe4f..df65711 100644
> --- a/source3/include/proto.h
> +++ b/source3/include/proto.h
> @@ -825,7 +825,7 @@ bool namecache_status_fetch(const char *keyname,
>  bool saf_store( const char *domain, const char *servername );
>  bool saf_join_store( const char *domain, const char *servername );
>  bool saf_delete( const char *domain );
> -char *saf_fetch( const char *domain );
> +char *saf_fetch(TALLOC_CTX *mem_ctx, const char *domain );
>  struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
>  					  struct tevent_context *ev,
>  					  struct nmb_name *name,
> diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
> index 15c7cac..7fac0c9 100644
> --- a/source3/libsmb/namequery.c
> +++ b/source3/libsmb/namequery.c
> @@ -165,7 +165,7 @@ bool saf_delete( const char *domain )
>  /****************************************************************************
>  ****************************************************************************/
>  
> -char *saf_fetch( const char *domain )
> +char *saf_fetch(TALLOC_CTX *mem_ctx, const char *domain )
>  {
>  	char *server = NULL;
>  	time_t timeout;
> @@ -183,7 +183,7 @@ char *saf_fetch( const char *domain )
>  		return NULL;
>  	}
>  
> -	ret = gencache_get( key, NULL, &server, &timeout );
> +	ret = gencache_get( key, mem_ctx, &server, &timeout );
>  
>  	TALLOC_FREE( key );
>  
> @@ -199,7 +199,7 @@ char *saf_fetch( const char *domain )
>  		return NULL;
>  	}
>  
> -	ret = gencache_get( key, NULL, &server, &timeout );
> +	ret = gencache_get( key, mem_ctx, &server, &timeout );
>  
>  	TALLOC_FREE( key );
>  
> @@ -3073,7 +3073,7 @@ static NTSTATUS get_dc_list(const char *domain,
>  	/* fetch the server we have affinity for.  Add the
>  	   'password server' list to a search for our domain controllers */
>  
> -	saf_servername = saf_fetch( domain);
> +	saf_servername = saf_fetch(ctx, domain);
>  
>  	if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
>  		pserver = talloc_asprintf(ctx, "%s, %s",
> @@ -3084,7 +3084,7 @@ static NTSTATUS get_dc_list(const char *domain,
>  			saf_servername ? saf_servername : "");
>  	}
>  
> -	SAFE_FREE(saf_servername);
> +	TALLOC_FREE(saf_servername);
>  	if (!pserver) {
>  		status = NT_STATUS_NO_MEMORY;
>  		goto out;
> diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
> index 4c26389..18749c9 100644
> --- a/source3/winbindd/winbindd_ads.c
> +++ b/source3/winbindd/winbindd_ads.c
> @@ -151,7 +151,7 @@ ADS_STATUS ads_idmap_cached_connection(ADS_STRUCT **adsp, const char *dom_name)
>  	 * Check if we can get server nam and realm from SAF cache
>  	 * and the domain list.
>  	 */
> -	ldap_server = saf_fetch(dom_name);
> +	ldap_server = saf_fetch(talloc_tos(), dom_name);
>  	DEBUG(10, ("ldap_server from saf cache: '%s'\n",
>  		   ldap_server ? ldap_server : ""));
>  
> @@ -165,6 +165,7 @@ ADS_STATUS ads_idmap_cached_connection(ADS_STRUCT **adsp, const char *dom_name)
>  			  " domain '%s'\n", wb_dom->alt_name, dom_name));
>  
>  	if (!get_trust_pw_clear(dom_name, &password, NULL, NULL)) {
> +		TALLOC_FREE(ldap_server);
>  		return ADS_ERROR_NT(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
>  	}
>  
> @@ -190,6 +191,7 @@ ADS_STATUS ads_idmap_cached_connection(ADS_STRUCT **adsp, const char *dom_name)
>  	status = ads_cached_connection_connect(adsp, realm, dom_name, ldap_server,
>  					       password, realm, 0);
>  	SAFE_FREE(realm);
> +	TALLOC_FREE(ldap_server);
>  
>  	return status;
>  }
> diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
> index 0b8308a..114feed 100644
> --- a/source3/winbindd/winbindd_cm.c
> +++ b/source3/winbindd/winbindd_cm.c
> @@ -1549,15 +1549,16 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
>  {
>  	TALLOC_CTX *mem_ctx;
>  	NTSTATUS result;
> -	char *saf_servername = saf_fetch( domain->name );
> +	char *saf_servername;
>  	int retries;
>  
>  	if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
> -		SAFE_FREE(saf_servername);
>  		set_domain_offline(domain);
>  		return NT_STATUS_NO_MEMORY;
>  	}
>  
> +	saf_servername = saf_fetch(mem_ctx, domain->name );
> +
>  	/* we have to check the server affinity cache here since 
>  	   later we select a DC based on response time and not preference */
>  
> @@ -1577,13 +1578,14 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
>  
>  			if (!interpret_string_addr(&ss, saf_servername,
>  						AI_NUMERICHOST)) {
> +				TALLOC_FREE(mem_ctx);
>  				return NT_STATUS_UNSUCCESSFUL;
>  			}
>  			if (dcip_to_name(mem_ctx, domain, &ss, &dcname)) {
>  				domain->dcname = talloc_strdup(domain,
>  							       dcname);
>  				if (domain->dcname == NULL) {
> -					SAFE_FREE(saf_servername);
> +					TALLOC_FREE(mem_ctx);
>  					return NT_STATUS_NO_MEMORY;
>  				}
>  			} else {
> @@ -1594,12 +1596,12 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
>  		} else {
>  			domain->dcname = talloc_strdup(domain, saf_servername);
>  			if (domain->dcname == NULL) {
> -				SAFE_FREE(saf_servername);
> +				TALLOC_FREE(mem_ctx);
>  				return NT_STATUS_NO_MEMORY;
>  			}
>  		}
>  
> -		SAFE_FREE( saf_servername );
> +		TALLOC_FREE( saf_servername );
>  	}
>  
>  	for (retries = 0; retries < 3; retries++) {
> -- 
> 1.8.4
> 
> 
> >From c79fbc13ce8b2fa25ca4ccc59052f27fa53c3457 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Wed, 4 Sep 2013 13:58:18 -0700
> Subject: [PATCH 7/8] Add a talloc context to sitename_fetch().
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/libads/ldap.c           | 15 ++++++---------
>  source3/libads/sitename_cache.c |  8 ++++----
>  source3/libads/sitename_cache.h |  2 +-
>  source3/libsmb/dsgetdcname.c    |  4 ++--
>  source3/libsmb/namequery.c      | 12 ++++++------
>  source3/libsmb/namequery_dc.c   | 14 +++++++-------
>  source3/utils/net_lookup.c      | 17 +++++------------
>  source3/winbindd/winbindd_cm.c  |  8 ++++----
>  8 files changed, 35 insertions(+), 45 deletions(-)
> 
> diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
> index c8ef5b5..12aacd4 100644
> --- a/source3/libads/ldap.c
> +++ b/source3/libads/ldap.c
> @@ -414,7 +414,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
>  		return NT_STATUS_NO_LOGON_SERVERS;
>  	}
>  
> -	sitename = sitename_fetch(realm);
> +	sitename = sitename_fetch(talloc_tos(), realm);
>  
>   again:
>  
> @@ -429,7 +429,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
>  			goto again;
>  		}
>  
> -		SAFE_FREE(sitename);
> +		TALLOC_FREE(sitename);
>  		return status;
>  	}
>  
> @@ -464,7 +464,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
>  
>  		if ( ads_try_connect(ads, server, false) ) {
>  			SAFE_FREE(ip_list);
> -			SAFE_FREE(sitename);
> +			TALLOC_FREE(sitename);
>  			return NT_STATUS_OK;
>  		}
>  
> @@ -481,7 +481,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
>  	if (sitename) {
>  		DEBUG(1,("ads_find_dc: failed to find a valid DC on our site (%s), "
>  				"trying to find another DC\n", sitename));
> -		SAFE_FREE(sitename);
> +		TALLOC_FREE(sitename);
>  		namecache_delete(realm, 0x1C);
>  		goto again;
>  	}
> @@ -563,9 +563,9 @@ ADS_STATUS ads_connect_gc(ADS_STRUCT *ads)
>  	if (!realm)
>  		realm = lp_realm();
>  
> -	if ((sitename = sitename_fetch(realm)) == NULL) {
> +	if ((sitename = sitename_fetch(frame, realm)) == NULL) {
>  		ads_lookup_site();
> -		sitename = sitename_fetch(realm);
> +		sitename = sitename_fetch(frame, realm);
>  	}
>  
>  	dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL);
> @@ -581,8 +581,6 @@ ADS_STATUS ads_connect_gc(ADS_STRUCT *ads)
>  					      realm, sitename,
>  					      &gcs_list, &num_gcs);
>  
> -		SAFE_FREE(sitename);
> -
>  		if (!NT_STATUS_IS_OK(nt_status)) {
>  			ads_status = ADS_ERROR_NT(nt_status);
>  			goto done;
> @@ -618,7 +616,6 @@ ADS_STATUS ads_connect_gc(ADS_STRUCT *ads)
>  	} while (!done);
>  
>  done:
> -	SAFE_FREE(sitename);
>  	talloc_destroy(frame);
>  
>  	return ads_status;
> diff --git a/source3/libads/sitename_cache.c b/source3/libads/sitename_cache.c
> index b0c4423..b064aea 100644
> --- a/source3/libads/sitename_cache.c
> +++ b/source3/libads/sitename_cache.c
> @@ -79,7 +79,7 @@ bool sitename_store(const char *realm, const char *sitename)
>   Caller must free.
>  ****************************************************************************/
>  
> -char *sitename_fetch(const char *realm)
> +char *sitename_fetch(TALLOC_CTX *mem_ctx, const char *realm)
>  {
>  	char *sitename = NULL;
>  	time_t timeout;
> @@ -95,7 +95,7 @@ char *sitename_fetch(const char *realm)
>  
>  	key = sitename_key(query_realm);
>  
> -	ret = gencache_get( key, NULL, &sitename, &timeout );
> +	ret = gencache_get( key, mem_ctx, &sitename, &timeout );
>  	SAFE_FREE(key);
>  	if ( !ret ) {
>  		DEBUG(5,("sitename_fetch: No stored sitename for %s\n",
> @@ -122,7 +122,7 @@ bool stored_sitename_changed(const char *realm, const char *sitename)
>  		return False;
>  	}
>  
> -	new_sitename = sitename_fetch(realm);
> +	new_sitename = sitename_fetch(talloc_tos(), realm);
>  
>  	if (sitename && new_sitename && !strequal(sitename, new_sitename)) {
>  		ret = True;
> @@ -130,7 +130,7 @@ bool stored_sitename_changed(const char *realm, const char *sitename)
>  			(!sitename && new_sitename)) {
>  		ret = True;
>  	}
> -	SAFE_FREE(new_sitename);
> +	TALLOC_FREE(new_sitename);
>  	return ret;
>  }
>  
> diff --git a/source3/libads/sitename_cache.h b/source3/libads/sitename_cache.h
> index 4e62f00..9044964 100644
> --- a/source3/libads/sitename_cache.h
> +++ b/source3/libads/sitename_cache.h
> @@ -22,7 +22,7 @@
>  #define _LIBADS_SITENAME_CACHE_H_
>  
>  bool sitename_store(const char *realm, const char *sitename);
> -char *sitename_fetch(const char *realm);
> +char *sitename_fetch(TALLOC_CTX *mem_ctx, const char *realm);
>  bool stored_sitename_changed(const char *realm, const char *sitename);
>  
>  #endif /* _LIBADS_SITENAME_CACHE_H_ */
> diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
> index 4f2aa63..71995fd 100644
> --- a/source3/libsmb/dsgetdcname.c
> +++ b/source3/libsmb/dsgetdcname.c
> @@ -1185,7 +1185,7 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx,
>  	bool retry_query_with_null = false;
>  
>  	if ((site_name == NULL) || (site_name[0] == '\0')) {
> -		ptr_to_free = sitename_fetch(domain_name);
> +		ptr_to_free = sitename_fetch(mem_ctx, domain_name);
>  		if (ptr_to_free != NULL) {
>  			retry_query_with_null = true;
>  		}
> @@ -1202,7 +1202,7 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx,
>  				flags,
>  				info);
>  
> -	SAFE_FREE(ptr_to_free);
> +	TALLOC_FREE(ptr_to_free);
>  
>  	if (!NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
>  		return status;
> diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
> index 7fac0c9..f2fffde 100644
> --- a/source3/libsmb/namequery.c
> +++ b/source3/libsmb/namequery.c
> @@ -2799,7 +2799,7 @@ bool resolve_name(const char *name,
>  		return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
>  	}
>  
> -	sitename = sitename_fetch(lp_realm()); /* wild guess */
> +	sitename = sitename_fetch(talloc_tos(), lp_realm()); /* wild guess */
>  
>  	status = internal_resolve_name(name, name_type, sitename,
>  				       &ss_list, &count,
> @@ -2814,7 +2814,7 @@ bool resolve_name(const char *name,
>  						(ss_list[i].ss.ss_family == AF_INET)) {
>  					*return_ss = ss_list[i].ss;
>  					SAFE_FREE(ss_list);
> -					SAFE_FREE(sitename);
> +					TALLOC_FREE(sitename);
>  					return True;
>  				}
>  			}
> @@ -2826,14 +2826,14 @@ bool resolve_name(const char *name,
>  			    !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
>  				*return_ss = ss_list[i].ss;
>  				SAFE_FREE(ss_list);
> -				SAFE_FREE(sitename);
> +				TALLOC_FREE(sitename);
>  				return True;
>  			}
>  		}
>  	}
>  
>  	SAFE_FREE(ss_list);
> -	SAFE_FREE(sitename);
> +	TALLOC_FREE(sitename);
>  	return False;
>  }
>  
> @@ -2873,12 +2873,12 @@ NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
>  		return NT_STATUS_OK;
>  	}
>  
> -	sitename = sitename_fetch(lp_realm()); /* wild guess */
> +	sitename = sitename_fetch(ctx, lp_realm()); /* wild guess */
>  
>  	status = internal_resolve_name(name, name_type, sitename,
>  						  &ss_list, &count,
>  						  lp_name_resolve_order());
> -	SAFE_FREE(sitename);
> +	TALLOC_FREE(sitename);
>  
>  	if (!NT_STATUS_IS_OK(status)) {
>  		return status;
> diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c
> index df5eeb8..3cfae79 100644
> --- a/source3/libsmb/namequery_dc.c
> +++ b/source3/libsmb/namequery_dc.c
> @@ -64,13 +64,13 @@ static bool ads_dc_name(const char *domain,
>  		realm = lp_realm();
>  	}
>  
> -	sitename = sitename_fetch(realm);
> +	sitename = sitename_fetch(talloc_tos(), realm);
>  
>  	/* Try this 3 times then give up. */
>  	for( i =0 ; i < 3; i++) {
>  		ads = ads_init(realm, domain, NULL);
>  		if (!ads) {
> -			SAFE_FREE(sitename);
> +			TALLOC_FREE(sitename);
>  			return False;
>  		}
>  
> @@ -83,7 +83,7 @@ static bool ads_dc_name(const char *domain,
>  #endif
>  
>  		if (!ads->config.realm) {
> -			SAFE_FREE(sitename);
> +			TALLOC_FREE(sitename);
>  			ads_destroy(&ads);
>  			return False;
>  		}
> @@ -93,8 +93,8 @@ static bool ads_dc_name(const char *domain,
>  		   to ensure we only find servers in our site. */
>  
>  		if (stored_sitename_changed(realm, sitename)) {
> -			SAFE_FREE(sitename);
> -			sitename = sitename_fetch(realm);
> +			TALLOC_FREE(sitename);
> +			sitename = sitename_fetch(talloc_tos(), realm);
>  			ads_destroy(&ads);
>  			/* Ensure we don't cache the DC we just connected to. */
>  			namecache_delete(realm, 0x1C);
> @@ -129,12 +129,12 @@ static bool ads_dc_name(const char *domain,
>  	if (i == 3) {
>  		DEBUG(1,("ads_dc_name: sitename (now \"%s\") keeps changing ???\n",
>  			sitename ? sitename : ""));
> -		SAFE_FREE(sitename);
> +		TALLOC_FREE(sitename);
>  		ads_destroy(&ads);
>  		return False;
>  	}
>  
> -	SAFE_FREE(sitename);
> +	TALLOC_FREE(sitename);
>  
>  	fstrcpy(srv_name, ads->config.ldap_server_name);
>  	if (!strupper_m(srv_name)) {
> diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c
> index 50226f0..9d61be2 100644
> --- a/source3/utils/net_lookup.c
> +++ b/source3/utils/net_lookup.c
> @@ -113,15 +113,14 @@ static int net_lookup_ldap(struct net_context *c, int argc, const char **argv)
>  	else
>  		domain = c->opt_target_workgroup;
>  
> -	sitename = sitename_fetch(domain);
> -
>  	if ( (ctx = talloc_init("net_lookup_ldap")) == NULL ) {
>  		d_fprintf(stderr,"net_lookup_ldap: talloc_init() %s!\n",
>  			  _("failed"));
> -		SAFE_FREE(sitename);
>  		return -1;
>  	}
>  
> +	sitename = sitename_fetch(ctx, domain);
> +
>  	DEBUG(9, ("Lookup up ldap for domain %s\n", domain));
>  
>  	dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL);
> @@ -130,14 +129,12 @@ static int net_lookup_ldap(struct net_context *c, int argc, const char **argv)
>  	if ( NT_STATUS_IS_OK(status) && numdcs ) {
>  		print_ldap_srvlist(dcs, numdcs);
>  		TALLOC_FREE( ctx );
> -		SAFE_FREE(sitename);
>  		return 0;
>  	}
>  
>       	DEBUG(9, ("Looking up PDC for domain %s\n", domain));
>  	if (!get_pdc_ip(domain, &ss)) {
>  		TALLOC_FREE( ctx );
> -		SAFE_FREE(sitename);
>  		return -1;
>  	}
>  
> @@ -149,7 +146,6 @@ static int net_lookup_ldap(struct net_context *c, int argc, const char **argv)
>  
>  	if (ret) {
>  		TALLOC_FREE( ctx );
> -		SAFE_FREE(sitename);
>  		return -1;
>  	}
>  
> @@ -157,7 +153,6 @@ static int net_lookup_ldap(struct net_context *c, int argc, const char **argv)
>  	domain = strchr(h_name, '.');
>  	if (!domain) {
>  		TALLOC_FREE( ctx );
> -		SAFE_FREE(sitename);
>  		return -1;
>  	}
>  	domain++;
> @@ -169,12 +164,10 @@ static int net_lookup_ldap(struct net_context *c, int argc, const char **argv)
>  	if ( NT_STATUS_IS_OK(status) && numdcs ) {
>  		print_ldap_srvlist(dcs, numdcs);
>  		TALLOC_FREE( ctx );
> -		SAFE_FREE(sitename);
>  		return 0;
>  	}
>  
>  	TALLOC_FREE( ctx );
> -	SAFE_FREE(sitename);
>  
>  	return -1;
>  #endif
> @@ -212,14 +205,14 @@ static int net_lookup_dc(struct net_context *c, int argc, const char **argv)
>  	}
>  	d_printf("%s\n", pdc_str);
>  
> -	sitename = sitename_fetch(domain);
> +	sitename = sitename_fetch(talloc_tos(), domain);
>  	if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, sitename,
>  					&ip_list, &count, sec_ads))) {
>  		SAFE_FREE(pdc_str);
> -		SAFE_FREE(sitename);
> +		TALLOC_FREE(sitename);
>  		return 0;
>  	}
> -	SAFE_FREE(sitename);
> +	TALLOC_FREE(sitename);
>  	for (i=0;i<count;i++) {
>  		print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
>  		if (!strequal(pdc_str, addr))
> diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
> index 114feed..b7c141a 100644
> --- a/source3/winbindd/winbindd_cm.c
> +++ b/source3/winbindd/winbindd_cm.c
> @@ -1161,7 +1161,7 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
>  
>  			if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
>  				if (ads_closest_dc(ads)) {
> -					char *sitename = sitename_fetch(ads->config.realm);
> +					char *sitename = sitename_fetch(mem_ctx, ads->config.realm);
>  
>  					/* We're going to use this KDC for this realm/domain.
>  					   If we are using sites, then force the krb5 libs
> @@ -1173,7 +1173,7 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
>  									pss,
>  									*name);
>  
> -					SAFE_FREE(sitename);
> +					TALLOC_FREE(sitename);
>  				} else {
>  					/* use an off site KDC */
>  					create_local_private_krb5_conf_for_domain(domain->alt_name,
> @@ -1279,7 +1279,7 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
>  
>  		get_dc_name(domain->name, domain->alt_name, dcname, &ss);
>  
> -		sitename = sitename_fetch(domain->alt_name);
> +		sitename = sitename_fetch(mem_ctx, domain->alt_name);
>  		if (sitename) {
>  
>  			/* Do the site-specific AD dns lookup first. */
> @@ -1303,7 +1303,7 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
>  			}
>  
>  			SAFE_FREE(ip_list);
> -			SAFE_FREE(sitename);
> +			TALLOC_FREE(sitename);
>  			iplist_size = 0;
>  		}
>  
> -- 
> 1.8.4
> 
> 
> >From 6413b36d6a73c413240f07e77b1ea98a66e1e472 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 8/8] lib: Use "mem_ctx" arg in gencache_get
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/auth/user_util.c                    |  5 ++---
>  source3/lib/gencache.c                      | 24 ++++++++++++++----------
>  source3/lib/idmap_cache.c                   | 14 +++++++-------
>  source3/libsmb/conncache.c                  |  4 ++--
>  source3/libsmb/namecache.c                  |  8 ++++----
>  source3/libsmb/trustdom_cache.c             | 10 +++++-----
>  source3/passdb/account_pol.c                |  4 ++--
>  source3/rpc_server/spoolss/srv_spoolss_nt.c |  6 +++---
>  source3/torture/torture.c                   | 14 +++++++-------
>  source3/winbindd/winbindd_cm.c              |  3 ++-
>  10 files changed, 48 insertions(+), 44 deletions(-)
> 
> diff --git a/source3/auth/user_util.c b/source3/auth/user_util.c
> index b52f1dd..70ab5ad 100644
> --- a/source3/auth/user_util.c
> +++ b/source3/auth/user_util.c
> @@ -96,14 +96,13 @@ static bool fetch_map_from_gencache(TALLOC_CTX *ctx,
>  	if (key == NULL) {
>  		return false;
>  	}
> -	found = gencache_get(key, NULL, &value, NULL);
> +	found = gencache_get(key, ctx, &value, NULL);
>  	TALLOC_FREE(key);
>  	if (!found) {
>  		return false;
>  	}
>  	TALLOC_FREE(*p_user_out);
> -	*p_user_out = talloc_strdup(ctx, value);
> -	SAFE_FREE(value);
> +	*p_user_out = value;
>  	if (!*p_user_out) {
>  		return false;
>  	}
> diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
> index 1ecaad5..2c5e9ab 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,11 +725,7 @@ bool gencache_get(const char *keystr, TALLOC_CTX *mem_ctx, char **value,
>  		return false;
>  	}
>  	if (value) {
> -		*value = SMB_STRDUP((char *)blob.data);
> -		data_blob_free(&blob);
> -		if (*value == NULL) {
> -			return false;
> -		}
> +		*value = talloc_move(mem_ctx, (char **)&blob.data);
>  		return true;
>  	}
>  	data_blob_free(&blob);
> @@ -783,8 +779,11 @@ static int gencache_iterate_blobs_fn(struct tdb_context *tdb, TDB_DATA key,
>  		keystr = (char *)key.dptr;
>  	} else {
>  		/* ensure 0-termination */
> -		keystr = SMB_STRNDUP((char *)key.dptr, key.dsize);
> +		keystr = talloc_strndup(talloc_tos(), (char *)key.dptr, key.dsize);
>  		free_key = keystr;
> +		if (keystr == NULL) {
> +			goto done;
> +		}
>  	}
>  
>  	if (!gencache_pull_timeout((char *)data.dptr, &timeout, &endptr)) {
> @@ -806,7 +805,7 @@ static int gencache_iterate_blobs_fn(struct tdb_context *tdb, TDB_DATA key,
>  		  timeout, state->private_data);
>  
>   done:
> -	SAFE_FREE(free_key);
> +	TALLOC_FREE(free_key);
>  	return 0;
>  }
>  
> @@ -862,8 +861,11 @@ static void gencache_iterate_fn(const char *key, DATA_BLOB value,
>  		valstr = (char *)value.data;
>  	} else {
>  		/* ensure 0-termination */
> -		valstr = SMB_STRNDUP((char *)value.data, value.length);
> +		valstr = talloc_strndup(talloc_tos(), (char *)value.data, value.length);
>  		free_val = valstr;
> +		if (valstr == NULL) {
> +			goto done;
> +		}
>  	}
>  
>  	DEBUG(10, ("Calling function with arguments "
> @@ -872,7 +874,9 @@ static void gencache_iterate_fn(const char *key, DATA_BLOB value,
>  
>  	state->fn(key, valstr, timeout, state->private_data);
>  
> -	SAFE_FREE(free_val);
> +  done:
> +
> +	TALLOC_FREE(free_val);
>  }
>  
>  void gencache_iterate(void (*fn)(const char *key, const char *value,
> diff --git a/source3/lib/idmap_cache.c b/source3/lib/idmap_cache.c
> index 627ced3..ffd3c19 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, NULL, &value, &timeout);
> +	ret = gencache_get(key, talloc_tos(), &value, &timeout);
>  	if (!ret) {
>  		goto done;
>  	}
> @@ -128,7 +128,7 @@ bool idmap_cache_find_sid2unixid(const struct dom_sid *sid, struct unixid *id,
>  
>  done:
>  	TALLOC_FREE(key);
> -	SAFE_FREE(value);
> +	TALLOC_FREE(value);
>  	return ret;
>  }
>  
> @@ -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, NULL, &value, &timeout);
> +	ret = gencache_get(key, talloc_tos(), &value, &timeout);
>  	TALLOC_FREE(key);
>  	if (!ret) {
>  		return false;
> @@ -218,7 +218,7 @@ bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired)
>  	if (value[0] != '-') {
>  		ret = string_to_sid(sid, value);
>  	}
> -	SAFE_FREE(value);
> +	TALLOC_FREE(value);
>  	if (ret) {
>  		*expired = (timeout <= time(NULL));
>  	}
> @@ -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, NULL, &value, &timeout);
> +	ret = gencache_get(key, talloc_tos(), &value, &timeout);
>  	TALLOC_FREE(key);
>  	if (!ret) {
>  		return false;
> @@ -255,7 +255,7 @@ bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired)
>  	if (value[0] != '-') {
>  		ret = string_to_sid(sid, value);
>  	}
> -	SAFE_FREE(value);
> +	TALLOC_FREE(value);
>  	if (ret) {
>  		*expired = (timeout <= time(NULL));
>  	}
> @@ -431,7 +431,7 @@ static bool idmap_cache_del_xid(char t, int xid)
>  	time_t timeout;
>  	bool ret = true;
>  
> -	if (!gencache_get(key, NULL, &sid_str, &timeout)) {
> +	if (!gencache_get(key, mem_ctx, &sid_str, &timeout)) {
>  		DEBUG(3, ("no entry: %s\n", key));
>  		ret = false;
>  		goto done;
> diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c
> index dfc2f47..9bf4c56 100644
> --- a/source3/libsmb/conncache.c
> +++ b/source3/libsmb/conncache.c
> @@ -143,13 +143,13 @@ NTSTATUS check_negative_conn_cache( const char *domain, const char *server)
>  	if (key == NULL)
>  		goto done;
>  
> -	if (gencache_get(key, NULL, &value, NULL))
> +	if (gencache_get(key, talloc_tos(), &value, NULL))
>  		result = negative_conn_cache_valuedecode(value);
>   done:
>  	DEBUG(9,("check_negative_conn_cache returning result %d for domain %s "
>  		  "server %s\n", NT_STATUS_V(result), domain, server));
>  	TALLOC_FREE(key);
> -	SAFE_FREE(value);
> +	TALLOC_FREE(value);
>  	return result;
>  }
>  
> diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c
> index ebd51fd..1e61584 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, NULL, &value, &timeout)) {
> +	if (!gencache_get(key, talloc_tos(), &value, &timeout)) {
>  		DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type));
>  		SAFE_FREE(key);
>  		return False;
> @@ -170,7 +170,7 @@ bool namecache_fetch(const char *name,
>  	*num_names = ipstr_list_parse(value, ip_list);
>  
>  	SAFE_FREE(key);
> -	SAFE_FREE(value);
> +	TALLOC_FREE(value);
>  
>  	return *num_names > 0; /* true only if some ip has been fetched */
>  }
> @@ -294,7 +294,7 @@ bool namecache_status_fetch(const char *keyname,
>  	if (!key)
>  		return False;
>  
> -	if (!gencache_get(key, NULL, &value, &timeout)) {
> +	if (!gencache_get(key, talloc_tos(), &value, &timeout)) {
>  		DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n",
>  					key));
>  		SAFE_FREE(key);
> @@ -306,6 +306,6 @@ bool namecache_status_fetch(const char *keyname,
>  
>  	strlcpy(srvname_out, value, 16);
>  	SAFE_FREE(key);
> -	SAFE_FREE(value);
> +	TALLOC_FREE(value);
>  	return True;
>  }
> diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c
> index 81b366a..81d8bf9 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, NULL, &value, &timeout)) {
> +	if (!gencache_get(key, talloc_tos(), &value, &timeout)) {
>  		DEBUG(5, ("no entry for trusted domain %s found.\n", name));
>  		SAFE_FREE(key);
>  		return False;
> @@ -172,11 +172,11 @@ bool trustdom_cache_fetch(const char* name, struct dom_sid* sid)
>  	/* convert sid string representation into struct dom_sid structure */
>  	if(! string_to_sid(sid, value)) {
>  		sid = NULL;
> -		SAFE_FREE(value);
> +		TALLOC_FREE(value);
>  		return False;
>  	}
>  
> -	SAFE_FREE(value);
> +	TALLOC_FREE(value);
>  	return True;
>  }
>  
> @@ -191,7 +191,7 @@ uint32 trustdom_cache_fetch_timestamp( void )
>  	time_t timeout;
>  	uint32 timestamp;
>  
> -	if (!gencache_get(TDOMTSKEY, NULL, &value, &timeout)) {
> +	if (!gencache_get(TDOMTSKEY, talloc_tos(), &value, &timeout)) {
>  		DEBUG(5, ("no timestamp for trusted domain cache located.\n"));
>  		SAFE_FREE(value);
>  		return 0;
> @@ -199,7 +199,7 @@ uint32 trustdom_cache_fetch_timestamp( void )
>  
>  	timestamp = atoi(value);
>  
> -	SAFE_FREE(value);
> +	TALLOC_FREE(value);
>  	return timestamp;
>  }
>  
> diff --git a/source3/passdb/account_pol.c b/source3/passdb/account_pol.c
> index 14ff946..06925e8 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, NULL, &cache_value, NULL)) {
> +	if (gencache_get(cache_key, talloc_tos(), &cache_value, NULL)) {
>  		uint32 tmp = strtoul(cache_value, NULL, 10);
>  		*value = tmp;
>  		ret = True;
> @@ -454,7 +454,7 @@ bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value)
>  
>   done:
>  	SAFE_FREE(cache_key);
> -	SAFE_FREE(cache_value);
> +	TALLOC_FREE(cache_value);
>  	return ret;
>  }
>  
> diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
> index 37f11c7..89938e4 100644
> --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
> +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
> @@ -631,16 +631,16 @@ 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, NULL, &tmp, NULL)) {
> +	    gencache_get(cache_key, talloc_tos(), &tmp, NULL)) {
>  
>  		found = (strcmp(tmp, printer_not_found) != 0);
>  		if (!found) {
>  			DEBUG(4, ("Printer %s not found\n", aprinter));
> -			SAFE_FREE(tmp);
> +			TALLOC_FREE(tmp);
>  			return WERR_INVALID_PRINTER_NAME;
>  		}
>  		fstrcpy(sname, tmp);
> -		SAFE_FREE(tmp);
> +		TALLOC_FREE(tmp);
>  	}
>  
>  	/* Search all sharenames first as this is easier than pulling
> diff --git a/source3/torture/torture.c b/source3/torture/torture.c
> index f2446d1..8313cf1 100644
> --- a/source3/torture/torture.c
> +++ b/source3/torture/torture.c
> @@ -8135,7 +8135,7 @@ static bool run_local_gencache(int dummy)
>  		return False;
>  	}
>  
> -	if (!gencache_get("foo", NULL, &val, &tm)) {
> +	if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
>  		d_printf("%s: gencache_get() failed\n", __location__);
>  		return False;
>  	}
> @@ -8143,11 +8143,11 @@ static bool run_local_gencache(int dummy)
>  	if (strcmp(val, "bar") != 0) {
>  		d_printf("%s: gencache_get() returned %s, expected %s\n",
>  			 __location__, val, "bar");
> -		SAFE_FREE(val);
> +		TALLOC_FREE(val);
>  		return False;
>  	}
>  
> -	SAFE_FREE(val);
> +	TALLOC_FREE(val);
>  
>  	if (!gencache_del("foo")) {
>  		d_printf("%s: gencache_del() failed\n", __location__);
> @@ -8159,7 +8159,7 @@ static bool run_local_gencache(int dummy)
>  		return False;
>  	}
>  
> -	if (gencache_get("foo", NULL, &val, &tm)) {
> +	if (gencache_get("foo", talloc_tos(), &val, &tm)) {
>  		d_printf("%s: gencache_get() on deleted entry "
>  			 "succeeded\n", __location__);
>  		return False;
> @@ -8173,7 +8173,7 @@ static bool run_local_gencache(int dummy)
>  		return False;
>  	}
>  
> -	if (!gencache_get_data_blob("foo", NULL, &blob, NULL, NULL)) {
> +	if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
>  		d_printf("%s: gencache_get_data_blob() failed\n", __location__);
>  		return False;
>  	}
> @@ -8197,7 +8197,7 @@ static bool run_local_gencache(int dummy)
>  		return False;
>  	}
>  
> -	if (gencache_get_data_blob("foo", NULL, &blob, NULL, NULL)) {
> +	if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
>  		d_printf("%s: gencache_get_data_blob() 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", NULL, &val, &tm)) {
> +	if (gencache_get("blob", talloc_tos(), &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 b7c141a..2db7d05 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, NULL, &value, NULL)) {
> +	if (!gencache_get(key, mem_ctx, &value, NULL)) {
>  		goto done;
>  	}
>  	p = strchr(value, ' ');
> @@ -1541,6 +1541,7 @@ done:
>  	TALLOC_FREE(dc_name);
>  	TALLOC_FREE(dc_ip);
>  	TALLOC_FREE(key);
> +	TALLOC_FREE(value);
>  	return ret;
>  }
>  
> -- 
> 1.8.4
> 


-- 
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
******************************************************************


More information about the samba-technical mailing list