The Meaning of 'su'
pthree.org
pthree.org
======================================================== "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. =========================================
$ sudo -s
$ pwd
/home/ralph
$ exit
$ sudo -i
root@orac:~# pwd
/root
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
$(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.)
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).
su -- substitute user identity1. 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.
(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.
q = password;
while((*q = getchar()) != '\n')
if(*q++ == '\0')
return;
Notably, you don't actually need the password... Buffer overflow!I enjoy how informal that man page is. All of today's man-pages would never get away with "fun."
$ man su
NAME
su -- substitute user identityI thought it meant super user too, but then I put in that command and said "ah". Then I moved on with my life....
NAME
su - change user ID or become superuser
It's not quite so simple. The meaning has changed over time. ~$ man su
NAME
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.You should see this beast in Solaris!
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/sr...
It is slightly over dramatized, isn't it ? :)
The author points out that the meaning has changed over time from the initial meaning of "superuser" to "switch user", due to feature creep.
http://harmful.cat-v.org/cat-v/
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.
This could be a simple wrapper script around sudo, but that could require entering the password twice.
(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/.
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.
What about this snippet:
if (error_return) {
printf("My error");
return;
}
Clearer than a goto, no? And see, no exceptions ma'!(Oh yeah, and longjmp/setjmp are the worst ideas in the world...)
SU(1) BSD General Commands Manual
NAME su -- substitute user identity
SYNOPSIS su [-] [-flm] [login [args]]
...
</barney>