diff options
Diffstat (limited to 'src/responder/common')
-rw-r--r-- | src/responder/common/responder.h | 30 | ||||
-rw-r--r-- | src/responder/common/responder_cmd.c | 51 | ||||
-rw-r--r-- | src/responder/common/responder_common.c | 66 |
3 files changed, 97 insertions, 50 deletions
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 2b5b05412..adf7b3d19 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -68,6 +68,11 @@ struct cli_protocol_version { const char *description; }; +struct cli_protocol { + struct cli_request *creq; + struct cli_protocol_version *cli_protocol_version; +}; + struct resp_ctx; struct be_conn { @@ -130,26 +135,14 @@ struct cli_ctx { struct resp_ctx *rctx; int cfd; struct tevent_fd *cfde; + tevent_fd_handler_t cfd_handler; struct sockaddr_un addr; - struct cli_request *creq; - struct cli_protocol_version *cli_protocol_version; int priv; struct cli_creds *creds; - int pwent_dom_idx; - int pwent_cur; - - int grent_dom_idx; - int grent_cur; - - int svc_dom_idx; - int svcent_cur; - - char *netgr_name; - int netgrent_cur; - - char *automntmap_name; + void *protocol_ctx; + void *state_ctx; struct tevent_timer *idle; }; @@ -165,6 +158,12 @@ struct mon_cli_iface; /* * responder_common.c * + */ + +typedef int (*connection_setup_t)(struct cli_ctx *cctx); + +int sss_connection_setup(struct cli_ctx *cctx); +/* * NOTE: We would like to use more strong typing for the @dp_vtable argument * but can't since it accepts either a struct data_provider_iface * or struct data_provider_rev_iface. So pass the base struct: sbus_vtable @@ -183,6 +182,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx, struct mon_cli_iface *monitor_intf, const char *cli_name, struct sbus_vtable *dp_intf, + connection_setup_t conn_setup, struct resp_ctx **responder_ctx); int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain, diff --git a/src/responder/common/responder_cmd.c b/src/responder/common/responder_cmd.c index 1ac86fddf..175a8e5d6 100644 --- a/src/responder/common/responder_cmd.c +++ b/src/responder/common/responder_cmd.c @@ -24,20 +24,25 @@ #include "responder/common/responder.h" #include "responder/common/responder_packet.h" + int sss_cmd_send_error(struct cli_ctx *cctx, int err) { + struct cli_protocol *pctx; int ret; + pctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol); + if (!pctx) return EINVAL; + /* create response packet */ - ret = sss_packet_new(cctx->creq, 0, - sss_packet_get_cmd(cctx->creq->in), - &cctx->creq->out); + ret = sss_packet_new(pctx->creq, 0, + sss_packet_get_cmd(pctx->creq->in), + &pctx->creq->out); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create new packet: %d\n", ret); return ret; } - sss_packet_set_error(cctx->creq->out, err); + sss_packet_set_error(pctx->creq->out, err); return EOK; } @@ -63,22 +68,26 @@ int sss_cmd_empty_packet(struct sss_packet *packet) int sss_cmd_send_empty(struct cli_ctx *cctx, TALLOC_CTX *freectx) { + struct cli_protocol *pctx; int ret; + pctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol); + if (!pctx) return EINVAL; + /* create response packet */ - ret = sss_packet_new(cctx->creq, 0, - sss_packet_get_cmd(cctx->creq->in), - &cctx->creq->out); + ret = sss_packet_new(pctx->creq, 0, + sss_packet_get_cmd(pctx->creq->in), + &pctx->creq->out); if (ret != EOK) { return ret; } - ret = sss_cmd_empty_packet(cctx->creq->out); + ret = sss_cmd_empty_packet(pctx->creq->out); if (ret != EOK) { return ret; } - sss_packet_set_error(cctx->creq->out, EOK); + sss_packet_set_error(pctx->creq->out, EOK); sss_cmd_done(cctx, freectx); return EOK; } @@ -95,6 +104,7 @@ void sss_cmd_done(struct cli_ctx *cctx, void *freectx) int sss_cmd_get_version(struct cli_ctx *cctx) { + struct cli_protocol *pctx; uint8_t *req_body; size_t req_blen; uint8_t *body; @@ -105,16 +115,19 @@ int sss_cmd_get_version(struct cli_ctx *cctx) int i; static struct cli_protocol_version *cli_protocol_version = NULL; - cctx->cli_protocol_version = NULL; + pctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol); + if (!pctx) return EINVAL; + + pctx->cli_protocol_version = NULL; if (cli_protocol_version == NULL) { cli_protocol_version = register_cli_protocol_version(); } if (cli_protocol_version != NULL) { - cctx->cli_protocol_version = &cli_protocol_version[0]; + pctx->cli_protocol_version = &cli_protocol_version[0]; - sss_packet_get_body(cctx->creq->in, &req_body, &req_blen); + sss_packet_get_body(pctx->creq->in, &req_body, &req_blen); if (req_blen == sizeof(uint32_t)) { memcpy(&client_version, req_body, sizeof(uint32_t)); DEBUG(SSSDBG_FUNC_DATA, @@ -123,7 +136,7 @@ int sss_cmd_get_version(struct cli_ctx *cctx) i=0; while(cli_protocol_version[i].version>0) { if (cli_protocol_version[i].version == client_version) { - cctx->cli_protocol_version = &cli_protocol_version[i]; + pctx->cli_protocol_version = &cli_protocol_version[i]; break; } i++; @@ -132,16 +145,16 @@ int sss_cmd_get_version(struct cli_ctx *cctx) } /* create response packet */ - ret = sss_packet_new(cctx->creq, sizeof(uint32_t), - sss_packet_get_cmd(cctx->creq->in), - &cctx->creq->out); + ret = sss_packet_new(pctx->creq, sizeof(uint32_t), + sss_packet_get_cmd(pctx->creq->in), + &pctx->creq->out); if (ret != EOK) { return ret; } - sss_packet_get_body(cctx->creq->out, &body, &blen); + sss_packet_get_body(pctx->creq->out, &body, &blen); - protocol_version = (cctx->cli_protocol_version != NULL) - ? cctx->cli_protocol_version->version : 0; + protocol_version = (pctx->cli_protocol_version != NULL) + ? pctx->cli_protocol_version->version : 0; SAFEALIGN_COPY_UINT32(body, &protocol_version, NULL); DEBUG(SSSDBG_FUNC_DATA, "Offered version [%d].\n", protocol_version); diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c index 67a7aa8f9..e67456bb1 100644 --- a/src/responder/common/responder_common.c +++ b/src/responder/common/responder_common.c @@ -241,12 +241,14 @@ done: return ret; } - static void client_send(struct cli_ctx *cctx) { + struct cli_protocol *pctx; int ret; - ret = sss_packet_send(cctx->creq->out, cctx->cfd); + pctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol); + + ret = sss_packet_send(pctx->creq->out, cctx->cfd); if (ret == EAGAIN) { /* not all data was sent, loop again */ return; @@ -260,26 +262,30 @@ static void client_send(struct cli_ctx *cctx) /* ok all sent */ TEVENT_FD_NOT_WRITEABLE(cctx->cfde); TEVENT_FD_READABLE(cctx->cfde); - talloc_free(cctx->creq); - cctx->creq = NULL; + talloc_zfree(pctx->creq); return; } static int client_cmd_execute(struct cli_ctx *cctx, struct sss_cmd_table *sss_cmds) { + struct cli_protocol *pctx; enum sss_cli_command cmd; - cmd = sss_packet_get_cmd(cctx->creq->in); + pctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol); + cmd = sss_packet_get_cmd(pctx->creq->in); return sss_cmd_execute(cctx, cmd, sss_cmds); } static void client_recv(struct cli_ctx *cctx) { + struct cli_protocol *pctx; int ret; - if (!cctx->creq) { - cctx->creq = talloc_zero(cctx, struct cli_request); - if (!cctx->creq) { + pctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol); + + if (!pctx->creq) { + pctx->creq = talloc_zero(cctx, struct cli_request); + if (!pctx->creq) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to alloc request, aborting client!\n"); talloc_free(cctx); @@ -287,9 +293,9 @@ static void client_recv(struct cli_ctx *cctx) } } - if (!cctx->creq->in) { - ret = sss_packet_new(cctx->creq, SSS_PACKET_MAX_RECV_SIZE, - 0, &cctx->creq->in); + if (!pctx->creq->in) { + ret = sss_packet_new(pctx->creq, SSS_PACKET_MAX_RECV_SIZE, + 0, &pctx->creq->in); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to alloc request, aborting client!\n"); @@ -298,7 +304,7 @@ static void client_recv(struct cli_ctx *cctx) } } - ret = sss_packet_recv(cctx->creq->in, cctx->cfd); + ret = sss_packet_recv(pctx->creq->in, cctx->cfd); switch (ret) { case EOK: /* do not read anymore */ @@ -368,6 +374,7 @@ static void client_fd_handler(struct tevent_context *ev, struct accept_fd_ctx { struct resp_ctx *rctx; bool is_private; + connection_setup_t connection_setup; }; static void idle_handler(struct tevent_context *ev, @@ -468,8 +475,19 @@ static void accept_fd_handler(struct tevent_context *ev, } } + ret = accept_ctx->connection_setup(cctx); + if (ret != EOK) { + close(cctx->cfd); + talloc_free(cctx); + DEBUG(SSSDBG_OP_FAILURE, + "Failed to setup client handler%s\n", + accept_ctx->is_private ? " on privileged pipe" : ""); + return; + } + cctx->cfde = tevent_add_fd(ev, cctx, cctx->cfd, - TEVENT_FD_READ, client_fd_handler, cctx); + TEVENT_FD_READ, cctx->cfd_handler, + cctx); if (!cctx->cfde) { close(cctx->cfd); talloc_free(cctx); @@ -644,10 +662,11 @@ done: } /* create a unix socket and listen to it */ -static int set_unix_socket(struct resp_ctx *rctx) +static int set_unix_socket(struct resp_ctx *rctx, + connection_setup_t conn_setup) { errno_t ret; - struct accept_fd_ctx *accept_ctx; + struct accept_fd_ctx *accept_ctx = NULL; /* for future use */ #if 0 @@ -699,6 +718,7 @@ static int set_unix_socket(struct resp_ctx *rctx) if(!accept_ctx) goto failed; accept_ctx->rctx = rctx; accept_ctx->is_private = false; + accept_ctx->connection_setup = conn_setup; rctx->lfde = tevent_add_fd(rctx->ev, rctx, rctx->lfd, TEVENT_FD_READ, accept_fd_handler, @@ -723,6 +743,7 @@ static int set_unix_socket(struct resp_ctx *rctx) if(!accept_ctx) goto failed; accept_ctx->rctx = rctx; accept_ctx->is_private = true; + accept_ctx->connection_setup = conn_setup; rctx->priv_lfde = tevent_add_fd(rctx->ev, rctx, rctx->priv_lfd, TEVENT_FD_READ, accept_fd_handler, @@ -742,6 +763,18 @@ failed: return EIO; } +int sss_connection_setup(struct cli_ctx *cctx) +{ + cctx->protocol_ctx = talloc_zero(cctx, struct cli_protocol); + if (!cctx->protocol_ctx) { + return ENOMEM; + } + + cctx->cfd_handler = client_fd_handler; + + return EOK; +} + static int sss_responder_ctx_destructor(void *ptr) { struct resp_ctx *rctx = talloc_get_type(ptr, struct resp_ctx); @@ -829,6 +862,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx, struct mon_cli_iface *monitor_intf, const char *cli_name, struct sbus_vtable *dp_intf, + connection_setup_t conn_setup, struct resp_ctx **responder_ctx) { struct resp_ctx *rctx; @@ -959,7 +993,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx, } /* after all initializations we are ready to listen on our socket */ - ret = set_unix_socket(rctx); + ret = set_unix_socket(rctx, conn_setup); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing socket\n"); goto fail; |