9b91decbfddba43f44f05ab1fe104e9c4c016000
[linux-3.10.git] / net / ipv6 / netfilter / ip6t_owner.c
1 /* Kernel module to match various things tied to sockets associated with
2    locally generated outgoing packets. */
3
4 /* (C) 2000-2001 Marc Boucher <marc@mbsi.ca>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/module.h>
12 #include <linux/skbuff.h>
13 #include <linux/file.h>
14 #include <net/sock.h>
15
16 #include <linux/netfilter_ipv6/ip6t_owner.h>
17 #include <linux/netfilter_ipv6/ip6_tables.h>
18
19 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
20 MODULE_DESCRIPTION("IP6 tables owner matching module");
21 MODULE_LICENSE("GPL");
22
23
24 static int
25 match(const struct sk_buff *skb,
26       const struct net_device *in,
27       const struct net_device *out,
28       const void *matchinfo,
29       int offset,
30       unsigned int protoff,
31       int *hotdrop)
32 {
33         const struct ip6t_owner_info *info = matchinfo;
34
35         if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
36                 return 0;
37
38         if(info->match & IP6T_OWNER_UID) {
39                 if((skb->sk->sk_socket->file->f_uid != info->uid) ^
40                     !!(info->invert & IP6T_OWNER_UID))
41                         return 0;
42         }
43
44         if(info->match & IP6T_OWNER_GID) {
45                 if((skb->sk->sk_socket->file->f_gid != info->gid) ^
46                     !!(info->invert & IP6T_OWNER_GID))
47                         return 0;
48         }
49
50         return 1;
51 }
52
53 static int
54 checkentry(const char *tablename,
55            const struct ip6t_ip6 *ip,
56            void *matchinfo,
57            unsigned int matchsize,
58            unsigned int hook_mask)
59 {
60         const struct ip6t_owner_info *info = matchinfo;
61
62         if (hook_mask
63             & ~((1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING))) {
64                 printk("ip6t_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
65                 return 0;
66         }
67
68         if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info)))
69                 return 0;
70
71         if (info->match & (IP6T_OWNER_PID|IP6T_OWNER_SID)) {
72                 printk("ipt_owner: pid and sid matching "
73                        "not supported anymore\n");
74                 return 0;
75         }
76
77         return 1;
78 }
79
80 static struct ip6t_match owner_match = {
81         .name           = "owner",
82         .match          = &match,
83         .checkentry     = &checkentry,
84         .me             = THIS_MODULE,
85 };
86
87 static int __init init(void)
88 {
89         return ip6t_register_match(&owner_match);
90 }
91
92 static void __exit fini(void)
93 {
94         ip6t_unregister_match(&owner_match);
95 }
96
97 module_init(init);
98 module_exit(fini);