Ignore:
Timestamp:
Nov 12, 2012, 5:09:31 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server 3.5: update branche to 3.5.13

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.5.x/source3/winbindd/winbindd_cache.c

    r599 r733  
    3333#define DBGC_CLASS DBGC_WINBIND
    3434
    35 #define WINBINDD_CACHE_VERSION 1
     35#define WINBINDD_CACHE_VER1 1 /* initial db version */
     36#define WINBINDD_CACHE_VER2 2 /* second version with timeouts for NDR entries */
     37
     38#define WINBINDD_CACHE_VERSION WINBINDD_CACHE_VER2
    3639#define WINBINDD_CACHE_VERSION_KEYSTR "WINBINDD_CACHE_VERSION"
    3740
     
    9396        NTSTATUS status;
    9497        uint32 sequence_number;
     98        uint64 timeout;
    9599        uint8 *data;
    96100        uint32 len, ofs;
     
    224228
    225229/*
     230  pull a uint64 from a cache entry
     231*/
     232static uint64 centry_uint64(struct cache_entry *centry)
     233{
     234        uint64 ret;
     235
     236        if (!centry_check_bytes(centry, 8)) {
     237                smb_panic_fn("centry_uint64");
     238        }
     239        ret = BVAL(centry->data, centry->ofs);
     240        centry->ofs += 8;
     241        return ret;
     242}
     243
     244/*
    226245  pull a uint32 from a cache entry
    227246*/
     
    615634
    616635        /* if the server is down or the cache entry is not older than the
    617            current sequence number then it is OK */
    618         if (wcache_server_down(domain) ||
    619             centry->sequence_number == domain->sequence_number) {
     636           current sequence number or it did not timeout then it is OK */
     637        if (wcache_server_down(domain)
     638            || (centry->sequence_number == domain->sequence_number
     639                && centry->timeout > time(NULL))) {
    620640                DEBUG(10,("centry_expired: Key %s for domain %s is good.\n",
    621641                        keystr, domain->name ));
     
    648668        centry->ofs = 0;
    649669
    650         if (centry->len < 8) {
     670        if (centry->len < 16) {
    651671                /* huh? corrupt cache? */
    652                 DEBUG(10,("wcache_fetch_raw: Corrupt cache for key %s (len < 8) ?\n", kstr));
     672                DEBUG(10,("wcache_fetch_raw: Corrupt cache for key %s "
     673                          "(len < 16)?\n", kstr));
    653674                centry_free(centry);
    654675                return NULL;
     
    657678        centry->status = centry_ntstatus(centry);
    658679        centry->sequence_number = centry_uint32(centry);
     680        centry->timeout = centry_uint64(centry);
    659681
    660682        return centry;
     
    743765
    744766/*
     767  push a uint64 into a centry
     768*/
     769static void centry_put_uint64(struct cache_entry *centry, uint64 v)
     770{
     771        centry_expand(centry, 8);
     772        SBVAL(centry->data, centry->ofs, v);
     773        centry->ofs += 8;
     774}
     775
     776/*
    745777  push a uint32 into a centry
    746778*/
     
    863895        centry->ofs = 0;
    864896        centry->sequence_number = domain->sequence_number;
     897        centry->timeout = lp_winbind_cache_time() + time(NULL);
    865898        centry_put_ntstatus(centry, status);
    866899        centry_put_uint32(centry, centry->sequence_number);
     900        centry_put_uint64(centry, centry->timeout);
    867901        return centry;
    868902}
     
    34493483        centry->ofs = 0;
    34503484
    3451         if (centry->len < 8) {
     3485        if (centry->len < 16) {
    34523486                /* huh? corrupt cache? */
    3453                 DEBUG(0,("create_centry_validate: Corrupt cache for key %s (len < 8) ?\n", kstr));
     3487                DEBUG(0,("create_centry_validate: Corrupt cache for key %s "
     3488                         "(len < 16) ?\n", kstr));
    34543489                centry_free(centry);
    34553490                state->bad_entry = true;
     
    34603495        centry->status = NT_STATUS(centry_uint32(centry));
    34613496        centry->sequence_number = centry_uint32(centry);
     3497        centry->timeout = centry_uint64(centry);
    34623498        return centry;
    34633499}
     
    40124048}
    40134049
     4050static int wbcache_update_centry_fn(TDB_CONTEXT *tdb,
     4051                                    TDB_DATA key,
     4052                                    TDB_DATA data,
     4053                                    void *state)
     4054{
     4055        uint64_t ctimeout;
     4056        TDB_DATA blob;
     4057
     4058        if (is_non_centry_key(key)) {
     4059                return 0;
     4060        }
     4061
     4062        if (data.dptr == NULL || data.dsize == 0) {
     4063                if (tdb_delete(tdb, key) < 0) {
     4064                        DEBUG(0, ("tdb_delete for [%s] failed!\n",
     4065                                  key.dptr));
     4066                        return 1;
     4067                }
     4068        }
     4069
     4070        /* add timeout to blob (uint64_t) */
     4071        blob.dsize = data.dsize + 8;
     4072
     4073        blob.dptr = SMB_XMALLOC_ARRAY(uint8_t, blob.dsize);
     4074        if (blob.dptr == NULL) {
     4075                return 1;
     4076        }
     4077        memset(blob.dptr, 0, blob.dsize);
     4078
     4079        /* copy status and seqnum */
     4080        memcpy(blob.dptr, data.dptr, 8);
     4081
     4082        /* add timeout */
     4083        ctimeout = lp_winbind_cache_time() + time(NULL);
     4084        SBVAL(blob.dptr, 8, ctimeout);
     4085
     4086        /* copy the rest */
     4087        memcpy(blob.dptr + 16, data.dptr + 8, data.dsize - 8);
     4088
     4089        if (tdb_store(tdb, key, blob, TDB_REPLACE) < 0) {
     4090                DEBUG(0, ("tdb_store to update [%s] failed!\n",
     4091                          key.dptr));
     4092                SAFE_FREE(blob.dptr);
     4093                return 1;
     4094        }
     4095
     4096        SAFE_FREE(blob.dptr);
     4097        return 0;
     4098}
     4099
     4100static bool wbcache_upgrade_v1_to_v2(TDB_CONTEXT *tdb)
     4101{
     4102        int rc;
     4103
     4104        DEBUG(1, ("Upgrade to version 2 of the winbindd_cache.tdb\n"));
     4105
     4106        rc = tdb_traverse(tdb, wbcache_update_centry_fn, NULL);
     4107        if (rc < 0) {
     4108                return false;
     4109        }
     4110
     4111        return true;
     4112}
     4113
    40144114/***********************************************************************
    40154115 Try and validate every entry in the winbindd cache. If we fail here,
     
    40224122        const char *tdb_path = cache_path("winbindd_cache.tdb");
    40234123        TDB_CONTEXT *tdb = NULL;
     4124        uint32_t vers_id;
     4125        bool ok;
    40244126
    40254127        DEBUG(10, ("winbindd_validate_cache: replacing panic function\n"));
    40264128        smb_panic_fn = validate_panic;
    4027 
    40284129
    40294130        tdb = tdb_open_log(tdb_path,
     
    40394140                goto done;
    40404141        }
     4142
     4143        /* Version check and upgrade code. */
     4144        if (!tdb_fetch_uint32(tdb, WINBINDD_CACHE_VERSION_KEYSTR, &vers_id)) {
     4145                DEBUG(10, ("Fresh database\n"));
     4146                tdb_store_uint32(tdb, WINBINDD_CACHE_VERSION_KEYSTR, WINBINDD_CACHE_VERSION);
     4147                vers_id = WINBINDD_CACHE_VERSION;
     4148        }
     4149
     4150        if (vers_id != WINBINDD_CACHE_VERSION) {
     4151                if (vers_id == WINBINDD_CACHE_VER1) {
     4152                        ok = wbcache_upgrade_v1_to_v2(tdb);
     4153                        if (!ok) {
     4154                                DEBUG(10, ("winbindd_validate_cache: upgrade to version 2 failed.\n"));
     4155                                unlink(tdb_path);
     4156                                goto done;
     4157                        }
     4158
     4159                        tdb_store_uint32(tdb,
     4160                                         WINBINDD_CACHE_VERSION_KEYSTR,
     4161                                         WINBINDD_CACHE_VERSION);
     4162                        vers_id = WINBINDD_CACHE_VER2;
     4163                }
     4164        }
     4165
    40414166        tdb_close(tdb);
    40424167
     
    46584783                return false;
    46594784        }
    4660         if (data.dsize < 4) {
     4785        if (data.dsize < 12) {
    46614786                goto fail;
    46624787        }
     
    46644789        if (!is_domain_offline(domain)) {
    46654790                uint32_t entry_seqnum, dom_seqnum, last_check;
     4791                uint64_t entry_timeout;
    46664792
    46674793                if (!wcache_fetch_seqnum(domain->name, &dom_seqnum,
     
    46754801                        goto fail;
    46764802                }
    4677         }
    4678 
    4679         resp->data = (uint8_t *)talloc_memdup(mem_ctx, data.dptr + 4,
    4680                                               data.dsize - 4);
     4803                entry_timeout = BVAL(data.dptr, 4);
     4804                if (time(NULL) > entry_timeout) {
     4805                        DEBUG(10, ("Entry has timed out\n"));
     4806                        goto fail;
     4807                }
     4808        }
     4809
     4810        resp->data = (uint8_t *)talloc_memdup(mem_ctx, data.dptr + 12,
     4811                                              data.dsize - 12);
    46814812        if (resp->data == NULL) {
    46824813                DEBUG(10, ("talloc failed\n"));
    46834814                goto fail;
    46844815        }
    4685         resp->length = data.dsize - 4;
     4816        resp->length = data.dsize - 12;
    46864817
    46874818        ret = true;
     
    46964827        TDB_DATA key, data;
    46974828        uint32_t dom_seqnum, last_check;
     4829        uint64_t timeout;
    46984830
    46994831        if (!wcache_opnum_cacheable(opnum)) {
     
    47154847        }
    47164848
    4717         data.dsize = resp->length + 4;
     4849        timeout = time(NULL) + lp_winbind_cache_time();
     4850
     4851        data.dsize = resp->length + 12;
    47184852        data.dptr = talloc_array(key.dptr, uint8_t, data.dsize);
    47194853        if (data.dptr == NULL) {
     
    47224856
    47234857        SIVAL(data.dptr, 0, dom_seqnum);
    4724         memcpy(data.dptr+4, resp->data, resp->length);
     4858        SBVAL(data.dptr, 4, timeout);
     4859        memcpy(data.dptr + 12, resp->data, resp->length);
    47254860
    47264861        tdb_store(wcache->tdb, key, data, 0);
Note: See TracChangeset for help on using the changeset viewer.