diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/nsswitch/winbindd_cache.c | 292 |
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) { } |