Wandering Thoughts archives

2012-03-26

What it means to become another user on Unix

Ignoring things like SELinux for the moment, the basic security state of Unix system calls has always been that root is allowed to become any other UID at will, but no one else is allowed to change their UID or other security attributes (setuid programs then provide an escape hatch from this). But what does it mean to become another user on Unix, beyond just setting your UID? In fact there are a whole series of things that it can mean, some of which you do not necessarily want.

Let's make a list:

  • switching to the user's UID. This is the basic prerequisite of what it means to become another user on Unix, and is done by setuid().
  • switching your groups to the user's groups, which is done with a combination of initgroups() and setgid().

  • setting some environment variables like $HOME and $SHELL to values appropriate for the new user.

    (Most but not all versions of su do this. Versions of su that do not change $HOME can be exciting, especially when combined with shells that read initialization files from $HOME.)

  • clearing various environment variables; in the extreme case, you will clear all environment variables and give yourself a new set of safe values for things like $PATH and so on.

    (Aggressively scrubbing the environment is generally the default for sudo. In general there are any number of environment variables that are very dangerous to leave intact, such as all of the LD_* variables that influence the behavior of the dynamic loader.)

  • running the user's shell, either interactively or with -c ... to execute commands.

    (su normally always runs the user's shell; sudo will often run commands directly without starting the user's shell.)

  • changing to the user's home directory.
  • running the user's shell as a login shell.

  • allocating a new pseudo-tty as the user and attaching the user's shell and so on to it as a new session. This is generally the domain of things that are making real login sessions, like sshd, instead of programs that just become the user.

(Note that this list is not in the order that your code wants to actually do these operations. For example, you want to set groups before changing to the other UID because the moment you setuid() to a non-root user you lose the power to set your own groups list.)

Many things that become another user deliberately run the the target user's shell even when they just want to run a command. This is done partly so that the user's shell can do any special initialization that, eg, may augment its $PATH and partly so that users with restricted shells can't escape them in various clever ways. However, not everything does this and sometimes running the user's shell is inconvenient.

There are a surprising number of cases where you want basically the first two only; you want to run a command as a user but in a way such that their environment (their shell, their shell initialization, and so on) is ignored. It's possible to do this with standard commands like su and sudo by carefully reading their manpages and picking exactly the right options, but I find it easier to have a very basic runas program sitting around.

(runas only works for root, so it can completely ignore authentication and similar issues.)

BecomingAUser written at 00:05:07; Add Comment

2012-03-21

My view of where the Unix community is

I've written before about how there once was a time when Sun could be seen as the heart of the Unix community (cf), and this view of Sun's place in the community is why some people don't like Oracle's Sun-related actions (cf the commentator here). As I wrote back then, my feelings about Sun are somewhat more complicated and tangled (cf) because I don't think that Sun has been the heart of the Unix community for a long time.

There's a lot of reasons that Sun stopped being the center of the Unix community (and maybe I'll write about them sometime), but the important thing is that it did not happen this decade or even this century. Sun ceased being the center in the mid 1990s, when it increasingly had only tired hardware and tired software to offer. Even back then, it was not hard to see where the community was going if you paid attention: it was going to x86 systems, because they were good enough and cheap.

(I don't have a clean and clear definition of the Unix community, but to me it is some mixture of the people using Unix, the people enthused about Unix, and the people who are evolving Unix and moving it forward. Mostly the latter two, really; you need to be interested in Unix as itself in order to really be part of the community instead of just a passive user of computing. This is why most of the OS X people don't count.)

Thus it's clear to me that today's Unix community is found in either FreeBSD or Linux. The part of the community that likes Unix as it is has mostly wound up in FreeBSD; the part of the community that has radical dreams for the future has mostly wound up in Linux (this is where it's appropriate to borrow a Henry Spencer quote and say 'those who don't understand Plan 9 are condemned to reinvent it, poorly'). This is not a new development; it's been this way since no later than the late 1990s.

(My somewhat inflammatory view is that while many of the people of the old Unix community who stayed around Unix seem to have wound up in the *BSDs, the spirit of the Unix community mostly settled in Linux. Unfortunately there are significant drawbacks to this split, some of which I have captured in my borrowed witticism.)

Sun's death and absorption by Oracle was not a real loss for the Unix community because Sun hasn't been important to the real Unix community for some time. The real Unix community is going on just as it has been for years, and is probably roughly as healthy as it ever has been.

Sidebar: why the Unix community is not in all of the *BSDs

OpenBSD is not where the Unix community is today because its scope is too small, although valuable. NetBSD and DragonFly are simply too small, period. Only FreeBSD is large and encompassing enough.

WhereUnixCommunity written at 01:44:37; Add Comment

2012-03-15

Part of the cleverness of Unix permissions (a little thought)

Ever since it's become popular to add various sorts of advanced permissions schemes to Unixes (ACLs, for example), it's struck me that part of the genius of Unix permissions is that they are short.

I don't particularly mean short in storage terms (although that didn't hurt Unix in the early days). I mean short more in the sense of 'simple'; Unix permissions are simple enough that they have a short, clear representation. You can describe the basic access permissions for a file with three relatively short strings (the actual permissions plus who the owner and group of the file is), and these strings are mostly self-contained.

(You don't necessarily know who is in the group without running a command.)

I think that this shortness is an important part of why Unix permissions work relatively well. Short permissions are easy to display (which means that they can be displayed routinely, for example in 'ls -l' output) and relatively easy to understand. Because they are simple, they have few surprising interactions. I'll even go so far as to say that short, simple permissions are relatively easy to manipulate.

(There are aspects of Unix permissions that are not easy to understand and predict, things like what even the permission bits mean on directories, what the various obscure permission bits mean on everything, and so on. But I tend to think that this just adds complexity around the edges, not in the center.)

UnixShortPermissions written at 23:36:48; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.