*
* This returns a buffer allocated by xmalloc.
*/
-static char *
+char *
expand_authorized_keys(const char *filename, struct passwd *pw)
{
char *file, ret[MAXPATHLEN];
} else {
client->store.envvar = strdup((char *)export_cred.value);
}
+ if (access(p, R_OK) == 0) {
+ if (client->store.filename) {
+ if (rename(p, client->store.filename) < 0) {
+ logit("Failed to rename %s to %s: %s", p,
+ client->store.filename, strerror(errno));
+ xfree(client->store.filename);
+ client->store.filename = strdup(p);
+ } else {
+ p = client->store.filename;
+ }
+ } else {
+ client->store.filename = strdup(p);
+ }
+ }
client->store.envval = strdup(p);
#ifdef USE_PAM
if (options.use_pam)
do_pam_putenv(client->store.envvar, client->store.envval);
#endif
- if (strncmp(p, "FILE:", 5) == 0) {
- p += 5;
- }
- if (access(p, R_OK) == 0) {
- client->store.filename = strdup(p);
- }
gss_release_buffer(&minor_status, &export_cred);
}
#include "monitor_wrap.h"
extern ServerOptions options;
+extern Authctxt *the_authctxt;
static ssh_gssapi_client gssapi_client =
{ GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
ssh_gssapi_storecreds(void)
{
if (gssapi_client.mech && gssapi_client.mech->storecreds) {
+ if (options.gss_creds_path) {
+ gssapi_client.store.filename =
+ expand_authorized_keys(options.gss_creds_path,
+ the_authctxt->pw);
+ }
(*gssapi_client.mech->storecreds)(&gssapi_client);
} else
debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
sGssKeyEx,
+ sGssCredsPath,
sGsiAllowLimitedProxy,
sAcceptEnv, sPermitTunnel,
sMatch, sPermitOpen, sForceCommand,
#ifdef GSSAPI
{ "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
+ { "gssapicredentialspath", sGssCredsPath, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
#ifdef GSI
#else
{ "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
+ { "gssapicredentialspath", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
#ifdef GSI
intptr = &options->gss_cleanup_creds;
goto parse_flag;
+ case sGssCredsPath:
+ charptr = &options->gss_creds_path;
+ goto parse_filename;
+
case sGssStrictAcceptor:
intptr = &options->gss_strict_acceptor;
+ goto parse_flag;
case sGsiAllowLimitedProxy:
intptr = &options->gsi_allow_limited_proxy;
int gss_authentication; /* If true, permit GSSAPI authentication */
int gss_keyex; /* If true, permit GSSAPI key exchange */
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
+ char* gss_creds_path; /* If true, destroy cred cache on logout */
int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */
int gsi_allow_limited_proxy; /* If true, accept limited proxies */
int password_authentication; /* If true, permit password
and setting it to
.Dq no
may only work with recent Kerberos GSSAPI libraries.
+.It Cm GSSAPICredentialsPath
+If specified, the delegated GSSAPI credential is stored in the
+given path, overwriting any existing credentials.
+Paths can be specified with syntax similar to the AuthorizedKeysFile
+option (i.e., accepting %h and %u tokens).
+When using this option,
+setting 'GssapiCleanupCredentials no' is recommended,
+so logging out of one session
+doesn't remove the credentials in use by another session of
+the same user.
+Currently only implemented for the GSI mechanism.
.It Cm GSIAllowLimitedProxy
Specifies whether to accept limited proxy credentials for
authentication.