summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/responder/common/responder.h2
-rw-r--r--src/responder/common/responder_common.c67
2 files changed, 67 insertions, 2 deletions
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 2cc85445c..67884ed76 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -126,6 +126,8 @@ struct cli_ctx {
int netgrent_cur;
char *automntmap_name;
+
+ struct tevent_timer *idle;
};
struct sss_cmd_table {
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 5d5248809..3c2697252 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -219,12 +219,24 @@ static void client_recv(struct cli_ctx *cctx)
return;
}
+static errno_t reset_idle_timer(struct cli_ctx *cctx);
+
static void client_fd_handler(struct tevent_context *ev,
struct tevent_fd *fde,
uint16_t flags, void *ptr)
{
+ errno_t ret;
struct cli_ctx *cctx = talloc_get_type(ptr, struct cli_ctx);
+ /* Always reset the idle timer on any activity */
+ ret = reset_idle_timer(cctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Could not create idle timer for client. "
+ "This connection may not auto-terminate\n"));
+ /* Non-fatal, continue */
+ }
+
if (flags & TEVENT_FD_READ) {
client_recv(cctx);
return;
@@ -240,6 +252,11 @@ struct accept_fd_ctx {
bool is_private;
};
+static void idle_handler(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *data);
+
static void accept_fd_handler(struct tevent_context *ev,
struct tevent_fd *fde,
uint16_t flags, void *ptr)
@@ -317,12 +334,58 @@ static void accept_fd_handler(struct tevent_context *ev,
talloc_set_destructor(cctx, client_destructor);
- DEBUG(4, ("Client connected%s!\n",
- accept_ctx->is_private ? " to privileged pipe" : ""));
+ /* Set up the idle timer */
+ ret = reset_idle_timer(cctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Could not create idle timer for client. "
+ "This connection may not auto-terminate\n"));
+ /* Non-fatal, continue */
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC,
+ ("Client connected%s!\n",
+ accept_ctx->is_private ? " to privileged pipe" : ""));
return;
}
+static errno_t reset_idle_timer(struct cli_ctx *cctx)
+{
+ struct timeval tv;
+
+ /* TODO: make this configurable */
+ tv = tevent_timeval_current_ofs(60, 0);
+
+ talloc_zfree(cctx->idle);
+
+ cctx->idle = tevent_add_timer(cctx->ev, cctx, tv, idle_handler, cctx);
+ if (!cctx->idle) return ENOMEM;
+
+ DEBUG(SSSDBG_TRACE_ALL,
+ ("Idle timer re-set for client [%p][%d]\n",
+ cctx, cctx->cfd));
+
+ return EOK;
+}
+
+static void idle_handler(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *data)
+{
+ /* This connection is idle. Terminate it */
+ struct cli_ctx *cctx =
+ talloc_get_type(data, struct cli_ctx);
+
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ ("Terminating idle client [%p][%d]\n",
+ cctx, cctx->cfd));
+
+ /* The cli_ctx destructor will handle the rest */
+ talloc_free(cctx);
+}
+
static int sss_dp_init(struct resp_ctx *rctx,
struct sbus_interface *intf,
const char *cli_name,