1 /* Shared library add-on to iptables to add OWNER matching support. */
11 #include <linux/netfilter_ipv4/ipt_owner.h>
13 /* Function which prints out usage message. */
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 "NOTE: pid, sid and command matching are broken on SMP\n"
30 "OWNER match v%s options:\n"
31 "[!] --uid-owner userid Match local uid\n"
32 "[!] --gid-owner groupid Match local gid\n"
33 "[!] --pid-owner processid Match local pid\n"
34 "[!] --sid-owner sessionid Match local sid\n"
35 "NOTE: pid and sid matching are broken on SMP\n"
38 #endif /* IPT_OWNER_COMM */
41 static struct option opts
[] = {
42 { "uid-owner", 1, 0, '1' },
43 { "gid-owner", 1, 0, '2' },
44 { "pid-owner", 1, 0, '3' },
45 { "sid-owner", 1, 0, '4' },
47 { "cmd-owner", 1, 0, '5' },
52 /* Function which parses command options; returns true if it
55 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
56 const struct ipt_entry
*entry
,
57 unsigned int *nfcache
,
58 struct ipt_entry_match
**match
)
60 struct ipt_owner_info
*ownerinfo
= (struct ipt_owner_info
*)(*match
)->data
;
67 check_inverse(optarg
, &invert
, &optind
, 0);
68 if ((pwd
= getpwnam(optarg
)))
69 ownerinfo
->uid
= pwd
->pw_uid
;
71 ownerinfo
->uid
= strtoul(optarg
, &end
, 0);
72 if (*end
!= '\0' || end
== optarg
)
73 exit_error(PARAMETER_PROBLEM
, "Bad OWNER UID value `%s'", optarg
);
76 ownerinfo
->invert
|= IPT_OWNER_UID
;
77 ownerinfo
->match
|= IPT_OWNER_UID
;
82 check_inverse(optarg
, &invert
, &optind
, 0);
83 if ((grp
= getgrnam(optarg
)))
84 ownerinfo
->gid
= grp
->gr_gid
;
86 ownerinfo
->gid
= strtoul(optarg
, &end
, 0);
87 if (*end
!= '\0' || end
== optarg
)
88 exit_error(PARAMETER_PROBLEM
, "Bad OWNER GID value `%s'", optarg
);
91 ownerinfo
->invert
|= IPT_OWNER_GID
;
92 ownerinfo
->match
|= IPT_OWNER_GID
;
97 check_inverse(optarg
, &invert
, &optind
, 0);
98 ownerinfo
->pid
= strtoul(optarg
, &end
, 0);
99 if (*end
!= '\0' || end
== optarg
)
100 exit_error(PARAMETER_PROBLEM
, "Bad OWNER PID value `%s'", optarg
);
102 ownerinfo
->invert
|= IPT_OWNER_PID
;
103 ownerinfo
->match
|= IPT_OWNER_PID
;
108 check_inverse(optarg
, &invert
, &optind
, 0);
109 ownerinfo
->sid
= strtoul(optarg
, &end
, 0);
110 if (*end
!= '\0' || end
== optarg
)
111 exit_error(PARAMETER_PROBLEM
, "Bad OWNER SID value `%s'", optarg
);
113 ownerinfo
->invert
|= IPT_OWNER_SID
;
114 ownerinfo
->match
|= IPT_OWNER_SID
;
118 #ifdef IPT_OWNER_COMM
120 check_inverse(optarg
, &invert
, &optind
, 0);
121 if(strlen(optarg
) > sizeof(ownerinfo
->comm
))
122 exit_error(PARAMETER_PROBLEM
, "OWNER CMD `%s' too long, max %u characters", optarg
, (unsigned int)sizeof(ownerinfo
->comm
));
124 strncpy(ownerinfo
->comm
, optarg
, sizeof(ownerinfo
->comm
));
125 ownerinfo
->comm
[sizeof(ownerinfo
->comm
)-1] = '\0';
128 ownerinfo
->invert
|= IPT_OWNER_COMM
;
129 ownerinfo
->match
|= IPT_OWNER_COMM
;
141 print_item(struct ipt_owner_info
*info
, u_int8_t flag
, int numeric
, char *label
)
143 if(info
->match
& flag
) {
145 if (info
->invert
& flag
)
150 switch(info
->match
& flag
) {
153 struct passwd
*pwd
= getpwuid(info
->uid
);
155 if(pwd
&& pwd
->pw_name
) {
156 printf("%s ", pwd
->pw_name
);
161 printf("%u ", info
->uid
);
165 struct group
*grp
= getgrgid(info
->gid
);
167 if(grp
&& grp
->gr_name
) {
168 printf("%s ", grp
->gr_name
);
173 printf("%u ", info
->gid
);
176 printf("%u ", info
->pid
);
179 printf("%u ", info
->sid
);
181 #ifdef IPT_OWNER_COMM
183 printf("%.*s ", (int)sizeof(info
->comm
), info
->comm
);
192 /* Final check; must have specified --own. */
194 final_check(unsigned int flags
)
197 exit_error(PARAMETER_PROBLEM
,
198 "OWNER match: You must specify one or more options");
201 /* Prints out the matchinfo. */
203 print(const struct ipt_ip
*ip
,
204 const struct ipt_entry_match
*match
,
207 struct ipt_owner_info
*info
= (struct ipt_owner_info
*)match
->data
;
209 print_item(info
, IPT_OWNER_UID
, numeric
, "OWNER UID match ");
210 print_item(info
, IPT_OWNER_GID
, numeric
, "OWNER GID match ");
211 print_item(info
, IPT_OWNER_PID
, numeric
, "OWNER PID match ");
212 print_item(info
, IPT_OWNER_SID
, numeric
, "OWNER SID match ");
213 #ifdef IPT_OWNER_COMM
214 print_item(info
, IPT_OWNER_COMM
, numeric
, "OWNER CMD match ");
218 /* Saves the union ipt_matchinfo in parsable form to stdout. */
220 save(const struct ipt_ip
*ip
, const struct ipt_entry_match
*match
)
222 struct ipt_owner_info
*info
= (struct ipt_owner_info
*)match
->data
;
224 print_item(info
, IPT_OWNER_UID
, 0, "--uid-owner ");
225 print_item(info
, IPT_OWNER_GID
, 0, "--gid-owner ");
226 print_item(info
, IPT_OWNER_PID
, 0, "--pid-owner ");
227 print_item(info
, IPT_OWNER_SID
, 0, "--sid-owner ");
228 #ifdef IPT_OWNER_COMM
229 print_item(info
, IPT_OWNER_COMM
, 0, "--cmd-owner ");
233 static struct iptables_match owner
= {
236 .version
= IPTABLES_VERSION
,
237 .size
= IPT_ALIGN(sizeof(struct ipt_owner_info
)),
238 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_owner_info
)),
241 .final_check
= &final_check
,
249 register_match(&owner
);