ptg10805159
650 Advanced IPC Chapter 17
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_flags = 0;
if (fd_to_send < 0) {
msg.msg_control = NULL;
msg.msg_controllen = 0;
buf[1] = -fd_to_send; /* nonzero status means error */
if (buf[1] == 0)
buf[1] = 1; /* -256, etc. would screw up protocol */
}else {
if (cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL)
return(-1);
msg.msg_control = cmptr;
msg.msg_controllen = CONTROLLEN;
cmp = cmptr;
cmp->cmsg_level = SOL_SOCKET;
cmp->cmsg_type = SCM_RIGHTS;
cmp->cmsg_len = RIGHTSLEN;
*(int *)CMSG_DATA(cmp) = fd_to_send; /* the fd to pass */
cmp = CMSG_NXTHDR(&msg, cmp);
cmp->cmsg_level = SOL_SOCKET;
cmp->cmsg_type = SCM_CREDTYPE;
cmp->cmsg_len = CREDSLEN;
credp = (struct CREDSTRUCT *)CMSG_DATA(cmp);
#if defined(SCM_CREDENTIALS)
credp->uid = geteuid();
credp->gid = getegid();
credp->pid = getpid();
#endif
buf[1] = 0; /* zero status means OK */
}
buf[0] = 0; /* null byte flag to recv_ufd() */
if (sendmsg(fd, &msg, 0) != 2)
return(-1);
return(0);
}
Figure 17.15 Sending credentials over UNIX domain sockets
Note that we need to initialize the credentials structureonly on Linux.
The function in Figure17.16 is a modified version ofrecv_fd,calledrecv_ufd,
that returns the user ID of the sender through a reference parameter.
#include "apue.h"
#include <sys/socket.h> /* struct msghdr */
#include <sys/un.h>
#if defined(SCM_CREDS) /* BSD interface */
#define CREDSTRUCT cmsgcred
#define CR_UID cmcred_uid
#define SCM_CREDTYPE SCM_CREDS
#elif defined(SCM_CREDENTIALS) /* Linux interface */