Created
February 1, 2015 22:04
-
-
Save zonque/1eb194021c0369514e4d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _GNU_SOURCE | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <sys/un.h> | |
static int recv_creds(int fd) { | |
unsigned char buf[128], ctrl[128]; | |
struct iovec iov = { | |
.iov_base = buf, | |
.iov_len = sizeof(buf) | |
}; | |
struct msghdr mh = { | |
.msg_iov = &iov, | |
.msg_iovlen = 1, | |
.msg_control = ctrl, | |
.msg_controllen = sizeof(ctrl) | |
}; | |
struct ucred ucred_peer; | |
socklen_t ucred_peer_len = sizeof(ucred_peer); | |
struct cmsghdr *cmsg; | |
int ret; | |
ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred_peer, &ucred_peer_len); | |
if (ret < 0) | |
return 0; | |
printf("SO_PEERCRED on fd %d: pid %d uid %d gid %d\n", | |
fd, ucred_peer.pid, ucred_peer.uid, ucred_peer.gid); | |
ret = recvmsg(fd, &mh, 0); | |
if (ret < 0) | |
return ret; | |
for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) { | |
if (cmsg->cmsg_level == SOL_SOCKET && | |
cmsg->cmsg_type == SCM_CREDENTIALS) { | |
struct ucred *ucred = (struct ucred *) CMSG_DATA(cmsg); | |
printf("SCM_CREDENTIALS on fd %d: pid %d uid %d gid %d\n", | |
fd, ucred->pid, ucred->uid, ucred->gid); | |
} | |
} | |
return 0; | |
} | |
int main(void) { | |
const int one = 1; | |
int ret, fd[2]; | |
pid_t pid; | |
ret = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fd); | |
if (ret < 0) | |
return ret; | |
ret = setsockopt(fd[1], SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); | |
if (ret < 0) | |
return ret; | |
write(fd[0], &one, sizeof(one)); | |
pid = fork(); | |
if (pid < 0) | |
return pid; | |
if (pid == 0) { | |
/* child */ | |
setresgid(1000, 1000, 1000); | |
setresuid(1000, 1000, 1000); | |
write(fd[0], &one, sizeof(one)); | |
exit(0); | |
} else { | |
int i; | |
printf("Current PID: %d, child PID: %d\n", getpid(), pid); | |
for (i = 0; i < 2; i++) { | |
printf("---------------------------------------\n"); | |
ret = recv_creds(fd[1]); | |
if (ret < 0) | |
return ret; | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment