On Tue, Dec 02, 2014 at 02:54:42PM +0100, Jakub Hrozek wrote:
Hi,
these patches depend on Sumit's "[PATCHES] ldap_child, krb5_child: copy
keytab and FAST ccache into memory".
When applied, the FAST ccache is created as the SSSD so that no Kerberos
networking code runs as the root user. In order to do that, the
krb5_child receives the SSSD user IDs as parameters.
I also have tests for the other functions in the child_common.c module
but I will send them separately to speed up the review.
Patches are working well in my tests, I have a few comments to the 3rd
patch.
bye,
Sumit
From f5905625ce08f2a02058d23beb43a86fe3e3faed Mon Sep 17 00:00:00
2001
From: Jakub Hrozek <jhrozek(a)redhat.com>
Date: Mon, 1 Dec 2014 12:04:25 +0100
Subject: [PATCH 1/3] TESTS: Basic child tests
ACK
From fb6c0c1aa80a138d56cd12a5061fbe05a3db5798 Mon Sep 17 00:00:00
2001
From: Jakub Hrozek <jhrozek(a)redhat.com>
Date: Mon, 1 Dec 2014 12:25:24 +0100
Subject: [PATCH 2/3] Add extra_args to exec_child()
ACK
From 74ae76ecea1d469ff9dc8937eacdd077707352b9 Mon Sep 17 00:00:00
2001
From: Jakub Hrozek <jhrozek(a)redhat.com>
Date: Fri, 28 Nov 2014 13:04:42 +0100
Subject: [PATCH 3/3] KRB5: Create the fast ccache in a child process
---
src/providers/krb5/krb5_child.c | 108 ++++++++++++++++++++++++--------
src/providers/krb5/krb5_child_handler.c | 10 ++-
2 files changed, 90 insertions(+), 28 deletions(-)
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index cd78874db111e620a6a156f4310bc4e026a45121..fcf299229d2bdeae20223546edaba2fb2d96f7df
100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -74,6 +74,9 @@ struct krb5_req {
bool old_cc_valid;
bool old_cc_active;
enum k5c_fast_opt fast_val;
+
+ uid_t fast_uid;
+ gid_t fast_gid;
};
static krb5_context krb5_error_ctx;
@@ -1009,17 +1012,6 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
DEBUG(SSSDBG_CONF_SETTINGS, "TGT validation is disabled.\n");
}
- if (kr->validate || kr->fast_ccname != NULL) {
- /* We drop root privileges which were needed to read the keytab file
- * for the validation of the credentials or for FAST here to run the
- * ccache I/O operations with user privileges. */
- kerr = become_user(kr->uid, kr->gid);
- if (kerr != 0) {
- DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
- return kerr;
- }
- }
-
/* If kr->ccname is cache collection (DIR:/...), we want to work
* directly with file ccache (DIR::/...), but cache collection
* should be returned back to back end.
@@ -1440,17 +1432,6 @@ static errno_t renew_tgt_child(struct krb5_req *kr)
DEBUG(SSSDBG_CONF_SETTINGS, "TGT validation is disabled.\n");
}
- if (kr->validate || kr->fast_ccname != NULL) {
- /* We drop root privileges which were needed to read the keytab file
- * for the validation of the credentials or for FAST here to run the
- * ccache I/O operations with user privileges. */
- kerr = become_user(kr->uid, kr->gid);
- if (kerr != 0) {
- DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
- goto done;
- }
- }
-
kerr = krb5_cc_initialize(kr->ctx, ccache, kr->princ);
if (kerr != 0) {
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
@@ -1724,6 +1705,8 @@ done:
static krb5_error_code check_fast_ccache(TALLOC_CTX *mem_ctx,
krb5_context ctx,
+ uid_t fast_uid,
+ gid_t fast_gid,
const char *primary,
const char *realm,
const char *keytab_name,
@@ -1737,6 +1720,8 @@ static krb5_error_code check_fast_ccache(TALLOC_CTX *mem_ctx,
krb5_keytab keytab = NULL;
krb5_principal client_princ = NULL;
krb5_principal server_princ = NULL;
+ pid_t fchild_pid;
+ int status;
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
@@ -1794,10 +1779,68 @@ static krb5_error_code check_fast_ccache(TALLOC_CTX *mem_ctx,
}
}
- kerr = get_and_save_tgt_with_keytab(ctx, client_princ, keytab, ccname);
- if (kerr != 0) {
- DEBUG(SSSDBG_CRIT_FAILURE, "get_and_save_tgt_with_keytab failed.\n");
- goto done;
+ /* Need to recreate the FAST ccache */
+ fchild_pid = fork();
+ switch (fchild_pid) {
+ case -1:
+ DEBUG(SSSDBG_CRIT_FAILURE, "fork failed\n");
+ kerr = EIO;
+ goto done;
+ case 0:
+ /* Child */
please change debug_prg_name for the child
+ kerr = become_user(fast_uid, fast_gid);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed: %d\n", kerr);
+ exit(1);
+ }
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "Running as
[%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
+
+ kerr = get_and_save_tgt_with_keytab(ctx, client_princ,
+ keytab, ccname);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "get_and_save_tgt_with_keytab failed: %d\n", kerr);
+ exit(2);
+ }
+ exit(0);
+ default:
+ /* Parent */
+ do {
+ errno = 0;
+ kerr = waitpid(fchild_pid, &status, 0);
+ } while (kerr == -1 && errno == EINTR);
+
+ if (kerr > 0) {
+ kerr = EIO;
+ if (WIFEXITED(status)) {
+ kerr = WEXITSTATUS(status);
+ /* Don't blindly fail if the child fails, but check
+ * the ccache again */
+ if (kerr != 0) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Creating FAST ccache failed, krb5_child will "
+ "likely fail!\n");
+ }
+ }
please add and else with a message the the child terminated
unexpectedly.
+ } else {
+ DEBUG(SSSDBG_FUNC_DATA,
+ "Failed to wait for children %d\n", fchild_pid);
+ kerr = EIO;
+ }
+ }
+
+ /* Check the ccache times again. Should be updated ... */
+ memset(&tgtt, 0, sizeof(tgtt));
+ kerr = get_tgt_times(ctx, ccname, server_princ, client_princ, &tgtt);
+ if (kerr == 0) {
+ if (tgtt.endtime > time(NULL)) {
+ DEBUG(SSSDBG_FUNC_DATA, "FAST TGT was successfully
recreated!\n");
+ goto done;
+ } else {
+ kerr = ERR_CREDS_EXPIRED;
+ goto done;
+ }
}
kerr = 0;
@@ -1889,7 +1932,8 @@ static int k5c_setup_fast(struct krb5_req *kr, bool demand)
fast_principal = NULL;
}
- kerr = check_fast_ccache(kr, kr->ctx, fast_principal, fast_principal_realm,
+ kerr = check_fast_ccache(kr, kr->ctx, kr->fast_uid, kr->fast_gid,
+ fast_principal, fast_principal_realm,
kr->keytab, &kr->fast_ccname);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "check_fast_ccache failed.\n");
@@ -2253,6 +2297,9 @@ int main(int argc, const char *argv[])
int debug_fd = -1;
errno_t ret;
krb5_error_code kerr;
+ char *mem_keytab;
unused
+ uid_t fast_uid;
+ gid_t fast_gid;
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -2267,6 +2314,10 @@ int main(int argc, const char *argv[])
{"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN,
&debug_to_stderr, 0,
_("Send the debug output to stderr directly."), NULL },
+ {"fast-ccache-uid", 0, POPT_ARG_INT, &fast_uid, 0,
+ _("The user to create FAST ccache as"), NULL},
+ {"fast-ccache-gid", 0, POPT_ARG_INT, &fast_gid, 0,
+ _("The group to create FAST ccache as"), NULL},
POPT_TABLEEND
};
@@ -2313,6 +2364,9 @@ int main(int argc, const char *argv[])
}
talloc_steal(kr, debug_prg_name);
+ kr->fast_uid = fast_uid;
+ kr->fast_gid = fast_gid;
+
ret = k5c_recv_data(kr, STDIN_FILENO, &offline);
if (ret != EOK) {
goto done;
diff --git a/src/providers/krb5/krb5_child_handler.c
b/src/providers/krb5/krb5_child_handler.c
index 9bb61f65437694d8aa2109513b5f061dfc9ee21c..1454d220fb294abc339df6e862154012a03fdca0
100644
--- a/src/providers/krb5/krb5_child_handler.c
+++ b/src/providers/krb5/krb5_child_handler.c
@@ -278,6 +278,14 @@ static errno_t fork_child(struct tevent_req *req)
errno_t err;
struct handle_child_state *state = tevent_req_data(req,
struct handle_child_state);
+ const char *k5c_extra_args[3];
+
+ k5c_extra_args[0] = talloc_asprintf(state, "--fast-ccache-uid=%"SPRIuid,
getuid());
+ k5c_extra_args[1] = talloc_asprintf(state, "--fast-ccache-gid=%"SPRIgid,
getgid());
+ k5c_extra_args[2] = NULL;
+ if (k5c_extra_args[0] == NULL || k5c_extra_args[1] == NULL) {
+ return ENOMEM;
+ }
ret = pipe(pipefd_from_child);
if (ret == -1) {
@@ -300,7 +308,7 @@ static errno_t fork_child(struct tevent_req *req)
err = exec_child(state,
pipefd_to_child, pipefd_from_child,
KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd,
- NULL);
+ k5c_extra_args);
if (err != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec KRB5 child:
[%d][%s].\n",
err, strerror(err));
--
1.9.3
_______________________________________________
sssd-devel mailing list
sssd-devel(a)lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel