Changeset 733 for branches/samba-3.5.x/source3/winbindd/winbindd_cache.c
- Timestamp:
- Nov 12, 2012, 5:09:31 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.5.x/source3/winbindd/winbindd_cache.c
r599 r733 33 33 #define DBGC_CLASS DBGC_WINBIND 34 34 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 36 39 #define WINBINDD_CACHE_VERSION_KEYSTR "WINBINDD_CACHE_VERSION" 37 40 … … 93 96 NTSTATUS status; 94 97 uint32 sequence_number; 98 uint64 timeout; 95 99 uint8 *data; 96 100 uint32 len, ofs; … … 224 228 225 229 /* 230 pull a uint64 from a cache entry 231 */ 232 static 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 /* 226 245 pull a uint32 from a cache entry 227 246 */ … … 615 634 616 635 /* 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))) { 620 640 DEBUG(10,("centry_expired: Key %s for domain %s is good.\n", 621 641 keystr, domain->name )); … … 648 668 centry->ofs = 0; 649 669 650 if (centry->len < 8) {670 if (centry->len < 16) { 651 671 /* 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)); 653 674 centry_free(centry); 654 675 return NULL; … … 657 678 centry->status = centry_ntstatus(centry); 658 679 centry->sequence_number = centry_uint32(centry); 680 centry->timeout = centry_uint64(centry); 659 681 660 682 return centry; … … 743 765 744 766 /* 767 push a uint64 into a centry 768 */ 769 static 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 /* 745 777 push a uint32 into a centry 746 778 */ … … 863 895 centry->ofs = 0; 864 896 centry->sequence_number = domain->sequence_number; 897 centry->timeout = lp_winbind_cache_time() + time(NULL); 865 898 centry_put_ntstatus(centry, status); 866 899 centry_put_uint32(centry, centry->sequence_number); 900 centry_put_uint64(centry, centry->timeout); 867 901 return centry; 868 902 } … … 3449 3483 centry->ofs = 0; 3450 3484 3451 if (centry->len < 8) {3485 if (centry->len < 16) { 3452 3486 /* 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)); 3454 3489 centry_free(centry); 3455 3490 state->bad_entry = true; … … 3460 3495 centry->status = NT_STATUS(centry_uint32(centry)); 3461 3496 centry->sequence_number = centry_uint32(centry); 3497 centry->timeout = centry_uint64(centry); 3462 3498 return centry; 3463 3499 } … … 4012 4048 } 4013 4049 4050 static 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 4100 static 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 4014 4114 /*********************************************************************** 4015 4115 Try and validate every entry in the winbindd cache. If we fail here, … … 4022 4122 const char *tdb_path = cache_path("winbindd_cache.tdb"); 4023 4123 TDB_CONTEXT *tdb = NULL; 4124 uint32_t vers_id; 4125 bool ok; 4024 4126 4025 4127 DEBUG(10, ("winbindd_validate_cache: replacing panic function\n")); 4026 4128 smb_panic_fn = validate_panic; 4027 4028 4129 4029 4130 tdb = tdb_open_log(tdb_path, … … 4039 4140 goto done; 4040 4141 } 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 4041 4166 tdb_close(tdb); 4042 4167 … … 4658 4783 return false; 4659 4784 } 4660 if (data.dsize < 4) {4785 if (data.dsize < 12) { 4661 4786 goto fail; 4662 4787 } … … 4664 4789 if (!is_domain_offline(domain)) { 4665 4790 uint32_t entry_seqnum, dom_seqnum, last_check; 4791 uint64_t entry_timeout; 4666 4792 4667 4793 if (!wcache_fetch_seqnum(domain->name, &dom_seqnum, … … 4675 4801 goto fail; 4676 4802 } 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); 4681 4812 if (resp->data == NULL) { 4682 4813 DEBUG(10, ("talloc failed\n")); 4683 4814 goto fail; 4684 4815 } 4685 resp->length = data.dsize - 4;4816 resp->length = data.dsize - 12; 4686 4817 4687 4818 ret = true; … … 4696 4827 TDB_DATA key, data; 4697 4828 uint32_t dom_seqnum, last_check; 4829 uint64_t timeout; 4698 4830 4699 4831 if (!wcache_opnum_cacheable(opnum)) { … … 4715 4847 } 4716 4848 4717 data.dsize = resp->length + 4; 4849 timeout = time(NULL) + lp_winbind_cache_time(); 4850 4851 data.dsize = resp->length + 12; 4718 4852 data.dptr = talloc_array(key.dptr, uint8_t, data.dsize); 4719 4853 if (data.dptr == NULL) { … … 4722 4856 4723 4857 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); 4725 4860 4726 4861 tdb_store(wcache->tdb, key, data, 0);
Note:
See TracChangeset
for help on using the changeset viewer.