The Pedigree Project 0.1
Process-credentials.cc
1#include "pedigree/kernel/LockGuard.h"
2#include "pedigree/kernel/process/Process.h"
3#include "pedigree/kernel/process/Scheduler.h"
4#include "pedigree/kernel/processor/Processor.h"
5
6#include "modules/system/users/Group.h"
7#include "modules/system/users/User.h"
8
9bool Process::loadFilesystemIds(const Thread& task, uint32_t& uid, uint32_t& gid) {
10 if (!task.m_FilesystemIdsValid)
11 return false;
12 uid = task.m_FilesystemUid;
13 gid = task.m_FilesystemGid;
14 return true;
15}
16
17void Process::publishFilesystemIds(Thread& task, uint32_t uid, uint32_t gid) {
18 task.m_FilesystemUid = uid;
19 task.m_FilesystemGid = gid;
20 task.m_FilesystemIdsValid = true;
21}
22
23bool Process::snapshotFilesystemCredentials(const Thread* task, FilesystemCredentials& out) const {
24 LockGuard<Spinlock> guard(m_CredentialLock);
26 if (task && task->getParent() != this)
27 return false;
28 // Early filesystem discovery precedes loading the account database.
29 if (!out.valid && this == Scheduler::instance().getKernelProcess()) {
30 out.uid = out.gid = 0;
31 out.valid = true;
32 }
33 if (!out.valid) {
34 User* user = m_pEffectiveUser ? m_pEffectiveUser : m_pUser;
36 if (!user || !group || user->getId() >= UINT32_MAX || group->getId() >= UINT32_MAX)
37 return false;
38 out.uid = user->getId();
39 out.gid = group->getId();
40 out.valid = true;
41 }
42 if (task)
43 loadFilesystemIds(*task, out.uid, out.gid);
44 return true;
45}
46
47bool Process::currentFilesystemCredentials(FilesystemCredentials& out) {
48 Thread* task = Processor::information().getCurrentThread();
49 if (!task)
50 return false;
51 if (task->m_FilesystemOverride) {
52 out = *task->m_FilesystemOverride;
53 return out.valid;
54 }
55 return task->getParent()->snapshotFilesystemCredentials(task, out);
56}
57
58void Process::inheritFilesystemIds(Thread& child, const Thread* creator) const {
59 FilesystemCredentials credentials;
60 const Process* source = creator ? creator->getParent() : this;
61 if (!source->snapshotFilesystemCredentials(creator, credentials))
62 return;
63 LockGuard<Spinlock> guard(m_CredentialLock);
64 publishFilesystemIds(child, credentials.uid, credentials.gid);
65}
66
67void Process::publishAccountIdentity(User* user, Group* group) {
68 m_pUser = m_pEffectiveUser = user;
70}
71
72bool Process::installUserIdentity(User* user, Group* group, const uint32_t* groups, size_t count) {
73 if (!user || !group || user->getId() >= UINT32_MAX || group->getId() >= UINT32_MAX ||
74 count > FilesystemCredentials::MaximumGroups || (count && !groups))
75 return false;
76 for (size_t i = 0; i < count; ++i)
77 if (groups[i] == UINT32_MAX)
78 return false;
79 LockGuard<Spinlock> guard(m_CredentialLock);
80 publishAccountIdentity(user, group);
81 auto& credentials = m_NativeFilesystemCredentials;
82 credentials.uid = user->getId();
83 credentials.gid = group->getId();
84 credentials.groupCount = count;
85 for (size_t i = 0; i < count; ++i)
86 credentials.groups[i] = groups[i];
87 credentials.valid = true;
88 Thread* current = Processor::information().getCurrentThread();
89 if (current && current->getParent() == this)
90 publishFilesystemIds(*current, credentials.uid, credentials.gid);
91 return true;
92}
93
94Process::FilesystemAccessScope::FilesystemAccessScope(const FilesystemCredentials& credentials)
95 : m_Credentials(credentials),
96 m_Thread(Processor::information().getCurrentThread()),
97 m_Previous(m_Thread ? m_Thread->m_FilesystemOverride : nullptr) {
98 if (m_Thread)
99 m_Thread->m_FilesystemOverride = &m_Credentials;
100}
101
102Process::FilesystemAccessScope::~FilesystemAccessScope() {
103 if (m_Thread)
104 m_Thread->m_FilesystemOverride = m_Previous;
105}
106
108 LockGuard<Spinlock> guard(m_CredentialLock);
109 return m_pUser;
110}
111
113 LockGuard<Spinlock> guard(m_CredentialLock);
114 return m_pEffectiveUser;
115}
116
118 LockGuard<Spinlock> guard(m_CredentialLock);
119 return m_pGroup;
120}
121
123 LockGuard<Spinlock> guard(m_CredentialLock);
124 return m_pEffectiveGroup;
125}
126
127void Process::setUser(User* value) {
128 LockGuard<Spinlock> guard(m_CredentialLock);
129 m_pUser = value;
130 m_NativeFilesystemCredentials.valid = false;
131}
132
134 LockGuard<Spinlock> guard(m_CredentialLock);
135 m_pEffectiveUser = value;
136 m_NativeFilesystemCredentials.valid = false;
137}
138
140 LockGuard<Spinlock> guard(m_CredentialLock);
141 m_pGroup = value;
142 m_NativeFilesystemCredentials.valid = false;
143}
144
145void Process::setEffectiveGroup(Group* value) {
146 LockGuard<Spinlock> guard(m_CredentialLock);
147 m_pEffectiveGroup = value;
148 m_NativeFilesystemCredentials.valid = false;
149}
Definition Group.h:32
size_t getId() const
Definition Group.h:50
Group * m_pGroup
Definition Process.h:1036
Group * getEffectiveGroup() const
FilesystemCredentials m_NativeFilesystemCredentials
Definition Process.h:1033
Group * m_pEffectiveGroup
Definition Process.h:1040
void setGroup(Group *pGroup)
Group * getGroup() const
User * getEffectiveUser() const
User * m_pEffectiveUser
Definition Process.h:1038
User * getUser() const
void setEffectiveUser(User *pUser)
void setUser(User *pUser)
static ProcessorInformation & information()
static Scheduler & instance()
Definition Scheduler.h:96
Process * getParent() const
Definition Thread.h:338
Definition User.h:32
size_t getId() const
Definition User.h:60