r21784: Replace smb_register_idle_event() with event_add_timed(). This fixes winbind
authorVolker Lendecke <vlendec@samba.org>
Sun, 11 Mar 2007 16:49:16 +0000 (16:49 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:18:33 +0000 (12:18 -0500)
who did not run the idle events to drop ldap connections.

Volker

14 files changed:
source/include/smbldap.h
source/lib/module.c
source/lib/smbldap.c
source/nsswitch/idmap_ldap.c
source/passdb/pdb_interface.c
source/passdb/pdb_ldap.c
source/rpc_server/srv_samr_nt.c
source/smbd/process.c
source/smbd/server.c
source/utils/net.c
source/utils/net_sam.c
source/utils/pdbedit.c
source/utils/smbpasswd.c
source/web/swat.c

index 390b8f681a4a62dcb785a4a5c10113452b9be7ca..67061fec86d0f4d017be1a8a63306b758b670951 100644 (file)
@@ -128,6 +128,7 @@ extern ATTRIB_MAP_ENTRY trustpw_attr_list[];
    have to worry about LDAP structure types */
 
 NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx,
+                     struct event_context *event_ctx,
                       const char *location,
                       struct smbldap_state **smbldap_state);
 
@@ -169,7 +170,8 @@ struct smbldap_state {
        unsigned int num_failures;
 
        time_t last_use;
-       smb_event_id_t event_id;
+       struct event_context *event_context;
+       struct timed_event *idle_event;
 
        struct timeval last_rebind;
 };
index 092a68cd680d330ede95faf07fff8c58736739bb..96a37ae6b55be11e395e941640164e17a7dde704 100644 (file)
@@ -150,88 +150,3 @@ void init_modules(void)
        if(lp_preload_modules()) 
                smb_load_modules(lp_preload_modules());
 }
-
-
-/***************************************************************************
- * This Function registers a idle event
- *
- * the registered funtions are run periodically
- * and maybe shutdown idle connections (e.g. to an LDAP server)
- ***************************************************************************/
-static smb_event_id_t smb_idle_event_id = 1;
-
-struct smb_idle_list_ent {
-       struct smb_idle_list_ent *prev,*next;
-       smb_event_id_t id;
-       smb_idle_event_fn *fn;
-       void *data;
-       time_t interval;
-       time_t lastrun;
-};
-
-static struct smb_idle_list_ent *smb_idle_event_list = NULL;
-
-smb_event_id_t smb_register_idle_event(smb_idle_event_fn *fn, void *data, time_t interval)
-{
-       struct smb_idle_list_ent *event;
-
-       if (!fn) {      
-               return SMB_EVENT_ID_INVALID;
-       }
-
-       event = SMB_MALLOC_P(struct smb_idle_list_ent);
-       if (!event) {
-               DEBUG(0,("malloc() failed!\n"));
-               return SMB_EVENT_ID_INVALID;
-       }
-       event->fn = fn;
-       event->data = data;
-       event->interval = interval;
-       event->lastrun = 0;
-       event->id = smb_idle_event_id++;
-
-       DLIST_ADD(smb_idle_event_list,event);
-
-       return event->id;
-}
-
-BOOL smb_unregister_idle_event(smb_event_id_t id)
-{
-       struct smb_idle_list_ent *event = smb_idle_event_list;
-       
-       while(event) {
-               if (event->id == id) {
-                       DLIST_REMOVE(smb_idle_event_list,event);
-                       SAFE_FREE(event);
-                       return True;
-               }
-               event = event->next;
-       }
-       
-       return False;
-}
-
-void smb_run_idle_events(time_t now)
-{
-       struct smb_idle_list_ent *event = smb_idle_event_list;
-
-       while (event) {
-               struct smb_idle_list_ent *next = event->next;
-               time_t interval;
-
-               if (event->interval <= 0) {
-                       interval = SMB_IDLE_EVENT_DEFAULT_INTERVAL;
-               } else if (event->interval >= SMB_IDLE_EVENT_MIN_INTERVAL) {
-                       interval = event->interval;
-               } else {
-                       interval = SMB_IDLE_EVENT_MIN_INTERVAL;
-               }
-               if (now >(event->lastrun+interval)) {
-                       event->lastrun = now;
-                       event->fn(&event->data,&event->interval,now);
-               }
-               event = next;
-       }
-
-       return;
-}
index c102c2185f5d585c1c8649ccbcfc4c368de9c9fd..5b9ec1d55bb0751f61ad61cab0566a31cb8fafb7 100644 (file)
@@ -999,6 +999,11 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
        return rc;
 }
 
+static void smbldap_idle_fn(struct event_context *event_ctx,
+                           struct timed_event *te,
+                           const struct timeval *now,
+                           void *private_data);
+
 /**********************************************************************
  Connect to LDAP server (called before every ldap operation)
 *********************************************************************/
@@ -1061,6 +1066,16 @@ static int smbldap_open(struct smbldap_state *ldap_state)
 
        ldap_state->last_ping = time(NULL);
        ldap_state->pid = sys_getpid();
+
+       TALLOC_FREE(ldap_state->idle_event);
+
+       if (ldap_state->event_context != NULL) {
+               ldap_state->idle_event = event_add_timed(
+                       ldap_state->event_context, NULL,
+                       timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
+                       "smbldap_idle_fn", smbldap_idle_fn, ldap_state);
+       }
+
        DEBUG(4,("The LDAP server is succesfully connected\n"));
 
        return LDAP_SUCCESS;
@@ -1545,17 +1560,28 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state,
                              filter, search_attr, 0, result);
 }
 
-static void smbldap_idle_fn(void **data, time_t *interval, time_t now)
+static void smbldap_idle_fn(struct event_context *event_ctx,
+                           struct timed_event *te,
+                           const struct timeval *now,
+                           void *private_data)
 {
-       struct smbldap_state *state = (struct smbldap_state *)(*data);
+       struct smbldap_state *state = (struct smbldap_state *)private_data;
+
+       TALLOC_FREE(state->idle_event);
 
        if (state->ldap_struct == NULL) {
                DEBUG(10,("ldap connection not connected...\n"));
                return;
        }
                
-       if ((state->last_use+SMBLDAP_IDLE_TIME) > now) {
+       if ((state->last_use+SMBLDAP_IDLE_TIME) > now->tv_sec) {
                DEBUG(10,("ldap connection not idle...\n"));
+
+               state->idle_event = event_add_timed(
+                       event_ctx, NULL,
+                       timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
+                       "smbldap_idle_fn", smbldap_idle_fn,
+                       private_data);
                return;
        }
                
@@ -1578,7 +1604,7 @@ void smbldap_free_struct(struct smbldap_state **ldap_state)
        SAFE_FREE((*ldap_state)->bind_dn);
        SAFE_FREE((*ldap_state)->bind_secret);
 
-       smb_unregister_idle_event((*ldap_state)->event_id);
+       TALLOC_FREE((*ldap_state)->idle_event);
 
        *ldap_state = NULL;
 
@@ -1590,7 +1616,9 @@ void smbldap_free_struct(struct smbldap_state **ldap_state)
  Intitalise the 'general' ldap structures, on which ldap operations may be conducted
  *********************************************************************/
 
-NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_state **smbldap_state) 
+NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx,
+                     const char *location,
+                     struct smbldap_state **smbldap_state)
 {
        *smbldap_state = TALLOC_ZERO_P(mem_ctx, struct smbldap_state);
        if (!*smbldap_state) {
@@ -1604,14 +1632,7 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_
                (*smbldap_state)->uri = "ldap://localhost";
        }
 
-       (*smbldap_state)->event_id =
-               smb_register_idle_event(smbldap_idle_fn, (void *)(*smbldap_state),
-                                       SMBLDAP_IDLE_TIME);
-
-       if ((*smbldap_state)->event_id == SMB_EVENT_ID_INVALID) {
-               DEBUG(0,("Failed to register LDAP idle event!\n"));
-               return NT_STATUS_INVALID_HANDLE;
-       }
+       (*smbldap_state)->event_context = event_ctx;
 
        return NT_STATUS_OK;
 }
index f74372eceab660a3b25bae75fe500885c8c0c777..15f88d28c7343150e486a6d1d14eef75abe38809 100644 (file)
@@ -24,6 +24,7 @@
 */
 
 #include "includes.h"
+#include "winbindd.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
@@ -295,8 +296,9 @@ static NTSTATUS idmap_ldap_alloc_init(const char *params)
        idmap_alloc_ldap->suffix = talloc_strdup(idmap_alloc_ldap, tmp);
        CHECK_ALLOC_DONE( idmap_alloc_ldap->suffix );
        
-       ret = smbldap_init(idmap_alloc_ldap, idmap_alloc_ldap->url,
-                                &idmap_alloc_ldap->smbldap_state);     
+       ret = smbldap_init(idmap_alloc_ldap, winbind_event_context(),
+                          idmap_alloc_ldap->url,
+                          &idmap_alloc_ldap->smbldap_state);   
        if (!NT_STATUS_IS_OK(ret)) { 
                DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", 
                          idmap_alloc_ldap->url));
@@ -766,7 +768,8 @@ static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom, const char *params)
        ctx->suffix = talloc_strdup(ctx, tmp);
        CHECK_ALLOC_DONE(ctx->suffix);
 
-       ret = smbldap_init(ctx, ctx->url, &ctx->smbldap_state);
+       ret = smbldap_init(ctx, winbind_event_context(), ctx->url,
+                          &ctx->smbldap_state);
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url));
                goto done;
index ce8b46eb0f3a36755d850559f9bf1df11c20478b..976dfc1d081b6fb4ff49f34e8aa8f05a8422d180 100644 (file)
@@ -94,6 +94,23 @@ struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
        return NULL;
 }
 
+/*
+ * The event context for the passdb backend. I know this is a bad hack and yet
+ * another static variable, but our pdb API is a global thing per
+ * definition. The first use for this is the LDAP idle function, more might be
+ * added later.
+ *
+ * I don't feel too bad about this static variable, it replaces the
+ * smb_idle_event_list that used to exist in lib/module.c.  -- VL
+ */
+
+static struct event_context *pdb_event_ctx;
+
+struct event_context *pdb_get_event_context(void)
+{
+       return pdb_event_ctx;
+}
+
 /******************************************************************
   Make a pdb_methods from scratch
  *******************************************************************/
@@ -1116,8 +1133,9 @@ BOOL pdb_new_rid(uint32 *rid)
   If uninitialised, context will auto-init on first use.
  ***************************************************************/
 
-BOOL initialize_password_db(BOOL reload)
-{      
+BOOL initialize_password_db(BOOL reload, struct event_context *event_ctx)
+{
+       pdb_event_ctx = event_ctx;
        return (pdb_get_methods_reload(reload) != NULL);
 }
 
index c4c53c306649343625be59d7a73ff6fea35bf1a4..7765eb3c201e6ec96fdbce6a5d997537325b4476 100644 (file)
@@ -5539,7 +5539,8 @@ static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const c
                return NT_STATUS_NO_MEMORY;
        }
 
-       nt_status = smbldap_init(*pdb_method, location, &ldap_state->smbldap_state);
+       nt_status = smbldap_init(*pdb_method, pdb_get_event_context(),
+                                location, &ldap_state->smbldap_state);
 
        if ( !NT_STATUS_IS_OK(nt_status) ) {
                return nt_status;
index 56f2344247751ad307c63105ff459d4c1e9d7706..ca7185f527bcb8331b59b5b6256eb47b94ec49c0 100644 (file)
@@ -56,8 +56,8 @@ typedef struct disp_info {
        uint16 enum_acb_mask;
        struct pdb_search *enum_users; /* enumusers with a mask */
 
-
-       smb_event_id_t di_cache_timeout_event; /* cache idle timeout handler. */
+       struct timed_event *cache_timeout_event; /* cache idle timeout
+                                                 * handler. */
 } DISP_INFO;
 
 /* We keep a static list of these by SID as modern clients close down
@@ -345,9 +345,10 @@ static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
  Function to free the per SID data.
  ********************************************************************/
 
-static void free_samr_cache(DISP_INFO *disp_info, const char *sid_str)
+static void free_samr_cache(DISP_INFO *disp_info)
 {
-       DEBUG(10,("free_samr_cache: deleting cache for SID %s\n", sid_str));
+       DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
+                  sid_string_static(&disp_info->sid)));
 
        /* We need to become root here because the paged search might have to
         * tell the LDAP server we're not interested in the rest anymore. */
@@ -395,10 +396,8 @@ static void free_samr_info(void *ptr)
        /* Only free the dispinfo cache if no one bothered to set up
           a timeout. */
 
-       if (info->disp_info && info->disp_info->di_cache_timeout_event == (smb_event_id_t)0) {
-               fstring sid_str;
-               sid_to_string(sid_str, &info->disp_info->sid);
-               free_samr_cache(info->disp_info, sid_str);
+       if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
+               free_samr_cache(info->disp_info);
        }
 
        talloc_destroy(info->mem_ctx);
@@ -408,23 +407,18 @@ static void free_samr_info(void *ptr)
  Idle event handler. Throw away the disp info cache.
  ********************************************************************/
 
-static void disp_info_cache_idle_timeout_handler(void **private_data,
-                                       time_t *ev_interval,
-                                       time_t ev_now)
+static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
+                                                struct timed_event *te,
+                                                const struct timeval *now,
+                                                void *private_data)
 {
-       fstring sid_str;
-       DISP_INFO *disp_info = (DISP_INFO *)(*private_data);
-
-       sid_to_string(sid_str, &disp_info->sid);
+       DISP_INFO *disp_info = (DISP_INFO *)private_data;
 
-       free_samr_cache(disp_info, sid_str);
+       TALLOC_FREE(disp_info->cache_timeout_event);
 
-       /* Remove the event. */
-       smb_unregister_idle_event(disp_info->di_cache_timeout_event);
-       disp_info->di_cache_timeout_event = (smb_event_id_t)0;
-
-       DEBUG(10,("disp_info_cache_idle_timeout_handler: caching timed out for SID %s at %u\n",
-               sid_str, (unsigned int)ev_now));
+       DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
+                  "out\n"));
+       free_samr_cache(disp_info);
 }
 
 /*******************************************************************
@@ -433,24 +427,20 @@ static void disp_info_cache_idle_timeout_handler(void **private_data,
 
 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
 {
-       fstring sid_str;
-
-       sid_to_string(sid_str, &disp_info->sid);
-
        /* Remove any pending timeout and update. */
 
-       if (disp_info->di_cache_timeout_event) {
-               smb_unregister_idle_event(disp_info->di_cache_timeout_event);
-               disp_info->di_cache_timeout_event = (smb_event_id_t)0;
-       }
+       TALLOC_FREE(disp_info->cache_timeout_event);
 
-       DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for SID %s for %u seconds\n",
-               sid_str, (unsigned int)secs_fromnow ));
+       DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
+                 "SID %s for %u seconds\n",
+                 sid_string_static(&disp_info->sid),
+                 (unsigned int)secs_fromnow ));
 
-       disp_info->di_cache_timeout_event =
-               smb_register_idle_event(disp_info_cache_idle_timeout_handler,
-                                       disp_info,
-                                       secs_fromnow);
+       disp_info->cache_timeout_event = event_add_timed(
+               smbd_event_context(), NULL,
+               timeval_current_ofs(secs_fromnow, 0),
+               "disp_info_cache_idle_timeout_handler",
+               disp_info_cache_idle_timeout_handler, (void *)disp_info);
 }
 
 /*******************************************************************
@@ -460,18 +450,13 @@ static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromno
 
 static void force_flush_samr_cache(DISP_INFO *disp_info)
 {
-       if (disp_info) {
-               fstring sid_str;
-
-               sid_to_string(sid_str, &disp_info->sid);
-               if (disp_info->di_cache_timeout_event) {
-                       smb_unregister_idle_event(disp_info->di_cache_timeout_event);
-                       disp_info->di_cache_timeout_event = (smb_event_id_t)0;
-                       DEBUG(10,("force_flush_samr_cache: clearing idle event for SID %s\n",
-                               sid_str));
-               }
-               free_samr_cache(disp_info, sid_str);
+       if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
+               return;
        }
+
+       DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
+       TALLOC_FREE(disp_info->cache_timeout_event);
+       free_samr_cache(disp_info);
 }
 
 /*******************************************************************
index dbac553aea3d8798ee025d9f60023f6993d4cf3e..11ef33679f36479f224dac541911633c3c3af9c1 100644 (file)
@@ -1351,9 +1351,6 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
        /* become root again if waiting */
        change_to_root_user();
 
-       /* run all registered idle events */
-       smb_run_idle_events(t);
-
        /* check if we need to reload services */
        check_reload(t);
 
index ab32d656d38ebba32ec6463f7c7353142745a251..0ae2f3e836f09bd087d14a59b9af533660f20537 100644 (file)
@@ -1010,7 +1010,7 @@ extern void build_options(BOOL screen);
        /* Initialise the password backed before the global_sam_sid
           to ensure that we fetch from ldap before we make a domain sid up */
 
-       if(!initialize_password_db(False))
+       if(!initialize_password_db(False, smbd_event_context()))
                exit(1);
 
        if (!secrets_init()) {
index 068af2626f884d6f7a5ccddf4489e8dd9fde54a3..5a9b7d31ec5617992caa8163e28b4d3a8325cbb0 100644 (file)
@@ -602,7 +602,7 @@ static int net_getlocalsid(int argc, const char **argv)
                name = global_myname();
        }
 
-       if(!initialize_password_db(False)) {
+       if(!initialize_password_db(False, NULL)) {
                DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n"
                          "backend knowlege (such as the sid stored in LDAP)\n"));
        }
@@ -672,7 +672,7 @@ static int net_getdomainsid(int argc, const char **argv)
        DOM_SID domain_sid;
        fstring sid_str;
 
-       if(!initialize_password_db(False)) {
+       if(!initialize_password_db(False, NULL)) {
                DEBUG(0, ("WARNING: Could not open passdb - domain sid may not reflect passdb\n"
                          "backend knowlege (such as the sid stored in LDAP)\n"));
        }
index bf397803bc544a6432ae4a469af5e8db892a8e46..3b7d604dc628766f0a31cee057204f8030841b61 100644 (file)
@@ -990,7 +990,7 @@ static int net_sam_provision(int argc, const char **argv)
                goto failed;
        }
 
-       if (!NT_STATUS_IS_OK(smbldap_init(tc, ldap_uri, &ls))) {
+       if (!NT_STATUS_IS_OK(smbldap_init(tc, NULL, ldap_uri, &ls))) {
                d_fprintf(stderr, "Unable to connect to the LDAP server.\n");
                goto failed;
        }
index d1a87260fa90003cd9228073c76eab0eec7e78e3..0e8de82043c9793ba2e93d800fdbdcc05c590afb 100644 (file)
@@ -831,7 +831,7 @@ int main (int argc, char **argv)
                exit(1);
        }
 
-       if(!initialize_password_db(False))
+       if(!initialize_password_db(False, NULL))
                exit(1);
 
        if (!init_names())
index da9ac8d279d3acd43b8ec05ea454dda5ab8376e1..e7bd0e5faeeecf3e15537492f09bbd8588860f49 100644 (file)
@@ -305,7 +305,7 @@ static int process_root(int local_flags)
        }
 
        /* Ensure passdb startup(). */
-       if(!initialize_password_db(False)) {
+       if(!initialize_password_db(False, NULL)) {
                DEBUG(0, ("Failed to open passdb!\n"));
                exit(1);
        }
index d43f8941bc14d2c39ddaeb5764c3031bb9aee3a7..e30c6d35f92f9cde745694ce1f6d65a36a103606 100644 (file)
@@ -1003,7 +1003,7 @@ static BOOL change_password(const char *remote_machine, const char *user_name,
                return NT_STATUS_IS_OK(ret);
        }
 
-       if(!initialize_password_db(True)) {
+       if(!initialize_password_db(True, NULL)) {
                printf("%s\n<p>", _("Can't setup password database vectors."));
                return False;
        }