]> git.pld-linux.org Git - packages/nfs-utils.git/commitdiff
- rel 5 auto/th/nfs-utils-1_2_3-5 auto/ti/nfs-utils-1_2_3-5
authorJan Rękorajski <baggins@pld-linux.org>
Mon, 18 Oct 2010 17:28:12 +0000 (17:28 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
- Heimdal KCM credential cache support for gssd

Changed files:
    nfs-utils-heimdal-kcm.patch -> 1.1
    nfs-utils.spec -> 1.199

nfs-utils-heimdal-kcm.patch [new file with mode: 0644]
nfs-utils.spec

diff --git a/nfs-utils-heimdal-kcm.patch b/nfs-utils-heimdal-kcm.patch
new file mode 100644 (file)
index 0000000..ccf7511
--- /dev/null
@@ -0,0 +1,212 @@
+diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
+index ccadb07..c1339b6 100644
+--- a/utils/gssd/gssd.c
++++ b/utils/gssd/gssd.c
+@@ -60,6 +60,7 @@ char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
+ char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR;
+ char *ccachesearch[GSSD_MAX_CCACHE_SEARCH + 1];
+ int  use_memcache = 0;
++int  use_kcmcache = 0;
+ int  root_uses_machine_creds = 1;
+ unsigned int  context_timeout = 0;
+ char *preferred_realm = NULL;
+@@ -85,7 +86,7 @@ sig_hup(int signal)
+ static void
+ usage(char *progname)
+ {
+-      fprintf(stderr, "usage: %s [-f] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm]\n",
++      fprintf(stderr, "usage: %s [-f] [-K] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm]\n",
+               progname);
+       exit(1);
+ }
+@@ -102,7 +103,7 @@ main(int argc, char *argv[])
+       char *progname;
+       memset(ccachesearch, 0, sizeof(ccachesearch));
+-      while ((opt = getopt(argc, argv, "fvrmnMp:k:d:t:R:")) != -1) {
++      while ((opt = getopt(argc, argv, "fvrmnMKp:k:d:t:R:")) != -1) {
+               switch (opt) {
+                       case 'f':
+                               fg = 1;
+@@ -113,6 +114,9 @@ main(int argc, char *argv[])
+                       case 'M':
+                               use_memcache = 1;
+                               break;
++                      case 'K':
++                              use_kcmcache = 1;
++                              break;
+                       case 'n':
+                               root_uses_machine_creds = 0;
+                               break;
+diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
+index b1b5793..82c4406 100644
+--- a/utils/gssd/gssd.h
++++ b/utils/gssd/gssd.h
+@@ -63,6 +63,7 @@ extern char                  pipefs_dir[PATH_MAX];
+ extern char                   keytabfile[PATH_MAX];
+ extern char                   *ccachesearch[];
+ extern int                    use_memcache;
++extern int                    use_kcmcache;
+ extern int                    root_uses_machine_creds;
+ extern unsigned int           context_timeout;
+ extern char                   *preferred_realm;
+diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
+index f071600..503cac2 100644
+--- a/utils/gssd/krb5_util.c
++++ b/utils/gssd/krb5_util.c
+@@ -125,6 +125,7 @@
+ #include "err_util.h"
+ #include "gss_util.h"
+ #include "krb5_util.h"
++#include "xcommon.h"
+ /* Global list of principals/cache file names for machine credentials */
+ struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL;
+@@ -299,6 +300,115 @@ gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d)
+       return err;
+ }
++#ifdef HAVE_HEIMDAL
++static int
++gssd_find_existing_krb5_ccache_kcm(uid_t uid, char **cc)
++{
++      krb5_context context;
++      krb5_cc_cache_cursor cursor;
++      krb5_ccache id;
++      char *best_match_name = NULL;
++      krb5_timestamp best_match_mtime, mtime;
++      char *ccname;
++      uid_t ccuid;
++      int i;
++      int found = 0;
++      char buf[1030];
++      char *princname = NULL;
++      char *realm = NULL;
++      int score, best_match_score = 0, err = -EACCES;
++
++      *cc = NULL;
++      if (krb5_init_context(&context))
++              return err;
++
++      if (krb5_cc_cache_get_first(context, "KCM", &cursor))
++              return err;
++
++      while (krb5_cc_cache_next(context, cursor, &id) == 0) {
++              ccname = xstrdup(krb5_cc_get_name(context, id));
++              if (ccname == NULL) {
++                      printerr(0, "Error getting CC name\n");
++                      continue;
++              }
++              for (i=0,ccuid=0; ccname[i] && isdigit(ccname[i]); i++) {
++                      ccuid = ccuid*10 + (ccname[i] - '0');
++              }
++              if (i == 0) {
++                      printerr(3, "CC '%s' not available due to"
++                                      " non-standard name\n",
++                               ccname);
++                      continue;
++              }
++              /* Only pick caches owned by the user (uid) */
++              if (ccuid != uid) {
++                      printerr(3, "CC '%s' owned by %u, not %u\n",
++                               ccname, ccuid, uid);
++                      continue;
++              }
++              snprintf(buf, sizeof(buf), "KCM:%s", ccname);
++              if (!query_krb5_ccache(buf, &princname, &realm)) {
++                      printerr(3, "CC '%s' is expired or corrupt\n",
++                               ccname);
++                      err = -EKEYEXPIRED;
++                      continue;
++              }
++              krb5_cc_last_change_time(context, id, &mtime);
++
++              score = 0;
++              if (preferred_realm && strcmp(realm, preferred_realm) == 0) 
++                      score++;
++
++              printerr(3, "CC '%s'(%s@%s) passed all checks and"
++                          " has mtime of %u\n",
++                       ccname, princname, realm, 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_name = ccname;
++                      best_match_mtime = mtime;
++                      best_match_score = score;
++                      found++;
++              } else {
++                      /*
++                       * If current score is higher than best match 
++                       * score, we use the current match. Otherwise,
++                       * 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 (best_match_score < score ||
++                          (best_match_score == score && 
++                             mtime > best_match_mtime)) {
++                              free(best_match_name);
++                              best_match_name = ccname;
++                              best_match_mtime = mtime;
++                              best_match_score = score;
++                      } else {
++                              free(ccname);
++                      }
++                      printerr(3, "CC '%s' is our current best match "
++                                  "with mtime of %u\n",
++                               best_match_name, best_match_mtime);
++              }
++              free(princname);
++              free(realm);
++      }
++      krb5_cc_cache_end_seq_get(context, cursor);
++      krb5_free_context(context);
++      if (found) {
++              *cc = best_match_name;
++              return 0;
++      }
++
++      return err;
++}
++#endif
++
+ /*
+  * Obtain credentials via a key in the keytab given
+  * a keytab handle and a gssd_k5_kt_princ structure.
+@@ -1002,12 +1112,26 @@ gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname)
+       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);
+-      if (err)
+-              return err;
++#ifdef HAVE_HEIMDAL
++      if (use_kcmcache) {
++              char *s;
++              err = gssd_find_existing_krb5_ccache_kcm(uid, &s);
++              if (err)
++                      return err;
++
++              snprintf(buf, sizeof(buf), "KCM:%s", s);
++              free(s);
++      } else {
++#endif
++              err = gssd_find_existing_krb5_ccache(uid, dirname, &d);
++              if (err)
++                      return err;
+-      snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name);
+-      free(d);
++              snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name);
++              free(d);
++#ifdef HAVE_HEIMDAL
++      }
++#endif
+       printerr(2, "using %s as credentials cache for client with "
+                   "uid %u for server %s\n", buf, uid, servername);
index be6708a320ff8e33133cabe1d0a392b8ed98c007..6767762d74cfdb417d64fd583b857805acddbc2a 100644 (file)
@@ -13,7 +13,7 @@ Summary(ru.UTF-8):    Утилиты для NFS и демоны поддержки
 Summary(uk.UTF-8):     Утиліти для NFS та демони підтримки для NFS-сервера ядра
 Name:          nfs-utils
 Version:       1.2.3
-Release:       4
+Release:       5
 License:       GPL v2
 Group:         Networking/Daemons
 Source0:       http://www.kernel.org/pub/linux/utils/nfs/%{name}-%{version}.tar.bz2
@@ -36,6 +36,7 @@ Patch2:               %{name}-subsys.patch
 Patch3:                %{name}-union-mount.patch
 Patch4:                %{name}-heimdal.patch
 Patch5:                svc-create-fixed-port.patch
+Patch6:                %{name}-heimdal-kcm.patch
 URL:           http://nfs.sourceforge.net/
 BuildRequires: autoconf >= 2.59
 BuildRequires: automake
@@ -172,6 +173,7 @@ Wspólne programy do obsługi NFS.
 %patch3 -p1
 %patch4 -p1
 %patch5 -p1
+%patch6 -p1
 
 %build
 %{__libtoolize}
This page took 0.052295 seconds and 4 git commands to generate.