1 #include "unp.h"
2 #include <sys/param.h>
3 #include <sys/ucred.h>
4
5 ssize_t
read_cred(int fd,void * ptr,size_t nbytes,struct fcred * fcredptr)6 read_cred(int fd, void *ptr, size_t nbytes, struct fcred *fcredptr)
7 {
8 struct msghdr msg;
9 struct iovec iov[1];
10 ssize_t n;
11
12 union {
13 struct cmsghdr cm;
14 char control[CMSG_SPACE(sizeof(struct fcred))];
15 } control_un;
16 struct cmsghdr *cmptr;
17
18 msg.msg_control = control_un.control;
19 msg.msg_controllen = sizeof(control_un.control);
20
21 msg.msg_name = NULL;
22 msg.msg_namelen = 0;
23
24 iov[0].iov_base = ptr;
25 iov[0].iov_len = nbytes;
26 msg.msg_iov = iov;
27 msg.msg_iovlen = 1;
28
29 if ( (n = recvmsg(fd, &msg, 0)) < 0)
30 return(n);
31
32 /* *INDENT-OFF* */
33 if (fcredptr) {
34 if (msg.msg_controllen > sizeof(struct cmsghdr)) {
35 cmptr = CMSG_FIRSTHDR(&msg);
36
37 if (cmptr->cmsg_len != CMSG_LEN(sizeof(struct fcred)))
38 err_quit("control length = %d", cmptr->cmsg_len);
39 if (cmptr->cmsg_level != SOL_SOCKET)
40 err_quit("control level != SOL_SOCKET");
41 if (cmptr->cmsg_type != SCM_CREDS)
42 err_quit("control type != SCM_CREDS");
43 memcpy(fcredptr, CMSG_DATA(cmptr), sizeof(struct fcred));
44 } else
45 bzero(fcredptr, sizeof(struct fcred)); /* none returned */
46 }
47 /* *INDENT-ON* */
48
49 return(n);
50 }
51