You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
6.1 KiB
247 lines
6.1 KiB
diff -up openssh-6.3p1/auth-krb5.c.ccache_name openssh-6.3p1/auth-krb5.c |
|
--- openssh-6.3p1/auth-krb5.c.ccache_name 2013-10-23 22:03:52.322950759 +0200 |
|
+++ openssh-6.3p1/auth-krb5.c 2013-10-23 22:04:24.295799873 +0200 |
|
@@ -50,7 +50,9 @@ |
|
#include <errno.h> |
|
#include <unistd.h> |
|
#include <string.h> |
|
+#include <sys/stat.h> |
|
#include <krb5.h> |
|
+#include <profile.h> |
|
|
|
extern ServerOptions options; |
|
|
|
@@ -91,6 +93,7 @@ auth_krb5_password(Authctxt *authctxt, c |
|
#endif |
|
krb5_error_code problem; |
|
krb5_ccache ccache = NULL; |
|
+ const char *ccache_type; |
|
int len; |
|
char *client, *platform_client; |
|
const char *errmsg; |
|
@@ -191,12 +194,30 @@ auth_krb5_password(Authctxt *authctxt, c |
|
goto out; |
|
#endif |
|
|
|
+ ccache_type = krb5_cc_get_type(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); |
|
authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); |
|
|
|
- len = strlen(authctxt->krb5_ticket_file) + 6; |
|
+ if (authctxt->krb5_ticket_file[0] == ':') |
|
+ authctxt->krb5_ticket_file++; |
|
+ |
|
+ len = strlen(authctxt->krb5_ticket_file) + strlen(ccache_type) + 2; |
|
authctxt->krb5_ccname = xmalloc(len); |
|
- snprintf(authctxt->krb5_ccname, len, "FILE:%s", |
|
+ |
|
+#ifdef USE_CCAPI |
|
+ snprintf(authctxt->krb5_ccname, len, "API:%s", |
|
authctxt->krb5_ticket_file); |
|
+#else |
|
+ snprintf(authctxt->krb5_ccname, len, "%s:%s", |
|
+ ccache_type, authctxt->krb5_ticket_file); |
|
+#endif |
|
+ |
|
+ if (strcmp(ccache_type, "DIR") == 0) { |
|
+ char *p; |
|
+ p = strrchr(authctxt->krb5_ccname, '/'); |
|
+ if (p) |
|
+ *p = '\0'; |
|
+ } |
|
+ |
|
|
|
#ifdef USE_PAM |
|
if (options.use_pam) |
|
@@ -235,10 +256,34 @@ auth_krb5_password(Authctxt *authctxt, c |
|
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); |
|
authctxt->krb5_fwd_ccache = NULL; |
|
+ |
|
+ 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) |
|
+ ); |
|
+ } |
|
+ } |
|
} |
|
if (authctxt->krb5_user) { |
|
krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); |
|
@@ -250,34 +295,139 @@ krb5_cleanup_proc(Authctxt *authctxt) |
|
} |
|
} |
|
|
|
+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; |
|
+ |
|
+ 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 (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; |
|
+ |
|
+ ret = krb5_get_profile(ctx, &p); |
|
+ if (ret) |
|
+ return ret; |
|
+ |
|
+ ret = profile_get_string(p, "libdefaults", "default_ccache_name", NULL, NULL, &value); |
|
+ if (ret) |
|
+ return ret; |
|
+ |
|
+ ret = ssh_krb5_expand_template(ccname, value); |
|
+ |
|
+ return ret; |
|
+} |
|
+ |
|
#ifndef HEIMDAL |
|
krb5_error_code |
|
ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { |
|
int tmpfd, ret, oerrno; |
|
- char ccname[40]; |
|
+ char *ccname; |
|
+#ifdef USE_CCAPI |
|
+ char cctemplate[] = "API:krb5cc_%d"; |
|
+#else |
|
mode_t old_umask; |
|
+ char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX"; |
|
|
|
- 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; |
|
- } |
|
+#endif |
|
+ |
|
+ ret = ssh_krb5_get_cctemplate(ctx, &ccname); |
|
|
|
- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { |
|
+ if (ret) { |
|
+ ret = asprintf(&ccname, cctemplate, geteuid()); |
|
+ if (ret == -1) |
|
+ 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; |
|
+ } |
|
close(tmpfd); |
|
- return oerrno; |
|
} |
|
- close(tmpfd); |
|
+ debug("%s: Setting ccname to %s", __func__, ccname); |
|
|
|
return (krb5_cc_resolve(ctx, ccname, ccache)); |
|
}
|
|
|