1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

r24733: Add support for storing DATA_BLOBs in gencache.tdb (including torturetest).

Mimir, please have a look. DATA_BLOBs will now just show up as "DATA_BLOB"
values with "net cache list".

Guenther
(This used to be commit b8ad546d04)
This commit is contained in:
Günther Deschner 2007-08-28 12:40:01 +00:00 committed by Gerald (Jerry) Carter
parent 40102ad546
commit 2af9637925
2 changed files with 198 additions and 0 deletions

View File

@ -28,6 +28,8 @@
#define TIMEOUT_LEN 12
#define CACHE_DATA_FMT "%12u/%s"
#define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us"
#define BLOB_TYPE "DATA_BLOB"
#define BLOB_TYPE_LEN 9
static TDB_CONTEXT *cache;
static BOOL cache_readonly;
@ -243,6 +245,161 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout)
return True;
}
/**
* Get existing entry from the cache file.
*
* @param keystr string that represents a key of this entry
* @param blob DATA_BLOB that is filled with entry's blob
* @param expired pointer to a BOOL that indicates whether the entry is expired
*
* @retval true when entry is successfuly fetched
* @retval False for failure
**/
BOOL gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, BOOL *expired)
{
TDB_DATA databuf;
time_t t;
char *blob_type;
unsigned char *buf = NULL;
BOOL ret = False;
fstring valstr;
int buflen = 0, len = 0, blob_len = 0;
unsigned char *blob_buf = NULL;
/* fail completely if get null pointers passed */
SMB_ASSERT(keystr);
if (!gencache_init()) {
return False;
}
databuf = tdb_fetch_bystring(cache, keystr);
if (!databuf.dptr) {
DEBUG(10,("Cache entry with key = %s couldn't be found\n",
keystr));
return False;
}
buf = (unsigned char *)databuf.dptr;
buflen = databuf.dsize;
len += tdb_unpack(buf+len, buflen-len, "fB",
&valstr,
&blob_len, &blob_buf);
if (len == -1) {
goto out;
}
t = strtol(valstr, &blob_type, 10);
if (strcmp(blob_type+1, BLOB_TYPE) != 0) {
goto out;
}
DEBUG(10,("Returning %s cache entry: key = %s, "
"timeout = %s", t > time(NULL) ? "valid" :
"expired", keystr, ctime(&t)));
if (t <= time(NULL)) {
/* We're expired */
if (expired) {
*expired = True;
}
}
if (blob) {
*blob = data_blob(blob_buf, blob_len);
if (!blob->data) {
goto out;
}
}
ret = True;
out:
SAFE_FREE(blob_buf);
SAFE_FREE(databuf.dptr);
return ret;
}
/**
* Set an entry in the cache file. If there's no such
* one, then add it.
*
* @param keystr string that represents a key of this entry
* @param blob DATA_BLOB value being cached
* @param timeout time when the value is expired
*
* @retval true when entry is successfuly stored
* @retval false on failure
**/
BOOL gencache_set_data_blob(const char *keystr, DATA_BLOB *blob, time_t timeout)
{
BOOL ret = False;
int tdb_ret;
TDB_DATA databuf;
char *valstr = NULL;
unsigned char *buf = NULL;
int len = 0, buflen = 0;
/* fail completely if get null pointers passed */
SMB_ASSERT(keystr && blob);
if (!gencache_init()) {
return False;
}
if (cache_readonly) {
return False;
}
asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE);
if (!valstr) {
return False;
}
again:
len = 0;
len += tdb_pack(buf+len, buflen-len, "fB",
valstr,
blob->length, blob->data);
if (len == -1) {
goto out;
}
if (buflen < len) {
SAFE_FREE(buf);
buf = SMB_MALLOC_ARRAY(unsigned char, len);
if (!buf) {
goto out;
}
buflen = len;
goto again;
}
databuf = make_tdb_data(buf, len);
DEBUG(10,("Adding cache entry with key = %s; "
"blob size = %d and timeout = %s"
"(%d seconds %s)\n", keystr, (int)databuf.dsize,
ctime(&timeout), (int)(timeout - time(NULL)),
timeout > time(NULL) ? "ahead" : "in the past"));
tdb_ret = tdb_store_bystring(cache, keystr, databuf, 0);
if (tdb_ret == 0) {
ret = True;
}
out:
SAFE_FREE(valstr);
SAFE_FREE(buf);
return ret;
}
/**
* Iterate through all entries which key matches to specified pattern

View File

@ -4820,6 +4820,7 @@ static BOOL run_local_gencache(int dummy)
{
char *val;
time_t tm;
DATA_BLOB blob;
if (!gencache_init()) {
d_printf("%s: gencache_init() failed\n", __location__);
@ -4861,6 +4862,46 @@ static BOOL run_local_gencache(int dummy)
return False;
}
blob = data_blob_string_const("bar");
tm = time(NULL);
if (!gencache_set_data_blob("foo", &blob, tm)) {
d_printf("%s: gencache_set_data_blob() failed\n", __location__);
return False;
}
data_blob_free(&blob);
if (!gencache_get_data_blob("foo", &blob, NULL)) {
d_printf("%s: gencache_get_data_blob() failed\n", __location__);
return False;
}
if (strcmp((const char *)blob.data, "bar") != 0) {
d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
__location__, (const char *)blob.data, "bar");
data_blob_free(&blob);
return False;
}
data_blob_free(&blob);
if (!gencache_del("foo")) {
d_printf("%s: gencache_del() failed\n", __location__);
return False;
}
if (gencache_del("foo")) {
d_printf("%s: second gencache_del() succeeded\n",
__location__);
return False;
}
if (gencache_get_data_blob("foo", &blob, NULL)) {
d_printf("%s: gencache_get_data_blob() on deleted entry "
"succeeded\n", __location__);
return False;
}
if (!gencache_shutdown()) {
d_printf("%s: gencache_shutdown() failed\n", __location__);
return False;