diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-07-14 12:23:39 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-07-22 15:53:45 +0200 |
commit | e4631b48e17e63a3859456df639482063a0276fd (patch) | |
tree | e8dcdec9dbfda12093f4266ce495a27b65cfa580 /src/basic/user-util.c | |
parent | bf3dd08a81f7500973d8a4add8c73a0856ae5f7d (diff) |
sysusers: move various user credential validity checks to src/basic/
This way we can reuse them for validating User=/Group= settings in unit files
(to be added in a later commit).
Also, add some tests for them.
Diffstat (limited to 'src/basic/user-util.c')
-rw-r--r-- | src/basic/user-util.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/basic/user-util.c b/src/basic/user-util.c index e9d668ddfc..122d9a0c7c 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -29,6 +29,7 @@ #include <string.h> #include <sys/stat.h> #include <unistd.h> +#include <utmp.h> #include "missing.h" #include "alloc-util.h" @@ -39,6 +40,7 @@ #include "path-util.h" #include "string-util.h" #include "user-util.h" +#include "utf8.h" bool uid_is_valid(uid_t uid) { @@ -479,3 +481,94 @@ int take_etc_passwd_lock(const char *root) { return fd; } + +bool valid_user_group_name(const char *u) { + const char *i; + long sz; + + /* Checks if the specified name is a valid user/group name. */ + + if (isempty(u)) + return false; + + if (!(u[0] >= 'a' && u[0] <= 'z') && + !(u[0] >= 'A' && u[0] <= 'Z') && + u[0] != '_') + return false; + + for (i = u+1; *i; i++) { + if (!(*i >= 'a' && *i <= 'z') && + !(*i >= 'A' && *i <= 'Z') && + !(*i >= '0' && *i <= '9') && + *i != '_' && + *i != '-') + return false; + } + + sz = sysconf(_SC_LOGIN_NAME_MAX); + assert_se(sz > 0); + + if ((size_t) (i-u) > (size_t) sz) + return false; + + if ((size_t) (i-u) > UT_NAMESIZE - 1) + return false; + + return true; +} + +bool valid_user_group_name_or_id(const char *u) { + + /* Similar as above, but is also fine with numeric UID/GID specifications, as long as they are in the right + * range, and not the invalid user ids. */ + + if (isempty(u)) + return false; + + if (valid_user_group_name(u)) + return true; + + return parse_uid(u, NULL) >= 0; +} + +bool valid_gecos(const char *d) { + + if (!d) + return false; + + if (!utf8_is_valid(d)) + return false; + + if (string_has_cc(d, NULL)) + return false; + + /* Colons are used as field separators, and hence not OK */ + if (strchr(d, ':')) + return false; + + return true; +} + +bool valid_home(const char *p) { + + if (isempty(p)) + return false; + + if (!utf8_is_valid(p)) + return false; + + if (string_has_cc(p, NULL)) + return false; + + if (!path_is_absolute(p)) + return false; + + if (!path_is_safe(p)) + return false; + + /* Colons are used as field separators, and hence not OK */ + if (strchr(p, ':')) + return false; + + return true; +} |