diff options
author | Peter Elliott <pelliott@ualberta.ca> | 2020-09-04 12:01:48 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-09-21 20:18:05 +0200 |
commit | 7ba7b72736ecece784b87c51dae6405501071031 (patch) | |
tree | 3e9c89e65f289c3a1ec9424b93497cbf979a166f /Userland | |
parent | 4a834f969faf997fc40623d6daaf7b98f9453616 (diff) | |
download | serenity-7ba7b72736ecece784b87c51dae6405501071031.zip |
Userland: Convert passwd(1) to use Core::Account
this fixes the passwd issues discovered in #3296
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/passwd.cpp | 89 |
1 files changed, 27 insertions, 62 deletions
diff --git a/Userland/passwd.cpp b/Userland/passwd.cpp index a848caebee..61cd1e6094 100644 --- a/Userland/passwd.cpp +++ b/Userland/passwd.cpp @@ -24,53 +24,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <AK/Base64.h> -#include <AK/StringBuilder.h> #include <AK/Types.h> +#include <LibCore/Account.h> #include <LibCore/ArgsParser.h> #include <LibCore/File.h> #include <LibCore/GetPassword.h> -#include <pwd.h> #include <string.h> #include <unistd.h> -static String get_salt() -{ - char random_data[12]; - arc4random_buf(random_data, sizeof(random_data)); - - StringBuilder builder; - builder.append("$5$"); - builder.append(encode_base64(ReadonlyBytes(random_data, sizeof(random_data)))); - - return builder.build(); -} - -static void write_passwd_file(struct passwd* pwd) -{ - StringBuilder new_passwd_file; - - setpwent(); - - struct passwd* p; - while ((p = getpwent())) { - if (p->pw_uid == pwd->pw_uid) { - p = pwd; - } - - new_passwd_file.appendf("%s:%s:%u:%u:%s:%s:%s\n", - p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell); - } - endpwent(); - - auto file = Core::File::open("/etc/passwd", Core::IODevice::OpenMode::WriteOnly); - if (file.is_error()) { - fprintf(stderr, "Core::File::open: %s\n", file.error().characters()); - exit(1); - } - file.value()->write(new_passwd_file.build()); -} - int main(int argc, char** argv) { if (geteuid() != 0) { @@ -88,6 +49,11 @@ int main(int argc, char** argv) return 1; } + if (unveil("/etc/group", "rwc") < 0) { + perror("unveil"); + return 1; + } + unveil(nullptr, nullptr); bool del = false; @@ -103,32 +69,29 @@ int main(int argc, char** argv) args_parser.parse(argc, argv); - uid_t current_user = getuid(); + uid_t current_uid = getuid(); - struct passwd pwd; - if (username) { - pwd = *getpwnam(username); - if (current_user != 0 && current_user != pwd.pw_uid) { - fprintf(stderr, "You can't modify passwd for %s.\n", username); - return 1; - } - } else { - pwd = *getpwuid(current_user); + auto account_or_error = (username) ? Core::Account::from_name(username) : Core::Account::from_uid(current_uid); + + if (account_or_error.is_error()) { + fprintf(stderr, "Core::Account::%s: %s\n", (username) ? "from_name" : "from_uid", account_or_error.error().characters()); + return 1; + } + + // target_account is the account we are changing the password of. + auto target_account = account_or_error.value(); + + if (current_uid != 0 && current_uid != target_account.uid()) { + fprintf(stderr, "You can't modify passwd for %s\n", username); + return 1; } - String pw_string; if (del) { - pwd.pw_passwd = const_cast<char*>(""); + target_account.delete_password(); } else if (lock) { - StringBuilder builder; - builder.append('!'); - builder.append(pwd.pw_passwd); - pw_string = builder.build(); - pwd.pw_passwd = const_cast<char*>(pw_string.characters()); + target_account.set_password_enabled(false); } else if (unlock) { - if (pwd.pw_passwd[0] == '!') { - pwd.pw_passwd += 1; - } + target_account.set_password_enabled(true); } else { auto new_password = Core::get_password("New password: "); if (new_password.is_error()) { @@ -136,10 +99,12 @@ int main(int argc, char** argv) return 1; } - pwd.pw_passwd = crypt(new_password.value().characters(), get_salt().characters()); + target_account.set_password(new_password.value().characters()); } - write_passwd_file(&pwd); + if (!target_account.sync()) { + perror("Core::Account::Sync"); + } return 0; } |