1999-03-18 Thorsten Kukuk <kukuk@suse.de>

* 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  <kukuk@suse.de>

	* sunrpc/clnt_unix.c: Fix creation of parameters for
 	sendmsg/recvmsg on non intel platforms.
	* sunrpc/svc_unix.c: Likewise.
This commit is contained in:
Andreas Schwab 1999-03-19 02:01:36 +00:00
parent 6fc8f783a4
commit d1275afec4
3 changed files with 104 additions and 56 deletions

View File

@ -1,3 +1,9 @@
1999-03-18 Thorsten Kukuk <kukuk@suse.de>
* sunrpc/clnt_unix.c: Fix creation of parameters for
sendmsg/recvmsg on non intel platforms.
* sunrpc/svc_unix.c: Likewise.
1999-03-18 Philip Blundell <philb@gnu.org> 1999-03-18 Philip Blundell <philb@gnu.org>
* sysdeps/unix/sysv/linux/arm/getgroups.c: New file. Use the i386 * sysdeps/unix/sysv/linux/arm/getgroups.c: New file. Use the i386

View File

@ -434,32 +434,26 @@ clntunix_destroy (CLIENT *h)
mem_free ((caddr_t) h, sizeof (CLIENT)); mem_free ((caddr_t) h, sizeof (CLIENT));
} }
#ifdef SCM_CREDENTIALS
struct cmessage {
struct cmsghdr cmsg;
struct ucred cmcred;
};
#endif
static int 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; struct msghdr msg;
#ifdef SCM_CREDENTIALS #ifdef SCM_CREDENTIALS
struct cmessage cm; static char cm[CMSG_SPACE(sizeof (struct ucred))];
#endif #endif
int len;
iov[0].iov_base = buf; iov.iov_base = data;
iov[0].iov_len = cnt; iov.iov_len = cnt;
msg.msg_iov = iov; msg.msg_iov = &iov;
msg.msg_iovlen = 1; msg.msg_iovlen = 1;
msg.msg_name = NULL; msg.msg_name = NULL;
msg.msg_namelen = 0; msg.msg_namelen = 0;
#ifdef SCM_CREDENTIALS #ifdef SCM_CREDENTIALS
msg.msg_control = (caddr_t)&cm; msg.msg_control = (caddr_t) &cm;
msg.msg_controllen = sizeof(struct cmessage); msg.msg_controllen = CMSG_SPACE(sizeof (struct ucred));
#endif #endif
msg.msg_flags = 0; msg.msg_flags = 0;
@ -471,43 +465,65 @@ __msgread (int sock, void *buf, size_t cnt)
} }
#endif #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 static int
__msgwrite (int sock, void *buf, size_t cnt) __msgwrite (int sock, void *data, size_t cnt)
{ {
#ifndef SCM_CREDENTIALS #ifndef SCM_CREDENTIALS
/* We cannot implement this reliably. */ /* We cannot implement this reliably. */
__set_errno (ENOSYS); __set_errno (ENOSYS);
return -1; return -1;
#else #else
struct iovec iov[1]; struct iovec iov;
struct msghdr msg; struct msghdr msg;
struct cmessage cm; struct cmsghdr *cmsg = alloca (CMSG_SPACE(sizeof (struct ucred)));
struct ucred cred;
int len;
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 gete?id() is always correct, or if we should use /* 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. 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. */ It would be much better, if the kernel could pass both to the server. */
cm.cmcred.pid = __getpid (); cred.pid = __getpid ();
cm.cmcred.uid = __geteuid (); cred.uid = __geteuid ();
cm.cmcred.gid = __getegid (); cred.gid = __getegid ();
msg.msg_iov = iov; 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_iovlen = 1;
msg.msg_name = NULL; msg.msg_name = NULL;
msg.msg_namelen = 0; msg.msg_namelen = 0;
msg.msg_control = (caddr_t) &cm; msg.msg_control = cmsg;
msg.msg_controllen = sizeof (struct cmessage); msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len);
msg.msg_flags = 0; 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 #endif
} }

View File

@ -284,6 +284,8 @@ svcunix_destroy (SVCXPRT *xprt)
struct cmessage { struct cmessage {
struct cmsghdr cmsg; struct cmsghdr cmsg;
struct ucred cmcred; 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 /* XXX This is not thread safe, but since the main functions in svc.c
@ -293,15 +295,16 @@ static struct cmessage cm;
#endif #endif
static int 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; struct msghdr msg;
int len;
iov[0].iov_base = buf; iov.iov_base = data;
iov[0].iov_len = cnt; iov.iov_len = cnt;
msg.msg_iov = iov; msg.msg_iov = &iov;
msg.msg_iovlen = 1; msg.msg_iovlen = 1;
msg.msg_name = NULL; msg.msg_name = NULL;
msg.msg_namelen = 0; msg.msg_namelen = 0;
@ -319,42 +322,65 @@ __msgread (int sock, void *buf, size_t cnt)
} }
#endif #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 static int
__msgwrite (int sock, void *buf, size_t cnt) __msgwrite (int sock, void *data, size_t cnt)
{ {
#ifndef SCM_CREDENTIALS #ifndef SCM_CREDENTIALS
/* We cannot implement this reliably. */ /* We cannot implement this reliably. */
__set_errno (ENOSYS); __set_errno (ENOSYS);
return -1; return -1;
#else #else
struct iovec iov[1]; struct iovec iov;
struct msghdr msg; struct msghdr msg;
struct cmsghdr *cmsg = &cm.cmsg;
struct ucred cred;
int len;
iov[0].iov_base = buf; /* XXX I'm not sure, if gete?id() is always correct, or if we should use
iov[0].iov_len = cnt; 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 ();
cm.cmsg.cmsg_type = SCM_CREDENTIALS; memcpy (CMSG_DATA(cmsg), &cred, sizeof (struct ucred));
cm.cmsg.cmsg_level = SOL_SOCKET; cmsg->cmsg_level = SOL_SOCKET;
cm.cmsg.cmsg_len = sizeof (struct cmessage); cmsg->cmsg_type = SCM_CREDENTIALS;
/* XXX I'm not sure, if we really should use gete?id(), or get?id(). cmsg->cmsg_len = sizeof(*cmsg) + sizeof(struct ucred);
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; iov.iov_base = data;
iov.iov_len = cnt;
msg.msg_iov = &iov;
msg.msg_iovlen = 1; msg.msg_iovlen = 1;
msg.msg_name = NULL; msg.msg_name = NULL;
msg.msg_namelen = 0; msg.msg_namelen = 0;
msg.msg_control = (caddr_t) &cm; msg.msg_control = cmsg;
msg.msg_controllen = sizeof (struct cmessage); msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len);
msg.msg_flags = 0; 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 #endif
} }
@ -446,8 +472,8 @@ svcunix_recv (SVCXPRT *xprt, struct rpc_msg *msg)
{ {
cd->x_id = msg->rm_xid; cd->x_id = msg->rm_xid;
/* set up verifiers */ /* set up verifiers */
msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX;
#ifdef SCM_CREDENTIALS #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_base = (caddr_t) &cm;
msg->rm_call.cb_verf.oa_length = sizeof (cm); msg->rm_call.cb_verf.oa_length = sizeof (cm);
#endif #endif