Package: krb5 / 1.12.1+dfsg-19+deb8u4

upstream/0011-Load-mechglue-config-files-from-etc-gss-mech.d.patch Patch series | download
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
From d60787cd0a5d2fb43ce107b4aa0bc5d6ad9f6e3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gdeschner@redhat.com>
Date: Wed, 5 Mar 2014 15:25:43 +0100
Subject: 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)

Patch-Category: upstream
---
 src/lib/gssapi/mechglue/g_initialize.c | 65 ++++++++++++++++++++++++++++------
 1 file changed, 54 insertions(+), 11 deletions(-)

diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
index 0c37063..a586e1c 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 time_t g_mechSetTime = (time_t)0;
 static gss_OID_set_desc g_mechSet = { 0, NULL };
@@ -410,6 +413,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.
@@ -428,17 +481,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