diff options
author | alfred <alfred@FreeBSD.org> | 2002-02-05 19:30:30 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2002-02-05 19:30:30 +0000 |
commit | 33d91c2dd3a6841c8dfaa3c863181e4650878dbb (patch) | |
tree | b89c66dc0378771d82472c775eacb8cbac557395 /lib | |
parent | 4b6dfb0371e69053a084f9be4527d00c21ff21b2 (diff) | |
download | FreeBSD-src-33d91c2dd3a6841c8dfaa3c863181e4650878dbb.zip FreeBSD-src-33d91c2dd3a6841c8dfaa3c863181e4650878dbb.tar.gz |
Fix the credential handling code.
In NetBSD, Solaris, xprt->xp_p2 pointed directly to the credentials,
in FreeBSD xprt->xp_verf.oa_base was a pointer to a struct cmessage,
which is defined as follow:
struct cmessage {
struct cmsghdr cmsg;
struct cmsgcred cmcred;
};
The credentials were submitted the right way and xprt->xp_p2 pointed to them.
But cb_verf.oa_flavor was still empty. There was an assignment missing
in svc_recv() in svc_vc.c:
msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX;
Also
+ if (addr.ss_family == AF_LOCAL) {
+ xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf;
+ xprt->xp_addrlen = sizeof (struct sockaddr_in);
+ }
was missing. But the first seems not to be needed:
I guess in rpc.yppasswdd there was a typo:
- transp>xp_verf.oa_flavor != AUTH_UNIX) {
+ rqstp->rq_cred.oa_flavor != AUTH_UNIX) {
This little fix does fix the breakage in rpc.yppasswdd :-)
+ if (msg.msg_controllen == 0 ||
+ (msg.msg_flags & MSG_CTRUNC) != 0)
+ return (-1);
We cannot set the cb_verf.oa_length in svc_recv() of svc_vc.c,
the credentials get overwritten then, and that's bad.
Submitted by: mbr
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/rpc/svc_vc.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/lib/libc/rpc/svc_vc.c b/lib/libc/rpc/svc_vc.c index 95b907a..4ba71e2 100644 --- a/lib/libc/rpc/svc_vc.c +++ b/lib/libc/rpc/svc_vc.c @@ -313,6 +313,10 @@ again: return (FALSE); memcpy(xprt->xp_rtaddr.buf, &addr, len); xprt->xp_rtaddr.len = len; + if (addr.ss_family == AF_LOCAL) { + xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf; + xprt->xp_addrlen = sizeof (struct sockaddr_in); + } #ifdef PORTMAP if (addr.ss_family == AF_INET) { xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf; @@ -423,13 +427,15 @@ read_vc(xprtp, buf, len) } } while ((pollfd.revents & POLLIN) == 0); + cm = NULL; sa = (struct sockaddr *)xprt->xp_rtaddr.buf; if (sa->sa_family == AF_LOCAL) { cm = (struct cmessage *)xprt->xp_verf.oa_base; if ((len = __msgread_withcred(sock, buf, len, cm)) > 0) { xprt->xp_p2 = &cm->cmcred; return (len); - } + } else + goto fatal_err; } else { if ((len = _read(sock, buf, (size_t)len)) > 0) return (len); @@ -656,7 +662,12 @@ __msgread_withcred(sock, buf, cnt, cmp) ret = _recvmsg(sock, &msg, 0); bcopy(&cm.cmsg, &cmp->cmsg, sizeof(cmp->cmsg)); bcopy(CMSG_DATA(&cm), &cmp->cmcred, sizeof(cmp->cmcred)); - return ret; + + if (msg.msg_controllen == 0 || + (msg.msg_flags & MSG_CTRUNC) != 0) + return (-1); + + return (ret); } static int @@ -696,6 +707,17 @@ int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid) { struct cmsgcred *cmcred; + struct cmessage *cm; + struct cmsghdr *cmp; + + cm = (struct cmessage *)transp->xp_verf.oa_base; + + if (cm == NULL) + return (-1); + cmp = &cm->cmsg; + if (cmp == NULL || cmp->cmsg_level != SOL_SOCKET || + cmp->cmsg_type != SCM_CREDS) + return (-1); cmcred = __svc_getcallercreds(transp); if (cmcred == NULL) |