blob: ee3283cdfdf226c66d2e7479c70ca5eec93031fa [file] [log] [blame]
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +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 <ip6tables.h>
11#include <linux/netfilter_ipv6/ip6t_owner.h>
12
13/* Function which prints out usage message. */
14static void
15help(void)
16{
Patrick McHardy5e3d5ca2003-04-13 16:32:49 +000017#ifdef IP6T_OWNER_COMM
18 printf(
19"OWNER match v%s options:\n"
20"[!] --uid-owner userid Match local uid\n"
21"[!] --gid-owner groupid Match local gid\n"
22"[!] --pid-owner processid Match local pid\n"
23"[!] --sid-owner sessionid Match local sid\n"
24"[!] --cmd-owner name Match local command name\n"
25"\n",
26IPTABLES_VERSION);
27#else
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +000028 printf(
29"OWNER match v%s options:\n"
30"[!] --uid-owner userid Match local uid\n"
31"[!] --gid-owner groupid Match local gid\n"
32"[!] --pid-owner processid Match local pid\n"
33"[!] --sid-owner sessionid Match local sid\n"
34"\n",
Harald Welte80fe35d2002-05-29 13:08:15 +000035IPTABLES_VERSION);
Patrick McHardy5e3d5ca2003-04-13 16:32:49 +000036#endif /* IP6T_OWNER_COMM */
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +000037}
38
39static struct option opts[] = {
40 { "uid-owner", 1, 0, '1' },
41 { "gid-owner", 1, 0, '2' },
42 { "pid-owner", 1, 0, '3' },
43 { "sid-owner", 1, 0, '4' },
Patrick McHardy5e3d5ca2003-04-13 16:32:49 +000044#ifdef IP6T_OWNER_COMM
45 { "cmd-owner", 1, 0, '5' },
46#endif
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +000047 {0}
48};
49
50/* Initialize the match. */
51static void
52init(struct ip6t_entry_match *m, unsigned int *nfcache)
53{
54 /* Can't cache this. */
55 *nfcache |= NFC_UNKNOWN;
56}
57
58/* Function which parses command options; returns true if it
59 ate an option */
60static int
61parse(int c, char **argv, int invert, unsigned int *flags,
62 const struct ip6t_entry *entry,
63 unsigned int *nfcache,
64 struct ip6t_entry_match **match)
65{
66 struct ip6t_owner_info *ownerinfo = (struct ip6t_owner_info *)(*match)->data;
67
68 switch (c) {
69 char *end;
70 struct passwd *pwd;
71 struct group *grp;
72 case '1':
Harald Welteb77f1da2002-03-14 11:35:58 +000073 check_inverse(optarg, &invert, &optind, 0);
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +000074
75 if ((pwd = getpwnam(optarg)))
76 ownerinfo->uid = pwd->pw_uid;
77 else {
78 ownerinfo->uid = strtoul(optarg, &end, 0);
79 if (*end != '\0' || end == optarg)
80 exit_error(PARAMETER_PROBLEM, "Bad OWNER UID value `%s'", optarg);
81 }
82 if (invert)
83 ownerinfo->invert |= IP6T_OWNER_UID;
84 ownerinfo->match |= IP6T_OWNER_UID;
85 *flags = 1;
86 break;
87
88 case '2':
Harald Welteb77f1da2002-03-14 11:35:58 +000089 check_inverse(optarg, &invert, &optind, 0);
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +000090 if ((grp = getgrnam(optarg)))
91 ownerinfo->gid = grp->gr_gid;
92 else {
93 ownerinfo->gid = strtoul(optarg, &end, 0);
94 if (*end != '\0' || end == optarg)
95 exit_error(PARAMETER_PROBLEM, "Bad OWNER GID value `%s'", optarg);
96 }
97 if (invert)
98 ownerinfo->invert |= IP6T_OWNER_GID;
99 ownerinfo->match |= IP6T_OWNER_GID;
100 *flags = 1;
101 break;
102
103 case '3':
Harald Welteb77f1da2002-03-14 11:35:58 +0000104 check_inverse(optarg, &invert, &optind, 0);
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000105 ownerinfo->pid = strtoul(optarg, &end, 0);
106 if (*end != '\0' || end == optarg)
107 exit_error(PARAMETER_PROBLEM, "Bad OWNER PID value `%s'", optarg);
108 if (invert)
109 ownerinfo->invert |= IP6T_OWNER_PID;
110 ownerinfo->match |= IP6T_OWNER_PID;
111 *flags = 1;
112 break;
113
114 case '4':
Harald Welteb77f1da2002-03-14 11:35:58 +0000115 check_inverse(optarg, &invert, &optind, 0);
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000116 ownerinfo->sid = strtoul(optarg, &end, 0);
117 if (*end != '\0' || end == optarg)
118 exit_error(PARAMETER_PROBLEM, "Bad OWNER SID value `%s'", optarg);
119 if (invert)
120 ownerinfo->invert |= IP6T_OWNER_SID;
121 ownerinfo->match |= IP6T_OWNER_SID;
122 *flags = 1;
123 break;
124
Patrick McHardy5e3d5ca2003-04-13 16:32:49 +0000125#ifdef IP6T_OWNER_COMM
126 case '5':
127 check_inverse(optarg, &invert, &optind, 0);
128 if(strlen(optarg) > sizeof(ownerinfo->comm))
129 exit_error(PARAMETER_PROBLEM, "OWNER CMD `%s' too long, max %d characters", optarg, sizeof(ownerinfo->comm));
130
131 strncpy(ownerinfo->comm, optarg, sizeof(ownerinfo->comm));
132
133 if (invert)
134 ownerinfo->invert |= IP6T_OWNER_COMM;
135 ownerinfo->match |= IP6T_OWNER_COMM;
136 *flags = 1;
137 break;
138#endif
139
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000140 default:
141 return 0;
142 }
143 return 1;
144}
145
146static void
147print_item(struct ip6t_owner_info *info, u_int8_t flag, int numeric, char *label)
148{
149 if(info->match & flag) {
150
151 printf(label);
152
153 if (info->invert & flag)
154 fputc('!', stdout);
155
156 switch(info->match & flag) {
157 case IP6T_OWNER_UID:
158 if(!numeric) {
159 struct passwd *pwd = getpwuid(info->uid);
160
161 if(pwd && pwd->pw_name) {
162 printf("%s ", pwd->pw_name);
163 break;
164 }
165 /* FALLTHROUGH */
166 }
167 printf("%u ", info->uid);
168 break;
169 case IP6T_OWNER_GID:
170 if(!numeric) {
171 struct group *grp = getgrgid(info->gid);
172
173 if(grp && grp->gr_name) {
174 printf("%s ", grp->gr_name);
175 break;
176 }
177 /* FALLTHROUGH */
178 }
179 printf("%u ", info->gid);
180 break;
181 case IP6T_OWNER_PID:
182 printf("%u ", info->pid);
183 break;
184 case IP6T_OWNER_SID:
185 printf("%u ", info->sid);
186 break;
Patrick McHardy5e3d5ca2003-04-13 16:32:49 +0000187#ifdef IP6T_OWNER_COMM
188 case IP6T_OWNER_COMM:
189 printf("%.*s ", (int)sizeof(info->comm), info->comm);
190 break;
191#endif
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000192 default:
193 break;
194 }
195 }
196}
197
198/* Final check; must have specified --own. */
199static void
200final_check(unsigned int flags)
201{
202 if (!flags)
203 exit_error(PARAMETER_PROBLEM,
204 "OWNER match: You must specify one or more options");
205}
206
207/* Prints out the matchinfo. */
208static void
209print(const struct ip6t_ip6 *ip,
210 const struct ip6t_entry_match *match,
211 int numeric)
212{
213 struct ip6t_owner_info *info = (struct ip6t_owner_info *)match->data;
214
215 print_item(info, IP6T_OWNER_UID, numeric, "OWNER UID match ");
216 print_item(info, IP6T_OWNER_GID, numeric, "OWNER GID match ");
217 print_item(info, IP6T_OWNER_PID, numeric, "OWNER PID match ");
218 print_item(info, IP6T_OWNER_SID, numeric, "OWNER SID match ");
Patrick McHardy5e3d5ca2003-04-13 16:32:49 +0000219#ifdef IP6T_OWNER_COMM
220 print_item(info, IP6T_OWNER_COMM, numeric, "OWNER CMD match ");
221#endif
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000222}
223
224/* Saves the union ip6t_matchinfo in parsable form to stdout. */
225static void
226save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
227{
228 struct ip6t_owner_info *info = (struct ip6t_owner_info *)match->data;
229
230 print_item(info, IP6T_OWNER_UID, 0, "--uid-owner ");
231 print_item(info, IP6T_OWNER_GID, 0, "--gid-owner ");
232 print_item(info, IP6T_OWNER_PID, 0, "--pid-owner ");
233 print_item(info, IP6T_OWNER_SID, 0, "--sid-owner ");
Patrick McHardy5e3d5ca2003-04-13 16:32:49 +0000234#ifdef IP6T_OWNER_COMM
235 print_item(info, IP6T_OWNER_COMM, 0, "--cmd-owner ");
236#endif
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000237}
238
Harald Welte3efb6ea2001-08-06 18:50:21 +0000239static
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000240struct ip6tables_match owner
241= { NULL,
242 "owner",
Harald Welte80fe35d2002-05-29 13:08:15 +0000243 IPTABLES_VERSION,
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000244 IP6T_ALIGN(sizeof(struct ip6t_owner_info)),
245 IP6T_ALIGN(sizeof(struct ip6t_owner_info)),
246 &help,
247 &init,
248 &parse,
249 &final_check,
250 &print,
251 &save,
252 opts
253};
254
255void _init(void)
256{
257 register_match6(&owner);
258}