linux/net/netfilter/xt_owner.c
<<
>>
Prefs
   1/*
   2 * Kernel module to match various things tied to sockets associated with
   3 * locally generated outgoing packets.
   4 *
   5 * (C) 2000 Marc Boucher <marc@mbsi.ca>
   6 *
   7 * Copyright © CC Computer Consultants GmbH, 2007 - 2008
   8 * <jengelh@computergmbh.de>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 */
  14#include <linux/module.h>
  15#include <linux/skbuff.h>
  16#include <linux/file.h>
  17#include <net/sock.h>
  18#include <linux/netfilter/x_tables.h>
  19#include <linux/netfilter/xt_owner.h>
  20#include <linux/netfilter_ipv4/ipt_owner.h>
  21#include <linux/netfilter_ipv6/ip6t_owner.h>
  22
  23static bool
  24owner_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
  25{
  26        const struct ipt_owner_info *info = par->matchinfo;
  27        const struct file *filp;
  28
  29        if (skb->sk == NULL || skb->sk->sk_socket == NULL)
  30                return false;
  31
  32        filp = skb->sk->sk_socket->file;
  33        if (filp == NULL)
  34                return false;
  35
  36        if (info->match & IPT_OWNER_UID)
  37                if ((filp->f_uid != info->uid) ^
  38                    !!(info->invert & IPT_OWNER_UID))
  39                        return false;
  40
  41        if (info->match & IPT_OWNER_GID)
  42                if ((filp->f_gid != info->gid) ^
  43                    !!(info->invert & IPT_OWNER_GID))
  44                        return false;
  45
  46        return true;
  47}
  48
  49static bool
  50owner_mt6_v0(const struct sk_buff *skb, const struct xt_match_param *par)
  51{
  52        const struct ip6t_owner_info *info = par->matchinfo;
  53        const struct file *filp;
  54
  55        if (skb->sk == NULL || skb->sk->sk_socket == NULL)
  56                return false;
  57
  58        filp = skb->sk->sk_socket->file;
  59        if (filp == NULL)
  60                return false;
  61
  62        if (info->match & IP6T_OWNER_UID)
  63                if ((filp->f_uid != info->uid) ^
  64                    !!(info->invert & IP6T_OWNER_UID))
  65                        return false;
  66
  67        if (info->match & IP6T_OWNER_GID)
  68                if ((filp->f_gid != info->gid) ^
  69                    !!(info->invert & IP6T_OWNER_GID))
  70                        return false;
  71
  72        return true;
  73}
  74
  75static bool
  76owner_mt(const struct sk_buff *skb, const struct xt_match_param *par)
  77{
  78        const struct xt_owner_match_info *info = par->matchinfo;
  79        const struct file *filp;
  80
  81        if (skb->sk == NULL || skb->sk->sk_socket == NULL)
  82                return (info->match ^ info->invert) == 0;
  83        else if (info->match & info->invert & XT_OWNER_SOCKET)
  84                /*
  85                 * Socket exists but user wanted ! --socket-exists.
  86                 * (Single ampersands intended.)
  87                 */
  88                return false;
  89
  90        filp = skb->sk->sk_socket->file;
  91        if (filp == NULL)
  92                return ((info->match ^ info->invert) &
  93                       (XT_OWNER_UID | XT_OWNER_GID)) == 0;
  94
  95        if (info->match & XT_OWNER_UID)
  96                if ((filp->f_uid >= info->uid_min &&
  97                    filp->f_uid <= info->uid_max) ^
  98                    !(info->invert & XT_OWNER_UID))
  99                        return false;
 100
 101        if (info->match & XT_OWNER_GID)
 102                if ((filp->f_gid >= info->gid_min &&
 103                    filp->f_gid <= info->gid_max) ^
 104                    !(info->invert & XT_OWNER_GID))
 105                        return false;
 106
 107        return true;
 108}
 109
 110static bool owner_mt_check_v0(const struct xt_mtchk_param *par)
 111{
 112        const struct ipt_owner_info *info = par->matchinfo;
 113
 114        if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) {
 115                printk(KERN_WARNING KBUILD_MODNAME
 116                       ": PID, SID and command matching is not "
 117                       "supported anymore\n");
 118                return false;
 119        }
 120
 121        return true;
 122}
 123
 124static bool owner_mt6_check_v0(const struct xt_mtchk_param *par)
 125{
 126        const struct ip6t_owner_info *info = par->matchinfo;
 127
 128        if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
 129                printk(KERN_WARNING KBUILD_MODNAME
 130                       ": PID and SID matching is not supported anymore\n");
 131                return false;
 132        }
 133
 134        return true;
 135}
 136
 137static struct xt_match owner_mt_reg[] __read_mostly = {
 138        {
 139                .name       = "owner",
 140                .revision   = 0,
 141                .family     = NFPROTO_IPV4,
 142                .match      = owner_mt_v0,
 143                .matchsize  = sizeof(struct ipt_owner_info),
 144                .checkentry = owner_mt_check_v0,
 145                .hooks      = (1 << NF_INET_LOCAL_OUT) |
 146                              (1 << NF_INET_POST_ROUTING),
 147                .me         = THIS_MODULE,
 148        },
 149        {
 150                .name       = "owner",
 151                .revision   = 0,
 152                .family     = NFPROTO_IPV6,
 153                .match      = owner_mt6_v0,
 154                .matchsize  = sizeof(struct ip6t_owner_info),
 155                .checkentry = owner_mt6_check_v0,
 156                .hooks      = (1 << NF_INET_LOCAL_OUT) |
 157                              (1 << NF_INET_POST_ROUTING),
 158                .me         = THIS_MODULE,
 159        },
 160        {
 161                .name       = "owner",
 162                .revision   = 1,
 163                .family     = NFPROTO_UNSPEC,
 164                .match      = owner_mt,
 165                .matchsize  = sizeof(struct xt_owner_match_info),
 166                .hooks      = (1 << NF_INET_LOCAL_OUT) |
 167                              (1 << NF_INET_POST_ROUTING),
 168                .me         = THIS_MODULE,
 169        },
 170};
 171
 172static int __init owner_mt_init(void)
 173{
 174        return xt_register_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg));
 175}
 176
 177static void __exit owner_mt_exit(void)
 178{
 179        xt_unregister_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg));
 180}
 181
 182module_init(owner_mt_init);
 183module_exit(owner_mt_exit);
 184MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
 185MODULE_DESCRIPTION("Xtables: socket owner matching");
 186MODULE_LICENSE("GPL");
 187MODULE_ALIAS("ipt_owner");
 188MODULE_ALIAS("ip6t_owner");
 189
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.