diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-05-01 11:43:38 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-01 12:40:12 +0200 |
commit | 302f9798eebc3b0b80ea08aa3506959b249e4155 (patch) | |
tree | 46f2cae69da5485b70cf52c280333f848cadcf19 /Userland/Libraries/LibCore | |
parent | ce77caf479a8f7003d3789737a888cec628efae3 (diff) | |
download | serenity-302f9798eebc3b0b80ea08aa3506959b249e4155.zip |
LibC: Implement support for getspnam() and friends
Diffstat (limited to 'Userland/Libraries/LibCore')
-rw-r--r-- | Userland/Libraries/LibCore/Account.cpp | 97 | ||||
-rw-r--r-- | Userland/Libraries/LibCore/Account.h | 12 |
2 files changed, 53 insertions, 56 deletions
diff --git a/Userland/Libraries/LibCore/Account.cpp b/Userland/Libraries/LibCore/Account.cpp index 869958c604..c86fb1d6f0 100644 --- a/Userland/Libraries/LibCore/Account.cpp +++ b/Userland/Libraries/LibCore/Account.cpp @@ -13,6 +13,7 @@ #include <errno.h> #include <grp.h> #include <pwd.h> +#include <shadow.h> #include <stdio.h> #include <string.h> #include <sys/stat.h> @@ -47,39 +48,52 @@ static Vector<gid_t> get_gids(const StringView& username) return extra_gids; } -Result<Account, String> Account::from_passwd(const passwd& pwd) +Result<Account, String> Account::from_passwd(const passwd& pwd, const spwd& spwd) { - Account account(pwd, get_gids(pwd.pw_name)); + Account account(pwd, spwd, get_gids(pwd.pw_name)); endpwent(); + endspent(); return account; } Result<Account, String> Account::from_name(const char* username) { - struct passwd* pwd = nullptr; errno = 0; - pwd = getpwnam(username); + auto* pwd = getpwnam(username); if (!pwd) { if (errno == 0) return String("No such user"); return String(strerror(errno)); } - return from_passwd(*pwd); + auto* spwd = getspnam(username); + if (!spwd) { + if (errno == 0) + return String("No such user"); + + return String(strerror(errno)); + } + return from_passwd(*pwd, *spwd); } Result<Account, String> Account::from_uid(uid_t uid) { - struct passwd* pwd = nullptr; errno = 0; - pwd = getpwuid(uid); + auto* pwd = getpwuid(uid); if (!pwd) { if (errno == 0) return String("No such user"); return String(strerror(errno)); } - return from_passwd(*pwd); + auto* spwd = getspnam(pwd->pw_name); + if (!spwd) { + if (errno == 0) + return String("No such user"); + + return String(strerror(errno)); + } + return from_passwd(*pwd, *spwd); } bool Account::authenticate(const char* password) const @@ -133,8 +147,9 @@ void Account::delete_password() m_password_hash = ""; } -Account::Account(const passwd& pwd, Vector<gid_t> extra_gids) +Account::Account(const passwd& pwd, const spwd& spwd, Vector<gid_t> extra_gids) : m_username(pwd.pw_name) + , m_password_hash(spwd.sp_pwdp) , m_uid(pwd.pw_uid) , m_gid(pwd.pw_gid) , m_gecos(pwd.pw_gecos) @@ -142,7 +157,6 @@ Account::Account(const passwd& pwd, Vector<gid_t> extra_gids) , m_shell(pwd.pw_shell) , m_extra_gids(extra_gids) { - load_shadow_file(); } String Account::generate_passwd_file() const @@ -179,50 +193,39 @@ String Account::generate_passwd_file() const return builder.to_string(); } -void Account::load_shadow_file() +String Account::generate_shadow_file() const { - auto file_or_error = Core::File::open("/etc/shadow", Core::File::ReadOnly); - VERIFY(!file_or_error.is_error()); - auto shadow_file = file_or_error.release_value(); - VERIFY(shadow_file->is_open()); - - Vector<ShadowEntry> entries; - - for (;;) { - auto line = shadow_file->read_line(); - if (line.is_null()) - break; - auto parts = line.split(':', true); - if (parts.size() != 2) { - dbgln("Malformed shadow entry, ignoring."); - continue; - } - const auto& username = parts[0]; - const auto& password_hash = parts[1]; - entries.append({ username, password_hash }); + StringBuilder builder; - if (username == m_username) { - m_password_hash = password_hash; - } - } + setspent(); - m_shadow_entries = move(entries); -} + struct spwd* p; + errno = 0; + while ((p = getspent())) { + if (p->sp_namp == m_username) { + builder.appendff("{}:{}:{}:{}:{}:{}:{}:{}:{}\n", + m_username, m_password_hash, + p->sp_lstchg, p->sp_min, + p->sp_max, p->sp_warn, + p->sp_inact, p->sp_expire, + p->sp_flag); -String Account::generate_shadow_file() const -{ - StringBuilder builder; - bool updated_entry_in_place = false; - for (auto& entry : m_shadow_entries) { - if (entry.username == m_username) { - updated_entry_in_place = true; - builder.appendff("{}:{}\n", m_username, m_password_hash); } else { - builder.appendff("{}:{}\n", entry.username, entry.password_hash); + builder.appendff("{}:{}:{}:{}:{}:{}:{}:{}:{}\n", + p->sp_namp, p->sp_pwdp, + p->sp_lstchg, p->sp_min, + p->sp_max, p->sp_warn, + p->sp_inact, p->sp_expire, + p->sp_flag); } } - if (!updated_entry_in_place) - builder.appendff("{}:{}\n", m_username, m_password_hash); + endspent(); + + if (errno) { + dbgln("errno was non-zero after generating new passwd file."); + return {}; + } + return builder.to_string(); } diff --git a/Userland/Libraries/LibCore/Account.h b/Userland/Libraries/LibCore/Account.h index b9231f10e9..c97dae424b 100644 --- a/Userland/Libraries/LibCore/Account.h +++ b/Userland/Libraries/LibCore/Account.h @@ -11,6 +11,7 @@ #include <AK/Types.h> #include <AK/Vector.h> #include <pwd.h> +#include <shadow.h> #include <sys/types.h> namespace Core { @@ -46,10 +47,9 @@ public: bool sync(); private: - static Result<Account, String> from_passwd(const passwd&); + static Result<Account, String> from_passwd(const passwd&, const spwd&); - Account(const passwd& pwd, Vector<gid_t> extra_gids); - void load_shadow_file(); + Account(const passwd& pwd, const spwd& spwd, Vector<gid_t> extra_gids); String generate_passwd_file() const; String generate_shadow_file() const; @@ -63,12 +63,6 @@ private: String m_home_directory; String m_shell; Vector<gid_t> m_extra_gids; - - struct ShadowEntry { - String username; - String password_hash; - }; - Vector<ShadowEntry> m_shadow_entries; }; } |