Gentoo Archives: gentoo-dev

From: Anthony Gorecki <agorecki@××××××××××.com>
To: gentoo-dev@l.g.o
Subject: [gentoo-dev] The results of an evening of Apache and PAM debugging
Date: Tue, 14 Jun 2005 11:20:44
1 This message is fairly long, however I've decided to pass it along in the hope
2 that someone may find it useful as a reference source. It was originally
3 intended to be a problem description and debugging request for the gnomes to
4 ponder over.
7 I've recently encountered an interesting debugging paradox. Upon deploying
8 Subversion with an Apache-based server, I discovered an interesting issue
9 with PAM that seems to be intent on defying explanation:
11 I have a repository that's accessible through <>, with
12 the repository root set at location / (using Subversion 1.2.0, which has a
13 fix for the cache bug that prevented repositories from being located at the
14 root of a web address). The server is setup to allow read-only access to the
15 repository through unencrypted HTTP connections, while write operations must
16 use HTTPS (TLSv1, AES256).
18 When accessing the repository through HTTPS, Apache dispatches an
19 authorization request to mod_auth_pam and PAM, which in turn passes the
20 request off as follows:
22 The username and password authentication (auth) process is passed to pam_krb5
23 and the accompanying KDC. This process works flawlessly on every service,
24 including Apache's requests. The logs indicate successful logins when
25 submitting a username and password via web request.
27 The account management (account) process is passed to pam_unix, which then
28 does a bit of nsswitch magic to tie everything together. In this context,
29 only network-based user accounts are permitted, therefore nsswitch uses the
30 NSVS (MySQL backend) service to retrieve all of the information. For example,
31 calls to getspnam are handled as follows:
33 getspnam \
35 '%1$s','x',1,0,99999,7,0,DATEDIFF(expiration_date,'1970-01-01'),0 \
36 FROM users \
37 WHERE username='%1$s' \
38 LIMIT 1
40 Herein lies the problem. During the authorization process, PAM will fail
41 during the account stage with the error: "PAM: user 'agorecki' - invalid
42 account: Authentication service cannot retrieve authentication info."
44 For whatever reason, the debug and audit flags in the pam_unix module are not
45 functional. As a result, I extracted the information I needed directly from
46 the source code, and found the error location to be:
48 ./Linux-PAM-0.78/modules/pam_unix/pam_unix_acct.c:
49 127 spent = _pammodutil_getspnam (pamh, uname);
50 128 else
51 129 return PAM_SUCCESS;
52 130
53 131 if (!spent)
54 132 if (on(UNIX_BROKEN_SHADOW,ctrl))
55 133 return PAM_SUCCESS;
56 134
57 135 if (!spent)
58 136 return PAM_AUTHINFO_UNAVAIL; /* Couldn't get username from
59 shadow */
61 The call on line 127 takes place, and the error originates on line 136.
63 For the purposes of debugging, I've removed all chroot restrictions from
64 Apache and have given it complete access to the filesystem. The Apache
65 Subversion interface works through the unencrypted connections, which do not
66 require authentication.
68 Hours of Google searching turned up nothing of use; what I don't understand is
69 how Apache can fail to retrieve the shadow information when it's accessible
70 by any unprivileged--
72 While writing the above, it occurred to me to run a final check on the debug
73 output of nsvsd, which produced:
75 run_query: query: SELECT 'agorecki','x',user_id,group_id,CONCAT(first_name,'
76 ',last_name),CONCAT('/home/',username),'/bin/bash' FROM users WHERE
77 username='agorecki' AND group_id IS NOT NULL LIMIT 1
78 send_response: sending 120-byte response
79 main_loop: pid 12314 unauthorized for type 8
80 main_loop: pid 12314 unauthorized for type 8
82 The obligatory check of the code found:
84 ./nsvs/src/nsvsd/nsvsd.c:
85 449 /*
86 450 * Don't allow shadow queries to non-root users
87 451 * It is CRITICAL that this code occurs AFTER reading the
88 key
89 452 * to avoid clientside sigpipe issues
90 453 */
91 454 if ((req.type == GETSPBYNAME || req.type == GETSP) &&
92 caller.uid != 0)
93 455 {
94 456 nsvs_log (LOG_DEBUG, "%s: pid %d unauthorized for type
95 %d",
96 457 __FUNCTION__,, req.type);
99 Having non-root users access the shadow-emulated MySQL information is of no
100 consequence to me as I don't use that system for password storage, however
101 I'd prefer not to start patching software to work around the above
102 restriction.
104 Having wasted forty-five minutes typing the above only to find the cause of
105 the problem that was illuding me, I'm left with the next problem:
107 My network authentication scheme cannot solely rely on Kerberos' built-in
108 account expiration and suspension system, because a user could still login
109 through SSH using a certificate. As a result, I've tied the entire system's
110 account expiration process into the emulated shadow suite so that I can
111 expire all access simply by changing the expiration date of the account in
112 the MySQL database. Consequently, I can't use the broken_shadow option of
113 pam_unix to get around the problem that way, otherwise I wouldn't be able to
114 keep someone from modifying the repository without deleting their account or
115 changing the account's password.
117 Therefore, the only viable option would seem to be to use mod_auth_external
118 and an authentication binary to serve as an intermediary between PAM and
119 Apache. Unfortunately, that process would be considerably slower than calling
120 the PAM functions directly or through a library. I also don't see a SASL
121 module for a Apache.
123 Does anyone have a suggestion that would fit the requirements, other than
124 using mod_auth_external, coupled with an authentication program? An interface
125 to Cyrus-SASL would be ideal since I already have saslauthd running for
126 Postfix.
128 In addition, does anyone have an idea as to what authentication program could
129 be used as the aforementioned intermediary?
131 Thanks.
134 --
135 Anthony Gorecki
136 Ectro-Linux Foundation