diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c index e7170ee..f8fbe46 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -40,6 +40,7 @@ #include "auth.h" #include "log.h" #include "servconf.h" +#include "groupaccess.h" #include "buffer.h" #include "ssh-gss.h" @@ -57,6 +58,7 @@ extern ServerOptions options; #endif static krb5_context krb_context = NULL; +int user_should_have_tickets(char *name); /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ @@ -77,6 +79,28 @@ ssh_gssapi_krb5_init(void) return 1; } +int +user_should_have_tickets(char *name) +{ + int result = 0; + struct passwd *pwd; + + // If no group is specified, assume that the user should not + // have to have tickets + if (options.gss_req_deleg_creds_for == NULL) + { + return 0; + } + + pwd = getpwnam(name); + + ga_init(name, pwd->pw_gid); + result = ga_match_pattern_list(options.gss_req_deleg_creds_for); + ga_free(); + return result; +} + + /* Check if this user is OK to login. This only works with krb5 - other * GSSAPI mechanisms will need their own. * Returns true if the user is OK to log in, otherwise returns 0 @@ -90,7 +114,16 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) if (ssh_gssapi_krb5_init() == 0) return 0; - + + /* If the user should have tickets (i.e., they are in the + * specified group) and have not forwarded them, fall through + * to password authentication. */ + if (user_should_have_tickets(name) && !client->creds) { + logit("%s is a member of %s and did not forward tickets.", + name, options.gss_req_deleg_creds_for); + return 0; + } + if ((retval = krb5_parse_name(krb_context, client->exportedname.value, &princ))) { logit("krb5_parse_name(): %.100s", diff --git a/servconf.c b/servconf.c index b087726..a4dd364 100644 --- a/servconf.c +++ b/servconf.c @@ -101,6 +101,7 @@ initialize_server_options(ServerOptions *options) options->gss_cleanup_creds = -1; options->gss_strict_acceptor = -1; options->gss_store_rekey = -1; + options->gss_req_deleg_creds_for = NULL; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; @@ -332,7 +333,7 @@ typedef enum { sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, - sGssKeyEx, sGssStoreRekey, + sGssKeyEx, sGssStoreRekey, sGssReqDelCredsFor, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, @@ -401,6 +402,7 @@ static struct { { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, + { "gssapirequiredelegatedcredentialsfor", sGssReqDelCredsFor, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, @@ -408,6 +410,7 @@ static struct { { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, + { "gssapirequiredelegatedcredentialsfor", sUnsupported, SSHCFG_GLOBAL }, #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, @@ -981,6 +984,10 @@ process_server_config_line(ServerOptions *options, char *line, intptr = &options->gss_store_rekey; goto parse_flag; + case sGssReqDelCredsFor: + options->gss_req_deleg_creds_for = strdup(arg = strdelim(&cp)); + break; + case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; diff --git a/servconf.h b/servconf.h index 38de135..06cebd3 100644 --- a/servconf.h +++ b/servconf.h @@ -101,6 +101,7 @@ typedef struct { int gss_cleanup_creds; /* If true, destroy cred cache on logout */ int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; + char *gss_req_deleg_creds_for; /* If not null, require tickets if the user is a member of the specified group */ int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */