« /home/rc

unix access control exercise


This is an exercise from my last Computer Security written exam:

A restaurant processes orders with a FIFO strategy. Orders are stored in file orders.txt.

Define a UNIX-based ACL of the files so to ensure that the following access control policy is enforced by the operating system:

Please provide your answer by completing the dump of the ls -l shell command (assuming that all relevant files are in the current folder):

---------- ________ ________ orders.txt
---------- ________ waiters  enqueue
---------- ________ cooks    dequeue

where cooks is a group containing charlie and cathy and waiters is a group containing willie and winona.

During the exam I wasn't able to answer as precisely as I think I could have. So now I will recreate the environment for this exercise and I will test whether my solution is correct.

my solution

First of all let's write dequeue program, it's a simple C file to append a list to orders.txt

// enqueue.c
#include <stdio.h>
#include <stdlib.h>

int main()
  FILE *pFile;

  pFile = fopen("orders.txt", "a");
  if (pFile == NULL)
    perror("Error appending to file.");
  fprintf(pFile, "just a simple order");

Dequeue comes next, in order to remove a line I am just overriding the first line with a newline"\n"

// dequeue.c
#include <stdio.h>
#include <stdlib.h>

int main()
  FILE *pFile;

  pFile = fopen("orders.txt", "w");
  if (pFile == NULL)
    perror("Error opening file.");
  fprintf(pFile, "\\n");

Now let's create all the users and groups (-m creates a system user with a home directory and a login shell), then we compile the two simple c programs as mario and we set some permission bits.

# init.sh
groupadd waiters
groupadd cooks

useradd -m charlie
useradd -m cathy
useradd -m willie
useradd -m winona
useradd -m mario

usermod -a -G waiters willie
usermod -a -G waiters winona

usermod -a -G cooks charlie
usermod -a -G cooks cathy

runuser -u mario mkdir /home/mario/acl
runuser -u mario -- gcc -o /home/mario/acl/enqueue enqueue.c
runuser -u mario -- gcc -o /home/mario/acl/dequeue dequeue.c
runuser -u mario -- touch /home/mario/acl/orders.txt
chgrp waiters /home/mario/acl/enqueue
chgrp cooks /home/mario/acl/dequeue
chmod o-x /home/mario/acl/enqueue
chmod o-r /home/mario/acl/enqueue
chmod u+s /home/mario/acl/enqueue
chmod o-x /home/mario/acl/dequeue
chmod o-r /home/mario/acl/dequeue
chmod u+s /home/mario/acl/dequeue

This is the simple dockerfile I am using to have a clean enviroment, vim was installed for debugging reasons

# Dockerfile
FROM ubuntu:latest
RUN apt-get update && apt-get install -y vim gcc
ADD . .
RUN sh init.sh

Now this is the output of ls -l command:

$: ls -l
-rwsr-x--- 1 mario cooks   16832 Jan 13 00:18 dequeue
-rwsr-x--- 1 mario waiters 16832 Jan 13 00:18 enqueue
-rw-r--r-- 1 mario mario       1 Jan 13 00:19 orders.txt

Let's see if it works as expected by running a few commands:

root@b17f8eed5dcf:/home/mario/acl\\# su willie
$ ./enqueue
$ cat orders.txt
just a simple order
$ ./dequeue
sh: 4: ./dequeue: Permission denied
root@b17f8eed5dcf:/home/mario/acl\\# su cathy
$ ./dequeue
$ cat orders.txt

$ ./enqueue
sh: 3: ./enqueue: Permission denied
root@b17f8eed5dcf:/home/mario/acl\\# su mario
$ echo "i am the maitre, i do whatever i want" > orders.txt
$ cat orders.txt
i am the maitre, i do whatever i want

Yay! Everything works as expected, it turns out the exercise was definitely doable, I am not entirely sure what happened during the exam, however the most important thing is I understand Unix ACLs.
Here you can find a repository with the source code.