Bug 1215 - sshd requires entry from getpwnam for PAM accounts
Summary: sshd requires entry from getpwnam for PAM accounts
Status: NEW
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: PAM support (show other bugs)
Version: 4.3p2
Hardware: Other All
: P2 enhancement
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-08-10 00:27 EST by Darren Tucker
Modified: 2015-08-22 01:58 EST (History)
9 users (show)

See Also:


Attachments
attempt to make sshd handle when getpwnam doesn't know about the user but PAM does (5.51 KB, patch)
2006-08-10 00:38 EST, Darren Tucker
no flags Details | Diff
make sshd handle when getpwnam doesn't know about the user but PAM does (6.34 KB, patch)
2006-08-10 08:01 EST, Darren Tucker
no flags Details | Diff
vs pam_tacplus v1.2.9 http://ipsec.pl/pubs/pam_tacplus.php (425 bytes, patch)
2007-05-19 11:24 EST, Jesse Zbikowski
no flags Details | Diff
Remember the mapped username and restore it (1.95 KB, patch)
2007-05-19 11:26 EST, Jesse Zbikowski
no flags Details | Diff
PermitPAMUserChange: runtime option that checks and handles PAM changing the username (5.65 KB, patch)
2007-05-30 02:38 EST, James R. Leu
no flags Details | Diff
Authorize with PAM virtual username, not local username (1.56 KB, patch)
2007-06-02 11:23 EST, Jesse Zbikowski
no flags Details | Diff
Debug output of accounting failure (1.22 KB, text/plain)
2008-10-15 16:19 EST, Aaron Smith
no flags Details
add needed pwcopy call in sshpam_check_userchanged (510 bytes, patch)
2013-03-13 07:20 EST, Jim Basney
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Darren Tucker 2006-08-10 00:27:11 EST
sshd requires that a user exists in /etc/passwd or similar (eg nss).

With some changes, it should be possible to track PAM_USER as it changes and adjust the authctxt accordingly.

I'm not sure that this is a good idea, but I wanted to investigate what's involved.
Comment 1 Darren Tucker 2006-08-10 00:38:34 EST
Created attachment 1170 [details]
attempt to make sshd handle when getpwnam doesn't know about the user but PAM does

Warning: this is not production-quality code.  I wrote it based on hacking one of my test modules to behave as I think the RADIUS/TACACS PAM modules would.  It leaks like a sieve and is barely tested.

It would be interesting to know if it works, though.
Comment 2 Darren Tucker 2006-08-10 08:01:22 EST
Created attachment 1171 [details]
make sshd handle when getpwnam doesn't know about the user but PAM does

Updated patch (against 4.3p2).  Leaks less (but still leaks) and copies passwd struct when PAM changes the username (the old one should have, but didn't).
Comment 3 Asif Iqbal 2006-10-02 04:00:41 EST
(In reply to comment #2)
> Created an attachment (id=1171) [edit]
> make sshd handle when getpwnam doesn't know about the user but PAM does
> 
> Updated patch (against 4.3p2).  Leaks less (but still leaks) and copies
> passwd struct when PAM changes the username (the old one should have,
> but didn't).
> 

Is it included in 4.4p1? If yes, is that mean user can ssh with pam auth success even if s/he do not have a local account?
Comment 4 Darren Tucker 2006-10-02 10:14:00 EST
(In reply to comment #3)
> Is it included in 4.4p1?

No, it's not in 4.4p1.  I'm still not convinced it's a good idea and it has not been tested or reviewed much.

> If yes, is that mean user can ssh with pam
> auth success even if s/he do not have a local account?

If you apply the patch then yes, you should be able to log into a system using a username that does not exist in the local passwd file (or wherever's listed in nsswitch.conf) provided that PAM accepts the username, permits the login and maps PAM_USER to a name that does exist before the end of the authentication.
Comment 5 Markus Mueller 2006-12-09 00:58:21 EST
I posted a workaround via NSS about this problem to Bug #1269, this sould also be a hotfix the problem in this bug #1215. Maybe it is useful for anybody. The direct link to the attachment is http://bugzilla.mindrot.org/attachment.cgi?id=1219
Comment 6 Markus Mueller 2006-12-09 01:00:29 EST
For Infos about this hotfix, how to compile and use it, see http://bugzilla.mindrot.org/show_bug.cgi?id=1269#c3
Comment 7 Jesse Zbikowski 2007-05-19 11:21:19 EST
Darren, thanks for this patch.  I am using it to authenticate TACACS+ users using pam_tacplus.  However I can't get it to do authorization in a sane way.

The user mapping is done immediately after authentication.  This means I can't use TACACS+ for authorization.  For my experiment, I hacked pam_tacplus to set the PAM username to "op", which is a valid Unix user, following authentication.  When ssh then makes the authorization request, it tries to authorize "op", which TACACS+ doesn't know about -- rather than the original TACACS+ user.  /etc/pam.d/ssh then falls back to system-auth (in Fedora 5, this is basically pam_unix.so passwd-based authorization).  So the effect is, all authenticated TACACS+ users get authorized, even if they don't have the desired service/protocol a/v pairs.  I believe the user mapping should be performed as the last step, after pam_acct_mgmt() (i.e. authorization) and pam_open_session() (i.e. accounting).

Worse: after authorizing "op" via system-auth, the PAM username gets set to "root".  Thus pam_open_session() is sending accounting data for "root" to the TACACS+ server, and the user gets a root shell.  Presumably the username gets set to "root" by pam_unix.so.

To work around this, I patched pam-auth.c to store the mapped username in an environment variable PAM_MAP_USER.  Then after accounting, we restore the mapped username.  This works around the "root shell" problem, though not the inability to authorize with TACACS+.  Clearly what I'm doing here is awful, but it illustrates the problem.  I did try to change pam-auth.c to defer user-mapping until after we open the accounting session, but this seems to be non-trivial.  Please advise on the best approach from here.

Here is the debug output for sshd without my hack:

debug1: auth2_challenge: user=tacuser devs=
debug1: kbdint_alloc: devices 'pam'
debug1: auth2_challenge_start: trying authentication method 'pam'
Postponed keyboard-interactive for tacuser from 192.168.0.104 port 37235 ssh2
debug1: sshpam_check_userchanged
debug1: PAM: user mapped from 'tacuser' to 'op'
debug1: PAM: user 'op' now valid
debug1: do_pam_account: called
debug1: sshpam_check_userchanged
debug1: PAM: got username 'root' from thread
Comment 8 Jesse Zbikowski 2007-05-19 11:24:06 EST
Created attachment 1292 [details]
vs pam_tacplus v1.2.9 http://ipsec.pl/pubs/pam_tacplus.php
Comment 9 Jesse Zbikowski 2007-05-19 11:26:35 EST
Created attachment 1293 [details]
Remember the mapped username and restore it

This is applied on top of the patch 1171 above.
Comment 10 James R. Leu 2007-05-30 02:38:44 EST
Created attachment 1298 [details]
PermitPAMUserChange: runtime option that checks and handles PAM changing the username

Works for PasswordAuthentication, but not ChallengeResponseAuthentication
Comment 11 Jesse Zbikowski 2007-06-02 11:23:30 EST
Created attachment 1300 [details]
Authorize with PAM virtual username, not local username

Thanks James!  This indeed gets around the "mapping-to-root" problem
without my hack in Comment 9.

I still believe the authorization request needs send the virtual (PAM)
username, NOT the local username.  Otherwise I see no way to give
different privileges to different PAM users, or to allow for a TACACS+
server which manages multiple independent systems.

My attached patch temporarily restores the virtual username during
authorization.  The idea is that the PAM module should map to
e.g. "nobody" during authentication, then map to an appropriate user
(perhaps based on TACACS+ AV pairs) during authorization: "op",
"admin", "guest", etc.  This patch is vs. 4.3p2 with Darren's and
James' patches applied.  It saves the usernames during
sshpam_handle_user_change() and swaps them during do_pam_account().

Please let me know if I am on the right track with this.  I think a
much better design would be not to do any username mapping or
valid-user checking until *after* the accounting, but I haven't been
able to make that work yet.
Comment 12 Aaron Smith 2008-10-15 16:19:59 EST
Created attachment 1574 [details]
Debug output of accounting failure

I am trying to use patches 1171, 1298, and 1300 in conjunction with the pam_radius library.  Authentication works fine, but the final call to getpwnam() fails with debug output "PAM: completed authentication but PAM account invalid".  Debug is attached.

I have manually applied the patches to openssh-5.1p1, but have not tried with any 4.x version.  Is this due to changes to ssh 5.x, or am I missing something here?  Thanks for any help...
Comment 13 Matt Joyce 2012-07-21 04:30:51 EST
So can we fix this?

It's been around causing damage for several years.  And technically openssh is responsible for this bug breaking a ton of stuff for no particularly good reason.

So...  I've seen probably 20 or so proposed patches to address the issue here.  Can we just select one?  Or allow people to selectively remove the pwnam check in sshd_config?

This is very annoying.  And the reality is working around this or patching ssh willy nilly is not an acceptable way for engineering infrastructure.
Comment 14 Damien Miller 2012-07-23 18:10:14 EST
I never seen the point in duplicating functionality already in nsswitch and similar mechanisms just for PAM.
Comment 15 Matt Joyce 2012-07-24 03:42:00 EST
(In reply to comment #14)
> I never seen the point in duplicating functionality already in
> nsswitch and similar mechanisms just for PAM.

Well not everyone has a full posix data set in their authentication / identity management backend.  Also not all of them have an NSS module.

I direct your attention to the 3000 some odd emails on google pertaining to the pam module for radius and people who can no longer use it without obscene work arounds.

In my case I am authenticating against a REST API in a cloud environment so I can pass cloud API credentials to a VM for tight integration to that API.  I feel like that sort of authentication is pretty likely to occur in a number of areas.  And making the solution portable has values.

Requiring patched ssh or an nss module that all but breaks the hell out of getpwnam is pretty much terrible.

The way I see it OpenSSH broke a bunch of stuff 6 years ago has received chronic complaints and has basically ignored it.  And that's not very cool or responsible.  This fix should never have gone in the way it was written, and that speaks volumes as to the level of quality control currently being held to.
Comment 16 Tomas Mraz 2012-07-24 04:05:03 EST
Are you really talking about this bug? This newer worked with OpenSSH afaik.
Comment 17 Matt Joyce 2012-07-24 07:31:32 EST
I am talking about this bug.  It is still an issue.
Comment 18 Damien Miller 2012-07-24 10:50:12 EST
It didn't break six years ago. It never worked from day one (i.e. 1999). This was largely by design, since I've never liked PAM's adding an unnecessary layer of username indirection when better alternatives (NSS) exist.
Comment 19 Matt Joyce 2012-07-24 10:55:06 EST
NSS is not a 'better alternative'.

It's not actually an alternative at all.  It is in fact some other thing entirely that is not PAM or OpenSSH. A thing that has no bearing on the authentication chain as far as openssh is concerned.
Comment 20 Jim Basney 2013-03-13 07:20:23 EST
Created attachment 2228 [details]
add needed pwcopy call in sshpam_check_userchanged

Attachment 1171 [details] should do

  sshpam_authctxt->pw = pwcopy(pw);

instead of

  sshpam_authctxt->pw = pw;

to avoid potential trouble in later getpwnam(sshpam_authctxt->pw->pw_name) and pwfree(sshpam_authctxt->pw) calls.
Comment 21 Brad Huntting 2015-08-22 01:58:36 EST
In most environments users control their own workstations and servers, and root on these machines is not to be trusted any more than the users who own them. And most AAA databases (RADIUS, LDAP, etc) are administered by someone other than the user/owner of the workstation using them.

In some cases, the AAA database may be administered by a service provider, with users as customers. In such an environment it's not unreasonable to expect that customer data (name, phone number, homedir, etc) should not be shared with other customers.

In other cases, the location of the users homedir may not even be knowable before the user is authentication.

In these, and many other situations, it is simply presumptuous to suppose that nss passwd information for every user would be available to every other user everywhere.

I do agree that PAM changing the username during authentication is a bad idea, I think it would be better to pass user info to an nss_radius.so module via some runtime (/var/run/radius_users.db) database.

However, asking a user to authenticate before giving out their personal information is not unreasonable requirement. This needs to be a configurable option.