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