summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/nsswitch/winbindd_cache.c292
1 files changed, 175 insertions, 117 deletions
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index 9c0ad5015c..1dc9f06050 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -41,101 +41,106 @@ void winbindd_cache_init(void)
if (!(cache_tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 0,
TDB_NOLOCK, O_RDWR | O_CREAT | O_TRUNC,
- 0600))) {
+ 0600)))
DEBUG(0, ("Unable to open tdb cache - user and group caching "
"disabled\n"));
- }
}
/* 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;
-
-#if 0
- struct winbindd_domain *domain;
+ TALLOC_CTX *mem_ctx;
+ CLI_POLICY_HND *hnd;
SAM_UNK_CTR ctr;
+ uint16 switch_value = 2;
+ NTSTATUS result;
+ uint32 seqnum = DOM_SEQUENCE_NONE;
- domain = find_domain_from_name(domain_name);
- if (!domain) return DOM_SEQUENCE_NONE;
+ if (!(mem_ctx = talloc_init()))
+ 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"));
- return DOM_SEQUENCE_NONE;
- }
+ if (NT_STATUS_IS_OK(result))
+ seqnum = ctr.info.inf2.seq_num;
- DEBUG(4,("got domain sequence number for %s of %u\n",
- domain_name, (unsigned)ctr.info.inf2.seq_num));
-
- return ctr.info.inf2.seq_num;
-#endif
+ done:
+ talloc_destroy(mem_ctx);
+ return seqnum;
}
/* 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;
TDB_DATA dbuf;
struct cache_rec rec;
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);
- if (!dbuf.dptr || dbuf.dsize != sizeof(rec)) {
+
+ if (!dbuf.dptr || dbuf.dsize != sizeof(rec))
goto refetch;
- }
+
memcpy(&rec, dbuf.dptr, sizeof(rec));
SAFE_FREE(dbuf.dptr);
if (t < (rec.mod_time + lp_winbind_cache_time())) {
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;
}
refetch:
- rec.seq_num = domain_sequence_number(domain_name);
+ rec.seq_num = domain_sequence_number(domain);
rec.mod_time = t;
+
tdb_store_by_string(cache_tdb, keystr, &rec, sizeof(rec));
return rec.seq_num;
}
/* 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,
- domain_name));
+ domain->name));
return True;
}
+
return False;
}
-static void set_cache_sequence_number(char *domain_name, char *cache_type,
- char *subkey)
+static void set_cache_sequence_number(struct winbindd_domain *domain,
+ char *cache_type, char *subkey)
{
fstring keystr;
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,
- char *subkey)
+static uint32 get_cache_sequence_number(struct winbindd_domain *domain,
+ char *cache_type, char *subkey)
{
fstring keystr;
uint32 seq_num;
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);
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 */
-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)
{
fstring keystr;
- if (lp_winbind_cache_time() == 0) return;
+ if (lp_winbind_cache_time() == 0)
+ return;
/* Error check */
- if (!sam_entries || buflen == 0) return;
+
+ if (!sam_entries || buflen == 0)
+ return;
/* Store data as a mega-huge chunk in the tdb */
+
snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
- domain_name);
+ domain->name);
tdb_store_by_string(cache_tdb, keystr, sam_entries, buflen);
/* 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 */
-void winbindd_store_user_cache(char *domain,
+void winbindd_store_user_cache(struct winbindd_domain *domain,
struct getpwent_user *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));
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 */
-void winbindd_store_group_cache(char *domain,
+void winbindd_store_group_cache(struct winbindd_domain *domain,
struct acct_info *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));
store_cache(domain, CACHE_TYPE_GROUP, sam_entries,
num_sam_entries * sizeof(struct acct_info));
}
-static void store_cache_entry(char *domain, char *cache_type, char *name,
- void *buf, int len)
+static void store_cache_entry(struct winbindd_domain *domain, char *cache_type,
+ char *name, void *buf, int len)
{
fstring keystr;
/* 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 */
+
tdb_store_by_string(cache_tdb, keystr, buf, len);
}
/* Fill a user info cache entry */
-void winbindd_store_user_cache_entry(char *domain, char *user_name,
- struct winbindd_pw *pw)
+void winbindd_store_user_cache_entry(struct winbindd_domain *domain,
+ 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,
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 */
-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)
{
fstring uidstr;
@@ -227,7 +241,7 @@ void winbindd_store_uid_cache_entry(char *domain, uid_t 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,
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 */
-void winbindd_store_group_cache_entry(char *domain, char *group_name,
- struct winbindd_gr *gr, void *extra_data,
- int extra_data_len)
+
+void winbindd_store_group_cache_entry(struct winbindd_domain *domain,
+ char *group_name, struct winbindd_gr *gr,
+ void *extra_data, int extra_data_len)
{
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 */
@@ -254,7 +271,8 @@ void winbindd_store_group_cache_entry(char *domain, char *group_name,
/* Fill extra data */
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);
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 */
-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,
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);
- 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 */
@@ -283,7 +302,7 @@ void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
/* Fill extra data */
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);
@@ -291,35 +310,38 @@ void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
}
/* 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)
{
TDB_DATA data;
fstring keystr;
- if (lp_winbind_cache_time() == 0) return False;
+ if (lp_winbind_cache_time() == 0)
+ return False;
/* Parameter check */
- if (!sam_entries || !buflen) {
+
+ if (!sam_entries || !buflen)
return False;
- }
/* Check cache data is current */
- if (cache_domain_expired(domain_name,
- get_cache_sequence_number(domain_name,
- cache_type,
- NULL))) {
+
+ if (cache_domain_expired(
+ domain, get_cache_sequence_number(domain, cache_type, NULL)))
return False;
- }
/* Create key */
+
snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
- domain_name);
+ domain->name);
/* Fetch cache information */
+
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
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
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,
int *num_entries)
{
BOOL result;
int buflen;
- result = fetch_cache(domain_name, CACHE_TYPE_USER,
+ result = fetch_cache(domain, CACHE_TYPE_USER,
(void **)sam_entries, &buflen);
*num_entries = buflen / sizeof(struct getpwent_user);
DEBUG(3, ("fetched %d cache entries for %s\n", *num_entries,
- domain_name));
+ domain->name));
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
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,
int *num_entries)
{
BOOL result;
int buflen;
- result = fetch_cache(domain_name, CACHE_TYPE_GROUP,
+ result = fetch_cache(domain, CACHE_TYPE_GROUP,
(void **)sam_entries, &buflen);
*num_entries = buflen / sizeof(struct acct_info);
DEBUG(3, ("fetched %d cache entries for %s\n", *num_entries,
- domain_name));
+ domain->name));
return result;
}
-static BOOL fetch_cache_entry(char *domain, char *cache_type, char *name,
- void *buf, int len)
+static BOOL fetch_cache_entry(struct winbindd_domain *domain,
+ char *cache_type, char *name, void *buf, int len)
{
TDB_DATA data;
fstring keystr;
/* 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 */
+
data = tdb_fetch_by_string(cache_tdb, keystr);
- if (!data.dptr) return False;
+
+ if (!data.dptr)
+ return False;
/* Copy found entry into buffer */
+
memcpy((char *)buf, data.dptr, len < data.dsize ? len : data.dsize);
SAFE_FREE(data.dptr);
+
return True;
}
/* 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;
- 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);
- 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));
}
/* 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)
{
fstring uidstr;
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);
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER,
+
+ seq_num = get_cache_sequence_number(domain, 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,
+ if (cache_domain_expired(domain, seq_num))
+ return False;
+
+ return fetch_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw,
sizeof(struct winbindd_pw));
}
/* Fetch an individual group cache entry. This function differs from the
user cache code as we need to store the group membership data. */
-BOOL winbindd_fetch_group_cache_entry(char *domain_name, char *group,
- struct winbindd_gr *gr,
+BOOL winbindd_fetch_group_cache_entry(struct winbindd_domain *domain,
+ char *group, struct winbindd_gr *gr,
void **extra_data, int *extra_data_len)
{
TDB_DATA data;
fstring keystr;
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);
- if (cache_domain_expired(domain_name, seq_num)) return False;
+ if (cache_domain_expired(domain, seq_num))
+ return False;
/* 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;
- }
/* Fetch extra data */
+
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);
- if (!data.dptr) return False;
+ if (!data.dptr)
+ return False;
/* 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;
}
@@ -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
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,
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);
- 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);
- if (cache_domain_expired(domain_name, seq_num)) return False;
+ if (cache_domain_expired(domain, seq_num))
+ return False;
/* 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;
- }
/* Fetch extra data */
+
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);
- if (!data.dptr) return False;
+
+ if (!data.dptr)
+ return False;
/* 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;
}
/* Flush cache data - easiest to just reopen the tdb */
+
void winbindd_flush_cache(void)
{
tdb_close(cache_tdb);
@@ -514,6 +571,7 @@ void winbindd_flush_cache(void)
}
/* Print cache status information */
+
void winbindd_cache_dump_status(void)
{
}