sfakeroot

manipulate files faking root privileges
git clone git://git.vx21.xyz/sfakeroot
Log | Files | Refs | README | LICENSE

sfakeroot_inline.h (2966B)


      1 #include <sys/socket.h>
      2 #include <sys/un.h>
      3 
      4 #include "sfakeroot.h"
      5 
      6 static int sfakeroot__session_open_internal(bool session_expected)
      7 {
      8     struct sockaddr_un sa = {.sun_family = AF_UNIX};
      9     int sockfd;
     10     socklen_t socklen;
     11     char *sockpath = getenv("SFAKEROOT_SOCKET_PATH");
     12 
     13     if (sockpath == NULL) {
     14         fprintf(stderr, "environment variable SFAKEROOT_SOCKET_PATH not set!\n");
     15         return -1;
     16     }
     17 
     18     sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
     19     if (sockfd == -1) {
     20         fprintf(stderr, "socket: %s\n", strerror(errno));
     21         return -1;
     22     }
     23 
     24     strlcpy(sa.sun_path, sockpath, sizeof (sa.sun_path));
     25     socklen = strlen(sa.sun_path) + 1 + sizeof (sa.sun_family);
     26 
     27     if (connect(sockfd, (struct sockaddr *) &sa, socklen) == -1) {
     28         if (session_expected) {
     29             fprintf(stderr, "connect: %s\n", strerror(errno));
     30         }
     31         return -1;
     32     }
     33 
     34     return sockfd;
     35 }
     36 
     37 int sfakeroot_session_open(void)
     38 {
     39     return sfakeroot__session_open_internal(true);
     40 }
     41 
     42 int sfakeroot_recvmsg(int fd, struct sfakeroot_msg *m)
     43 {
     44     union {
     45         char buf[CMSG_SPACE(253)]; // 253 SCM_MAX_FD
     46         struct cmsghdr align;
     47     } u;
     48     struct iovec io = {
     49         .iov_base = m,
     50         .iov_len = sizeof (*m)
     51     };
     52     struct msghdr msg = {
     53         .msg_iov = &io,
     54         .msg_iovlen = 1,
     55         .msg_control = u.buf,
     56         .msg_controllen = sizeof (u.buf)
     57     };
     58     if (recvmsg(fd, &msg, 0) == -1) {
     59         fprintf(stderr, "sfakeroot_recvmsg: error reading message\n");
     60         return -1;
     61     }
     62     struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
     63     if (cmsg && cmsg->cmsg_type == SCM_RIGHTS) {
     64         debug("got an fd!!!\n");
     65         memcpy(&m->fd, CMSG_DATA(cmsg), sizeof (int));
     66     }
     67 
     68     return 0;
     69 }
     70 
     71 int sfakeroot_sendmsg(int fd, struct sfakeroot_msg *m, int send_fds[], int send_fds_len)
     72 {
     73     union {
     74         char *buf;
     75         struct cmsghdr align;
     76     } u;
     77     int ret = -1;
     78     struct iovec io = {
     79         .iov_base = m,
     80         .iov_len = sizeof (*m)
     81     };
     82     struct msghdr msg = {
     83         .msg_iov = &io,
     84         .msg_iovlen = 1,
     85     };
     86     if (send_fds_len > 0) {
     87         size_t buflen = CMSG_SPACE(send_fds_len * sizeof(int));
     88         u.buf = malloc(buflen);
     89         if (u.buf == NULL) {
     90             fprintf(stderr, "sfakeroot_sendmsg: out of memory: %s\n", strerror(errno));
     91             goto cleanup;
     92         }
     93         msg.msg_control = u.buf;
     94         msg.msg_controllen = buflen;
     95         struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
     96         cmsg->cmsg_level = SOL_SOCKET;
     97         cmsg->cmsg_type = SCM_RIGHTS;
     98         cmsg->cmsg_len = CMSG_LEN(send_fds_len * sizeof (int));
     99         memcpy(CMSG_DATA(cmsg), send_fds, send_fds_len * sizeof (int));
    100     }
    101     if (sendmsg(fd, &msg, 0) == -1) {
    102         fprintf(stderr, "sfakeroot_sendmsg: error writing message: %s\n", strerror(errno));
    103         goto cleanup;
    104     }
    105     ret = 0;
    106 cleanup:
    107     if (send_fds_len > 0) {
    108         free(u.buf);
    109     }
    110     return ret;
    111 }