summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch/winbindd_cache.c')
-rw-r--r--source3/nsswitch/winbindd_cache.c249
1 files changed, 156 insertions, 93 deletions
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index 7b263dfe00..2e404a7eb0 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -38,10 +38,10 @@ struct cache_rec {
void winbindd_cache_init(void)
{
/* Open tdb cache */
- unlink(lock_path("winbindd_cache.tdb"));
+
if (!(cache_tdb = tdb_open(lock_path("winbindd_cache.tdb"), 0,
- TDB_NOLOCK,
- O_RDWR | O_CREAT, 0600))) {
+ TDB_NOLOCK, O_RDWR | O_CREAT | O_TRUNC,
+ 0600))) {
DEBUG(0, ("Unable to open tdb cache - user and group caching "
"disabled\n"));
}
@@ -55,8 +55,7 @@ static uint32 cached_sequence_number(char *domain_name)
struct cache_rec rec;
time_t t = time(NULL);
- slprintf(keystr, sizeof(keystr)-1, "CACHESEQ/%s", domain_name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+ snprintf(keystr, sizeof(keystr), "CACHESEQ/%s", domain_name);
dbuf = tdb_fetch_by_string(cache_tdb, keystr);
if (!dbuf.dptr || dbuf.dsize != sizeof(rec)) {
goto refetch;
@@ -65,7 +64,7 @@ static uint32 cached_sequence_number(char *domain_name)
free(dbuf.dptr);
if (t < (rec.mod_time + lp_winbind_cache_time())) {
- DEBUG(4,("cached sequence number for %s is %u\n",
+ DEBUG(3,("cached sequence number for %s is %u\n",
domain_name, (unsigned)rec.seq_num));
return rec.seq_num;
}
@@ -82,54 +81,56 @@ static uint32 cached_sequence_number(char *domain_name)
static BOOL cache_domain_expired(char *domain_name, uint32 seq_num)
{
if (cached_sequence_number(domain_name) != seq_num) {
- DEBUG(4,("seq %u for %s has expired\n", (unsigned)seq_num, domain_name));
+ DEBUG(3,("seq %u for %s has expired\n", (unsigned)seq_num,
+ 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(char *domain_name, char *cache_type,
+ char *subkey)
{
fstring keystr;
- slprintf(keystr,sizeof(keystr)-1,"CACHESEQ %s/%s/%s",
+
+ snprintf(keystr, sizeof(keystr),"CACHESEQ %s/%s/%s",
domain_name, cache_type, subkey?subkey:"");
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+
tdb_store_int(cache_tdb, keystr, cached_sequence_number(domain_name));
}
-static uint32 get_cache_sequence_number(char *domain_name, char *cache_type, char *subkey)
+static uint32 get_cache_sequence_number(char *domain_name, char *cache_type,
+ char *subkey)
{
fstring keystr;
uint32 seq_num;
- slprintf(keystr,sizeof(keystr)-1,"CACHESEQ %s/%s/%s",
+
+ snprintf(keystr, sizeof(keystr), "CACHESEQ %s/%s/%s",
domain_name, cache_type, subkey?subkey:"");
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
seq_num = (uint32)tdb_fetch_int(cache_tdb, keystr);
- DEBUG(4,("%s is %u\n", keystr, (unsigned)seq_num));
+
+ DEBUG(3,("%s is %u\n", keystr, (unsigned)seq_num));
+
return seq_num;
}
/* Fill the user or group cache with supplied data */
-static void fill_cache(char *domain_name, char *cache_type,
- struct acct_info *sam_entries,
- int num_sam_entries)
+
+static void store_cache(char *domain_name, char *cache_type,
+ void *sam_entries, int buflen)
{
fstring keystr;
if (lp_winbind_cache_time() == 0) return;
/* Error check */
- if (!sam_entries || (num_sam_entries == 0)) return;
-
- DEBUG(4, ("filling %s cache for domain %s with %d entries\n",
- cache_type, domain_name, num_sam_entries));
+ if (!sam_entries || buflen == 0) return;
/* Store data as a mega-huge chunk in the tdb */
- slprintf(keystr, sizeof(keystr)-1, "%s CACHE DATA/%s", cache_type,
+ snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
domain_name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
- tdb_store_by_string(cache_tdb, keystr,
- sam_entries, sizeof(struct acct_info) * num_sam_entries);
+
+ 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);
@@ -137,97 +138,124 @@ static void fill_cache(char *domain_name, char *cache_type,
/* Fill the user cache with supplied data */
-void winbindd_fill_user_cache(char *domain_name,
- struct acct_info *sam_entries,
- int num_sam_entries)
+void winbindd_store_user_cache(char *domain,
+ struct getpwent_user *sam_entries,
+ int num_sam_entries)
{
- fill_cache(domain_name, CACHE_TYPE_USER, sam_entries, num_sam_entries);
+ DEBUG(3, ("storing user cache %s/%d entries\n", domain,
+ num_sam_entries));
+
+ store_cache(domain, CACHE_TYPE_USER, sam_entries,
+ num_sam_entries * sizeof(struct getpwent_user));
}
/* Fill the group cache with supplied data */
-void winbindd_fill_group_cache(char *domain_name,
- struct acct_info *sam_entries,
- int num_sam_entries)
+void winbindd_store_group_cache(char *domain,
+ struct acct_info *sam_entries,
+ int num_sam_entries)
{
- fill_cache(domain_name, CACHE_TYPE_GROUP, sam_entries, num_sam_entries);
+ DEBUG(0, ("storing group cache %s/%d entries\n", domain,
+ num_sam_entries));
+
+ store_cache(domain, CACHE_TYPE_GROUP, sam_entries,
+ num_sam_entries * sizeof(struct acct_info));
}
-static void fill_cache_entry(char *domain, char *cache_type, char *name, void *buf, int len)
+static void store_cache_entry(char *domain, char *cache_type, char *name,
+ void *buf, int len)
{
fstring keystr;
/* Create key for store */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s", cache_type, domain, name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
-
- DEBUG(4, ("filling cache entry %s\n", keystr));
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type, domain, name);
/* Store it */
tdb_store_by_string(cache_tdb, keystr, buf, len);
}
/* Fill a user info cache entry */
-void winbindd_fill_user_cache_entry(char *domain, char *user_name,
- struct winbindd_pw *pw)
+
+void winbindd_store_user_cache_entry(char *domain, char *user_name,
+ struct winbindd_pw *pw)
{
if (lp_winbind_cache_time() == 0) return;
- fill_cache_entry(domain, CACHE_TYPE_USER, user_name, pw, sizeof(struct winbindd_pw));
+ store_cache_entry(domain, CACHE_TYPE_USER, user_name, pw,
+ sizeof(struct winbindd_pw));
+
set_cache_sequence_number(domain, CACHE_TYPE_USER, user_name);
}
/* Fill a user uid cache entry */
-void winbindd_fill_uid_cache_entry(char *domain, uid_t uid,
+
+void winbindd_store_uid_cache_entry(char *domain, uid_t uid,
struct winbindd_pw *pw)
{
fstring uidstr;
if (lp_winbind_cache_time() == 0) return;
- slprintf(uidstr, sizeof(uidstr)-1, "#%u", (unsigned)uid);
- fill_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw, sizeof(struct winbindd_pw));
+ snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned)uid);
+
+ DEBUG(3, ("storing uid cache entry %s/%s\n", domain, uidstr));
+
+ store_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw,
+ sizeof(struct winbindd_pw));
+
set_cache_sequence_number(domain, CACHE_TYPE_USER, uidstr);
}
/* Fill a group info cache entry */
-void winbindd_fill_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(char *domain, char *group_name,
+ struct winbindd_gr *gr, void *extra_data,
+ int extra_data_len)
{
fstring keystr;
if (lp_winbind_cache_time() == 0) return;
+ DEBUG(3, ("storing group cache entry %s/%s\n", domain, group_name));
+
/* Fill group data */
- fill_cache_entry(domain, CACHE_TYPE_GROUP, group_name, gr, sizeof(struct winbindd_gr));
+
+ store_cache_entry(domain, CACHE_TYPE_GROUP, group_name, gr,
+ sizeof(struct winbindd_gr));
/* Fill extra data */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s DATA", CACHE_TYPE_GROUP, domain, group_name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain, group_name);
tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
set_cache_sequence_number(domain, CACHE_TYPE_GROUP, group_name);
}
/* Fill a group info cache entry */
-void winbindd_fill_gid_cache_entry(char *domain, gid_t gid,
- struct winbindd_gr *gr, void *extra_data,
- int extra_data_len)
+
+void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
+ struct winbindd_gr *gr, void *extra_data,
+ int extra_data_len)
{
fstring keystr;
fstring gidstr;
- slprintf(gidstr, sizeof(gidstr)-1, "#%u", (unsigned)gid);
+ snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned)gid);
if (lp_winbind_cache_time() == 0) return;
+ DEBUG(3, ("storing gid cache entry %s/%s\n", domain, gidstr));
+
/* Fill group data */
- fill_cache_entry(domain, CACHE_TYPE_GROUP, gidstr, gr, sizeof(struct winbindd_gr));
+
+ store_cache_entry(domain, CACHE_TYPE_GROUP, gidstr, gr,
+ sizeof(struct winbindd_gr));
/* Fill extra data */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s DATA", CACHE_TYPE_GROUP, domain, gidstr);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain, gidstr);
+
tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
set_cache_sequence_number(domain, CACHE_TYPE_GROUP, gidstr);
@@ -235,7 +263,7 @@ void winbindd_fill_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,
- struct acct_info **sam_entries, int *num_sam_entries)
+ void **sam_entries, int *buflen)
{
TDB_DATA data;
fstring keystr;
@@ -243,20 +271,21 @@ static BOOL fetch_cache(char *domain_name, char *cache_type,
if (lp_winbind_cache_time() == 0) return False;
/* Parameter check */
- if (!sam_entries || !num_sam_entries) {
+ 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))) {
+ get_cache_sequence_number(domain_name,
+ cache_type,
+ NULL))) {
return False;
}
/* Create key */
- slprintf(keystr, sizeof(keystr)-1, "%s CACHE DATA/%s", cache_type,
+ snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
domain_name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
/* Fetch cache information */
data = tdb_fetch_by_string(cache_tdb, keystr);
@@ -268,10 +297,7 @@ static BOOL fetch_cache(char *domain_name, char *cache_type,
be freed by the end{pw,gr}ent() function. */
*sam_entries = (struct acct_info *)data.dptr;
- *num_sam_entries = data.dsize / sizeof(struct acct_info);
-
- DEBUG(4, ("fetched %d cached %s entries for domain %s\n",
- *num_sam_entries, cache_type, domain_name));
+ *buflen = data.dsize;
return True;
}
@@ -279,40 +305,58 @@ 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,
- struct acct_info **sam_entries,
+BOOL winbindd_fetch_user_cache(char *domain_name,
+ struct getpwent_user **sam_entries,
int *num_entries)
{
- return fetch_cache(domain_name, CACHE_TYPE_USER, sam_entries,
- num_entries);
+ BOOL result;
+ int buflen;
+
+ result = fetch_cache(domain_name, 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));
+
+ return result;
}
/* 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,
- struct acct_info **sam_entries,
+BOOL winbindd_fetch_group_cache(char *domain_name,
+ struct acct_info **sam_entries,
int *num_entries)
{
- return fetch_cache(domain_name, CACHE_TYPE_GROUP, sam_entries,
- num_entries);
+ BOOL result;
+ int buflen;
+
+ result = fetch_cache(domain_name, 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));
+
+ return result;
}
-static BOOL fetch_cache_entry(char *domain, char *cache_type, char *name, void *buf, int len)
+static BOOL fetch_cache_entry(char *domain, char *cache_type, char *name,
+ void *buf, int len)
{
TDB_DATA data;
fstring keystr;
/* Create key for lookup */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s", cache_type, domain, name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type, domain, name);
/* Look up cache entry */
data = tdb_fetch_by_string(cache_tdb, keystr);
if (!data.dptr) return False;
- DEBUG(4, ("returning cached entry for %s\\%s\n", domain, name));
-
/* Copy found entry into buffer */
memcpy((char *)buf, data.dptr, len < data.dsize ? len : data.dsize);
free(data.dptr);
@@ -327,10 +371,12 @@ BOOL winbindd_fetch_user_cache_entry(char *domain_name, char *user,
if (lp_winbind_cache_time() == 0) return False;
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER, user);
+ seq_num = get_cache_sequence_number(domain_name, 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, sizeof(struct winbindd_pw));
+ return fetch_cache_entry(domain_name, CACHE_TYPE_USER, user, pw,
+ sizeof(struct winbindd_pw));
}
/* Fetch an individual uid cache entry */
@@ -342,11 +388,13 @@ BOOL winbindd_fetch_uid_cache_entry(char *domain_name, uid_t uid,
if (lp_winbind_cache_time() == 0) return False;
- slprintf(uidstr, sizeof(uidstr)-1, "#%u", (unsigned)uid);
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER, uidstr);
+ 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, sizeof(struct winbindd_pw));
+ return fetch_cache_entry(domain_name, CACHE_TYPE_USER, uidstr, pw,
+ sizeof(struct winbindd_pw));
}
/* Fetch an individual group cache entry. This function differs from the
@@ -362,15 +410,21 @@ BOOL winbindd_fetch_group_cache_entry(char *domain_name, char *group,
if (lp_winbind_cache_time() == 0) return False;
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP, group);
+ seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP,
+ group);
+
if (cache_domain_expired(domain_name, seq_num)) return False;
/* Fetch group data */
- if (!fetch_cache_entry(domain_name, CACHE_TYPE_GROUP, group, gr, sizeof(struct winbindd_gr))) return False;
+ if (!fetch_cache_entry(domain_name, CACHE_TYPE_GROUP, group, gr,
+ sizeof(struct winbindd_gr))) {
+ return False;
+ }
/* Fetch extra data */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s DATA", CACHE_TYPE_GROUP, domain_name, group);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain_name, group);
+
data = tdb_fetch_by_string(cache_tdb, keystr);
if (!data.dptr) return False;
@@ -395,20 +449,24 @@ BOOL winbindd_fetch_gid_cache_entry(char *domain_name, gid_t gid,
fstring gidstr;
uint32 seq_num;
- slprintf(gidstr, sizeof(gidstr)-1, "#%u", (unsigned)gid);
+ snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned)gid);
if (lp_winbind_cache_time() == 0) return False;
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP, gidstr);
+ seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP,
+ gidstr);
+
if (cache_domain_expired(domain_name, seq_num)) return False;
/* Fetch group data */
if (!fetch_cache_entry(domain_name, CACHE_TYPE_GROUP,
- gidstr, gr, sizeof(struct winbindd_gr))) return False;
+ gidstr, gr, sizeof(struct winbindd_gr))) {
+ return False;
+ }
/* Fetch extra data */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s DATA", CACHE_TYPE_GROUP, domain_name, gidstr);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain_name, gidstr);
data = tdb_fetch_by_string(cache_tdb, keystr);
if (!data.dptr) return False;
@@ -425,3 +483,8 @@ void winbindd_flush_cache(void)
tdb_close(cache_tdb);
winbindd_cache_init();
}
+
+/* Print cache status information */
+void winbindd_cache_dump_status(void)
+{
+}