[MUSIC] We're going to look at managing privileges here. How do you do it right? We've shown how to do it wrong, but what do we do to do it right? Well, for that, there's several different ways to do it. And in order to do that, I have to give some background on users and groups. And then we'll talk about these setuid and setgid privileges, and then we'll talk about jails and other restrictions. Now, on a typical Linux system, there are four types of UIDs, at least. The real user ID, which is whoever is running the program. The effective user ID, that's who the program runs, whose privileges the programs run as. The audit UID, which is what gets written to log files, and it's typically the ID of the user who first logged in, it's sometimes called the login ID as well. And then we talked about the saved UID earlier. Every process has those four UIDs associated with it. So now, here's an example. This is not privileged program, it's just a standard Linux program called doit. When the user Holly runs it, all of those UIDs are the same. Holly logged in, ran this program, so the audit or login UID is holly. Holly is running the program, so the real UID is holly. It's running with Holly's privileges, so the effective UID is holly. And the saved UID is holly also. Now, if you look at this output on Linux, notice the s following the first rw, this is output from ls-l. That little s means that that setuid. The owner is Matt, the group is sys. Since it's a setuid, when Holly runs doit, it will run with Matt's privileges. So the program starts up. Now, the audit UID, again, is Holly because that's who logged in. And the real UID is also Holly because that's the person running the program. But the effective and saved UIDs are Matt, so this program runs with Matt's privileges. Again, with saved UID, we explained this earlier, but as a refresher, the idea here is to provide a mechanism to limit privileges in accordance with the principle of least privilege. If you need privileges only for a short period, you start the program up with those privileges and immediately drop them. The effective UID reverts to whoever's running it, but the saved UID becomes the UID of the person whose privileges you just dropped. When you need them again, you simply issue a setuid call to change back to the saved UID, and you'll get those privileges or rights back. Here's how you get the UIDs, there's several system calls that will do this. The FreeBSD comment after the getlogin system call there is to emphasize that at least on FreeBSD, which is a variant of Unix which is similar to Linux, the getlogin function there is a system call. On some versions of Linux, it's also a system call, on others, it is not, it's a library function. And remember what we warned you about with library functions. Now, to get the audit UID, sometimes you have to be root. The reason for this is that on those systems, the designers didn't want you to know whose identity was being written into log files. And the warning about getlogin is repeated here. If you want to get the saved UID, notice that earlier on there was no system call for getting saved UID. In general, you can't get it directly, you have to first of all use geteuid to get the effective UID. And then when you change them, that old effective UID is the saved UID. On a few systems, they have a system called very specifically that will return the real effective and saved UIDs. And on those systems, you actually can't get it directly. Okay, so we've talked about getting them, how do you set them? Well, there are a number of system calls to do this. They are all analagous to the get versions, just here they change it instead of getting it. The one caveat is the function seteuid. If you are root when you issue that, Then the real effective and saved UIDs are all changed, so you have to be careful. On the other hand, if you're not root, then the effective UID is simply changed to the argument. If you're root and you only want to change the effective UID, then you have to use seteuid. And that's normally what you would do when you are running as root and want to drop privileges temporarily. Because when you do the EUID, it saves the old effective UID. And again, on some systems, you can change the audit or login UID if you're root. And the specific reason for this is that when you log into a system, the server you're dealing with is running its root, it has to in order to give you the privileges you want. But then if you couldn't change that, then everybody would be seen as root. So the superuser, the root user, the administrator can change that to the user who's logging in. Now, if you want to get user names associated with UIDs, there are a couple of functions to do this. getpwuid is the main one, that actually takes an integer or user identifier, integer UID, and looks up in the authentication database and returns the associated information. By the way, notice the line of code that begins with user_name, this is an example of robust programming. If I simply assigned up- >pw_name to user name, what happens if there's no such entry in the user database corresponding to that UID? Well, getpwuid returns null. And then it'd be dereferencing a null pointer, and that would cause, ideally, my program to crash. If not, it would cause undefined behavior. So that's why you do the check for null first. You can use an if statement for this, this is a C conditional. Similarly, if I have a user name and I want to get the associated information including the UID, then I would use get pw_name. And as I said earlier, if I want to get the login name, then I might be able to do it with getlogin, assuming it's a system call. If it's a library function, then this describes exactly how it works. And here is another issue for you. The authentication database on Linux systems is a file and it's readable by everybody. This includes the authentication information, which is typically a hash password. So the point is, even if it's readable, the user can't see what the password is. And on other systems, in fact, the actual authentication information is stored elsewhere, in a protected file. Why couldn't you make the password file, the authentication database, accessible only by root? That would avoid you having to store the authentication information, the hashes, in a separate file. Think about that a bit while we go on to the next video.