main() { int fd[2], on, n; char buf[100]; struct fcred cred; if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fd) < 0) err_sys("socketpair error"); /* must set the socket option on the *receiving* socket */ on = 1; Setsockopt(fd[1], 0, LOCAL_CREDS, &on, sizeof(on)); Write(fd[0], "hello, world\n", 13); if ((n = recv_cred(fd[1], buf, sizeof(buf), &cred)) < 0) err_sys("recv_cred error"); else if (n == 0) err_quit("recv_cred, unexpected EOF"); buf[n] = 0; /* null terminate */ printf("data: %s", buf); if (cred.fc_ngroups == 0) printf("(no credentials returned)\n"); else { printf("real user ID = %d\n", cred.fc_ruid); printf("real group ID = %d\n", cred.fc_rgid); printf("login name = %-*s\n", MAXLOGNAME, cred.fc_login); printf("effective user ID = %d\n", cred.fc_uid); printf("effective group ID = %d\n", cred.fc_gid); printf("%d supplementary groups:", cred.fc_ngroups - 1); for (n = 1; n < cred.fc_ngroups; n++) /* [0] is the egid */ printf(" %d", cred.fc_groups[n]); printf("\n"); } exit(0); }
int do_recvmsg(message *dev_m_in, message *dev_m_out) { int minor; int rc; struct msg_control msg_ctrl; socklen_t controllen_avail = 0; socklen_t controllen_needed = 0; socklen_t controllen_desired = 0; #if DEBUG == 1 static int call_count = 0; printf("(uds) [%d] do_sendmsg() call_count=%d\n", uds_minor(dev_m_in), ++call_count); #endif minor = uds_minor(dev_m_in); #if DEBUG == 1 printf("(uds) [%d] CREDENTIALS {pid:%d,uid:%d,gid:%d}\n", minor, uds_fd_table[minor].ancillary_data.cred.pid, uds_fd_table[minor].ancillary_data.cred.uid, uds_fd_table[minor].ancillary_data.cred.gid); #endif memset(&msg_ctrl, '\0', sizeof(struct msg_control)); /* get the msg_control from the user, it will include the * amount of space the user has allocated for control data. */ rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, (vir_bytes) 0, (vir_bytes) &msg_ctrl, sizeof(struct msg_control)); if (rc != OK) { return EIO; } controllen_avail = MIN(msg_ctrl.msg_controllen, MSG_CONTROL_MAX); if (uds_fd_table[minor].ancillary_data.nfiledes > 0) { controllen_needed = CMSG_LEN(sizeof(int) * (uds_fd_table[minor].ancillary_data.nfiledes)); } /* if there is room we also include credentials */ controllen_desired = controllen_needed + CMSG_LEN(sizeof(struct ucred)); if (controllen_needed > controllen_avail) { return EOVERFLOW; } rc = recv_fds(minor, &uds_fd_table[minor].ancillary_data, &msg_ctrl); if (rc != OK) { return rc; } if (controllen_desired <= controllen_avail) { rc = recv_cred(minor, &uds_fd_table[minor].ancillary_data, &msg_ctrl); if (rc != OK) { return rc; } } /* send the user the control data */ rc = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, (vir_bytes) 0, (vir_bytes) &msg_ctrl, sizeof(struct msg_control)); return rc ? EIO : OK; }