A key difference is that the file system contents is preprocessed into content-addressable storage (somewhat similar to the format in a .git folder). Also a number of features and optimizations to make it work well as a shared software area, which is characterized by many small, often memory-mapped files and a meta-data heavy access pattern.
What not to do: host “self documenting” API docs which are only accessible from an API endpoint themself and contain zero context or examples, only terse names and descriptions.
PAM is crusty and has a bad architecture. The fact that it's written in C, and is linked into another program as a library makes it impossible to fully isolate it from its host application, and exposes it to a myriad possible exploit points.
Even wrapper binaries are not a great idea because of how UNIX works.
fork() + exec() means the executed binary inherits a lot of state from the caller. Open files, signals, environment variables, chroot, mlock, resource limits, seccomp... there's a myriad of mechanisms that an executed binary can be exposed to, and even if it somehow perfectly takes all of them into account and defends itself against any possible malicious manipulation, the next kernel version could add a new one.
That's why I think a sane, modern version of PAM should be a service and only communicate via a UNIX socket. That way you vastly reduce the attack surface, and allow locking up the PAM bits into their own, well defended box.
The calling convention is C, but you can write PAM in any language.
"and is linked into another program as a library makes it impossible to fully isolate it from its host application"
Huh? You can never isolate the client side code. You will always have something in your app.
"I think a sane, modern version of PAM should be a service and only communicate via a UNIX socket."
So, write a module that talks to a socket. That's how like half of the PAM modules already operate. You will always have to have code in the application to talk to whatever oracle you're using. What you're describing here isn't any different from how PAM already works.
> Huh? You can never isolate the client side code. You will always have something in your app.
Yes, and that "something" can be reduced to reads and writes to a socket.
> So, write a module that talks to a socket. That's how like half of the PAM modules already operate.
I mean move all of PAM to a service. So for instance currently chsh is a setuid application because it needs to be able to write to /etc/passwd. This is a requirement because the way it works is that it links to libpam, which will load a module, which will write to /etc/passwd, all inside the 'chsh' program.
My suggestion would result in chsh becoming a completely unprivileged application that only deals with interfacing with the user, then passes the action to pamd, which would run with the required privileges.
"Yes, and that "something" can be reduced to reads and writes to a socket."
Yes, and as I said that is already what most PAM modules do. That is how most things work today.
"I mean move all of PAM to a service."
I think you don't understand what PAM is.
"which will load a module, which will write to /etc/passwd"
No, this isn't how PAM works at all. PAM modules don't write to /etc/password. They just authenticate. They do not (necessarily) need root privileges.
"My suggestion would result in chsh becoming a completely unprivileged application that only deals with interfacing with the user, then passes the action to pamd, which would run with the required privileges. "
You have the way PAM and chsh works entirely backwards. Here's how it actually works:
1) chsh runs as root only because chsh itself needs to modify system files. This has nothing to do with PAM, and is optional (see below)
2) chsh calls pam_auth("chsh",...) to authenticate the current user, if the current user isn't really root. This is PAM's ONLY involvement.
3) chsh then directly edits /etc/passwd itself[1]. Totally unrelated to PAM. If you're on a system with directory services instead of local files, then chsh needs to change those directory services instead (and, as such, doesn't need to run as root - though it will need to authenticate to the directory service)
In summary, your ideas aren't bad - it's just that they're how things already work. Most PAM modules are already just talking to a socket somewhere. They don't do the other things you seem to think they do.
For completeness it's worth mentioning that chsh calls into pam with pam_acct_mgmt and pam_open_session/pam_close_session after it's authenticated the user with pam_auth.
I'm being serious, as exactly what you're describing sounds an awful lot like their micro-kernel approach. At least as of the last time I looked into it.
This sort of already exists in the form of sssd. In particular, pam_ssd.so connects to sssd's PAM responder & acts as a dumb client library to the authentication logic within the sssd process.
Back in 2013 I had an interview with a large company whose game consoles are very rare to find in stores currently where the guy wanted me to recite JS syntax over the phone. He'd tell me I was incorrect if I didn't say "semi-colon". I wish I was making this up. Hoping they've modified their process a bit. :)
You send them a full on mini-vim implementation in Rust that uses ropes and then they just look at you disapprovingly because you didn't just tie together a dozen npm packages.
If you attempt to copy or paste anything during the interview process you will be immediately disqualified from this and all future employment opportunities.
No, this was a bank who said they would stop offering loans for gas/diesel cars because of their corporate stand on environmental issues. It's only one bank for now.
It does not scale.