diff options
author | Gerald Carter <jerry@samba.org> | 2007-05-06 21:04:30 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:21:49 -0500 |
commit | c16059f1f0eab31835f577aa4985fd9d70a8982c (patch) | |
tree | 76e1241da919617cf78f45c0fa9b14d4f5dd7a54 /source3 | |
parent | fd5ff711b6fa4b1146776ba6f915a20e64786c53 (diff) | |
download | samba-c16059f1f0eab31835f577aa4985fd9d70a8982c.tar.gz samba-c16059f1f0eab31835f577aa4985fd9d70a8982c.tar.bz2 samba-c16059f1f0eab31835f577aa4985fd9d70a8982c.zip |
r22713: Offline logon fixes for idmap manager:
(a) Ignore the negative cache when the domain is offline
(b) don't delete expired entries from the cache as these
can be used when offline (same model as thw wcache entries)
(c) Delay idmap backend initialization when offline
as the backend routines will not be called until we go
online anyways. This prevents idmap_init() from failing
when a backend's init() function fails becuase of lack of
network connectivity
(This used to be commit 4086ef15b395f1a536fb669af2103a33ecc14de4)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/nsswitch/idmap.c | 24 | ||||
-rw-r--r-- | source3/nsswitch/idmap_cache.c | 113 | ||||
-rw-r--r-- | source3/nsswitch/winbindd.h | 3 |
3 files changed, 80 insertions, 60 deletions
diff --git a/source3/nsswitch/idmap.c b/source3/nsswitch/idmap.c index 73a30f6087..babd5645aa 100644 --- a/source3/nsswitch/idmap.c +++ b/source3/nsswitch/idmap.c @@ -282,8 +282,18 @@ NTSTATUS idmap_init(void) if ( !NT_STATUS_IS_OK(ret) ) return ret; - if (NT_STATUS_IS_OK(idmap_init_status)) + if (NT_STATUS_IS_OK(idmap_init_status)) { return NT_STATUS_OK; + } + + /* We can't reliably call intialization code here unless + we are online. But return NT_STATUS_OK so the upper + level code doesn't abort idmap lookups. */ + + if ( get_global_winbindd_state_offline() ) { + idmap_init_status = NT_STATUS_FILE_IS_OFFLINE; + return NT_STATUS_OK; + } static_init_idmap; @@ -1114,6 +1124,7 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) struct id_map **bids; int i, bi; int bn = 0; + struct winbindd_domain *our_domain = find_our_domain(); if (! NT_STATUS_IS_OK(ret = idmap_init())) { return ret; @@ -1179,6 +1190,11 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) /* let's see if there is any id mapping to be retieved from the backends */ if (bi) { + /* Only do query if we are online */ + if ( IS_DOMAIN_OFFLINE(our_domain) ) { + ret = NT_STATUS_FILE_IS_OFFLINE; + goto done; + } ret = idmap_backends_unixids_to_sids(bids); IDMAP_CHECK_RET(ret); @@ -1218,6 +1234,7 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) struct id_map **bids; int i, bi; int bn = 0; + struct winbindd_domain *our_domain = find_our_domain(); if (! NT_STATUS_IS_OK(ret = idmap_init())) { return ret; @@ -1284,6 +1301,11 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) /* let's see if there is any id mapping to be retieved from the backends */ if (bids) { + /* Only do query if we are online */ + if ( IS_DOMAIN_OFFLINE(our_domain) ) { + ret = NT_STATUS_FILE_IS_OFFLINE; + goto done; + } ret = idmap_backends_sids_to_unixids(bids); IDMAP_CHECK_RET(ret); diff --git a/source3/nsswitch/idmap_cache.c b/source3/nsswitch/idmap_cache.c index d43dc63f42..4fbc3c7eff 100644 --- a/source3/nsswitch/idmap_cache.c +++ b/source3/nsswitch/idmap_cache.c @@ -182,42 +182,6 @@ done: return ret; } -NTSTATUS idmap_cache_del(struct idmap_cache_ctx *cache, const struct id_map *id) -{ - NTSTATUS ret; - char *sidkey = NULL; - char *idkey = NULL; - - ret = idmap_cache_build_sidkey(cache, &sidkey, id); - if (!NT_STATUS_IS_OK(ret)) return ret; - - ret = idmap_cache_build_idkey(cache, &idkey, id); - if (!NT_STATUS_IS_OK(ret)) { - goto done; - } - - /* delete SID */ - - DEBUG(10, ("Deleting cache entry (key = %s)\n", sidkey)); - - if (tdb_delete_bystring(cache->tdb, sidkey) != 0) { - DEBUG(3, ("Failed to delete cache entry!\n")); - } - - /* delete ID */ - - DEBUG(10, ("Deleting cache entry (key = %s)\n", idkey)); - - if (tdb_delete_bystring(cache->tdb, idkey) != 0) { - DEBUG(3, ("Failed to delete cache entry!\n")); - } - -done: - talloc_free(sidkey); - talloc_free(idkey); - return ret; -} - NTSTATUS idmap_cache_set_negative_sid(struct idmap_cache_ctx *cache, const struct id_map *id) { NTSTATUS ret; @@ -365,9 +329,11 @@ NTSTATUS idmap_cache_map_sid(struct idmap_cache_ctx *cache, struct id_map *id) { NTSTATUS ret; TDB_DATA databuf; - time_t t, now; + time_t t; char *sidkey; char *endptr; + struct winbindd_domain *our_domain = find_our_domain(); + time_t now = time(NULL); /* make sure it is marked as not mapped by default */ id->status = ID_UNKNOWN; @@ -392,8 +358,6 @@ NTSTATUS idmap_cache_map_sid(struct idmap_cache_ctx *cache, struct id_map *id) goto done; } - now = time(NULL); - /* check it is not negative */ if (strcmp("IDMAP/NEGATIVE", endptr+1) != 0) { @@ -413,26 +377,40 @@ NTSTATUS idmap_cache_map_sid(struct idmap_cache_ctx *cache, struct id_map *id) /* here ret == NT_STATUS_OK and id->status = ID_MAPPED */ if (t <= now) { - - /* we have it, but it is expired */ - id->status = ID_EXPIRED; + /* If we've been told to be offline - stay in + that state... */ + if ( IS_DOMAIN_OFFLINE(our_domain) ) { + DEBUG(10,("idmap_cache_map_sid: idmap is offline\n")); + goto done; + } /* We're expired, set an error code for upper layer */ ret = NT_STATUS_SYNCHRONIZATION_REQUIRED; } - } else { + + goto done; + } + + /* Was a negative cache hit */ + + /* Ignore the negative cache when offline */ + + if ( IS_DOMAIN_OFFLINE(our_domain) ) { + DEBUG(10,("idmap_cache_map_sid: idmap is offline\n")); + goto done; + } + + + /* Check for valid or expired cache hits */ if (t <= now) { - /* We're expired, delete the NEGATIVE entry and return - not mapped */ - tdb_delete_bystring(cache->tdb, sidkey); + /* We're expired. Return not mapped */ ret = NT_STATUS_NONE_MAPPED; } else { /* this is not mapped as it was a negative cache hit */ id->status = ID_UNMAPPED; ret = NT_STATUS_OK; } - } done: SAFE_FREE(databuf.dptr); @@ -459,9 +437,11 @@ NTSTATUS idmap_cache_map_id(struct idmap_cache_ctx *cache, struct id_map *id) { NTSTATUS ret; TDB_DATA databuf; - time_t t, now; + time_t t; char *idkey; char *endptr; + struct winbindd_domain *our_domain = find_our_domain(); + time_t now = time(NULL); /* make sure it is marked as unknown by default */ id->status = ID_UNKNOWN; @@ -486,8 +466,6 @@ NTSTATUS idmap_cache_map_id(struct idmap_cache_ctx *cache, struct id_map *id) goto done; } - now = time(NULL); - /* check it is not negative */ if (strcmp("IDMAP/NEGATIVE", endptr+1) != 0) { @@ -507,26 +485,43 @@ NTSTATUS idmap_cache_map_id(struct idmap_cache_ctx *cache, struct id_map *id) /* here ret == NT_STATUS_OK and id->mapped = ID_MAPPED */ if (t <= now) { - - /* we have it, but it is expired */ - id->status = ID_EXPIRED; + /* If we've been told to be offline - stay in + that state... */ + if ( IS_DOMAIN_OFFLINE(our_domain) ) { + DEBUG(10,("idmap_cache_map_sid: idmap is offline\n")); + goto done; + } /* We're expired, set an error code for upper layer */ ret = NT_STATUS_SYNCHRONIZATION_REQUIRED; } - } else { + + goto done; + } + + /* Was a negative cache hit */ + + /* Ignore the negative cache when offline */ + + if ( IS_DOMAIN_OFFLINE(our_domain) ) { + DEBUG(10,("idmap_cache_map_sid: idmap is offline\n")); + ret = NT_STATUS_NONE_MAPPED; + + goto done; + } + + /* Process the negative cache hit */ + if (t <= now) { - /* We're expired, delete the NEGATIVE entry and return - not mapped */ - tdb_delete_bystring(cache->tdb, idkey); + /* We're expired. Return not mapped */ ret = NT_STATUS_NONE_MAPPED; } else { - /* this is not mapped as it was a negative cache hit */ + /* this is not mapped is it was a negative cache hit */ id->status = ID_UNMAPPED; ret = NT_STATUS_OK; } - } + done: SAFE_FREE(databuf.dptr); talloc_free(idkey); diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index b316e988b8..e43cb0853a 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -354,4 +354,7 @@ struct winbindd_tdc_domain { #define WINBINDD_PAM_AUTH_KRB5_RENEW_TIME 2592000 /* one month */ #define DOM_SEQUENCE_NONE ((uint32)-1) +#define IS_DOMAIN_OFFLINE(x) ( lp_winbind_offline_logon() && \ + ( get_global_winbindd_state_offline() \ + || !(x)->online ) ) #endif /* _WINBINDD_H */ |