*/
sendcred:
{
- int fds[2];
- if (pipe(fds) == 0) {
- /* Abandon, noop, has no reply */
- struct iovec iov;
- struct msghdr msg = {0};
+ fchmod( s, S_ISUID|S_IRWXU );
+
+ /* Abandon, noop, has no reply */
+ struct iovec iov;
+ struct msghdr msg = {0};
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
# ifndef CMSG_SPACE
# define CMSG_SPACE(len) (_CMSG_ALIGN( sizeof(struct cmsghdr)) + _CMSG_ALIGN(len) )
# ifndef CMSG_LEN
# define CMSG_LEN(len) (_CMSG_ALIGN( sizeof(struct cmsghdr)) + (len) )
# endif
- union {
- struct cmsghdr cm;
- unsigned char control[CMSG_SPACE(sizeof(int))];
- } control_un;
- struct cmsghdr *cmsg;
+ union {
+ struct cmsghdr cm;
+ unsigned char control[CMSG_SPACE(sizeof(int))];
+ } control_un;
+ struct cmsghdr *cmsg;
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- iov.iov_base = (char *) abandonPDU;
- iov.iov_len = sizeof abandonPDU;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ iov.iov_base = (char *) abandonPDU;
+ iov.iov_len = sizeof abandonPDU;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
- msg.msg_control = control_un.control;
- msg.msg_controllen = sizeof( control_un.control );
- msg.msg_flags = 0;
+ msg.msg_control = control_un.control;
+ msg.msg_controllen = sizeof( control_un.control );
+ msg.msg_flags = 0;
- cmsg = CMSG_FIRSTHDR( &msg );
- cmsg->cmsg_len = CMSG_LEN( sizeof(int) );
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg = CMSG_FIRSTHDR( &msg );
+ cmsg->cmsg_len = CMSG_LEN( sizeof(int) );
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
- *((int *)CMSG_DATA(cmsg)) = fds[0];
+ *((int *)CMSG_DATA(cmsg)) = s;
# else
- msg.msg_accrights = (char *)fds;
- msg.msg_accrightslen = sizeof(int);
+ msg.msg_accrights = (char *)&s;
+ msg.msg_accrightslen = sizeof(int);
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
- sendmsg( s, &msg, 0 );
- close(fds[0]);
- close(fds[1]);
- }
- }
-#endif
- return 0;
+ sendmsg( s, &msg, 0 );
}
+#endif
+ return 0;
+}
if ( errno != EINPROGRESS && errno != EWOULDBLOCK ) return -1;
# ifndef CMSG_LEN
# define CMSG_LEN(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
# endif
- union {
+ struct {
struct cmsghdr cm;
- unsigned char control[CMSG_SPACE(sizeof(int))];
- } control_un;
+ int fd;
+ } control_st;
struct cmsghdr *cmsg;
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
struct stat st;
+ struct sockaddr_un lname, rname;
+ socklen_t llen, rlen;
+
+ rlen = sizeof(rname);
+ llen = sizeof(lname);
+ getsockname(s, (struct sockaddr *)&lname, &llen);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
- msg.msg_control = control_un.control;
- msg.msg_controllen = sizeof( control_un.control );
+ msg.msg_control = &control_st;
+ msg.msg_controllen = sizeof( struct cmsghdr ) + sizeof( int ); /* no padding! */
cmsg = CMSG_FIRSTHDR( &msg );
# else
msg.msg_accrightslen == sizeof(int)
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL*/
) {
- /* We must receive a valid descriptor, it must be a pipe,
- * and it must only be accessible by its owner.
+ int mode = S_IFSOCK|S_ISUID|S_IRWXU;
+
+ /* We must receive a valid descriptor, it must be a socket,
+ * it must only be accessible by its owner, and it must be
+ * connected to our socket.
*/
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
fd = (*(int *)CMSG_DATA( cmsg ));
# endif
err = fstat( fd, &st );
+ if ( err == 0 )
+ err = getpeername(fd, (struct sockaddr *)&rname, &rlen);
close(fd);
- if( err == 0 && S_ISFIFO(st.st_mode) &&
- ((st.st_mode & (S_IRWXG|S_IRWXO)) == 0))
+ if( err == 0 && st.st_mode == mode &&
+ llen == rlen && !memcmp(&lname, &rname, llen))
{
*euid = st.st_uid;
*egid = st.st_gid;