20#include "UserManager.h"
21#include "pedigree/kernel/Log.h"
22#include "pedigree/kernel/process/Process.h"
23#include "pedigree/kernel/process/Thread.h"
24#include "pedigree/kernel/processor/Processor.h"
25#include "pedigree/kernel/processor/ProcessorInformation.h"
26#include "pedigree/kernel/utilities/Iterator.h"
27#include "pedigree/kernel/utilities/utility.h"
31#include "modules/Module.h"
32#include "modules/system/vfs/File.h"
33#include "modules/system/vfs/VFS.h"
39UserManager::~UserManager() {}
41static bool readAccountFile(
const char* path,
String& contents) {
45 ERROR(
"USERS: Unable to read " << path);
51 while (offset < pFile->getSize()) {
52 size_t amount = pFile->getSize() - offset;
53 if (amount >=
sizeof(buffer))
54 amount =
sizeof(buffer) - 1;
56 uint64_t nRead = pFile->
read(offset, amount,
reinterpret_cast<uintptr_t
>(buffer));
58 ERROR(
"USERS: Unable to read " << path);
62 contents +=
String(buffer, nRead,
true);
69bool UserManager::initialiseGroups() {
71 if (!readAccountFile(
"/etc/group", contents))
75 contents.tokenise(
'\n', lines);
76 for (
auto& line : lines) {
78 if (!line.length() || line[0] ==
'#')
82 line.tokenise(
':', fields);
83 if (fields.
count() < 3) {
84 WARNING(
"USERS: Ignoring malformed /etc/group entry");
88 addGroup(StringToUnsignedLong(fields[2].cstr(), 0, 10), fields[0]);
94bool UserManager::initialiseUsers() {
96 if (!readAccountFile(
"/etc/passwd", contents))
100 contents.tokenise(
'\n', lines);
101 for (
auto& line : lines) {
103 if (!line.length() || line[0] ==
'#')
107 line.tokenise(
':', fields);
108 if (fields.
count() < 7) {
109 WARNING(
"USERS: Ignoring malformed /etc/passwd entry");
113 addUser(StringToUnsignedLong(fields[2].cstr(), 0, 10), fields[0], fields[4],
114 StringToUnsignedLong(fields[3].cstr(), 0, 10), fields[5], fields[6]);
120bool UserManager::initialiseMemberships() {
122 if (!readAccountFile(
"/etc/group", contents))
126 contents.tokenise(
'\n', lines);
127 for (
auto& line : lines) {
129 if (!line.length() || line[0] ==
'#')
133 line.tokenise(
':', fields);
134 if (fields.
count() < 4)
137 Group* pGroup =
getGroup(StringToUnsignedLong(fields[2].cstr(), 0, 10));
142 fields[3].tokenise(
',', members);
143 for (
auto& member : members) {
159 User* pU = it.value();
172 Group* pG = it.value();
179void UserManager::addUser(
size_t uid,
String username,
String fullName,
size_t group,
String home,
183 WARNING(
"USERS: Not inserting user '" << username <<
"' with uid " << uid <<
": duplicate.");
190 WARNING(
"USERS: Not inserting user '" << username <<
"': group " << group
191 <<
" does not exist.");
195 NOTICE(
"USERS: Adding user {" << uid <<
",'" << username <<
"','" << fullName <<
"'}");
196 User* pUser =
new User(uid, username, fullName, pGroup, home, shell);
201void UserManager::addGroup(
size_t gid,
String name) {
204 WARNING(
"USERS: Not inserting group '" << name <<
"' with gid " << gid <<
": duplicate.");
208 NOTICE(
"USERS: Adding group {" << gid <<
",'" << name <<
"'}");
214 if (!initialiseGroups() || !initialiseUsers() || !initialiseMemberships()) {
215 FATAL(
"USERS: Unable to load /etc/passwd and /etc/group");
221 FATAL(
"USERS: Unable to set default user (no such user for uid 0)");
226 if (!pProcess->installUserIdentity(pUser, pUser->
getDefaultGroup(),
nullptr, 0))
227 FATAL(
"USERS: Unable to publish the initial identity");
237static void destroy() {}
239MODULE_INFO(
"users", &init, &destroy,
"mountroot");
virtual uint64_t read(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true) final
virtual bool isDirectory()
const String & getName() const
static ProcessorInformation & information()
An iterator applicable for many data structures.
E lookup(const K &key) const
void insert(const K &key, const E &value)
User * getUser(size_t id)
Tree< size_t, User * > m_Users
Tree< size_t, Group * > m_Groups
static UserManager & instance()
Group * getGroup(size_t id)
const String & getUsername() const
Group * getDefaultGroup()
File * findRetained(const String &path, Directory::ChildLease &result, File *pStartNode=nullptr)
A vector / dynamic array.