X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fgssd%2Fkrb5_util.c;h=238927622f614c284970b2e5d2360f21046c8f51;hp=4b13fa1f5c2ac2e1fd64d2036fe0c6c6ad1a0e63;hb=1c787f1471d733f8a90b46924945c59de7478bac;hpb=45e4597bd570ed40221f51887cde7d7f096f55e7 diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c index 4b13fa1..2389276 100644 --- a/utils/gssd/krb5_util.c +++ b/utils/gssd/krb5_util.c @@ -129,13 +129,17 @@ /* Global list of principals/cache file names for machine credentials */ struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL; +#ifdef HAVE_SET_ALLOWABLE_ENCTYPES +int limit_to_legacy_enctypes = 0; +#endif + /*==========================*/ /*=== Internal routines ===*/ /*==========================*/ static int select_krb5_ccache(const struct dirent *d); static int gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, - struct dirent **d); + const char **cctype, struct dirent **d); static int gssd_get_single_krb5_cred(krb5_context context, krb5_keytab kt, struct gssd_k5_kt_princ *ple, int nocache); static int query_krb5_ccache(const char* cred_cache, char **ret_princname, @@ -174,7 +178,8 @@ select_krb5_ccache(const struct dirent *d) * code otherwise. */ static int -gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d) +gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, + const char **cctype, struct dirent **d) { struct dirent **namelist; int n; @@ -188,6 +193,7 @@ gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d) int score, best_match_score = 0, err = -EACCES; memset(&best_match_stat, 0, sizeof(best_match_stat)); + *cctype = NULL; *d = NULL; n = scandir(dirname, &namelist, select_krb5_ccache, 0); if (n < 0) { @@ -199,41 +205,51 @@ gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d) for (i = 0; i < n; i++) { snprintf(statname, sizeof(statname), "%s/%s", dirname, namelist[i]->d_name); - printerr(3, "CC file '%s' being considered, " + printerr(3, "CC '%s' being considered, " "with preferred realm '%s'\n", statname, preferred_realm ? preferred_realm : ""); - snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, - namelist[i]->d_name); if (lstat(statname, &tmp_stat)) { - printerr(0, "Error doing stat on file '%s'\n", + printerr(0, "Error doing stat on '%s'\n", statname); free(namelist[i]); continue; } /* Only pick caches owned by the user (uid) */ if (tmp_stat.st_uid != uid) { - printerr(3, "CC file '%s' owned by %u, not %u\n", + printerr(3, "CC '%s' owned by %u, not %u\n", statname, tmp_stat.st_uid, uid); free(namelist[i]); continue; } - if (!S_ISREG(tmp_stat.st_mode)) { - printerr(3, "CC file '%s' is not a regular file\n", + if (!S_ISREG(tmp_stat.st_mode) && + !S_ISDIR(tmp_stat.st_mode)) { + printerr(3, "CC '%s' is not a regular " + "file or directory\n", statname); free(namelist[i]); continue; } if (uid == 0 && !root_uses_machine_creds && strstr(namelist[i]->d_name, "_machine_")) { - printerr(3, "CC file '%s' not available to root\n", + printerr(3, "CC '%s' not available to root\n", statname); free(namelist[i]); continue; } + if (S_ISDIR(tmp_stat.st_mode)) { + *cctype = "DIR"; + } else + if (S_ISREG(tmp_stat.st_mode)) { + *cctype = "FILE"; + } else { + continue; + } + snprintf(buf, sizeof(buf), "%s:%s/%s", *cctype, + dirname, namelist[i]->d_name); if (!query_krb5_ccache(buf, &princname, &realm)) { - printerr(3, "CC file '%s' is expired or corrupt\n", - statname); + printerr(3, "CC '%s' is expired or corrupt\n", + buf); free(namelist[i]); err = -EKEYEXPIRED; continue; @@ -244,9 +260,9 @@ gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d) strcmp(realm, preferred_realm) == 0) score++; - printerr(3, "CC file '%s'(%s@%s) passed all checks and" + printerr(3, "CC '%s'(%s@%s) passed all checks and" " has mtime of %u\n", - statname, princname, realm, + buf, princname, realm, tmp_stat.st_mtime); /* * if more than one match is found, return the most @@ -280,10 +296,11 @@ gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d) else { free(namelist[i]); } - printerr(3, "CC file '%s/%s' is our " + printerr(3, "CC '%s:%s/%s' is our " "current best match " "with mtime of %u\n", - dirname, best_match_dir->d_name, + cctype, dirname, + best_match_dir->d_name, best_match_stat.st_mtime); } free(princname); @@ -1022,17 +1039,18 @@ int gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname) { char buf[MAX_NETOBJ_SZ]; + const char *cctype; struct dirent *d; int err; printerr(2, "getting credentials for client with uid %u for " "server %s\n", uid, servername); memset(buf, 0, sizeof(buf)); - err = gssd_find_existing_krb5_ccache(uid, dirname, &d); + err = gssd_find_existing_krb5_ccache(uid, dirname, &cctype, &d); if (err) return err; - snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name); + snprintf(buf, sizeof(buf), "%s:%s/%s", cctype, dirname, d->d_name); free(d); printerr(2, "using %s as credentials cache for client with " @@ -1342,7 +1360,7 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec) * If we failed for any reason to produce global * list of supported enctypes, use local default here. */ - if (krb5_enctypes == NULL) + if (krb5_enctypes == NULL || limit_to_legacy_enctypes) maj_stat = gss_set_allowable_enctypes(&min_stat, credh, &krb5oid, num_enctypes, enctypes); else