summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-11-29 11:23:09 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2013-11-29 11:29:41 +0100
commite0ed4c45d9ad2564ae3ab3f4465466b0130a845c (patch)
tree7c01dfb9fd12e0a60e926806243898441984eb6c /src
parent3f513f1d264c0a6c481e04fd346d35e9fb9a56e2 (diff)
meta: relax restriction on UID/GID parsing
nft is currently rejecting unknown UID/GID if they don't exist in the system, relax this as Bjørnar Ness considers this is a valid scenario. Now this only reports an error if you pass an unknown user (expressed as string or if the UID/GID goes above 32 bits). Reported-by: Bjørnar Ness <bjornar.ness@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/meta.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/src/meta.c b/src/meta.c
index 80c2638f..32f30121 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -197,11 +197,14 @@ static void uid_type_print(const struct expr *expr)
struct passwd *pw;
if (numeric_output < NUMERIC_ALL) {
- pw = getpwuid(mpz_get_uint32(expr->value));
- if (pw != NULL) {
+ uint32_t uid = mpz_get_uint32(expr->value);
+
+ pw = getpwuid(uid);
+ if (pw != NULL)
printf("%s", pw->pw_name);
- return;
- }
+ else
+ printf("%d", uid);
+ return;
}
expr_basetype(expr)->print(expr);
}
@@ -210,19 +213,23 @@ static struct error_record *uid_type_parse(const struct expr *sym,
struct expr **res)
{
struct passwd *pw;
+ uint64_t uid;
+ char *endptr = NULL;
pw = getpwnam(sym->identifier);
- if (pw == NULL) {
- /* Try harder, lookup based on UID */
- pw = getpwuid(atol(sym->identifier));
- if (pw == NULL)
+ if (pw != NULL)
+ uid = pw->pw_uid;
+ else {
+ uid = strtoull(sym->identifier, &endptr, 10);
+ if (uid > UINT32_MAX)
+ return error(&sym->location, "Value too large");
+ else if (*endptr)
return error(&sym->location, "User does not exist");
}
*res = constant_expr_alloc(&sym->location, sym->dtype,
BYTEORDER_HOST_ENDIAN,
- sizeof(pw->pw_uid) * BITS_PER_BYTE,
- &pw->pw_uid);
+ sizeof(pw->pw_uid) * BITS_PER_BYTE, &uid);
return NULL;
}
@@ -242,11 +249,14 @@ static void gid_type_print(const struct expr *expr)
struct group *gr;
if (numeric_output < NUMERIC_ALL) {
- gr = getgrgid(mpz_get_uint32(expr->value));
- if (gr != NULL) {
+ uint32_t gid = mpz_get_uint32(expr->value);
+
+ gr = getgrgid(gid);
+ if (gr != NULL)
printf("%s", gr->gr_name);
- return;
- }
+ else
+ printf("%u", gid);
+ return;
}
expr_basetype(expr)->print(expr);
}
@@ -255,19 +265,23 @@ static struct error_record *gid_type_parse(const struct expr *sym,
struct expr **res)
{
struct group *gr;
+ uint64_t gid;
+ char *endptr = NULL;
gr = getgrnam(sym->identifier);
- if (gr == NULL) {
- /* Try harder, lookup based on GID */
- gr = getgrgid(atol(sym->identifier));
- if (gr == NULL)
+ if (gr != NULL)
+ gid = gr->gr_gid;
+ else {
+ gid = strtoull(sym->identifier, &endptr, 0);
+ if (gid > UINT32_MAX)
+ return error(&sym->location, "Value too large");
+ else if (*endptr)
return error(&sym->location, "Group does not exist");
}
*res = constant_expr_alloc(&sym->location, sym->dtype,
BYTEORDER_HOST_ENDIAN,
- sizeof(gr->gr_gid) * BITS_PER_BYTE,
- &gr->gr_gid);
+ sizeof(gr->gr_gid) * BITS_PER_BYTE, &gid);
return NULL;
}