summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_cache.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2003-06-21 04:05:01 +0000
committerGerald Carter <jerry@samba.org>2003-06-21 04:05:01 +0000
commit93bcb9963bef53b91a0b16c6389cefdb7bea2b0e (patch)
tree25622225b6bab1d54e82d4871254eed7d2c110f5 /source3/nsswitch/winbindd_cache.c
parentf70cc4cdc188fd8bf9f8f84cb55d15c122e463dd (diff)
downloadsamba-93bcb9963bef53b91a0b16c6389cefdb7bea2b0e.tar.gz
samba-93bcb9963bef53b91a0b16c6389cefdb7bea2b0e.tar.bz2
samba-93bcb9963bef53b91a0b16c6389cefdb7bea2b0e.zip
merge of the netsamlogon caching code from APPLIANCE_HEAD
This replaces the universal group caching code (was originally based on that code). Only applies to the the RPC code. One comment: domain local groups don't show up in 'getent group' that's easy to fix. Code has been tested against 2k domain but doesn't change anything with respect to NT4 domains. netsamlogon caching works pretty much like the universal group caching code did but has had much more testing and puts winbind mostly back in sync between branches. (This used to be commit aac01dc7bc95c20ee21c93f3581e2375d9a894e1)
Diffstat (limited to 'source3/nsswitch/winbindd_cache.c')
-rw-r--r--source3/nsswitch/winbindd_cache.c140
1 files changed, 116 insertions, 24 deletions
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index e0860cd695..5464e765d1 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -4,6 +4,8 @@
Winbind cache backend functions
Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Gerald Carter 2003
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -342,6 +344,7 @@ static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force)
domain->sequence_number = DOM_SEQUENCE_NONE;
}
+ domain->last_status = status;
domain->last_seq_check = time(NULL);
/* save the new sequence number ni the cache */
@@ -671,9 +674,10 @@ do_query:
*num_entries = 0;
*info = NULL;
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ /* Return status value returned by seq number check */
+
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
/* Put the query_user_list() in a retry loop. There appears to be
* some bug either with Windows 2000 or Samba's handling of large
@@ -697,7 +701,8 @@ do_query:
winbindd_cm_flush();
}
- } while (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) && (retry++ < 5));
+ } while (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) &&
+ (retry++ < 5));
/* and save it */
refresh_sequence_number(domain, False);
@@ -775,9 +780,10 @@ do_query:
*num_entries = 0;
*info = NULL;
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ /* Return status value returned by seq number check */
+
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
DEBUG(10,("enum_dom_groups: [Cached] - doing backend query for list for domain %s\n",
domain->name ));
@@ -857,9 +863,10 @@ do_query:
*num_entries = 0;
*info = NULL;
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ /* Return status value returned by seq number check */
+
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
DEBUG(10,("enum_local_groups: [Cached] - doing backend query for list for domain %s\n",
domain->name ));
@@ -924,9 +931,16 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
do_query:
ZERO_STRUCTP(sid);
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ /* If the seq number check indicated that there is a problem
+ * with this DC, then return that status... except for
+ * access_denied. This is special because the dc may be in
+ * "restrict anonymous = 1" mode, in which case it will deny
+ * most unauthenticated operations, but *will* allow the LSA
+ * name-to-sid that we try as a fallback. */
+
+ if (!(NT_STATUS_IS_OK(domain->last_status)
+ || NT_STATUS_EQUAL(domain->last_status, NT_STATUS_ACCESS_DENIED)))
+ return domain->last_status;
DEBUG(10,("name_to_sid: [Cached] - doing backend query for name for domain %s\n",
domain->name ));
@@ -980,6 +994,17 @@ do_query:
return NT_STATUS_SERVER_DISABLED;
}
+ /* If the seq number check indicated that there is a problem
+ * with this DC, then return that status... except for
+ * access_denied. This is special because the dc may be in
+ * "restrict anonymous = 1" mode, in which case it will deny
+ * most unauthenticated operations, but *will* allow the LSA
+ * sid-to-name that we try as a fallback. */
+
+ if (!(NT_STATUS_IS_OK(domain->last_status)
+ || NT_STATUS_EQUAL(domain->last_status, NT_STATUS_ACCESS_DENIED)))
+ return domain->last_status;
+
DEBUG(10,("sid_to_name: [Cached] - doing backend query for name for domain %s\n",
domain->name ));
@@ -1003,12 +1028,24 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- fstring sid_string;
if (!cache->tdb)
goto do_query;
- centry = wcache_fetch(cache, domain, "U/%s", sid_to_string(sid_string, user_sid));
+ centry = wcache_fetch(cache, domain, "U/%s", sid_string_static(user_sid));
+
+ /* If we have an access denied cache entry and a cached info3 in the
+ samlogon cache then do a query. This will force the rpc back end
+ to return the info3 data. */
+
+ if (NT_STATUS_V(domain->last_status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) &&
+ netsamlogon_cache_have(user_sid)) {
+ DEBUG(10, ("query_user: cached access denied and have cached info3\n"));
+ domain->last_status = NT_STATUS_OK;
+ centry_free(centry);
+ goto do_query;
+ }
+
if (!centry)
goto do_query;
@@ -1027,9 +1064,10 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
do_query:
ZERO_STRUCTP(info);
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ /* Return status value returned by seq number check */
+
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
DEBUG(10,("sid_to_name: [Cached] - doing backend query for info for domain %s\n",
domain->name ));
@@ -1060,6 +1098,19 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
goto do_query;
centry = wcache_fetch(cache, domain, "UG/%s", sid_to_string(sid_string, user_sid));
+
+ /* If we have an access denied cache entry and a cached info3 in the
+ samlogon cache then do a query. This will force the rpc back end
+ to return the info3 data. */
+
+ if (NT_STATUS_V(domain->last_status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) &&
+ netsamlogon_cache_have(user_sid)) {
+ DEBUG(10, ("query_user: cached access denied and have cached info3\n"));
+ domain->last_status = NT_STATUS_OK;
+ centry_free(centry);
+ goto do_query;
+ }
+
if (!centry)
goto do_query;
@@ -1088,9 +1139,10 @@ do_query:
(*num_groups) = 0;
(*user_gids) = NULL;
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ /* Return status value returned by seq number check */
+
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
DEBUG(10,("lookup_usergroups: [Cached] - doing backend query for info for domain %s\n",
domain->name ));
@@ -1167,10 +1219,10 @@ do_query:
(*names) = NULL;
(*name_types) = NULL;
+ /* Return status value returned by seq number check */
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
DEBUG(10,("lookup_groupmem: [Cached] - doing backend query for info for domain %s\n",
domain->name ));
@@ -1248,6 +1300,46 @@ static NTSTATUS alternate_name(struct winbindd_domain *domain)
return domain->backend->alternate_name(domain);
}
+/* Invalidate cached user and group lists coherently */
+
+static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+ void *state)
+{
+ if (strncmp(kbuf.dptr, "UL/", 3) == 0 ||
+ strncmp(kbuf.dptr, "GL/", 3) == 0)
+ tdb_delete(the_tdb, kbuf);
+
+ return 0;
+}
+
+/* Invalidate the getpwnam and getgroups entries for a winbindd domain */
+
+void wcache_invalidate_samlogon(struct winbindd_domain *domain,
+ NET_USER_INFO_3 *info3)
+{
+ struct winbind_cache *cache;
+
+ if (!domain)
+ return;
+
+ cache = get_cache(domain);
+ netsamlogon_clear_cached_user(cache->tdb, info3);
+}
+
+void wcache_invalidate_cache(void)
+{
+ struct winbindd_domain *domain;
+
+ for (domain = domain_list(); domain; domain = domain->next) {
+ struct winbind_cache *cache = get_cache(domain);
+
+ DEBUG(10, ("wcache_invalidate_cache: invalidating cache "
+ "entries for %s\n", domain->name));
+ if (cache)
+ tdb_traverse(cache->tdb, traverse_fn, NULL);
+ }
+}
+
/* the ADS backend methods are exposed via this structure */
struct winbindd_methods cache_methods = {
True,