r22713: Offline logon fixes for idmap manager:
authorGerald Carter <jerry@samba.org>
Sun, 6 May 2007 21:04:30 +0000 (21:04 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:21:49 +0000 (12:21 -0500)
(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

source/nsswitch/idmap.c
source/nsswitch/idmap_cache.c
source/nsswitch/winbindd.h

index 73a30f608747f8a73e0f552363ded65f819ec9cf..babd5645aaf79b2a61c8b094731c017e292446f6 100644 (file)
@@ -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);
index d43dc63f4260c2ff3555712f83f26156f622886e..4fbc3c7effebfe288c5c277ba5312c6722fba875 100644 (file)
@@ -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);
index b316e988b8850557d93f674143dbf8e05784f7ae..e43cb0853a38ae4364b3168f0e2f306d55e27ec9 100644 (file)
@@ -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 */