Introduction

Hello, and welcome back to CS631 "Advanced Programming in the UNIX Environment". This is week three, segment four. In our previous video segment we saw a lot of examples of creating files, changing their ownership ,changing their permissions, and how that affects who can access them. In this segment, we focus on the system calls that are used to implement the commands we used in the previous segment.

chmod(2)

In particular, in our previous command examples we've seen many calls to the chmod(1) command, so it comes as no surprise that this command is implemented via the chmod(2) family of system calls. Likewise, it should be no surprise that the call comes in the same familiar flavors as before: chmod(2) to act on the file and indirect through symlinks, lchmod(2) to act on the symlink itself, fchmod(2) to act on a file descriptor, and fchmodat(2) to handle relative path names, all as usual. Changing the permissions on the file requires that you are either euid 0 - root can do whatever they want - or your euid matches the st_uid of the file. The permissions you are able to set are those we've already seen, as well as a few additional ones. The one outlier we've not discussed yet is the so called "sticky bit", aka "save text" bit - we'll get back to the details of the sticky bit in a future lecture. Nowadays, it is primarily of interest if set on directories, but more on that another time.

chmod(2) examples

Here, let's see what calling chmod(2) looks like in practice: In this program, we will perform manipulation of existing permissions as well as setting permissions to an absolute value. To update the existing permissions, we first have to get them, so we call stat(2). Then we turn on or off the relevant bits in the st_mode bitmask. Setting bits to an absolute value does not require us to consider the existing st_mode, so we can just go ahead and call chmod(2) here. Okay, let's run it. First, we create 'file' and 'file1'. Here they are now. We run our program and we see that we successfully turned off the user read bit, and enabled the setgid bit; likewise we set the octal 0644 mode as promised. By the way, note that the 's' for the setgid bit here is a capital S. This is because our file is missing the group execute bit, so ls(1) is kind enough to show us this difference. Yeah, let's fix it. There, that looks more normal, doesn't it?

chown(2)

Okay, now let's look at the syscalls required to change ownership of a file. Look familiar? Same family as before - consistency is a virtue. Okay, so changing a files owner is clearly something that can impact the security of the system, and on most systems this action requires euid 0. Now POSIX does allow users to change files they currently own to another user, which was influenced by early System V versions, but by and large you should find that the _POSIX_CHOWN_RESTRICTED constant is defined on most systems, and chown(2)ing files requires root privileges. Changing the group ownership, however, is something that non-root users can do. If you are the owner of the file and the group you're chown(2)ing the file to is either your primary or one of your supplementary groups. We saw this a little bit ago when 'jschauma' was able to change the group ownership of a file to 'wheel' or 'users' in our previous segment.

chown(2) examples

Here's our obligatory code example: first, we try to chown(2) a file to ourselves. This isn't really useful, since either you are the owner, and it'll work, or you're not, and it won't. Unless, of course, you're root. Passing '-1' as the group id means that we won't change the GID when calling chown(2). Next, we try to change the file ownership to 'fred' and leave the group as is, followed by an attempt to change the group to 'users' and finally, an attempt to change the group to 'tty'. Let's give it a try. Here's a file owned by 'jschauma' in group 'wheel'. Of course we are able to chown(2) the file owned by 'jschauma' to 'jschauma" when we run the program, right? But chown(2)ing it to fred, however, - uid 1001 - didn't work. Then changing the group ownership to 'users' succeeded again, but trying to change it to 'tty' failed. 'ls -l' shows the new ownership. Trying to chown(2) a file we don't own, such as /etc/passwd is going to fail on all accounts. We'll try anyway. Okay, what if we were root, though? Well, no surprise here: root can do whatever they want, we said, so all the chown(2) calls succeed, and our file is now owned by fred with group 'tty'.

Recap

Okay, to recap: chmod(2) and chown(2) consistently follow the semantics of the other calls we've seen. That is, we have different flavors allowing operation on the file, on the symlink, on a file descriptor, and atomically safe on a relative path. You don't get a whole lot of surprises here - Unix is nice that way. Next, only root and the owner of a file can change its permissions, which makes sense. Only root can change the owner of a file, but the owner may change the group ownership of a file, including to one of their supplementary groups. Technically, some systems may allow users to chown(2) their own files to another user, but in practice you are unlikely to encounter this. For whatever it's worth, I have not seen a Unix system that allows this in the last 20 years. Changing file permissions and ownerships has significant security implications, so always be careful about what kind of access you grant. In our next video segment, we'll take a look at the default ownership and permissions given to newly created files. See you then, and thanks for watching.

Outro

Cheers!