TWiki> CS385fall14 Web>Homework9 (2014-11-28, Main.jakob)EditAttach

Authentication and protection

In most operating systems today, you are asked to log in before using it. xv6 doesn't do that, but we'll add it.

Moreover, once you've logged in, you have restricted access rights: you may only modify files to which you have write permissions, read those to which you have read permission and so on. We'll add those facilities as well.

For this homework, the template is simply the master xv6 branch from the class repository.

login prompt

Modify xv6 so that the user must first log in before being presented with the command line. To do this, look at how "sh" is started, and replace this with a "login" program, that runs "sh" after authentication is complete.

A new file called passwd should hold all valid user names and ID's, containing at least these three entries:

root 0 
user1 1
user2 2

For the purpose of this homework, there is no need to actually check the password. Ask for a username and password, and simply verify that the user name is valid.

exit command

Add an exit command to sh to take the user back to the login prompt. The most straightforward design here is to have login fork before running sh, then wait for sh to finish before presenting another login prompt.

user identity for processes

In the standard UNIX security model, every process runs "on behalf of" a user. Typically, after logging in as user1, every process run within the logged-in console should run on behalf of user1. Add a field to struct proc to track the user responsible for each process, and update xv6 so that this field contains the correct value. The login program should run as user root.

You will need to introduce a system call setuid() to allow login to change identity from root to the appropriate user after a successful login. Important: only root may use the setuid() system call. Hence, if the user id in struct proc is not 0, setuid() should return an error and not change the user id.

Note that multiple users may be running processes simultaneously, and conceptually also be logged in simultaneously (though we only have a single console at this point). Hence, you can't use globals to track which user is logged in.

file ownership

Add a field to struct inode (and the corresponding struct dinode of course) to indicate the owner of the file. Add a system call chown(path,userid) and an executable chown, for changing the owner of a file. It's ok if the executable takes a userid, as opposed to a user name as parameter.

PS. The reading and writing of inode data to disk happens in iupdate and ilock.

file protection

Now that we know the user running a given process, and the owner of each file, we can start enforcing permissions. Modify xv6 system calls to ensure that only the owner of a file, and root, may modify or delete a file. For simplicity you may allow all users to write on console.

sudo (50% bonus)

Using your machine as a regular user (as opposed to root) is typically good practice: mistakes tend to be much less disastrous that way. However, it is inconvenient to have to log out every time you need to do something as root (which you sometimes have to).

As you no doubt have learned by now, Unix provides a sudo command which allows the user to execute programs as superuser, assuming they have the appropriate permissions. For this homework, we will simplify this, and there are no permissions checked - if a user runs "sudo", we pretend they have the correct permissions and proceed with executing the remainder of the command as root.

Interestingly, since only processes running as root may change their user id, it is not (currently) possible for sudo to change id to root. To make this possible, add another field to struct inode: setuid_allowed (and the corresponding struct dinode). If setuid_allowed=1, then this particular program may use setuid even if it is not running as root. Introduce a new system call allow_setuid(path, yesorno) to modify this field. For this to be safe, only programs running as root may use allow_setuid. Create a binary (executable program) called enablesetuid that uses the system call.

Finally, create the sudo program, which runs the specified command as root. Use enablesetuid when logged in as root to allow sudo to do this, then test it when logged in as a regular user.

Topic revision: r4 - 2014-11-28 - 04:52:44 - Main.jakob
Copyright 2016 The Board of Trustees
of the University of
Helping Women Faculty Advance
Funded by NSF