summaryrefslogtreecommitdiffstats
path: root/krb5-master-mechd.patch
blob: 965a4363b52c0a2f27efc87fbd800d768ab54ea0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
commit 123c14fd8862ee8f11f6084d25958cb380655f35
Author: Günther Deschner <gdeschner@redhat.com>
Date:   Wed Mar 5 16:21:55 2014 +0100

    Remove dead code from the mechglue initialization
    
    The stat check in gss_indicate_mechs had no consequent and would have
    been redundant with logic in updateMechList if it did.
    
    [ghudson@mit.edu: elaborated commit message; removed unused
    g_mechSetTime and now-irrelevant comment]

diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
index 48a825e..c6904e0 100644
--- a/src/lib/gssapi/mechglue/g_initialize.c
+++ b/src/lib/gssapi/mechglue/g_initialize.c
@@ -91,7 +91,6 @@ static gss_mech_info g_mechListTail = NULL;
 static k5_mutex_t g_mechListLock = K5_MUTEX_PARTIAL_INITIALIZER;
 static time_t g_confFileModTime = (time_t)0;
 
-static time_t g_mechSetTime = (time_t)0;
 static gss_OID_set_desc g_mechSet = { 0, NULL };
 static k5_mutex_t g_mechSetLock = K5_MUTEX_PARTIAL_INITIALIZER;
 
@@ -213,8 +212,6 @@ gss_indicate_mechs(minorStatus, mechSet_out)
 OM_uint32 *minorStatus;
 gss_OID_set *mechSet_out;
 {
-	char *fileName;
-	struct stat fileInfo;
 	OM_uint32 status;
 
 	/* Initialize outputs. */
@@ -233,16 +230,6 @@ gss_OID_set *mechSet_out;
 	if (*minorStatus != 0)
 		return (GSS_S_FAILURE);
 
-	fileName = MECH_CONF;
-
-	/*
-	 * If we have already computed the mechanisms supported and if it
-	 * is still valid; make a copy and return to caller,
-	 * otherwise build it first.
-	 */
-	if ((stat(fileName, &fileInfo) == 0 &&
-		fileInfo.st_mtime > g_mechSetTime)) {
-	} /* if g_mechSet is out of date or not initialized */
 	if (build_mechSet())
 		return GSS_S_FAILURE;
 
@@ -289,20 +276,6 @@ build_mechSet(void)
 	 */
 	k5_mutex_lock(&g_mechListLock);
 
-#if 0
-	/*
-	 * this checks for the case when we need to re-construct the
-	 * g_mechSet structure, but the mechanism list is upto date
-	 * (because it has been read by someone calling
-	 * gssint_get_mechanism)
-	 */
-	if (fileInfo.st_mtime > g_confFileModTime)
-	{
-		g_confFileModTime = fileInfo.st_mtime;
-		loadConfigFile(fileName);
-	}
-#endif
-
 	updateMechList();
 
 	/*

commit 05cbef80d53f49d30a5d0563501226dc173734d4
Author: Günther Deschner <gdeschner@redhat.com>
Date:   Wed Mar 5 15:25:43 2014 +0100

    Load mechglue config files from /etc/gss/mech.d
    
    In addition to loading /etc/gss/mech, glob for *.conf files in
    /etc/gss/mech.d.  Load only config files which have changed since the
    highest mtime we saw in the previous scan.  Scan at most once per
    second to avoid excessive numbers of filesystem syscalls for busy
    GSSAPI applications.
    
    [ghudson@mit.edu: rewrote commit message; style changes; added
    once-per-second throttle on glob/stat calls]
    
    ticket: 7882 (new)

diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
index c6904e0..f0acf1a 100644
--- a/src/lib/gssapi/mechglue/g_initialize.c
+++ b/src/lib/gssapi/mechglue/g_initialize.c
@@ -41,6 +41,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <errno.h>
+#include <glob.h>
 
 #define	M_DEFAULT	"default"
 
@@ -58,6 +59,7 @@
 #ifndef MECH_CONF
 #define	MECH_CONF "/etc/gss/mech"
 #endif
+#define MECH_CONF_PATTERN MECH_CONF ".d/*.conf"
 
 /* Local functions */
 static void addConfigEntry(const char *oidStr, const char *oid,
@@ -90,6 +92,7 @@ static gss_mech_info g_mechList = NULL;
 static gss_mech_info g_mechListTail = NULL;
 static k5_mutex_t g_mechListLock = K5_MUTEX_PARTIAL_INITIALIZER;
 static time_t g_confFileModTime = (time_t)0;
+static time_t g_confLastCall = (time_t)0;
 
 static gss_OID_set_desc g_mechSet = { 0, NULL };
 static k5_mutex_t g_mechSetLock = K5_MUTEX_PARTIAL_INITIALIZER;
@@ -383,6 +386,56 @@ const gss_OID oid;
 	return (modOptions);
 } /* gssint_get_modOptions */
 
+/* Return the mtime of filename or its eventual symlink target (if it is a
+ * symlink), whichever is larger.  Return (time_t)-1 if lstat or stat fails. */
+static time_t
+check_link_mtime(const char *filename, time_t *mtime_out)
+{
+	struct stat st1, st2;
+
+	if (lstat(filename, &st1) != 0)
+		return (time_t)-1;
+	if (!S_ISLNK(st1.st_mode))
+		return st1.st_mtime;
+	if (stat(filename, &st2) != 0)
+		return (time_t)-1;
+	return (st1.st_mtime > st2.st_mtime) ? st1.st_mtime : st2.st_mtime;
+}
+
+/* Try to load any config files which have changed since the last call.  Config
+ * files are MECH_CONF and any files matching MECH_CONF_PATTERN. */
+static void
+loadConfigFiles()
+{
+	glob_t globbuf;
+	time_t highest_mtime = 0, mtime, now;
+	char **pathptr;
+
+	/* Don't glob and stat more than once per second. */
+	if (time(&now) == (time_t)-1 || now == g_confLastCall)
+		return;
+	g_confLastCall = now;
+
+	globbuf.gl_offs = 1;
+	if (glob(MECH_CONF_PATTERN, GLOB_DOOFFS, NULL, &globbuf) != 0)
+		return;
+	globbuf.gl_pathv[0] = MECH_CONF;
+
+	for (pathptr = globbuf.gl_pathv; *pathptr != NULL; pathptr++) {
+		mtime = check_link_mtime(*pathptr, &mtime);
+		if (mtime == (time_t)-1)
+			continue;
+		if (mtime > highest_mtime)
+			highest_mtime = mtime;
+		if (mtime > g_confFileModTime)
+			loadConfigFile(*pathptr);
+	}
+	g_confFileModTime = highest_mtime;
+
+	globbuf.gl_pathv[0] = NULL;
+	globfree(&globbuf);
+}
+
 /*
  * determines if the mechList needs to be updated from file
  * and performs the update.
@@ -401,17 +454,7 @@ updateMechList(void)
 	loadConfigFromRegistry(HKEY_CURRENT_USER, MECH_KEY);
 	loadConfigFromRegistry(HKEY_LOCAL_MACHINE, MECH_KEY);
 #else /* _WIN32 */
-	char *fileName;
-	struct stat fileInfo;
-
-	fileName = MECH_CONF;
-
-	/* check if mechList needs updating */
-	if (stat(fileName, &fileInfo) != 0 ||
-	    g_confFileModTime >= fileInfo.st_mtime)
-		return;
-	g_confFileModTime = fileInfo.st_mtime;
-	loadConfigFile(fileName);
+	loadConfigFiles();
 #endif /* !_WIN32 */
 
 	/* Load any unloaded interposer mechanisms immediately, to make sure we

commit ac98187641f6943ae571606c0b6a97f236f9b60c
Author: Greg Hudson <ghudson@mit.edu>
Date:   Wed May 28 23:51:49 2014 -0400

    Read /etc/gss/mech if no mech.d/*.conf found
    
    Always read /etc/gss/mech, even if globbing /etc/gss/mech.d/*.conf
    doesn't work.  Doing this using GLOB_DOOFFS proved error-prone, so use
    a simpler approach: factor out the per-pathname handling into a helper
    function load_if_changed, call it with MECH_CONF before the glob, then
    pass each glob result through the helper.
    
    ticket: 7925

diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
index f0acf1a..8bce14c 100644
--- a/src/lib/gssapi/mechglue/g_initialize.c
+++ b/src/lib/gssapi/mechglue/g_initialize.c
@@ -402,38 +402,45 @@ check_link_mtime(const char *filename, time_t *mtime_out)
 	return (st1.st_mtime > st2.st_mtime) ? st1.st_mtime : st2.st_mtime;
 }
 
+/* Load pathname if it is newer than last.  Update *highest to the maximum of
+ * its current value and pathname's mod time. */
+static void
+load_if_changed(const char *pathname, time_t last, time_t *highest)
+{
+	time_t mtime;
+
+	mtime = check_link_mtime(pathname, &mtime);
+	if (mtime == (time_t)-1)
+		return;
+	if (mtime > *highest)
+		*highest = mtime;
+	if (mtime > last)
+		loadConfigFile(pathname);
+}
+
 /* Try to load any config files which have changed since the last call.  Config
  * files are MECH_CONF and any files matching MECH_CONF_PATTERN. */
 static void
 loadConfigFiles()
 {
 	glob_t globbuf;
-	time_t highest_mtime = 0, mtime, now;
-	char **pathptr;
+	time_t highest = 0, now;
+	char **path;
 
 	/* Don't glob and stat more than once per second. */
 	if (time(&now) == (time_t)-1 || now == g_confLastCall)
 		return;
 	g_confLastCall = now;
 
-	globbuf.gl_offs = 1;
-	if (glob(MECH_CONF_PATTERN, GLOB_DOOFFS, NULL, &globbuf) != 0)
-		return;
-	globbuf.gl_pathv[0] = MECH_CONF;
+	load_if_changed(MECH_CONF, g_confFileModTime, &highest);
 
-	for (pathptr = globbuf.gl_pathv; *pathptr != NULL; pathptr++) {
-		mtime = check_link_mtime(*pathptr, &mtime);
-		if (mtime == (time_t)-1)
-			continue;
-		if (mtime > highest_mtime)
-			highest_mtime = mtime;
-		if (mtime > g_confFileModTime)
-			loadConfigFile(*pathptr);
+	if (glob(MECH_CONF_PATTERN, 0, NULL, &globbuf) == 0) {
+		for (path = globbuf.gl_pathv; *path != NULL; path++)
+			load_if_changed(*path, g_confFileModTime, &highest);
+		globfree(&globbuf);
 	}
-	g_confFileModTime = highest_mtime;
 
-	globbuf.gl_pathv[0] = NULL;
-	globfree(&globbuf);
+	g_confFileModTime = highest;
 }
 
 /*