[SSSD] [PATCH] Recreate FAST ccache as the sssd user

Sumit Bose sbose at redhat.com
Tue Dec 2 20:40:42 UTC 2014


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 at 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 at 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 at 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 at lists.fedorahosted.org
> https://lists.fedorahosted.org/mailman/listinfo/sssd-devel




More information about the sssd-devel mailing list