mirror of
https://github.com/samba-team/samba.git
synced 2025-02-09 09:57:48 +03:00
Resurrected sam sequence number code.
Pass domain structure around in cache code rather than the domain name. Some misc reformatting to make things look prettier. (This used to be commit 295dd2a5817b5d7c40474b9e460f3515e8c8e449)
This commit is contained in:
parent
b46f6d865e
commit
1bce5c0b62
@ -41,101 +41,106 @@ void winbindd_cache_init(void)
|
|||||||
|
|
||||||
if (!(cache_tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 0,
|
if (!(cache_tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 0,
|
||||||
TDB_NOLOCK, O_RDWR | O_CREAT | O_TRUNC,
|
TDB_NOLOCK, O_RDWR | O_CREAT | O_TRUNC,
|
||||||
0600))) {
|
0600)))
|
||||||
DEBUG(0, ("Unable to open tdb cache - user and group caching "
|
DEBUG(0, ("Unable to open tdb cache - user and group caching "
|
||||||
"disabled\n"));
|
"disabled\n"));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the sequence number for a domain */
|
/* find the sequence number for a domain */
|
||||||
|
|
||||||
static uint32 domain_sequence_number(char *domain_name)
|
static uint32 domain_sequence_number(struct winbindd_domain *domain)
|
||||||
{
|
{
|
||||||
return DOM_SEQUENCE_NONE;
|
TALLOC_CTX *mem_ctx;
|
||||||
|
CLI_POLICY_HND *hnd;
|
||||||
#if 0
|
|
||||||
struct winbindd_domain *domain;
|
|
||||||
SAM_UNK_CTR ctr;
|
SAM_UNK_CTR ctr;
|
||||||
|
uint16 switch_value = 2;
|
||||||
|
NTSTATUS result;
|
||||||
|
uint32 seqnum = DOM_SEQUENCE_NONE;
|
||||||
|
|
||||||
domain = find_domain_from_name(domain_name);
|
if (!(mem_ctx = talloc_init()))
|
||||||
if (!domain) return DOM_SEQUENCE_NONE;
|
return DOM_SEQUENCE_NONE;
|
||||||
|
|
||||||
if (!wb_samr_query_dom_info(&domain->sam_dom_handle, 2, &ctr)) {
|
if (!(hnd = cm_get_sam_dom_handle(domain->name, &domain->sid)))
|
||||||
|
goto done;
|
||||||
|
|
||||||
/* If this fails, something bad has gone wrong */
|
result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &hnd->pol,
|
||||||
|
switch_value, &ctr);
|
||||||
|
|
||||||
DEBUG(2,("domain sequence query failed\n"));
|
if (NT_STATUS_IS_OK(result))
|
||||||
return DOM_SEQUENCE_NONE;
|
seqnum = ctr.info.inf2.seq_num;
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(4,("got domain sequence number for %s of %u\n",
|
done:
|
||||||
domain_name, (unsigned)ctr.info.inf2.seq_num));
|
talloc_destroy(mem_ctx);
|
||||||
|
|
||||||
return ctr.info.inf2.seq_num;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
return seqnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the domain sequence number, possibly re-fetching */
|
/* get the domain sequence number, possibly re-fetching */
|
||||||
static uint32 cached_sequence_number(char *domain_name)
|
|
||||||
|
static uint32 cached_sequence_number(struct winbindd_domain *domain)
|
||||||
{
|
{
|
||||||
fstring keystr;
|
fstring keystr;
|
||||||
TDB_DATA dbuf;
|
TDB_DATA dbuf;
|
||||||
struct cache_rec rec;
|
struct cache_rec rec;
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
|
|
||||||
snprintf(keystr, sizeof(keystr), "CACHESEQ/%s", domain_name);
|
snprintf(keystr, sizeof(keystr), "CACHESEQ/%s", domain->name);
|
||||||
dbuf = tdb_fetch_by_string(cache_tdb, keystr);
|
dbuf = tdb_fetch_by_string(cache_tdb, keystr);
|
||||||
if (!dbuf.dptr || dbuf.dsize != sizeof(rec)) {
|
|
||||||
|
if (!dbuf.dptr || dbuf.dsize != sizeof(rec))
|
||||||
goto refetch;
|
goto refetch;
|
||||||
}
|
|
||||||
memcpy(&rec, dbuf.dptr, sizeof(rec));
|
memcpy(&rec, dbuf.dptr, sizeof(rec));
|
||||||
SAFE_FREE(dbuf.dptr);
|
SAFE_FREE(dbuf.dptr);
|
||||||
|
|
||||||
if (t < (rec.mod_time + lp_winbind_cache_time())) {
|
if (t < (rec.mod_time + lp_winbind_cache_time())) {
|
||||||
DEBUG(3,("cached sequence number for %s is %u\n",
|
DEBUG(3,("cached sequence number for %s is %u\n",
|
||||||
domain_name, (unsigned)rec.seq_num));
|
domain->name, (unsigned)rec.seq_num));
|
||||||
return rec.seq_num;
|
return rec.seq_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
refetch:
|
refetch:
|
||||||
rec.seq_num = domain_sequence_number(domain_name);
|
rec.seq_num = domain_sequence_number(domain);
|
||||||
rec.mod_time = t;
|
rec.mod_time = t;
|
||||||
|
|
||||||
tdb_store_by_string(cache_tdb, keystr, &rec, sizeof(rec));
|
tdb_store_by_string(cache_tdb, keystr, &rec, sizeof(rec));
|
||||||
|
|
||||||
return rec.seq_num;
|
return rec.seq_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether a seq_num for a cached item has expired */
|
/* Check whether a seq_num for a cached item has expired */
|
||||||
static BOOL cache_domain_expired(char *domain_name, uint32 seq_num)
|
static BOOL cache_domain_expired(struct winbindd_domain *domain,
|
||||||
|
uint32 seq_num)
|
||||||
{
|
{
|
||||||
if (cached_sequence_number(domain_name) != seq_num) {
|
if (cached_sequence_number(domain) != seq_num) {
|
||||||
DEBUG(3,("seq %u for %s has expired\n", (unsigned)seq_num,
|
DEBUG(3,("seq %u for %s has expired\n", (unsigned)seq_num,
|
||||||
domain_name));
|
domain->name));
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_cache_sequence_number(char *domain_name, char *cache_type,
|
static void set_cache_sequence_number(struct winbindd_domain *domain,
|
||||||
char *subkey)
|
char *cache_type, char *subkey)
|
||||||
{
|
{
|
||||||
fstring keystr;
|
fstring keystr;
|
||||||
|
|
||||||
snprintf(keystr, sizeof(keystr),"CACHESEQ %s/%s/%s",
|
snprintf(keystr, sizeof(keystr),"CACHESEQ %s/%s/%s",
|
||||||
domain_name, cache_type, subkey?subkey:"");
|
domain->name, cache_type, subkey?subkey:"");
|
||||||
|
|
||||||
tdb_store_int(cache_tdb, keystr, cached_sequence_number(domain_name));
|
tdb_store_int(cache_tdb, keystr, cached_sequence_number(domain));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 get_cache_sequence_number(char *domain_name, char *cache_type,
|
static uint32 get_cache_sequence_number(struct winbindd_domain *domain,
|
||||||
char *subkey)
|
char *cache_type, char *subkey)
|
||||||
{
|
{
|
||||||
fstring keystr;
|
fstring keystr;
|
||||||
uint32 seq_num;
|
uint32 seq_num;
|
||||||
|
|
||||||
snprintf(keystr, sizeof(keystr), "CACHESEQ %s/%s/%s",
|
snprintf(keystr, sizeof(keystr), "CACHESEQ %s/%s/%s",
|
||||||
domain_name, cache_type, subkey?subkey:"");
|
domain->name, cache_type, subkey ? subkey : "");
|
||||||
|
|
||||||
seq_num = (uint32)tdb_fetch_int(cache_tdb, keystr);
|
seq_num = (uint32)tdb_fetch_int(cache_tdb, keystr);
|
||||||
|
|
||||||
DEBUG(3,("%s is %u\n", keystr, (unsigned)seq_num));
|
DEBUG(3,("%s is %u\n", keystr, (unsigned)seq_num));
|
||||||
@ -145,33 +150,38 @@ static uint32 get_cache_sequence_number(char *domain_name, char *cache_type,
|
|||||||
|
|
||||||
/* Fill the user or group cache with supplied data */
|
/* Fill the user or group cache with supplied data */
|
||||||
|
|
||||||
static void store_cache(char *domain_name, char *cache_type,
|
static void store_cache(struct winbindd_domain *domain, char *cache_type,
|
||||||
void *sam_entries, int buflen)
|
void *sam_entries, int buflen)
|
||||||
{
|
{
|
||||||
fstring keystr;
|
fstring keystr;
|
||||||
|
|
||||||
if (lp_winbind_cache_time() == 0) return;
|
if (lp_winbind_cache_time() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Error check */
|
/* Error check */
|
||||||
if (!sam_entries || buflen == 0) return;
|
|
||||||
|
if (!sam_entries || buflen == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Store data as a mega-huge chunk in the tdb */
|
/* Store data as a mega-huge chunk in the tdb */
|
||||||
|
|
||||||
snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
|
snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
|
||||||
domain_name);
|
domain->name);
|
||||||
|
|
||||||
tdb_store_by_string(cache_tdb, keystr, sam_entries, buflen);
|
tdb_store_by_string(cache_tdb, keystr, sam_entries, buflen);
|
||||||
|
|
||||||
/* Stamp cache with current seq number */
|
/* Stamp cache with current seq number */
|
||||||
set_cache_sequence_number(domain_name, cache_type, NULL);
|
|
||||||
|
set_cache_sequence_number(domain, cache_type, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill the user cache with supplied data */
|
/* Fill the user cache with supplied data */
|
||||||
|
|
||||||
void winbindd_store_user_cache(char *domain,
|
void winbindd_store_user_cache(struct winbindd_domain *domain,
|
||||||
struct getpwent_user *sam_entries,
|
struct getpwent_user *sam_entries,
|
||||||
int num_sam_entries)
|
int num_sam_entries)
|
||||||
{
|
{
|
||||||
DEBUG(3, ("storing user cache %s/%d entries\n", domain,
|
DEBUG(3, ("storing user cache %s/%d entries\n", domain->name,
|
||||||
num_sam_entries));
|
num_sam_entries));
|
||||||
|
|
||||||
store_cache(domain, CACHE_TYPE_USER, sam_entries,
|
store_cache(domain, CACHE_TYPE_USER, sam_entries,
|
||||||
@ -180,35 +190,39 @@ void winbindd_store_user_cache(char *domain,
|
|||||||
|
|
||||||
/* Fill the group cache with supplied data */
|
/* Fill the group cache with supplied data */
|
||||||
|
|
||||||
void winbindd_store_group_cache(char *domain,
|
void winbindd_store_group_cache(struct winbindd_domain *domain,
|
||||||
struct acct_info *sam_entries,
|
struct acct_info *sam_entries,
|
||||||
int num_sam_entries)
|
int num_sam_entries)
|
||||||
{
|
{
|
||||||
DEBUG(0, ("storing group cache %s/%d entries\n", domain,
|
DEBUG(0, ("storing group cache %s/%d entries\n", domain->name,
|
||||||
num_sam_entries));
|
num_sam_entries));
|
||||||
|
|
||||||
store_cache(domain, CACHE_TYPE_GROUP, sam_entries,
|
store_cache(domain, CACHE_TYPE_GROUP, sam_entries,
|
||||||
num_sam_entries * sizeof(struct acct_info));
|
num_sam_entries * sizeof(struct acct_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void store_cache_entry(char *domain, char *cache_type, char *name,
|
static void store_cache_entry(struct winbindd_domain *domain, char *cache_type,
|
||||||
void *buf, int len)
|
char *name, void *buf, int len)
|
||||||
{
|
{
|
||||||
fstring keystr;
|
fstring keystr;
|
||||||
|
|
||||||
/* Create key for store */
|
/* Create key for store */
|
||||||
snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type, domain, name);
|
|
||||||
|
snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type,
|
||||||
|
domain->name, name);
|
||||||
|
|
||||||
/* Store it */
|
/* Store it */
|
||||||
|
|
||||||
tdb_store_by_string(cache_tdb, keystr, buf, len);
|
tdb_store_by_string(cache_tdb, keystr, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill a user info cache entry */
|
/* Fill a user info cache entry */
|
||||||
|
|
||||||
void winbindd_store_user_cache_entry(char *domain, char *user_name,
|
void winbindd_store_user_cache_entry(struct winbindd_domain *domain,
|
||||||
struct winbindd_pw *pw)
|
char *user_name, struct winbindd_pw *pw)
|
||||||
{
|
{
|
||||||
if (lp_winbind_cache_time() == 0) return;
|
if (lp_winbind_cache_time() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
store_cache_entry(domain, CACHE_TYPE_USER, user_name, pw,
|
store_cache_entry(domain, CACHE_TYPE_USER, user_name, pw,
|
||||||
sizeof(struct winbindd_pw));
|
sizeof(struct winbindd_pw));
|
||||||
@ -218,7 +232,7 @@ void winbindd_store_user_cache_entry(char *domain, char *user_name,
|
|||||||
|
|
||||||
/* Fill a user uid cache entry */
|
/* Fill a user uid cache entry */
|
||||||
|
|
||||||
void winbindd_store_uid_cache_entry(char *domain, uid_t uid,
|
void winbindd_store_uid_cache_entry(struct winbindd_domain *domain, uid_t uid,
|
||||||
struct winbindd_pw *pw)
|
struct winbindd_pw *pw)
|
||||||
{
|
{
|
||||||
fstring uidstr;
|
fstring uidstr;
|
||||||
@ -227,7 +241,7 @@ void winbindd_store_uid_cache_entry(char *domain, uid_t uid,
|
|||||||
|
|
||||||
snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned)uid);
|
snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned)uid);
|
||||||
|
|
||||||
DEBUG(3, ("storing uid cache entry %s/%s\n", domain, uidstr));
|
DEBUG(3, ("storing uid cache entry %s/%s\n", domain->name, uidstr));
|
||||||
|
|
||||||
store_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw,
|
store_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw,
|
||||||
sizeof(struct winbindd_pw));
|
sizeof(struct winbindd_pw));
|
||||||
@ -236,15 +250,18 @@ void winbindd_store_uid_cache_entry(char *domain, uid_t uid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fill a group info cache entry */
|
/* Fill a group info cache entry */
|
||||||
void winbindd_store_group_cache_entry(char *domain, char *group_name,
|
|
||||||
struct winbindd_gr *gr, void *extra_data,
|
void winbindd_store_group_cache_entry(struct winbindd_domain *domain,
|
||||||
int extra_data_len)
|
char *group_name, struct winbindd_gr *gr,
|
||||||
|
void *extra_data, int extra_data_len)
|
||||||
{
|
{
|
||||||
fstring keystr;
|
fstring keystr;
|
||||||
|
|
||||||
if (lp_winbind_cache_time() == 0) return;
|
if (lp_winbind_cache_time() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
DEBUG(3, ("storing group cache entry %s/%s\n", domain, group_name));
|
DEBUG(3, ("storing group cache entry %s/%s\n", domain->name,
|
||||||
|
group_name));
|
||||||
|
|
||||||
/* Fill group data */
|
/* Fill group data */
|
||||||
|
|
||||||
@ -254,7 +271,8 @@ void winbindd_store_group_cache_entry(char *domain, char *group_name,
|
|||||||
/* Fill extra data */
|
/* Fill extra data */
|
||||||
|
|
||||||
snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
|
snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
|
||||||
domain, group_name);
|
domain->name, group_name);
|
||||||
|
|
||||||
tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
|
tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
|
||||||
|
|
||||||
set_cache_sequence_number(domain, CACHE_TYPE_GROUP, group_name);
|
set_cache_sequence_number(domain, CACHE_TYPE_GROUP, group_name);
|
||||||
@ -262,7 +280,7 @@ void winbindd_store_group_cache_entry(char *domain, char *group_name,
|
|||||||
|
|
||||||
/* Fill a group info cache entry */
|
/* Fill a group info cache entry */
|
||||||
|
|
||||||
void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
|
void winbindd_store_gid_cache_entry(struct winbindd_domain *domain, gid_t gid,
|
||||||
struct winbindd_gr *gr, void *extra_data,
|
struct winbindd_gr *gr, void *extra_data,
|
||||||
int extra_data_len)
|
int extra_data_len)
|
||||||
{
|
{
|
||||||
@ -271,9 +289,10 @@ void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
|
|||||||
|
|
||||||
snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned)gid);
|
snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned)gid);
|
||||||
|
|
||||||
if (lp_winbind_cache_time() == 0) return;
|
if (lp_winbind_cache_time() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
DEBUG(3, ("storing gid cache entry %s/%s\n", domain, gidstr));
|
DEBUG(3, ("storing gid cache entry %s/%s\n", domain->name, gidstr));
|
||||||
|
|
||||||
/* Fill group data */
|
/* Fill group data */
|
||||||
|
|
||||||
@ -283,7 +302,7 @@ void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
|
|||||||
/* Fill extra data */
|
/* Fill extra data */
|
||||||
|
|
||||||
snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
|
snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
|
||||||
domain, gidstr);
|
domain->name, gidstr);
|
||||||
|
|
||||||
tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
|
tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
|
||||||
|
|
||||||
@ -291,35 +310,38 @@ void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch some cached user or group data */
|
/* Fetch some cached user or group data */
|
||||||
static BOOL fetch_cache(char *domain_name, char *cache_type,
|
|
||||||
|
static BOOL fetch_cache(struct winbindd_domain *domain, char *cache_type,
|
||||||
void **sam_entries, int *buflen)
|
void **sam_entries, int *buflen)
|
||||||
{
|
{
|
||||||
TDB_DATA data;
|
TDB_DATA data;
|
||||||
fstring keystr;
|
fstring keystr;
|
||||||
|
|
||||||
if (lp_winbind_cache_time() == 0) return False;
|
if (lp_winbind_cache_time() == 0)
|
||||||
|
return False;
|
||||||
|
|
||||||
/* Parameter check */
|
/* Parameter check */
|
||||||
if (!sam_entries || !buflen) {
|
|
||||||
|
if (!sam_entries || !buflen)
|
||||||
return False;
|
return False;
|
||||||
}
|
|
||||||
|
|
||||||
/* Check cache data is current */
|
/* Check cache data is current */
|
||||||
if (cache_domain_expired(domain_name,
|
|
||||||
get_cache_sequence_number(domain_name,
|
if (cache_domain_expired(
|
||||||
cache_type,
|
domain, get_cache_sequence_number(domain, cache_type, NULL)))
|
||||||
NULL))) {
|
|
||||||
return False;
|
return False;
|
||||||
}
|
|
||||||
|
|
||||||
/* Create key */
|
/* Create key */
|
||||||
|
|
||||||
snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
|
snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
|
||||||
domain_name);
|
domain->name);
|
||||||
|
|
||||||
/* Fetch cache information */
|
/* Fetch cache information */
|
||||||
|
|
||||||
data = tdb_fetch_by_string(cache_tdb, keystr);
|
data = tdb_fetch_by_string(cache_tdb, keystr);
|
||||||
|
|
||||||
if (!data.dptr) return False;
|
if (!data.dptr)
|
||||||
|
return False;
|
||||||
|
|
||||||
/* Copy across cached data. We can save a memcpy() by directly
|
/* Copy across cached data. We can save a memcpy() by directly
|
||||||
assigning the data.dptr to the sam_entries pointer. It will
|
assigning the data.dptr to the sam_entries pointer. It will
|
||||||
@ -334,20 +356,20 @@ static BOOL fetch_cache(char *domain_name, char *cache_type,
|
|||||||
/* Return cached entries for a domain. Return false if there are no cached
|
/* Return cached entries for a domain. Return false if there are no cached
|
||||||
entries, or the cached information has expired for the domain. */
|
entries, or the cached information has expired for the domain. */
|
||||||
|
|
||||||
BOOL winbindd_fetch_user_cache(char *domain_name,
|
BOOL winbindd_fetch_user_cache(struct winbindd_domain *domain,
|
||||||
struct getpwent_user **sam_entries,
|
struct getpwent_user **sam_entries,
|
||||||
int *num_entries)
|
int *num_entries)
|
||||||
{
|
{
|
||||||
BOOL result;
|
BOOL result;
|
||||||
int buflen;
|
int buflen;
|
||||||
|
|
||||||
result = fetch_cache(domain_name, CACHE_TYPE_USER,
|
result = fetch_cache(domain, CACHE_TYPE_USER,
|
||||||
(void **)sam_entries, &buflen);
|
(void **)sam_entries, &buflen);
|
||||||
|
|
||||||
*num_entries = buflen / sizeof(struct getpwent_user);
|
*num_entries = buflen / sizeof(struct getpwent_user);
|
||||||
|
|
||||||
DEBUG(3, ("fetched %d cache entries for %s\n", *num_entries,
|
DEBUG(3, ("fetched %d cache entries for %s\n", *num_entries,
|
||||||
domain_name));
|
domain->name));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -355,112 +377,136 @@ BOOL winbindd_fetch_user_cache(char *domain_name,
|
|||||||
/* Return cached entries for a domain. Return false if there are no cached
|
/* Return cached entries for a domain. Return false if there are no cached
|
||||||
entries, or the cached information has expired for the domain. */
|
entries, or the cached information has expired for the domain. */
|
||||||
|
|
||||||
BOOL winbindd_fetch_group_cache(char *domain_name,
|
BOOL winbindd_fetch_group_cache(struct winbindd_domain *domain,
|
||||||
struct acct_info **sam_entries,
|
struct acct_info **sam_entries,
|
||||||
int *num_entries)
|
int *num_entries)
|
||||||
{
|
{
|
||||||
BOOL result;
|
BOOL result;
|
||||||
int buflen;
|
int buflen;
|
||||||
|
|
||||||
result = fetch_cache(domain_name, CACHE_TYPE_GROUP,
|
result = fetch_cache(domain, CACHE_TYPE_GROUP,
|
||||||
(void **)sam_entries, &buflen);
|
(void **)sam_entries, &buflen);
|
||||||
|
|
||||||
*num_entries = buflen / sizeof(struct acct_info);
|
*num_entries = buflen / sizeof(struct acct_info);
|
||||||
|
|
||||||
DEBUG(3, ("fetched %d cache entries for %s\n", *num_entries,
|
DEBUG(3, ("fetched %d cache entries for %s\n", *num_entries,
|
||||||
domain_name));
|
domain->name));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL fetch_cache_entry(char *domain, char *cache_type, char *name,
|
static BOOL fetch_cache_entry(struct winbindd_domain *domain,
|
||||||
void *buf, int len)
|
char *cache_type, char *name, void *buf, int len)
|
||||||
{
|
{
|
||||||
TDB_DATA data;
|
TDB_DATA data;
|
||||||
fstring keystr;
|
fstring keystr;
|
||||||
|
|
||||||
/* Create key for lookup */
|
/* Create key for lookup */
|
||||||
snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type, domain, name);
|
|
||||||
|
snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type,
|
||||||
|
domain->name, name);
|
||||||
|
|
||||||
/* Look up cache entry */
|
/* Look up cache entry */
|
||||||
|
|
||||||
data = tdb_fetch_by_string(cache_tdb, keystr);
|
data = tdb_fetch_by_string(cache_tdb, keystr);
|
||||||
if (!data.dptr) return False;
|
|
||||||
|
if (!data.dptr)
|
||||||
|
return False;
|
||||||
|
|
||||||
/* Copy found entry into buffer */
|
/* Copy found entry into buffer */
|
||||||
|
|
||||||
memcpy((char *)buf, data.dptr, len < data.dsize ? len : data.dsize);
|
memcpy((char *)buf, data.dptr, len < data.dsize ? len : data.dsize);
|
||||||
SAFE_FREE(data.dptr);
|
SAFE_FREE(data.dptr);
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch an individual user cache entry */
|
/* Fetch an individual user cache entry */
|
||||||
BOOL winbindd_fetch_user_cache_entry(char *domain_name, char *user,
|
|
||||||
struct winbindd_pw *pw)
|
BOOL winbindd_fetch_user_cache_entry(struct winbindd_domain *domain,
|
||||||
|
char *user, struct winbindd_pw *pw)
|
||||||
{
|
{
|
||||||
uint32 seq_num;
|
uint32 seq_num;
|
||||||
|
|
||||||
if (lp_winbind_cache_time() == 0) return False;
|
if (lp_winbind_cache_time() == 0)
|
||||||
|
return False;
|
||||||
|
|
||||||
seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER,
|
seq_num = get_cache_sequence_number(domain, CACHE_TYPE_USER,
|
||||||
user);
|
user);
|
||||||
if (cache_domain_expired(domain_name, seq_num)) return False;
|
|
||||||
|
|
||||||
return fetch_cache_entry(domain_name, CACHE_TYPE_USER, user, pw,
|
if (cache_domain_expired(domain, seq_num))
|
||||||
|
return False;
|
||||||
|
|
||||||
|
return fetch_cache_entry(domain, CACHE_TYPE_USER, user, pw,
|
||||||
sizeof(struct winbindd_pw));
|
sizeof(struct winbindd_pw));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch an individual uid cache entry */
|
/* Fetch an individual uid cache entry */
|
||||||
BOOL winbindd_fetch_uid_cache_entry(char *domain_name, uid_t uid,
|
|
||||||
|
BOOL winbindd_fetch_uid_cache_entry(struct winbindd_domain *domain, uid_t uid,
|
||||||
struct winbindd_pw *pw)
|
struct winbindd_pw *pw)
|
||||||
{
|
{
|
||||||
fstring uidstr;
|
fstring uidstr;
|
||||||
uint32 seq_num;
|
uint32 seq_num;
|
||||||
|
|
||||||
if (lp_winbind_cache_time() == 0) return False;
|
if (lp_winbind_cache_time() == 0)
|
||||||
|
return False;
|
||||||
|
|
||||||
snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned)uid);
|
snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned)uid);
|
||||||
seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER,
|
|
||||||
uidstr);
|
|
||||||
if (cache_domain_expired(domain_name, seq_num)) return False;
|
|
||||||
|
|
||||||
return fetch_cache_entry(domain_name, CACHE_TYPE_USER, uidstr, pw,
|
seq_num = get_cache_sequence_number(domain, CACHE_TYPE_USER,
|
||||||
|
uidstr);
|
||||||
|
|
||||||
|
if (cache_domain_expired(domain, seq_num))
|
||||||
|
return False;
|
||||||
|
|
||||||
|
return fetch_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw,
|
||||||
sizeof(struct winbindd_pw));
|
sizeof(struct winbindd_pw));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch an individual group cache entry. This function differs from the
|
/* Fetch an individual group cache entry. This function differs from the
|
||||||
user cache code as we need to store the group membership data. */
|
user cache code as we need to store the group membership data. */
|
||||||
|
|
||||||
BOOL winbindd_fetch_group_cache_entry(char *domain_name, char *group,
|
BOOL winbindd_fetch_group_cache_entry(struct winbindd_domain *domain,
|
||||||
struct winbindd_gr *gr,
|
char *group, struct winbindd_gr *gr,
|
||||||
void **extra_data, int *extra_data_len)
|
void **extra_data, int *extra_data_len)
|
||||||
{
|
{
|
||||||
TDB_DATA data;
|
TDB_DATA data;
|
||||||
fstring keystr;
|
fstring keystr;
|
||||||
uint32 seq_num;
|
uint32 seq_num;
|
||||||
|
|
||||||
if (lp_winbind_cache_time() == 0) return False;
|
if (lp_winbind_cache_time() == 0)
|
||||||
|
return False;
|
||||||
|
|
||||||
seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP,
|
seq_num = get_cache_sequence_number(domain, CACHE_TYPE_GROUP,
|
||||||
group);
|
group);
|
||||||
|
|
||||||
if (cache_domain_expired(domain_name, seq_num)) return False;
|
if (cache_domain_expired(domain, seq_num))
|
||||||
|
return False;
|
||||||
|
|
||||||
/* Fetch group data */
|
/* Fetch group data */
|
||||||
if (!fetch_cache_entry(domain_name, CACHE_TYPE_GROUP, group, gr,
|
|
||||||
sizeof(struct winbindd_gr))) {
|
if (!fetch_cache_entry(domain, CACHE_TYPE_GROUP, group, gr,
|
||||||
|
sizeof(struct winbindd_gr)))
|
||||||
return False;
|
return False;
|
||||||
}
|
|
||||||
|
|
||||||
/* Fetch extra data */
|
/* Fetch extra data */
|
||||||
|
|
||||||
snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
|
snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
|
||||||
domain_name, group);
|
domain->name, group);
|
||||||
|
|
||||||
data = tdb_fetch_by_string(cache_tdb, keystr);
|
data = tdb_fetch_by_string(cache_tdb, keystr);
|
||||||
|
|
||||||
if (!data.dptr) return False;
|
if (!data.dptr)
|
||||||
|
return False;
|
||||||
|
|
||||||
/* Extra data freed when data has been sent */
|
/* Extra data freed when data has been sent */
|
||||||
if (extra_data) *extra_data = data.dptr;
|
|
||||||
if (extra_data_len) *extra_data_len = data.dsize;
|
if (extra_data)
|
||||||
|
*extra_data = data.dptr;
|
||||||
|
|
||||||
|
if (extra_data_len)
|
||||||
|
*extra_data_len = data.dsize;
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
@ -469,7 +515,7 @@ BOOL winbindd_fetch_group_cache_entry(char *domain_name, char *group,
|
|||||||
/* Fetch an individual gid cache entry. This function differs from the
|
/* Fetch an individual gid cache entry. This function differs from the
|
||||||
user cache code as we need to store the group membership data. */
|
user cache code as we need to store the group membership data. */
|
||||||
|
|
||||||
BOOL winbindd_fetch_gid_cache_entry(char *domain_name, gid_t gid,
|
BOOL winbindd_fetch_gid_cache_entry(struct winbindd_domain *domain, gid_t gid,
|
||||||
struct winbindd_gr *gr,
|
struct winbindd_gr *gr,
|
||||||
void **extra_data, int *extra_data_len)
|
void **extra_data, int *extra_data_len)
|
||||||
{
|
{
|
||||||
@ -480,33 +526,44 @@ BOOL winbindd_fetch_gid_cache_entry(char *domain_name, gid_t gid,
|
|||||||
|
|
||||||
snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned)gid);
|
snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned)gid);
|
||||||
|
|
||||||
if (lp_winbind_cache_time() == 0) return False;
|
if (lp_winbind_cache_time() == 0)
|
||||||
|
return False;
|
||||||
|
|
||||||
seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP,
|
seq_num = get_cache_sequence_number(domain, CACHE_TYPE_GROUP,
|
||||||
gidstr);
|
gidstr);
|
||||||
|
|
||||||
if (cache_domain_expired(domain_name, seq_num)) return False;
|
if (cache_domain_expired(domain, seq_num))
|
||||||
|
return False;
|
||||||
|
|
||||||
/* Fetch group data */
|
/* Fetch group data */
|
||||||
if (!fetch_cache_entry(domain_name, CACHE_TYPE_GROUP,
|
|
||||||
gidstr, gr, sizeof(struct winbindd_gr))) {
|
if (!fetch_cache_entry(domain, CACHE_TYPE_GROUP,
|
||||||
|
gidstr, gr, sizeof(struct winbindd_gr)))
|
||||||
return False;
|
return False;
|
||||||
}
|
|
||||||
|
|
||||||
/* Fetch extra data */
|
/* Fetch extra data */
|
||||||
|
|
||||||
snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
|
snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
|
||||||
domain_name, gidstr);
|
domain->name, gidstr);
|
||||||
|
|
||||||
data = tdb_fetch_by_string(cache_tdb, keystr);
|
data = tdb_fetch_by_string(cache_tdb, keystr);
|
||||||
if (!data.dptr) return False;
|
|
||||||
|
if (!data.dptr)
|
||||||
|
return False;
|
||||||
|
|
||||||
/* Extra data freed when data has been sent */
|
/* Extra data freed when data has been sent */
|
||||||
if (extra_data) *extra_data = data.dptr;
|
|
||||||
if (extra_data_len) *extra_data_len = data.dsize;
|
if (extra_data)
|
||||||
|
*extra_data = data.dptr;
|
||||||
|
|
||||||
|
if (extra_data_len)
|
||||||
|
*extra_data_len = data.dsize;
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush cache data - easiest to just reopen the tdb */
|
/* Flush cache data - easiest to just reopen the tdb */
|
||||||
|
|
||||||
void winbindd_flush_cache(void)
|
void winbindd_flush_cache(void)
|
||||||
{
|
{
|
||||||
tdb_close(cache_tdb);
|
tdb_close(cache_tdb);
|
||||||
@ -514,6 +571,7 @@ void winbindd_flush_cache(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Print cache status information */
|
/* Print cache status information */
|
||||||
|
|
||||||
void winbindd_cache_dump_status(void)
|
void winbindd_cache_dump_status(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user