#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <netdb.h>
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
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 (stat(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);
}
* might use to perform mount operations.
*
* Returns:
- * 0 => Sucess
+ * 0 => Success
* nonzero => Error
*/
static int
gssd_set_krb5_ccache_name(char *ccname)
{
#ifdef USE_GSS_KRB5_CCACHE_NAME
- u_int maj_stat, min_stat;
+ unsigned int maj_stat, min_stat;
printerr(2, "using gss_krb5_ccache_name to select krb5 ccache %s\n",
ccname);
struct gssd_k5_kt_princ *ple;
/* Assume failure */
- retval = -1;
- *list = (char **) NULL;
+ *list = NULL;
/* Refresh machine credentials */
- if ((retval = gssd_refresh_krb5_machine_creds())) {
+ retval = gssd_refresh_krb5_machine_creds();
+ if (retval)
goto out;
- }
- if ((l = (char **) malloc(listsize * sizeof(char *))) == NULL) {
+ l = malloc(listsize * sizeof(char *));
+ if (l == NULL) {
retval = ENOMEM;
goto out;
}
for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) {
if (ple->ccname) {
if (i + 1 > listsize) {
+ void *tmp;
+
listsize += listinc;
- l = (char **)
- realloc(l, listsize * sizeof(char *));
- if (l == NULL) {
+ tmp = realloc(l, listsize * sizeof(char *));
+ if (tmp == NULL) {
retval = ENOMEM;
- goto out;
+ goto out_free;
}
+ l = tmp;
}
- if ((l[i++] = strdup(ple->ccname)) == NULL) {
+ l[i] = strdup(ple->ccname);
+ if (l[i++] == NULL) {
retval = ENOMEM;
- goto out;
+ goto out_free;
}
}
}
if (i > 0) {
l[i] = NULL;
*list = l;
- retval = 0;
- goto out;
+ return 0;
}
- out:
+out_free:
+ while (i > 0)
+ free(l[i--]);
+ free(l);
+out:
return retval;
}
krb5_free_context(context);
}
-#if 0
-#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
-/*
- * this routine obtains a credentials handle via gss_acquire_cred()
- * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
- * types negotiated.
- *
- * Returns:
- * 0 => all went well
- * -1 => there was an error
- */
-int
-limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
-{
- u_int maj_stat, min_stat;
- gss_cred_id_t credh;
- gss_OID_set_desc desired_mechs;
- krb5_enctype enctypes[] = {ENCTYPE_DES_CBC_CRC};
- int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
-
- /* We only care about getting a krb5 cred */
- desired_mechs.count = 1;
- desired_mechs.elements = &krb5oid;
-
- maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
- &desired_mechs, GSS_C_INITIATE,
- &credh, NULL, NULL);
-
- if (maj_stat != GSS_S_COMPLETE) {
- pgsserr("gss_acquire_cred",
- maj_stat, min_stat, &krb5oid);
- return -1;
- }
-
- /*
- * If we failed for any reason to produce global
- * list of supported enctypes, use local default here.
- */
- if (krb5_enctypes == NULL)
- maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
- &krb5oid, num_enctypes, &enctypes);
- else
- maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
- &krb5oid, num_krb5_enctypes,
- krb5_enctypes);
- if (maj_stat != GSS_S_COMPLETE) {
- pgsserr("gss_set_allowable_enctypes",
- maj_stat, min_stat, &krb5oid);
- return -1;
- }
- sec->cred = credh;
-
- return 0;
-}
-#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
-#endif
-
-/*
- * Obtain supported enctypes from kernel.
- * Set defaults if info is not available.
- */
-void
-gssd_obtain_kernel_krb5_info(void)
-{
- char enctype_file_name[128];
- char buf[1024];
- char enctypes[128];
- int nscanned;
- int fd;
- int use_default_enctypes = 0;
- int nbytes, numfields;
- char default_enctypes[] = "1,3,2";
- int code;
-
- snprintf(enctype_file_name, sizeof(enctype_file_name),
- "%s/%s", pipefs_dir, "krb5_info");
-
- if ((fd = open(enctype_file_name, O_RDONLY)) == -1) {
- printerr(1, "WARNING: gssd_obtain_kernel_krb5_info: "
- "Unable to open '%s'. Unable to determine "
- "Kerberos encryption types supported by the "
- "kernel; using defaults (%s).\n",
- enctype_file_name, default_enctypes);
- use_default_enctypes = 1;
- goto do_the_parse;
- }
- memset(buf, 0, sizeof(buf));
- if ((nbytes = read(fd, buf, sizeof(buf)-1)) == -1) {
- printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
- "Error reading Kerberos encryption type "
- "information file '%s'; using defaults (%s).\n",
- enctype_file_name, default_enctypes);
- use_default_enctypes = 1;
- close(fd);
- goto do_the_parse;
- }
- close(fd);
- numfields = sscanf(buf, "enctypes: %s\n%n", enctypes, &nscanned);
- if (numfields < 1) {
- printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
- "error parsing Kerberos encryption type "
- "information from file '%s'; using defaults (%s).\n",
- enctype_file_name, default_enctypes);
- use_default_enctypes = 1;
- goto do_the_parse;
- }
- if (nbytes > nscanned) {
- printerr(2, "gssd_obtain_kernel_krb5_info: "
- "Ignoring extra information, '%s', from '%s'\n",
- buf+nscanned, enctype_file_name);
- goto do_the_parse;
- }
- do_the_parse:
- if (use_default_enctypes)
- strcpy(enctypes, default_enctypes);
-
- if ((code = parse_enctypes(enctypes)) != 0) {
- printerr(0, "ERROR: gssd_obtain_kernel_krb5_info: "
- "parse_enctypes%s failed with code %d\n",
- use_default_enctypes ? " (with default enctypes)" : "",
- code);
- }
-}