7a8867abfa
This reworks the user validation infrastructure. There are now two modes. In regular mode we are strict and test against a strict set of valid chars. And in "relaxed" mode we just filter out some really obvious, dangerous stuff. i.e. strict is whitelisting what is OK, but "relaxed" is blacklisting what is really not OK. The idea is that we use strict mode whenver we allocate a new user (i.e. in sysusers.d or homed), while "relaxed" mode is when we process users registered elsewhere, (i.e. userdb, logind, …) The requirements on user name validity vary wildly. SSSD thinks its fine to embedd "@" for example, while the suggested NAME_REGEX field on Debian does not even allow uppercase chars… This effectively liberaralizes a lot what we expect from usernames. The code that warns about questionnable user names is now optional and only used at places such as unit file parsing, so that it doesn't show up on every userdb query, but only when processing configuration files that know better. Fixes: #15149 #15090
391 lines
18 KiB
C
391 lines
18 KiB
C
/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
|
|
#include "alloc-util.h"
|
|
#include "format-util.h"
|
|
#include "libcrypt-util.h"
|
|
#include "log.h"
|
|
#include "macro.h"
|
|
#include "memory-util.h"
|
|
#include "path-util.h"
|
|
#include "string-util.h"
|
|
#include "user-util.h"
|
|
|
|
static void test_uid_to_name_one(uid_t uid, const char *name) {
|
|
_cleanup_free_ char *t = NULL;
|
|
|
|
log_info("/* %s("UID_FMT", \"%s\") */", __func__, uid, name);
|
|
|
|
assert_se(t = uid_to_name(uid));
|
|
if (!synthesize_nobody() && streq(name, NOBODY_USER_NAME)) {
|
|
log_info("(skipping detailed tests because nobody is not synthesized)");
|
|
return;
|
|
}
|
|
assert_se(streq_ptr(t, name));
|
|
}
|
|
|
|
static void test_gid_to_name_one(gid_t gid, const char *name) {
|
|
_cleanup_free_ char *t = NULL;
|
|
|
|
log_info("/* %s("GID_FMT", \"%s\") */", __func__, gid, name);
|
|
|
|
assert_se(t = gid_to_name(gid));
|
|
if (!synthesize_nobody() && streq(name, NOBODY_GROUP_NAME)) {
|
|
log_info("(skipping detailed tests because nobody is not synthesized)");
|
|
return;
|
|
}
|
|
assert_se(streq_ptr(t, name));
|
|
}
|
|
|
|
static void test_parse_uid(void) {
|
|
int r;
|
|
uid_t uid;
|
|
|
|
log_info("/* %s */", __func__);
|
|
|
|
r = parse_uid("100", &uid);
|
|
assert_se(r == 0);
|
|
assert_se(uid == 100);
|
|
|
|
r = parse_uid("65535", &uid);
|
|
assert_se(r == -ENXIO);
|
|
|
|
r = parse_uid("asdsdas", &uid);
|
|
assert_se(r == -EINVAL);
|
|
}
|
|
|
|
static void test_uid_ptr(void) {
|
|
log_info("/* %s */", __func__);
|
|
|
|
assert_se(UID_TO_PTR(0) != NULL);
|
|
assert_se(UID_TO_PTR(1000) != NULL);
|
|
|
|
assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
|
|
assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
|
|
}
|
|
|
|
static void test_valid_user_group_name_relaxed(void) {
|
|
log_info("/* %s */", __func__);
|
|
|
|
assert_se(!valid_user_group_name(NULL, VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("", VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("1", VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("65535", VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("-1", VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("foo\nbar", VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_RELAX|VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name(".aaa:bbb", VALID_USER_RELAX|VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name(".", VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("..", VALID_USER_RELAX));
|
|
|
|
assert_se(valid_user_group_name("root", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("lennart", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("LENNART", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("_kkk", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("kkk-", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("kk-k", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("eff.eff", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("eff.", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("-kkk", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("rööt", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name(".eff", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name(".1", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name(".65535", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name(".-1", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name(".-kkk", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name(".rööt", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("...", VALID_USER_RELAX));
|
|
|
|
assert_se(valid_user_group_name("some5", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("5some", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("INNER5NUMBER", VALID_USER_RELAX));
|
|
|
|
assert_se(valid_user_group_name("piff.paff@ad.domain.example", VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("Dāvis", VALID_USER_RELAX));
|
|
}
|
|
|
|
static void test_valid_user_group_name(void) {
|
|
log_info("/* %s */", __func__);
|
|
|
|
assert_se(!valid_user_group_name(NULL, 0));
|
|
assert_se(!valid_user_group_name("", 0));
|
|
assert_se(!valid_user_group_name("1", 0));
|
|
assert_se(!valid_user_group_name("65535", 0));
|
|
assert_se(!valid_user_group_name("-1", 0));
|
|
assert_se(!valid_user_group_name("-kkk", 0));
|
|
assert_se(!valid_user_group_name("rööt", 0));
|
|
assert_se(!valid_user_group_name(".", 0));
|
|
assert_se(!valid_user_group_name(".eff", 0));
|
|
assert_se(!valid_user_group_name("foo\nbar", 0));
|
|
assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", 0));
|
|
assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name(".", 0));
|
|
assert_se(!valid_user_group_name("..", 0));
|
|
assert_se(!valid_user_group_name("...", 0));
|
|
assert_se(!valid_user_group_name(".1", 0));
|
|
assert_se(!valid_user_group_name(".65535", 0));
|
|
assert_se(!valid_user_group_name(".-1", 0));
|
|
assert_se(!valid_user_group_name(".-kkk", 0));
|
|
assert_se(!valid_user_group_name(".rööt", 0));
|
|
assert_se(!valid_user_group_name(".aaa:bbb", VALID_USER_ALLOW_NUMERIC));
|
|
|
|
assert_se(valid_user_group_name("root", 0));
|
|
assert_se(valid_user_group_name("lennart", 0));
|
|
assert_se(valid_user_group_name("LENNART", 0));
|
|
assert_se(valid_user_group_name("_kkk", 0));
|
|
assert_se(valid_user_group_name("kkk-", 0));
|
|
assert_se(valid_user_group_name("kk-k", 0));
|
|
assert_se(!valid_user_group_name("eff.eff", 0));
|
|
assert_se(!valid_user_group_name("eff.", 0));
|
|
|
|
assert_se(valid_user_group_name("some5", 0));
|
|
assert_se(!valid_user_group_name("5some", 0));
|
|
assert_se(valid_user_group_name("INNER5NUMBER", 0));
|
|
|
|
assert_se(!valid_user_group_name("piff.paff@ad.domain.example", 0));
|
|
assert_se(!valid_user_group_name("Dāvis", 0));
|
|
}
|
|
|
|
static void test_valid_user_group_name_or_numeric_relaxed(void) {
|
|
log_info("/* %s */", __func__);
|
|
|
|
assert_se(!valid_user_group_name(NULL, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("0", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("1", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("65534", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("65535", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("65536", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("-1", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("foo\nbar", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name(".", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(!valid_user_group_name("..", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
|
|
assert_se(valid_user_group_name("root", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("lennart", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("LENNART", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("_kkk", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("kkk-", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("kk-k", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("-kkk", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("rööt", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name(".eff", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("eff.eff", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("eff.", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("...", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
|
|
assert_se(valid_user_group_name("some5", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("5some", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("INNER5NUMBER", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
|
|
assert_se(valid_user_group_name("piff.paff@ad.domain.example", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
assert_se(valid_user_group_name("Dāvis", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
|
}
|
|
|
|
static void test_valid_user_group_name_or_numeric(void) {
|
|
log_info("/* %s */", __func__);
|
|
|
|
assert_se(!valid_user_group_name(NULL, VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(valid_user_group_name("0", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(valid_user_group_name("1", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(valid_user_group_name("65534", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("65535", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(valid_user_group_name("65536", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("-1", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("-kkk", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("rööt", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name(".", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("..", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("...", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name(".eff", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("eff.eff", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("eff.", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("foo\nbar", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_ALLOW_NUMERIC));
|
|
|
|
assert_se(valid_user_group_name("root", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(valid_user_group_name("lennart", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(valid_user_group_name("LENNART", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(valid_user_group_name("_kkk", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(valid_user_group_name("kkk-", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(valid_user_group_name("kk-k", VALID_USER_ALLOW_NUMERIC));
|
|
|
|
assert_se(valid_user_group_name("some5", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("5some", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(valid_user_group_name("INNER5NUMBER", VALID_USER_ALLOW_NUMERIC));
|
|
|
|
assert_se(!valid_user_group_name("piff.paff@ad.domain.example", VALID_USER_ALLOW_NUMERIC));
|
|
assert_se(!valid_user_group_name("Dāvis", VALID_USER_ALLOW_NUMERIC));
|
|
}
|
|
|
|
static void test_valid_gecos(void) {
|
|
log_info("/* %s */", __func__);
|
|
|
|
assert_se(!valid_gecos(NULL));
|
|
assert_se(valid_gecos(""));
|
|
assert_se(valid_gecos("test"));
|
|
assert_se(valid_gecos("Ümläüt"));
|
|
assert_se(!valid_gecos("In\nvalid"));
|
|
assert_se(!valid_gecos("In:valid"));
|
|
}
|
|
|
|
static void test_valid_home(void) {
|
|
log_info("/* %s */", __func__);
|
|
|
|
assert_se(!valid_home(NULL));
|
|
assert_se(!valid_home(""));
|
|
assert_se(!valid_home("."));
|
|
assert_se(!valid_home("/home/.."));
|
|
assert_se(!valid_home("/home/../"));
|
|
assert_se(!valid_home("/home\n/foo"));
|
|
assert_se(!valid_home("./piep"));
|
|
assert_se(!valid_home("piep"));
|
|
assert_se(!valid_home("/home/user:lennart"));
|
|
|
|
assert_se(valid_home("/"));
|
|
assert_se(valid_home("/home"));
|
|
assert_se(valid_home("/home/foo"));
|
|
}
|
|
|
|
static void test_get_user_creds_one(const char *id, const char *name, uid_t uid, gid_t gid, const char *home, const char *shell) {
|
|
const char *rhome = NULL;
|
|
const char *rshell = NULL;
|
|
uid_t ruid = UID_INVALID;
|
|
gid_t rgid = GID_INVALID;
|
|
int r;
|
|
|
|
log_info("/* %s(\"%s\", \"%s\", "UID_FMT", "GID_FMT", \"%s\", \"%s\") */",
|
|
__func__, id, name, uid, gid, home, shell);
|
|
|
|
r = get_user_creds(&id, &ruid, &rgid, &rhome, &rshell, 0);
|
|
log_info_errno(r, "got \"%s\", "UID_FMT", "GID_FMT", \"%s\", \"%s\": %m",
|
|
id, ruid, rgid, strnull(rhome), strnull(rshell));
|
|
if (!synthesize_nobody() && streq(name, NOBODY_USER_NAME)) {
|
|
log_info("(skipping detailed tests because nobody is not synthesized)");
|
|
return;
|
|
}
|
|
assert_se(r == 0);
|
|
assert_se(streq_ptr(id, name));
|
|
assert_se(ruid == uid);
|
|
assert_se(rgid == gid);
|
|
assert_se(path_equal(rhome, home));
|
|
assert_se(path_equal(rshell, shell));
|
|
}
|
|
|
|
static void test_get_group_creds_one(const char *id, const char *name, gid_t gid) {
|
|
gid_t rgid = GID_INVALID;
|
|
int r;
|
|
|
|
log_info("/* %s(\"%s\", \"%s\", "GID_FMT") */", __func__, id, name, gid);
|
|
|
|
r = get_group_creds(&id, &rgid, 0);
|
|
log_info_errno(r, "got \"%s\", "GID_FMT": %m", id, rgid);
|
|
if (!synthesize_nobody() && streq(name, NOBODY_GROUP_NAME)) {
|
|
log_info("(skipping detailed tests because nobody is not synthesized)");
|
|
return;
|
|
}
|
|
assert_se(r == 0);
|
|
assert_se(streq_ptr(id, name));
|
|
assert_se(rgid == gid);
|
|
}
|
|
|
|
static void test_make_salt(void) {
|
|
log_info("/* %s */", __func__);
|
|
|
|
_cleanup_free_ char *s, *t;
|
|
|
|
assert_se(make_salt(&s) == 0);
|
|
log_info("got %s", s);
|
|
|
|
assert_se(make_salt(&t) == 0);
|
|
log_info("got %s", t);
|
|
|
|
assert(!streq(s, t));
|
|
}
|
|
|
|
static void test_in_gid(void) {
|
|
assert(in_gid(getgid()) >= 0);
|
|
assert(in_gid(getegid()) >= 0); assert(in_gid(TTY_GID) == 0); /* The TTY gid is for owning ttys, it would be really really weird if we were in it. */
|
|
}
|
|
|
|
static void test_gid_lists_ops(void) {
|
|
static const gid_t l1[] = { 5, 10, 15, 20, 25};
|
|
static const gid_t l2[] = { 1, 2, 3, 15, 20, 25};
|
|
static const gid_t l3[] = { 5, 10, 15, 20, 25, 26, 27};
|
|
static const gid_t l4[] = { 25, 26, 20, 15, 5, 27, 10};
|
|
|
|
static const gid_t result1[] = {1, 2, 3, 5, 10, 15, 20, 25, 26, 27};
|
|
static const gid_t result2[] = {5, 10, 15, 20, 25, 26, 27};
|
|
|
|
_cleanup_free_ gid_t *gids = NULL;
|
|
_cleanup_free_ gid_t *res1 = NULL;
|
|
_cleanup_free_ gid_t *res2 = NULL;
|
|
_cleanup_free_ gid_t *res3 = NULL;
|
|
_cleanup_free_ gid_t *res4 = NULL;
|
|
int nresult;
|
|
|
|
nresult = merge_gid_lists(l2, ELEMENTSOF(l2), l3, ELEMENTSOF(l3), &res1);
|
|
assert_se(nresult >= 0);
|
|
assert_se(memcmp_nn(res1, nresult, result1, ELEMENTSOF(result1)) == 0);
|
|
|
|
nresult = merge_gid_lists(NULL, 0, l2, ELEMENTSOF(l2), &res2);
|
|
assert_se(nresult >= 0);
|
|
assert_se(memcmp_nn(res2, nresult, l2, ELEMENTSOF(l2)) == 0);
|
|
|
|
nresult = merge_gid_lists(l1, ELEMENTSOF(l1), l1, ELEMENTSOF(l1), &res3);
|
|
assert_se(nresult >= 0);
|
|
assert_se(memcmp_nn(l1, ELEMENTSOF(l1), res3, nresult) == 0);
|
|
|
|
nresult = merge_gid_lists(l1, ELEMENTSOF(l1), l4, ELEMENTSOF(l4), &res4);
|
|
assert_se(nresult >= 0);
|
|
assert_se(memcmp_nn(result2, ELEMENTSOF(result2), res4, nresult) == 0);
|
|
|
|
nresult = getgroups_alloc(&gids);
|
|
assert_se(nresult >= 0 || nresult == -EINVAL || nresult == -ENOMEM);
|
|
assert_se(gids);
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
test_uid_to_name_one(0, "root");
|
|
test_uid_to_name_one(UID_NOBODY, NOBODY_USER_NAME);
|
|
test_uid_to_name_one(0xFFFF, "65535");
|
|
test_uid_to_name_one(0xFFFFFFFF, "4294967295");
|
|
|
|
test_gid_to_name_one(0, "root");
|
|
test_gid_to_name_one(GID_NOBODY, NOBODY_GROUP_NAME);
|
|
test_gid_to_name_one(TTY_GID, "tty");
|
|
test_gid_to_name_one(0xFFFF, "65535");
|
|
test_gid_to_name_one(0xFFFFFFFF, "4294967295");
|
|
|
|
test_get_user_creds_one("root", "root", 0, 0, "/root", "/bin/sh");
|
|
test_get_user_creds_one("0", "root", 0, 0, "/root", "/bin/sh");
|
|
test_get_user_creds_one(NOBODY_USER_NAME, NOBODY_USER_NAME, UID_NOBODY, GID_NOBODY, "/", NOLOGIN);
|
|
test_get_user_creds_one("65534", NOBODY_USER_NAME, UID_NOBODY, GID_NOBODY, "/", NOLOGIN);
|
|
|
|
test_get_group_creds_one("root", "root", 0);
|
|
test_get_group_creds_one("0", "root", 0);
|
|
test_get_group_creds_one(NOBODY_GROUP_NAME, NOBODY_GROUP_NAME, GID_NOBODY);
|
|
test_get_group_creds_one("65534", NOBODY_GROUP_NAME, GID_NOBODY);
|
|
|
|
test_parse_uid();
|
|
test_uid_ptr();
|
|
|
|
test_valid_user_group_name_relaxed();
|
|
test_valid_user_group_name();
|
|
test_valid_user_group_name_or_numeric_relaxed();
|
|
test_valid_user_group_name_or_numeric();
|
|
test_valid_gecos();
|
|
test_valid_home();
|
|
|
|
test_make_salt();
|
|
|
|
test_in_gid();
|
|
test_gid_lists_ops();
|
|
|
|
return 0;
|
|
}
|