Index: openssh-5.3p1/auth-krb5.c =================================================================== --- openssh-5.3p1.orig/auth-krb5.c 2006-08-05 03:39:39.000000000 +0100 +++ openssh-5.3p1/auth-krb5.c 2010-01-24 10:29:25.000000000 +0000 @@ -166,8 +166,13 @@ len = strlen(authctxt->krb5_ticket_file) + 6; authctxt->krb5_ccname = xmalloc(len); +#ifdef USE_CCAPI + snprintf(authctxt->krb5_ccname, len, "API:%s", + authctxt->krb5_ticket_file); +#else snprintf(authctxt->krb5_ccname, len, "FILE:%s", authctxt->krb5_ticket_file); +#endif #ifdef USE_PAM if (options.use_pam) @@ -219,15 +224,22 @@ #ifndef HEIMDAL krb5_error_code ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { - int tmpfd, ret; + int ret; char ccname[40]; mode_t old_umask; +#ifdef USE_CCAPI + char cctemplate[] = "API:krb5cc_%d"; +#else + char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX"; + int tmpfd; +#endif ret = snprintf(ccname, sizeof(ccname), - "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); + cctemplate, geteuid()); if (ret < 0 || (size_t)ret >= sizeof(ccname)) return ENOMEM; +#ifndef USE_CCAPI old_umask = umask(0177); tmpfd = mkstemp(ccname + strlen("FILE:")); umask(old_umask); @@ -242,6 +254,7 @@ return errno; } close(tmpfd); +#endif return (krb5_cc_resolve(ctx, ccname, ccache)); } Index: openssh-5.3p1/gss-serv-krb5.c =================================================================== --- openssh-5.3p1.orig/gss-serv-krb5.c 2006-09-01 06:38:36.000000000 +0100 +++ openssh-5.3p1/gss-serv-krb5.c 2010-01-24 10:29:25.000000000 +0000 @@ -120,6 +120,7 @@ krb5_principal princ; OM_uint32 maj_status, min_status; int len; + const char *new_ccname; if (client->creds == NULL) { debug("No credentials stored"); @@ -168,11 +169,16 @@ return; } - client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); + new_ccname = krb5_cc_get_name(krb_context, ccache); + client->store.envvar = "KRB5CCNAME"; - len = strlen(client->store.filename) + 6; - client->store.envval = xmalloc(len); - snprintf(client->store.envval, len, "FILE:%s", client->store.filename); +#ifdef USE_CCAPI + xasprintf(&client->store.envval, "API:%s", new_ccname); + client->store.filename = NULL; +#else + xasprintf(&client->store.envval, "FILE:%s", new_ccname); + client->store.filename = xstrdup(new_ccname); +#endif #ifdef USE_PAM if (options.use_pam) Index: openssh-5.3p1/sshd.c =================================================================== --- openssh-5.3p1.orig/sshd.c 2009-06-21 11:26:17.000000000 +0100 +++ openssh-5.3p1/sshd.c 2010-01-24 10:29:25.000000000 +0000 @@ -120,6 +120,10 @@ #include "roaming.h" #include "version.h" +#ifdef USE_SECURITY_SESSION_API +#include +#endif + #ifdef LIBWRAP #include #include @@ -1818,6 +1822,60 @@ /* Log the connection. */ verbose("Connection from %.500s port %d", remote_ip, remote_port); +#ifdef USE_SECURITY_SESSION_API + /* + * Create a new security session for use by the new user login if + * the current session is the root session or we are not launched + * by inetd (eg: debugging mode or server mode). We do not + * necessarily need to create a session if we are launched from + * inetd because Panther xinetd will create a session for us. + * + * The only case where this logic will fail is if there is an + * inetd running in a non-root session which is not creating + * new sessions for us. Then all the users will end up in the + * same session (bad). + * + * When the client exits, the session will be destroyed for us + * automatically. + * + * We must create the session before any credentials are stored + * (including AFS pags, which happens a few lines below). + */ + { + OSStatus err = 0; + SecuritySessionId sid = 0; + SessionAttributeBits sattrs = 0; + + err = SessionGetInfo(callerSecuritySession, &sid, &sattrs); + if (err) + error("SessionGetInfo() failed with error %.8X", + (unsigned) err); + else + debug("Current Session ID is %.8X / Session Attributes are %.8X", + (unsigned) sid, (unsigned) sattrs); + + if (inetd_flag && !(sattrs & sessionIsRoot)) + debug("Running in inetd mode in a non-root session... " + "assuming inetd created the session for us."); + else { + debug("Creating new security session..."); + err = SessionCreate(0, sessionHasTTY | sessionIsRemote); + if (err) + error("SessionCreate() failed with error %.8X", + (unsigned) err); + + err = SessionGetInfo(callerSecuritySession, &sid, + &sattrs); + if (err) + error("SessionGetInfo() failed with error %.8X", + (unsigned) err); + else + debug("New Session ID is %.8X / Session Attributes are %.8X", + (unsigned) sid, (unsigned) sattrs); + } + } +#endif + /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is Index: openssh-5.3p1/configure.ac =================================================================== --- openssh-5.3p1.orig/configure.ac 2009-09-11 05:56:08.000000000 +0100 +++ openssh-5.3p1/configure.ac 2010-01-24 10:29:25.000000000 +0000 @@ -477,6 +477,30 @@ [Use tunnel device compatibility to OpenBSD]) AC_DEFINE(SSH_TUN_PREPEND_AF, 1, [Prepend the address family to IP tunnel traffic]) + AC_MSG_CHECKING(if we have the Security Authorization Session API) + AC_TRY_COMPILE([#include ], + [SessionCreate(0, 0);], + [ac_cv_use_security_session_api="yes" + AC_DEFINE(USE_SECURITY_SESSION_API, 1, + [platform has the Security Authorization Session API]) + LIBS="$LIBS -framework Security" + AC_MSG_RESULT(yes)], + [ac_cv_use_security_session_api="no" + AC_MSG_RESULT(no)]) + AC_MSG_CHECKING(if we have an in-memory credentials cache) + AC_TRY_COMPILE( + [#include ], + [cc_context_t c; + (void) cc_initialize (&c, 0, NULL, NULL);], + [AC_DEFINE(USE_CCAPI, 1, + [platform uses an in-memory credentials cache]) + LIBS="$LIBS -framework Security" + AC_MSG_RESULT(yes) + if test "x$ac_cv_use_security_session_api" = "xno"; then + AC_MSG_ERROR(*** Need a security framework to use the credentials cache API ***) + fi], + [AC_MSG_RESULT(no)] + ) m4_pattern_allow(AU_IPv) AC_CHECK_DECL(AU_IPv4, [], AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit records])