1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 00:57:45 +00:00

LibCore+passwd+usermod: Make Core::Account::sync() return ErrorOr<void>

This commit is contained in:
Andreas Kling 2021-12-16 21:41:57 +01:00
parent ead9c36c92
commit b38f8902d2
4 changed files with 25 additions and 61 deletions

View file

@ -8,6 +8,7 @@
#include <AK/Random.h> #include <AK/Random.h>
#include <AK/ScopeGuard.h> #include <AK/ScopeGuard.h>
#include <LibCore/Account.h> #include <LibCore/Account.h>
#include <LibCore/System.h>
#include <errno.h> #include <errno.h>
#include <grp.h> #include <grp.h>
#include <pwd.h> #include <pwd.h>
@ -218,7 +219,7 @@ Account::Account(const passwd& pwd, const spwd& spwd, Vector<gid_t> extra_gids)
{ {
} }
String Account::generate_passwd_file() const ErrorOr<String> Account::generate_passwd_file() const
{ {
StringBuilder builder; StringBuilder builder;
@ -244,16 +245,14 @@ String Account::generate_passwd_file() const
} }
endpwent(); endpwent();
if (errno) { if (errno)
dbgln("errno was non-zero after generating new passwd file."); return Error::from_errno(errno);
return {};
}
return builder.to_string(); return builder.to_string();
} }
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
String Account::generate_shadow_file() const ErrorOr<String> Account::generate_shadow_file() const
{ {
StringBuilder builder; StringBuilder builder;
@ -287,22 +286,18 @@ String Account::generate_shadow_file() const
} }
endspent(); endspent();
if (errno) { if (errno)
dbgln("errno was non-zero after generating new passwd file."); return Error::from_errno(errno);
return {};
}
return builder.to_string(); return builder.to_string();
} }
#endif #endif
bool Account::sync() ErrorOr<void> Account::sync()
{ {
auto new_passwd_file_content = generate_passwd_file(); auto new_passwd_file_content = TRY(generate_passwd_file());
VERIFY(!new_passwd_file_content.is_null());
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
auto new_shadow_file_content = generate_shadow_file(); auto new_shadow_file_content = TRY(generate_shadow_file());
VERIFY(!new_shadow_file_content.is_null());
#endif #endif
char new_passwd_name[] = "/etc/passwd.XXXXXX"; char new_passwd_name[] = "/etc/passwd.XXXXXX";
@ -311,56 +306,30 @@ bool Account::sync()
#endif #endif
{ {
auto new_passwd_fd = mkstemp(new_passwd_name); auto new_passwd_fd = TRY(Core::System::mkstemp(new_passwd_name));
if (new_passwd_fd < 0) {
perror("mkstemp");
VERIFY_NOT_REACHED();
}
ScopeGuard new_passwd_fd_guard = [new_passwd_fd] { close(new_passwd_fd); }; ScopeGuard new_passwd_fd_guard = [new_passwd_fd] { close(new_passwd_fd); };
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
auto new_shadow_fd = mkstemp(new_shadow_name); auto new_shadow_fd = TRY(Core::System::mkstemp(new_shadow_name));
if (new_shadow_fd < 0) {
perror("mkstemp");
VERIFY_NOT_REACHED();
}
ScopeGuard new_shadow_fd_guard = [new_shadow_fd] { close(new_shadow_fd); }; ScopeGuard new_shadow_fd_guard = [new_shadow_fd] { close(new_shadow_fd); };
#endif #endif
if (fchmod(new_passwd_fd, 0644) < 0) { TRY(Core::System::fchmod(new_passwd_fd, 0644));
perror("fchmod");
VERIFY_NOT_REACHED();
}
auto nwritten = write(new_passwd_fd, new_passwd_file_content.characters(), new_passwd_file_content.length()); auto nwritten = TRY(Core::System::write(new_passwd_fd, new_passwd_file_content.bytes()));
if (nwritten < 0) {
perror("write");
VERIFY_NOT_REACHED();
}
VERIFY(static_cast<size_t>(nwritten) == new_passwd_file_content.length()); VERIFY(static_cast<size_t>(nwritten) == new_passwd_file_content.length());
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
nwritten = write(new_shadow_fd, new_shadow_file_content.characters(), new_shadow_file_content.length()); nwritten = TRY(Core::System::write(new_shadow_fd, new_shadow_file_content.bytes()));
if (nwritten < 0) {
perror("write");
VERIFY_NOT_REACHED();
}
VERIFY(static_cast<size_t>(nwritten) == new_shadow_file_content.length()); VERIFY(static_cast<size_t>(nwritten) == new_shadow_file_content.length());
#endif #endif
} }
if (rename(new_passwd_name, "/etc/passwd") < 0) { TRY(Core::System::rename(new_passwd_name, "/etc/passwd"));
perror("Failed to install new /etc/passwd");
return false;
}
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
if (rename(new_shadow_name, "/etc/shadow") < 0) { TRY(Core::System::rename(new_shadow_name, "/etc/shadow"));
perror("Failed to install new /etc/shadow");
return false;
}
#endif #endif
return true; return {};
// FIXME: Sync extra groups. // FIXME: Sync extra groups.
} }

View file

@ -64,16 +64,16 @@ public:
const String& shell() const { return m_shell; } const String& shell() const { return m_shell; }
const Vector<gid_t>& extra_gids() const { return m_extra_gids; } const Vector<gid_t>& extra_gids() const { return m_extra_gids; }
bool sync(); ErrorOr<void> sync();
private: private:
static ErrorOr<Account> from_passwd(passwd const&, spwd const&); static ErrorOr<Account> from_passwd(passwd const&, spwd const&);
Account(const passwd& pwd, const spwd& spwd, Vector<gid_t> extra_gids); Account(const passwd& pwd, const spwd& spwd, Vector<gid_t> extra_gids);
String generate_passwd_file() const; ErrorOr<String> generate_passwd_file() const;
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
String generate_shadow_file() const; ErrorOr<String> generate_shadow_file() const;
#endif #endif
String m_username; String m_username;

View file

@ -92,11 +92,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio wpath rpath cpath fattr")); TRY(Core::System::pledge("stdio wpath rpath cpath fattr"));
if (!target_account.sync()) { TRY(target_account.sync());
perror("Core::Account::Sync");
} else {
outln("Password for user {} successfully updated.", target_account.username());
}
outln("Password for user {} successfully updated.", target_account.username());
return 0; return 0;
} }

View file

@ -134,10 +134,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
} }
TRY(Core::System::pledge("stdio wpath rpath cpath fattr")); TRY(Core::System::pledge("stdio wpath rpath cpath fattr"));
if (!target_account.sync()) {
perror("Core::Account::Sync"); TRY(target_account.sync());
return 1;
}
return 0; return 0;
} }