summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2015-01-07 10:36:12 +0100
committerJakub Hrozek <jhrozek@redhat.com>2015-01-13 17:45:19 +0100
commit16cb0969f0a9ea71524d852077d6a480740d4f12 (patch)
treee9783c109010476b0c795cd55e76de60f9b2268f
parentbb7ddd2be9847bfb07395341c7623da1b104b8a6 (diff)
downloadsssd-16cb0969f0a9ea71524d852077d6a480740d4f12.tar.gz
sssd-16cb0969f0a9ea71524d852077d6a480740d4f12.tar.xz
sssd-16cb0969f0a9ea71524d852077d6a480740d4f12.zip
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 <sbose@redhat.com>
-rw-r--r--src/providers/ad/ad_gpo.c2
-rw-r--r--src/providers/ipa/ipa_selinux.c3
-rw-r--r--src/providers/krb5/krb5_child_handler.c8
-rw-r--r--src/providers/ldap/sdap_child_helpers.c3
-rw-r--r--src/tests/cmocka/test_child_common.c11
-rw-r--r--src/util/child_common.c22
-rw-r--r--src/util/child_common.h12
7 files changed, 39 insertions, 22 deletions
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 4f8497809..1ae62e7c4 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 c4e70cfcb..133b679b6 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 1454d220f..633cd9177 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 b60891d2b..400109890 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 ee6e297f5..23e14ce49 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 d3f488d18..d632cd4ec 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 e659388ec..369de71a1 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);