Unix shells are generally not viable access control mechanisms any more
utcc.utoronto.ca
utcc.utoronto.ca
1. Once upon a time you could rely on the passwd file and shell behavior as an effective means of authentication and access control.
2. It has been a very long time since that was an effective approach, for a variety of reasons, and you should not do this on modern production systems.
TFA = The Fucking Article.
Much like:
RTFM = Read The Fucking Manual.
That look of realisation is precious.
I've manufactured this experience once or twice, and it's wonderful.
A recipient who is being not-so-subtly reproached with an F-bomb acronym might misunderstand what is being implied.
All of that is now wrapped up in the initialism.
The guidelines say that you should not accuse someone of not having read the article. However, as the guidelines say it is fine to point out that something is mentioned in the article.
There is a subtle difference.
From the guidelines:
> Please don't comment on whether someone read an article. "Did you even read the article? It mentions that" can be shortened to "The article mentions that".
Parent comment was in line with the guidelines IMO.
And as for “TFA” as an acronym I like to read it as meaning “The Featured Article”. Then it seems nice and friendly.
If you fuck up the sudo file while saving it, you might no longer be able to log in to fix it. Before I knew about sudoedit I would open two shells as root, edit the file, then use a third window to make sure I could still sudo.
With two windows I could accidentally close the subshell in one without locking myself out. Think if it like linemen, who use two tethers for climbing structures. They are never detached from the safety lines.
sudo visudo* Doesn't scale. Having passwords in a plain text file is not a scalable solution for users directory. Can probably go up to a hundred users, but not much more.
* In computer clusters you want user identity to "stick" to the user when they use multiple machines, containers etc. That's why you have LDAP... but it doesn't help all that much because user id is encoded into the file system (huge mistake...) which makes it very difficult to contain users to things they should control. If your only mechanism was the /etc/passwd, it would mean you'd have to constantly synchronize this file across all those machines and containers you have.
If you look in your /etc/passwd right now, you'll almost certainly see a single "x" where the (EDIT: no, it was still encrypted!) password originally was - nowadays that single "x" is an instruction to go look in /etc/shadow instead, for the salted hash of the password you're trying to check.
I think this minimizes the number of users who need read permissions to /etc/shadow, and the amount of time they need it for.
This has been your seemingly useless bit of Linux trivia for today. :)
unencrypted vs unstructured
Of course, unstructured is also incorrect; the passwd and shadow files have structured records, one per line.
My mistaken memory really sells the underlying point that everything old is new again.
I think they may have been mounting parts of /etc as well. People get the idea that managing accounts for a cluster of boxes should be centralized. It's all fun and games until the network mount disappears.
Can't remember exact date, but might have been around time of SVR4 intro.
I know because I remember going "ugh", but without investigating the reason why it (shadow) was introduced :) - which was of course wrong on my part.
This is the same format used by the classic htpasswd utility.
https://en.wikipedia.org/wiki/Crypt_(C)#Traditional_DES-base...
But the article is not about this at all.
This file is the public interface of the Linux system to everyone who wants to get information about users on the system. It doesn't matter that alternative tools exist: they were already mentioned in the post you replied to. It's not the point...
As far as I know that file does not get referenced for the users in an external directory server. That's how the systems scale without needing to put the users in the file. Aren't we talking about a high number of users (and their authorization levels) when talking about scalibility in this case?
No it isn't. PAM is. The password file is only one of the places where users might be defined.
Using a terminal remains standard practice for sysadmins and devops.[1]
I believe there's some confusion in both the article and the comment between authentication and authorization. LDAP is fully equipped to handle both tasks.
[0]https://access.redhat.com/documentation/en-us/red_hat_enterp...
[1]https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-co...
This simply cannot be true. A users directory that is frequently read will be in cache. The file is also fairly simple to parse. Even on old hardware you should be able to parse thousands of users.
This file is a public interface exposed by Linux to other programs. So what if Linux caches its contents when eg. Python interpreter on launch will read this file. And it's not coming from some "fake" filesystem like procfs or sysfs. It's an actual physical file most of the time.
As long as new nodes start with the same base configuration/image this seems manageable. Simple to do with inotify, but even prior to that some simple C programs to broadcast that a change is available and listen for a change broadcast and pull the changed file is totally within the realm of a classic sysadmin's skillset.
So... the system is kind of broken to begin with, and it's kind of pointless to try to assess its performance.
Also, it would obviously make a lot of difference if you had a hundred of users with only a handful being active users, or if you had a hundred of active users. I meant active users. Running programs all the time.
NB. You might have heard about this language called Python. Upon starting the interpreter it reads /etc/passwd (because it needs to populate some "static" data in os module). Bet a bunch of similar tools do the same thing. If you have a bunch of users all running Python scripts while there are some changes to the user directory... things are going to get interesting.
I think the standard approach to atomicity is to copy, change the copy, then move that copy overwriting the original (edit: file moves are sorta atomic). Not perfect but generally works.
I agree that this approach is not good for a users directory, I'm just disagreeing that the reason it's not good is performance-related.
A whole bunch of standard functions like getpwents() are defined to read /etc/password, so that can't be changed.
In practice, `getpwent` on linux uses the nsswitch mechanism to provide return values from `getpwent`. One can probably disable using `/etc/passwd` entirely when using glibc if: all users do use `getpwent`, and you remove `files` from the `passwd` entry in `/etc/nsswitch.conf`.
We moved to LDAP a couple years later because it was a much nicer architecture to deal with overall, but performance and consistency weren't problems in practice.
After that they gave up. Even with aggressive ulimits it was too hard, and each new class was apportioned to a separate Sparc. Which was a shame because we learned an awful lot about Unix administration from users pranking each other, figuring out what they did and how they did it, protecting yourself and retaliating (some people would prank others without first protecting themselves).
Made it a lot harder chatting with people from other classes as well. For electives and humanities you weren’t always in classes with people your exact age. They could be ahead of you or behind.
This is kind of unavoidable, but you do have 32 bits to play with. Windows did it slightly better with the SID: https://learn.microsoft.com/en-us/windows-server/identity/ad...
> which makes it very difficult to contain users to things they should control
It's not the file system that's the problem here, it's that "everything is a file" is not true for a whole bunch of important stuff that you might want to apply access control to on a UNIX system. Such as the right to initiate TCP connections. This sort of thing is why containers are so popular.
NIS and LDAP do let you have a large number of users. Heck, we managed a few thousand users in /etc/password back when I was running https://www.srcf.net/ .. in 2000.
I wonder if there has ever been an attempt to really lean into, and push the limits of sticking with the "everything is a file" philosophy in this realm.
I.e. how far could you get with having special files for fine grained permissions like "right to initiate a TCP connection", and making access control management be, essentially, managing which groups a user belonged to?
But in reality a file is not a good abstraction for an internet socket. The ACLs would in essence spell out firewall rules. Because the bigger question is where can it connect to than "user" that is connecting.
That's why this is done on the level of kernel networking, where kernel knows what process is trying to open a socket and can firewall it.
Why not? A file 100,000 line file will only take a moment to scan.
LDAP is pretty old and very well supported overall. At one point I configured ldap for postfix virtual hosting. I chose LDAP rather than a database backed solution because of widespread first class support everywhere. The same directory later enabled me to use a ton of other things including SSO. You're always finding new ways to use it once you have it.
It's a great skill to have and is nowhere near as complicated as people make it out to be, including live replication.
1. system: in the context of setting up secure remote access to a Unix-like system, discuss whether relying on the passwd file and shell behavior as an effective means of authentication and access control is a good approach. What are some reasons this is not (or is) an effective approach, which should not (or should) be used on modern production systems. user: system administrator on a Unix-based network. assistant: technically, there are several reasons...
2. If you have a collection of Unix systems, can you reasonably do a certain amount of access control to your overall environment by forcing different logins to have specific administrative shells?
30+ years ago we already had services (daemons!) with their own user id, to keep them isolated from root and the human users. This post is as news as the invention of hot water.
Most ftpd need a shell whitelisted in /etc/shells .
In macOS, /etc/shells begin with this comment:
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.1. They introduce their argument as if it is solely about shell access (the conclusion also only mentions "login access control"), but then the first example/statement they make is about non-shell access (Samba, IMAP, Apache).
2. The second argument conflates authentication and authorization, and concludes that to implement shell authorization properly, your only choice is to provide multiple authentication systems.
Zero effort is spent on explaining why existing/historic shell authorization systems (such as simple DAC groups or rbash) are inadequate, and it's not clear to me what threat model they are using to arrive at their conclusion.
edit: rethinking this, I think TFA is just lacking a clear problem statement. They seem to be talking specifically about non-shell services that (ab)use the user's shell field in /etc/passwd as authorization information, and then complaining that many services did not follow suit.
spell them out or use authn/authz.
authn/authentication: user proves who they are, with username/password or otherwise
authz/authorization: based on who the user is, system determines what they are allowed to do, via group membership or otherwise
Which has been true for...... 30 years? If not longer?
Its expected that as tech grows in number of workers clutching to that middle-class life-raft that the baseline of knowledge discussed in tech spheres (like this site) will sink lower.
Fun fact: one of the commands [2] the shell implements is `personal_access_token`, so you can programmatically mint a new PAT, since you've already authenticated via your SSH key:
ssh git@gitlab.com personal_access_token someTokenName api,read_repository,read_api,read_user,read_registry 90
[0] https://about.gitlab.com/blog/2022/08/17/why-we-have-impleme...[1] https://gitlab.com/gitlab-org/gitlab-shell
[2] https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/inter...
#!/bin/bash
cmd_foo() {
printf "called foo with %s\n" "$*"
}
cmd_bar() {
printf "called bar with %s\n" "$*"
}
run_cmd_call() {
local cmd="$1"; shift
local cmd_args=("$@")
case "$cmd" in
foo) cmd_foo "${cmd_args[@]}" ;;
bar) cmd_bar "${cmd_args[@]}" ;;
*) printf "%s: unknown command\n" "$cmd" >&2
esac
}
while (( $# )); do
case "$1" in
-c)
read -ra cmd_call <<< "$2"
shift
;;
*)
printf "%s: unknown argument\n" "$1" >&2
exit 1
;;
esac
shift
done
if [[ "$cmd_call" ]]; then
run_cmd_call "${cmd_call[@]}"
else
while
printf "> "
read -ra cmd_call
do
run_cmd_call "${cmd_call[@]}"
done
fi
(then, of course,) sudo useradd -ms /path/to/custom-shell.sh userfoo
sudo -u userfoo bash -c 'mkdir ~/.ssh; printf "%s\n" "$your_pubkey" >> ~/.ssh/authorized_keys'
How would you "do more than run one of the commands that it already runs" with this from a `ssh userfoo@localhost` call?ORIG_REPLY:
> Don't forget to disable sftp in your sshd_config
Doing `strace -fp $(pgrep sshd)` then `sftp userfoo@localhost` in another terminal, I see:
$ sftp userfoo@localhost
Connection closed.
Connection closed
$
then in the `strace` output: [pid 408173] execve("/tmp/custom-shell.sh", ["custom-shell.sh", "-c", "/usr/lib/ssh/sftp-server"], 0x55c5f3bae0d0 /* 14 vars */) = 0
[pid 408173] write(1, "/usr/lib/ssh/sftp-server: unknown command\n", 42) = 42
As far as I understand, SSH's security of what a user can do is completely based on what the shell permits the user to do.> are you sure there are no directly/indirectly exploitable bugs/omissions in your script logic for invoking complex commands like git
Including a ssh server in the same executable doesn't save you from such bugs.
> and that your distributed filesystem works quickly across a few million home folders for your authorized_keys files
OpenSSH's sshd seems quite flexible in ways to authenticate users. I don't think having a home folder per user is necessary if you don't want it.
> and hopefully there's no sneaky way that an attacker can push an environment variable to break something like with LD_PRELOAD
SSH's default is to not accept the client's environment, and this shell itself provides no way to manipulate them. They can be nonexistent in the shell's interface if you don't want them.
I put the script so someone can offer some concrete way (as in show me some code) to bypass it in a way that having a custom integrated SSH server would prevent it. I'd love to see a `ssh/sftp userfoo@localhost` call that does something other than call cmd_foo, cmd_bar, or erring out.
Additionally, maybe they are using a custom server because they don't want to fork a new instance of the handler on every login.
Here is a stackoverflow topic on limiting the SSH user: https://serverfault.com/questions/152726/how-can-ssh-allowed.... They suggest a few more options, probably not relevant for a gitlab-like use-case.
> SSH's default is to not accept the client's environment
sshd accepts environment variables specified by AcceptEnv in /etc/ssh/sshd_config. By default, they are mostly related to locales.
$ LC_ALL=en_US.UTF8 ssh x date
Tue Sep 19 01:14:41 AM UTC 2023
$ LC_ALL=cs_CZ.UTF8 ssh x date
Út 19. září 2023, 01:14:46 UTCI agree bash is not the best choice security-wise, but language choice is a bit beside the point with regards to whether or not to bundle a server.
> Additionally, maybe they are using a custom server because they don't want to fork a new instance of the handler on every login.
That's very valid, though the discussion was about having a reduced attack surface from adding a custom server.
> Here is a stackoverflow topic on limiting the SSH user: https://serverfault.com/questions/152726/how-can-ssh-allowed.... They suggest a few more options, probably not relevant for a gitlab-like use-case.
Thanks for that.
> sshd accepts environment variables specified by AcceptEnv in /etc/ssh/sshd_config. By default, they are mostly related to locales.
That seems to be a Debian-specific patch. Upstream doesn't include AcceptEnv in the default config file and there seems to be no default value. Your example commands fail to set LC_ALL on my system. `ssh -o SetEnv=LC_ALL=...` also fails.
>> Don't forget to disable sftp in your sshd_config >Doing `strace -fp $(pgrep sshd)` then `sftp userfoo@localhost` in another terminal, I see: [...] >execve("/tmp/custom-shell.sh", ["custom-shell.sh", "-c", "/usr/lib/ssh/sftp-server"]
If your sshd_config had "Subsystem sftp internal-sftp" as a shipped default, then I don't think it would have gone through the user's shell. Not a major issue, but there are just so many little points to be certain are locked down
>I'd love to see a `ssh/sftp userfoo@localhost` call that does something other than call cmd_foo, cmd_bar, or erring out.
The reference to LD_PRELOAD was to hint at that (since if the attacker can get a binary on the system -- e.g. in a git repo or config file) they could change what functions bash is invoking... I'm not a wiley enough attacker, but I bet if you put something valuable behind it and put out a public challenge you'd be impressed with the opensshd vulnerabilities and other interesting features of ssh/tty/environment variables.
As you probably guessed, my comment was just listing a few of the things (today) that you're playing whack-a-mole with when it comes to making sure everything is secure. I think your "disprove me with code" approach is a great basis for a discussion.
Writing their own 'ssh server and shell' program is a different set of tradeoffs vs trying to fully lock down programs that are intended to be general-purpose... to be perfectly honest I don't think I'd want to be involved in either route, the stakes are stressfully high... but there sure is a lot less code to audit and test in writing your own ssh+shell than there is trying to secure and keep up-to-date sshd, pam, bash, etc. (especially since they'll be adding features that you explicitly do not want for your purposes)
>> As far as I understand, SSH's security of what a user can do is completely based on what the shell permits the user to do.
I was mistaken in believing that sshd was designed with the user being limited to their specific shell as their sole system interface (as their only way to get the system to do things) as a core design principle. With that sort of funnel, I thought a custom shell would suffice.
> If your sshd_config had "Subsystem sftp internal-sftp" as a shipped default, then I don't think it would have gone through the user's shell.
It's curious how much you can do on a secure "shell" server without involving shells at all.
You know, what's particularly interesting is that strace shows sshd does `custom-shell.sh -c /usr/lib/ssh/sftp-server` instead of `/usr/lib/ssh/sftp-server` directly. That feels like it has no other purpose than to adhere to the principle I believed it was following, but it doesn't apply it for everything. I think it should be possible wrap stuff like `-L`, `-R`, `-D`, `-J` et al. in their own shell calls to another executable, but they don't... Wonder what's the story there.
> The reference to LD_PRELOAD was to hint at that (since if the attacker can get a binary on the system -- e.g. in a git repo or config file) they could change what functions bash is invoking
I had mentioned that the client's environment is not accepted by sshd by default, so I did address this point in my previous comment. Maybe what you're getting at here is that the shell itself may allow modifying the environment through its own logic? But you're still going to have that issue regardless of whether you use sshd or a custom integrated ssh server.
> Writing their own 'ssh server and shell' program is a different set of tradeoffs vs trying to fully lock down programs that are intended to be general-purpose
Indeed. If the hassle to lock-down is large enough, it can be better to opt for simpler, more easily verifiable software. Tradeoffs aplenty, and one such is that you may end up adopting less mature software, by way of the chosen dependencies and your own code, however that server is implemented. That can be worth it.
It will lock down the shell to not allow cd, setting envvars, launching commands outside working directory and a lot more.
If you look at the full list of things they disable you realize how many obscure holes are available you never would have thought about.
Not that I would ever trust it enough to expose on a shared box. Likewise with a tailor made shellscript. I’d take a bespoke server in go any day.
> First, you almost certainly operate a variety of services that normally only use Unix logins as a source of (password) authentication and perhaps a UID to operate as, and ignore the login's shell. This is the common pattern of Samba, IMAP servers, Apache HTTP Basic Authentication, and so on.
So you have a user on your server nginx:x:100:101:nginx:/var/lib/nginx:/sbin/nologin
And your also running samba network shares, you point your samba client at your server and use user nginx and inexplicably the password you also set for that user to login? This a service is using etc/shadow basses authentication but not sending the message in /etc/nologin .. presumably samba won’t work really in this case..
>In some cases you may be able to teach these services to look at the login's shell and do special things, but some of them are sealed black boxes and even the ones that can be changed require you to go out of your way. If you forget one, it fails open (allowing access to people with an administrative shell that should lock them out
Is this talking about setting up applications..like a web server, that would give a http access to a uses home for, And having these services authenticate with the servers etc/shadow or configured Pam providers, and also then check out the shell in /etc/password to gracefully handle access management and error messages?
One is what I'd call a shell-server. On a shell-server, I have a bunch of accounts for users, and there are services supplied for these users. There will be /home/tetha, and /home/tetha/share and /home/tetha/http. And then you have some SMB sharing /home/*/share and you login there with your password, Apache serves /home/*/http for the intranet and so on. This is a very common setup at universities, for example.
The other thing is what I'd call an application server or a service server (but that name sucks). Here, you have a system and the main purpose of the system is to serve a web page via nginx, or be a postgres node and such.
These service-systems tend to be both more controlled, but also simpler. You need to grant a rather small, very known set of users access to these - 10 - 30 usually. And, honestly, these service-level systems tend to have very streamlined permissions, because realistically, shell-access is enough attack profile to be considered root access unless you are very diligent.
Shell-servers however are very, very complex to handle. One big shell-server can be overall more complex than many infrastructures around in total.
Meanwhile, these days, it seems like the only user ever running anything is docker, and “access control” has an entirely different set of meanings.
For the various kind of forwarding SSH supports, they all can be disabled via sshd_config.
"One of these services is SSH itself, since you can generally initiate SSH sessions and ask for port forwarding or other features that don't cause SSH to run the login shell"
But, even that sort of falls apart because we also had inetd in the "old days", which spawned lots of different things as different users without invoking a login shell.
Generally, the article seems to be lamenting that not everything is gated by userids and groups anymore. That's true, but it doesn't seem recent to me. Aside from inetd, I could (and did) massage kermit (or uucp, etc) into being a multi-service gateway in the 1980's.
I suppose it's somewhat correct in the idea that figuring how any particular service limits rights is now very complicated. You have the old familiar stuff (users, groups). But now you also have virtual machines, containers, namespaces, capabilities. And things like seccomp and apparmor. Then, various sandboxing schemes within utilities, languages and frameworks or OS facilities like ebpf.
Besides that, I don’t know.
To bypass shell restrictions in the past, but I'm not sure if that will work with your example.
`ssh -t user@remote /bin/sh asdf` would execute `/bin/false -c "/bin/sh asdf"` on the remote.
sftp share@ohblog.net (no pw)
# grep share /etc/passwd /etc/shadow
/etc/passwd:share:x:5002:5000::/data/sftp/share:/bin/false
/etc/shadow:share::19614::::::
The partially redacted /etc/ssh/sshd_config is copied to /pub/ in the SFTP account.If you can bypass the restriction please do share how it was done. I don't offer bug bounties but I think people would find it interesting. OS is Alpine Linux. All CPU mitigations are disabled in the VM. No MAC As in no SElinux or AppArmor. I won't complain, just pretty please don't DDoS the server or anything that would make that VPS do work.
Feel free to also tinker with the web and voice chat server on that node.
Match User anonymous
PasswordAuthentication yes
PermitEmptyPasswords yes
DisableForwarding yes
PermitTTY no
and possibly ForceCommand and ChrootDirectory depending on how you're sandboxing anonymous and to what; plus a restricted login shell (the above anonymous user of mine has gotsh, got's version of git-shell).But I vaguely remember that in the past it may have been anything, including SHELL.
Firstly it only really worked if you were all sharing the same machine with remote terminals, which most people don't do anymore. Second NFS happened when if you configured it badly you could just pretend you were any user you liked.
I'm assuming this is part of the reason why kerberos was invented. Basically the only practical way to tie down a network of machines was to make sure that authentication was done with LDAP and Kerberos. LDAP did the name, UID/GID and user metadata and kerberos the authentication. You could then use that ticket to gain access to other things (yes, even over HTTP, NFS or SSH)
Nowadays you'd use active directory, which is LDAP+Kerberos, but with a nice expensive gui.
/etc/passwd(or shadow) died _years_ ago, It was dodgy even in the 90s, let alone now. Its fine for single user machines, but not networked.
That went away a long, long time ago; the question of "which system am i authenticating myself to" was often already too complicated for that way back when when "shadow passwords" were a new idea.
Maybe next we will hear that Hammers are not viable screwdrivers any more because, you know, that is also probably something everybody already knows.
Using scanning electron microscopy (SEM), we characterized the microstructure of hamster claws, revealing a keratinous composition with intricate surface patterns. Nano-indentation techniques were employed to determine the hardness and resilience of the claws. Their sharpness was quantitatively assessed using a sharpness index, which considered both geometric and material properties.
To test the potential application as micro-screwdrivers, we designed a set of experiments where hamster claws were used to engage with micro-screws commonly found in electronics and precision instruments. The results indicated that while hamster claws can fit into the grooves of certain micro-screws, the torque they can generate is limited due to their flexibility and the lack of a proper grip mechanism.
A Unix account is a viable access control mechanism. If you create one, you give its human user access to do everything that the Unix user can do. This can be very useful.
But others want to give humans users more restricted access than their corresponding Unix account. This is futile, since the Unix account is the basic unit of access control on a Unix or Unix-like system. The author is correct that if you want to do this then you must create a sandbox. General tools won't do, because they're not designed for it, and/or are generally swimming against the tide.
If your idea of “Unix” is Linux kernel with Busybox and dropbear, it makes sense. I think.
> Today, the only two measures of login access control that really work in a general environment are either scrambling the login's password (and disable any SSH authorized keys) or excluding the login entirely from your various authentication data sources (your LDAP servers, your Apache htpasswd files, and so on). It's a pity that changing people's shells is no longer enough (it was both easy and convenient), but that's how the environment has evolved.
This literally makes no sense. Scrambling a login password is not an access control mechanism. Excluding "a login" (a what?) from an authentication data source... the hell does this mean? You mean disabling a user account?
The last part, "changing a user's shell", makes a little sense, as you used to be able to prevent a user from logging in by changing their shell to "/bin/false" or something, but that isn't disabling authentication, that's just breaking the shell. Authentication still works if the shell has changed, it just can't execute the shell after you authenticate.
The proper way of disabling the account is to set the "disabled account" bit in the shadow or password file. But that's just one authentication mechanism (NSS). There is no universal authentication mechanism, so for any other given authentication mechanism, you need to disable it however that given method allows you.
Scrambling the password works as a deauthorization mechanism solely because you strip the user of the ability to authenticate. This wouldn't clear authorized_keys, though; services that needed to implement new authentication mechanisms generally did not bother extending /etc/shadow or NSS in an obvious way everyone agreed upon.
Changing the login shell used to work because Unix used to be used solely through the medium of /bin/sh. This, however, conflates two different signals:
- Who should be allowed to start an interactive session on this machine?
- What kind of shell does this user prefer to use?
We pretend that disabled users just really love using this one particular shell that immediately kicks them out of their login session.
The only bulletproof way to deauthorize a user is to unperson them - delete the account. Except if you do this then their old files still sit there on the disk with their user ID. If you reuse the user ID then the new user gains authorization to the old user's files; so you have to keep track of unpersons to avoid reusing their IDs or meticulously reassign their files to a dedicated cleanup user.
Incorrect. Nearly every service in a Unix computer has its own authorization mechanisms, there is no blanket authorization over an entire host.
The login service has a "nologin" and "securetty" files. Sudo has its sudoers file. RSH has the .rhosts file. FTP daemons have their own authorization logic. NFS authorization options could override local filesystem permissions. Filesystem permissions defined the authorization for device files, but network services (such as CUPS) would add their own authorization mechanisms. Etc, etc, etc.
The difference between authentication and authorization has been apparent since time-sharing systems were invented. The operators were authorized to perform different operations than the bog-standard users. There hasn't been a time since the 60's that everyone was authorized the same just because they were authenticated.
> Scrambling the password works as a deauthorization mechanism solely because you strip the user of the ability to authenticate.
Doesn't work. If you're using SSH key authentication you can skip password auth. With RSH, password auth isn't required if you're coming from a trusted host defined in a .rhosts file.
> The only bulletproof way to deauthorize a user is to unperson them - delete the account.
That doesn't always work either. There may be more than one authentication system, and they may be configured to simply skip to the next authentication method if a user account is not found. So you would have to delete the account from every authentication system connected.
You have to use the prescribed deactivation method for every authentication system connected, otherwise the first auth method may skip the deactivated user but the second system would pick up its own user with that name/ID.