user-util: add mangle_gecos() call for turning strings into fields suitable as GECOS fields
This commit is contained in:
@@ -863,6 +863,37 @@ bool valid_gecos(const char *d) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char *mangle_gecos(const char *d) {
|
||||
char *mangled;
|
||||
|
||||
/* Makes sure the provided string becomes valid as a GEGOS field, by dropping bad chars. glibc's
|
||||
* putwent() only changes \n and : to spaces. We do more: replace all CC too, and remove invalid
|
||||
* UTF-8 */
|
||||
|
||||
mangled = strdup(d);
|
||||
if (!mangled)
|
||||
return NULL;
|
||||
|
||||
for (char *i = mangled; *i; i++) {
|
||||
int len;
|
||||
|
||||
if ((uint8_t) *i < (uint8_t) ' ' || *i == ':') {
|
||||
*i = ' ';
|
||||
continue;
|
||||
}
|
||||
|
||||
len = utf8_encoded_valid_unichar(i, (size_t) -1);
|
||||
if (len < 0) {
|
||||
*i = ' ';
|
||||
continue;
|
||||
}
|
||||
|
||||
i += len - 1;
|
||||
}
|
||||
|
||||
return mangled;
|
||||
}
|
||||
|
||||
bool valid_home(const char *p) {
|
||||
/* Note that this function is also called by valid_shell(), any
|
||||
* changes must account for that. */
|
||||
|
||||
@@ -105,6 +105,7 @@ typedef enum ValidUserFlags {
|
||||
|
||||
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) {
|
||||
|
||||
@@ -452,6 +452,25 @@ static void test_parse_uid_range(void) {
|
||||
assert_se(parse_uid_range(" 01", &a, &b) == -EINVAL && a == 4 && b == 5);
|
||||
}
|
||||
|
||||
static void test_mangle_gecos_one(const char *input, const char *expected) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
||||
assert_se(p = mangle_gecos(input));
|
||||
assert_se(streq(p, expected));
|
||||
assert_se(valid_gecos(p));
|
||||
}
|
||||
|
||||
static void test_mangle_gecos(void) {
|
||||
test_mangle_gecos_one("", "");
|
||||
test_mangle_gecos_one("root", "root");
|
||||
test_mangle_gecos_one("wuff\nwuff", "wuff wuff");
|
||||
test_mangle_gecos_one("wuff:wuff", "wuff wuff");
|
||||
test_mangle_gecos_one("wuff\r\n:wuff", "wuff wuff");
|
||||
test_mangle_gecos_one("\n--wüff-wäff-wöff::", " --wüff-wäff-wöff ");
|
||||
test_mangle_gecos_one("\xc3\x28", " (");
|
||||
test_mangle_gecos_one("\xe2\x28\xa1", " ( ");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_uid_to_name_one(0, "root");
|
||||
test_uid_to_name_one(UID_NOBODY, NOBODY_USER_NAME);
|
||||
@@ -482,6 +501,7 @@ int main(int argc, char *argv[]) {
|
||||
test_valid_user_group_name_or_numeric_relaxed();
|
||||
test_valid_user_group_name_or_numeric();
|
||||
test_valid_gecos();
|
||||
test_mangle_gecos();
|
||||
test_valid_home();
|
||||
|
||||
test_make_salt();
|
||||
|
||||
Reference in New Issue
Block a user