diff --git a/02-clone/clone.c b/02-clone/clone.c
index 47ad1dc..9bf44ca 100644
--- a/02-clone/clone.c
+++ b/02-clone/clone.c
@@ -70,6 +70,20 @@ int child_entry(void* arg) {
     syscall_write(": gettid()  = ", gettid());  // The ID of this thread!
     syscall_write(": getuid()  = ", getuid());  // What is the user id of this thread.
 
+    if (arg != NULL) {
+        // We got a uid_map. So we install it
+        int fd = open("/proc/self/uid_map", O_RDWR);
+        char *uid_map = (char*) arg;
+        write(fd, uid_map, strlen(uid_map));
+        close(fd);
+
+        // With the uid_map in place, we have become 'root' in our
+        // namespace, as the PID from outside maps to the UID=0 within
+        // the namespace. So, we've become root... but not for real!
+        syscall_write(": getuid()  = ", getuid());
+        syscall_write(": setuid() = ", setuid(0));
+    }
+
     // We increment the global counter in one second intervals. If we
     // are in our own address space, this will have no influence on
     // the parent!
@@ -101,12 +115,45 @@ int main(int argc, char *argv[]) {
     int flags = 0;
     void *arg = NULL;
     if (!strcmp(argv[1], "fork")) {
-        // TODO: Implement multiple clone modes.
+        // For a fork, we usually want to recieve a SIGCHLD signal if
+        // the child's process group terminates.
+        flags = SIGCHLD;
+    } else if (!strcmp(argv[1], "chimera")) {
+        // For the chimera, we _only_ share the virtual memory with
+        // the child process. Thereby, a new process but with the same
+        // address space is created.
+        flags = SIGCHLD | CLONE_VM;
+    } else if (!strcmp(argv[1], "thread")) {
+        // For a real thread, we also put the child in the same thread
+        // group. Please note that Linux requires us to also share the
+        // signal handler table, if two threads want to live in the
+        // same thread group.
+        flags = CLONE_VM | CLONE_THREAD | CLONE_SIGHAND;
+    } else if (!strcmp(argv[1], "user")) {
+        // For the UID namespace, we just do a fork, but request a new
+        // user namespace for it.
+        flags = SIGCHLD | CLONE_NEWUSER;
+
+        // In order to actually use this new namespace, we have to
+        // install a simple uid_map. Tomake our life easy, we just
+        // create the uid_map within the parent, pass it as argument
+        // to clone and write it there to the /proc/self/uid_map
+        // pseudo file.
+        arg = malloc(100);
+        snprintf((char*)arg, 99, "0 %d 1\n", getuid());
     } else {
         printf("Invalid clone() mode: %s\n", argv[1]);
         return -1;
     }
-    // TODO: Call clone here!
+
+    // For the clone system call, we specify the start address, and
+    // pass a pointer to the _top_ of stack.
+    pid_t pid = clone(child_entry, &stack[sizeof(stack)-1], flags, arg);
+    if (pid == -1) {
+        perror("clone");
+        return -1;
+    }
+    syscall_write("> clone() returned ", pid);
 
     syscall_write("\n!!!!! Press C-c to terminate. !!!!!", 0);
     while(counter < 4) {