Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/lib/gencache.c

    r740 r988  
    2626#include "system/glob.h"
    2727#include "util_tdb.h"
     28#include "tdb_wrap/tdb_wrap.h"
     29#include "../lib/util/memcache.h"
    2830
    2931#undef  DBGC_CLASS
     
    3638#define BLOB_TYPE_LEN 9
    3739
    38 static struct tdb_context *cache;
    39 static struct tdb_context *cache_notrans;
     40static struct tdb_wrap *cache;
     41static struct tdb_wrap *cache_notrans;
     42static int cache_notrans_seqnum;
    4043
    4144/**
     
    5962        char* cache_fname = NULL;
    6063        int open_flags = O_RDWR|O_CREAT;
    61         bool first_try = true;
    6264
    6365        /* skip file open if it's already opened */
    64         if (cache) return True;
    65 
    66         cache_fname = lock_path("gencache.tdb");
     66        if (cache) {
     67                return true;
     68        }
     69
     70        cache_fname = cache_path("gencache.tdb");
     71        if (cache_fname == NULL) {
     72                return false;
     73        }
    6774
    6875        DEBUG(5, ("Opening cache file at %s\n", cache_fname));
    6976
    70 again:
    71         cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT|TDB_INCOMPATIBLE_HASH, open_flags, 0644);
     77        cache = tdb_wrap_open(NULL, cache_fname, 0,
     78                              TDB_DEFAULT|TDB_INCOMPATIBLE_HASH,
     79                              open_flags, 0644);
    7280        if (cache) {
    7381                int ret;
    74                 ret = tdb_check(cache, NULL, NULL);
     82                ret = tdb_check(cache->tdb, NULL, NULL);
    7583                if (ret != 0) {
    76                         tdb_close(cache);
    77                         cache = NULL;
    78                         if (!first_try) {
    79                                 DEBUG(0, ("gencache_init: tdb_check(%s) failed\n",
    80                                           cache_fname));
    81                                 return false;
    82                         }
    83                         first_try = false;
    84                         DEBUG(0, ("gencache_init: tdb_check(%s) failed - retry after CLEAR_IF_FIRST\n",
    85                                   cache_fname));
    86                         cache = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, open_flags, 0644);
    87                         if (cache) {
    88                                 tdb_close(cache);
    89                                 cache = NULL;
    90                                 goto again;
    91                         }
     84                        TALLOC_FREE(cache);
     85
     86                        /*
     87                         * Retry with CLEAR_IF_FIRST.
     88                         *
     89                         * Warning: Converting this to dbwrap won't work
     90                         * directly. gencache.c does transactions on this tdb,
     91                         * and dbwrap forbids this for CLEAR_IF_FIRST
     92                         * databases. tdb does allow transactions on
     93                         * CLEAR_IF_FIRST databases, so lets use it here to
     94                         * clean up a broken database.
     95                         */
     96                        cache = tdb_wrap_open(NULL, cache_fname, 0,
     97                                              TDB_DEFAULT|
     98                                              TDB_INCOMPATIBLE_HASH|
     99                                              TDB_CLEAR_IF_FIRST,
     100                                              open_flags, 0644);
    92101                }
    93102        }
     
    95104        if (!cache && (errno == EACCES)) {
    96105                open_flags = O_RDONLY;
    97                 cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT|TDB_INCOMPATIBLE_HASH, open_flags,
    98                                      0644);
     106                cache = tdb_wrap_open(NULL, cache_fname, 0,
     107                                      TDB_DEFAULT|TDB_INCOMPATIBLE_HASH,
     108                                      open_flags, 0644);
    99109                if (cache) {
    100110                        DEBUG(5, ("gencache_init: Opening cache file %s read-only.\n", cache_fname));
    101111                }
    102112        }
     113        TALLOC_FREE(cache_fname);
    103114
    104115        if (!cache) {
    105116                DEBUG(5, ("Attempt to open gencache.tdb has failed.\n"));
    106                 return False;
     117                return false;
    107118        }
    108119
    109120        cache_fname = lock_path("gencache_notrans.tdb");
     121        if (cache_fname == NULL) {
     122                TALLOC_FREE(cache);
     123                return false;
     124        }
    110125
    111126        DEBUG(5, ("Opening cache file at %s\n", cache_fname));
    112127
    113         cache_notrans = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
    114                                      open_flags, 0644);
     128        cache_notrans = tdb_wrap_open(NULL, cache_fname, 0,
     129                                      TDB_CLEAR_IF_FIRST|
     130                                      TDB_INCOMPATIBLE_HASH|
     131                                      TDB_SEQNUM|
     132                                      TDB_NOSYNC|
     133                                      TDB_MUTEX_LOCKING,
     134                                      open_flags, 0644);
    115135        if (cache_notrans == NULL) {
    116136                DEBUG(5, ("Opening %s failed: %s\n", cache_fname,
    117137                          strerror(errno)));
    118                 tdb_close(cache);
    119                 cache = NULL;
    120                 return false;
    121         }
    122 
    123         return True;
     138                TALLOC_FREE(cache_fname);
     139                TALLOC_FREE(cache);
     140                return false;
     141        }
     142        TALLOC_FREE(cache_fname);
     143
     144        return true;
    124145}
    125146
     
    127148{
    128149        TDB_DATA result;
    129         result.dptr = (uint8_t *)"@LAST_STABILIZED";
     150        result.dptr = discard_const_p(uint8_t, "@LAST_STABILIZED");
    130151        result.dsize = 17;
    131152        return result;
     153}
     154
     155struct gencache_have_val_state {
     156        time_t new_timeout;
     157        const DATA_BLOB *data;
     158        bool gotit;
     159};
     160
     161static void gencache_have_val_parser(time_t old_timeout, DATA_BLOB data,
     162                                     void *private_data)
     163{
     164        struct gencache_have_val_state *state =
     165                (struct gencache_have_val_state *)private_data;
     166        time_t now = time(NULL);
     167        int cache_time_left, new_time_left, additional_time;
     168
     169        /*
     170         * Excuse the many variables, but these time calculations are
     171         * confusing to me. We do not want to write to gencache with a
     172         * possibly expensive transaction if we are about to write the same
     173         * value, just extending the remaining timeout by less than 10%.
     174         */
     175
     176        cache_time_left = old_timeout - now;
     177        if (cache_time_left <= 0) {
     178                /*
     179                 * timed out, write new value
     180                 */
     181                return;
     182        }
     183
     184        new_time_left = state->new_timeout - now;
     185        if (new_time_left <= 0) {
     186                /*
     187                 * Huh -- no new timeout?? Write it.
     188                 */
     189                return;
     190        }
     191
     192        if (new_time_left < cache_time_left) {
     193                /*
     194                 * Someone wants to shorten the timeout. Let it happen.
     195                 */
     196                return;
     197        }
     198
     199        /*
     200         * By how much does the new timeout extend the remaining cache time?
     201         */
     202        additional_time = new_time_left - cache_time_left;
     203
     204        if (additional_time * 10 < 0) {
     205                /*
     206                 * Integer overflow. We extend by so much that we have to write it.
     207                 */
     208                return;
     209        }
     210
     211        /*
     212         * The comparison below is essentially equivalent to
     213         *
     214         *    new_time_left > cache_time_left * 1.10
     215         *
     216         * but without floating point calculations.
     217         */
     218
     219        if (additional_time * 10 > cache_time_left) {
     220                /*
     221                 * We extend the cache timeout by more than 10%. Do it.
     222                 */
     223                return;
     224        }
     225
     226        /*
     227         * Now the more expensive data compare.
     228         */
     229        if (data_blob_cmp(state->data, &data) != 0) {
     230                /*
     231                 * Write a new value. Certainly do it.
     232                 */
     233                return;
     234        }
     235
     236        /*
     237         * Extending the timeout by less than 10% for the same cache value is
     238         * not worth the trouble writing a value into gencache under a
     239         * possibly expensive transaction.
     240         */
     241        state->gotit = true;
     242}
     243
     244static bool gencache_have_val(const char *keystr, const DATA_BLOB *data,
     245                              time_t timeout)
     246{
     247        struct gencache_have_val_state state;
     248
     249        state.new_timeout = timeout;
     250        state.data = data;
     251        state.gotit = false;
     252
     253        if (!gencache_parse(keystr, gencache_have_val_parser, &state)) {
     254                return false;
     255        }
     256        return state.gotit;
     257}
     258
     259static int last_stabilize_parser(TDB_DATA key, TDB_DATA data,
     260                                 void *private_data)
     261{
     262        time_t *last_stabilize = private_data;
     263
     264        if ((data.dsize != 0) && (data.dptr[data.dsize-1] == '\0')) {
     265                *last_stabilize = atoi((char *)data.dptr);
     266        }
     267        return 0;
    132268}
    133269
     
    140276 * @param timeout time when the value is expired
    141277 *
    142  * @retval true when entry is successfuly stored
     278 * @retval true when entry is successfully stored
    143279 * @retval false on failure
    144280 **/
     
    148284{
    149285        int ret;
    150         TDB_DATA databuf;
     286        fstring hdr;
     287        int hdr_len;
    151288        char* val;
    152289        time_t last_stabilize;
     
    163300        }
    164301
    165         if (!gencache_init()) return False;
    166 
    167         val = talloc_asprintf(talloc_tos(), CACHE_DATA_FMT, (int)timeout);
     302        if (!gencache_init()) {
     303                return false;
     304        }
     305
     306        if (gencache_have_val(keystr, blob, timeout)) {
     307                DEBUG(10, ("Did not store value for %s, we already got it\n",
     308                           keystr));
     309                return true;
     310        }
     311
     312        hdr_len = fstr_sprintf(hdr, CACHE_DATA_FMT, (int)timeout);
     313
     314        if (hdr_len == -1) {
     315                return false;
     316        }
     317        if ((blob->length + (size_t)hdr_len) < blob->length) {
     318                return false;
     319        }
     320
     321        val = talloc_array(talloc_tos(), char, hdr_len + blob->length);
    168322        if (val == NULL) {
    169                 return False;
    170         }
    171         val = talloc_realloc(NULL, val, char, talloc_array_length(val)-1);
    172         if (val == NULL) {
    173                 return false;
    174         }
    175         val = (char *)talloc_append_blob(NULL, val, *blob);
    176         if (val == NULL) {
    177                 return false;
    178         }
    179 
    180         DEBUG(10, ("Adding cache entry with key = %s and timeout ="
    181                    " %s (%d seconds %s)\n", keystr, ctime(&timeout),
     323                return false;
     324        }
     325
     326        memcpy(val, hdr, hdr_len);
     327        memcpy(val+hdr_len, blob->data, blob->length);
     328
     329        DEBUG(10, ("Adding cache entry with key=[%s] and timeout="
     330                   "[%s] (%d seconds %s)\n", keystr,
     331                   timestring(talloc_tos(), timeout),
    182332                   (int)(timeout - time(NULL)),
    183333                   timeout > time(NULL) ? "ahead" : "in the past"));
    184334
    185335        ret = tdb_store_bystring(
    186                 cache_notrans, keystr,
     336                cache_notrans->tdb, keystr,
    187337                make_tdb_data((uint8_t *)val, talloc_array_length(val)),
    188338                0);
     
    211361
    212362        last_stabilize = 0;
    213         databuf = tdb_fetch(cache_notrans, last_stabilize_key());
    214         if ((databuf.dptr != NULL)
    215             && (databuf.dptr[databuf.dsize-1] == '\0')) {
    216                 last_stabilize = atoi((char *)databuf.dptr);
    217                 SAFE_FREE(databuf.dptr);
    218         }
     363
     364        tdb_parse_record(cache_notrans->tdb, last_stabilize_key(),
     365                         last_stabilize_parser, &last_stabilize);
     366
    219367        if ((last_stabilize
    220368             + lp_parm_int(-1, "gencache", "stabilize_interval", 300))
     
    246394        }
    247395
    248         if (!gencache_init()) return False;     
    249 
    250         DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr));
     396        if (!gencache_init()) {
     397                return false;
     398        }
     399
     400        DEBUG(10, ("Deleting cache entry (key=[%s])\n", keystr));
    251401
    252402        /*
     
    256406         */
    257407
    258         exists = gencache_get_data_blob(keystr, &value, NULL, &was_expired);
     408        exists = gencache_get_data_blob(keystr, NULL, &value, NULL,
     409                                        &was_expired);
    259410
    260411        if (!exists && was_expired) {
     
    300451        void (*parser)(time_t timeout, DATA_BLOB blob, void *private_data);
    301452        void *private_data;
     453        bool is_memcache;
    302454};
    303455
     
    321473                endptr+1, data.dsize - PTR_DIFF(endptr+1, data.dptr));
    322474        state->parser(t, blob, state->private_data);
     475
     476        if (!state->is_memcache) {
     477                memcache_add(NULL, GENCACHE_RAM,
     478                             data_blob_const(key.dptr, key.dsize),
     479                             data_blob_const(data.dptr, data.dsize));
     480        }
     481
    323482        return 0;
    324483}
     
    330489{
    331490        struct gencache_parse_state state;
    332         TDB_DATA key;
     491        TDB_DATA key = string_term_tdb_data(keystr);
     492        DATA_BLOB memcache_val;
    333493        int ret;
    334494
     
    336496                return false;
    337497        }
    338         if (tdb_data_cmp(string_term_tdb_data(keystr),
    339                          last_stabilize_key()) == 0) {
     498        if (tdb_data_cmp(key, last_stabilize_key()) == 0) {
    340499                return false;
    341500        }
     
    344503        }
    345504
    346         key = string_term_tdb_data(keystr);
    347505        state.parser = parser;
    348506        state.private_data = private_data;
    349507
    350         ret = tdb_parse_record(cache_notrans, key, gencache_parse_fn, &state);
    351         if (ret != -1) {
     508        if (memcache_lookup(NULL, GENCACHE_RAM,
     509                            data_blob_const(key.dptr, key.dsize),
     510                            &memcache_val)) {
     511                /*
     512                 * Make sure that nobody has changed the gencache behind our
     513                 * back.
     514                 */
     515                int current_seqnum = tdb_get_seqnum(cache_notrans->tdb);
     516                if (current_seqnum == cache_notrans_seqnum) {
     517                        /*
     518                         * Ok, our memcache is still current, use it without
     519                         * going to the tdb files.
     520                         */
     521                        state.is_memcache = true;
     522                        gencache_parse_fn(key, make_tdb_data(memcache_val.data,
     523                                                             memcache_val.length),
     524                                          &state);
     525                        return true;
     526                }
     527                memcache_flush(NULL, GENCACHE_RAM);
     528                cache_notrans_seqnum = current_seqnum;
     529        }
     530
     531        state.is_memcache = false;
     532
     533        ret = tdb_parse_record(cache_notrans->tdb, key,
     534                               gencache_parse_fn, &state);
     535        if (ret == 0) {
    352536                return true;
    353537        }
    354         ret = tdb_parse_record(cache, key, gencache_parse_fn, &state);
    355         return (ret != -1);
     538        ret = tdb_parse_record(cache->tdb, key, gencache_parse_fn, &state);
     539        return (ret == 0);
    356540}
    357541
    358542struct gencache_get_data_blob_state {
     543        TALLOC_CTX *mem_ctx;
    359544        DATA_BLOB *blob;
    360545        time_t timeout;
     
    379564        }
    380565
    381         *state->blob = data_blob(blob.data, blob.length);
     566        *state->blob = data_blob_talloc(state->mem_ctx, blob.data,
     567                                        blob.length);
    382568        if (state->blob->data == NULL) {
    383569                state->result = false;
     
    396582 *
    397583 * @retval true when entry is successfuly fetched
    398  * @retval False for failure
     584 * @retval false for failure
    399585 **/
    400586
    401 bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
     587bool gencache_get_data_blob(const char *keystr, TALLOC_CTX *mem_ctx,
     588                            DATA_BLOB *blob,
    402589                            time_t *timeout, bool *was_expired)
    403590{
     
    406593
    407594        state.result = false;
     595        state.mem_ctx = mem_ctx;
    408596        state.blob = blob;
    409597
     
    429617        }
    430618
    431         return True;
     619        return true;
    432620
    433621fail:
     
    443631struct stabilize_state {
    444632        bool written;
    445         bool error;
    446633};
    447634static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
    448635                        void *priv);
    449636
     637static int wipe_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
     638                   void *priv);
     639
    450640/**
    451641 * Stabilize gencache
     
    465655        }
    466656
    467         res = tdb_transaction_start_nonblock(cache);
    468         if (res == -1) {
    469 
    470                 if (tdb_error(cache) == TDB_ERR_NOLOCK) {
     657        res = tdb_transaction_start_nonblock(cache->tdb);
     658        if (res != 0) {
     659                if (tdb_error(cache->tdb) == TDB_ERR_NOLOCK)
     660                {
    471661                        /*
    472662                         * Someone else already does the stabilize,
     
    477667
    478668                DEBUG(10, ("Could not start transaction on gencache.tdb: "
    479                            "%s\n", tdb_errorstr(cache)));
    480                 return false;
    481         }
    482         res = tdb_transaction_start(cache_notrans);
    483         if (res == -1) {
    484                 tdb_transaction_cancel(cache);
    485                 DEBUG(10, ("Could not start transaction on "
     669                           "%s\n", tdb_errorstr(cache->tdb)));
     670                return false;
     671        }
     672
     673        res = tdb_lockall(cache_notrans->tdb);
     674        if (res != 0) {
     675                tdb_transaction_cancel(cache->tdb);
     676                DEBUG(10, ("Could not get allrecord lock on "
    486677                           "gencache_notrans.tdb: %s\n",
    487                            tdb_errorstr(cache_notrans)));
    488                 return false;
    489         }
    490 
    491         state.error = false;
     678                           tdb_errorstr(cache_notrans->tdb)));
     679                return false;
     680        }
     681
    492682        state.written = false;
    493683
    494         res = tdb_traverse(cache_notrans, stabilize_fn, &state);
    495         if ((res == -1) || state.error) {
    496                 if ((tdb_transaction_cancel(cache_notrans) == -1)
    497                     || (tdb_transaction_cancel(cache) == -1)) {
    498                         smb_panic("tdb_transaction_cancel failed\n");
    499                 }
     684        res = tdb_traverse(cache_notrans->tdb, stabilize_fn, &state);
     685        if (res < 0) {
     686                tdb_unlockall(cache_notrans->tdb);
     687                tdb_transaction_cancel(cache->tdb);
    500688                return false;
    501689        }
    502690
    503691        if (!state.written) {
    504                 if ((tdb_transaction_cancel(cache_notrans) == -1)
    505                     || (tdb_transaction_cancel(cache) == -1)) {
    506                         smb_panic("tdb_transaction_cancel failed\n");
    507                 }
     692                tdb_unlockall(cache_notrans->tdb);
     693                tdb_transaction_cancel(cache->tdb);
    508694                return true;
    509695        }
    510696
    511         res = tdb_transaction_commit(cache);
    512         if (res == -1) {
     697        res = tdb_transaction_commit(cache->tdb);
     698        if (res != 0) {
    513699                DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
    514                            "%s\n", tdb_errorstr(cache)));
    515                 if (tdb_transaction_cancel(cache_notrans) == -1) {
    516                         smb_panic("tdb_transaction_cancel failed\n");
    517                 }
    518                 return false;
    519         }
    520 
    521         res = tdb_transaction_commit(cache_notrans);
    522         if (res == -1) {
    523                 DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
    524                            "%s\n", tdb_errorstr(cache)));
     700                           "%s\n", tdb_errorstr(cache->tdb)));
     701                tdb_unlockall(cache_notrans->tdb);
     702                return false;
     703        }
     704
     705        res = tdb_traverse(cache_notrans->tdb, wipe_fn, NULL);
     706        if (res < 0) {
     707                DEBUG(10, ("tdb_traverse with wipe_fn on gencache_notrans.tdb "
     708                          "failed: %s\n",
     709                           tdb_errorstr(cache_notrans->tdb)));
     710                tdb_unlockall(cache_notrans->tdb);
     711                return false;
     712        }
     713
     714        res = tdb_unlockall(cache_notrans->tdb);
     715        if (res != 0) {
     716                DEBUG(10, ("tdb_unlockall on gencache.tdb failed: "
     717                           "%s\n", tdb_errorstr(cache->tdb)));
    525718                return false;
    526719        }
     
    528721        now = talloc_asprintf(talloc_tos(), "%d", (int)time(NULL));
    529722        if (now != NULL) {
    530                 tdb_store(cache_notrans, last_stabilize_key(),
     723                tdb_store(cache_notrans->tdb, last_stabilize_key(),
    531724                          string_term_tdb_data(now), 0);
    532725                TALLOC_FREE(now);
     
    552745        }
    553746        if ((timeout < time(NULL)) || (val.dsize == 0)) {
    554                 res = tdb_delete(cache, key);
    555                 if ((res == -1) && (tdb_error(cache) == TDB_ERR_NOEXIST)) {
     747                res = tdb_delete(cache->tdb, key);
     748                if (res == 0) {
     749                        state->written = true;
     750                } else if (tdb_error(cache->tdb) == TDB_ERR_NOEXIST) {
    556751                        res = 0;
    557                 } else {
    558                         state->written = true;
    559752                }
    560753        } else {
    561                 res = tdb_store(cache, key, val, 0);
     754                res = tdb_store(cache->tdb, key, val, 0);
    562755                if (res == 0) {
    563756                        state->written = true;
     
    565758        }
    566759
    567         if (res == -1) {
     760        if (res != 0) {
    568761                DEBUG(10, ("Transfer to gencache.tdb failed: %s\n",
    569                            tdb_errorstr(cache)));
    570                 state->error = true;
     762                           tdb_errorstr(cache->tdb)));
    571763                return -1;
    572764        }
    573765
    574         if (tdb_delete(cache_notrans, key) == -1) {
     766        return 0;
     767}
     768
     769static int wipe_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
     770                   void *priv)
     771{
     772        int res;
     773        bool ok;
     774        time_t timeout;
     775
     776        res = tdb_data_cmp(key, last_stabilize_key());
     777        if (res == 0) {
     778                return 0;
     779        }
     780
     781        ok = gencache_pull_timeout((char *)val.dptr, &timeout, NULL);
     782        if (!ok) {
     783                DEBUG(10, ("Ignoring invalid entry\n"));
     784                return 0;
     785        }
     786
     787        res = tdb_delete(tdb, key);
     788        if (res != 0) {
    575789                DEBUG(10, ("tdb_delete from gencache_notrans.tdb failed: "
    576                            "%s\n", tdb_errorstr(cache_notrans)));
    577                 state->error = true;
     790                           "%s\n", tdb_errorstr(cache_notrans->tdb)));
    578791                return -1;
    579792        }
     793
    580794        return 0;
    581795}
     796
    582797
    583798/**
     
    591806 *
    592807 * @retval true when entry is successfuly fetched
    593  * @retval False for failure
     808 * @retval false for failure
    594809 **/
    595810
    596 bool gencache_get(const char *keystr, char **value, time_t *ptimeout)
     811bool gencache_get(const char *keystr, TALLOC_CTX *mem_ctx, char **value,
     812                  time_t *ptimeout)
    597813{
    598814        DATA_BLOB blob;
    599         bool ret = False;
    600 
    601         ret = gencache_get_data_blob(keystr, &blob, ptimeout, NULL);
     815        bool ret = false;
     816
     817        ret = gencache_get_data_blob(keystr, mem_ctx, &blob, ptimeout, NULL);
    602818        if (!ret) {
    603819                return false;
    604820        }
    605821        if ((blob.data == NULL) || (blob.length == 0)) {
    606                 SAFE_FREE(blob.data);
     822                data_blob_free(&blob);
    607823                return false;
    608824        }
    609825        if (blob.data[blob.length-1] != '\0') {
    610826                /* Not NULL terminated, can't be a string */
    611                 SAFE_FREE(blob.data);
     827                data_blob_free(&blob);
    612828                return false;
    613829        }
    614830        if (value) {
    615                 *value = SMB_STRDUP((char *)blob.data);
    616                 data_blob_free(&blob);
    617                 if (*value == NULL) {
    618                         return false;
    619                 }
     831                /*
     832                 * talloc_move generates a type-punned warning here. As we
     833                 * leave the function immediately, do a simple talloc_steal.
     834                 */
     835                *value = (char *)talloc_steal(mem_ctx, blob.data);
    620836                return true;
    621837        }
     
    663879                return 0;
    664880        }
    665         if (state->in_persistent && tdb_exists(cache_notrans, key)) {
     881        if (state->in_persistent && tdb_exists(cache_notrans->tdb, key)) {
    666882                return 0;
    667883        }
     
    671887        } else {
    672888                /* ensure 0-termination */
    673                 keystr = SMB_STRNDUP((char *)key.dptr, key.dsize);
     889                keystr = talloc_strndup(talloc_tos(), (char *)key.dptr, key.dsize);
    674890                free_key = keystr;
     891                if (keystr == NULL) {
     892                        goto done;
     893                }
    675894        }
    676895
     
    684903        }
    685904
    686         DEBUG(10, ("Calling function with arguments (key=%s, timeout=%s)\n",
    687                    keystr, ctime(&timeout)));
     905        DEBUG(10, ("Calling function with arguments "
     906                   "(key=[%s], timeout=[%s])\n",
     907                   keystr, timestring(talloc_tos(), timeout)));
    688908
    689909        state->fn(keystr,
     
    693913
    694914 done:
    695         SAFE_FREE(free_key);
     915        TALLOC_FREE(free_key);
    696916        return 0;
    697917}
     
    714934
    715935        state.in_persistent = false;
    716         tdb_traverse(cache_notrans, gencache_iterate_blobs_fn, &state);
     936        tdb_traverse(cache_notrans->tdb, gencache_iterate_blobs_fn, &state);
    717937
    718938        state.in_persistent = true;
    719         tdb_traverse(cache, gencache_iterate_blobs_fn, &state);
     939        tdb_traverse(cache->tdb, gencache_iterate_blobs_fn, &state);
    720940}
    721941
     
    749969        } else {
    750970                /* ensure 0-termination */
    751                 valstr = SMB_STRNDUP((char *)value.data, value.length);
     971                valstr = talloc_strndup(talloc_tos(), (char *)value.data, value.length);
    752972                free_val = valstr;
     973                if (valstr == NULL) {
     974                        goto done;
     975                }
    753976        }
    754977
    755978        DEBUG(10, ("Calling function with arguments "
    756                    "(key = %s, value = %s, timeout = %s)\n",
    757                    key, valstr, ctime(&timeout)));
     979                   "(key=[%s], value=[%s], timeout=[%s])\n",
     980                   key, valstr, timestring(talloc_tos(), timeout)));
    758981
    759982        state->fn(key, valstr, timeout, state->private_data);
    760983
    761         SAFE_FREE(free_val);
     984  done:
     985
     986        TALLOC_FREE(free_val);
    762987}
    763988
Note: See TracChangeset for help on using the changeset viewer.