From 16cb0969f0a9ea71524d852077d6a480740d4f12 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Jan 13 2015 16:45:19 +0000 Subject: UTIL: Allow dup-ing child pipe to a different FD Related to: https://fedorahosted.org/sssd/ticket/2544 Adds a new function exec_child_ex and moves setting the extra_argv[] to exec_child_ex() along with specifying the input and output fds. Reviewed-by: Sumit Bose --- diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c index 4f84978..1ae62e7 100644 --- a/src/providers/ad/ad_gpo.c +++ b/src/providers/ad/ad_gpo.c @@ -3963,7 +3963,7 @@ gpo_fork_child(struct tevent_req *req) if (pid == 0) { /* child */ err = exec_child(state, pipefd_to_child, pipefd_from_child, - GPO_CHILD, gpo_child_debug_fd, NULL); + GPO_CHILD, gpo_child_debug_fd); DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec gpo_child: [%d][%s].\n", err, strerror(err)); return err; diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c index c4e70cf..133b679 100644 --- a/src/providers/ipa/ipa_selinux.c +++ b/src/providers/ipa/ipa_selinux.c @@ -1049,8 +1049,7 @@ static errno_t selinux_fork_child(struct selinux_child_state *state) if (pid == 0) { /* child */ ret = exec_child(state, pipefd_to_child, pipefd_from_child, - SELINUX_CHILD, selinux_child_debug_fd, - NULL); + SELINUX_CHILD, selinux_child_debug_fd); DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec selinux_child: [%d][%s].\n", ret, sss_strerror(ret)); return ret; diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c index 1454d22..633cd91 100644 --- a/src/providers/krb5/krb5_child_handler.c +++ b/src/providers/krb5/krb5_child_handler.c @@ -305,10 +305,10 @@ static errno_t fork_child(struct tevent_req *req) pid = fork(); if (pid == 0) { /* child */ - err = exec_child(state, - pipefd_to_child, pipefd_from_child, - KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd, - k5c_extra_args); + err = exec_child_ex(state, + pipefd_to_child, pipefd_from_child, + KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd, + k5c_extra_args, STDIN_FILENO, STDOUT_FILENO); if (err != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec KRB5 child: [%d][%s].\n", err, strerror(err)); diff --git a/src/providers/ldap/sdap_child_helpers.c b/src/providers/ldap/sdap_child_helpers.c index b60891d..4001098 100644 --- a/src/providers/ldap/sdap_child_helpers.c +++ b/src/providers/ldap/sdap_child_helpers.c @@ -108,8 +108,7 @@ static errno_t sdap_fork_child(struct tevent_context *ev, if (pid == 0) { /* child */ err = exec_child(child, pipefd_to_child, pipefd_from_child, - LDAP_CHILD, ldap_child_debug_fd, - NULL); + LDAP_CHILD, ldap_child_debug_fd); DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec LDAP child: [%d][%s].\n", err, strerror(err)); return err; diff --git a/src/tests/cmocka/test_child_common.c b/src/tests/cmocka/test_child_common.c index ee6e297..23e14ce 100644 --- a/src/tests/cmocka/test_child_common.c +++ b/src/tests/cmocka/test_child_common.c @@ -89,7 +89,7 @@ void test_exec_child(void **state) ret = exec_child(child_tctx, child_tctx->pipefd_to_child, child_tctx->pipefd_from_child, - CHILD_DIR"/"TEST_BIN, 2, NULL); + CHILD_DIR"/"TEST_BIN, 2); assert_int_equal(ret, EOK); } else { do { @@ -128,10 +128,11 @@ void test_exec_child_extra_args(void **state) child_pid = fork(); assert_int_not_equal(child_pid, -1); if (child_pid == 0) { - ret = exec_child(child_tctx, - child_tctx->pipefd_to_child, - child_tctx->pipefd_from_child, - CHILD_DIR"/"TEST_BIN, 2, extra_args); + ret = exec_child_ex(child_tctx, + child_tctx->pipefd_to_child, + child_tctx->pipefd_from_child, + CHILD_DIR"/"TEST_BIN, 2, extra_args, + STDIN_FILENO, STDOUT_FILENO); assert_int_equal(ret, EOK); } else { do { diff --git a/src/util/child_common.c b/src/util/child_common.c index d3f488d..d632cd4 100644 --- a/src/util/child_common.c +++ b/src/util/child_common.c @@ -729,17 +729,18 @@ fail: return ret; } -errno_t exec_child(TALLOC_CTX *mem_ctx, - int *pipefd_to_child, int *pipefd_from_child, - const char *binary, int debug_fd, - const char *extra_argv[]) +errno_t exec_child_ex(TALLOC_CTX *mem_ctx, + int *pipefd_to_child, int *pipefd_from_child, + const char *binary, int debug_fd, + const char *extra_argv[], + int child_in_fd, int child_out_fd) { int ret; errno_t err; char **argv; close(pipefd_to_child[1]); - ret = dup2(pipefd_to_child[0], STDIN_FILENO); + ret = dup2(pipefd_to_child[0], child_in_fd); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, @@ -748,7 +749,7 @@ errno_t exec_child(TALLOC_CTX *mem_ctx, } close(pipefd_from_child[0]); - ret = dup2(pipefd_from_child[1], STDOUT_FILENO); + ret = dup2(pipefd_from_child[1], child_out_fd); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, @@ -770,6 +771,15 @@ errno_t exec_child(TALLOC_CTX *mem_ctx, return err; } +errno_t exec_child(TALLOC_CTX *mem_ctx, + int *pipefd_to_child, int *pipefd_from_child, + const char *binary, int debug_fd) +{ + return exec_child_ex(mem_ctx, pipefd_to_child, pipefd_from_child, + binary, debug_fd, NULL, + STDIN_FILENO, STDOUT_FILENO); +} + void child_cleanup(int readfd, int writefd) { int ret; diff --git a/src/util/child_common.h b/src/util/child_common.h index e659388..369de71 100644 --- a/src/util/child_common.h +++ b/src/util/child_common.h @@ -112,10 +112,18 @@ void child_sig_handler(struct tevent_context *ev, int count, void *__siginfo, void *pvt); /* Never returns EOK, ether returns an error, or doesn't return on success */ +errno_t exec_child_ex(TALLOC_CTX *mem_ctx, + int *pipefd_to_child, int *pipefd_from_child, + const char *binary, int debug_fd, + const char *extra_argv[], + int child_in_fd, int child_out_fd); + +/* Same as exec_child_ex() except child_in_fd is set to STDIN_FILENO and + * child_out_fd is set to STDOUT_FILENO and extra_argv is always NULL. + */ errno_t exec_child(TALLOC_CTX *mem_ctx, int *pipefd_to_child, int *pipefd_from_child, - const char *binary, int debug_fd, - const char *extra_argv[]); + const char *binary, int debug_fd); void child_cleanup(int readfd, int writefd);