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