X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fgssd%2Fkrb5_util.c;h=7ef690bfabcafc7ea5d353ddb3d85122b6accbae;hp=2f5e70ed2d78371e18b68ee744925866ad68126a;hb=72e1cf8784fbcb1bffa28b08f663ea9469634590;hpb=0f899e6d862994ffb437ae73e087c4a21ab59723 diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c index 2f5e70e..7ef690b 100644 --- a/utils/gssd/krb5_util.c +++ b/utils/gssd/krb5_util.c @@ -178,78 +178,73 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d) struct dirent *best_match_dir = NULL; struct stat best_match_stat, tmp_stat; + memset(&best_match_stat, 0, sizeof(best_match_stat)); *d = NULL; n = scandir(ccachedir, &namelist, select_krb5_ccache, 0); if (n < 0) { perror("scandir looking for krb5 credentials caches"); } else if (n > 0) { - char substring[128]; - char fullstring[128]; char statname[1024]; - snprintf(substring, sizeof(substring), "_%d_", uid); - snprintf(fullstring, sizeof(fullstring), "_%d", uid); for (i = 0; i < n; i++) { printerr(3, "CC file '%s' being considered\n", namelist[i]->d_name); - if (strstr(namelist[i]->d_name, substring) || - !strcmp(namelist[i]->d_name, fullstring)) { - snprintf(statname, sizeof(statname), - "%s/%s", ccachedir, - namelist[i]->d_name); - if (stat(statname, &tmp_stat)) { - printerr(0, "Error doing stat " - "on file '%s'\n", - statname); - continue; - } - if (!S_ISREG(tmp_stat.st_mode)) { - printerr(3, "File '%s' is not " - "a regular file\n", - statname); - continue; - } - printerr(3, "CC file '%s' matches " - "name check and has " - "mtime of %u\n", - namelist[i]->d_name, - tmp_stat.st_mtime); - /* if more than one match is found, - * return the most recent (the one - * with the latest mtime), - * and don't free the dirent */ - if (!found) { + snprintf(statname, sizeof(statname), + "%s/%s", ccachedir, namelist[i]->d_name); + if (lstat(statname, &tmp_stat)) { + printerr(0, "Error doing stat on file '%s'\n", + statname); + free(namelist[i]); + continue; + } + /* Only pick caches owned by the user (uid) */ + if (tmp_stat.st_uid != uid) { + printerr(3, "'%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, "'%s' is not a regular file\n", + statname); + free(namelist[i]); + continue; + } + printerr(3, "CC file '%s' matches owner check and has " + "mtime of %u\n", + namelist[i]->d_name, tmp_stat.st_mtime); + /* + * if more than one match is found, return the most + * recent (the one with the latest mtime), and + * don't free the dirent + */ + if (!found) { + best_match_dir = namelist[i]; + best_match_stat = tmp_stat; + found++; + } + else { + /* + * If the current match has an mtime later + * than the one we are looking at, then use + * the current match. Otherwise, we still + * have the best match. + */ + if (tmp_stat.st_mtime > + best_match_stat.st_mtime) { + free(best_match_dir); best_match_dir = namelist[i]; best_match_stat = tmp_stat; - found++; } else { - /* - * If the current match has - * an mtime later than the - * one we are looking at, - * then use the current match. - * Otherwise, we still have - * the best match. - */ - if (tmp_stat.st_mtime > - best_match_stat.st_mtime) { - free(best_match_dir); - best_match_dir = namelist[i]; - best_match_stat = tmp_stat; - } - else { - free(namelist[i]); - } - printerr(3, "CC file '%s' is our " - "current best match " - "with mtime of %u\n", - best_match_dir->d_name, - best_match_stat.st_mtime); + free(namelist[i]); } + printerr(3, "CC file '%s' is our " + "current best match " + "with mtime of %u\n", + best_match_dir->d_name, + best_match_stat.st_mtime); } - else - free(namelist[i]); } free(namelist); } @@ -303,6 +298,7 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid) if (maj_stat != GSS_S_COMPLETE) { pgsserr("gss_set_allowable_enctypes", maj_stat, min_stat, &krb5oid); + gss_release_cred(&min_stat, &credh); return -1; } sec->cred = credh; @@ -333,6 +329,7 @@ gssd_get_single_krb5_cred(krb5_context context, char cc_name[BUFSIZ]; int code; time_t now = time(0); + char *cache_type; memset(&my_creds, 0, sizeof(my_creds)); @@ -367,11 +364,7 @@ gssd_get_single_krb5_cred(krb5_context context, "principal '%s' from keytab '%s'\n", error_message(code), pname ? pname : "", kt_name); -#ifdef HAVE_KRB5 - if (pname) krb5_free_unparsed_name(context, pname); -#else - if (pname) free(pname); -#endif + if (pname) k5_free_unparsed_name(context, pname); goto out; } @@ -379,7 +372,12 @@ gssd_get_single_krb5_cred(krb5_context context, * Initialize cache file which we're going to be using */ - snprintf(cc_name, sizeof(cc_name), "FILE:%s/%s%s_%s", + if (use_memcache) + cache_type = "MEMORY"; + else + cache_type = "FILE"; + snprintf(cc_name, sizeof(cc_name), "%s:%s/%s%s_%s", + cache_type, GSSD_DEFAULT_CRED_DIR, GSSD_DEFAULT_CRED_PREFIX, GSSD_DEFAULT_MACHINE_CRED_SUFFIX, ple->realm); ple->endtime = my_creds.times.endtime; @@ -447,7 +445,7 @@ gssd_have_realm_ple(void *r) /* * Process the given keytab file and create a list of principals we - * might use to perform mount operations. + * might use as machine credentials. * * Returns: * 0 => Sucess @@ -464,9 +462,8 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name) /* * Look through each entry in the keytab file and determine - * if we might want to use it later to do a mount. If so, - * save info in the global principal list - * (gssd_k5_kt_princ_list). + * if we might want to use it as machine credentials. If so, + * save info in the global principal list (gssd_k5_kt_princ_list). * Note: (ple == principal list entry) */ if ((code = krb5_kt_start_seq_get(context, kt, &cursor))) { @@ -484,31 +481,20 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name) printerr(0, "WARNING: Skipping keytab entry because " "we failed to unparse principal name: %s\n", error_message(code)); + krb5_kt_free_entry(context, &kte); continue; } printerr(2, "Processing keytab entry for principal '%s'\n", pname); -#ifdef HAVE_KRB5 - if ( (kte.principal->data[0].length == GSSD_SERVICE_NAME_LEN) && - (strncmp(kte.principal->data[0].data, GSSD_SERVICE_NAME, - GSSD_SERVICE_NAME_LEN) == 0) && -#else - if ( (strlen(kte.principal->name.name_string.val[0]) == GSSD_SERVICE_NAME_LEN) && - (strncmp(kte.principal->name.name_string.val[0], GSSD_SERVICE_NAME, - GSSD_SERVICE_NAME_LEN) == 0) && - -#endif - (!gssd_have_realm_ple((void *)&kte.principal->realm)) ) { - printerr(2, "We will use this entry (%s)\n", pname); + /* Just use the first keytab entry found for each realm */ + if ((!gssd_have_realm_ple((void *)&kte.principal->realm)) ) { + printerr(2, "We WILL use this entry (%s)\n", pname); ple = malloc(sizeof(struct gssd_k5_kt_princ)); if (ple == NULL) { printerr(0, "ERROR: could not allocate storage " "for principal list entry\n"); -#ifdef HAVE_KRB5 - krb5_free_unparsed_name(context, pname); -#else - free(pname); -#endif + k5_free_unparsed_name(context, pname); + krb5_kt_free_entry(context, &kte); retval = ENOMEM; goto out; } @@ -527,11 +513,8 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name) printerr(0, "ERROR: %s while copying realm to " "principal list entry\n", "not enough memory"); -#ifdef HAVE_KRB5 - krb5_free_unparsed_name(context, pname); -#else - free(pname); -#endif + k5_free_unparsed_name(context, pname); + krb5_kt_free_entry(context, &kte); retval = ENOMEM; goto out; } @@ -540,11 +523,8 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name) printerr(0, "ERROR: %s while copying principal " "to principal list entry\n", error_message(code)); -#ifdef HAVE_KRB5 - krb5_free_unparsed_name(context, pname); -#else - free(pname); -#endif + k5_free_unparsed_name(context, pname); + krb5_kt_free_entry(context, &kte); retval = code; goto out; } @@ -559,11 +539,8 @@ gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name) printerr(2, "We will NOT use this entry (%s)\n", pname); } -#ifdef HAVE_KRB5 - krb5_free_unparsed_name(context, pname); -#else - free(pname); -#endif + k5_free_unparsed_name(context, pname); + krb5_kt_free_entry(context, &kte); } if ((code = krb5_kt_end_seq_get(context, kt, &cursor))) {