diff --git a/Makefile.am b/Makefile.am index 43c2710..c160a95 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,7 +29,8 @@ if LIBWRAP AM_CPPFLAGS += -DLIBWRAP endif -bin_PROGRAMS = rpcbind rpcinfo +bin_PROGRAMS = rpcinfo +sbin_PROGRAMS = rpcbind rpcbind_SOURCES = \ src/check_bound.c \ diff --git a/configure.ac b/configure.ac index 3790310..359a418 100644 --- a/configure.ac +++ b/configure.ac @@ -61,9 +61,9 @@ AC_SEARCH_LIBS([pthread_create], [pthread]) AC_CHECK_HEADERS([nss.h rpcsvc/mount.h]) -# make bindir available for substitution in config file +# make sbindir available for substitution in config file # 2 "evals" needed to expand variable names -AC_SUBST([_bindir]) -AC_CONFIG_COMMANDS_PRE([eval eval _bindir=$bindir]) +AC_SUBST([_sbindir]) +AC_CONFIG_COMMANDS_PRE([eval eval _sbindir=$sbindir]) AC_OUTPUT([Makefile systemd/rpcbind.service]) diff --git a/src/pmap_svc.c b/src/pmap_svc.c index 4c744fe..a53dd5f 100644 --- a/src/pmap_svc.c +++ b/src/pmap_svc.c @@ -175,6 +175,7 @@ pmapproc_change(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt, unsigned long long ans; uid_t uid; char uidbuf[32]; + int rc = TRUE; /* * Can't use getpwnam here. We might end up calling ourselves @@ -194,7 +195,8 @@ pmapproc_change(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt, unsigned long if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)®)) { svcerr_decode(xprt); - return (FALSE); + rc = FALSE; + goto done; } #ifdef RPCBIND_DEBUG if (debugging) @@ -205,7 +207,8 @@ pmapproc_change(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt, unsigned long if (!check_access(xprt, op, reg.pm_prog, PMAPVERS)) { svcerr_weakauth(xprt); - return (FALSE); + rc = (FALSE); + goto done; } rpcbreg.r_prog = reg.pm_prog; @@ -258,7 +261,18 @@ done_change: rpcbs_set(RPCBVERS_2_STAT, ans); else rpcbs_unset(RPCBVERS_2_STAT, ans); - return (TRUE); +done: + if (!svc_freeargs(xprt, (xdrproc_t) xdr_pmap, (char *)®)) { +#ifdef RPCBIND_DEBUG + if (debugging) { + (void) xlog(LOG_DEBUG, "unable to free arguments\n"); + if (doabort) { + rpcbind_abort(); + } + } +#endif + } + return (rc); } /* ARGSUSED */ @@ -272,15 +286,18 @@ pmapproc_getport(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt) #ifdef RPCBIND_DEBUG char *uaddr; #endif + int rc = TRUE; if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)®)) { svcerr_decode(xprt); - return (FALSE); + rc = FALSE; + goto done; } if (!check_access(xprt, PMAPPROC_GETPORT, reg.pm_prog, PMAPVERS)) { svcerr_weakauth(xprt); - return FALSE; + rc = FALSE; + goto done; } #ifdef RPCBIND_DEBUG @@ -330,21 +347,36 @@ pmapproc_getport(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt) pmap_ipprot2netid(reg.pm_prot) ?: "", port ? udptrans : ""); - return (TRUE); +done: + if (!svc_freeargs(xprt, (xdrproc_t) xdr_pmap, (char *)®)) { +#ifdef RPCBIND_DEBUG + if (debugging) { + (void) xlog(LOG_DEBUG, "unable to free arguments\n"); + if (doabort) { + rpcbind_abort(); + } + } +#endif + } + return (rc); } /* ARGSUSED */ static bool_t pmapproc_dump(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt) { + int rc = TRUE; + if (!svc_getargs(xprt, (xdrproc_t)xdr_void, NULL)) { svcerr_decode(xprt); - return (FALSE); + rc = FALSE; + goto done; } if (!check_access(xprt, PMAPPROC_DUMP, 0, PMAPVERS)) { svcerr_weakauth(xprt); - return FALSE; + rc = FALSE; + goto done; } if ((!svc_sendreply(xprt, (xdrproc_t) xdr_pmaplist_ptr, @@ -354,7 +386,19 @@ pmapproc_dump(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt) rpcbind_abort(); } } - return (TRUE); + +done: + if (!svc_freeargs(xprt, (xdrproc_t) xdr_void, (char *)NULL)) { +#ifdef RPCBIND_DEBUG + if (debugging) { + (void) xlog(LOG_DEBUG, "unable to free arguments\n"); + if (doabort) { + rpcbind_abort(); + } + } +#endif + } + return (rc); } int pmap_netid2ipprot(const char *netid) diff --git a/src/rpcb_svc.c b/src/rpcb_svc.c index 709e3fb..091f530 100644 --- a/src/rpcb_svc.c +++ b/src/rpcb_svc.c @@ -166,7 +166,7 @@ rpcb_service_3(struct svc_req *rqstp, SVCXPRT *transp) svcerr_decode(transp); if (debugging) (void) xlog(LOG_DEBUG, "rpcbind: could not decode"); - return; + goto done; } if (rqstp->rq_proc == RPCBPROC_SET diff --git a/src/rpcb_svc_4.c b/src/rpcb_svc_4.c index 5094879..eebbbbe 100644 --- a/src/rpcb_svc_4.c +++ b/src/rpcb_svc_4.c @@ -218,7 +218,7 @@ rpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp) svcerr_decode(transp); if (debugging) (void) xlog(LOG_DEBUG, "rpcbind: could not decode\n"); - return; + goto done; } if (rqstp->rq_proc == RPCBPROC_SET diff --git a/src/rpcb_svc_com.c b/src/rpcb_svc_com.c index 5862c26..9c1c3af 100644 --- a/src/rpcb_svc_com.c +++ b/src/rpcb_svc_com.c @@ -612,9 +612,7 @@ rpcbproc_callit_com(struct svc_req *rqstp, SVCXPRT *transp, struct netconfig *nconf; struct netbuf *caller; struct r_rmtcall_args a; - char *buf_alloc = NULL, *outbufp; - char *outbuf_alloc = NULL; - char buf[RPC_BUF_MAX], outbuf[RPC_BUF_MAX]; + char outbuf[RPC_BUF_MAX]; struct netbuf *na = (struct netbuf *) NULL; struct rpc_msg call_msg; int outlen; @@ -635,36 +633,10 @@ rpcbproc_callit_com(struct svc_req *rqstp, SVCXPRT *transp, } if (si.si_socktype != SOCK_DGRAM) return; /* Only datagram type accepted */ - sendsz = __rpc_get_t_size(si.si_af, si.si_proto, UDPMSGSIZE); - if (sendsz == 0) { /* data transfer not supported */ - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - return; - } - /* - * Should be multiple of 4 for XDR. - */ - sendsz = ((sendsz + 3) / 4) * 4; - if (sendsz > RPC_BUF_MAX) { -#ifdef notyet - buf_alloc = alloca(sendsz); /* not in IDR2? */ -#else - buf_alloc = malloc(sendsz); -#endif /* notyet */ - if (buf_alloc == NULL) { - if (debugging) - xlog(LOG_DEBUG, - "rpcbproc_callit_com: No Memory!\n"); - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - return; - } - a.rmt_args.args = buf_alloc; - } else { - a.rmt_args.args = buf; - } + sendsz = UDPMSGSIZE; call_msg.rm_xid = 0; /* For error checking purposes */ + memset(&a, 0, sizeof(a)); /* Zero out the input buffer */ if (!svc_getargs(transp, (xdrproc_t) xdr_rmtcall_args, (char *) &a)) { if (reply_type == RPCBPROC_INDIRECT) svcerr_decode(transp); @@ -700,11 +672,11 @@ rpcbproc_callit_com(struct svc_req *rqstp, SVCXPRT *transp, rpcbs_rmtcall(versnum - 2, reply_type, a.rmt_prog, a.rmt_vers, a.rmt_proc, transp->xp_netid, rbl); - if (rbl == (rpcblist_ptr)NULL) { #ifdef RPCBIND_DEBUG if (debugging) - xlog(LOG_DEBUG, "not found\n"); + xlog(LOG_DEBUG, "prog %lu vers %lu: not found\n", + a.rmt_prog, a.rmt_vers); #endif if (reply_type == RPCBPROC_INDIRECT) svcerr_noprog(transp); @@ -818,24 +790,10 @@ rpcbproc_callit_com(struct svc_req *rqstp, SVCXPRT *transp, call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; call_msg.rm_call.cb_prog = a.rmt_prog; call_msg.rm_call.cb_vers = a.rmt_vers; - if (sendsz > RPC_BUF_MAX) { -#ifdef notyet - outbuf_alloc = alloca(sendsz); /* not in IDR2? */ -#else - outbuf_alloc = malloc(sendsz); -#endif /* notyet */ - if (outbuf_alloc == NULL) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - if (debugging) - xlog(LOG_DEBUG, - "rpcbproc_callit_com: No memory!\n"); - goto error; - } - xdrmem_create(&outxdr, outbuf_alloc, sendsz, XDR_ENCODE); - } else { - xdrmem_create(&outxdr, outbuf, sendsz, XDR_ENCODE); - } + + memset(outbuf, '\0', sendsz); /* Zero out the output buffer */ + xdrmem_create(&outxdr, outbuf, sendsz, XDR_ENCODE); + if (!xdr_callhdr(&outxdr, &call_msg)) { if (reply_type == RPCBPROC_INDIRECT) svcerr_systemerr(transp); @@ -900,10 +858,6 @@ rpcbproc_callit_com(struct svc_req *rqstp, SVCXPRT *transp, goto error; } outlen = (int) XDR_GETPOS(&outxdr); - if (outbuf_alloc) - outbufp = outbuf_alloc; - else - outbufp = outbuf; na = uaddr2taddr(nconf, local_uaddr); if (!na) { @@ -912,7 +866,7 @@ rpcbproc_callit_com(struct svc_req *rqstp, SVCXPRT *transp, goto error; } - if (sendto(fd, outbufp, outlen, 0, (struct sockaddr *)na->buf, na->len) + if (sendto(fd, outbuf, outlen, 0, (struct sockaddr *)na->buf, na->len) != outlen) { if (debugging) xlog(LOG_DEBUG, @@ -927,12 +881,16 @@ error: if (call_msg.rm_xid != 0) (void) free_slot_by_xid(call_msg.rm_xid); out: + if (!svc_freeargs(transp, (xdrproc_t) xdr_rmtcall_args, (char *) &a)) { + if (debugging) { + (void) xlog(LOG_DEBUG, "unable to free arguments\n"); + if (doabort) { + rpcbind_abort(); + } + } + } if (local_uaddr) free(local_uaddr); - if (buf_alloc) - free(buf_alloc); - if (outbuf_alloc) - free(outbuf_alloc); if (na) { free(na->buf); free(na); @@ -1094,7 +1052,6 @@ void my_svc_run() { int poll_ret, check_ret; - int n; for (;;) { struct pollfd my_pollfd[svc_max_pollfd]; diff --git a/systemd/rpcbind.service.in b/systemd/rpcbind.service.in index e7e86da..7b1c74b 100644 --- a/systemd/rpcbind.service.in +++ b/systemd/rpcbind.service.in @@ -2,16 +2,17 @@ Description=RPC Bind Documentation=man:rpcbind(8) DefaultDependencies=no +RequiresMountsFor=@statedir@ # Make sure we use the IP addresses listed for # rpcbind.socket, no matter how this unit is started. -Wants=rpcbind.socket -After=rpcbind.socket +Requires=rpcbind.socket +Wants=rpcbind.target [Service] Type=notify # distro can provide a drop-in adding EnvironmentFile=-/??? if needed. -ExecStart=@_bindir@/rpcbind $RPCBIND_OPTIONS -w -f +ExecStart=@_sbindir@/rpcbind $RPCBIND_OPTIONS -w -f [Install] WantedBy=multi-user.target