summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorbrapru <brapru@pm.me>2021-05-29 08:24:41 -0400
committerLinus Groh <mail@linusgroh.de>2021-05-30 17:42:03 +0100
commitff4f3dd5863b5863055bd03a0c200013ee4d9425 (patch)
tree4ba2d2883c2a1a3ebf2b97a5ee4fa05d6d807efc /Userland
parent15607754942b3c6866558ac9c01033b77c55c271 (diff)
downloadserenity-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.cpp43
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;
}