summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--Source/Kernel/Core/kmain.wtf.cpp4
-rw-r--r--Source/Kernel/Makefile1
-rw-r--r--Source/Kernel/Ressources/Configuration/Groups2
-rw-r--r--Source/Kernel/Ressources/Configuration/Users4
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp10
-rw-r--r--Source/Kernel/TaskManager/Process.class.h9
-rw-r--r--Source/Kernel/UserManager/Group.class.h22
-rw-r--r--Source/Kernel/UserManager/User.class.h67
-rw-r--r--Source/Kernel/UserManager/Usr.ns.cpp95
-rw-r--r--Source/Kernel/UserManager/Usr.ns.h23
-rw-r--r--Source/Library/Common/BasicString.class.cpp34
-rw-r--r--Source/Library/Common/String.class.cpp1
-rw-r--r--Source/Library/Interface/Process.iface.h3
-rw-r--r--Source/Library/Userland/Binding/Process.class.h10
15 files changed, 272 insertions, 19 deletions
diff --git a/Makefile b/Makefile
index 1237ef8..b15010d 100644
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,8 @@ Projects = Kernel Library Tools/MakeRamFS Applications/Shell Applications/Sample
Kernel = Source/Kernel/Melon.ke
RamFS = Init.rfs
RamFSFiles = :/System :/System/Applications :/System/Configuration :/System/Keymaps \
+ Source/Kernel/Ressources/Configuration/Users:/System/Configuration/Users \
+ Source/Kernel/Ressources/Configuration/Groups:/System/Configuration/Groups \
Source/Kernel/Ressources/Keymaps/fr.mkm:/System/Keymaps/fr.mkm \
Source/Kernel/Ressources/Texts/Welcome.txt:/Welcome.txt \
Source/Applications/SampleApps/asmdemo:/ad \
@@ -19,6 +21,7 @@ Floppy = Melon.img
all:
for p in $(Projects); do \
+ echo "=> Building $$p"; \
make -C Source/$$p -s; \
done
@@ -26,16 +29,19 @@ $(Files): all
rebuild:
for p in $(Projects); do \
+ echo "=> Building $$p"; \
make -C Source/$$p rebuild -s; \
done
clean:
for p in $(Projects); do \
+ echo "=> Building $$p"; \
make -C Source/$$p clean -s; \
done
mrproper:
for p in $(Projects); do \
+ echo "=> Building $$p"; \
make -C Source/$$p mrproper -s; \
done
diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp
index a8fb002..9ef55e9 100644
--- a/Source/Kernel/Core/kmain.wtf.cpp
+++ b/Source/Kernel/Core/kmain.wtf.cpp
@@ -17,6 +17,7 @@
#include <MemoryManager/PageAlloc.ns.h>
#include <MemoryManager/GDT.ns.h>
#include <TaskManager/Task.ns.h>
+#include <UserManager/Usr.ns.h>
#include <SyscallManager/IDT.ns.h>
#include <String.class.h>
#include <ByteArray.class.h>
@@ -164,6 +165,9 @@ void kmain(multiboot_info_t* mbd, u32int magic) {
FloppyController::detect();
Log::log(KL_STATUS, "kmain : Floppy drives detected");
+ Usr::load();
+ Log::log(KL_STATUS, "kmain : User list loaded");
+
asm volatile("sti");
Log::log(KL_STATUS, "kmain : Interrupts enabled.");
diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile
index 55c5fb0..4a65c54 100644
--- a/Source/Kernel/Makefile
+++ b/Source/Kernel/Makefile
@@ -59,6 +59,7 @@ Objects = Core/loader.wtf.o \
VFS/File.class.o \
VFS/TextFile.class.o \
VFS/DirectoryNode.class.o \
+ UserManager/Usr.ns.o \
FileSystems/RamFS/RamFS.class.o \
SyscallManager/IDT.ns.o \
SyscallManager/Ressource.class.o \
diff --git a/Source/Kernel/Ressources/Configuration/Groups b/Source/Kernel/Ressources/Configuration/Groups
new file mode 100644
index 0000000..1a222ec
--- /dev/null
+++ b/Source/Kernel/Ressources/Configuration/Groups
@@ -0,0 +1,2 @@
+0:root
+1:users
diff --git a/Source/Kernel/Ressources/Configuration/Users b/Source/Kernel/Ressources/Configuration/Users
new file mode 100644
index 0000000..ea4367f
--- /dev/null
+++ b/Source/Kernel/Ressources/Configuration/Users
@@ -0,0 +1,4 @@
+# format is uid:username:maingroup:completename
+
+0:root:0:Chuck Norris
+1000:alexis211:1:
diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp
index 5256b48..a19fc9e 100644
--- a/Source/Kernel/TaskManager/Process.class.cpp
+++ b/Source/Kernel/TaskManager/Process.class.cpp
@@ -13,6 +13,9 @@ call_t Process::m_callTable[] = {
CALL0(PRIF_EXIT, &Process::exitSC),
CALL1(PRIF_ALLOCPAGE, &Process::allocPageSC),
CALL1(PRIF_FREEPAGE, &Process::freePageSC),
+ CALL0(PRIF_GETPID, &Process::getPid),
+ CALL0(PRIF_GETPPID, &Process::getPpid),
+ CALL0(PRIF_GETCMDLINE, &Process::getCmdlineSC),
CALL0(0, 0)
};
@@ -27,6 +30,7 @@ Process::Process() : Ressource(PRIF_OBJTYPE, m_callTable) { //Private constructo
Process* Process::createKernel(String cmdline, VirtualTerminal *vt) {
Process* p = new Process();
p->m_pid = 0;
+ p->m_ppid = 0;
p->m_cmdline = cmdline;
p->m_retval = 0;
p->m_state = P_RUNNING;
@@ -68,6 +72,7 @@ Process* Process::run(String filename, FSNode* cwd, u32int uid) {
Process::Process(String cmdline, u32int uid) : Ressource(PRIF_OBJTYPE, m_callTable) {
m_pid = Task::nextPid();
+ m_ppid = Task::currProcess()->getPid();
m_cmdline = cmdline;
m_retval = 0;
m_state = P_STARTING;
@@ -170,6 +175,11 @@ u32int Process::allocPageSC(u32int pos) {
return 0;
}
+u32int Process::getCmdlineSC() {
+ if (Task::currProcess()->getPid() == m_pid or Task::currProcess()->getPid() == 0) return m_cmdline.serialize();
+ return (u32int) - 1;
+}
+
u32int Process::freePageSC(u32int pos) {
if (Task::currProcess() != this) return 1;
if ((pos & 0x00000FFF) != 0) pos = (pos & 0xFFFFF000) + 0x1000;
diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h
index eda5fc6..d5fe454 100644
--- a/Source/Kernel/TaskManager/Process.class.h
+++ b/Source/Kernel/TaskManager/Process.class.h
@@ -34,7 +34,8 @@ class Process : public Ressource {
private:
Process(); //Creates an empty process, used by creatKernel()
- u32int m_pid;
+ u32int m_pid; //Process IDentifier
+ u32int m_ppid; //Parent PID
String m_cmdline;
s32int m_retval; //Can be either a standard return value or an E_* (see #defines above)
u8int m_state; //Is one of P_* defined above
@@ -50,7 +51,9 @@ class Process : public Ressource {
//System calls
static call_t m_callTable[];
u32int exitSC();
+ u32int getCmdlineSC();
u32int allocPageSC(u32int);
+ u32int freePageSC(u32int);
public:
static u32int scall(u8int, u32int, u32int, u32int, u32int);
@@ -71,13 +74,15 @@ class Process : public Ressource {
void unregisterFileDescriptor(File* fd);
PageDirectory* getPagedir();
+ u32int getUid() { return m_uid; }
+ u32int getPid() { return m_pid; }
+ u32int getPpid() { return m_ppid; }
VirtualTerminal* getInVT();
VirtualTerminal* getOutVT();
void setInVT(VirtualTerminal* vt);
void setOutVT(VirtualTerminal* vt);
u32int getState() { return m_state; }
- u32int freePageSC(u32int);
};
#endif
diff --git a/Source/Kernel/UserManager/Group.class.h b/Source/Kernel/UserManager/Group.class.h
new file mode 100644
index 0000000..e515058
--- /dev/null
+++ b/Source/Kernel/UserManager/Group.class.h
@@ -0,0 +1,22 @@
+#ifndef DEF_GROUP_CLASS_H
+#define DEF_GROUP_CLASS_H
+
+#include <UserManager/Usr.ns.h>
+
+class Group {
+ friend void Usr::load();
+
+ private:
+ Group(String name, u32int gid) : m_name(name), m_gid(gid) {}
+
+ String m_name;
+ u32int m_gid;
+
+ public:
+ void setName(String wat) { m_name = wat; Usr::save(); }
+
+ String getName() { return m_name; }
+ u32int getGid() { return m_gid; }
+};
+
+#endif
diff --git a/Source/Kernel/UserManager/User.class.h b/Source/Kernel/UserManager/User.class.h
new file mode 100644
index 0000000..1ad55f4
--- /dev/null
+++ b/Source/Kernel/UserManager/User.class.h
@@ -0,0 +1,67 @@
+#ifndef DEF_USER_CLASS_H
+#define DEF_USER_CLASS_H
+
+#include <UserManager/Group.class.h>
+#include <Vector.class.h>
+
+class User {
+ friend void Usr::load();
+
+ private:
+ String m_username, m_completeName;
+ u32int m_uid;
+ Group* m_group;
+ Vector<Group*> m_extraGroups;
+
+ User(String username, String completeName, Group* group, String extragroups, u32int uid)
+ : m_username(username), m_completeName(completeName), m_uid(uid), m_group(group) {
+ Vector<String> eg = extragroups.split(",");
+ for (u32int i = 0; i < eg.size(); i++) {
+ Group* g = Usr::group(eg[i].toInt());
+ if (g != 0) m_extraGroups.push(g);
+ }
+ }
+
+ public:
+ String getUserName() { return m_username; }
+ String getCompleteName() { return m_completeName; }
+ u32int getUid() { return m_uid; }
+ Group* getGroup() { return m_group; }
+ bool isInGroup(u32int gid) {
+ for (u32int i = 0; i < m_extraGroups.size(); i++)
+ if (m_extraGroups[i]->getGid() == gid) return true;
+ return false;
+ }
+ bool isInGroup(String name) {
+ for (u32int i = 0; i < m_extraGroups.size(); i++)
+ if (m_extraGroups[i]->getName() == name) return true;
+ return false;
+ }
+ bool isInGroup(Group* g) {
+ for (u32int i = 0; i < m_extraGroups.size(); i++)
+ if (m_extraGroups[i] == g) return true;
+ return false;
+ }
+
+ String getGroups() {
+ String ret;
+ for (u32int i = 0; i < m_extraGroups.size(); i++) {
+ if (!ret.empty()) ret += ",";
+ ret += String::number(m_extraGroups[i]->getGid());
+ }
+ return ret;
+ }
+
+ void setUserName(String wat) { m_username = wat; Usr::save(); }
+ void setCompleteName(String wat) { m_completeName = wat; Usr::save(); }
+ void setGroup(Group* group) { m_group = group; Usr::save(); }
+ void addGroup(u32int gid) {
+ Group* g = Usr::group(gid);
+ if (g != 0 and !isInGroup(g)) {
+ m_extraGroups.push(g);
+ }
+ Usr::save();
+ }
+};
+
+#endif
diff --git a/Source/Kernel/UserManager/Usr.ns.cpp b/Source/Kernel/UserManager/Usr.ns.cpp
new file mode 100644
index 0000000..a551344
--- /dev/null
+++ b/Source/Kernel/UserManager/Usr.ns.cpp
@@ -0,0 +1,95 @@
+#include "Usr.ns.h"
+
+#include <UserManager/User.class.h>
+#include <SimpleList.class.h>
+#include <TaskManager/Task.ns.h>
+#include <VFS/TextFile.class.h>
+
+/*
+ * Syntax for Users and Groups configuration files : one entry per line
+ * syntax for Users : <uid>:<username>:<basegroup>:<extragroup>,<extragroup>:<completename>
+ * syntax for Groups : <gid>:<name>
+ */
+
+namespace Usr {
+
+SimpleList <User> *m_users = 0;
+SimpleList <Group> *m_groups = 0;
+
+void load() {
+ if (m_users != 0) delete m_users;
+ if (m_groups != 0) delete m_groups;
+ m_users = 0, m_groups = 0;
+
+ TextFile groups("/System/Configuration/Groups", FM_READ);
+ while (!groups.eof()) {
+ String s = groups.readLine();
+ Vector<String> data = s.split(":");
+ if (data.size() == 2 and !(s[0] == WChar("#"))) {
+ m_groups = m_groups->cons(Group(data[1], data[0].toInt()));
+ }
+ }
+
+ TextFile users("/System/Configuration/Users", FM_READ);
+ while (!users.eof()) {
+ String s = users.readLine();
+ Vector<String> data = s.split(":");
+ if (data.size() == 5 and !(s[0] == WChar("#"))) {
+ m_users = m_users->cons(User(data[1], data[4], group(data[2].toInt()), data[3], data[0].toInt()));
+ }
+ }
+}
+
+void save() {
+ TextFile groups("/System/Configuration/Groups", FM_TRUNCATE);
+ for (SimpleList<Group> *iter = m_groups; iter != 0; iter = iter->next()) {
+ groups.write(String::number(iter->v().getGid()) + ":" + iter->v().getName(), true);
+ }
+ TextFile users("/System/Configuration/Users", FM_TRUNCATE);
+ for (SimpleList<User> *iter = m_users; iter != 0; iter = iter->next()) {
+ users.write(String::number(iter->v().getUid()) + ":" + iter->v().getUserName() + ":"
+ + String::number(iter->v().getGroup()->getGid()) + ":"
+ + iter->v().getGroups() + ":" + iter->v().getCompleteName(), true);
+ }
+}
+
+u32int uid() {
+ return Task::currProcess()->getUid();
+}
+
+User* user(u32int uid) {
+ for (SimpleList<User> *iter = m_users; iter != 0; iter = iter->next()) {
+ if (iter->v().getUid() == uid) return &iter->v();
+ }
+ return 0;
+}
+
+User* user(String username) {
+ for (SimpleList<User> *iter = m_users; iter != 0; iter = iter->next()) {
+ if (iter->v().getUserName() == username) return &iter->v();
+ }
+ return 0;
+}
+
+User* user() { return user(uid()); }
+
+Group* group(u32int gid) {
+ for (SimpleList<Group> *iter = m_groups; iter != 0; iter = iter->next()) {
+ if (iter->v().getGid() == gid) return &iter->v();
+ }
+ return 0;
+}
+
+Group* group(String name) {
+ for (SimpleList<Group> *iter = m_groups; iter != 0; iter = iter->next()) {
+ if (iter->v().getName() == name) return &iter->v();
+ }
+ return 0;
+}
+
+u32int uid(String username) {
+ User* x = user(username);
+ return (x != 0 ? x->getUid() : (u32int) - 1);
+}
+
+};
diff --git a/Source/Kernel/UserManager/Usr.ns.h b/Source/Kernel/UserManager/Usr.ns.h
new file mode 100644
index 0000000..397b393
--- /dev/null
+++ b/Source/Kernel/UserManager/Usr.ns.h
@@ -0,0 +1,23 @@
+#ifndef DEF_USR_NS_H
+#define DEF_USR_NS_H
+
+#include <String.class.h>
+class Group;
+class User;
+
+namespace Usr {
+ void load(); //Loads users into memory, from /System/Configuration/{Users,Groups}
+ void save(); //Saves config from mem to filesystem
+
+ u32int uid(); //Returns current processes UID
+
+ User* user(u32int uid); //Returns user from UID
+ User* user(String username);
+ User* user();
+ Group* group(u32int gid);
+ Group* group(String name);
+
+ u32int uid(String username); //Returns UID of username
+};
+
+#endif
diff --git a/Source/Library/Common/BasicString.class.cpp b/Source/Library/Common/BasicString.class.cpp
index ceab60b..b8f7eea 100644
--- a/Source/Library/Common/BasicString.class.cpp
+++ b/Source/Library/Common/BasicString.class.cpp
@@ -1,8 +1,8 @@
#include <Vector.class.h>
-#define FREE if (m_string != 0) delete m_string;
-#define ALLOC m_string = new T[m_length];
-#define VRFY if (m_length == 0) { m_string = NULL; return; }
+#define BS_FREE if (m_string != 0) delete m_string;
+#define BS_ALLOC m_string = new T[m_length];
+#define BS_VRFY if (m_length == 0) { m_string = NULL; return; }
using namespace CMem;
@@ -32,33 +32,33 @@ BasicString<T>::BasicString(const T value, u32int count) {
template <typename T>
BasicString<T>::~BasicString() {
- FREE;
+ BS_FREE;
}
template <typename T>
void BasicString<T>::affect(const BasicString<T> &other) {
- FREE;
+ BS_FREE;
m_length = other.m_length;
- VRFY;
- ALLOC;
+ BS_VRFY;
+ BS_ALLOC;
memcpy((u8int*)m_string, (u8int*)(other.m_string), m_length * sizeof(T));
}
template <typename T>
void BasicString<T>::affect(const T* string, u32int length) {
- FREE;
+ BS_FREE;
m_length = length;
- VRFY;
- ALLOC;
+ BS_VRFY;
+ BS_ALLOC;
memcpy((u8int*)string, (u8int*)string, m_length * sizeof(T));
}
template <typename T>
void BasicString<T>::affect(const T value, u32int count) {
- FREE;
+ BS_FREE;
m_length = count;
- VRFY;
- ALLOC;
+ BS_VRFY;
+ BS_ALLOC;
for (u32int i = 0; i < count; i++) {
m_string[i] = value;
}
@@ -91,7 +91,7 @@ BasicString<T> &BasicString<T>::append(const BasicString<T> &other) {
for (u32int i = 0; i < other.m_length; i++) {
newdata[i + m_length] = other.m_string[i];
}
- FREE;
+ BS_FREE;
m_string = newdata;
m_length += other.m_length;
return *this;
@@ -106,7 +106,7 @@ BasicString<T> &BasicString<T>::append(const T* string, u32int length) {
for (u32int i = 0; i < length; i++) {
newdata[i + m_length] = string[i];
}
- FREE;
+ BS_FREE;
m_string = newdata;
m_length += length;
return *this;
@@ -118,7 +118,7 @@ BasicString<T> &BasicString<T>::append(const T other) {
for (u32int i = 0; i < m_length; i++) {
newdata[i] = m_string[i];
}
- FREE;
+ BS_FREE;
m_string = newdata;
m_string[m_length] = other;
m_length++;
@@ -145,7 +145,7 @@ BasicString<T> BasicString<T>::concat(const T other) const {
template <typename T>
void BasicString<T>::clear() {
- FREE;
+ BS_FREE;
m_string = 0;
m_length = 0;
}
diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp
index ac0eba0..63ff837 100644
--- a/Source/Library/Common/String.class.cpp
+++ b/Source/Library/Common/String.class.cpp
@@ -50,6 +50,7 @@ String String::number(s32int number) {
}
String String::unserialize(u32int w) {
+ if (w == (u32int) - 1) return String();
u32int* a = (u32int*)w;
String ret;
ret.m_length = a[0];
diff --git a/Source/Library/Interface/Process.iface.h b/Source/Library/Interface/Process.iface.h
index 2126dc6..b79639d 100644
--- a/Source/Library/Interface/Process.iface.h
+++ b/Source/Library/Interface/Process.iface.h
@@ -9,5 +9,8 @@
#define PRIF_EXIT 0x01
#define PRIF_ALLOCPAGE 0x02
#define PRIF_FREEPAGE 0x03
+#define PRIF_GETPID 0x04
+#define PRIF_GETPPID 0x05
+#define PRIF_GETCMDLINE 0x06
#endif
diff --git a/Source/Library/Userland/Binding/Process.class.h b/Source/Library/Userland/Binding/Process.class.h
index 00afe27..935bb39 100644
--- a/Source/Library/Userland/Binding/Process.class.h
+++ b/Source/Library/Userland/Binding/Process.class.h
@@ -1,6 +1,7 @@
#include <Syscall/RessourceCaller.class.h>
#include <Process.iface.h>
+#include <String.class.h>
class Process : public RessourceCaller {
public:
@@ -19,4 +20,13 @@ class Process : public RessourceCaller {
void freePage(u32int pos) {
doCall(PRIF_FREEPAGE, pos);
}
+ u32int getPid() {
+ return doCall(PRIF_GETPID);
+ }
+ u32int getPpid() {
+ return doCall(PRIF_GETPPID);
+ }
+ String getCmdline() {
+ return String::unserialize(doCall(PRIF_GETCMDLINE));
+ }
};