r22343: Commit to 3_0 as well after adapting the patch.
authorSimo Sorce <idra@samba.org>
Wed, 18 Apr 2007 21:10:37 +0000 (21:10 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:19:27 +0000 (12:19 -0500)
(tdb_delete_bystring instead of tdb_delete is used here)

source/include/idmap.h
source/include/smb.h
source/nsswitch/idmap.c
source/nsswitch/idmap_ad.c
source/nsswitch/idmap_cache.c
source/nsswitch/idmap_ldap.c
source/nsswitch/idmap_nss.c
source/nsswitch/idmap_passdb.c
source/nsswitch/idmap_tdb.c

index 80bd541a23f231ea8d3b725d56323c951a3f9e33..472358a2305629b5aefbe40dc1d85c3b4f3106ef 100644 (file)
@@ -42,13 +42,15 @@ struct idmap_domain {
        BOOL readonly;
        void *private_data;
        struct idmap_methods *methods;
+       BOOL initialized;
+       const char *params;
 };
 
 /* Filled out by IDMAP backends */
 struct idmap_methods {
 
        /* Called when backend is first loaded */
-       NTSTATUS (*init)(struct idmap_domain *dom, const char *compat_params);
+       NTSTATUS (*init)(struct idmap_domain *dom);
 
        NTSTATUS (*unixids_to_sids)(struct idmap_domain *dom, struct id_map **ids);
        NTSTATUS (*sids_to_unixids)(struct idmap_domain *dom, struct id_map **ids);
index a9c57f77f2507117f75b2d4addd2cbdb2254a7e3..f85201ed303fcafe3a9d4ca329aa61a32dfe5406 100644 (file)
@@ -278,7 +278,8 @@ typedef struct dom_sid {
 enum id_mapping {
        ID_UNKNOWN,
        ID_MAPPED,
-       ID_UNMAPPED
+       ID_UNMAPPED,
+       ID_EXPIRED
 };
 
 enum id_type {
index 885950830eb6ab6e4e3dc7d85b878dbe5f85f886..82b8f3d592e5635d2be90ecb641d1c6feb0693df 100644 (file)
@@ -43,6 +43,12 @@ struct idmap_alloc_backend {
 
 struct idmap_cache_ctx;
 
+struct idmap_alloc_context {
+       const char *params;
+       struct idmap_alloc_methods *methods;
+       BOOL initialized;
+};
+
 static TALLOC_CTX *idmap_ctx = NULL;
 static struct idmap_cache_ctx *idmap_cache;
 
@@ -53,9 +59,10 @@ static int pdb_dom_num = -1;
 static int def_dom_num = -1;
 
 static struct idmap_alloc_backend *alloc_backends = NULL;
-static struct idmap_alloc_methods *alloc_methods = NULL;
+static struct idmap_alloc_context *idmap_alloc_ctx = NULL;
 
 #define IDMAP_CHECK_RET(ret) do { if ( ! NT_STATUS_IS_OK(ret)) { DEBUG(2, ("ERROR: NTSTATUS = 0x%08x\n", NT_STATUS_V(ret))); goto done; } } while(0)
+#define IDMAP_REPORT_RET(ret) do { if ( ! NT_STATUS_IS_OK(ret)) { DEBUG(2, ("ERROR: NTSTATUS = 0x%08x\n", NT_STATUS_V(ret))); } } while(0)
 #define IDMAP_CHECK_ALLOC(mem) do { if (!mem) { DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } } while(0)
 
 static struct idmap_methods *get_methods(struct idmap_backend *be, const char *name)
@@ -102,6 +109,12 @@ void set_idmap_in_own_child(void)
        idmap_in_own_child = True;
 }
 
+BOOL idmap_is_offline(void)
+{
+       return ( lp_winbind_offline_logon() &&
+            get_global_winbindd_state_offline() );
+}
+
 /**********************************************************************
  Allow a module to register itself as a method.
 **********************************************************************/
@@ -221,9 +234,9 @@ static int close_domain_destructor(struct idmap_domain *dom)
 NTSTATUS idmap_close(void)
 {
        /* close the alloc backend first before freeing idmap_ctx */
-       if (alloc_methods) {
-               alloc_methods->close_fn();
-               alloc_methods = NULL;
+       if (idmap_alloc_ctx) {
+               idmap_alloc_ctx->methods->close_fn();
+               idmap_alloc_ctx->methods = NULL;
        }
        alloc_backends = NULL;
 
@@ -272,7 +285,7 @@ NTSTATUS idmap_init_cache(void)
 NTSTATUS idmap_init(void)
 {      
        NTSTATUS ret;
-       static NTSTATUS backend_init_status = NT_STATUS_UNSUCCESSFUL;   
+       static NTSTATUS idmap_init_status = NT_STATUS_UNSUCCESSFUL;
        struct idmap_domain *dom;
        char *compat_backend = NULL;
        char *compat_params = NULL;
@@ -283,24 +296,12 @@ NTSTATUS idmap_init(void)
        int compat = 0;
        int i;
 
-       /* Always initialize the cache.  We'll have to delay initialization
-          of backends if we are offline */
-
        ret = idmap_init_cache();
        if ( !NT_STATUS_IS_OK(ret) )
                return ret;
 
-       if ( NT_STATUS_IS_OK(backend_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 */
-
-       if ( get_global_winbindd_state_offline() ) {
-               backend_init_status = NT_STATUS_FILE_IS_OFFLINE;
-               return backend_init_status;             
-       }
 
        static_init_idmap;
 
@@ -432,13 +433,18 @@ NTSTATUS idmap_init(void)
                /* now that we have methods, set the destructor for this domain */
                talloc_set_destructor(dom, close_domain_destructor);
 
+               if (compat_params) {
+                       dom->params = talloc_strdup(dom, compat_params);
+                       IDMAP_CHECK_ALLOC(dom->params);
+               } else {
+                       dom->params = NULL;
+               }
+
                /* Finally instance a backend copy for this domain */
-               ret = dom->methods->init(dom, compat_params);
+               ret = dom->methods->init(dom);
                if ( ! NT_STATUS_IS_OK(ret)) {
-                       DEBUG(0, ("ERROR: Initialization failed for backend %s (domain %s)\n",
+                       DEBUG(0, ("ERROR: Initialization failed for backend %s (domain %s), deferred!\n",
                                                parm_backend, dom->name));
-                       ret = NT_STATUS_UNSUCCESSFUL;
-                       goto done;
                }
                idmap_domains = talloc_realloc(idmap_ctx, idmap_domains, struct idmap_domain *, i+1);
                if ( ! idmap_domains) {
@@ -489,8 +495,15 @@ NTSTATUS idmap_init(void)
                /* now that we have methods, set the destructor for this domain */
                talloc_set_destructor(dom, close_domain_destructor);
 
+               if (compat_params) {
+                       dom->params = talloc_strdup(dom, compat_params);
+                       IDMAP_CHECK_ALLOC(dom->params);
+               } else {
+                       dom->params = NULL;
+               }
+
                /* Finally instance a backend copy for this domain */
-               ret = dom->methods->init(dom, compat_params);
+               ret = dom->methods->init(dom);
                if ( ! NT_STATUS_IS_OK(ret)) {
                        DEBUG(0, ("ERROR: Initialization failed for idmap_nss ?!\n"));
                        ret = NT_STATUS_UNSUCCESSFUL;
@@ -533,8 +546,15 @@ NTSTATUS idmap_init(void)
        /* now that we have methods, set the destructor for this domain */
        talloc_set_destructor(dom, close_domain_destructor);
 
+       if (compat_params) {
+               dom->params = talloc_strdup(dom, compat_params);
+               IDMAP_CHECK_ALLOC(dom->params);
+       } else {
+               dom->params = NULL;
+       }
+
        /* Finally instance a backend copy for this domain */
-       ret = dom->methods->init(dom, compat_params);
+       ret = dom->methods->init(dom);
        if ( ! NT_STATUS_IS_OK(ret)) {
                DEBUG(0, ("ERROR: Initialization failed for idmap_passdb ?!\n"));
                ret = NT_STATUS_UNSUCCESSFUL;
@@ -595,37 +615,50 @@ NTSTATUS idmap_init(void)
        }
 
        if ( alloc_backend ) {
+               
+               idmap_alloc_ctx = talloc_zero(idmap_ctx, struct idmap_alloc_context);
+               IDMAP_CHECK_ALLOC(idmap_alloc_ctx);
 
-               alloc_methods = get_alloc_methods(alloc_backends, alloc_backend);
-               if ( ! alloc_methods) {
+               idmap_alloc_ctx->methods = get_alloc_methods(alloc_backends, alloc_backend);
+               if ( ! idmap_alloc_ctx->methods) {
                        ret = smb_probe_module("idmap", alloc_backend);
                        if (NT_STATUS_IS_OK(ret)) {
-                               alloc_methods = get_alloc_methods(alloc_backends, alloc_backend);
+                               idmap_alloc_ctx->methods = get_alloc_methods(alloc_backends, alloc_backend);
                        }
                }
-               if ( alloc_methods) {
-                       ret = alloc_methods->init(compat_params);
+               if (idmap_alloc_ctx->methods) {
+
+                       if (compat_params) {
+                               idmap_alloc_ctx->params = talloc_strdup(idmap_alloc_ctx, compat_params);
+                               IDMAP_CHECK_ALLOC(idmap_alloc_ctx->params);
+                       } else {
+                               idmap_alloc_ctx->params = NULL;
+                       }
+
+                       ret = idmap_alloc_ctx->methods->init(idmap_alloc_ctx->params);
                        if ( ! NT_STATUS_IS_OK(ret)) {
-                               DEBUG(0, ("idmap_init: Initialization failed for alloc "
-                                         "backend %s\n", alloc_backend));
-                               ret = NT_STATUS_UNSUCCESSFUL;
-                               goto done;
-               }
+                               DEBUG(0, ("ERROR: Initialization failed for alloc "
+                                         "backend %s, deferred!\n", alloc_backend));
+                       } else {
+                               idmap_alloc_ctx->initialized = True;
+                       }
                } else {
                        DEBUG(2, ("idmap_init: Unable to get methods for alloc backend %s\n", 
                                  alloc_backend));
                        /* certain compat backends are just readonly */
-                       if ( compat )
+                       if ( compat ) {
+                               TALLOC_FREE(idmap_alloc_ctx);
                                ret = NT_STATUS_OK;
-                       else
+                       } else {
                                ret = NT_STATUS_UNSUCCESSFUL;
+                       }
                }
        }
        
        /* cleanpu temporary strings */
        TALLOC_FREE( compat_backend );
-       
-       backend_init_status = NT_STATUS_OK;
+
+       idmap_init_status = NT_STATUS_OK;
        
        return ret;
 
@@ -633,12 +666,35 @@ done:
        DEBUG(0, ("Aborting IDMAP Initialization ...\n"));
        idmap_close();
 
-       /* save the init status for later checks */
-       backend_init_status = ret;
-       
        return ret;
 }
 
+static NTSTATUS idmap_alloc_init(void)
+{
+       NTSTATUS ret;
+
+       if (! NT_STATUS_IS_OK(ret = idmap_init())) {
+               return ret;
+       }
+
+       if ( ! idmap_alloc_ctx) {
+               return NT_STATUS_NOT_SUPPORTED;
+       }
+
+       if ( ! idmap_alloc_ctx->initialized) {
+               ret = idmap_alloc_ctx->methods->init(idmap_alloc_ctx->params);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       DEBUG(0, ("ERROR: Initialization failed for alloc "
+                                 "backend, deferred!\n"));
+                       return ret;
+               } else {
+                       idmap_alloc_ctx->initialized = True;
+               }
+       }
+
+       return NT_STATUS_OK;
+}
+
 /**************************************************************************
  idmap allocator interface functions
 **************************************************************************/
@@ -647,60 +703,48 @@ NTSTATUS idmap_allocate_uid(struct unixid *id)
 {
        NTSTATUS ret;
 
-       if (! NT_STATUS_IS_OK(ret = idmap_init())) {
+       if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) {
                return ret;
        }
 
-       if ( !alloc_methods )
-               return NT_STATUS_NOT_SUPPORTED; 
-
        id->type = ID_TYPE_UID;
-       return alloc_methods->allocate_id(id);
+       return idmap_alloc_ctx->methods->allocate_id(id);
 }
 
 NTSTATUS idmap_allocate_gid(struct unixid *id)
 {
        NTSTATUS ret;
 
-       if (! NT_STATUS_IS_OK(ret = idmap_init())) {
+       if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) {
                return ret;
        }
 
-       if ( !alloc_methods )
-               return NT_STATUS_NOT_SUPPORTED; 
-
        id->type = ID_TYPE_GID;
-       return alloc_methods->allocate_id(id);
+       return idmap_alloc_ctx->methods->allocate_id(id);
 }
 
 NTSTATUS idmap_set_uid_hwm(struct unixid *id)
 {
        NTSTATUS ret;
 
-       if (! NT_STATUS_IS_OK(ret = idmap_init())) {
+       if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) {
                return ret;
        }
 
-       if ( !alloc_methods )
-               return NT_STATUS_NOT_SUPPORTED; 
-
        id->type = ID_TYPE_UID;
-       return alloc_methods->set_id_hwm(id);
+       return idmap_alloc_ctx->methods->set_id_hwm(id);
 }
 
 NTSTATUS idmap_set_gid_hwm(struct unixid *id)
 {
        NTSTATUS ret;
 
-       if (! NT_STATUS_IS_OK(ret = idmap_init())) {
+       if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) {
                return ret;
        }
 
-       if ( !alloc_methods )
-               return NT_STATUS_NOT_SUPPORTED; 
-
        id->type = ID_TYPE_GID;
-       return alloc_methods->set_id_hwm(id);
+       return idmap_alloc_ctx->methods->set_id_hwm(id);
 }
 
 /******************************************************************************
@@ -815,6 +859,11 @@ static NTSTATUS idmap_new_mapping(TALLOC_CTX *ctx, struct id_map *map)
        enum lsa_SidType sid_type;
        BOOL wbret;
 
+       /* If we are offline we cannot lookup SIDs, deny mapping */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
        ret = idmap_can_map(map, &dom);
        if ( ! NT_STATUS_IS_OK(ret)) {
                return NT_STATUS_NONE_MAPPED;
@@ -937,11 +986,6 @@ static NTSTATUS idmap_backends_unixids_to_sids(struct id_map **ids)
 
        _ids = ids;
 
-       /* make sure all maps are marked as in UNKNOWN status */
-       for (i = 0; _ids[i]; i++) {
-               _ids[i]->status = ID_UNKNOWN;
-       }
-
        unmapped = NULL;
        for (n = num_domains-1; n >= 0; n--) { /* cycle backwards */
 
@@ -950,12 +994,12 @@ static NTSTATUS idmap_backends_unixids_to_sids(struct id_map **ids)
                DEBUG(10, ("Query sids from domain %s\n", dom->name));
                
                ret = dom->methods->unixids_to_sids(dom, _ids);
-               IDMAP_CHECK_RET(ret);
+               IDMAP_REPORT_RET(ret);
 
                unmapped = NULL;
 
                for (i = 0, u = 0; _ids[i]; i++) {
-                       if (_ids[i]->status == ID_UNKNOWN || _ids[i]->status == ID_UNMAPPED) {
+                       if (_ids[i]->status != ID_MAPPED) {
                                unmapped = talloc_realloc(ctx, unmapped, struct id_map *, u + 2);
                                IDMAP_CHECK_ALLOC(unmapped);
                                unmapped[u] = _ids[i];
@@ -975,7 +1019,9 @@ static NTSTATUS idmap_backends_unixids_to_sids(struct id_map **ids)
 
        if (unmapped) {
                /* there are still unmapped ids, map them to the unix users/groups domains */
+               /* except for expired entries, these will be returned as valid (offline mode) */
                for (i = 0; unmapped[i]; i++) {
+                       if (unmapped[i]->status == ID_EXPIRED) continue;
                        switch (unmapped[i]->xid.type) {
                        case ID_TYPE_UID:
                                uid_to_unix_users_sid((uid_t)unmapped[i]->xid.id, unmapped[i]->sid);
@@ -1025,11 +1071,8 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids)
        for (i = 0; ids[i]; i++) {
                uint32 idx;             
 
-               /* make sure they are unknown to start off */
-               ids[i]->status = ID_UNKNOWN;
-
                if ( (dom = find_idmap_domain_from_sid( ids[i]->sid )) == NULL ) {
-                       /* no vailable idmap_domain.  Move on */
+                       /* no available idmap_domain.  Move on */
                        continue;
                }
 
@@ -1057,7 +1100,7 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids)
                        dom = idmap_domains[i];
                        DEBUG(10, ("Query ids from domain %s\n", dom->name));
                        ret = dom->methods->sids_to_unixids(dom, dom_ids[i]);
-                       IDMAP_CHECK_RET(ret);
+                       IDMAP_REPORT_RET(ret);
                }
        }
 
@@ -1065,6 +1108,8 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids)
        /* let's see if we have any unmapped SID left and act accordingly */
 
        for (i = 0; ids[i]; i++) {
+               /* NOTE: this will NOT touch ID_EXPIRED entries that the backend
+                * was not able to confirm/deny (offline mode) */
                if (ids[i]->status == ID_UNKNOWN || ids[i]->status == ID_UNMAPPED) {
                        /* ok this is an unmapped one, see if we can map it */
                        ret = idmap_new_mapping(ctx, ids[i]);
@@ -1075,7 +1120,8 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids)
                                /* could not map it */
                                ids[i]->status = ID_UNMAPPED;
                        } else {
-                               /* Something very bad happened down there */
+                               /* Something very bad happened down there
+                                * OR we are offline */
                                ids[i]->status = ID_UNKNOWN;
                        }
                }
@@ -1164,13 +1210,6 @@ 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 ( lp_winbind_offline_logon() &&
-                    get_global_winbindd_state_offline() )
-               {
-                       ret = NT_STATUS_FILE_IS_OFFLINE;
-                       goto done;
-               }
 
                ret = idmap_backends_unixids_to_sids(bids);
                IDMAP_CHECK_RET(ret);
@@ -1179,11 +1218,17 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids)
                for (i = 0; i < bi; i++) {
                        if (bids[i]->status == ID_MAPPED) {
                                ret = idmap_cache_set(idmap_cache, bids[i]);
+                       } else if (bids[i]->status == ID_EXPIRED) {
+                               /* the cache returned an expired entry and the backend was
+                                * was not able to clear the situation (offline).
+                                * This handles a previous NT_STATUS_SYNCHRONIZATION_REQUIRED
+                                * for disconnected mode, */
+                               bids[i]->status = ID_MAPPED;
                        } else if (bids[i]->status == ID_UNKNOWN) {
-                               /* return an expired entry in the cache or an unknown */
-                               /* this handles a previous NT_STATUS_SYNCHRONIZATION_REQUIRED
-                                * for disconnected mode */
-                               idmap_cache_map_id(idmap_cache, ids[i]);
+                               /* something bad here. We were not able to handle this for some
+                                * reason, mark it as unmapped and hope next time things will
+                                * settle down. */
+                               bids[i]->status = ID_UNMAPPED;
                        } else { /* unmapped */
                                ret = idmap_cache_set_negative_id(idmap_cache, bids[i]);
                        }
@@ -1270,13 +1315,6 @@ 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 ( lp_winbind_offline_logon() &&
-                    get_global_winbindd_state_offline() )
-               {
-                       ret = NT_STATUS_FILE_IS_OFFLINE;
-                       goto done;
-               }
                
                ret = idmap_backends_sids_to_unixids(bids);
                IDMAP_CHECK_RET(ret);
@@ -1285,12 +1323,18 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids)
                for (i = 0; bids[i]; i++) {
                        if (bids[i]->status == ID_MAPPED) {
                                ret = idmap_cache_set(idmap_cache, bids[i]);
+                       } else if (bids[i]->status == ID_EXPIRED) {
+                               /* the cache returned an expired entry and the backend was
+                                * was not able to clear the situation (offline).
+                                * This handles a previous NT_STATUS_SYNCHRONIZATION_REQUIRED
+                                * for disconnected mode, */
+                               bids[i]->status = ID_MAPPED;
                        } else if (bids[i]->status == ID_UNKNOWN) {
-                               /* return an expired entry in the cache or an unknown */
-                               /* this handles a previous NT_STATUS_SYNCHRONIZATION_REQUIRED
-                                * for disconnected mode */
-                               idmap_cache_map_id(idmap_cache, ids[i]);
-                       } else {
+                               /* something bad here. We were not able to handle this for some
+                                * reason, mark it as unmapped and hope next time things will
+                                * settle down. */
+                               bids[i]->status = ID_UNMAPPED;
+                       } else { /* unmapped */
                                ret = idmap_cache_set_negative_sid(idmap_cache, bids[i]);
                        }
                        IDMAP_CHECK_RET(ret);
@@ -1362,15 +1406,15 @@ void idmap_dump_maps(char *logfile)
                return;
        }
 
-       if ( alloc_methods ) {          
+       if (NT_STATUS_IS_OK(ret = idmap_alloc_init())) {                
                allid.type = ID_TYPE_UID;
                allid.id = 0;
-               alloc_methods->get_id_hwm(&allid);
+               idmap_alloc_ctx->methods->get_id_hwm(&allid);
                fprintf(dump, "USER HWM %lu\n", (unsigned long)allid.id);
                
                allid.type = ID_TYPE_GID;
                allid.id = 0;
-               alloc_methods->get_id_hwm(&allid);
+               idmap_alloc_ctx->methods->get_id_hwm(&allid);
                fprintf(dump, "GROUP HWM %lu\n", (unsigned long)allid.id);
        }
        
index 87f73f99f0965dd42691ebae743f8a1a7368c7bb..9daa0024ea3bd562ed6823cfda7a3a6e66e9d2bd 100644 (file)
@@ -160,7 +160,7 @@ static ADS_STRUCT *ad_idmap_cached_connection(void)
 /************************************************************************
  ***********************************************************************/
 
-static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom, const char *params)
+static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom)
 {
        struct idmap_ad_context *ctx;
        char *config_option;
@@ -204,6 +204,7 @@ static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom, const char *params
        }
 
        dom->private_data = ctx;
+       dom->initialized = True;
 
        talloc_free(config_option);
 
@@ -269,6 +270,19 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map
        char *u_filter = NULL;
        char *g_filter = NULL;
 
+       /* Only do query if we are online */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
+       /* Initilization my have been deferred because we were offline */
+       if ( ! dom->initialized) {
+               ret = idmap_ad_initialize(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
 
        if ( (memctx = talloc_new(ctx)) == NULL ) {
@@ -320,7 +334,7 @@ again:
                        break;
 
                default:
-                       DEBUG(3, ("Unknown ID type\n"));
+                       DEBUG(3, ("Error: mapping requested but Unknown ID type\n"));
                        ids[idx]->status = ID_UNKNOWN;
                        continue;
                }
@@ -441,9 +455,9 @@ again:
 
        ret = NT_STATUS_OK;
 
-       /* mark all unknown ones as unmapped */
+       /* mark all unknown/expired ones as unmapped */
        for (i = 0; ids[i]; i++) {
-               if (ids[i]->status == ID_UNKNOWN
+               if (ids[i]->status != ID_MAPPED
                        ids[i]->status = ID_UNMAPPED;
        }
 
@@ -476,6 +490,19 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map
        int i;
        char *sidstr;
 
+       /* Only do query if we are online */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
+       /* Initilization my have been deferred because we were offline */
+       if ( ! dom->initialized) {
+               ret = idmap_ad_initialize(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);      
 
        if ( (memctx = talloc_new(ctx)) == NULL ) {             
@@ -615,9 +642,9 @@ again:
 
        ret = NT_STATUS_OK;
 
-       /* mark all unknwon ones as unmapped */
+       /* mark all unknwoni/expired ones as unmapped */
        for (i = 0; ids[i]; i++) {
-               if (ids[i]->status == ID_UNKNOWN
+               if (ids[i]->status != ID_MAPPED
                        ids[i]->status = ID_UNMAPPED;
        }
 
@@ -669,7 +696,7 @@ static NTSTATUS nss_sfu_init( struct nss_domain_entry *e )
        ad_map_type =  WB_POSIX_MAP_SFU;        
 
        if ( !ad_idmap_ads ) 
-               return idmap_ad_initialize( NULL, NULL );       
+               return idmap_ad_initialize(NULL);
 
        return NT_STATUS_OK;
 }
@@ -690,7 +717,7 @@ static NTSTATUS nss_rfc2307_init( struct nss_domain_entry *e )
        ad_map_type =  WB_POSIX_MAP_RFC2307;
 
        if ( !ad_idmap_ads ) 
-               return idmap_ad_initialize( NULL, NULL );       
+               return idmap_ad_initialize(NULL);       
 
        return NT_STATUS_OK;
 }
index 6e5febf2ba881ce2ef1b497ec0d64e4b2b99ced7..d43dc63f4260c2ff3555712f83f26156f622886e 100644 (file)
@@ -348,7 +348,7 @@ BOOL idmap_cache_is_negative(const char *val)
 
 /* search the cahce for the SID an return a mapping if found *
  *
- * 3 cases are possible
+ * 4 cases are possible
  *
  * 1 map found
  *     in this case id->status = ID_MAPPED and NT_STATUS_OK is returned
@@ -356,17 +356,16 @@ BOOL idmap_cache_is_negative(const char *val)
  *     in this case id->status = ID_UNKNOWN and NT_STATUS_NONE_MAPPED is returned
  * 3 negative cache found
  *     in this case id->status = ID_UNMAPPED and NT_STATUS_OK is returned
- *
- * As a special case if the cache is expired NT_STATUS_SYNCHRONIZATION_REQUIRED
- * is returned instead of NT_STATUS_OK. In this case revalidation of the cache
- * is needed.
+ * 4 map found but timer expired
+ *      in this case id->status = ID_EXPIRED and NT_STATUS_SYNCHRONIZATION_REQUIRED
+ *      is returned. In this case revalidation of the cache is needed.
  */
 
 NTSTATUS idmap_cache_map_sid(struct idmap_cache_ctx *cache, struct id_map *id)
 {
        NTSTATUS ret;
        TDB_DATA databuf;
-       time_t t;
+       time_t t, now;
        char *sidkey;
        char *endptr;
 
@@ -393,11 +392,13 @@ 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) {
-               
+
                DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
-                          "timeout = %s", t > time(NULL) ? "valid" :
+                          "timeout = %s", t > now ? "valid" :
                           "expired", sidkey, endptr+1, ctime(&t)));
 
                /* this call if successful will also mark the entry as mapped */
@@ -411,35 +412,21 @@ 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 <= time(NULL)) {
-                       /* If we've been told to be offline - stay in 
-                          that state... */
-                       if (lp_winbind_offline_logon() && 
-                           get_global_winbindd_state_offline()) 
-                       {
-                               DEBUG(10,("idmap_cache_map_sid: winbindd is "
-                                         "globally offline.\n"));
-                       } else {
-                               /* We're expired, set an error code
-                                  for upper layer */
-                               ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
-                       }                       
+               if (t <= now) {
+       
+                       /* we have it, but it is expired */
+                       id->status = ID_EXPIRED;
+                               
+                       /* We're expired, set an error code
+                          for upper layer */
+                       ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
                }
        } else {
-               if (t <= time(NULL)) {
-                       /* If we've been told to be offline - stay in 
-                          that state... */
-                       if (lp_winbind_offline_logon() && 
-                           get_global_winbindd_state_offline()) 
-                       {
-                               DEBUG(10,("idmap_cache_map_sid: winbindd is "
-                                         "globally offline.\n"));
-                       } else {                                
-                               /* We're expired, delete the entry and return
-                                  not mapped */
-                               tdb_delete_bystring(cache->tdb, sidkey);
-                               ret = NT_STATUS_NONE_MAPPED;
-                       }                       
+               if (t <= now) {
+                       /* We're expired, delete the NEGATIVE entry and return
+                          not mapped */
+                       tdb_delete_bystring(cache->tdb, sidkey);
+                       ret = NT_STATUS_NONE_MAPPED;
                } else {
                        /* this is not mapped as it was a negative cache hit */
                        id->status = ID_UNMAPPED;
@@ -455,7 +442,7 @@ done:
 
 /* search the cahce for the ID an return a mapping if found *
  *
- * 3 cases are possible
+ * 4 cases are possible
  *
  * 1 map found
  *     in this case id->status = ID_MAPPED and NT_STATUS_OK is returned
@@ -463,21 +450,20 @@ done:
  *     in this case id->status = ID_UNKNOWN and NT_STATUS_NONE_MAPPED is returned
  * 3 negative cache found
  *     in this case id->status = ID_UNMAPPED and NT_STATUS_OK is returned
- *
- * As a special case if the cache is expired NT_STATUS_SYNCHRONIZATION_REQUIRED
- * is returned instead of NT_STATUS_OK. In this case revalidation of the cache
- * is needed.
+ * 4 map found but timer expired
+ *      in this case id->status = ID_EXPIRED and NT_STATUS_SYNCHRONIZATION_REQUIRED
+ *      is returned. In this case revalidation of the cache is needed.
  */
 
 NTSTATUS idmap_cache_map_id(struct idmap_cache_ctx *cache, struct id_map *id)
 {
        NTSTATUS ret;
        TDB_DATA databuf;
-       time_t t;
+       time_t t, now;
        char *idkey;
        char *endptr;
 
-       /* make sure it is marked as not mapped by default */
+       /* make sure it is marked as unknown by default */
        id->status = ID_UNKNOWN;
        
        ret = idmap_cache_build_idkey(cache, &idkey, id);
@@ -500,11 +486,13 @@ 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) {
                
                DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
-                          "timeout = %s", t > time(NULL) ? "valid" :
+                          "timeout = %s", t > now ? "valid" :
                           "expired", idkey, endptr+1, ctime(&t)));
 
                /* this call if successful will also mark the entry as mapped */
@@ -516,39 +504,25 @@ NTSTATUS idmap_cache_map_id(struct idmap_cache_ctx *cache, struct id_map *id)
                        goto done;
                }
 
-               /* here ret == NT_STATUS_OK and id->mapped = True */
-
-               if (t <= time(NULL)) {
-                       /* If we've been told to be offline - stay in
-                          that state... */
-                       if (lp_winbind_offline_logon() && 
-                           get_global_winbindd_state_offline()) 
-                       {
-                               DEBUG(10,("idmap_cache_map_sid: winbindd is "
-                                         "globally offline.\n"));
-                       } else {
-                               /* We're expired, set an error code
-                                  for upper layer */
-                               ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
-                       }                       
+               /* here ret == NT_STATUS_OK and id->mapped = ID_MAPPED */
+
+               if (t <= now) {
+
+                       /* we have it, but it is expired */
+                       id->status = ID_EXPIRED;
+
+                       /* We're expired, set an error code
+                          for upper layer */
+                       ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
                }
        } else {
-               if (t <= time(NULL)) {
-                       /* If we've been told to be offline - stay in
-                          that state... */
-                       if (lp_winbind_offline_logon() && 
-                           get_global_winbindd_state_offline()) 
-                       {
-                               DEBUG(10,("idmap_cache_map_sid: winbindd is "
-                                         "globally offline.\n"));
-                       } else {
-                               /* We're expired, delete the entry and
-                                  return not mapped */
-                               tdb_delete_bystring(cache->tdb, idkey);
-                               ret = NT_STATUS_NONE_MAPPED;
-                       }                       
+               if (t <= now) {
+                       /* We're expired, delete the NEGATIVE entry and return
+                          not mapped */
+                       tdb_delete_bystring(cache->tdb, idkey);
+                       ret = NT_STATUS_NONE_MAPPED;
                } else {
-                       /* this is not mapped is it was a negative cache hit */
+                       /* this is not mapped as it was a negative cache hit */
                        id->status = ID_UNMAPPED;
                        ret = NT_STATUS_OK;
                }
index d6261f407befc6a40ff3e94b29cb7073e0384d20..7575416af5e3a631d2fc8ee7eaacc369d2f9f626 100644 (file)
@@ -152,6 +152,7 @@ static NTSTATUS verify_idpool(void)
                                &result);
 
        if (rc != LDAP_SUCCESS) {
+               DEBUG(1, ("Unable to verify the idpool, cannot continue initialization!\n"));
                return NT_STATUS_UNSUCCESSFUL;
        }
 
@@ -210,6 +211,11 @@ static NTSTATUS idmap_ldap_alloc_init(const char *params)
        gid_t low_gid = 0;
        gid_t high_gid = 0;
 
+       /* Only do init if we are online */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
        idmap_alloc_ldap = talloc_zero(NULL, struct idmap_ldap_alloc_context);
         CHECK_ALLOC_DONE( idmap_alloc_ldap );
        
@@ -346,6 +352,11 @@ static NTSTATUS idmap_ldap_allocate_id(struct unixid *xid)
        const char **attr_list;
        const char *type;
 
+       /* Only do query if we are online */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
        if ( ! idmap_alloc_ldap) {
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -492,6 +503,11 @@ static NTSTATUS idmap_ldap_get_hwm(struct unixid *xid)
        const char **attr_list;
        const char *type;
 
+       /* Only do query if we are online */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
        if ( ! idmap_alloc_ldap) {
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -582,6 +598,11 @@ static NTSTATUS idmap_ldap_set_hwm(struct unixid *xid)
        const char **attr_list;
        const char *type;
 
+       /* Only do query if we are online */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
        if ( ! idmap_alloc_ldap) {
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -702,14 +723,19 @@ static int idmap_ldap_close_destructor(struct idmap_ldap_context *ctx)
  Initialise idmap database. 
 ********************************/
 
-static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom, const char *params)
+static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
 {
        NTSTATUS ret;
        struct idmap_ldap_context *ctx = NULL;
        char *config_option = NULL;
        const char *range = NULL;
        const char *tmp = NULL;
-       
+
+       /* Only do init if we are online */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
        ctx = talloc_zero(dom, struct idmap_ldap_context);
        if ( ! ctx) {
                DEBUG(0, ("Out of memory!\n"));
@@ -734,9 +760,9 @@ static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom, const char *params)
                }
        }
 
-       if (params && *params) {
+       if (dom->params && *(dom->params)) {
                /* assume location is the only parameter */
-               ctx->url = talloc_strdup(ctx, params);
+               ctx->url = talloc_strdup(ctx, dom->params);
        } else {
                tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
 
@@ -840,6 +866,19 @@ static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom, struct id_m
        int rc;
        int i;
 
+       /* Only do query if we are online */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
+       /* Initilization my have been deferred because we were offline */
+       if ( ! dom->initialized) {
+               ret = idmap_ldap_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);    
 
        memctx = talloc_new(ctx);
@@ -994,10 +1033,10 @@ again:
 
        ret = NT_STATUS_OK;
 
-
-       /* mark all unknwon ones as unmapped */
+       /* mark all unknwon/expired ones as unmapped */
        for (i = 0; ids[i]; i++) {
-               if (ids[i]->status == ID_UNKNOWN) ids[i]->status = ID_UNMAPPED;
+               if (ids[i]->status != ID_MAPPED)
+                       ids[i]->status = ID_UNMAPPED;
        }
 
 done:
@@ -1044,6 +1083,19 @@ static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom, struct id_m
        int rc;
        int i;
 
+       /* Only do query if we are online */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
+       /* Initilization my have been deferred because we were offline */
+       if ( ! dom->initialized) {
+               ret = idmap_ldap_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);    
 
        memctx = talloc_new(ctx);
@@ -1195,9 +1247,10 @@ again:
 
        ret = NT_STATUS_OK;
 
-       /* mark all unknwon ones as unmapped */
+       /* mark all unknwon/expired ones as unmapped */
        for (i = 0; ids[i]; i++) {
-               if (ids[i]->status == ID_UNKNOWN) ids[i]->status = ID_UNMAPPED;
+               if (ids[i]->status != ID_MAPPED)
+                       ids[i]->status = ID_UNMAPPED;
        }
 
 done:
@@ -1224,6 +1277,19 @@ static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom, const struct id
        char *dn;
        int rc = -1;
 
+       /* Only do query if we are online */
+       if (idmap_is_offline()) {
+               return NT_STATUS_FILE_IS_OFFLINE;
+       }
+
+       /* Initilization my have been deferred because we were offline */
+       if ( ! dom->initialized) {
+               ret = idmap_ldap_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);    
 
        switch(map->xid.type) {
@@ -1303,15 +1369,6 @@ done:
        return ret;
 }
 
-/**********************************
- remove a mapping. 
-**********************************/
-
-static NTSTATUS idmap_ldap_remove_mapping(struct idmap_domain *dom, const struct id_map *map)
-{
-       return NT_STATUS_UNSUCCESSFUL;
-}
-
 /**********************************
  Close the idmap ldap instance 
 **********************************/
@@ -1336,8 +1393,6 @@ static struct idmap_methods idmap_ldap_methods = {
        .unixids_to_sids = idmap_ldap_unixids_to_sids,
        .sids_to_unixids = idmap_ldap_sids_to_unixids,
        .set_mapping = idmap_ldap_set_mapping,
-       .remove_mapping = idmap_ldap_remove_mapping,
-       /* .dump_data = TODO */
        .close_fn = idmap_ldap_close
 };
 
index 3cd8a8e8eae223037175472f0168788a4fad86c5..e3e425f105f4e5e14fe03f2dc43e4a20f32aab7e 100644 (file)
@@ -30,8 +30,9 @@
  Initialise idmap database. 
 *****************************/
 
-static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom, const char *compat_params)
+static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom)
 {      
+       dom->initialized = True;
        return NT_STATUS_OK;
 }
 
index a5f8a084b3a176c0a44c6e122c24cc1539367d22..665ead5bb104737918539bf891e788b49c1ec13d 100644 (file)
@@ -29,8 +29,9 @@
  Initialise idmap database. 
 *****************************/
 
-static NTSTATUS idmap_pdb_init(struct idmap_domain *dom, const char *compat_params)
+static NTSTATUS idmap_pdb_init(struct idmap_domain *dom)
 {      
+       dom->initialized = True;
        return NT_STATUS_OK;
 }
 
index 73db1def0ce844571cd053ed43bda002c55cd98e..4eb47c42b84fb3ea11a26e3f5cd8dbe9155744f6 100644 (file)
@@ -586,7 +586,7 @@ struct idmap_tdb_context {
  Initialise idmap database. 
 *****************************/
 
-static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *compat_params)
+static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom)
 {
        NTSTATUS ret;
        struct idmap_tdb_context *ctx;
@@ -620,6 +620,7 @@ static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *compat_p
        }
 
        dom->private_data = ctx;
+       dom->initialized = True;
 
        talloc_free(config_option);
        return NT_STATUS_OK;
@@ -772,6 +773,14 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
        NTSTATUS ret;
        int i;
 
+       /* make sure we initialized */
+       if ( ! dom->initialized) {
+               ret = idmap_tdb_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
 
        for (i = 0; ids[i]; i++) {
@@ -810,6 +819,14 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
        NTSTATUS ret;
        int i;
 
+       /* make sure we initialized */
+       if ( ! dom->initialized) {
+               ret = idmap_tdb_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
 
        for (i = 0; ids[i]; i++) {
@@ -849,6 +866,14 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
        TDB_DATA ksid, kid, data;
        char *ksidstr, *kidstr;
 
+       /* make sure we initialized */
+       if ( ! dom->initialized) {
+               ret = idmap_tdb_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        if (!map || !map->sid) {
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -954,6 +979,14 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
        TDB_DATA ksid, kid, data;
        char *ksidstr, *kidstr;
 
+       /* make sure we initialized */
+       if ( ! dom->initialized) {
+               ret = idmap_tdb_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        if (!map || !map->sid) {
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -1133,6 +1166,14 @@ static NTSTATUS idmap_tdb_dump_data(struct idmap_domain *dom, struct id_map **ma
        struct dump_data *data;
        NTSTATUS ret = NT_STATUS_OK;
 
+       /* make sure we initialized */
+       if ( ! dom->initialized) {
+               ret = idmap_tdb_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
 
        data = talloc_zero(ctx, struct dump_data);