libxt_owner.c revision c4e1c0992937bce3ac72987aa43f4f3c219cf3e3
10469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy/* 20469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * libxt_owner - iptables addon for xt_owner 30469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * 40469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Copyright © CC Computer Consultants GmbH, 2007 - 2008 50469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Jan Engelhardt <jengelh@computergmbh.de> 60469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy */ 70469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <grp.h> 80469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <pwd.h> 90469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <stdbool.h> 100469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <stdio.h> 110469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <limits.h> 120469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <xtables.h> 130469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <linux/netfilter/xt_owner.h> 140469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 150469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy/* match and invert flags */ 160469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyenum { 172fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy IPT_OWNER_UID = 0x01, 180469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy IPT_OWNER_GID = 0x02, 190469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy IPT_OWNER_PID = 0x04, 200469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy IPT_OWNER_SID = 0x08, 210832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy IPT_OWNER_COMM = 0x10, 220469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy IP6T_OWNER_UID = IPT_OWNER_UID, 230832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy IP6T_OWNER_GID = IPT_OWNER_GID, 240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy IP6T_OWNER_PID = IPT_OWNER_PID, 250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy IP6T_OWNER_SID = IPT_OWNER_SID, 260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy IP6T_OWNER_COMM = IPT_OWNER_COMM, 278e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy}; 280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamystruct ipt_owner_info { 300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy uid_t uid; 310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy gid_t gid; 320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy pid_t pid; 330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy pid_t sid; 340832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy char comm[16]; 350832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy uint8_t match, invert; /* flags */ 3693a826f78f6313db791e6fc880439189897651b3Siva Velusamy}; 37e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block 3893a826f78f6313db791e6fc880439189897651b3Siva Velusamystruct ip6t_owner_info { 3993a826f78f6313db791e6fc880439189897651b3Siva Velusamy uid_t uid; 400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy gid_t gid; 410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy pid_t pid; 420832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy pid_t sid; 430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy char comm[16]; 440832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy uint8_t match, invert; /* flags */ 450832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy}; 460832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy 470832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy/* 480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Note: "UINT32_MAX - 1" is used in the code because -1 is a reserved 490832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy * UID/GID value anyway. 500832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy */ 510832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy 5293a826f78f6313db791e6fc880439189897651b3Siva Velusamyenum { 53e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block O_USER = 0, 5493a826f78f6313db791e6fc880439189897651b3Siva Velusamy O_GROUP, 550469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy O_SOCK_EXISTS, 560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy O_PROCESS, 5793a826f78f6313db791e6fc880439189897651b3Siva Velusamy O_SESSION, 5893a826f78f6313db791e6fc880439189897651b3Siva Velusamy O_COMM, 59e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block}; 6093a826f78f6313db791e6fc880439189897651b3Siva Velusamy 610469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamystatic void owner_mt_help_v0(void) 620469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy{ 630832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy printf( 640469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy"owner match options:\n" 6593a826f78f6313db791e6fc880439189897651b3Siva Velusamy"[!] --uid-owner userid Match local UID\n" 6693a826f78f6313db791e6fc880439189897651b3Siva Velusamy"[!] --gid-owner groupid Match local GID\n" 6793a826f78f6313db791e6fc880439189897651b3Siva Velusamy"[!] --pid-owner processid Match local PID\n" 68e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block"[!] --sid-owner sessionid Match local SID\n" 6993a826f78f6313db791e6fc880439189897651b3Siva Velusamy"[!] --cmd-owner name Match local command name\n" 700469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy"NOTE: PID, SID and command matching are broken on SMP\n"); 710469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 728e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy 738e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamystatic void owner_mt6_help_v0(void) 748e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy{ 758e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy printf( 768e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy"owner match options:\n" 778e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy"[!] --uid-owner userid Match local UID\n" 788e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy"[!] --gid-owner groupid Match local GID\n" 79c7d767ad57a25eeefbbfe2610396d800f04178edSiva Velusamy"[!] --pid-owner processid Match local PID\n" 80c7d767ad57a25eeefbbfe2610396d800f04178edSiva Velusamy"[!] --sid-owner sessionid Match local SID\n" 81c7d767ad57a25eeefbbfe2610396d800f04178edSiva Velusamy"NOTE: PID and SID matching are broken on SMP\n"); 828e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy} 838e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy 848e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamystatic void owner_mt_help(void) 858e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy{ 860832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy printf( 8793a826f78f6313db791e6fc880439189897651b3Siva Velusamy"owner match options:\n" 8893a826f78f6313db791e6fc880439189897651b3Siva Velusamy"[!] --uid-owner userid[-userid] Match local UID\n" 8993a826f78f6313db791e6fc880439189897651b3Siva Velusamy"[!] --gid-owner groupid[-groupid] Match local GID\n" 9093a826f78f6313db791e6fc880439189897651b3Siva Velusamy"[!] --socket-exists Match if socket exists\n"); 9193a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 9293a826f78f6313db791e6fc880439189897651b3Siva Velusamy 9393a826f78f6313db791e6fc880439189897651b3Siva Velusamy#define s struct ipt_owner_info 9493a826f78f6313db791e6fc880439189897651b3Siva Velusamystatic const struct xt_option_entry owner_mt_opts_v0[] = { 9593a826f78f6313db791e6fc880439189897651b3Siva Velusamy {.name = "uid-owner", .id = O_USER, .type = XTTYPE_STRING, 9693a826f78f6313db791e6fc880439189897651b3Siva Velusamy .flags = XTOPT_INVERT}, 970469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy {.name = "gid-owner", .id = O_GROUP, .type = XTTYPE_STRING, 980469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy .flags = XTOPT_INVERT}, 9993a826f78f6313db791e6fc880439189897651b3Siva Velusamy {.name = "pid-owner", .id = O_PROCESS, .type = XTTYPE_UINT32, 10093a826f78f6313db791e6fc880439189897651b3Siva Velusamy .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, pid), 10193a826f78f6313db791e6fc880439189897651b3Siva Velusamy .max = INT_MAX}, 10293a826f78f6313db791e6fc880439189897651b3Siva Velusamy {.name = "sid-owner", .id = O_SESSION, .type = XTTYPE_UINT32, 10393a826f78f6313db791e6fc880439189897651b3Siva Velusamy .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, sid), 10493a826f78f6313db791e6fc880439189897651b3Siva Velusamy .max = INT_MAX}, 10593a826f78f6313db791e6fc880439189897651b3Siva Velusamy {.name = "cmd-owner", .id = O_COMM, .type = XTTYPE_STRING, 10693a826f78f6313db791e6fc880439189897651b3Siva Velusamy .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, comm)}, 1070469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy XTOPT_TABLEEND, 1080469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}; 1090469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#undef s 11093a826f78f6313db791e6fc880439189897651b3Siva Velusamy 11193a826f78f6313db791e6fc880439189897651b3Siva Velusamy#define s struct ip6t_owner_info 11293a826f78f6313db791e6fc880439189897651b3Siva Velusamystatic const struct xt_option_entry owner_mt6_opts_v0[] = { 1130469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy {.name = "uid-owner", .id = O_USER, .type = XTTYPE_STRING, 1140469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy .flags = XTOPT_INVERT}, 11593a826f78f6313db791e6fc880439189897651b3Siva Velusamy {.name = "gid-owner", .id = O_GROUP, .type = XTTYPE_STRING, 11693a826f78f6313db791e6fc880439189897651b3Siva Velusamy .flags = XTOPT_INVERT}, 11793a826f78f6313db791e6fc880439189897651b3Siva Velusamy {.name = "pid-owner", .id = O_PROCESS, .type = XTTYPE_UINT32, 11893a826f78f6313db791e6fc880439189897651b3Siva Velusamy .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, pid), 11993a826f78f6313db791e6fc880439189897651b3Siva Velusamy .max = INT_MAX}, 12093a826f78f6313db791e6fc880439189897651b3Siva Velusamy {.name = "sid-owner", .id = O_SESSION, .type = XTTYPE_UINT32, 1210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, sid), 12293a826f78f6313db791e6fc880439189897651b3Siva Velusamy .max = INT_MAX}, 12393a826f78f6313db791e6fc880439189897651b3Siva Velusamy XTOPT_TABLEEND, 12493a826f78f6313db791e6fc880439189897651b3Siva Velusamy}; 1250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#undef s 1260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 1272fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamystatic const struct xt_option_entry owner_mt_opts[] = { 1282fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy {.name = "uid-owner", .id = O_USER, .type = XTTYPE_STRING, 1292fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy .flags = XTOPT_INVERT}, 1302fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy {.name = "gid-owner", .id = O_GROUP, .type = XTTYPE_STRING, 1312fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy .flags = XTOPT_INVERT}, 1322fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy {.name = "socket-exists", .id = O_SOCK_EXISTS, .type = XTTYPE_NONE, 1332fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy .flags = XTOPT_INVERT}, 1342fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy XTOPT_TABLEEND, 1352fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy}; 1362fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 1372fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamystatic void owner_mt_parse_v0(struct xt_option_call *cb) 1382fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy{ 13993a826f78f6313db791e6fc880439189897651b3Siva Velusamy struct ipt_owner_info *info = cb->data; 14093a826f78f6313db791e6fc880439189897651b3Siva Velusamy struct passwd *pwd; 14193a826f78f6313db791e6fc880439189897651b3Siva Velusamy struct group *grp; 14293a826f78f6313db791e6fc880439189897651b3Siva Velusamy unsigned int id; 14393a826f78f6313db791e6fc880439189897651b3Siva Velusamy 14493a826f78f6313db791e6fc880439189897651b3Siva Velusamy xtables_option_parse(cb); 14593a826f78f6313db791e6fc880439189897651b3Siva Velusamy switch (cb->entry->id) { 14693a826f78f6313db791e6fc880439189897651b3Siva Velusamy case O_USER: 14793a826f78f6313db791e6fc880439189897651b3Siva Velusamy if ((pwd = getpwnam(cb->arg)) != NULL) 14893a826f78f6313db791e6fc880439189897651b3Siva Velusamy id = pwd->pw_uid; 14993a826f78f6313db791e6fc880439189897651b3Siva Velusamy else if (!xtables_strtoui(cb->arg, NULL, &id, 0, UINT32_MAX - 1)) 15093a826f78f6313db791e6fc880439189897651b3Siva Velusamy xtables_param_act(XTF_BAD_VALUE, "owner", "--uid-owner", cb->arg); 15193a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (cb->invert) 15293a826f78f6313db791e6fc880439189897651b3Siva Velusamy info->invert |= IPT_OWNER_UID; 15393a826f78f6313db791e6fc880439189897651b3Siva Velusamy info->match |= IPT_OWNER_UID; 15493a826f78f6313db791e6fc880439189897651b3Siva Velusamy info->uid = id; 15593a826f78f6313db791e6fc880439189897651b3Siva Velusamy break; 15693a826f78f6313db791e6fc880439189897651b3Siva Velusamy case O_GROUP: 15793a826f78f6313db791e6fc880439189897651b3Siva Velusamy if ((grp = getgrnam(cb->arg)) != NULL) 15893a826f78f6313db791e6fc880439189897651b3Siva Velusamy id = grp->gr_gid; 15993a826f78f6313db791e6fc880439189897651b3Siva Velusamy else if (!xtables_strtoui(cb->arg, NULL, &id, 0, UINT32_MAX - 1)) 16093a826f78f6313db791e6fc880439189897651b3Siva Velusamy xtables_param_act(XTF_BAD_VALUE, "owner", "--gid-owner", cb->arg); 16193a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (cb->invert) 16293a826f78f6313db791e6fc880439189897651b3Siva Velusamy info->invert |= IPT_OWNER_GID; 16393a826f78f6313db791e6fc880439189897651b3Siva Velusamy info->match |= IPT_OWNER_GID; 16493a826f78f6313db791e6fc880439189897651b3Siva Velusamy info->gid = id; 16593a826f78f6313db791e6fc880439189897651b3Siva Velusamy break; 16693a826f78f6313db791e6fc880439189897651b3Siva Velusamy case O_PROCESS: 16793a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (cb->invert) 16893a826f78f6313db791e6fc880439189897651b3Siva Velusamy info->invert |= IPT_OWNER_PID; 16993a826f78f6313db791e6fc880439189897651b3Siva Velusamy info->match |= IPT_OWNER_PID; 17093a826f78f6313db791e6fc880439189897651b3Siva Velusamy break; 1710469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy case O_SESSION: 17293a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (cb->invert) 17393a826f78f6313db791e6fc880439189897651b3Siva Velusamy info->invert |= IPT_OWNER_SID; 1740469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy info->match |= IPT_OWNER_SID; 1750469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy break; 1760469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy case O_COMM: 1770469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy if (cb->invert) 178 info->invert |= IPT_OWNER_COMM; 179 info->match |= IPT_OWNER_COMM; 180 break; 181 } 182} 183 184static void owner_mt6_parse_v0(struct xt_option_call *cb) 185{ 186 struct ip6t_owner_info *info = cb->data; 187 struct passwd *pwd; 188 struct group *grp; 189 unsigned int id; 190 191 xtables_option_parse(cb); 192 switch (cb->entry->id) { 193 case O_USER: 194 if ((pwd = getpwnam(cb->arg)) != NULL) 195 id = pwd->pw_uid; 196 else if (!xtables_strtoui(cb->arg, NULL, &id, 0, UINT32_MAX - 1)) 197 xtables_param_act(XTF_BAD_VALUE, "owner", "--uid-owner", cb->arg); 198 if (cb->invert) 199 info->invert |= IP6T_OWNER_UID; 200 info->match |= IP6T_OWNER_UID; 201 info->uid = id; 202 break; 203 case O_GROUP: 204 if ((grp = getgrnam(cb->arg)) != NULL) 205 id = grp->gr_gid; 206 else if (!xtables_strtoui(cb->arg, NULL, &id, 0, UINT32_MAX - 1)) 207 xtables_param_act(XTF_BAD_VALUE, "owner", "--gid-owner", cb->arg); 208 if (cb->invert) 209 info->invert |= IP6T_OWNER_GID; 210 info->match |= IP6T_OWNER_GID; 211 info->gid = id; 212 break; 213 case O_PROCESS: 214 if (cb->invert) 215 info->invert |= IP6T_OWNER_PID; 216 info->match |= IP6T_OWNER_PID; 217 break; 218 case O_SESSION: 219 if (cb->invert) 220 info->invert |= IP6T_OWNER_SID; 221 info->match |= IP6T_OWNER_SID; 222 break; 223 } 224} 225 226static void owner_parse_range(const char *s, unsigned int *from, 227 unsigned int *to, const char *opt) 228{ 229 char *end; 230 231 /* -1 is reversed, so the max is one less than that. */ 232 if (!xtables_strtoui(s, &end, from, 0, UINT32_MAX - 1)) 233 xtables_param_act(XTF_BAD_VALUE, "owner", opt, s); 234 *to = *from; 235 if (*end == '-' || *end == ':') 236 if (!xtables_strtoui(end + 1, &end, to, 0, UINT32_MAX - 1)) 237 xtables_param_act(XTF_BAD_VALUE, "owner", opt, s); 238 if (*end != '\0') 239 xtables_param_act(XTF_BAD_VALUE, "owner", opt, s); 240} 241 242static void owner_mt_parse(struct xt_option_call *cb) 243{ 244 struct xt_owner_match_info *info = cb->data; 245 struct passwd *pwd; 246 struct group *grp; 247 unsigned int from, to; 248 249 xtables_option_parse(cb); 250 switch (cb->entry->id) { 251 case O_USER: 252 if ((pwd = getpwnam(cb->arg)) != NULL) 253 from = to = pwd->pw_uid; 254 else 255 owner_parse_range(cb->arg, &from, &to, "--uid-owner"); 256 if (cb->invert) 257 info->invert |= XT_OWNER_UID; 258 info->match |= XT_OWNER_UID; 259 info->uid_min = from; 260 info->uid_max = to; 261 break; 262 case O_GROUP: 263 if ((grp = getgrnam(cb->arg)) != NULL) 264 from = to = grp->gr_gid; 265 else 266 owner_parse_range(cb->arg, &from, &to, "--gid-owner"); 267 if (cb->invert) 268 info->invert |= XT_OWNER_GID; 269 info->match |= XT_OWNER_GID; 270 info->gid_min = from; 271 info->gid_max = to; 272 break; 273 case O_SOCK_EXISTS: 274 if (cb->invert) 275 info->invert |= XT_OWNER_SOCKET; 276 info->match |= XT_OWNER_SOCKET; 277 break; 278 } 279} 280 281static void owner_mt_check(struct xt_fcheck_call *cb) 282{ 283 if (cb->xflags == 0) 284 xtables_error(PARAMETER_PROBLEM, "owner: At least one of " 285 "--uid-owner, --gid-owner or --socket-exists " 286 "is required"); 287} 288 289static void 290owner_mt_print_item_v0(const struct ipt_owner_info *info, const char *label, 291 uint8_t flag, bool numeric) 292{ 293 if (!(info->match & flag)) 294 return; 295 if (info->invert & flag) 296 printf(" !"); 297 printf(" %s", label); 298 299 switch (info->match & flag) { 300 case IPT_OWNER_UID: 301 if (!numeric) { 302 struct passwd *pwd = getpwuid(info->uid); 303 304 if (pwd != NULL && pwd->pw_name != NULL) { 305 printf(" %s", pwd->pw_name); 306 break; 307 } 308 } 309 printf(" %u", (unsigned int)info->uid); 310 break; 311 312 case IPT_OWNER_GID: 313 if (!numeric) { 314 struct group *grp = getgrgid(info->gid); 315 316 if (grp != NULL && grp->gr_name != NULL) { 317 printf(" %s", grp->gr_name); 318 break; 319 } 320 } 321 printf(" %u", (unsigned int)info->gid); 322 break; 323 324 case IPT_OWNER_PID: 325 printf(" %u", (unsigned int)info->pid); 326 break; 327 328 case IPT_OWNER_SID: 329 printf(" %u", (unsigned int)info->sid); 330 break; 331 332 case IPT_OWNER_COMM: 333 printf(" %.*s", (int)sizeof(info->comm), info->comm); 334 break; 335 } 336} 337 338static void 339owner_mt6_print_item_v0(const struct ip6t_owner_info *info, const char *label, 340 uint8_t flag, bool numeric) 341{ 342 if (!(info->match & flag)) 343 return; 344 if (info->invert & flag) 345 printf(" !"); 346 printf(" %s", label); 347 348 switch (info->match & flag) { 349 case IP6T_OWNER_UID: 350 if (!numeric) { 351 struct passwd *pwd = getpwuid(info->uid); 352 353 if (pwd != NULL && pwd->pw_name != NULL) { 354 printf(" %s", pwd->pw_name); 355 break; 356 } 357 } 358 printf(" %u", (unsigned int)info->uid); 359 break; 360 361 case IP6T_OWNER_GID: 362 if (!numeric) { 363 struct group *grp = getgrgid(info->gid); 364 365 if (grp != NULL && grp->gr_name != NULL) { 366 printf(" %s", grp->gr_name); 367 break; 368 } 369 } 370 printf(" %u", (unsigned int)info->gid); 371 break; 372 373 case IP6T_OWNER_PID: 374 printf(" %u", (unsigned int)info->pid); 375 break; 376 377 case IP6T_OWNER_SID: 378 printf(" %u", (unsigned int)info->sid); 379 break; 380 } 381} 382 383static void 384owner_mt_print_item(const struct xt_owner_match_info *info, const char *label, 385 uint8_t flag, bool numeric) 386{ 387 if (!(info->match & flag)) 388 return; 389 if (info->invert & flag) 390 printf(" !"); 391 printf(" %s", label); 392 393 switch (info->match & flag) { 394 case XT_OWNER_UID: 395 if (info->uid_min != info->uid_max) { 396 printf(" %u-%u", (unsigned int)info->uid_min, 397 (unsigned int)info->uid_max); 398 break; 399 } else if (!numeric) { 400 const struct passwd *pwd = getpwuid(info->uid_min); 401 402 if (pwd != NULL && pwd->pw_name != NULL) { 403 printf(" %s", pwd->pw_name); 404 break; 405 } 406 } 407 printf(" %u", (unsigned int)info->uid_min); 408 break; 409 410 case XT_OWNER_GID: 411 if (info->gid_min != info->gid_max) { 412 printf(" %u-%u", (unsigned int)info->gid_min, 413 (unsigned int)info->gid_max); 414 break; 415 } else if (!numeric) { 416 const struct group *grp = getgrgid(info->gid_min); 417 418 if (grp != NULL && grp->gr_name != NULL) { 419 printf(" %s", grp->gr_name); 420 break; 421 } 422 } 423 printf(" %u", (unsigned int)info->gid_min); 424 break; 425 } 426} 427 428static void 429owner_mt_print_v0(const void *ip, const struct xt_entry_match *match, 430 int numeric) 431{ 432 const struct ipt_owner_info *info = (void *)match->data; 433 434 owner_mt_print_item_v0(info, "owner UID match", IPT_OWNER_UID, numeric); 435 owner_mt_print_item_v0(info, "owner GID match", IPT_OWNER_GID, numeric); 436 owner_mt_print_item_v0(info, "owner PID match", IPT_OWNER_PID, numeric); 437 owner_mt_print_item_v0(info, "owner SID match", IPT_OWNER_SID, numeric); 438 owner_mt_print_item_v0(info, "owner CMD match", IPT_OWNER_COMM, numeric); 439} 440 441static void 442owner_mt6_print_v0(const void *ip, const struct xt_entry_match *match, 443 int numeric) 444{ 445 const struct ip6t_owner_info *info = (void *)match->data; 446 447 owner_mt6_print_item_v0(info, "owner UID match", IPT_OWNER_UID, numeric); 448 owner_mt6_print_item_v0(info, "owner GID match", IPT_OWNER_GID, numeric); 449 owner_mt6_print_item_v0(info, "owner PID match", IPT_OWNER_PID, numeric); 450 owner_mt6_print_item_v0(info, "owner SID match", IPT_OWNER_SID, numeric); 451} 452 453static void owner_mt_print(const void *ip, const struct xt_entry_match *match, 454 int numeric) 455{ 456 const struct xt_owner_match_info *info = (void *)match->data; 457 458 owner_mt_print_item(info, "owner socket exists", XT_OWNER_SOCKET, numeric); 459 owner_mt_print_item(info, "owner UID match", XT_OWNER_UID, numeric); 460 owner_mt_print_item(info, "owner GID match", XT_OWNER_GID, numeric); 461} 462 463static void 464owner_mt_save_v0(const void *ip, const struct xt_entry_match *match) 465{ 466 const struct ipt_owner_info *info = (void *)match->data; 467 468 owner_mt_print_item_v0(info, "--uid-owner", IPT_OWNER_UID, true); 469 owner_mt_print_item_v0(info, "--gid-owner", IPT_OWNER_GID, true); 470 owner_mt_print_item_v0(info, "--pid-owner", IPT_OWNER_PID, true); 471 owner_mt_print_item_v0(info, "--sid-owner", IPT_OWNER_SID, true); 472 owner_mt_print_item_v0(info, "--cmd-owner", IPT_OWNER_COMM, true); 473} 474 475static void 476owner_mt6_save_v0(const void *ip, const struct xt_entry_match *match) 477{ 478 const struct ip6t_owner_info *info = (void *)match->data; 479 480 owner_mt6_print_item_v0(info, "--uid-owner", IPT_OWNER_UID, true); 481 owner_mt6_print_item_v0(info, "--gid-owner", IPT_OWNER_GID, true); 482 owner_mt6_print_item_v0(info, "--pid-owner", IPT_OWNER_PID, true); 483 owner_mt6_print_item_v0(info, "--sid-owner", IPT_OWNER_SID, true); 484} 485 486static void owner_mt_save(const void *ip, const struct xt_entry_match *match) 487{ 488 const struct xt_owner_match_info *info = (void *)match->data; 489 490 owner_mt_print_item(info, "--socket-exists", XT_OWNER_SOCKET, true); 491 owner_mt_print_item(info, "--uid-owner", XT_OWNER_UID, true); 492 owner_mt_print_item(info, "--gid-owner", XT_OWNER_GID, true); 493} 494 495static struct xtables_match owner_mt_reg[] = { 496 { 497 .version = XTABLES_VERSION, 498 .name = "owner", 499 .revision = 0, 500 .family = NFPROTO_IPV4, 501 .size = XT_ALIGN(sizeof(struct ipt_owner_info)), 502 .userspacesize = XT_ALIGN(sizeof(struct ipt_owner_info)), 503 .help = owner_mt_help_v0, 504 .x6_parse = owner_mt_parse_v0, 505 .x6_fcheck = owner_mt_check, 506 .print = owner_mt_print_v0, 507 .save = owner_mt_save_v0, 508 .x6_options = owner_mt_opts_v0, 509 }, 510 { 511 .version = XTABLES_VERSION, 512 .name = "owner", 513 .revision = 0, 514 .family = NFPROTO_IPV6, 515 .size = XT_ALIGN(sizeof(struct ip6t_owner_info)), 516 .userspacesize = XT_ALIGN(sizeof(struct ip6t_owner_info)), 517 .help = owner_mt6_help_v0, 518 .x6_parse = owner_mt6_parse_v0, 519 .x6_fcheck = owner_mt_check, 520 .print = owner_mt6_print_v0, 521 .save = owner_mt6_save_v0, 522 .x6_options = owner_mt6_opts_v0, 523 }, 524 { 525 .version = XTABLES_VERSION, 526 .name = "owner", 527 .revision = 1, 528 .family = NFPROTO_UNSPEC, 529 .size = XT_ALIGN(sizeof(struct xt_owner_match_info)), 530 .userspacesize = XT_ALIGN(sizeof(struct xt_owner_match_info)), 531 .help = owner_mt_help, 532 .x6_parse = owner_mt_parse, 533 .x6_fcheck = owner_mt_check, 534 .print = owner_mt_print, 535 .save = owner_mt_save, 536 .x6_options = owner_mt_opts, 537 }, 538}; 539 540void _init(void) 541{ 542 xtables_register_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg)); 543} 544