]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/gssd/krb5_util.c
Hide differences between MIT and Heimdal in macros
[nfs-utils.git] / utils / gssd / krb5_util.c
index c43eb36254e33a766c0f5897c99fffc43fdbd1a0..7ef690bfabcafc7ea5d353ddb3d85122b6accbae 100644 (file)
@@ -185,72 +185,66 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
                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);
        }
@@ -304,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;
@@ -369,11 +364,7 @@ gssd_get_single_krb5_cred(krb5_context context,
                            "principal '%s' from keytab '%s'\n",
                         error_message(code),
                         pname ? pname : "<unparsable>", 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;
        }
 
@@ -454,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
@@ -471,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))) {
@@ -491,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;
                        }
@@ -534,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;
                        }
@@ -547,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;
                        }
@@ -566,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))) {