blob: 233cd0be1431ce2adb9a7c5421599baa1b4be93e [file] [log] [blame]
Marc Bouchere6869a82000-03-20 06:03:29 +00001/* Shared library add-on to iptables to add OWNER matching support. */
2#include <stdio.h>
3#include <netdb.h>
4#include <string.h>
5#include <stdlib.h>
6#include <getopt.h>
7#include <pwd.h>
8#include <grp.h>
9
10#include <iptables.h>
11#include <linux/netfilter_ipv4/ipt_owner.h>
12
13/* Function which prints out usage message. */
14static void
15help(void)
16{
17 printf(
18"OWNER match v%s options:\n"
19"[!] --uid-owner userid Match local uid\n"
20"[!] --gid-owner groupid Match local gid\n"
21"[!] --pid-owner processid Match local pid\n"
22"[!] --sid-owner sessionid Match local sid\n"
23"\n",
24NETFILTER_VERSION);
25}
26
27static struct option opts[] = {
28 { "uid-owner", 1, 0, '1' },
29 { "gid-owner", 1, 0, '2' },
30 { "pid-owner", 1, 0, '3' },
31 { "sid-owner", 1, 0, '4' },
32 {0}
33};
34
35/* Initialize the match. */
36static void
37init(struct ipt_entry_match *m, unsigned int *nfcache)
38{
39 /* Can't cache this. */
40 *nfcache |= NFC_UNKNOWN;
41}
42
43/* Function which parses command options; returns true if it
44 ate an option */
45static int
46parse(int c, char **argv, int invert, unsigned int *flags,
47 const struct ipt_entry *entry,
48 unsigned int *nfcache,
49 struct ipt_entry_match **match)
50{
51 struct ipt_owner_info *ownerinfo = (struct ipt_owner_info *)(*match)->data;
52
53 switch (c) {
54 char *end;
55 struct passwd *pwd;
56 struct group *grp;
57 case '1':
58 if (check_inverse(optarg, &invert))
59 optind++;
60
61 if ((pwd = getpwnam(optarg)))
62 ownerinfo->uid = pwd->pw_uid;
63 else {
64 ownerinfo->uid = strtoul(optarg, &end, 0);
65 if (*end != '\0' || end == optarg)
66 exit_error(PARAMETER_PROBLEM, "Bad OWNER UID value `%s'", optarg);
67 }
68 if (invert)
69 ownerinfo->invert |= IPT_OWNER_UID;
70 ownerinfo->match |= IPT_OWNER_UID;
71 *flags = 1;
72 break;
73
74 case '2':
75 if (check_inverse(optarg, &invert))
76 optind++;
77 if ((grp = getgrnam(optarg)))
78 ownerinfo->gid = grp->gr_gid;
79 else {
80 ownerinfo->gid = strtoul(optarg, &end, 0);
81 if (*end != '\0' || end == optarg)
82 exit_error(PARAMETER_PROBLEM, "Bad OWNER GID value `%s'", optarg);
83 }
84 if (invert)
85 ownerinfo->invert |= IPT_OWNER_GID;
86 ownerinfo->match |= IPT_OWNER_GID;
87 *flags = 1;
88 break;
89
90 case '3':
91 if (check_inverse(optarg, &invert))
92 optind++;
93 ownerinfo->pid = strtoul(optarg, &end, 0);
94 if (*end != '\0' || end == optarg)
95 exit_error(PARAMETER_PROBLEM, "Bad OWNER PID value `%s'", optarg);
96 if (invert)
97 ownerinfo->invert |= IPT_OWNER_PID;
98 ownerinfo->match |= IPT_OWNER_PID;
99 *flags = 1;
100 break;
101
102 case '4':
103 if (check_inverse(optarg, &invert))
104 optind++;
105 ownerinfo->sid = strtoul(optarg, &end, 0);
106 if (*end != '\0' || end == optarg)
107 exit_error(PARAMETER_PROBLEM, "Bad OWNER SID value `%s'", optarg);
108 if (invert)
109 ownerinfo->invert |= IPT_OWNER_SID;
110 ownerinfo->match |= IPT_OWNER_SID;
111 *flags = 1;
112 break;
113
114 default:
115 return 0;
116 }
117 return 1;
118}
119
120static void
121print_item(struct ipt_owner_info *info, u_int8_t flag, int numeric, char *label)
122{
123 if(info->match & flag) {
124
125 printf(label);
126
127 if (info->invert & flag)
128 fputc('!', stdout);
129
130 switch(info->match & flag) {
131 case IPT_OWNER_UID:
132 if(!numeric) {
133 struct passwd *pwd = getpwuid(info->uid);
134
135 if(pwd && pwd->pw_name) {
136 printf("%s ", pwd->pw_name);
137 break;
138 }
139 /* FALLTHROUGH */
140 }
141 printf("%u ", info->uid);
142 break;
143 case IPT_OWNER_GID:
144 if(!numeric) {
145 struct group *grp = getgrgid(info->gid);
146
147 if(grp && grp->gr_name) {
148 printf("%s ", grp->gr_name);
149 break;
150 }
151 /* FALLTHROUGH */
152 }
153 printf("%u ", info->gid);
154 break;
155 case IPT_OWNER_PID:
156 printf("%u ", info->pid);
157 break;
158 case IPT_OWNER_SID:
159 printf("%u ", info->sid);
160 break;
161 default:
162 break;
163 }
164 }
165}
166
167/* Final check; must have specified --own. */
168static void
169final_check(unsigned int flags)
170{
171 if (!flags)
172 exit_error(PARAMETER_PROBLEM,
173 "OWNER match: You must specify one or more options");
174}
175
176/* Prints out the matchinfo. */
177static void
178print(const struct ipt_ip *ip,
179 const struct ipt_entry_match *match,
180 int numeric)
181{
182 struct ipt_owner_info *info = (struct ipt_owner_info *)match->data;
183
184 print_item(info, IPT_OWNER_UID, numeric, "OWNER UID match ");
185 print_item(info, IPT_OWNER_GID, numeric, "OWNER GID match ");
186 print_item(info, IPT_OWNER_PID, numeric, "OWNER PID match ");
187 print_item(info, IPT_OWNER_SID, numeric, "OWNER SID match ");
188}
189
190/* Saves the union ipt_matchinfo in parsable form to stdout. */
191static void
192save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
193{
194 struct ipt_owner_info *info = (struct ipt_owner_info *)match->data;
195
196 print_item(info, IPT_OWNER_UID, 0, "--uid-owner ");
197 print_item(info, IPT_OWNER_GID, 0, "--gid-owner ");
198 print_item(info, IPT_OWNER_PID, 0, "--pid-owner ");
199 print_item(info, IPT_OWNER_SID, 0, "--sid-owner ");
200}
201
202struct iptables_match owner
203= { NULL,
204 "owner",
205 NETFILTER_VERSION,
Rusty Russell73f72f52000-07-03 10:17:57 +0000206 IPT_ALIGN(sizeof(struct ipt_owner_info)),
207 IPT_ALIGN(sizeof(struct ipt_owner_info)),
Marc Bouchere6869a82000-03-20 06:03:29 +0000208 &help,
209 &init,
210 &parse,
211 &final_check,
212 &print,
213 &save,
214 opts
215};
216
217void _init(void)
218{
219 register_match(&owner);
220}