user-util: tighten shell validation a tiny bit

This commit is contained in:
Lennart Poettering
2024-10-24 22:28:17 +02:00
parent 4e69da071d
commit 4167e9e210
3 changed files with 30 additions and 9 deletions
+11
View File
@@ -884,6 +884,17 @@ bool valid_home(const char *p) {
return true;
}
bool valid_shell(const char *p) {
/* We have the same requirements, so just piggy-back on the home check.
*
* Let's ignore /etc/shells because this is only applicable to real and not system users. It is also
* incompatible with the idea of empty /etc/. */
if (!valid_home(p))
return false;
return !endswith(p, "/"); /* one additional restriction: shells may not be dirs */
}
int maybe_setgroups(size_t size, const gid_t *list) {
int r;
+1 -9
View File
@@ -108,15 +108,7 @@ bool valid_user_group_name(const char *u, ValidUserFlags flags);
bool valid_gecos(const char *d);
char* mangle_gecos(const char *d);
bool valid_home(const char *p);
static inline bool valid_shell(const char *p) {
/* We have the same requirements, so just piggy-back on the home check.
*
* Let's ignore /etc/shells because this is only applicable to real and
* not system users. It is also incompatible with the idea of empty /etc.
*/
return valid_home(p);
}
bool valid_shell(const char *p);
int maybe_setgroups(size_t size, const gid_t *list);
+18
View File
@@ -318,6 +318,24 @@ TEST(valid_home) {
assert_se(valid_home("/"));
assert_se(valid_home("/home"));
assert_se(valid_home("/home/foo"));
assert_se(valid_home("/home/foo/"));
}
TEST(valid_shell) {
assert_se(!valid_shell(NULL));
assert_se(!valid_shell(""));
assert_se(!valid_shell("."));
assert_se(!valid_shell("/shell/.."));
assert_se(!valid_shell("/shell/../"));
assert_se(!valid_shell("/shell\n/foo"));
assert_se(!valid_shell("./piep"));
assert_se(!valid_shell("piep"));
assert_se(!valid_shell("/shell/user:lennart"));
assert_se(!valid_shell("/"));
assert_se(!valid_shell("/bin/sh/"));
assert_se(valid_shell("/shell"));
assert_se(valid_shell("/shell/foo"));
assert_se(valid_shell("/bin/sh"));
}
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) {