diff options
author | brapru <brapru@pm.me> | 2021-05-29 08:24:41 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-05-30 17:42:03 +0100 |
commit | ff4f3dd5863b5863055bd03a0c200013ee4d9425 (patch) | |
tree | 4ba2d2883c2a1a3ebf2b97a5ee4fa05d6d807efc /Userland | |
parent | 15607754942b3c6866558ac9c01033b77c55c271 (diff) | |
download | serenity-ff4f3dd5863b5863055bd03a0c200013ee4d9425.zip |
Utilities: Update useradd to use /etc/shadow
This updates useradd to write the spwd struct entry into
the /etc/shadow file via putspent.
Fixes #4884
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Utilities/useradd.cpp | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/Userland/Utilities/useradd.cpp b/Userland/Utilities/useradd.cpp index 0a11bbf68e..04755687d7 100644 --- a/Userland/Utilities/useradd.cpp +++ b/Userland/Utilities/useradd.cpp @@ -1,14 +1,19 @@ /* * Copyright (c) 2019-2020, Jesse Buhagiar <jooster669@gmail.com> + * Copyright (c) 2021, Brandon Pruitt <brapru@pm.me> * * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/Base64.h> +#include <AK/Random.h> #include <AK/String.h> #include <LibCore/ArgsParser.h> +#include <crypt.h> #include <ctype.h> #include <errno.h> #include <pwd.h> +#include <shadow.h> #include <stdio.h> #include <string.h> #include <sys/stat.h> @@ -87,6 +92,12 @@ int main(int argc, char** argv) return 1; } + FILE* spwdfile = fopen("/etc/shadow", "a"); + if (!spwdfile) { + perror("failed to open /etc/shadow"); + return 1; + } + String home; if (!home_path) home = String::formatted("/home/{}", username); @@ -111,21 +122,51 @@ int main(int argc, char** argv) } } + auto get_salt = []() { + char random_data[12]; + fill_with_random(random_data, sizeof(random_data)); + + StringBuilder builder; + builder.append("$5$"); + builder.append(encode_base64(ReadonlyBytes(random_data, sizeof(random_data)))); + + return builder.build(); + }; + + char* hash = crypt(password, get_salt().characters()); + struct passwd p; p.pw_name = const_cast<char*>(username); - p.pw_passwd = const_cast<char*>(password); + p.pw_passwd = const_cast<char*>("!"); p.pw_dir = const_cast<char*>(home.characters()); p.pw_uid = static_cast<uid_t>(uid); p.pw_gid = static_cast<gid_t>(gid); p.pw_shell = const_cast<char*>(shell); p.pw_gecos = const_cast<char*>(gecos); + struct spwd s; + s.sp_namp = const_cast<char*>(username); + s.sp_pwdp = const_cast<char*>(hash); + s.sp_lstchg = 18727; + s.sp_min = 0; + s.sp_max = 99999; + s.sp_warn = -1; + s.sp_inact = -1; + s.sp_expire = -1; + s.sp_flag = -1; + if (putpwent(&p, pwfile) < 0) { perror("putpwent"); return 1; } + if (putspent(&s, spwdfile) < 0) { + perror("putspent"); + return 1; + } + fclose(pwfile); + fclose(spwdfile); return 0; } |