aboutsummaryrefslogtreecommitdiffstats
path: root/main/nfs-utils/0003-gssd-talk-to-kernel-using-file-descriptors-instead-o.patch
blob: 735cc0d3b398a7151f21564f6935353c9bdb428f (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
From e2a56ac1aeaaca0d02fa4eae24bbd4d27e361e32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Thu, 2 Oct 2014 16:09:46 +0300
Subject: [PATCH v2 3/5] gssd: talk to kernel using file descriptors instead of
 FILE
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
 utils/gssd/gssd_proc.c         |  9 +++++---
 utils/gssd/svcgssd.h           |  2 +-
 utils/gssd/svcgssd_main_loop.c |  9 ++++----
 utils/gssd/svcgssd_proc.c      | 51 ++++++++++++++++++++++--------------------
 4 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
index 121feb1..1d8e6a7 100644
--- a/utils/gssd/gssd_proc.c
+++ b/utils/gssd/gssd_proc.c
@@ -78,6 +78,7 @@
 #include "nfsrpc.h"
 #include "nfslib.h"
 #include "gss_names.h"
+#include "misc.h"
 
 /*
  * pollarray:
@@ -1250,7 +1251,7 @@ void
 handle_gssd_upcall(struct clnt_info *clp)
 {
 	uid_t			uid;
-	char			*lbuf = NULL;
+	char			lbuf[RPC_CHAN_BUF_SIZE];
 	int			lbuflen = 0;
 	char			*p;
 	char			*mech = NULL;
@@ -1260,11 +1261,14 @@ handle_gssd_upcall(struct clnt_info *clp)
 
 	printerr(1, "handling gssd upcall (%s)\n", clp->dirname);
 
-	if (readline(clp->gssd_fd, &lbuf, &lbuflen) != 1) {
+	lbuflen = read(clp->gssd_fd, lbuf, sizeof(lbuf));
+	if (lbuflen <= 0 || lbuf[lbuflen-1] != '\n') {
 		printerr(0, "WARNING: handle_gssd_upcall: "
 			    "failed reading request\n");
 		return;
 	}
+	lbuf[lbuflen-1] = 0;
+
 	printerr(2, "%s: '%s'\n", __func__, lbuf);
 
 	/* find the mechanism name */
@@ -1362,7 +1366,6 @@ handle_gssd_upcall(struct clnt_info *clp)
 	}
 
 out:
-	free(lbuf);
 	free(mech);
 	free(enctypes);
 	free(target);
diff --git a/utils/gssd/svcgssd.h b/utils/gssd/svcgssd.h
index 9a2e2e8..02b5c7a 100644
--- a/utils/gssd/svcgssd.h
+++ b/utils/gssd/svcgssd.h
@@ -35,7 +35,7 @@
 #include <sys/queue.h>
 #include <gssapi/gssapi.h>
 
-void handle_nullreq(FILE *f);
+void handle_nullreq(int f);
 void gssd_run(void);
 
 #define GSSD_SERVICE_NAME	"nfs"
diff --git a/utils/gssd/svcgssd_main_loop.c b/utils/gssd/svcgssd_main_loop.c
index 2b4111c..b5681ce 100644
--- a/utils/gssd/svcgssd_main_loop.c
+++ b/utils/gssd/svcgssd_main_loop.c
@@ -54,19 +54,18 @@ void
 gssd_run()
 {
 	int			ret;
-	FILE			*f;
+	int			f;
 	struct pollfd		pollfd;
 
 #define NULLRPC_FILE "/proc/net/rpc/auth.rpcsec.init/channel"
 
-	f = fopen(NULLRPC_FILE, "rw");
-
-	if (!f) {
+	f = open(NULLRPC_FILE, O_RDWR);
+	if (f < 0) {
 		printerr(0, "failed to open %s: %s\n",
 			 NULLRPC_FILE, strerror(errno));
 		exit(1);
 	}
-	pollfd.fd = fileno(f);
+	pollfd.fd = f;
 	pollfd.events = POLLIN;
 	while (1) {
 		int save_err;
diff --git a/utils/gssd/svcgssd_proc.c b/utils/gssd/svcgssd_proc.c
index 5bdb438..72ec254 100644
--- a/utils/gssd/svcgssd_proc.c
+++ b/utils/gssd/svcgssd_proc.c
@@ -73,36 +73,35 @@ struct svc_cred {
 	int	cr_ngroups;
 	gid_t	cr_groups[NGROUPS];
 };
-static char vbuf[RPC_CHAN_BUF_SIZE];
 
 static int
 do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
 		gss_OID mech, gss_buffer_desc *context_token,
 		int32_t endtime, char *client_name)
 {
-	FILE *f;
-	int i;
+	char buf[RPC_CHAN_BUF_SIZE], *bp;
+	int i, f, err, blen;
 	char *fname = NULL;
-	int err;
 
 	printerr(1, "doing downcall\n");
 	if ((fname = mech2file(mech)) == NULL)
 		goto out_err;
-	f = fopen(SVCGSSD_CONTEXT_CHANNEL, "w");
-	if (f == NULL) {
+
+	f = open(SVCGSSD_CONTEXT_CHANNEL, O_WRONLY);
+	if (f < 0) {
 		printerr(0, "WARNING: unable to open downcall channel "
 			     "%s: %s\n",
 			     SVCGSSD_CONTEXT_CHANNEL, strerror(errno));
 		goto out_err;
 	}
-	setvbuf(f, vbuf, _IOLBF, RPC_CHAN_BUF_SIZE);
-	qword_printhex(f, out_handle->value, out_handle->length);
+	bp = buf, blen = sizeof(buf);
+	qword_addhex(&bp, &blen, out_handle->value, out_handle->length);
 	/* XXX are types OK for the rest of this? */
 	/* For context cache, use the actual context endtime */
-	qword_printint(f, endtime);
-	qword_printint(f, cred->cr_uid);
-	qword_printint(f, cred->cr_gid);
-	qword_printint(f, cred->cr_ngroups);
+	qword_addint(&bp, &blen, endtime);
+	qword_addint(&bp, &blen, cred->cr_uid);
+	qword_addint(&bp, &blen, cred->cr_gid);
+	qword_addint(&bp, &blen, cred->cr_ngroups);
 	printerr(2, "mech: %s, hndl len: %d, ctx len %d, timeout: %d (%d from now), "
 		 "clnt: %s, uid: %d, gid: %d, num aux grps: %d:\n",
 		 fname, out_handle->length, context_token->length,
@@ -110,19 +109,21 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
 		 client_name ? client_name : "<null>",
 		 cred->cr_uid, cred->cr_gid, cred->cr_ngroups);
 	for (i=0; i < cred->cr_ngroups; i++) {
-		qword_printint(f, cred->cr_groups[i]);
+		qword_addint(&bp, &blen, cred->cr_groups[i]);
 		printerr(2, "  (%4d) %d\n", i+1, cred->cr_groups[i]);
 	}
-	qword_print(f, fname);
-	qword_printhex(f, context_token->value, context_token->length);
+	qword_add(&bp, &blen, fname);
+	qword_addhex(&bp, &blen, context_token->value, context_token->length);
 	if (client_name)
-		qword_print(f, client_name);
-	err = qword_eol(f);
-	if (err) {
+		qword_add(&bp, &blen, client_name);
+	qword_addeol(&bp, &blen);
+	err = 0;
+	if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) {
 		printerr(1, "WARNING: error writing to downcall channel "
 			 "%s: %s\n", SVCGSSD_CONTEXT_CHANNEL, strerror(errno));
+		err = -1;
 	}
-	fclose(f);
+	close(f);
 	return err;
 out_err:
 	printerr(1, "WARNING: downcall failed\n");
@@ -317,7 +318,7 @@ print_hexl(const char *description, unsigned char *cp, int length)
 #endif
 
 void
-handle_nullreq(FILE *f) {
+handle_nullreq(int f) {
 	/* XXX initialize to a random integer to reduce chances of unnecessary
 	 * invalidation of existing ctx's on restarting svcgssd. */
 	static u_int32_t	handle_seq = 0;
@@ -339,19 +340,21 @@ handle_nullreq(FILE *f) {
 	u_int32_t		maj_stat = GSS_S_FAILURE, min_stat = 0;
 	u_int32_t		ignore_min_stat;
 	struct svc_cred		cred;
-	static char		*lbuf = NULL;
-	static int		lbuflen = 0;
-	static char		*cp;
+	char			lbuf[RPC_CHAN_BUF_SIZE];
+	int			lbuflen = 0;
+	char			*cp;
 	int32_t			ctx_endtime;
 	char			*hostbased_name = NULL;
 
 	printerr(1, "handling null request\n");
 
-	if (readline(fileno(f), &lbuf, &lbuflen) != 1) {
+	lbuflen = read(f, lbuf, sizeof(lbuf));
+	if (lbuflen <= 0 || lbuf[lbuflen-1] != '\n') {
 		printerr(0, "WARNING: handle_nullreq: "
 			    "failed reading request\n");
 		return;
 	}
+	lbuf[lbuflen-1] = 0;
 
 	cp = lbuf;
 
-- 
2.1.2