Bugzilla – Attachment 3161 Details for
Bug 2775
Improve kerberos credential forwarding support
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Allow using default ccache or unique one as before
openssh-kerberos.patch (text/plain), 18.86 KB, created by
Jakub Jelen
on 2018-06-19 21:28:56 AEST
(
hide
)
Description:
Allow using default ccache or unique one as before
Filename:
MIME Type:
Creator:
Jakub Jelen
Created:
2018-06-19 21:28:56 AEST
Size:
18.86 KB
patch
obsolete
>diff --git a/auth-krb5.c b/auth-krb5.c >index a5a81ed2..63f877f2 100644 >--- a/auth-krb5.c >+++ b/auth-krb5.c >@@ -51,6 +51,7 @@ > #include <unistd.h> > #include <string.h> > #include <krb5.h> >+#include <profile.h> > > extern ServerOptions options; > >@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) > #endif > krb5_error_code problem; > krb5_ccache ccache = NULL; >- int len; >+ char *ticket_name = NULL; > char *client, *platform_client; > const char *errmsg; > >@@ -163,7 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password) > goto out; > } > >- problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &authctxt->krb5_fwd_ccache); >+ problem = ssh_krb5_cc_new_unique(authctxt->krb5_ctx, >+ &authctxt->krb5_fwd_ccache, &authctxt->krb5_set_env); > if (problem) > goto out; > >@@ -172,21 +174,20 @@ auth_krb5_password(Authctxt *authctxt, const char *password) > if (problem) > goto out; > >- problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, >+ problem = krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, > &creds); > if (problem) > goto out; > #endif > >- authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); >+ problem = krb5_cc_get_full_name(authctxt->krb5_ctx, >+ authctxt->krb5_fwd_ccache, &ticket_name); > >- len = strlen(authctxt->krb5_ticket_file) + 6; >- authctxt->krb5_ccname = xmalloc(len); >- snprintf(authctxt->krb5_ccname, len, "FILE:%s", >- authctxt->krb5_ticket_file); >+ authctxt->krb5_ccname = xstrdup(ticket_name); >+ krb5_free_string(authctxt->krb5_ctx, ticket_name); > > #ifdef USE_PAM >- if (options.use_pam) >+ if (options.use_pam && authctxt->krb5_set_env) > do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); > #endif > >@@ -222,10 +223,59 @@ auth_krb5_password(Authctxt *authctxt, const char *password) > void > krb5_cleanup_proc(Authctxt *authctxt) > { >+ struct stat krb5_ccname_stat; >+ char krb5_ccname[128], *krb5_ccname_dir_start, *krb5_ccname_dir_end; >+ > debug("krb5_cleanup_proc called"); > if (authctxt->krb5_fwd_ccache) { >- krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); >+ krb5_context ctx = authctxt->krb5_ctx; >+ krb5_cccol_cursor cursor; >+ krb5_ccache ccache; >+ int ret; >+ >+ /* Avoid race conditions with other processes touching the same collection */ >+ //krb5_cccol_lock(ctx); >+ >+ krb5_cc_destroy(ctx, authctxt->krb5_fwd_ccache); > authctxt->krb5_fwd_ccache = NULL; >+ >+ ret = krb5_cccol_cursor_new(ctx, &cursor); >+ if (ret) >+ goto unlock; >+ >+ ret = krb5_cccol_cursor_next(ctx, cursor, &ccache); >+ if (ret == 0 && ccache != NULL) { >+ /* There is at least one other ccache in collection >+ * we can switch to */ >+ krb5_cc_switch(ctx, ccache); >+ } else { >+ /* Clean up the collection too */ >+ strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10); >+ krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1; >+ *krb5_ccname_dir_start++ = '\0'; >+ if (strcmp(krb5_ccname, "DIR") == 0) { >+ >+ strcat(krb5_ccname_dir_start, "/primary"); >+ >+ if (stat(krb5_ccname_dir_start, &krb5_ccname_stat) == 0) { >+ if (unlink(krb5_ccname_dir_start) == 0) { >+ krb5_ccname_dir_end = strrchr(krb5_ccname_dir_start, '/'); >+ *krb5_ccname_dir_end = '\0'; >+ if (rmdir(krb5_ccname_dir_start) == -1) >+ debug("cache dir '%s' remove failed: %s", >+ krb5_ccname_dir_start, strerror(errno)); >+ } >+ else >+ debug("cache primary file '%s', remove failed: %s", >+ krb5_ccname_dir_start, strerror(errno)); >+ } >+ } >+ } >+unlock: >+ krb5_cccol_cursor_free(ctx, &cursor); >+ >+ /* Release lock */ >+ //krb5_cccol_unlock(ctx); > } > if (authctxt->krb5_user) { > krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); >@@ -237,36 +287,186 @@ krb5_cleanup_proc(Authctxt *authctxt) > } > } > >-#ifndef HEIMDAL >-krb5_error_code >-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { >- int tmpfd, ret, oerrno; >- char ccname[40]; >- mode_t old_umask; > >- ret = snprintf(ccname, sizeof(ccname), >- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); >- if (ret < 0 || (size_t)ret >= sizeof(ccname)) >- return ENOMEM; >- >- old_umask = umask(0177); >- tmpfd = mkstemp(ccname + strlen("FILE:")); >- oerrno = errno; >- umask(old_umask); >- if (tmpfd == -1) { >- logit("mkstemp(): %.100s", strerror(oerrno)); >- return oerrno; >+#if !defined(HEIMDAL) >+int >+ssh_asprintf_append(char **dsc, const char *fmt, ...) { >+ char *src, *old; >+ va_list ap; >+ int i; >+ >+ va_start(ap, fmt); >+ i = vasprintf(&src, fmt, ap); >+ va_end(ap); >+ >+ if (i == -1 || src == NULL) >+ return -1; >+ >+ old = *dsc; >+ >+ i = asprintf(dsc, "%s%s", *dsc, src); >+ if (i == -1 || src == NULL) { >+ free(src); >+ return -1; >+ } >+ >+ free(old); >+ free(src); >+ >+ return i; >+} >+ >+int >+ssh_krb5_expand_template(char **result, const char *template) { >+ char *p_n, *p_o, *r, *tmp_template; >+ >+ debug3("%s: called, template = %s", __func__, template); >+ if (template == NULL) >+ return -1; >+ >+ tmp_template = p_n = p_o = xstrdup(template); >+ r = xstrdup(""); >+ >+ while ((p_n = strstr(p_o, "%{")) != NULL) { >+ >+ *p_n++ = '\0'; >+ if (ssh_asprintf_append(&r, "%s", p_o) == -1) >+ goto cleanup; >+ >+ if (strncmp(p_n, "{uid}", 5) == 0 || strncmp(p_n, "{euid}", 6) == 0 || >+ strncmp(p_n, "{USERID}", 8) == 0) { >+ p_o = strchr(p_n, '}') + 1; >+ if (ssh_asprintf_append(&r, "%d", geteuid()) == -1) >+ goto cleanup; >+ continue; >+ } >+ else if (strncmp(p_n, "{TEMP}", 6) == 0) { >+ p_o = strchr(p_n, '}') + 1; >+ if (ssh_asprintf_append(&r, "/tmp") == -1) >+ goto cleanup; >+ continue; >+ } else { >+ p_o = strchr(p_n, '}') + 1; >+ p_o = '\0'; >+ debug("%s: unsupported token %s in %s", __func__, p_n, template); >+ /* unknown token, fallback to the default */ >+ goto cleanup; >+ } > } > >- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { >+ if (ssh_asprintf_append(&r, "%s", p_o) == -1) >+ goto cleanup; >+ >+ *result = r; >+ free(tmp_template); >+ return 0; >+ >+cleanup: >+ free(r); >+ free(tmp_template); >+ return -1; >+} >+ >+krb5_error_code >+ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { >+ profile_t p; >+ int ret = 0; >+ char *value = NULL; >+ >+ debug3("%s: called", __func__); >+ ret = krb5_get_profile(ctx, &p); >+ if (ret) >+ return ret; >+ >+ ret = profile_get_string(p, "libdefaults", "default_ccache_name", NULL, NULL, &value); >+ if (ret || !value) >+ return ret; >+ >+ ret = ssh_krb5_expand_template(ccname, value); >+ >+ debug3("%s: returning with ccname = %s", __func__, *ccname); >+ return ret; >+} >+ >+krb5_error_code >+ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) { >+ int tmpfd, ret, oerrno, type_len; >+ char *ccname = NULL; >+ mode_t old_umask; >+ char *type = NULL, *colon = NULL; >+ >+ debug3("%s: called", __func__); >+ if (need_environment) >+ *need_environment = 0; >+ ret = ssh_krb5_get_cctemplate(ctx, &ccname); >+ if (ret || !ccname || options.kerberos_unique_ticket) { >+ /* Otherwise, go with the old method */ >+ if (ccname) >+ free(ccname); >+ ccname = NULL; >+ >+ ret = asprintf(&ccname, >+ "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); >+ if (ret < 0) >+ return ENOMEM; >+ >+ old_umask = umask(0177); >+ tmpfd = mkstemp(ccname + strlen("FILE:")); > oerrno = errno; >- logit("fchmod(): %.100s", strerror(oerrno)); >+ umask(old_umask); >+ if (tmpfd == -1) { >+ logit("mkstemp(): %.100s", strerror(oerrno)); >+ return oerrno; >+ } >+ >+ if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { >+ oerrno = errno; >+ logit("fchmod(): %.100s", strerror(oerrno)); >+ close(tmpfd); >+ return oerrno; >+ } >+ /* make sure the KRB5CCNAME is set for non-standard location */ >+ if (need_environment) >+ *need_environment = 1; > close(tmpfd); >- return oerrno; > } >- close(tmpfd); > >- return (krb5_cc_resolve(ctx, ccname, ccache)); >+ debug3("%s: setting default ccname to %s", __func__, ccname); >+ /* set the default with already expanded user IDs */ >+ ret = krb5_cc_set_default_name(ctx, ccname); >+ if (ret) >+ return ret; >+ >+ if ((colon = strstr(ccname, ":")) != NULL) { >+ type_len = colon - ccname; >+ type = malloc((type_len + 1) * sizeof(char)); >+ if (type == NULL) >+ return ENOMEM; >+ strncpy(type, ccname, type_len); >+ type[type_len] = 0; >+ } else { >+ type = strdup(ccname); >+ } >+ >+ /* If we have a credential cache from krb5.conf, we need to switch >+ * a primary cache for this collection, if it supports that (non-FILE) >+ */ >+ if (krb5_cc_support_switch(ctx, type)) { >+ debug3("%s: calling cc_new_unique(%s)", __func__, ccname); >+ ret = krb5_cc_new_unique(ctx, type, NULL, ccache); >+ if (ret) >+ return ret; >+ >+ debug3("%s: calling cc_switch()", __func__); >+ return krb5_cc_switch(ctx, *ccache); >+ } else { >+ /* Otherwise, we can not create a unique ccname here (either >+ * it is already unique from above or the type does not support >+ * collections >+ */ >+ debug3("%s: calling cc_resolve(%s)", __func__, ccname); >+ return (krb5_cc_resolve(ctx, ccname, ccache)); >+ } > } > #endif /* !HEIMDAL */ > #endif /* KRB5 */ >diff --git a/auth.h b/auth.h >index 29491df9..fdab5040 100644 >--- a/auth.h >+++ b/auth.h >@@ -82,6 +82,7 @@ struct Authctxt { > krb5_principal krb5_user; > char *krb5_ticket_file; > char *krb5_ccname; >+ int krb5_set_env; > #endif > struct sshbuf *loginmsg; > >@@ -243,6 +244,6 @@ int sys_auth_passwd(struct ssh *, const char *); > > #if defined(KRB5) && !defined(HEIMDAL) > #include <krb5.h> >-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); >+krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); > #endif > #endif >diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c >index 795992d9..cc3f11e3 100644 >--- a/gss-serv-krb5.c >+++ b/gss-serv-krb5.c >@@ -114,7 +114,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) > /* This writes out any forwarded credentials from the structure populated > * during userauth. Called after we have setuid to the user */ > >-static void >+static int > ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) > { > krb5_ccache ccache; >@@ -123,14 +123,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) > OM_uint32 maj_status, min_status; > int len; > const char *errmsg; >+ int set_env = 0; > > if (client->creds == NULL) { > debug("No credentials stored"); >- return; >+ return 0; > } > > if (ssh_gssapi_krb5_init() == 0) >- return; >+ return 0; > > #ifdef HEIMDAL > # ifdef HAVE_KRB5_CC_NEW_UNIQUE >@@ -147,11 +148,11 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) > return; > } > #else >- if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { >+ if ((problem = ssh_krb5_cc_new_unique(krb_context, &ccache, &set_env)) != 0) { > errmsg = krb5_get_error_message(krb_context, problem); >- logit("ssh_krb5_cc_gen(): %.100s", errmsg); >+ logit("ssh_krb5_cc_new_unique(): %.100s", errmsg); > krb5_free_error_message(krb_context, errmsg); >- return; >+ return 0; > } > #endif /* #ifdef HEIMDAL */ > >@@ -160,7 +161,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) > errmsg = krb5_get_error_message(krb_context, problem); > logit("krb5_parse_name(): %.100s", errmsg); > krb5_free_error_message(krb_context, errmsg); >- return; >+ return 0; > } > > if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { >@@ -169,7 +170,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) > krb5_free_error_message(krb_context, errmsg); > krb5_free_principal(krb_context, princ); > krb5_cc_destroy(krb_context, ccache); >- return; >+ return 0; > } > > krb5_free_principal(krb_context, princ); >@@ -178,7 +179,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) > client->creds, ccache))) { > logit("gss_krb5_copy_ccache() failed"); > krb5_cc_destroy(krb_context, ccache); >- return; >+ return 0; > } > > client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); >@@ -188,13 +189,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) > snprintf(client->store.envval, len, "FILE:%s", client->store.filename); > > #ifdef USE_PAM >- if (options.use_pam) >+ if (options.use_pam && set_env) > do_pam_putenv(client->store.envvar, client->store.envval); > #endif > > krb5_cc_close(krb_context, ccache); > >- return; >+ client->store.data = krb_context; >+ >+ return set_env; > } > > ssh_gssapi_mech gssapi_kerberos_mech = { >diff --git a/gss-serv.c b/gss-serv.c >index 6cae720e..b0afa09e 100644 >--- a/gss-serv.c >+++ b/gss-serv.c >@@ -320,22 +320,33 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) > void > ssh_gssapi_cleanup_creds(void) > { >- if (gssapi_client.store.filename != NULL) { >- /* Unlink probably isn't sufficient */ >- debug("removing gssapi cred file\"%s\"", >- gssapi_client.store.filename); >- unlink(gssapi_client.store.filename); >+ krb5_ccache ccache = NULL; >+ krb5_error_code problem; >+ >+ if (gssapi_client.store.data != NULL) { >+ if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) { >+ debug("%s: krb5_cc_resolve(): %.100s", __func__, >+ krb5_get_err_text(gssapi_client.store.data, problem)); >+ } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { >+ debug("%s: krb5_cc_destroy(): %.100s", __func__, >+ krb5_get_err_text(gssapi_client.store.data, problem)); >+ } else { >+ krb5_free_context(gssapi_client.store.data); >+ gssapi_client.store.data = NULL; >+ } > } > } > > /* As user */ >-void >+int > ssh_gssapi_storecreds(void) > { > if (gssapi_client.mech && gssapi_client.mech->storecreds) { >- (*gssapi_client.mech->storecreds)(&gssapi_client); >+ return (*gssapi_client.mech->storecreds)(&gssapi_client); > } else > debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); >+ >+ return 0; > } > > /* This allows GSSAPI methods to do things to the childs environment based >diff --git a/servconf.c b/servconf.c >index cb578658..a6e01df2 100644 >--- a/servconf.c >+++ b/servconf.c >@@ -122,6 +122,7 @@ initialize_server_options(ServerOptions *options) > options->kerberos_or_local_passwd = -1; > options->kerberos_ticket_cleanup = -1; > options->kerberos_get_afs_token = -1; >+ options->kerberos_unique_ticket = -1; > options->gss_authentication=-1; > options->gss_cleanup_creds = -1; > options->gss_strict_acceptor = -1; >@@ -315,6 +316,8 @@ fill_default_server_options(ServerOptions *options) > options->kerberos_ticket_cleanup = 1; > if (options->kerberos_get_afs_token == -1) > options->kerberos_get_afs_token = 0; >+ if (options->kerberos_unique_ticket == -1) >+ options->kerberos_unique_ticket = 0; > if (options->gss_authentication == -1) > options->gss_authentication = 0; > if (options->gss_cleanup_creds == -1) >@@ -447,7 +450,8 @@ typedef enum { > sPermitRootLogin, sLogFacility, sLogLevel, > sRhostsRSAAuthentication, sRSAAuthentication, > sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, >- sKerberosGetAFSToken, sChallengeResponseAuthentication, >+ sKerberosGetAFSToken, sKerberosUniqueTicket, >+ sChallengeResponseAuthentication, > sPasswordAuthentication, sKbdInteractiveAuthentication, > sListenAddress, sAddressFamily, > sPrintMotd, sPrintLastLog, sIgnoreRhosts, >@@ -526,11 +530,13 @@ static struct { > #else > { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, > #endif >+ { "kerberosuniqueticket", sKerberosUniqueTicket, SSHCFG_GLOBAL }, > #else > { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, > { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, > { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, > { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, >+ { "kerberosuniqueticket", sUnsupported, SSHCFG_GLOBAL }, > #endif > { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, > { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, >@@ -1437,6 +1443,10 @@ process_server_config_line(ServerOptions *options, char *line, > intptr = &options->kerberos_get_afs_token; > goto parse_flag; > >+ case sKerberosUniqueTicket: >+ intptr = &options->kerberos_unique_ticket; >+ goto parse_flag; >+ > case sGssAuthentication: > intptr = &options->gss_authentication; > goto parse_flag; >@@ -2507,6 +2517,7 @@ dump_config(ServerOptions *o) > # ifdef USE_AFS > dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); > # endif >+ dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket); > #endif > #ifdef GSSAPI > dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); >diff --git a/servconf.h b/servconf.h >index db8362c6..4fa42d64 100644 >--- a/servconf.h >+++ b/servconf.h >@@ -123,6 +123,8 @@ typedef struct { > * file on logout. */ > int kerberos_get_afs_token; /* If true, try to get AFS token if > * authenticated with Kerberos. */ >+ int kerberos_unique_ticket; /* If true, the aquired ticket will >+ * be stored in per-session ccache */ > int gss_authentication; /* If true, permit GSSAPI authentication */ > int gss_cleanup_creds; /* If true, destroy cred cache on logout */ > int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ >diff --git a/session.c b/session.c >index 85df6a27..480a5ead 100644 >--- a/session.c >+++ b/session.c >@@ -1033,7 +1033,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) > /* Allow any GSSAPI methods that we've used to alter > * the childs environment as they see fit > */ >- ssh_gssapi_do_child(&env, &envsize); >+ if (s->authctxt->krb5_set_env) >+ ssh_gssapi_do_child(&env, &envsize); > #endif > > /* Set basic environment. */ >@@ -1105,7 +1106,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) > } > #endif > #ifdef KRB5 >- if (s->authctxt->krb5_ccname) >+ if (s->authctxt->krb5_ccname && s->authctxt->krb5_set_env) > child_set_env(&env, &envsize, "KRB5CCNAME", > s->authctxt->krb5_ccname); > #endif >diff --git a/ssh-gss.h b/ssh-gss.h >index 6593e422..b9528fb8 100644 >--- a/ssh-gss.h >+++ b/ssh-gss.h >@@ -83,7 +83,7 @@ typedef struct ssh_gssapi_mech_struct { > int (*dochild) (ssh_gssapi_client *); > int (*userok) (ssh_gssapi_client *, char *); > int (*localname) (ssh_gssapi_client *, char **); >- void (*storecreds) (ssh_gssapi_client *); >+ int (*storecreds) (ssh_gssapi_client *); > } ssh_gssapi_mech; > > typedef struct { >@@ -127,7 +127,7 @@ int ssh_gssapi_userok(char *name); > OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); > void ssh_gssapi_do_child(char ***, u_int *); > void ssh_gssapi_cleanup_creds(void); >-void ssh_gssapi_storecreds(void); >+int ssh_gssapi_storecreds(void); > const char *ssh_gssapi_displayname(void); > > #endif /* GSSAPI */ >diff --git a/sshd.c b/sshd.c >index edbe815c..89514e8a 100644 >--- a/sshd.c >+++ b/sshd.c >@@ -2162,7 +2162,7 @@ main(int ac, char **av) > #ifdef GSSAPI > if (options.gss_authentication) { > temporarily_use_uid(authctxt->pw); >- ssh_gssapi_storecreds(); >+ authctxt->krb5_set_env = ssh_gssapi_storecreds(); > restore_uid(); > } > #endif >diff --git a/sshd_config.5 b/sshd_config.5 >index c0683d4a..2349f477 100644 >--- a/sshd_config.5 >+++ b/sshd_config.5 >@@ -860,6 +860,12 @@ Specifies whether to automatically destroy the user's ticket cache > file on logout. > The default is > .Cm yes . >+.It Cm KerberosUniqueTicket >+Specifies whether to store the aquired tickets in the per-session credential >+cache or whether to use per-user credential cache, which might overwrite >+tickets aquired in different sessions of the same user. >+The default is >+.Cm no . > .It Cm KexAlgorithms > Specifies the available KEX (Key Exchange) algorithms. > Multiple algorithms must be comma-separated.
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2775
:
3051
| 3161