xref: /openbmc/linux/include/net/scm.h (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus Torvalds #ifndef __LINUX_NET_SCM_H
2*1da177e4SLinus Torvalds #define __LINUX_NET_SCM_H
3*1da177e4SLinus Torvalds 
4*1da177e4SLinus Torvalds #include <linux/limits.h>
5*1da177e4SLinus Torvalds #include <linux/net.h>
6*1da177e4SLinus Torvalds 
7*1da177e4SLinus Torvalds /* Well, we should have at least one descriptor open
8*1da177e4SLinus Torvalds  * to accept passed FDs 8)
9*1da177e4SLinus Torvalds  */
10*1da177e4SLinus Torvalds #define SCM_MAX_FD	(OPEN_MAX-1)
11*1da177e4SLinus Torvalds 
12*1da177e4SLinus Torvalds struct scm_fp_list
13*1da177e4SLinus Torvalds {
14*1da177e4SLinus Torvalds 	int		count;
15*1da177e4SLinus Torvalds 	struct file	*fp[SCM_MAX_FD];
16*1da177e4SLinus Torvalds };
17*1da177e4SLinus Torvalds 
18*1da177e4SLinus Torvalds struct scm_cookie
19*1da177e4SLinus Torvalds {
20*1da177e4SLinus Torvalds 	struct ucred		creds;		/* Skb credentials	*/
21*1da177e4SLinus Torvalds 	struct scm_fp_list	*fp;		/* Passed files		*/
22*1da177e4SLinus Torvalds 	unsigned long		seq;		/* Connection seqno	*/
23*1da177e4SLinus Torvalds };
24*1da177e4SLinus Torvalds 
25*1da177e4SLinus Torvalds extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
26*1da177e4SLinus Torvalds extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
27*1da177e4SLinus Torvalds extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
28*1da177e4SLinus Torvalds extern void __scm_destroy(struct scm_cookie *scm);
29*1da177e4SLinus Torvalds extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
30*1da177e4SLinus Torvalds 
31*1da177e4SLinus Torvalds static __inline__ void scm_destroy(struct scm_cookie *scm)
32*1da177e4SLinus Torvalds {
33*1da177e4SLinus Torvalds 	if (scm && scm->fp)
34*1da177e4SLinus Torvalds 		__scm_destroy(scm);
35*1da177e4SLinus Torvalds }
36*1da177e4SLinus Torvalds 
37*1da177e4SLinus Torvalds static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
38*1da177e4SLinus Torvalds 			       struct scm_cookie *scm)
39*1da177e4SLinus Torvalds {
40*1da177e4SLinus Torvalds 	memset(scm, 0, sizeof(*scm));
41*1da177e4SLinus Torvalds 	scm->creds.uid = current->uid;
42*1da177e4SLinus Torvalds 	scm->creds.gid = current->gid;
43*1da177e4SLinus Torvalds 	scm->creds.pid = current->tgid;
44*1da177e4SLinus Torvalds 	if (msg->msg_controllen <= 0)
45*1da177e4SLinus Torvalds 		return 0;
46*1da177e4SLinus Torvalds 	return __scm_send(sock, msg, scm);
47*1da177e4SLinus Torvalds }
48*1da177e4SLinus Torvalds 
49*1da177e4SLinus Torvalds static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
50*1da177e4SLinus Torvalds 				struct scm_cookie *scm, int flags)
51*1da177e4SLinus Torvalds {
52*1da177e4SLinus Torvalds 	if (!msg->msg_control)
53*1da177e4SLinus Torvalds 	{
54*1da177e4SLinus Torvalds 		if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
55*1da177e4SLinus Torvalds 			msg->msg_flags |= MSG_CTRUNC;
56*1da177e4SLinus Torvalds 		scm_destroy(scm);
57*1da177e4SLinus Torvalds 		return;
58*1da177e4SLinus Torvalds 	}
59*1da177e4SLinus Torvalds 
60*1da177e4SLinus Torvalds 	if (test_bit(SOCK_PASSCRED, &sock->flags))
61*1da177e4SLinus Torvalds 		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
62*1da177e4SLinus Torvalds 
63*1da177e4SLinus Torvalds 	if (!scm->fp)
64*1da177e4SLinus Torvalds 		return;
65*1da177e4SLinus Torvalds 
66*1da177e4SLinus Torvalds 	scm_detach_fds(msg, scm);
67*1da177e4SLinus Torvalds }
68*1da177e4SLinus Torvalds 
69*1da177e4SLinus Torvalds 
70*1da177e4SLinus Torvalds #endif /* __LINUX_NET_SCM_H */
71*1da177e4SLinus Torvalds 
72