diff options
-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 */ |