Learn › Linux Foundations › User Switching
Final test: Chapter 7, User Switching. Twenty-five objectives on a real Debian 12 server: whoami, id in five forms, a login shell as the account operator and the file it leaves behind, exit, su -c, sudo, sudo -l, sudo -u, three refused reads and their sudo counterparts, /var/log/auth.log, and a command the policy refuses. Fifty minutes, graded from the commands you run and from the file operator owns.
One file opens; another says Permission denied. Which account can read it, and why? First check who your shell is running as and which groups it belongs to. Then inspect the access rules, try an allowed read, and compare the result with the earlier refusal.
Route: inspect identity, switch and return, borrow authority for one command, then read the policy and authentication evidence.
What you already know: Chapter 4 read /etc/passwd and /etc/group and defined an account, a UID and a group, and Chapter 6 created, copied and moved files. This chapter is about who the system thinks you are while you do that, how to become somebody else on purpose, and the written rules that decide how far you can go.
Objectives
After this chapter you can:
Before you start a machine, each exercise shows a rehearsal terminal with recorded output. It checks the requested command but does not change Linux files. Start one real practice machine and use its admin@server1 shell for this chapter. Commands run there, so an unintended command can still have an effect even if the lesson does not mark the exercise complete.
During one connection, the shell keeps your current account and directory. A new connection may start a fresh shell on the same machine. Use whoami and pwd to check where you are before a command that depends on either. The final Test Room starts a separate prepared server and checks its objectives automatically; rehearsal completion is not that result.
Five questions before the material. A wrong answer costs nothing: the explanation states the fact and names the section that teaches it.
>>> Names are for people. Every permission decision is made on numbers: your user ID and the group IDs you carry. Section 7.2 reads both out of the identity record.
>>> su becomes another account, so by default it asks for that account's password. This server replaces the password with a rule that lets your account, and only yours, become operator. Section 7.5.
>>> sudo runs one command as another account, root unless told otherwise, and then you are back to your own identity. Your shell never changes. Section 7.10.
>>> This named file is part of the practice server. The refusal shows that admin cannot read it. In general, Permission denied alone does not prove the final file exists: a directory on the path may deny access before the system can check the file. Section 7.12.
>>> On this server, authentication events go to /var/log/auth.log, which admin cannot read directly. Section 7.14 reads it through a narrowly allowed sudo command. Other Linux systems may use a journal or a different logging setup.
Every shell runs as exactly one account: a name the system knows, with a number behind it. Everything the shell does, it does as that account. Which file you may open, which directory you may write in and which program you may start are all decided by that one fact.
whoami prints the account name of the shell it runs in. It takes no options and no arguments, so it answers the same wherever you stand. It is the shortest way to establish which account a shell is running as before anything else is done on the machine.
prompt: admin@server1:~$ answer: whoami output: admin hint: Section 7.1. One word, no options and no arguments: the command that names the account this shell runs as. It works from any directory.
One word, and it is the word before the @ in your prompt. The prompt is a convenience the shell prints; whoami is the system answering. On a machine whose prompt has been changed, or in a script where there is no prompt at all, whoami is still correct.
The name is a label. Underneath it the system works with numbers, and id prints all of them at once.
Three terms, defined once. A UID is the number of an account. A GID is the number of a group. Your primary group is the one group your account carries by default. New files in this prepared home directory belong to that group; a directory with group-inheritance settings can choose a different group. The command takes no path, so it answers the same from any directory:
prompt: admin@server1:~$ answer: id output: uid=1000(admin) gid=1000(admin) groups=1000(admin) hint: Section 7.2. Two letters, nothing after them: the command that prints the whole identity record at once. It works from any directory.
Three fields. uid=1000(admin) is the account: number first, name in brackets. gid=1000(admin) is the primary group, which here has the same number and the same name, because Debian gives each new account a group of its own. groups=1000(admin) lists every group this account belongs to, primary group included. Chapter 4 read these same numbers out of /etc/passwd and /etc/group; id reads them for the running shell.
The whole record is useful to a person. A script usually wants one field, and id has an option for each one.
-u prints the numeric user ID and nothing else. Print your own:
prompt: admin@server1:~$ answer: id -u ||| id --user output: 1000 hint: Section 7.3. The record command with the option named after the user number, -u, and nothing after it.
One number on one line. Chapter 4 stated the convention this number follows: 0 is root, numbers below 1000 belong to system accounts that no person logs in as, and ordinary accounts start at 1000. A script that has to refuse to run unless it is root tests this value.
-g prints the primary group as a number. Add -n and id prints names instead of numbers. The two are written together as -gn. Print the name of your own primary group:
prompt: admin@server1:~$ answer: id -gn ||| id -ng ||| id -g -n ||| id -n -g output: admin hint: Section 7.3. The record command with the group option and the names option written together as -gn.
One word: the name of the group whose number is 1000 in the full record. -n only makes sense next to -u, -g or -G, because those are the options that produce numbers; on its own it has nothing to convert.
Give id an account name and it reads that account instead of yours. Nothing is switched and nothing is asked for: reading a record is not the same as becoming somebody.
This server has a second ordinary account beside yours, operator. Chapter 4 saw its line in /etc/passwd. Read the record of operator:
prompt: admin@server1:~$ answer: id operator output: uid=1001(operator) gid=37(operator) groups=37(operator),100(users) hint: Section 7.4. The record command with the account name operator after it.
The second ordinary account on this machine is UID 1001, one past yours. Its primary group is operator, GID 37, a group Debian ships on every system. After the comma comes 100(users), a supplementary group: a further group the account belongs to on top of its primary one. Your own record has no comma, because your account belongs to one group only.
One account on every Linux system is different. root, also called the superuser, is the account with UID 0. It normally bypasses ordinary file permission checks and can administer processes, although other security policies can still restrict it. Read the record of root:
prompt: admin@server1:~$ answer: id root output: uid=0(root) gid=0(root) groups=0(root) hint: Section 7.4. The same form as the last exercise, with the account name root.
Zero, three times. The number is what matters, not the name: it is not the word root that grants the power, it is UID 0. An account renamed to anything else with UID 0 would have the same authority, and an account named root with UID 1002 would have none of it.
-G prints every group ID the account carries, primary and supplementary together. With -n it prints their names. List the groups of operator by name:
prompt: admin@server1:~$ answer: id -Gn operator ||| id -nG operator ||| id -G -n operator ||| id -n -G operator output: operator users hint: Section 7.4. The all-groups option and the names option written together as -Gn, then the account name operator.
Two names on one line, separated by a space, the primary group first. This is the list a permission check walks: a file readable by the group users is readable by operator, and not by you.
su starts a new shell as another account. Its name is short for substitute user. You give it the account you want to become, and if the rules allow the switch it starts a shell under the new identity. Your own shell is not gone: it is waiting underneath, and it comes back when the new one ends.
The form to learn is su - operator. The hyphen on its own makes the new shell a login shell, with settings prepared for the account you are entering. It starts in operator's home directory and starts with an environment prepared for operator. An environment is the set of named values a shell hands to every program it starts. Chapter 8 is about that set.
Without the hyphen, su operator keeps your current working directory and much of your environment, but it still changes identity settings such as HOME and USER to operator. That mixture can be confusing: your shell runs as operator while it remains in the directory you came from. Use the login form here so the directory and starting environment match the account you entered.
su decides who may switch through PAM, the Pluggable Authentication Modules: a list of rules a program reads from its own file in /etc/pam.d, here /etc/pam.d/su. On a default Debian system those rules ask for the password of the account being entered. On this server three rules replace the password check for this switch. Your account may become operator without a password. Nobody but root may become any other account, root included. Operator's password is locked, so a password cannot open that account; the account itself still exists and this server's rule lets you switch into it.
You are in your own shell, admin@server1. Open a login shell as operator:
prompt: admin@server1:~$ answer: su - operator ||| su -l operator ||| su --login operator output: hint: Section 7.5. The switch command, the lone hyphen that makes the new shell a login shell, then the account name operator.
The shell switches to operator's account without asking for a password on this prepared server. The prompt's account label changes to operator; its ~ now refers to /home/operator. The next exercise confirms the account with whoami. On a system without this server's rule, a Password: line would come first.
You are now in an ordinary shell belonging to operator. The prompt shows that account, but whoami confirms the identity used for permission checks. Everything works the way it did in your own shell, with one difference: every permission decision is made against operator, not against you. Confirm the account:
prompt: operator@server1:~$ answer: whoami output: operator hint: Section 7.1. The same one-word identity command, run in this shell. It needs no path.
The answer changed. It is the same command and the same machine; only the identity of the shell is different. This is what makes a switch worth doing: to work as another account you become it, and every command you then run carries that account with it.
Chapter 6 copied files with cp. You are in the operator shell, standing in /home/operator. Copy /etc/server1/site.conf to ~/site.conf, which is /home/operator/site.conf; the source is world readable, so operator may read it.
prompt: operator@server1:~$ answer: cp /etc/server1/site.conf ~/site.conf ||| cp /etc/server1/site.conf . ||| cp /etc/server1/site.conf ~ ||| cp /etc/server1/site.conf /home/operator/site.conf ||| cp /etc/server1/site.conf site.conf output: hint: Section 7.6. The copy command from Chapter 6: the absolute source /etc/server1/site.conf, then the destination ~/site.conf, which names /home/operator/site.conf from anywhere.
Silent, like every successful cp. What the copy records about who made it is not printed; it is stored with the file and shown by a long listing.
The login shell put you in operator's own home directory, /home/operator. List it in long form; write ~ after the option and the listing is the same wherever you stand:
prompt: operator@server1:~$ answer: ls -l ||| ls -l ~ ||| ls -l . ||| ls -l /home/operator output: total 4 -rw-r--r-- 1 operator operator 198 Sep 30 15:03 site.conf hint: Section 2.4. The long listing from Chapter 2 with the option -l. Write ~ or /home/operator after it and it lists operator home wherever you stand.
The third and fourth fields of the line are the owner and the group of the file, and both say operator. Nothing asked for that. A new file belongs to the account that creates it, so the identity of the shell is stored with every file it makes. The date and time in your own listing are the moment you made the copy; the line above was captured when this machine started.
This is why ownership is useful evidence here. You made this copy while the operator shell was active, and the new file is owned by operator. A privileged account could also create or change ownership of a file, so ownership alone does not prove every step of its history. The lab checks the file you leave behind.
exit ends the current shell. In the shell su started, ending it puts you back in the shell that was waiting underneath, which is your own. You are in the operator shell; end it:
prompt: operator@server1:~$ answer: exit output: hint: Section 7.7. Four letters: the word that ends the current shell. It takes nothing after it.
The prompt shows your admin account again. Nothing was undone: the file you copied is still in operator's home directory, owned by operator. You simply left operator's shell.
The prompt is text the shell prints, and a prompt can be edited to say anything. The identity commands read the running shell itself, so they answer correctly whatever the prompt says. You are back in your own shell; confirm it:
prompt: admin@server1:~$ answer: whoami output: admin hint: Section 7.7. The one-word identity command again, now that the second shell has ended.
Back to admin. Two shells were involved and one of them has ended. Check with whoami after every switch. A command typed in the wrong shell runs under the wrong account. File ownership and log entries record the account, never the intention.
The rule that let you into operator names one account. su with a hyphen and no account name asks for root, the account with UID 0. You are in your own shell. Ask su for a root login shell:
prompt: admin@server1:~$ answer: su - ||| su ||| su - root ||| su root output: su: Permission denied hint: Section 7.5. The switch command with the lone hyphen and no account name after it, which means root.
Refused, and no password was asked for. The PAM rules turned the request down before the point where su would prompt, because your account is not one the rules allow to become root. On a default system su would ask for root's password first; here there is no password that could open this switch, and no member holds one. The attempt is still recorded in /var/log/auth.log, which Section 7.14 reads.
There is a second word for ending a shell, and it only works in one place. logout ends a login shell, the shell a session starts with. It is a builtin: a command bash carries inside itself rather than a program on disk.
In any other shell bash refuses logout and names the right tool:
bash: logout: not login shell: use `exit'
The rule is short. exit ends any shell. logout ends only a login shell, and answers with that line anywhere else.
Do not type logout in the lab or on the practice machine. The shell you connect with IS a login shell, so it works: it ends your session and closes the terminal. There is no exercise for it in this chapter for that reason, and the lab does not grade it.
Opening a shell to run one command and leave again is a lot of steps. The -c option takes a command, runs it as the other account, and returns you to your own prompt when it finishes. No second shell stays open.
The same PAM rules apply,
Practice Chapter 7. User Switching: whoami, id, su and sudo in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.