summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/nsswitch/idmap.c24
-rw-r--r--source3/nsswitch/idmap_cache.c113
-rw-r--r--source3/nsswitch/winbindd.h3
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 */