Index: acconfig.h =================================================================== RCS file: /afs/ncsa.uiuc.edu/src/ssh/CVSTREE/ssh/acconfig.h,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -r1.1.1.1 -r1.1.1.1.2.1 --- acconfig.h 1999/01/22 16:37:02 1.1.1.1 +++ acconfig.h 1999/01/26 03:45:28 1.1.1.1.2.1 @@ -257,6 +257,15 @@ /* Define this if you want to pass the Kerberos TGT. */ #undef KERBEROS_TGT_PASSING +/* Define this if you have the appdefault functions in your + Kerberos libraries. These are normally included as part + of the AFS-Kerberos 5 migration kit */ +#undef HAVE_APPDEFAULT + +/* Define this if you want to use AFS/Kerberos 5 option, runs aklog. */ +#undef AFS_KRB5 +#undef AKLOG_PATH + /* Define this if you dont have SIGINFO as signal but some other macro */ #undef HAVE_INCOMPATIBLE_SIGINFO Index: auth-passwd.c =================================================================== RCS file: /afs/ncsa.uiuc.edu/src/ssh/CVSTREE/ssh/auth-passwd.c,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.3 diff -u -r1.1.1.1 -r1.1.1.1.2.3 --- auth-passwd.c 1999/01/22 16:37:04 1.1.1.1 +++ auth-passwd.c 1999/01/29 19:43:04 1.1.1.1.2.3 @@ -17,6 +17,17 @@ /* * $Id$ * $Log$ + * Revision 1.1.1.1.2.3 1999/01/29 19:43:04 jbarlow + * Moved a coupld global variable defines into procedure defines. + * + * Revision 1.1.1.1.2.2 1999/01/28 19:07:54 jbarlow + * Took out setting KRB5CCNAME. Moved to function in sshd.c. + * + * Revision 1.1.1.1.2.1 1999/01/26 04:03:34 jbarlow + * Added code to check for appdefaults to set whether ticket is forwardable. + * Also set ticket lifetime based on value in appdefaults. + * Set KRB5CCNAME env variable so its set when aklog is run. + * * Revision 1.1.1.1 1999/01/22 16:37:04 jbarlow * Import of SSH 1.2.26 * @@ -290,6 +301,10 @@ #include extern krb5_context ssh_context; extern krb5_auth_context auth_context; + +/* Default ticket lifetime in seconds */ +#define KRB5_DEFAULT_LIFETIME 60 * 60 * 10 /* 10 hours */ + #else #include #endif /* KRB5 */ @@ -491,7 +506,7 @@ #ifdef KERBEROS krb5_error_code problem; - int krb5_options = KDC_OPT_RENEWABLE | KDC_OPT_FORWARDABLE; + int krb5_options = 0; krb5_deltat rlife = 0; krb5_principal server = 0; krb5_creds my_creds; @@ -499,6 +514,13 @@ krb5_ccache ccache; char ccname[80]; int results; +#ifdef HAVE_APPDEFAULT + char *lifetimestring; + krb5_deltat lifetime; + int forwardable; + int code; + int forward; +#endif /* HAVE_APPDEFAULT */ #endif /* KERBEROS */ extern ServerOptions options; extern char *crypt(const char *key, const char *salt); @@ -552,13 +574,40 @@ goto errout; my_creds.times.starttime = 0; /* start timer when request gets to KDC */ - my_creds.times.endtime = now + 60*60*10; /* 10 hours */ - - problem = krb5_string_to_deltat("7d", &rlife); /* 7 days renew time */ - if (problem || rlife == 0) - goto errout; + +#ifdef HAVE_APPDEFAULT + /* Read lifetime from krb5.conf */ + krb5_appdefault_string(ssh_context, "sshd", + krb5_princ_realm(ssh_context,client), + "default_lifetime", "", + &lifetimestring); + + if (lifetimestring[0]) { + code = krb5_string_to_deltat(lifetimestring, &lifetime); + if (code != 0 || lifetime == 0) { + log_msg("Bad Kerberos lifetime value: \"%s\"", lifetimestring); + lifetime = KRB5_DEFAULT_LIFETIME; + } + } else { + lifetime = KRB5_DEFAULT_LIFETIME; + } + free(lifetimestring); + + /* Read forwardable option from krb5.conf */ + krb5_appdefault_boolean(ssh_context, "sshd", + krb5_princ_realm(ssh_context,client), + "forwardable", 0, &forward); + if (forward) + krb5_options |= KDC_OPT_FORWARDABLE; + +#else /* !HAVE_APPDEFAULT */ + lifetime = KRB5_DEFAULT_LIFETIME; +#endif /* !HAVE_APPDEFAULT */ + + my_creds.times.endtime = now + lifetime; - my_creds.times.renew_till = now + rlife; + /* Currently don't want renewable ticket, may change in future */ + my_creds.times.renew_till = 0; problem = krb5_get_in_tkt_with_password(ssh_context, krb5_options, 0, @@ -610,7 +659,7 @@ ticket = xmalloc(strlen(ccname) + 1); (void) sprintf(ticket, "%s", ccname); - + /* We do not need this so free them up */ xfree(saved_pw_name); xfree(saved_pw_passwd); Index: configure.in =================================================================== RCS file: /afs/ncsa.uiuc.edu/src/ssh/CVSTREE/ssh/configure.in,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -r1.1.1.1 -r1.1.1.1.2.1 --- configure.in 1999/01/22 16:37:02 1.1.1.1 +++ configure.in 1999/01/26 03:50:32 1.1.1.1.2.1 @@ -939,6 +939,7 @@ KERBEROS_ROOT="$with_kerberos5" KERBEROS_INCS="-I${KERBEROS_ROOT}/include" KERBEROS_LIBS="-L${KERBEROS_ROOT}/lib -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err" + AC_CHECK_LIB(gen, compile, KERBEROS_LIBS="$KERBEROS_LIBS -lgen") AC_CHECK_LIB(ndbm, dbm_open, KERBEROS_LIBS="$KERBEROS_LIBS -lndbm") KERBEROS_OBJS="auth-kerberos.o" ;; @@ -948,6 +949,21 @@ AC_SUBST(KERBEROS_LIBS) AC_SUBST(KERBEROS_OBJS) +dnl Check to see if we have the appdefault functions() +if test "$with_kerberos5" != no ; then + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -L${KERBEROS_ROOT}/lib" + AC_CHECK_LIB(krb5, krb5_appdefault_boolean, + [have_appdefault=yes], + [have_appdefault=no], + [-lcom_err] + ) + LDFLAGS=$save_LDFLAGS + if test "$have_appdefault" = "yes" ; then + AC_DEFINE(HAVE_APPDEFAULT) + fi +fi + AC_MSG_CHECKING(whether to enable passing the Kerberos TGT) AC_ARG_ENABLE(kerberos-tgt-passing, [ --enable-kerberos-tgt-passing Pass Kerberos ticket-granting-ticket.], @@ -966,6 +982,38 @@ ;; esac ], AC_MSG_RESULT(no) +) + +AC_MSG_CHECKING(whether to use aklog) +AC_ARG_WITH(afs-krb5, +[ --with-afs-krb5[=AKLOG_PATH] AFS/KRB5 option, uses aklog to get token. ], +[ case "$withval" in + no) + AC_MSG_RESULT(no) + ;; + yes) + if test "$with_kerberos5" = no ; then + AC_MSG_RESULT(no) + AC_MSG_WARN("AFS/KRB5 option requires Kerberos5 support.") + else + AC_MSG_RESULT(yes) + AC_PATH_PROG(AKLOG_PATH, aklog, /usr/local/krb5/bin/aklog) + AC_DEFINE(AFS_KRB5) + AC_DEFINE_UNQUOTED(AKLOG_PATH, "$AKLOG_PATH") + fi + ;; + *) + if test "$with_kerberos5" = no ; then + AC_MSG_RESULT(no) + AC_MSG_WARN("AFS/KRB5 option requires Kerberos5 support.") + else + AC_MSG_RESULT($withval) + AC_DEFINE(AFS_KRB5) + AC_DEFINE_UNQUOTED(AKLOG_PATH, "$withval") + fi + ;; + esac ], + [ AC_MSG_RESULT(no) ] ) AC_MSG_CHECKING(whether to use libwrap) Index: sshd.c =================================================================== RCS file: /afs/ncsa.uiuc.edu/src/ssh/CVSTREE/ssh/sshd.c,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.5 diff -u -r1.1.1.1 -r1.1.1.1.2.5 --- sshd.c 1999/01/22 16:37:04 1.1.1.1 +++ sshd.c 1999/01/28 20:03:19 1.1.1.1.2.5 @@ -20,6 +20,19 @@ /* * $Id$ * $Log$ + * Revision 1.1.1.1.2.5 1999/01/28 20:03:19 jbarlow + * Moved setting KRB5CCNAME within testing for ticket. + * + * Revision 1.1.1.1.2.4 1999/01/28 19:12:28 jbarlow + * Moved aklog call code from do_authenticate to do_child. It is now + * called after the setuid(user_uid) call. + * Also set KRB5CCNAME so that aklog can find it. + * + * Revision 1.1.1.1.2.3 1999/01/26 04:19:40 jbarlow + * Added code to set KRB5CNAME just in case sshd was started by a user + * who had it set in the environment. We would not want to inherit + * KRB5CCNAME from another user. + * * Revision 1.1.1.1 1999/01/22 16:37:04 jbarlow * Import of SSH 1.2.26 * @@ -528,6 +541,21 @@ char *ticket = "none\0"; #endif /* KERBEROS */ +#ifdef AFS_KRB5 + +/* Default place to look for aklog. */ +#ifdef AKLOG_PATH +#define KPROGDIR AKLOG_PATH +#else +#define KPROGDIR "/usr/local/krb5/bin/aklog" +#endif /* AKLOG_PATH */ + +int run_aklog; +char *aklog_path; +struct stat st; +#include +#endif /* AFS_KRB5 */ + /* Server configuration options. */ ServerOptions options; @@ -2106,6 +2134,9 @@ char kuser[128]; krb5_principal client = 0, tkt_client = 0; krb5_data krb5data; +#ifdef AFS_KRB5 + char krb5cc_buf[50]; +#endif /* AFS_KRB5 */ #endif /* defined(KERBEROS) && defined(KRB5) */ #if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H) login_cap_t *lc; @@ -2121,6 +2152,26 @@ if (strlen(user) > 255) do_authentication_fail_loop(); +#ifdef AFS_KRB5 + /* If machine has AFS, set process authentication group. */ + if (k_hasafs()) { + debug("Setting pagsh."); + k_setpag(); + k_unlog(); + } + + /* Set the KRB5CCNAME env variable so that the sshd process + will not inherit a ticket from a user starting sshd. + This should most likely never happen, but just in case. */ + + sprintf(krb5cc_buf, "KRB5CCNAME=FILE:/tmp/krb5cc_p%d", getpid()); + if (putenv(krb5cc_buf)) + { + log_msg("WARNING: Couldn't set KRB5CCNAME in do_authentication."); + } + +#endif /* AFS_KRB5 */ + #if defined(KERBEROS) && defined(KRB5) /* For KRB5 allow the user to input fully qualified name i.e. "username@realm" as the local user name. Then use this name to call @@ -2710,7 +2761,7 @@ if (pw->pw_uid == UID_ROOT) log_severity(SYSLOG_SEVERITY_NOTICE, "ROOT LOGIN as '%.100s' from %.100s", pw->pw_name, get_canonical_hostname()); - + /* The user has been authenticated and accepted. */ packet_start(SSH_SMSG_SUCCESS); packet_send(); @@ -3161,6 +3212,10 @@ void pty_cleanup_proc(void *context) { struct pty_cleanup_context *cu = context; +#ifdef KERBEROS + krb5_ccache ccache = NULL; + int retval; +#endif if (cu->alread_cleaned) { @@ -3175,6 +3230,22 @@ /* Release the pseudo-tty. */ pty_release(cu->ttyname); + +#ifdef KERBEROS + if (ssh_context && ticket && (strcmp(ticket,"none") != 0)) { + debug("Destroying ticket file %s", ticket); + if(retval = krb5_cc_resolve(ssh_context, ticket, &ccache)) + { + debug("kdestroy failed in krb5_cc_resolve for %s: %s", ticket, error_message(retval)); + } + else { + debug("ccname: %s", krb5_cc_default_name(ssh_context)); + if ((retval = krb5_cc_destroy (ssh_context, ccache)) != 0) { + debug("kdestroy failed in krb5_cc_destroy: %s", error_message(retval)); + } + } + } +#endif cu->alread_cleaned = 1; } @@ -3733,6 +3804,12 @@ char *user_shell; char *remote_ip; int remote_port; +#if defined(KERBEROS) && defined(KRB5) + krb5_principal client = 0; +#ifdef AFS_KRB5 + char *krb5cc_buf; +#endif /* AFS_KRB5 */ +#endif /* defined(KERBEROS) && defined(KRB5) */ #if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H) login_cap_t *lc; char *real_shell; @@ -4145,6 +4222,63 @@ #ifdef KRB5 if (ticket) child_set_env(&env, &envsize, "KRB5CCNAME", ticket); + +#ifdef AFS_KRB5 + + /* User has authenticated, and if a ticket was going to be + passed we would have it. So test for valid ticket then + set KRB5CCNAME and then run aklog to get a token if + it's specified in the kerberos configuration file (krb5.conf). + */ + + if (ticket && (strcmp(ticket,"none") != 0)) { + + /* Set the current KRB5CCNAME env variable so that aklog can find it. */ + krb5cc_buf = xmalloc(strlen("KRB5CCNAME=") + strlen(ticket) + 1); + sprintf(krb5cc_buf, "KRB5CCNAME=%s", ticket); + if (putenv(krb5cc_buf)) { + log_msg("WARNING: Couldn't set KRB5CCNAME in do_child."); + } + + krb5_parse_name(ssh_context, pw->pw_name, &client); + +#ifdef HAVE_APPDEFAULT + /* Get run krb5_run_aklog value from krb5.conf and put into run_aklog */ + krb5_appdefault_boolean(ssh_context, "kinit", + krb5_princ_realm(ssh_context,client), + "krb5_run_aklog", 0, &run_aklog); + + if (run_aklog) { + + /* Alloc krb5_aklog_path in krb5.conf to override default */ + krb5_appdefault_string(ssh_context, "kinit", + krb5_princ_realm(ssh_context,client), + "krb5_aklog_path", KPROGDIR, + &aklog_path); + } +#else + aklog_path = xmalloc(strlen("KPROGDIR") + 1); + strcpy(aklog_path, KPROGDIR); +#endif /* HAVE_APPDEFAULT */ + + /* + * Make sure it exists before we try to run it + */ + if (stat(aklog_path, &st) == 0) { + debug("Running %s to get afs token.",aklog_path); + system(aklog_path); + } else { + debug("%s does not exist.",aklog_path); + } + + free(aklog_path); + if (client) + krb5_free_principal(ssh_context, client); + + + } +#endif /* AFS_KRB5 */ + #endif /* KRB5 */ #endif /* KERBEROS */