--- ./utils/gssd/svcgssd.h 2014-12-13 12:10:20.700844068 +0000 +++ ./utils/gssd/svcgssd.h 2014-12-13 12:10:53.108844068 +0000 @@ -35,7 +35,7 @@ #include #include -void handle_nullreq(FILE *f); +void handle_nullreq(int *f); void gssd_run(void); #define GSSD_SERVICE_NAME "nfs" --- ./utils/gssd/gssd_proc.c 2014-12-13 12:05:34.334844068 +0000 +++ ./utils/gssd/gssd_proc.c 2014-12-13 12:10:10.052844068 +0000 @@ -77,6 +77,7 @@ #include "context.h" #include "nfsrpc.h" #include "nfslib.h" +#include "misc.h" /* * pollarray: @@ -1225,7 +1226,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; @@ -1235,11 +1236,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 */ @@ -1337,7 +1341,6 @@ handle_gssd_upcall(struct clnt_info *clp } out: - free(lbuf); free(mech); free(enctypes); free(target); --- ./utils/gssd/svcgssd_proc.c 2014-12-13 12:12:24.075844068 +0000 +++ ./utils/gssd/svcgssd_proc.c 2014-12-13 12:18:26.413844068 +0000 @@ -72,36 +72,34 @@ 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, @@ -109,19 +107,21 @@ do_svc_downcall(gss_buffer_desc *out_han client_name ? client_name : "", 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"); @@ -381,7 +381,7 @@ out_err: } 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; @@ -403,20 +403,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; in_handle.length = (size_t) qword_get(&cp, in_handle.value, --- ./utils/gssd/svcgssd_main_loop.c 2014-12-13 12:10:59.733844068 +0000 +++ ./utils/gssd/svcgssd_main_loop.c 2014-12-13 12:12:14.675844068 +0000 @@ -54,19 +54,19 @@ 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"); + f = open(NULLRPC_FILE, O_RDWR); - if (!f) { + 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;