]> git.pld-linux.org Git - packages/nfs-utils.git/blame - nfs-utils-heimdal-kcm.patch
- merge -lock into -common
[packages/nfs-utils.git] / nfs-utils-heimdal-kcm.patch
CommitLineData
f5eebee2
JR
1diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
2index ccadb07..c1339b6 100644
3--- a/utils/gssd/gssd.c
4+++ b/utils/gssd/gssd.c
5@@ -60,6 +60,7 @@ char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
6 char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR;
7 char *ccachesearch[GSSD_MAX_CCACHE_SEARCH + 1];
8 int use_memcache = 0;
9+int use_kcmcache = 0;
10 int root_uses_machine_creds = 1;
11 unsigned int context_timeout = 0;
12 char *preferred_realm = NULL;
13@@ -85,7 +86,7 @@ sig_hup(int signal)
14 static void
15 usage(char *progname)
16 {
17- fprintf(stderr, "usage: %s [-f] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm]\n",
18+ fprintf(stderr, "usage: %s [-f] [-K] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm]\n",
19 progname);
20 exit(1);
21 }
22@@ -102,7 +103,7 @@ main(int argc, char *argv[])
23 char *progname;
24
25 memset(ccachesearch, 0, sizeof(ccachesearch));
26- while ((opt = getopt(argc, argv, "fvrmnMp:k:d:t:R:")) != -1) {
27+ while ((opt = getopt(argc, argv, "fvrmnMKp:k:d:t:R:")) != -1) {
28 switch (opt) {
29 case 'f':
30 fg = 1;
31@@ -113,6 +114,9 @@ main(int argc, char *argv[])
32 case 'M':
33 use_memcache = 1;
34 break;
35+ case 'K':
36+ use_kcmcache = 1;
37+ break;
38 case 'n':
39 root_uses_machine_creds = 0;
40 break;
41diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
42index b1b5793..82c4406 100644
43--- a/utils/gssd/gssd.h
44+++ b/utils/gssd/gssd.h
45@@ -63,6 +63,7 @@ extern char pipefs_dir[PATH_MAX];
46 extern char keytabfile[PATH_MAX];
47 extern char *ccachesearch[];
48 extern int use_memcache;
49+extern int use_kcmcache;
50 extern int root_uses_machine_creds;
51 extern unsigned int context_timeout;
52 extern char *preferred_realm;
53diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
54index f071600..503cac2 100644
55--- a/utils/gssd/krb5_util.c
56+++ b/utils/gssd/krb5_util.c
57@@ -125,6 +125,7 @@
58 #include "err_util.h"
59 #include "gss_util.h"
60 #include "krb5_util.h"
61+#include "xcommon.h"
62
63 /* Global list of principals/cache file names for machine credentials */
64 struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL;
65@@ -299,6 +300,115 @@ gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d)
66 return err;
67 }
68
69+#ifdef HAVE_HEIMDAL
70+static int
71+gssd_find_existing_krb5_ccache_kcm(uid_t uid, char **cc)
72+{
73+ krb5_context context;
74+ krb5_cc_cache_cursor cursor;
75+ krb5_ccache id;
76+ char *best_match_name = NULL;
77+ krb5_timestamp best_match_mtime, mtime;
78+ char *ccname;
79+ uid_t ccuid;
80+ int i;
81+ int found = 0;
82+ char buf[1030];
83+ char *princname = NULL;
84+ char *realm = NULL;
85+ int score, best_match_score = 0, err = -EACCES;
86+
87+ *cc = NULL;
88+ if (krb5_init_context(&context))
89+ return err;
90+
91+ if (krb5_cc_cache_get_first(context, "KCM", &cursor))
92+ return err;
93+
94+ while (krb5_cc_cache_next(context, cursor, &id) == 0) {
95+ ccname = xstrdup(krb5_cc_get_name(context, id));
96+ if (ccname == NULL) {
97+ printerr(0, "Error getting CC name\n");
98+ continue;
99+ }
100+ for (i=0,ccuid=0; ccname[i] && isdigit(ccname[i]); i++) {
101+ ccuid = ccuid*10 + (ccname[i] - '0');
102+ }
103+ if (i == 0) {
104+ printerr(3, "CC '%s' not available due to"
105+ " non-standard name\n",
106+ ccname);
107+ continue;
108+ }
109+ /* Only pick caches owned by the user (uid) */
110+ if (ccuid != uid) {
111+ printerr(3, "CC '%s' owned by %u, not %u\n",
112+ ccname, ccuid, uid);
113+ continue;
114+ }
115+ snprintf(buf, sizeof(buf), "KCM:%s", ccname);
116+ if (!query_krb5_ccache(buf, &princname, &realm)) {
117+ printerr(3, "CC '%s' is expired or corrupt\n",
118+ ccname);
119+ err = -EKEYEXPIRED;
120+ continue;
121+ }
122+ krb5_cc_last_change_time(context, id, &mtime);
123+
124+ score = 0;
125+ if (preferred_realm && strcmp(realm, preferred_realm) == 0)
126+ score++;
127+
128+ printerr(3, "CC '%s'(%s@%s) passed all checks and"
129+ " has mtime of %u\n",
130+ ccname, princname, realm, mtime);
131+ /*
132+ * if more than one match is found, return the most
133+ * recent (the one with the latest mtime), and
134+ * don't free the dirent
135+ */
136+ if (!found) {
137+ best_match_name = ccname;
138+ best_match_mtime = mtime;
139+ best_match_score = score;
140+ found++;
141+ } else {
142+ /*
143+ * If current score is higher than best match
144+ * score, we use the current match. Otherwise,
145+ * if the current match has an mtime later
146+ * than the one we are looking at, then use
147+ * the current match. Otherwise, we still
148+ * have the best match.
149+ */
150+ if (best_match_score < score ||
151+ (best_match_score == score &&
152+ mtime > best_match_mtime)) {
153+ free(best_match_name);
154+ best_match_name = ccname;
155+ best_match_mtime = mtime;
156+ best_match_score = score;
157+ } else {
158+ free(ccname);
159+ }
160+ printerr(3, "CC '%s' is our current best match "
161+ "with mtime of %u\n",
162+ best_match_name, best_match_mtime);
163+ }
164+ free(princname);
165+ free(realm);
166+ }
167+ krb5_cc_cache_end_seq_get(context, cursor);
168+ krb5_free_context(context);
169+ if (found) {
170+ *cc = best_match_name;
171+ return 0;
172+ }
173+
174+ return err;
175+}
176+#endif
177+
178 /*
179 * Obtain credentials via a key in the keytab given
180 * a keytab handle and a gssd_k5_kt_princ structure.
181@@ -1002,12 +1112,26 @@ gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname)
182 printerr(2, "getting credentials for client with uid %u for "
183 "server %s\n", uid, servername);
184 memset(buf, 0, sizeof(buf));
185- err = gssd_find_existing_krb5_ccache(uid, dirname, &d);
186- if (err)
187- return err;
188+#ifdef HAVE_HEIMDAL
189+ if (use_kcmcache) {
190+ char *s;
191+ err = gssd_find_existing_krb5_ccache_kcm(uid, &s);
192+ if (err)
193+ return err;
194+
195+ snprintf(buf, sizeof(buf), "KCM:%s", s);
196+ free(s);
197+ } else {
198+#endif
199+ err = gssd_find_existing_krb5_ccache(uid, dirname, &d);
200+ if (err)
201+ return err;
202
203- snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name);
204- free(d);
205+ snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name);
206+ free(d);
207+#ifdef HAVE_HEIMDAL
208+ }
209+#endif
210
211 printerr(2, "using %s as credentials cache for client with "
212 "uid %u for server %s\n", buf, uid, servername);
This page took 0.301475 seconds and 4 git commands to generate.