From d1275afec4c36467edc1da9c0ebcbf54f89ef262 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Fri, 19 Mar 1999 02:01:36 +0000 Subject: 1999-03-18 Thorsten Kukuk * sunrpc/clnt_unix.c: Fix creation of parameters for sendmsg/recvmsg on non intel platforms. * sunrpc/svc_unix.c: Likewise. 1999-03-18 Thorsten Kukuk * sunrpc/clnt_unix.c: Fix creation of parameters for sendmsg/recvmsg on non intel platforms. * sunrpc/svc_unix.c: Likewise. --- sunrpc/clnt_unix.c | 80 ++++++++++++++++++++++++++++++++---------------------- sunrpc/svc_unix.c | 80 ++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 101 insertions(+), 59 deletions(-) (limited to 'sunrpc') diff --git a/sunrpc/clnt_unix.c b/sunrpc/clnt_unix.c index 240cdbbce4..761ecafb05 100644 --- a/sunrpc/clnt_unix.c +++ b/sunrpc/clnt_unix.c @@ -434,32 +434,26 @@ clntunix_destroy (CLIENT *h) mem_free ((caddr_t) h, sizeof (CLIENT)); } -#ifdef SCM_CREDENTIALS -struct cmessage { - struct cmsghdr cmsg; - struct ucred cmcred; -}; -#endif - static int -__msgread (int sock, void *buf, size_t cnt) +__msgread (int sock, void *data, size_t cnt) { - struct iovec iov[1]; + struct iovec iov; struct msghdr msg; #ifdef SCM_CREDENTIALS - struct cmessage cm; + static char cm[CMSG_SPACE(sizeof (struct ucred))]; #endif + int len; - iov[0].iov_base = buf; - iov[0].iov_len = cnt; + iov.iov_base = data; + iov.iov_len = cnt; - msg.msg_iov = iov; + msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; #ifdef SCM_CREDENTIALS - msg.msg_control = (caddr_t)&cm; - msg.msg_controllen = sizeof(struct cmessage); + msg.msg_control = (caddr_t) &cm; + msg.msg_controllen = CMSG_SPACE(sizeof (struct ucred)); #endif msg.msg_flags = 0; @@ -471,43 +465,65 @@ __msgread (int sock, void *buf, size_t cnt) } #endif - return recvmsg (sock, &msg, 0); + restart: + len = recvmsg (sock, &msg, 0); + if (len >= 0) + { + if (msg.msg_flags & MSG_CTRUNC || len == 0) + return 0; + else + return len; + } + if (errno == EINTR) + goto restart; + return -1; } static int -__msgwrite (int sock, void *buf, size_t cnt) +__msgwrite (int sock, void *data, size_t cnt) { #ifndef SCM_CREDENTIALS /* We cannot implement this reliably. */ __set_errno (ENOSYS); return -1; #else - struct iovec iov[1]; + struct iovec iov; struct msghdr msg; - struct cmessage cm; - - iov[0].iov_base = buf; - iov[0].iov_len = cnt; + struct cmsghdr *cmsg = alloca (CMSG_SPACE(sizeof (struct ucred))); + struct ucred cred; + int len; - cm.cmsg.cmsg_type = SCM_CREDENTIALS; - cm.cmsg.cmsg_level = SOL_SOCKET; - cm.cmsg.cmsg_len = sizeof (struct cmessage); /* XXX I'm not sure, if gete?id() is always correct, or if we should use get?id(). But since keyserv needs geteuid(), we have no other chance. It would be much better, if the kernel could pass both to the server. */ - cm.cmcred.pid = __getpid (); - cm.cmcred.uid = __geteuid (); - cm.cmcred.gid = __getegid (); + cred.pid = __getpid (); + cred.uid = __geteuid (); + cred.gid = __getegid (); + + memcpy (CMSG_DATA(cmsg), &cred, sizeof (struct ucred)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS; + cmsg->cmsg_len = sizeof(*cmsg) + sizeof(struct ucred); - msg.msg_iov = iov; + iov.iov_base = data; + iov.iov_len = cnt; + + msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; - msg.msg_control = (caddr_t) &cm; - msg.msg_controllen = sizeof (struct cmessage); + msg.msg_control = cmsg; + msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len); msg.msg_flags = 0; - return sendmsg (sock, &msg, 0); + restart: + len = sendmsg (sock, &msg, 0); + if (len >= 0) + return len; + if (errno == EINTR) + goto restart; + return -1; + #endif } diff --git a/sunrpc/svc_unix.c b/sunrpc/svc_unix.c index 0ff26aaaba..a34e54dd71 100644 --- a/sunrpc/svc_unix.c +++ b/sunrpc/svc_unix.c @@ -284,6 +284,8 @@ svcunix_destroy (SVCXPRT *xprt) struct cmessage { struct cmsghdr cmsg; struct ucred cmcred; + /* hack to make sure we have enough memory */ + char dummy[(CMSG_ALIGN (sizeof (struct ucred)) - sizeof (struct ucred) + sizeof (long))]; }; /* XXX This is not thread safe, but since the main functions in svc.c @@ -293,15 +295,16 @@ static struct cmessage cm; #endif static int -__msgread (int sock, void *buf, size_t cnt) +__msgread (int sock, void *data, size_t cnt) { - struct iovec iov[1]; + struct iovec iov; struct msghdr msg; + int len; - iov[0].iov_base = buf; - iov[0].iov_len = cnt; + iov.iov_base = data; + iov.iov_len = cnt; - msg.msg_iov = iov; + msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; @@ -319,42 +322,65 @@ __msgread (int sock, void *buf, size_t cnt) } #endif - return recvmsg (sock, &msg, 0); + restart: + len = recvmsg (sock, &msg, 0); + if (len >= 0) + { + if (msg.msg_flags & MSG_CTRUNC || len == 0) + return 0; + else + return len; + } + if (errno == EINTR) + goto restart; + return -1; } static int -__msgwrite (int sock, void *buf, size_t cnt) +__msgwrite (int sock, void *data, size_t cnt) { #ifndef SCM_CREDENTIALS /* We cannot implement this reliably. */ __set_errno (ENOSYS); return -1; #else - struct iovec iov[1]; + struct iovec iov; struct msghdr msg; - - iov[0].iov_base = buf; - iov[0].iov_len = cnt; - - cm.cmsg.cmsg_type = SCM_CREDENTIALS; - cm.cmsg.cmsg_level = SOL_SOCKET; - cm.cmsg.cmsg_len = sizeof (struct cmessage); - /* XXX I'm not sure, if we really should use gete?id(), or get?id(). - It would be much better, if the kernel could pass both to the - client. */ - cm.cmcred.pid = __getpid (); - cm.cmcred.uid = __geteuid (); - cm.cmcred.gid = __getegid (); - - msg.msg_iov = iov; + struct cmsghdr *cmsg = &cm.cmsg; + struct ucred cred; + int len; + + /* XXX I'm not sure, if gete?id() is always correct, or if we should use + get?id(). But since keyserv needs geteuid(), we have no other chance. + It would be much better, if the kernel could pass both to the server. */ + cred.pid = __getpid (); + cred.uid = __geteuid (); + cred.gid = __getegid (); + + memcpy (CMSG_DATA(cmsg), &cred, sizeof (struct ucred)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS; + cmsg->cmsg_len = sizeof(*cmsg) + sizeof(struct ucred); + + iov.iov_base = data; + iov.iov_len = cnt; + + msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; - msg.msg_control = (caddr_t) &cm; - msg.msg_controllen = sizeof (struct cmessage); + msg.msg_control = cmsg; + msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len); msg.msg_flags = 0; - return sendmsg (sock, &msg, 0); + restart: + len = sendmsg (sock, &msg, 0); + if (len >= 0) + return len; + if (errno == EINTR) + goto restart; + return -1; + #endif } @@ -446,8 +472,8 @@ svcunix_recv (SVCXPRT *xprt, struct rpc_msg *msg) { cd->x_id = msg->rm_xid; /* set up verifiers */ - msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX; #ifdef SCM_CREDENTIALS + msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX; msg->rm_call.cb_verf.oa_base = (caddr_t) &cm; msg->rm_call.cb_verf.oa_length = sizeof (cm); #endif -- cgit 1.4.1