basic user, group and capability housekeeping.
[lunaix-os.git] / lunaix-os / kernel / process / process.c
index 91fe240860211153d3b6b8d3d31e86803b8ee46f..e9fab24e0851148c5ff27e3009dbff81e8eb70eb 100644 (file)
 #include <lunaix/exec.h>
 #include <lunaix/fs.h>
 
-#include <sys/abi.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/abi.h>
+#include <asm/mm_defs.h>
 
 LOG_MODULE("PROC")
 
+int
+spawn_process(struct thread** created, ptr_t entry, bool with_ustack) 
+{
+    struct proc_info* kproc = alloc_process();
+    struct proc_mm* mm = vmspace(kproc);
+
+    procvm_initvms_mount(mm);
+
+    struct thread* kthread = create_thread(kproc, with_ustack);
+
+    if (!kthread) {
+        procvm_unmount(mm);
+        delete_process(kproc);
+        return -1;
+    }
+
+    commit_process(kproc);
+    start_thread(kthread, entry);
+
+    procvm_unmount(mm);
+
+    if (created) {
+        *created = kthread;
+    }
+
+    return 0;
+}
+
+int
+spawn_process_usr(struct thread** created, char* path, 
+                    const char** argv, const char** envp)
+{
+    // FIXME remote injection of user stack not yet implemented
+
+    struct proc_info* proc   = alloc_process();
+    struct proc_mm*   mm     = vmspace(proc);
+    
+    assert(!kernel_process(proc));
+
+    procvm_initvms_mount(mm);
+
+    int errno = 0;
+    struct thread* main_thread;
+    if (!(main_thread = create_thread(proc, true))) {
+        errno = ENOMEM;
+        goto fail;
+    }
+
+    struct exec_host container;
+    exec_init_container(&container, main_thread, VMS_MOUNT_1, argv, envp);
+    if ((errno = exec_load_byname(&container, path))) {
+        goto fail;
+    }
+
+    commit_process(proc);
+    start_thread(main_thread, container.exe.entry);
+
+    if (created) {
+        *created = main_thread;
+    }
+
+    procvm_unmount(mm);
+    return 0;
+
+fail:
+    procvm_unmount(mm);
+    delete_process(proc);
+    return errno;
+}
+
+
+ptr_t proc_vmroot() {
+    return __current->mm->vmroot;
+}
+
 __DEFINE_LXSYSCALL(pid_t, getpid)
 {
     return __current->pid;
@@ -57,79 +132,121 @@ __DEFINE_LXSYSCALL2(int, setpgid, pid_t, pid, pid_t, pgid)
     return 0;
 }
 
-int
-spawn_process(struct thread** created, ptr_t entry, bool with_ustack) 
-{
-    struct proc_info* kproc = alloc_process();
+static inline bool
+__can_change_real_id(const struct user_scope* procu, caps_t id_cap) {
+    if (uscope_with_capability(procu, id_cap)) {
+        return true;
+    }
 
-    procvm_init_clean(kproc);
+    if (check_current_acl(0, 0) != ACL_NO_MATCH) {
+        return true;
+    }
 
-    vmm_mount_pd(VMS_MOUNT_1, vmroot(kproc));
-    
-    struct thread* kthread = create_thread(kproc, VMS_MOUNT_1, with_ustack);
+    return false;
+}
 
-    if (!kthread) {
-        vmm_unmount_pd(VMS_MOUNT_1);
-        delete_process(kproc);
-        return -1;
+__DEFINE_LXSYSCALL1(int, setuid, uid_t, uid)
+{
+    struct user_scope* procu;
+
+    procu = current_user_scope();
+
+    if (__can_change_real_id(procu, CAP_SETUID)) 
+    {
+        procu->ruid = uid;
     }
 
-    commit_process(kproc);
-    start_thread(kthread, VMS_MOUNT_1, entry);
+    __current->suid = uid;
+    __current->euid = uid;
+
+    return 0;
+}
 
-    vmm_unmount_pd(VMS_MOUNT_1);
+__DEFINE_LXSYSCALL1(int, setgid, gid_t, gid)
+{
+    struct user_scope* procu;
 
-    if (created) {
-        *created = kthread;
+    procu = current_user_scope();
+
+    if (__can_change_real_id(procu, CAP_SETGID)) 
+    {
+        procu->rgid = gid;
     }
 
+    __current->sgid = gid;
+    __current->egid = gid;
+
     return 0;
 }
 
-int
-spawn_process_usr(struct thread** created, char* path, 
-                    const char** argv, const char** envp)
+__DEFINE_LXSYSCALL1(int, seteuid, uid_t, euid)
 {
-    // FIXME remote injection of user stack not yet implemented
+    __current->euid = euid;
 
-    struct proc_info* proc = alloc_process();
-    
-    assert(!kernel_process(proc));
+    return 0;
+}
 
-    procvm_init_clean(proc);
+__DEFINE_LXSYSCALL1(int, setegid, gid_t, egid)
+{
+    __current->egid = egid;
 
-    vmm_mount_pd(VMS_MOUNT_1, vmroot(proc));
+    return 0;
+}
 
-    int errno = 0;
-    struct thread* main_thread;
-    if (!(main_thread = create_thread(proc, VMS_MOUNT_1, true))) {
-        errno = ENOMEM;
-        goto fail;
+__DEFINE_LXSYSCALL2(int, setgroups, const gid_t*, gids, unsigned int, len)
+{
+    struct user_scope* procu;
+
+    procu = current_user_scope();
+
+    if (check_current_acl(0, 0) == ACL_NO_MATCH) {
+        return EPERM;
     }
 
-    struct exec_container container;
-    exec_init_container(&container, main_thread, VMS_MOUNT_1, argv, envp);
-    if ((errno = exec_load_byname(&container, path))) {
-        goto fail;
+    if (uscope_with_capability(procu, CAP_SETGID)) {
+        return EPERM;
     }
 
-    commit_process(proc);
-    start_thread(main_thread, VMS_MOUNT_1, container.exe.entry);
+    return uscope_setgroups(procu, gids, len);
+}
 
-    if (created) {
-        *created = main_thread;
-    }
 
-    vmm_unmount_pd(VMS_MOUNT_1);
-    return 0;
+__DEFINE_LXSYSCALL(uid_t, getuid)
+{
+    return current_user_scope()->ruid;
+}
 
-fail:
-    vmm_unmount_pd(VMS_MOUNT_1);
-    delete_process(proc);
-    return errno;
+__DEFINE_LXSYSCALL(gid_t, getgid)
+{
+    return current_user_scope()->rgid;
 }
 
+__DEFINE_LXSYSCALL(uid_t, geteuid)
+{
+    return __current->euid;
+}
 
-ptr_t proc_vmroot() {
-    return __current->mm->vmroot;
+__DEFINE_LXSYSCALL(gid_t, getegid)
+{
+    return __current->egid;
+}
+
+__DEFINE_LXSYSCALL2(int, getgroups, gid_t*, out_buf, unsigned int, len)
+{
+    struct user_scope* procu;
+    struct ugroup_obj* gobj;
+
+    procu = current_user_scope();
+    gobj  = user_groups(procu);
+
+    assert(gobj);
+    len = MIN(gobj->maxcap, len);
+
+    unsigned i = 0;
+    for (; i < len && gobj->list[i] != grp_list_end; i++)
+    {
+        out_buf[i] = gobj->list[i];
+    }
+    
+    return i + 1;
 }
\ No newline at end of file