diff options
author | Volker Lendecke <vlendec@samba.org> | 2007-03-11 16:49:16 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:18:33 -0500 |
commit | 0d91334fe799f6b50a8265f9dc097411c3a29e18 (patch) | |
tree | c86395688b41edd01055a2a75ac0ba7f6113ad18 | |
parent | 5214cb6782b1ac01b4b23d53478fa11ad00915fe (diff) | |
download | samba-0d91334fe799f6b50a8265f9dc097411c3a29e18.tar.gz samba-0d91334fe799f6b50a8265f9dc097411c3a29e18.tar.bz2 samba-0d91334fe799f6b50a8265f9dc097411c3a29e18.zip |
r21784: Replace smb_register_idle_event() with event_add_timed(). This fixes winbind
who did not run the idle events to drop ldap connections.
Volker
(This used to be commit af3308ce5a21220ff4c510de356dbaa6cf9ff997)
-rw-r--r-- | source3/include/smbldap.h | 4 | ||||
-rw-r--r-- | source3/lib/module.c | 85 | ||||
-rw-r--r-- | source3/lib/smbldap.c | 47 | ||||
-rw-r--r-- | source3/nsswitch/idmap_ldap.c | 9 | ||||
-rw-r--r-- | source3/passdb/pdb_interface.c | 22 | ||||
-rw-r--r-- | source3/passdb/pdb_ldap.c | 3 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 79 | ||||
-rw-r--r-- | source3/smbd/process.c | 3 | ||||
-rw-r--r-- | source3/smbd/server.c | 2 | ||||
-rw-r--r-- | source3/utils/net.c | 4 | ||||
-rw-r--r-- | source3/utils/net_sam.c | 2 | ||||
-rw-r--r-- | source3/utils/pdbedit.c | 2 | ||||
-rw-r--r-- | source3/utils/smbpasswd.c | 2 | ||||
-rw-r--r-- | source3/web/swat.c | 2 |
14 files changed, 104 insertions, 162 deletions
diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 390b8f681a..67061fec86 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -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; }; diff --git a/source3/lib/module.c b/source3/lib/module.c index 092a68cd68..96a37ae6b5 100644 --- a/source3/lib/module.c +++ b/source3/lib/module.c @@ -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; -} diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index c102c2185f..5b9ec1d55b 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -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; } diff --git a/source3/nsswitch/idmap_ldap.c b/source3/nsswitch/idmap_ldap.c index f74372ecea..15f88d28c7 100644 --- a/source3/nsswitch/idmap_ldap.c +++ b/source3/nsswitch/idmap_ldap.c @@ -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; diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index ce8b46eb0f..976dfc1d08 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -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); } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index c4c53c3066..7765eb3c20 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -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; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 56f2344247..ca7185f527 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -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); } /******************************************************************* diff --git a/source3/smbd/process.c b/source3/smbd/process.c index dbac553aea..11ef33679f 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -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); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index ab32d656d3..0ae2f3e836 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -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()) { diff --git a/source3/utils/net.c b/source3/utils/net.c index 068af2626f..5a9b7d31ec 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -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")); } diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c index bf397803bc..3b7d604dc6 100644 --- a/source3/utils/net_sam.c +++ b/source3/utils/net_sam.c @@ -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; } diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index d1a87260fa..0e8de82043 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -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()) diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index da9ac8d279..e7bd0e5fae 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -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); } diff --git a/source3/web/swat.c b/source3/web/swat.c index d43f8941bc..e30c6d35f9 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -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; } |