IPT [PATCH 1/4] libxt_owner

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Import libxt_owner into iptables


libxt_owner merges libipt_owner and libip6t_owner, and adds support
for the new xt_owner kernel module.

Signed-off-by: Jan Engelhardt <jengelh@xxxxxxxxxxxxxxx>

---
 Delete libipt_owner.c
 Delete libip6t_owner.c

 extensions/Makefile                |    6 
 extensions/libip6t_owner.c         |  240 --------------
 extensions/libipt_owner.c          |  241 ---------------
 extensions/libipt_owner.man        |   28 -
 extensions/libxt_owner.c           |  593 +++++++++++++++++++++++++++++++++++++
 extensions/libxt_owner.man         |   16 
 include/linux/netfilter/xt_owner.h |   16 
 7 files changed, 628 insertions(+), 512 deletions(-)

Index: iptables-modules/extensions/Makefile
===================================================================
--- iptables-modules.orig/extensions/Makefile
+++ iptables-modules/extensions/Makefile
@@ -5,9 +5,9 @@
 # header files are present in the include/linux directory of this iptables
 # package (HW)
 #
-PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange owner policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
-PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh owner policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
+PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
+PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh policy rt HL LOG REJECT
+PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport owner physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
 
 PF_EXT_SELINUX_SLIB:=
 PF6_EXT_SELINUX_SLIB:=
Index: iptables-modules/extensions/libip6t_owner.c
===================================================================
--- iptables-modules.orig/extensions/libip6t_owner.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/* Shared library add-on to iptables to add OWNER matching support. */
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include <ip6tables.h>
-#include <linux/netfilter_ipv6/ip6t_owner.h>
-
-/* Function which prints out usage message. */
-static void owner_help(void)
-{
-#ifdef IP6T_OWNER_COMM
-	printf(
-"OWNER match v%s options:\n"
-"[!] --uid-owner userid     Match local uid\n"
-"[!] --gid-owner groupid    Match local gid\n"
-"[!] --pid-owner processid  Match local pid\n"
-"[!] --sid-owner sessionid  Match local sid\n"
-"[!] --cmd-owner name       Match local command name\n"
-"\n",
-IPTABLES_VERSION);
-#else
-	printf(
-"OWNER match v%s options:\n"
-"[!] --uid-owner userid     Match local uid\n"
-"[!] --gid-owner groupid    Match local gid\n"
-"[!] --pid-owner processid  Match local pid\n"
-"[!] --sid-owner sessionid  Match local sid\n"
-"\n",
-IPTABLES_VERSION);
-#endif /* IP6T_OWNER_COMM */
-}
-
-static const struct option owner_opts[] = {
-	{ "uid-owner", 1, NULL, '1' },
-	{ "gid-owner", 1, NULL, '2' },
-	{ "pid-owner", 1, NULL, '3' },
-	{ "sid-owner", 1, NULL, '4' },
-#ifdef IP6T_OWNER_COMM
-	{ "cmd-owner", 1, NULL, '5' },
-#endif
-	{ }
-};
-
-/* Function which parses command options; returns true if it
-   ate an option */
-static int owner_parse(int c, char **argv, int invert, unsigned int *flags,
-                       const void *entry, struct xt_entry_match **match)
-{
-	struct ip6t_owner_info *ownerinfo = (struct ip6t_owner_info *)(*match)->data;
-
-	switch (c) {
-		char *end;
-		struct passwd *pwd;
-		struct group *grp;
-	case '1':
-		check_inverse(optarg, &invert, &optind, 0);
-
-		if ((pwd = getpwnam(optarg)))
-			ownerinfo->uid = pwd->pw_uid;
-		else {
-			ownerinfo->uid = strtoul(optarg, &end, 0);
-			if (*end != '\0' || end == optarg)
-				exit_error(PARAMETER_PROBLEM, "Bad OWNER UID value `%s'", optarg);
-		}
-		if (invert)
-			ownerinfo->invert |= IP6T_OWNER_UID;
-		ownerinfo->match |= IP6T_OWNER_UID;
-		*flags = 1;
-		break;
-
-	case '2':
-		check_inverse(optarg, &invert, &optind, 0);
-		if ((grp = getgrnam(optarg)))
-			ownerinfo->gid = grp->gr_gid;
-		else {
-			ownerinfo->gid = strtoul(optarg, &end, 0);
-			if (*end != '\0' || end == optarg)
-				exit_error(PARAMETER_PROBLEM, "Bad OWNER GID value `%s'", optarg);
-		}
-		if (invert)
-			ownerinfo->invert |= IP6T_OWNER_GID;
-		ownerinfo->match |= IP6T_OWNER_GID;
-		*flags = 1;
-		break;
-
-	case '3':
-		check_inverse(optarg, &invert, &optind, 0);
-		ownerinfo->pid = strtoul(optarg, &end, 0);
-		if (*end != '\0' || end == optarg)
-			exit_error(PARAMETER_PROBLEM, "Bad OWNER PID value `%s'", optarg);
-		if (invert)
-			ownerinfo->invert |= IP6T_OWNER_PID;
-		ownerinfo->match |= IP6T_OWNER_PID;
-		*flags = 1;
-		break;
-
-	case '4':
-		check_inverse(optarg, &invert, &optind, 0);
-		ownerinfo->sid = strtoul(optarg, &end, 0);
-		if (*end != '\0' || end == optarg)
-			exit_error(PARAMETER_PROBLEM, "Bad OWNER SID value `%s'", optarg);
-		if (invert)
-			ownerinfo->invert |= IP6T_OWNER_SID;
-		ownerinfo->match |= IP6T_OWNER_SID;
-		*flags = 1;
-		break;
-
-#ifdef IP6T_OWNER_COMM
-	case '5':
-		check_inverse(optarg, &invert, &optind, 0);
-		if(strlen(optarg) > sizeof(ownerinfo->comm))
-			exit_error(PARAMETER_PROBLEM, "OWNER CMD `%s' too long, max %d characters", optarg, sizeof(ownerinfo->comm));
-		
-		strncpy(ownerinfo->comm, optarg, sizeof(ownerinfo->comm));
-		ownerinfo->comm[sizeof(ownerinfo->comm)-1] = '\0';
-
-		if (invert)
-			ownerinfo->invert |= IP6T_OWNER_COMM;
-		ownerinfo->match |= IP6T_OWNER_COMM;
-		*flags = 1;
-		break;
-#endif
-		
-	default:
-		return 0;
-	}
-	return 1;
-}
-
-static void
-print_item(struct ip6t_owner_info *info, u_int8_t flag, int numeric, char *label)
-{
-	if(info->match & flag) {
-
-		if (info->invert & flag)
-			printf("! ");
-
-		printf(label);
-
-		switch(info->match & flag) {
-		case IP6T_OWNER_UID:
-			if(!numeric) {
-				struct passwd *pwd = getpwuid(info->uid);
-
-				if(pwd && pwd->pw_name) {
-					printf("%s ", pwd->pw_name);
-					break;
-				}
-				/* FALLTHROUGH */
-			}
-			printf("%u ", info->uid);
-			break;
-		case IP6T_OWNER_GID:
-			if(!numeric) {
-				struct group *grp = getgrgid(info->gid);
-
-				if(grp && grp->gr_name) {
-					printf("%s ", grp->gr_name);
-					break;
-				}
-				/* FALLTHROUGH */
-			}
-			printf("%u ", info->gid);
-			break;
-		case IP6T_OWNER_PID:
-			printf("%u ", info->pid);
-			break;
-		case IP6T_OWNER_SID:
-			printf("%u ", info->sid);
-			break;
-#ifdef IP6T_OWNER_COMM
-		case IP6T_OWNER_COMM:
-			printf("%.*s ", (int)sizeof(info->comm), info->comm);
-			break;
-#endif
-		default:
-			break;
-		}
-	}
-}
-
-/* Final check; must have specified --own. */
-static void owner_check(unsigned int flags)
-{
-	if (!flags)
-		exit_error(PARAMETER_PROBLEM,
-			   "OWNER match: You must specify one or more options");
-}
-
-/* Prints out the matchinfo. */
-static void owner_print(const void *ip, const struct xt_entry_match *match,
-                        int numeric)
-{
-	struct ip6t_owner_info *info = (struct ip6t_owner_info *)match->data;
-
-	print_item(info, IP6T_OWNER_UID, numeric, "OWNER UID match ");
-	print_item(info, IP6T_OWNER_GID, numeric, "OWNER GID match ");
-	print_item(info, IP6T_OWNER_PID, numeric, "OWNER PID match ");
-	print_item(info, IP6T_OWNER_SID, numeric, "OWNER SID match ");
-#ifdef IP6T_OWNER_COMM
-	print_item(info, IP6T_OWNER_COMM, numeric, "OWNER CMD match ");
-#endif
-}
-
-/* Saves the union ip6t_matchinfo in parsable form to stdout. */
-static void owner_save(const void *ip, const struct xt_entry_match *match)
-{
-	struct ip6t_owner_info *info = (struct ip6t_owner_info *)match->data;
-
-	print_item(info, IP6T_OWNER_UID, 0, "--uid-owner ");
-	print_item(info, IP6T_OWNER_GID, 0, "--gid-owner ");
-	print_item(info, IP6T_OWNER_PID, 0, "--pid-owner ");
-	print_item(info, IP6T_OWNER_SID, 0, "--sid-owner ");
-#ifdef IP6T_OWNER_COMM
-	print_item(info, IP6T_OWNER_COMM, 0, "--cmd-owner ");
-#endif
-}
-
-static struct ip6tables_match owner_match6 = {
-	.name 		= "owner",
-	.version	= IPTABLES_VERSION,
-	.size		= IP6T_ALIGN(sizeof(struct ip6t_owner_info)),
-	.userspacesize	= IP6T_ALIGN(sizeof(struct ip6t_owner_info)),
-	.help		= owner_help,
-	.parse		= owner_parse,
-	.final_check	= owner_check,
-	.print		= owner_print,
-	.save		= owner_save,
-	.extra_opts	= owner_opts,
-};
-
-void _init(void)
-{
-	register_match6(&owner_match6);
-}
Index: iptables-modules/extensions/libipt_owner.c
===================================================================
--- iptables-modules.orig/extensions/libipt_owner.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Shared library add-on to iptables to add OWNER matching support. */
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include <iptables.h>
-#include <linux/netfilter_ipv4/ipt_owner.h>
-
-/* Function which prints out usage message. */
-static void owner_help(void)
-{
-#ifdef IPT_OWNER_COMM
-	printf(
-"OWNER match v%s options:\n"
-"[!] --uid-owner userid     Match local uid\n"
-"[!] --gid-owner groupid    Match local gid\n"
-"[!] --pid-owner processid  Match local pid\n"
-"[!] --sid-owner sessionid  Match local sid\n"
-"[!] --cmd-owner name       Match local command name\n"
-"NOTE: pid, sid and command matching are broken on SMP\n"
-"\n",
-IPTABLES_VERSION);
-#else
-	printf(
-"OWNER match v%s options:\n"
-"[!] --uid-owner userid     Match local uid\n"
-"[!] --gid-owner groupid    Match local gid\n"
-"[!] --pid-owner processid  Match local pid\n"
-"[!] --sid-owner sessionid  Match local sid\n"
-"NOTE: pid and sid matching are broken on SMP\n"
-"\n",
-IPTABLES_VERSION);
-#endif /* IPT_OWNER_COMM */
-}
-
-static const struct option owner_opts[] = {
-	{ "uid-owner", 1, NULL, '1' },
-	{ "gid-owner", 1, NULL, '2' },
-	{ "pid-owner", 1, NULL, '3' },
-	{ "sid-owner", 1, NULL, '4' },
-#ifdef IPT_OWNER_COMM
-	{ "cmd-owner", 1, NULL, '5' },
-#endif
-	{ }
-};
-
-/* Function which parses command options; returns true if it
-   ate an option */
-static int owner_parse(int c, char **argv, int invert, unsigned int *flags,
-                       const void *entry, struct xt_entry_match **match)
-{
-	struct ipt_owner_info *ownerinfo = (struct ipt_owner_info *)(*match)->data;
-
-	switch (c) {
-		char *end;
-		struct passwd *pwd;
-		struct group *grp;
-	case '1':
-		check_inverse(optarg, &invert, &optind, 0);
-		if ((pwd = getpwnam(optarg)))
-			ownerinfo->uid = pwd->pw_uid;
-		else {
-			ownerinfo->uid = strtoul(optarg, &end, 0);
-			if (*end != '\0' || end == optarg)
-				exit_error(PARAMETER_PROBLEM, "Bad OWNER UID value `%s'", optarg);
-		}
-		if (invert)
-			ownerinfo->invert |= IPT_OWNER_UID;
-		ownerinfo->match |= IPT_OWNER_UID;
-		*flags = 1;
-		break;
-
-	case '2':
-		check_inverse(optarg, &invert, &optind, 0);
-		if ((grp = getgrnam(optarg)))
-			ownerinfo->gid = grp->gr_gid;
-		else {
-			ownerinfo->gid = strtoul(optarg, &end, 0);
-			if (*end != '\0' || end == optarg)
-				exit_error(PARAMETER_PROBLEM, "Bad OWNER GID value `%s'", optarg);
-		}
-		if (invert)
-			ownerinfo->invert |= IPT_OWNER_GID;
-		ownerinfo->match |= IPT_OWNER_GID;
-		*flags = 1;
-		break;
-
-	case '3':
-		check_inverse(optarg, &invert, &optind, 0);
-		ownerinfo->pid = strtoul(optarg, &end, 0);
-		if (*end != '\0' || end == optarg)
-			exit_error(PARAMETER_PROBLEM, "Bad OWNER PID value `%s'", optarg);
-		if (invert)
-			ownerinfo->invert |= IPT_OWNER_PID;
-		ownerinfo->match |= IPT_OWNER_PID;
-		*flags = 1;
-		break;
-
-	case '4':
-		check_inverse(optarg, &invert, &optind, 0);
-		ownerinfo->sid = strtoul(optarg, &end, 0);
-		if (*end != '\0' || end == optarg)
-			exit_error(PARAMETER_PROBLEM, "Bad OWNER SID value `%s'", optarg);
-		if (invert)
-			ownerinfo->invert |= IPT_OWNER_SID;
-		ownerinfo->match |= IPT_OWNER_SID;
-		*flags = 1;
-		break;
-
-#ifdef IPT_OWNER_COMM
-	case '5':
-		check_inverse(optarg, &invert, &optind, 0);
-		if(strlen(optarg) > sizeof(ownerinfo->comm))
-			exit_error(PARAMETER_PROBLEM, "OWNER CMD `%s' too long, max %u characters", optarg, (unsigned int)sizeof(ownerinfo->comm));
-
-		strncpy(ownerinfo->comm, optarg, sizeof(ownerinfo->comm));
-		ownerinfo->comm[sizeof(ownerinfo->comm)-1] = '\0';
-
-		if (invert)
-			ownerinfo->invert |= IPT_OWNER_COMM;
-		ownerinfo->match |= IPT_OWNER_COMM;
-		*flags = 1;
-		break;
-#endif
-
-	default:
-		return 0;
-	}
-	return 1;
-}
-
-static void
-print_item(struct ipt_owner_info *info, u_int8_t flag, int numeric, char *label)
-{
-	if(info->match & flag) {
-
-		if (info->invert & flag)
-			printf("! ");
-
-		printf(label);
-
-		switch(info->match & flag) {
-		case IPT_OWNER_UID:
-			if(!numeric) {
-				struct passwd *pwd = getpwuid(info->uid);
-
-				if(pwd && pwd->pw_name) {
-					printf("%s ", pwd->pw_name);
-					break;
-				}
-				/* FALLTHROUGH */
-			}
-			printf("%u ", info->uid);
-			break;
-		case IPT_OWNER_GID:
-			if(!numeric) {
-				struct group *grp = getgrgid(info->gid);
-
-				if(grp && grp->gr_name) {
-					printf("%s ", grp->gr_name);
-					break;
-				}
-				/* FALLTHROUGH */
-			}
-			printf("%u ", info->gid);
-			break;
-		case IPT_OWNER_PID:
-			printf("%u ", info->pid);
-			break;
-		case IPT_OWNER_SID:
-			printf("%u ", info->sid);
-			break;
-#ifdef IPT_OWNER_COMM
-		case IPT_OWNER_COMM:
-			printf("%.*s ", (int)sizeof(info->comm), info->comm);
-			break;
-#endif
-		default:
-			break;
-		}
-	}
-}
-
-/* Final check; must have specified --own. */
-static void owner_check(unsigned int flags)
-{
-	if (!flags)
-		exit_error(PARAMETER_PROBLEM,
-			   "OWNER match: You must specify one or more options");
-}
-
-/* Prints out the matchinfo. */
-static void owner_print(const void *ip, const struct xt_entry_match *match,
-                        int numeric)
-{
-	struct ipt_owner_info *info = (struct ipt_owner_info *)match->data;
-
-	print_item(info, IPT_OWNER_UID, numeric, "OWNER UID match ");
-	print_item(info, IPT_OWNER_GID, numeric, "OWNER GID match ");
-	print_item(info, IPT_OWNER_PID, numeric, "OWNER PID match ");
-	print_item(info, IPT_OWNER_SID, numeric, "OWNER SID match ");
-#ifdef IPT_OWNER_COMM
-	print_item(info, IPT_OWNER_COMM, numeric, "OWNER CMD match ");
-#endif
-}
-
-/* Saves the union ipt_matchinfo in parsable form to stdout. */
-static void owner_save(const void *ip, const struct xt_entry_match *match)
-{
-	struct ipt_owner_info *info = (struct ipt_owner_info *)match->data;
-
-	print_item(info, IPT_OWNER_UID, 0, "--uid-owner ");
-	print_item(info, IPT_OWNER_GID, 0, "--gid-owner ");
-	print_item(info, IPT_OWNER_PID, 0, "--pid-owner ");
-	print_item(info, IPT_OWNER_SID, 0, "--sid-owner ");
-#ifdef IPT_OWNER_COMM
-	print_item(info, IPT_OWNER_COMM, 0, "--cmd-owner ");
-#endif
-}
-
-static struct iptables_match owner_match = {
-	.name		= "owner",
-	.version	= IPTABLES_VERSION,
-	.size		= IPT_ALIGN(sizeof(struct ipt_owner_info)),
-	.userspacesize	= IPT_ALIGN(sizeof(struct ipt_owner_info)),
-	.help		= owner_help,
-	.parse		= owner_parse,
-	.final_check	= owner_check,
-	.print		= owner_print,
-	.save		= owner_save,
-	.extra_opts	= owner_opts,
-};
-
-void _init(void)
-{
-	register_match(&owner_match);
-}
Index: iptables-modules/extensions/libipt_owner.man
===================================================================
--- iptables-modules.orig/extensions/libipt_owner.man
+++ /dev/null
@@ -1,28 +0,0 @@
-This module attempts to match various characteristics of the packet
-creator, for locally-generated packets.  It is only valid in the
-.B OUTPUT
-chain, and even this some packets (such as ICMP ping responses) may
-have no owner, and hence never match.
-.TP
-.BI "--uid-owner " "userid"
-Matches if the packet was created by a process with the given
-effective user id.
-.TP
-.BI "--gid-owner " "groupid"
-Matches if the packet was created by a process with the given
-effective group id.
-.TP
-.BI "--pid-owner " "processid"
-Matches if the packet was created by a process with the given
-process id.
-.TP
-.BI "--sid-owner " "sessionid"
-Matches if the packet was created by a process in the given session
-group.
-.TP
-.BI "--cmd-owner " "name"
-Matches if the packet was created by a process with the given command name.
-(this option is present only if iptables was compiled under a kernel
-supporting this feature)
-.TP
-.B NOTE: pid, sid and command matching are broken on SMP
Index: iptables-modules/extensions/libxt_owner.c
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_owner.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Contact: Jan Engelhardt <jengelh@xxxxxxxxxxxxxxx>
+ */
+#include <getopt.h>
+#include <grp.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <xtables.h>
+#include <linux/netfilter/xt_owner.h>
+#include <linux/netfilter_ipv4/ipt_owner.h>
+#include <linux/netfilter_ipv6/ip6t_owner.h>
+
+enum {
+	FLAG_UID_OWNER     = 1 << 0,
+	FLAG_GID_OWNER     = 1 << 1,
+	FLAG_SOCKET_EXISTS = 1 << 2,
+	FLAG_PID_OWNER     = 1 << 3,
+	FLAG_SID_OWNER     = 1 << 4,
+	FLAG_COMM          = 1 << 5,
+};
+
+static void owner_mt_help_v0(void)
+{
+#ifdef IPT_OWNER_COMM
+	printf(
+"owner match v%s options:\n"
+"[!] --uid-owner userid       Match local UID\n"
+"[!] --gid-owner groupid      Match local GID\n"
+"[!] --pid-owner processid    Match local PID\n"
+"[!] --sid-owner sessionid    Match local SID\n"
+"[!] --cmd-owner name         Match local command name\n"
+"NOTE: PID, SID and command matching are broken on SMP\n"
+"\n",
+IPTABLES_VERSION);
+#else
+	printf(
+"owner match v%s options:\n"
+"[!] --uid-owner userid       Match local UID\n"
+"[!] --gid-owner groupid      Match local GID\n"
+"[!] --pid-owner processid    Match local PID\n"
+"[!] --sid-owner sessionid    Match local SID\n"
+"NOTE: PID and SID matching are broken on SMP\n"
+"\n",
+IPTABLES_VERSION);
+#endif /* IPT_OWNER_COMM */
+}
+
+static void owner_mt6_help_v0(void)
+{
+	printf(
+"owner match v%s options:\n"
+"[!] --uid-owner userid       Match local UID\n"
+"[!] --gid-owner groupid      Match local GID\n"
+"[!] --pid-owner processid    Match local PID\n"
+"[!] --sid-owner sessionid    Match local SID\n"
+"NOTE: PID and SID matching are broken on SMP\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static void owner_mt_help(void)
+{
+	printf(
+"owner match v%s options:\n"
+"[!] --uid-owner userid     Match local UID\n"
+"[!] --gid-owner groupid    Match local GID\n"
+"[!] --socket-exists        Match if socket exists\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static const struct option owner_mt_opts_v0[] = {
+	{.name = "uid-owner", .has_arg = true, .val = 'u'},
+	{.name = "gid-owner", .has_arg = true, .val = 'g'},
+	{.name = "pid-owner", .has_arg = true, .val = 'p'},
+	{.name = "sid-owner", .has_arg = true, .val = 's'},
+#ifdef IPT_OWNER_COMM
+	{.name = "cmd-owner", .has_arg = true, .val = 'c'},
+#endif
+	{},
+};
+
+static const struct option owner_mt6_opts_v0[] = {
+	{.name = "uid-owner", .has_arg = true, .val = 'u'},
+	{.name = "gid-owner", .has_arg = true, .val = 'g'},
+	{.name = "pid-owner", .has_arg = true, .val = 'p'},
+	{.name = "sid-owner", .has_arg = true, .val = 's'},
+	{},
+};
+
+static const struct option owner_mt_opts[] = {
+	{.name = "uid-owner",     .has_arg = true,  .val = 'u'},
+	{.name = "gid-owner",     .has_arg = true,  .val = 'g'},
+	{.name = "socket-exists", .has_arg = false, .val = 'k'},
+	{},
+};
+
+static int
+owner_mt_parse_v0(int c, char **argv, int invert, unsigned int *flags,
+                  const void *entry, struct xt_entry_match **match)
+{
+	struct ipt_owner_info *ownerinfo = (void *)(*match)->data;
+	struct passwd *pwd;
+	struct group *grp;
+	unsigned int id;
+
+	switch (c) {
+	case 'u':
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((pwd = getpwnam(optarg)) != NULL)
+			ownerinfo->uid = pwd->pw_uid;
+		else if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad UID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IPT_OWNER_UID;
+		ownerinfo->match |= IPT_OWNER_UID;
+		ownerinfo->uid    = id;
+		*flags |= FLAG_UID_OWNER;
+		return true;
+
+	case 'g':
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((grp = getgrnam(optarg)) != NULL)
+			ownerinfo->gid = grp->gr_gid;
+		else if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad GID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IPT_OWNER_GID;
+		ownerinfo->match |= IPT_OWNER_GID;
+		ownerinfo->gid    = id;
+		*flags |= FLAG_GID_OWNER;
+		return true;
+
+	case 'p':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad PID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IPT_OWNER_PID;
+		ownerinfo->match |= IPT_OWNER_PID;
+		ownerinfo->pid    = id;
+		*flags |= FLAG_PID_OWNER;
+		return true;
+
+	case 's':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad SID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IPT_OWNER_SID;
+		ownerinfo->match |= IPT_OWNER_SID;
+		ownerinfo->sid    = id;
+		*flags |= FLAG_SID_OWNER;
+		return true;
+
+#ifdef IPT_OWNER_COMM
+	case 'c':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (strlen(optarg) > sizeof(ownerinfo->comm))
+			exit_error(PARAMETER_PROBLEM, "owner match: command "
+			           "\"%s\" too long, max. %u characters",
+			           optarg, (unsigned int)sizeof(ownerinfo->comm));
+
+		ownerinfo->comm[sizeof(ownerinfo->comm)-1] = '\0';
+		strncpy(ownerinfo->comm, optarg, sizeof(ownerinfo->comm));
+
+		if (invert)
+			ownerinfo->invert |= IPT_OWNER_COMM;
+		ownerinfo->match |= IPT_OWNER_COMM;
+		*flags |= FLAG_COMM;
+		return true;
+#endif
+	}
+	return false;
+}
+
+static int
+owner_mt6_parse_v0(int c, char **argv, int invert, unsigned int *flags,
+                   const void *entry, struct xt_entry_match **match)
+{
+	struct ip6t_owner_info *ownerinfo = (void *)(*match)->data;
+	struct passwd *pwd;
+	struct group *grp;
+	unsigned int id;
+
+	switch (c) {
+	case 'u':
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((pwd = getpwnam(optarg)) != NULL)
+			ownerinfo->uid = pwd->pw_uid;
+		else if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad UID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IP6T_OWNER_UID;
+		ownerinfo->match |= IP6T_OWNER_UID;
+		ownerinfo->uid    = id;
+		*flags |= FLAG_UID_OWNER;
+		return true;
+
+	case 'g':
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((grp = getgrnam(optarg)) != NULL)
+			ownerinfo->gid = grp->gr_gid;
+		else if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad GID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IP6T_OWNER_GID;
+		ownerinfo->match |= IP6T_OWNER_GID;
+		ownerinfo->gid    = id;
+		*flags |= FLAG_GID_OWNER;
+		return true;
+
+	case 'p':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad PID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IP6T_OWNER_PID;
+		ownerinfo->match |= IP6T_OWNER_PID;
+		ownerinfo->pid    = id;
+		*flags |= FLAG_PID_OWNER;
+		return true;
+
+	case 's':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad SID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IP6T_OWNER_SID;
+		ownerinfo->match |= IP6T_OWNER_SID;
+		ownerinfo->sid    = id;
+		*flags |= FLAG_SID_OWNER;
+		return true;
+	}
+	return false;
+}
+
+static int owner_mt_parse(int c, char **argv, int invert, unsigned int *flags,
+                          const void *entry, struct xt_entry_match **match)
+{
+	struct xt_owner_match_info *info = (void *)(*match)->data;
+	struct passwd *pwd;
+	struct group *grp;
+	unsigned int id;
+
+	switch (c) {
+	case 'u':
+		if (*flags & FLAG_UID_OWNER)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "--uid-owner may only be given once");
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((pwd = getpwnam(optarg)) != NULL) {
+			info->uid = pwd->pw_uid;
+		} else {
+			if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+				exit_error(PARAMETER_PROBLEM, "owner match: "
+				           "Invalid value for --uid-owner "
+				           "parameter: %s", optarg);
+			info->uid = id;
+		}
+		if (invert)
+			info->invert |= XT_OWNER_UID;
+		info->match |= XT_OWNER_UID;
+		*flags |= FLAG_UID_OWNER;
+		return true;
+
+	case 'g':
+		if (*flags & FLAG_GID_OWNER)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "--gid-owner may only be given once");
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((grp = getgrnam(optarg)) != NULL) {
+			info->gid = grp->gr_gid;
+		} else {
+			if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+				exit_error(PARAMETER_PROBLEM, "owner match: "
+				           "Invalid value for --gid-owner "
+				           "parameter: %s", optarg);
+			info->gid = id;
+		}
+		if (invert)
+			info->invert |= XT_OWNER_GID;
+		info->match |= XT_OWNER_GID;
+		*flags |= FLAG_GID_OWNER;
+		return true;
+
+	case 'k':
+		if (*flags & FLAG_SOCKET_EXISTS)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "--socket-exists may only be given once");
+		check_inverse(optarg, &invert, &optind, 0);
+		if (invert)
+			info->invert |= XT_OWNER_SOCKET;
+		info->match |= XT_OWNER_SOCKET;
+		*flags |= FLAG_SOCKET_EXISTS;
+		return true;
+
+	}
+	return false;
+}
+
+static void owner_mt_check(unsigned int flags)
+{
+	if (flags == 0)
+		exit_error(PARAMETER_PROBLEM,
+			   "owner match: One or more parameters are required");
+}
+
+static void
+owner_mt_print_item_v0(const struct ipt_owner_info *info, const char *label,
+                       u_int8_t flag, bool numeric)
+{
+	if (!(info->match & flag))
+		return;
+	if (info->invert & flag)
+		printf("! ");
+	printf(label);
+
+	switch (info->match & flag) {
+	case IPT_OWNER_UID:
+		if (!numeric) {
+			struct passwd *pwd = getpwuid(info->uid);
+
+			if (pwd != NULL && pwd->pw_name != NULL) {
+				printf("%s ", pwd->pw_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->uid);
+		break;
+
+	case IPT_OWNER_GID:
+		if (!numeric) {
+			struct group *grp = getgrgid(info->gid);
+
+			if (grp != NULL && grp->gr_name != NULL) {
+				printf("%s ", grp->gr_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->gid);
+		break;
+
+	case IPT_OWNER_PID:
+		printf("%u ", (unsigned int)info->pid);
+		break;
+
+	case IPT_OWNER_SID:
+		printf("%u ", (unsigned int)info->sid);
+		break;
+
+#ifdef IPT_OWNER_COMM
+	case IPT_OWNER_COMM:
+		printf("%.*s ", (int)sizeof(info->comm), info->comm);
+		break;
+#endif
+	}
+}
+
+static void
+owner_mt6_print_item_v0(const struct ip6t_owner_info *info, const char *label,
+                        u_int8_t flag, bool numeric)
+{
+	if (!(info->match & flag))
+		return;
+	if (info->invert & flag)
+		printf("! ");
+	printf(label);
+
+	switch (info->match & flag) {
+	case IP6T_OWNER_UID:
+		if (!numeric) {
+			struct passwd *pwd = getpwuid(info->uid);
+
+			if (pwd != NULL && pwd->pw_name != NULL) {
+				printf("%s ", pwd->pw_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->uid);
+		break;
+
+	case IP6T_OWNER_GID:
+		if (!numeric) {
+			struct group *grp = getgrgid(info->gid);
+
+			if (grp != NULL && grp->gr_name != NULL) {
+				printf("%s ", grp->gr_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->gid);
+		break;
+
+	case IP6T_OWNER_PID:
+		printf("%u ", (unsigned int)info->pid);
+		break;
+
+	case IP6T_OWNER_SID:
+		printf("%u ", (unsigned int)info->sid);
+		break;
+	}
+}
+
+static void
+owner_mt_print_item(const struct xt_owner_match_info *info, const char *label,
+                    u_int8_t flag, bool numeric)
+{
+	if (!(info->match & flag))
+		return;
+	if (info->invert & flag)
+		printf("! ");
+	printf(label);
+
+	switch (info->match & flag) {
+	case XT_OWNER_UID:
+		if (!numeric) {
+			const struct passwd *pwd = getpwuid(info->uid);
+
+			if (pwd != NULL && pwd->pw_name != NULL) {
+				printf("%s ", pwd->pw_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->uid);
+		break;
+
+	case XT_OWNER_GID:
+		if (!numeric) {
+			const struct group *grp = getgrgid(info->gid);
+
+			if (grp != NULL && grp->gr_name != NULL) {
+				printf("%s ", grp->gr_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->gid);
+		break;
+	}
+}
+
+static void
+owner_mt_print_v0(const void *ip, const struct xt_entry_match *match,
+                  int numeric)
+{
+	const struct ipt_owner_info *info = (void *)match->data;
+
+	owner_mt_print_item_v0(info, "owner UID match ", IPT_OWNER_UID, numeric);
+	owner_mt_print_item_v0(info, "owner GID match ", IPT_OWNER_GID, numeric);
+	owner_mt_print_item_v0(info, "owner PID match ", IPT_OWNER_PID, numeric);
+	owner_mt_print_item_v0(info, "owner SID match ", IPT_OWNER_SID, numeric);
+#ifdef IPT_OWNER_COMM
+	owner_mt_print_item_v0(info, "owner CMD match ", IPT_OWNER_COMM, numeric);
+#endif
+}
+
+static void
+owner_mt6_print_v0(const void *ip, const struct xt_entry_match *match,
+                   int numeric)
+{
+	const struct ip6t_owner_info *info = (void *)match->data;
+
+	owner_mt6_print_item_v0(info, "owner UID match ", IPT_OWNER_UID, numeric);
+	owner_mt6_print_item_v0(info, "owner GID match ", IPT_OWNER_GID, numeric);
+	owner_mt6_print_item_v0(info, "owner PID match ", IPT_OWNER_PID, numeric);
+	owner_mt6_print_item_v0(info, "owner SID match ", IPT_OWNER_SID, numeric);
+}
+
+static void owner_mt_print(const void *ip, const struct xt_entry_match *match,
+                           int numeric)
+{
+	const struct xt_owner_match_info *info = (void *)match->data;
+
+	owner_mt_print_item(info, "owner socket exists ", XT_OWNER_SOCKET, numeric);
+	owner_mt_print_item(info, "owner UID match ",     XT_OWNER_UID,    numeric);
+	owner_mt_print_item(info, "owner GID match ",     XT_OWNER_GID,    numeric);
+}
+
+static void
+owner_mt_save_v0(const void *ip, const struct xt_entry_match *match)
+{
+	const struct ipt_owner_info *info = (void *)match->data;
+
+	owner_mt_print_item_v0(info, "owner UID match ", IPT_OWNER_UID, true);
+	owner_mt_print_item_v0(info, "owner GID match ", IPT_OWNER_GID, true);
+	owner_mt_print_item_v0(info, "owner PID match ", IPT_OWNER_PID, true);
+	owner_mt_print_item_v0(info, "owner SID match ", IPT_OWNER_SID, true);
+#ifdef IPT_OWNER_COMM
+	owner_mt_print_item_v0(info, "owner CMD match ", IPT_OWNER_COMM, true);
+#endif
+}
+
+static void
+owner_mt6_save_v0(const void *ip, const struct xt_entry_match *match)
+{
+	const struct ip6t_owner_info *info = (void *)match->data;
+
+	owner_mt6_print_item_v0(info, "owner UID match ", IPT_OWNER_UID, true);
+	owner_mt6_print_item_v0(info, "owner GID match ", IPT_OWNER_GID, true);
+	owner_mt6_print_item_v0(info, "owner PID match ", IPT_OWNER_PID, true);
+	owner_mt6_print_item_v0(info, "owner SID match ", IPT_OWNER_SID, true);
+}
+
+static void owner_mt_save(const void *ip, const struct xt_entry_match *match)
+{
+	const struct xt_owner_match_info *info = (void *)match->data;
+
+	owner_mt_print_item(info, "--socket-exists ", XT_OWNER_SOCKET, false);
+	owner_mt_print_item(info, "--uid-owner",      XT_OWNER_UID,    false);
+	owner_mt_print_item(info, "--gid-owner",      XT_OWNER_GID,    false);
+}
+
+static struct xtables_match owner_mt_reg_v0 = {
+	.version       = IPTABLES_VERSION,
+	.name          = "owner",
+	.family        = AF_INET,
+	.revision      = 0,
+	.size          = XT_ALIGN(sizeof(struct ipt_owner_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct ipt_owner_info)),
+	.help          = owner_mt_help_v0,
+	.parse         = owner_mt_parse_v0,
+	.final_check   = owner_mt_check,
+	.print         = owner_mt_print_v0,
+	.save          = owner_mt_save_v0,
+	.extra_opts    = owner_mt_opts_v0,
+};
+
+static struct xtables_match owner_mt6_reg_v0 = {
+	.version       = IPTABLES_VERSION,
+	.name          = "owner",
+	.family        = AF_INET6,
+	.revision      = 0,
+	.size          = XT_ALIGN(sizeof(struct ip6t_owner_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct ip6t_owner_info)),
+	.help          = owner_mt6_help_v0,
+	.parse         = owner_mt6_parse_v0,
+	.final_check   = owner_mt_check,
+	.print         = owner_mt6_print_v0,
+	.save          = owner_mt6_save_v0,
+	.extra_opts    = owner_mt6_opts_v0,
+};
+
+static struct xtables_match owner_mt_reg = {
+	.version       = IPTABLES_VERSION,
+	.name          = "owner",
+	.family        = AF_INET,
+	.revision      = 1,
+	.size          = XT_ALIGN(sizeof(struct xt_owner_match_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct xt_owner_match_info)),
+	.help          = owner_mt_help,
+	.parse         = owner_mt_parse,
+	.final_check   = owner_mt_check,
+	.print         = owner_mt_print,
+	.save          = owner_mt_save,
+	.extra_opts    = owner_mt_opts,
+};
+
+static struct xtables_match owner_mt6_reg = {
+	.version       = IPTABLES_VERSION,
+	.name          = "owner",
+	.family        = AF_INET6,
+	.revision      = 1,
+	.size          = XT_ALIGN(sizeof(struct xt_owner_match_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct xt_owner_match_info)),
+	.help          = owner_mt_help,
+	.parse         = owner_mt_parse,
+	.final_check   = owner_mt_check,
+	.print         = owner_mt_print,
+	.save          = owner_mt_save,
+	.extra_opts    = owner_mt_opts,
+};
+
+void _init(void)
+{
+	xtables_register_match(&owner_mt_reg_v0);
+	xtables_register_match(&owner_mt6_reg_v0);
+	xtables_register_match(&owner_mt_reg);
+	xtables_register_match(&owner_mt6_reg);
+}
Index: iptables-modules/extensions/libxt_owner.man
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_owner.man
@@ -0,0 +1,16 @@
+This module attempts to match various characteristics of the packet creator,
+for locally generated packets. This match is only valid in the OUTPUT and
+POSTROUTING chains. Forwarded packets do not have any socket associated with
+them. Packets from kernel threads do have a socket, but usually no owner.
+.TP
+\fB--uid-owner\fR \fIuserid\fR
+Matches if the packet socket's file structure (if it has one) is owned by the
+given user ID. A user name may be specified in place of \fIuserid\fR, in which
+case iptables will try to look it up.
+.TP
+\fB--gid-owner\fR \fIgroupid\fR
+Matches if the packet socket's file structure is owned by the given group ID.
+A group name may be specified in place of \fIgroupid\fR.
+.TP
+\fB--socket-exists\fR
+Matches if the packet is associated with a socket.
Index: iptables-modules/include/linux/netfilter/xt_owner.h
===================================================================
--- /dev/null
+++ iptables-modules/include/linux/netfilter/xt_owner.h
@@ -0,0 +1,16 @@
+#ifndef _XT_OWNER_MATCH_H
+#define _XT_OWNER_MATCH_H
+
+enum {
+	XT_OWNER_UID    = 1 << 0,
+	XT_OWNER_GID    = 1 << 1,
+	XT_OWNER_SOCKET = 1 << 2,
+};
+
+struct xt_owner_match_info {
+	u_int32_t uid;
+	u_int32_t gid;
+	u_int8_t match, invert;
+};
+
+#endif /* _XT_OWNER_MATCH_H */
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux