Logging in, and what a session is
Domain 1 opens with logging in locally and remotely, which sounds like the easiest thing on the syllabus until you try to answer "who logged in yesterday" on a current Ubuntu. last is not installed, /var/run/utmp does not exist, and who prints nothing. This guide covers identity, what systemd means by a session, the difference between sudo and sudo -i, and where the login record actually lives now.
Essential Commands Guide 4 of 38 Beginner
- PlatformsUbuntu 26.04 LTS + AlmaLinux 10.2
- LVM2.03.31 (Ubuntu) / 2.03.36 (AlmaLinux)
- nftables1.1.6 (Ubuntu) / 1.1.5 (AlmaLinux)
- TimeAbout 16 min
The utmp situation is the interesting one: systemd 257 dropped utmp support, and Ubuntu 26.04 ships neither last nor wtmpdb. RHEL 10 still has the whole traditional set. Both answers are captured.
- Firewallufw 0.36.2 enabled but reporting inactive / firewalld active
- Network confignetplan + systemd-networkd / NetworkManager 1.56.0
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| LFCS-A01 | 192.168.0.70 | Ubuntu 26.04 LTS | Primary host - most guides run only here | 2 Core | 4 GB | 50 GB |
| LFCS-C01 | 192.168.0.72 | AlmaLinux 10.2 | The other distribution - dnf, firewalld and NetworkManager | 2 Core | 4 GB | 50 GB |
This guide includes
Use this for the opening of domain 1. This matters because the traditional login records are not there any more - who prints nothing on these hosts, and the journal is where the answer actually lives.
- separating four commands that look interchangeable and are not
- finding your groups, and where sudo comes from
- asking what systemd means by a session
- seeing why
whoprints nothing, and reading the login record from the journal instead - separating a login shell from a shell, and
sudofromsudo -i
Before you start
- guide 2 - the machines.
-
Who the system thinks you are
Four commands that look interchangeable and are not.
zsh Example session id; echo "---"; whoami; echo "---"; logname 2>&1; echo "---"; echo "USER=$USER LOGNAME=$LOGNAME HOME=$HOME"uid=1000(sysadmin) gid=1000(sysadmin) groups=1000(sysadmin),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users),101(lxd)---sysadmin---sysadmin---USER=sysadmin LOGNAME=sysadmin HOME=/home/sysadmingetent passwd sysadmin; echo "---"; getent passwd sysadmin | awk -F: '{printf "name=%s uid=%s gid=%s home=%s shell=%s\n", $1, $3, $4, $6, $7}'sysadmin:x:1000:1000:sysadmin:/home/sysadmin:/usr/bin/zsh---name=sysadmin uid=1000 gid=1000 home=/home/sysadmin shell=/usr/bin/zshExpected resultuid 1000, a group list, and the passwd line ending
/usr/bin/zsh.Success conditionYou can report an account's real configuration.
-
Groups, and where sudo comes from
The group that grants administrative access, and the two ways to list membership.
bash Example session getent group sudo; echo "---"; id -nG | tr ' ' '\n' | head -8sudo:x:27:sysadmin---sysadminadmcdromsudodipplugdevuserslxdExpected result
sudo:x:27:sysadmin, then the group names one per line.Success conditionYou can tell whether an account has admin rights.
-
What systemd means by a session
loginctl, which knows thingswhodoes not.bash Example session loginctl list-sessions --no-legend | head -5; echo "sessions above" 1 1000 sysadmin - 1372 user - no -1160 1000 sysadmin - 73476 user - no - 2 1000 sysadmin - 1378 manager - no -sessions aboveloginctl show-session $(loginctl list-sessions --no-legend | awk 'NR==1{print $1}') -p Id -p User -p Name -p Remote -p RemoteHost -p Service -p Type -p Class -p Active 2>&1 | head -12Id=1User=1000Name=sysadminRemote=yesRemoteHost=192.168.0.254Service=sshdType=ttyClass=userActive=yesExpected resultTwo sessions, and one of them shown as
Remote=yes,RemoteHost=192.168.0.254,Service=sshd,Class=user,Active=yes.Success conditionYou can inspect who is connected and how.
-
The login records that are not there any more
The traditional way to answer "who logged in recently". On this Ubuntu, none of it exists.
bash Example session for c in last lastlog lastb wtmpdb utmpdump who w; do printf '%-10s %s\n' "$c" "$(command -v $c || echo 'NOT INSTALLED')"; donelast NOT INSTALLEDlastlog NOT INSTALLEDlastb NOT INSTALLEDwtmpdb NOT INSTALLEDutmpdump NOT INSTALLEDwho /usr/bin/whow /usr/bin/wfor f in /var/log/wtmp /var/log/btmp /var/run/utmp /var/lib/wtmpdb/wtmp.db; do printf '%-26s %s\n' "$f" "$(test -e $f && stat -c '%s bytes' $f || echo absent)"; done/var/log/wtmp 768 bytes/var/log/btmp 0 bytes/var/run/utmp absent/var/lib/wtmpdb/wtmp.db absentExpected result
last,lastlog,lastb,wtmpdbandutmpdumpall NOT INSTALLED;/var/log/wtmppresent at 768 bytes but/var/run/utmpabsent.Success conditionYou know why the command from the textbook fails.
-
who prints nothing and w prints one line
The same question, two commands, two different sources.
bash Example session who; echo "who printed $(who | wc -l) line(s)"; echo "---"; w -h; echo "w printed $(w -h | wc -l) line(s)"who printed 0 line(s)---sysadmin 192.168.0.254 09:45 0.00s ? sshd-session: sysadmin [priv]sysadmin pts/0 192.168.0.254 08:29 46:52 0.01s 0.01s -bashw printed 2 line(s)Expected result
who printed 0 line(s)andw printed 1 line(s).Success conditionYou know which of the two still works.
-
So the journal is the login record
The same questions, answered from the journal instead.
bash Example session sudo journalctl --no-pager -n 6 -o short-iso _COMM=sshd-session 2>&1 | tail -72026-08-29T09:45:34+00:00 lfcs-a01 sshd-session[84436]: pam_unix(sshd:session): session opened for user sysadmin(uid=1000) by sysadmin(uid=0)2026-08-29T09:45:34+00:00 lfcs-a01 sshd-session[84483]: Received disconnect from 192.168.0.254 port 58449:11: disconnected by user2026-08-29T09:45:34+00:00 lfcs-a01 sshd-session[84483]: Disconnected from user sysadmin 192.168.0.254 port 584492026-08-29T09:45:34+00:00 lfcs-a01 sshd-session[84436]: pam_unix(sshd:session): session closed for user sysadmin2026-08-29T09:45:35+00:00 lfcs-a01 sshd-session[84494]: Accepted publickey for sysadmin from 192.168.0.254 port 58450 ssh2: ED25519 SHA256:aTxQ2TUQ/xdcGpeWfiZcVs2wa6VhoiGwnj43sn/bXyU2026-08-29T09:45:35+00:00 lfcs-a01 sshd-session[84494]: pam_unix(sshd:session): session opened for user sysadmin(uid=1000) by sysadmin(uid=0)sudo journalctl --no-pager --since "-2h" -g "Accepted publickey" -o cat 2>&1 | tail -3; echo "---"; sudo journalctl --no-pager --since "-2h" -g "Accepted" -o cat 2>&1 | wc -lAccepted publickey for sysadmin from 192.168.0.254 port 58450 ssh2: ED25519 SHA256:aTxQ2TUQ/xdcGpeWfiZcVs2wa6VhoiGwnj43sn/bXyUAccepted publickey for sysadmin from 192.168.0.254 port 58451 ssh2: ED25519 SHA256:aTxQ2TUQ/xdcGpeWfiZcVs2wa6VhoiGwnj43sn/bXyUsysadmin : PWD=/home/sysadmin ; USER=root ; COMMAND=/usr/bin/journalctl --no-pager --since -2h -g Accepted publickey -o cat---1359sudo journalctl --no-pager -n 3 -o cat _SYSTEMD_UNIT=systemd-logind.service 2>&1 | tail -4Session 1357 logged out. Waiting for processes to exit.Removed session 1357.New session '1358' of user 'sysadmin' with class 'user' and type 'tty'.Expected result
Accepted publickey for sysadmin from 192.168.0.254, session opened and closed lines, and logind reportingNew session '134'andRemoved session.Success conditionYou can answer who logged in, from where, and when.
-
A login shell is not the same as a shell
The distinction that decides which files get read.
bash Example session bash -c 'echo "non-login: shlvl=$SHLVL vars=$(env | wc -l)"; shopt -q login_shell && echo "login_shell: on" || echo "login_shell: off"'non-login: shlvl=1 vars=17login_shell: offbash -lc 'echo "login: shlvl=$SHLVL vars=$(env | wc -l)"; shopt -q login_shell && echo "login_shell: on" || echo "login_shell: off"'login: shlvl=1 vars=19login_shell: onbash -c 'echo "$PATH"' ; echo "--- vs login:"; bash -lc 'echo "$PATH"'/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin--- vs login:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/binExpected result
login_shell: offwith 17 variables,login_shell: onwith 19 - and an identical PATH either way.Success conditionYou can tell which startup files applied.
-
sudo, sudo -i, and what changes
Both make you root. They do not give you the same root.
bash Example session sudo -n whoami; echo "---"; sudo -n -i whoami; echo "---"; sudo -n sh -c 'echo "HOME=$HOME PWD=$PWD"'; echo "---"; sudo -n -i sh -c 'echo "HOME=$HOME PWD=$PWD"'root---root---HOME=/root PWD=/home/sysadmin---HOME=/root PWD=/rootsudo -n env | grep -cE '^' ; echo "vars with plain sudo"; sudo -n -i env | grep -cE '^'; echo "vars with sudo -i"12vars with plain sudo17vars with sudo -isudo -n sh -c 'echo "SUDO_USER=$SUDO_USER SUDO_UID=$SUDO_UID USER=$USER"'SUDO_USER=sysadmin SUDO_UID=1000 USER=rootExpected result
rootboth times, butPWD=/home/sysadminagainstPWD=/root, and 12 environment variables against 16.Success conditionYou can choose the right form deliberately.
Troubleshooting
last: command not found.Why: Ubuntu 26.04 does not ship it, and systemd no longer maintains utmp.
Fix:Use
journalctl _COMM=sshd-sessionorjournalctl _SYSTEMD_UNIT=systemd-logind.service. On RHEL,laststill works.whoprints nothing while people are logged in.Why: It reads
/var/run/utmp, which does not exist any more.Fix:
wreads /proc and still works.loginctl list-sessionsis the systemd answer.sudosays the user is not in the sudoers file.Why: Not a member of the admin group -
sudoon Debian and Ubuntu,wheelon RHEL.Fix:
usermod -aG sudo NAME, then log out and back in.A group was added and has no effect.
Why: Group membership is attached to the session at login.
Fix:Log out and in, or
newgrp GROUPfor the current shell.idshows what the session actually has.A command works after logging in and fails over
ssh host command.Why: The second is a non-login, non-interactive shell and read different startup files.
Fix:Compare
bash -lc 'echo $PATH'withbash -c 'echo $PATH'. Use absolute paths in anything unattended.A program run under
sudowrote its config into /root.Why:
HOMEwas set to root's home by the sudoers policy.Fix:
sudo -Epreserves the environment where policy allows, or setHOMEexplicitly.