summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-07-14 12:23:39 +0200
committerSven Eden <yamakuzure@gmx.net>2017-07-05 08:50:49 +0200
commit599f015c68718f04ee1946fc263aad8aaa614072 (patch)
tree9c2770ffc98a12ff95ce6117347622c83663eefe /src
parent638dd5096b5549b7838c821784041af86b87a1f3 (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')
-rw-r--r--src/basic/user-util.c91
-rw-r--r--src/basic/user-util.h5
2 files changed, 96 insertions, 0 deletions
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
index fbe9f2a96..2ba5c8575 100644
--- a/src/basic/user-util.c
+++ b/src/basic/user-util.c
@@ -485,3 +485,94 @@ int take_etc_passwd_lock(const char *root) {
return fd;
}
#endif // 0
+
+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;
+}
diff --git a/src/basic/user-util.h b/src/basic/user-util.h
index 5d1d0abe4..1b5b4f454 100644
--- a/src/basic/user-util.h
+++ b/src/basic/user-util.h
@@ -74,3 +74,8 @@ int take_etc_passwd_lock(const char *root);
static inline bool userns_supported(void) {
return access("/proc/self/uid_map", F_OK) >= 0;
}
+
+bool valid_user_group_name(const char *u);
+bool valid_user_group_name_or_id(const char *u);
+bool valid_gecos(const char *d);
+bool valid_home(const char *p);