diff --git a/src/shared/group-record-nss.c b/src/shared/group-record-nss.c index 5c4fae865ae..b018a46e18e 100644 --- a/src/shared/group-record-nss.c +++ b/src/shared/group-record-nss.c @@ -37,7 +37,7 @@ int nss_group_to_group_record( g->gid = grp->gr_gid; if (sgrp) { - if (hashed_password_valid(sgrp->sg_passwd)) { + if (looks_like_hashed_password(sgrp->sg_passwd)) { g->hashed_password = strv_new(sgrp->sg_passwd); if (!g->hashed_password) return -ENOMEM; diff --git a/src/shared/libcrypt-util.c b/src/shared/libcrypt-util.c index f41685ae450..bf6605508af 100644 --- a/src/shared/libcrypt-util.c +++ b/src/shared/libcrypt-util.c @@ -74,13 +74,18 @@ int make_salt(char **ret) { #endif } -bool hashed_password_valid(const char *s) { - - /* Returns true if the specified string is a 'valid' hashed UNIX password, i.e. if starts with '$' or - * with '!$' (the latter being a valid, yet locked password). */ - - if (isempty(s)) +bool looks_like_hashed_password(const char *s) { + /* Returns false if the specified string is certainly not a hashed UNIX password. crypt(5) lists + * various hashing methods. We only reject (return false) strings which are documented to have + * different meanings. + * + * In particular, we allow locked passwords, i.e. strings starting with "!", including just "!", + * i.e. the locked empty password. See also fc58c0c7bf7e4f525b916e3e5be0de2307fef04e. + */ + if (!s) return false; - return STARTSWITH_SET(s, "$", "!$"); + s += strspn(s, "!"); /* Skip (possibly duplicated) locking prefix */ + + return !STR_IN_SET(s, "x", "*"); } diff --git a/src/shared/libcrypt-util.h b/src/shared/libcrypt-util.h index 93f0e13ffbe..8a860ceb0d8 100644 --- a/src/shared/libcrypt-util.h +++ b/src/shared/libcrypt-util.h @@ -19,4 +19,4 @@ int make_salt(char **ret); -bool hashed_password_valid(const char *s); +bool looks_like_hashed_password(const char *s); diff --git a/src/shared/user-record-nss.c b/src/shared/user-record-nss.c index b27a12c55d0..b4c35b8a532 100644 --- a/src/shared/user-record-nss.c +++ b/src/shared/user-record-nss.c @@ -66,7 +66,7 @@ int nss_passwd_to_user_record( hr->uid = pwd->pw_uid; hr->gid = pwd->pw_gid; - if (spwd && hashed_password_valid(spwd->sp_pwdp)) { + if (spwd && looks_like_hashed_password(spwd->sp_pwdp)) { strv_free_erase(hr->hashed_password); hr->hashed_password = strv_new(spwd->sp_pwdp); if (!hr->hashed_password)