diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 937f68d..e6fb0fa 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -1216,6 +1216,12 @@ static void winbindd_register_handlers(struct messaging_context *msg_ctx, } } + if (tevent_add_timer(winbind_event_context(), NULL, + timeval_current_ofs(3*60,0), + cleanup_idle_winbindd_child, NULL) == NULL) { + DEBUG(0, ("Could not trigger cleanup_idle_winbindd_child()\n")); + } + } struct winbindd_addrchanged_state { diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 33a7082..e5b4d58 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -394,6 +394,8 @@ struct winbindd_domain *domain_list(void); bool domain_is_forest_root(const struct winbindd_domain *domain); void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te, struct timeval now, void *private_data); +void cleanup_idle_winbindd_child(struct tevent_context *ev, struct tevent_timer *te, + struct timeval now, void *private_data); enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain, struct winbindd_cli_state *state); bool init_domain_list(void); diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index a00fe14..a05a3b9 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -563,6 +563,48 @@ void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te, return; } +void cleanup_idle_winbindd_child(struct tevent_context *ev, struct tevent_timer *te, + struct timeval now, void *private_data) + +{ + struct winbindd_domain *domain; + int i=0; + + TALLOC_FREE(te); + + for (domain = domain_list(); domain != NULL; domain = domain->next) { + for (i=0; ichildren[i]; + + if (!child || ((child->pid) <= 1) || (child->domain==NULL) || + (child->domain->startup == True)) { + + continue; + } + if (tevent_queue_length(child->queue) > 0) { + DEBUG(10, ("cleanup_idle_winbindd_child: process(%d) is NOT free - %d \n", + (int)child->pid, tevent_queue_length(child->queue))); + + continue; + } + DEBUG(10, ("cleanup_idle_winbindd_child: exit child process(%d) \n", (int)child->pid)); + + /* ask child to exit */ + kill(child->pid, SIGTERM); + } + } + + if (tevent_add_timer(winbind_event_context(), NULL, timeval_current_ofs(3*60,0), + cleanup_idle_winbindd_child, NULL) == NULL) { + DEBUG(0, ("Could not trigger cleanup_idle_winbindd_child()\n")); + } else { + DEBUG(0, ("Installed next cleanup_idle_winbindd_child()\n")); + } + +} + + enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain, struct winbindd_cli_state *state) {