Hacker News new | past | comments | ask | show | jobs | submit login
The Meaning of 'su' (pthree.org)
141 points by myko on Feb 25, 2013 | hide | past | favorite | 55 comments

Copy pasting the best comment from the article. It basically covers the crux.

======================================================== "jonkx using on | May 31, 2010 at 10:22 am | Permalink

I worked with the Unix OS from the early 1980′s (at first we ran early versions on a DEC PDP-11) until 1992. Starting in 1992, I did contract work on proprietary versions based on SVR4.

It was just easier to say the initials “S U” or “super-user” than to say “switch user” or “substitute user”. To insist on correctness, whether authoritarian, historical or otherwise seems petty.

Depending on the options used, su can be used to switch user, substitute user or become “super user”. Success depends on knowledge of the appropriate password. “sudo” on the other hand may allow one to become any other user (depending on the configuration of sudo and being a “sodoer”) knowing only the login password.

On the systems I have used, a sudoer can become root (“super user”) using this shell command at a terminal:

sudo su – root

and responding to the prompt with the login password used to sign in the current user.

I think it is important to point out that you cannot become “super user” or root from a shell with the su command alone unless there is a root password and that password is entered at the prompt. =========================================

To all people who type "sudo su - root": the much simpler "sudo -i" accomplishes the same (-i launches an interactive shell).

The "-i" option actually means "simulate Initial login" -- the idea being -i will drop you into a shell as if you'd logged in as the user in a fresh session. -s will also give you an interactive shell, but doesn't mess with the environment.

(And both -i and -s can also not give you an interactive shell, if you give it a command to run. The point is that it will run the command in the shell rather than just fork()ing and exec()ing like a bare sudo invocation would do.)

Read carefully: "sudo -i" to replace "sudo su - root". You should check the "su" manpage and look for the -/-l/--login option.

I'm not objecting to that. I'm objecting to the (perhaps unintended) assertion that "sudo -i" means "give me an interactive shell". It does happen to give you an interactive shell (assuming you don't specify a command), but as a side effect. "-s" gives you an interactive shell too, but the semantics are different.

I thought "sudo -s" was the correct way to drop into a root user shell.

No, unless one understands the subtleties, it may be best to use -i.

    $ sudo -s
    $ pwd
    $ exit
    $ sudo -i
    root@orac:~# pwd
    root@orac:~# logout
    $ sudo strace -fe execve sudo -s
    execve("/usr/bin/sudo", ["sudo", "-s"], [/* 16 vars */]) = 0
    execve("/bin/bash", ["/bin/bash"], [/* 16 vars */]) = 0
    $ exit
    $ sudo strace -fe execve sudo -i
    execve("/usr/bin/sudo", ["sudo", "-i"], [/* 16 vars */]) = 0
    execve("/bin/bash", ["-bash"], [/* 16 vars */]) = 0
    root@orac:~# logout

What is the difference between that and sudo bash

One side effect of "sudo bash" is that when you exit that shell your local user's .bash_history file gets overwritten by one owned by root (and un{read/write}able by the local user), and so your local user loses the bash history functionality from that point on.

This is a great article and people quoting modern manual pages miss the point. The point is that the meaning of su(8) changed and that is conveyed through an nice anecdote where the author discovers exactly how it changed.

In the research version of Tenth Edition Unix, su(8) is described as:

  su, setlog -- substitute userid temporarily, become super user
Which is an interesting intermediate step from today's (or rather 2.9BSD's)

  su -- substitute user identity
found in BSD derivatives.

Btw, the Tenth Edition manual was written mostly by Douglas McIlroy, inventor of pipes. Even if the 1127 group imported outside code for the VAX versions of research Unix (v8-10), they liked a particular kind of documentation, which the imported code lacked, so they wrote their own. Dare I say the style of research Unix manuals closely matches the style of Go documentation today (unremarkable, considering the pedigree).

This comment has it correct. For those of you on a Mac (and I specifically mention a Mac, due to its BSD userland utilities), you can see that this is still defined this way today: type `man su` and you'll see:

    su -- substitute user identity

I would recommend against using sudo su -, esp if you have <user> ALL=(ALL) NOPASSWD: ALL or such constructs in your /etc/sudoers file that exempt password requirements from executing sudo commands.

1. su gives you a root shell. Principle of least privilege dictates you should executes the fewest commands as root as required, not all commands as root because you need one.

2. sudo su - loses auditability of who executed what/when. All we know is that someone got a sudo shell at some point. When the forensics guys come along post-breach, you won't have a lot of good info to give them.

3. Loss of a shell (via command injection on a web form) may allow remote Command-and-Control of your machine.

If you need a cron or other headless process (daemons, etc.) then use NOPASSWD in conjunction with a whitelisted set of commands (not /bin/bash) to be executed.

If you need an operator to execute a command as a specific user, then use sudo -u <user> <cmd>. Even if you allow ALL commands, at least your audit logs will know what/when the command was executed.

With all powerful commands comes the responsibility of understanding how to use them safely and what the possible repercussions are.

In production, yes. For debugging on a test machine, or during a post-mortem, it's just inconvenient not to. If the majority of your time is spent in the shell of a production machine, you're doing something wrong.

4. And if you need to do anything extensive as root on a any machine, you might want to consider doing it with a configuration management system (puppet, chef, ansible).

When perusing early Unix code, it's striking how concise and down-to-the-point it is. We've really accumulated a lot of cruft (mostly for the sake of compatibility and feeping creaturism) over the years.

A bit off topic, but man it really bugs me when people (like this author) say "command" because they don't know the right word.

(A mistake made by this article)

"I wonder why the creat() command doesn't have an 'e'."

(Similar examples I've seen around the web)

"I'm using the printf command." "I was doing assembly programming and I used the jump command."

Syscall! Function! Instruction! Let's be precise people.

Isn't "command" [at least conversationally] a supergroup of syscalls, functions and instructions?

So to be even more precise ;-) are you treating Syscall, Function and Instruction as synonyms?

I don't think he is. He references creat, printf and jump, which happen to be a syscall, function and instruction, respectively.

    q = password;
    while((*q = getchar()) != '\n')
        if(*q++ == '\0')
Notably, you don't actually need the password... Buffer overflow!

My beard is rather short as of yet, but I've always read 'su' as an acronym for 'setuid' (because that's what it does).

I think it really stands for "super user", here's its man page from Unix v1 http://man.cat-v.org/unix-1st/1/su .

> su allows one to become the super--user, who has all sortsof marvelous powers.

I enjoy how informal that man page is. All of today's man-pages would never get away with "fun."

  $ man su

     su -- substitute user identity

$ man su

       su - change user ID or become superuser
It's not quite so simple. The meaning has changed over time.

What coreutils are you using? I get:

  ~$ man su

    su - change user ID or become superuser
OS X uses the FreeBSD coreutils and not the GNU ones, so if you're on either OS X or FreeBSD, that would explain it.


I thought it meant super user too, but then I put in that command and said "ah". Then I moved on with my life....

It does stand for super user. The article cites the su.c code from 1975.

Taking 'super-user' to mean 'root' seems like a big assumption. Is there anywhere in the Unixverse where root is specifically referred to as 'super-user'? I sort of thought 'super-user' would refer to any user with higher privileges. Well, really just different privileges, but why would you switch to a user with lesser permission to preform the action you probably just got denied? I assume the presented code was just that way because it covered 99% of use cases and was good enough for then and that root is now the default user for the same reason.

I'm not 100% sure where you're going with all that, but there are legitimate reasons for the super-user to "move down" into a specific user's identity -- for example, to be sure that files/directories created during some maintenance are owned by that specific user, and have that user's umask applied. Another instance would be file cleanups when the super-user specifically didn't want to be able to delete arbitrary files. There are lots of other cases.

What a cute su.c file!

You should see this beast in Solaris!


In Italian it means "up".

In Turkish, it is water

It's funny how the article and most of the comments here assume that there is one meaning and it is "out there" for all of us to see. Maybe there isn't any one definite meaning: http://michaelfeathers.typepad.com/michael_feathers_blog/201...

> “su” was written to only change to the root user on the system. It wasn’t designed to switch to any other user that has an account. “su” meant “super-user”. I need to sit down for a second.

It is slightly over dramatized, isn't it ? :)

TL;DR: the author doesn't know, and lists the standard possibilities: superuser, switch user, or subshell. From the article: "Well, I wish I had an answer, but I don’t."

Better TL;DR:

The author points out that the meaning has changed over time from the initial meaning of "superuser" to "switch user", due to feature creep.

Funny as it's the opposite of the UNIX philosophy: "Write programs that do one thing and do it well"...

Is switching to an arbitrary user really "more than one thing"? Would the UNIX philosophy be to have a separate switch program for every user on the system?

I think `joshguthrie` means something along the lines of this:


I think `su` is pretty good as-is, but sudo has a bit of feature creep. For example, I don't think these belong in sudo (taken from Linux):

-e: edit something

-l: list allowed/forbidden commands

-p: change prompt

Ideally, sudo would just run as root and su would just switch users. Then instead of:

sudo -u some_user cmd

You'd do this instead:

sudo su -c "cmd" some_user

Su only does one thing (switch users, -c for one-off cmd) and sudo only does one thing (change to root). Currently, both "sudo -u some_user cmd" and "sudo su -c some_user cmd" accomplish basically the same thing, which is a sign of feature creep.

"-e: edit something" (or 'sudoedit') is actually very useful. It makes a temporary copy of th file that is editable by your user, allowing the editor to be run without elevated privileges. After the editor quits, it moves the edited file back over the original.

This could be a simple wrapper script around sudo, but that could require entering the password twice.

sudo has security features. It's possible to restrict the set of commands that can be executed, for example. What would be a Unixy way to do that? How can you decouple the thing that gives you root access from the thing that restricts what you can do with it?

There is a difference of "functionality" between "Become Super User" and "Switch User", the base intent is not the same.

TL;DR: Legacy code with gotos in it.

Way to nitpick about goto while completely overlooking the obvious buffer overflow.

This was all I could think about when reading that code.

There are at least two buffer overflows in that code.

It is C, of course it is going to have goto's in it. How else are you going to handle error conditions? Copy and paste the error code a dozen times within a single function?

(hint: C doesn't support exceptions)

You could use longjmp/setjmp but those have a lot of the same issues that people claim goto has. In fact worse in several ways, since while goto makes it hard to follow the program flow, longjmp makes it /impossible/.

No exceptions? What a conondrum I find myself faced with...

What about this snippet:

    if (error_return) {
       printf("My error");
Clearer than a goto, no? And see, no exceptions ma'!

(Oh yeah, and longjmp/setjmp are the worst ideas in the world...)

> since while goto makes it hard to follow the program flow, longjmp makes it /impossible/.

Only if you don't use it tastefully. It can be a nice way to bail out of a recursive function with an error code, which is precisely how I've used it. Really, it looks exactly the same as a try ... catch block in that C++/Java/C# language everyone's on about now.

Setjmp is great for reseting a state machine, and many things are modeled as state machine.

thats not an inappropriate use of gotos either. they're in the same function, just a few lines down, and are just used to improve the safety and efficiency of the code. in fact thats the textbook case of the only time when a goto is actually a good idea.

To old hands, su has always and will always mean super user. The meaning does not "change" (even if the program does).

$ man su

SU(1) BSD General Commands Manual

NAME su -- substitute user identity

SYNOPSIS su [-] [-flm] [login [args]]


Oh, so it isn't an acronym for suit-up?


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact