Modified lines:  29, 30, 81, 182, 188, 190, 194, 197, 205, 220, 221, 222, 223, 224, 225, 227, 339, 347, 367, 375, 381, 383, 390, 391, 392, 393, 394, 485, 486, 493
Added line:  31, 32, 33, 53, 54, 91, 92, 98, 139, 140, 141, 144, 150, 202, 203, 204, 205, 206, 207, 210, 211, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 379, 380, 395
Removed line:  206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 487, 494, 495, 496, 497, 498, 499, 500
Generated by diff2html
© Yves Bailly, MandrakeSoft S.A. 2001
diff2html is licensed under the GNU GPL.

  mod_auth_pam.c     mod_auth_pam2.c
  503 lines
14947 bytes
Last modified : Fri Jul 12 08:22:25 2002

    420 lines
12997 bytes
Last modified : Fri Jul 12 08:22:26 2002

1 /* Copyright (c) 2000 Ingo Luetkebohle, All rights reserved.   1 /* Copyright (c) 2000 Ingo Luetkebohle, All rights reserved.
2  *   2  *
3  * Redistribution and use in source and binary forms, with or without   3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions   4  * modification, are permitted provided that the following conditions
5  * are met:   5  * are met:
6  *   6  *
7  * 1. Redistributions of source code must retain the above copyright   7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.   8  * notice, this list of conditions and the following disclaimer.
9  *   9  *
10  * 2. Redistributions in binary form must reproduce the above copyright   10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in   11  * notice, this list of conditions and the following disclaimer in
12  * the documentation and/or other materials provided with the   12  * the documentation and/or other materials provided with the
13  * distribution.   13  * distribution.
14  *   14  *
15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED   15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
16  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES   16  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CODE CONTRIBUTORS   18  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CODE CONTRIBUTORS
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,   19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
20  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   20  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;   21  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF   22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT   24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.   26  * SUCH DAMAGE.
27  */   27  */
28   28
29 /*   29 /* $Id$
30  * v 1.1 from 07. July 2002   30  * mod_auth_pam for apache 2.0
      31  *
      32  * Based on: v 1.1 from 07. July 2002 (for apache 1.3)
      33  *
31  *   34  *
32  * mod_auth_pam:   35  * mod_auth_pam:
33  * basic authentication against pluggable authentication module lib   36  * basic authentication against pluggable authentication module lib
34  *   37  *
35  * The authoritative homepage for this module is at   38  * The authoritative homepage for this module is at
36  * http://pam.sourceforge.net/   39  * http://pam.sourceforge.net/
37  *   40  *
38  * For assistance and support, contact the pam-list   41  * For assistance and support, contact the pam-list
39  * https://listman.redhat.com/mailman/listinfo/pam-list   42  * https://listman.redhat.com/mailman/listinfo/pam-list
40  * or the Help forum on SourceForge.   43  * or the Help forum on SourceForge.
41  *   44  *
42  * Written by Ingo Luetkebohle, based upon mod_auth.c, with contributions   45  * Written by Ingo Luetkebohle, based upon mod_auth.c, with contributions
43  * from Fredrik Ohrn (group performance), Dirk-Willem van Gulik (licensing   46  * from Fredrik Ohrn (group performance), Dirk-Willem van Gulik (licensing
44  * consultation) and Michael Johnson (example group implementation).   47  * consultation) and Michael Johnson (example group implementation).
45  *   48  *
46  * Thanks to Andrew Morgan and the rest of the Linux-PAM developers who   49  * Thanks to Andrew Morgan and the rest of the Linux-PAM developers who
47  * provided invaluable development help and ideas.   50  * provided invaluable development help and ideas.
48  *   51  *
49  * Changes:   52  * Changes:
      53  * 09-Jul-02: Ported to apache 2.02 (Dirk-Willem van Gulik,
      54  * <dirkx@covalent.net>).
50  * 07-Jul-02: License changed to allow redistribution   55  * 07-Jul-02: License changed to allow redistribution
51  * Performance improvement for group lookup   56  * Performance improvement for group lookup
52 (many thanks to Fredrik Ohrn for the patch)   57 (many thanks to Fredrik Ohrn for the patch)
53  * 06-Dec-99: Special casing for Solaris 2.6 added   58  * 06-Dec-99: Special casing for Solaris 2.6 added
54  * Added versioning message to headers   59  * Added versioning message to headers
55  * 14-Feb-99: Cleaned up the configuration directives and named them   60  * 14-Feb-99: Cleaned up the configuration directives and named them
56  * in a more straightforward way   61  * in a more straightforward way
57  *   62  *
58  * incorporated getugroups patch from Klaus Wissmann <kw@aw.net>   63  * incorporated getugroups patch from Klaus Wissmann <kw@aw.net>
59  * to look up supplementary groups from /etc/group   64  * to look up supplementary groups from /etc/group
60  *   65  *
61  * 22-Jan-99: incorporated changes from Pavel Kankovsky <kan@dcit.cz>   66  * 22-Jan-99: incorporated changes from Pavel Kankovsky <kan@dcit.cz>
62  * Enabler configuration directive now called AuthPAM_Enabled   67  * Enabler configuration directive now called AuthPAM_Enabled
63  * Updated for Apache 1.3.x   68  * Updated for Apache 1.3.x
64  * 25-Sep-98: replaced pwdb groups routine with standard C   69  * 25-Sep-98: replaced pwdb groups routine with standard C
65  * 19-Oct-97: made module fall through (if configured to do so),   70  * 19-Oct-97: made module fall through (if configured to do so),
66  * even when a user of the given name is found in the PAM   71  * even when a user of the given name is found in the PAM
67  * databases   72  * databases
68  * 17-Apr-97: fixed segfault that occured when Apache couldn't look   73  * 17-Apr-97: fixed segfault that occured when Apache couldn't look
69  * up the remote host name   74  * up the remote host name
70  * removed annoying compiler warnings   75  * removed annoying compiler warnings
71  *   76  *
72  * 05-Apr-97: made fall-through configurable with AuthPAM_Authorative   77  * 05-Apr-97: made fall-through configurable with AuthPAM_Authorative
73  *   78  *
74  * 25-Mar-97: added support for transparent fall-through to other auth   79  * 25-Mar-97: added support for transparent fall-through to other auth
75  * modules with configurable fail delays   80  * modules with configurable fail delays
76  * added acct_mgmt hook   81  * added acct_mgmt hook
77  * added group support (through libpwdb)   82  * added group support (through libpwdb)
78  *   83  *
79  * usage information:   84  * usage information:
80  *   85  *
81  * new-style (DSO)   86  * new-style (DSO and apache 2.0)
82  *   87  *
83  * compile with   88  * compile with
84  * apxs -c -lpam mod_auth_pam.c   89  * apxs -c -lpam mod_auth_pam.c
85  *   90  *
      91  * apxs -I/usr/local/include -L/usr/local/lib -c -lpam mod_auth_pam.c
      92  *
86  * install with   93  * install with
87  * apxs -i -a mod_auth_pam.so   94  * apxs -i -a mod_auth_pam.so
88  *   95  *
89  * configure PAM by adding   96  * configure PAM by adding
90  * /etc/pam.d/httpd   97  * /etc/pam.d/httpd
      98  *
91  * with the appropriate pam modules (for starters, just copy over ftp)   99  * with the appropriate pam modules (for starters, just copy over ftp)
92  *   100  *
93  * old-style (from Apache 1.2.x)   101  * old-style (from Apache 1.2.x)
94  *   102  *
95  * 1. Configuration:   103  * 1. Configuration:
96  * Module pam_auth_module mod_auth_pam.o   104  * Module pam_auth_module mod_auth_pam.o
97  * EXTRA_LIBS+= -lpam -ldl   105  * EXTRA_LIBS+= -lpam -ldl
98  *   106  *
99  * 2. Add an auth and an account entry for service type "httpd"   107  * 2. Add an auth and an account entry for service type "httpd"
100  * to your PAM configuration   108  * to your PAM configuration
101  *   109  *
102  *   110  *
103  * configuration directives:   111  * configuration directives:
104  * AuthFailDelay <msecs>   112  * AuthFailDelay <msecs>
105  * number of mili-seconds to wait after a   113  * number of mili-seconds to wait after a
106  * failed authentication attempt. this is   114  * failed authentication attempt. this is
107  * a minimum value and may have been   115  * a minimum value and may have been
108  * increased by other pam apps.   116  * increased by other pam apps.
109  * defaults to 0   117  * defaults to 0
110  * REQUIRES lib_pam SUPPORT   118  * REQUIRES lib_pam SUPPORT
111  *   119  *
112  * AuthPAM_Enabled on|off   120  * AuthPAM_Enabled on|off
113  * If on, mod_auth_pam will try to authenticate   121  * If on, mod_auth_pam will try to authenticate
114  * the user.   122  * the user.
115  * If off, mod_auth_pam will DECLINE immediately   123  * If off, mod_auth_pam will DECLINE immediately
116  * instead of trying to authenticate the user.   124  * instead of trying to authenticate the user.
117  * This will make Apache try other modules.   125  * This will make Apache try other modules.
118  * Defaults to on   126  * Defaults to on
119  *   127  *
120  * AuthPAM_FallThrough   128  * AuthPAM_FallThrough
121  * If on, makes mod_auth_pam DECLINE if it can't   129  * If on, makes mod_auth_pam DECLINE if it can't
122  * the username, giving other modules a chance.   130  * the username, giving other modules a chance.
123  * Please note that, if it DOES find the username,   131  * Please note that, if it DOES find the username,
124  * and the password doesn't match, it will NOT   132  * and the password doesn't match, it will NOT
125  * fall through but return "access denied" instead   133  * fall through but return "access denied" instead
126  * Defaults to off   134  * Defaults to off
127  *   135  *
128  * AuthPAM_Authorative on|off DEPRECATED   136  * AuthPAM_Authorative on|off DEPRECATED
129  */   137  */
130   138
      139 #include <sys/types.h>
      140 #include <pwd.h> /* for getpwnam et.al. */
      141 #include <grp.h> /* for getpwnam et.al. */
131 #include <unistd.h>   142 #include <unistd.h>
132   143
      144 #include "ap_config.h"
133 #include "httpd.h"   145 #include "httpd.h"
134 #include "http_config.h"   146 #include "http_config.h"
135 #include "http_core.h"   147 #include "http_core.h"
136 #include "http_log.h"   148 #include "http_log.h"
137 #include "http_protocol.h"   149 #include "http_protocol.h"
      150 #include "http_request.h"
138   151
139 #include <security/pam_appl.h>   152 #include <security/pam_appl.h>
140   153
141 /* change this to 0 on RedHat 4.x */   154 /* change this to 0 on RedHat 4.x */
142 #define PAM_STRE_NEEDS_PAMH 1   155 #define PAM_STRE_NEEDS_PAMH 1
143 #define VERSION "1.0a"   156 #define VERSION "1.0a"
144   157
145 module pam_auth_module;   158 module pam_auth_module;
146   159
147 static const char   160 static const char
148 *pam_servicename = "httpd",   161 *pam_servicename = "httpd",
149   *valid_user = "valid-user";   162   *valid_user = "valid-user";
150   163
151 typedef struct {   164 typedef struct {
152   char *name, *pw;   165   char *name, *pw;
153 } auth_pam_userinfo;   166 } auth_pam_userinfo;
154   167
155 /*   168 /*
156  * Solaris 2.6.x has a broken conversation function and needs this   169  * Solaris 2.6.x has a broken conversation function and needs this
157  * as a global variable   170  * as a global variable
158  * I refused to pollute code for other platforms with this,   171  * I refused to pollute code for other platforms with this,
159  * so all Solaris 2.6 specific stuff is if'd like the following   172  * so all Solaris 2.6 specific stuff is if'd like the following
160  */   173  */
161 #if SOLARIS2 == 260   174 #if SOLARIS2 == 260
162 auth_pam_userinfo *global_userinfo;   175 auth_pam_userinfo *global_userinfo;
163 #endif   176 #endif
164   177
165 /*   178 /*
166  * the pam_strerror function has different parameters in early PAM   179  * the pam_strerror function has different parameters in early PAM
167  * versions   180  * versions
168  */   181  */
169 #ifndef PAM_STRE_NEEDS_PAMH   182 #ifndef PAM_STRE_NEEDS_PAMH
170 #define compat_pam_strerror(pamh, res) pam_strerror(res)   183 #define compat_pam_strerror(pamh, res) pam_strerror(res)
171 #else   184 #else
172 #define compat_pam_strerror(pamh, res) pam_strerror(pamh, res)   185 #define compat_pam_strerror(pamh, res) pam_strerror(pamh, res)
173 #endif   186 #endif
174   187
175 /*   188 /*
176  * configuration directive handling   189  * configuration directive handling
177  */   190  */
178   191
179 typedef struct {   192 typedef struct {
180   int   193   int
181     fail_delay, /* fail delay in ms -- needs library support */   194     fail_delay, /* fail delay in ms -- needs library support */
182     fall_through, /* 1 to DECLINE instead of AUTH_REQUIRED if we   195     fall_through, /* 1 to DECLINE instead of HTTP_UNAUTHORIZEDif we
183 can't find the username (defaults to 0) */   196 can't find the username (defaults to 0) */
184     enabled; /* 1 to use mod_auth_pam, 0 otherwise   197     enabled; /* 1 to use mod_auth_pam, 0 otherwise
185 (defaults to 1) */   198 (defaults to 1) */
186 } auth_pam_dir_config;   199 } auth_pam_dir_config;
187   200
188 void auth_pam_init(server_rec *s, pool *p)   201 static
      202 int auth_pam_init(
      203 apr_pool_t *p,
      204 apr_pool_t *plog,
      205 apr_pool_t *ptemp,
      206 server_rec *s
      207 )
189 {   208 {
190   ap_add_version_component("mod_auth_pam/" VERSION);   209   ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,"PAM: mod_auth_pam/" VERSION);
      210
      211   return OK;
191 }   212 }
192   213
193 static   214 static
194 void* create_auth_pam_dir_config(pool *p, char *dummy)   215 void* create_auth_pam_dir_config(apr_pool_t *p, char *dummy)
195 {   216 {
196   auth_pam_dir_config *new =   217   auth_pam_dir_config *new =
197     (auth_pam_dir_config*) ap_palloc (p, sizeof(auth_pam_dir_config));   218     (auth_pam_dir_config*) apr_palloc (p, sizeof(auth_pam_dir_config));
198   219
199   new->fail_delay = 0; /* 0 ms */   220   new->fail_delay = 0; /* 0 ms */
200   new->fall_through = 0; /* off */   221   new->fall_through = 0; /* off */
201   new->enabled = 1; /* on */   222   new->enabled = 1; /* on */
202   return new;   223   return new;
203 }   224 }
204   225
205 static   226 static command_rec auth_pam_cmds[] = {
206 char* auth_fail_delay(cmd_parms *cmd, auth_pam_dir_config *config, char *secs)      
207 {      
208   if(secs)      
209     config->fail_delay = atoi(secs);      
210   return NULL;      
211 }      
212      
213 static      
214 char* auth_fall_through(cmd_parms *cmd, auth_pam_dir_config *config, int arg)      
215 {      
216   config->fall_through = arg;      
217   return NULL;      
218 }      
219   227
220 static   228   AP_INIT_TAKE1("AuthPAM_FailDelay",
221 char* auth_enable(cmd_parms *cmd, auth_pam_dir_config *config, int arg)   229      ap_set_string_slot,
222 {   230      (void *)APR_OFFSETOF(auth_pam_dir_config, fail_delay),
223   config->enabled = arg;   231      OR_AUTHCFG,
224   return NULL;   232     "number of micro seconds to wait after failed authentication "
225 }   233     "attempt. (default is 0.)" ),
      234
      235   AP_INIT_FLAG("AuthPAM_FallThrough",
      236 ap_set_flag_slot,
      237      (void *)APR_OFFSETOF(auth_pam_dir_config, fall_through),
      238 OR_AUTHCFG,
      239     "on|off - determines if other authentication methods are attempted "
      240     "if this one fails; (default is off.)"),
      241
      242   AP_INIT_FLAG("AuthPAM_Enabled",
      243 ap_set_flag_slot,
      244      (void *)APR_OFFSETOF(auth_pam_dir_config, enabled),
      245 OR_AUTHCFG,
      246     "on|off - determines if PAM authentication is enabled; ("
      247     "default is on.)" ),
226   248
227 static command_rec auth_pam_cmds[] = {   249   { NULL }
228   { "AuthFailDelay", (const char*(*)())auth_fail_delay, 0, OR_AUTHCFG, TAKE1,      
229     "number of micro seconds to wait after failed authentication attempt. defau      
230 lt is 0" },      
231   { "AuthPAM_Authorative", (const char*(*)())auth_fall_through, NULL, OR_AUTHCFG, FLAG,      
232     "no longer in use -- see AuthPAM_FallThrough instead" },      
233   { "AuthPAM_FallThrough", (const char*(*)())auth_fall_through, NULL, OR_AUTHCFG, FLAG,      
234     "on|off - determines if other authentication methods are attempted if this      
235 one fails; default is off" },      
236   { "AuthPAM_Enabled", (const char*(*)())auth_enable, NULL, OR_AUTHCFG, FLAG,      
237     "on|off - determines if PAM authentication is enabled; default is on" },      
238   { 0 }      
239 };   250 };
240   251
241 /*   252 /*
242  * auth_pam_talker: supply authentication information to PAM when asked   253  * auth_pam_talker: supply authentication information to PAM when asked
243  *   254  *
244  * Assumptions:   255  * Assumptions:
245  * A password is asked for by requesting input without echoing   256  * A password is asked for by requesting input without echoing
246  * A username is asked for by requesting input _with_ echoing   257  * A username is asked for by requesting input _with_ echoing
247  *   258  *
248  */   259  */
249 static   260 static
250 int auth_pam_talker(int num_msg,   261 int auth_pam_talker(int num_msg,
251                     const struct pam_message **msg,   262                     const struct pam_message **msg,
252                     struct pam_response **resp,   263                     struct pam_response **resp,
253                     void *appdata_ptr)   264                     void *appdata_ptr)
254 {   265 {
255   unsigned short i = 0;   266   unsigned short i = 0;
256   auth_pam_userinfo *userinfo = (auth_pam_userinfo*)appdata_ptr;   267   auth_pam_userinfo *userinfo = (auth_pam_userinfo*)appdata_ptr;
257   struct pam_response *response = 0;   268   struct pam_response *response = 0;
258   269
259 #if SOLARIS2 == 260   270 #if SOLARIS2 == 260
260   if(!userinfo)   271   if(!userinfo)
261     userinfo = global_userinfo;   272     userinfo = global_userinfo;
262   /* fprintf(stderr,"%s : %s", userinfo->name, userinfo->pw); */   273   /* fprintf(stderr,"%s : %s", userinfo->name, userinfo->pw); */
263 #endif   274 #endif
264   275
265   /* parameter sanity checking */   276   /* parameter sanity checking */
266   if(!resp || !msg || !userinfo)   277   if(!resp || !msg || !userinfo)
267     return PAM_CONV_ERR;   278     return PAM_CONV_ERR;
268   279
269   /* allocate memory to store response */   280   /* allocate memory to store response */
270   response = malloc(num_msg * sizeof(struct pam_response));   281   response = malloc(num_msg * sizeof(struct pam_response));
271   if(!response)   282   if(!response)
272     return PAM_CONV_ERR;   283     return PAM_CONV_ERR;
273   284
274   /* copy values */   285   /* copy values */
275   for(i = 0; i < num_msg; i++) {   286   for(i = 0; i < num_msg; i++) {
276     /* initialize to safe values */   287     /* initialize to safe values */
277     response[i].resp_retcode = 0;   288     response[i].resp_retcode = 0;
278     response[i].resp = 0;   289     response[i].resp = 0;
279   290
280     /* select response based on requested output style */   291     /* select response based on requested output style */
281     switch(msg[i]->msg_style) {   292     switch(msg[i]->msg_style) {
282     case PAM_PROMPT_ECHO_ON:   293     case PAM_PROMPT_ECHO_ON:
283       /* on memory allocation failure, auth fails */   294       /* on memory allocation failure, auth fails */
284       response[i].resp = strdup(userinfo->name);   295       response[i].resp = strdup(userinfo->name);
285       break;   296       break;
286     case PAM_PROMPT_ECHO_OFF:   297     case PAM_PROMPT_ECHO_OFF:
287       response[i].resp = strdup(userinfo->pw);   298       response[i].resp = strdup(userinfo->pw);
288       break;   299       break;
289     default:   300     default:
290       if(response)   301       if(response)
291         free(response);   302         free(response);
292       return PAM_CONV_ERR;   303       return PAM_CONV_ERR;
293     }   304     }
294   }   305   }
295   /* everything okay, set PAM response values */   306   /* everything okay, set PAM response values */
296   *resp = response;   307   *resp = response;
297   return PAM_SUCCESS;   308   return PAM_SUCCESS;
298 }   309 }
299   310
300 /*   311 /*
301  * These functions return 0 if client is OK, and proper error status   312  * These functions return 0 if client is OK, and proper error status
302  * if not... either AUTH_REQUIRED, if we made a check, and it failed, or   313  * if not... either AUTH_REQUIRED, if we made a check, and it failed, or
303  * SERVER_ERROR, if things are so totally confused that we couldn't   314  * SERVER_ERROR, if things are so totally confused that we couldn't
304  * figure out how to tell if the client is authorized or not.   315  * figure out how to tell if the client is authorized or not.
305  *   316  *
306  * If they return DECLINED, and all other modules also decline, that's   317  * If they return DECLINED, and all other modules also decline, that's
307  * treated by the server core as a configuration error, logged and   318  * treated by the server core as a configuration error, logged and
308  * reported as such.   319  * reported as such.
309  */   320  */
310   321
311 /*   322 /*
312  * Determine user ID, and check if it really is that user   323  * Determine user ID, and check if it really is that user
313  */   324  */
314 static   325 static
315 int pam_auth_basic_user (request_rec *r)   326 int pam_auth_basic_user (request_rec *r)
316 {   327 {
317   int res = 0;   328   int res = 0;
318   /* mod_auth_pam specific */   329   /* mod_auth_pam specific */
319   auth_pam_userinfo userinfo = { NULL, NULL };   330   auth_pam_userinfo userinfo = { NULL, NULL };
320   auth_pam_dir_config *conf = (auth_pam_dir_config*)   331   auth_pam_dir_config *conf = (auth_pam_dir_config*)
321     ap_get_module_config(r->per_dir_config, &pam_auth_module);   332     ap_get_module_config(r->per_dir_config, &pam_auth_module);
322   /* PAM specific */   333   /* PAM specific */
323   struct pam_conv conv_info = { &auth_pam_talker, (void*)&userinfo};   334   struct pam_conv conv_info = { &auth_pam_talker, (void*)&userinfo};
324   pam_handle_t *pamh = NULL;   335   pam_handle_t *pamh = NULL;
325   336
326 #if SOLARIS2 == 260   337 #if SOLARIS2 == 260
327   global_userinfo = &userinfo;   338   global_userinfo = &userinfo;
328 #endif   339 #endif
329   340
330   /* enabled? */   341   /* enabled? */
331   if (!conf->enabled)   342   if (!conf->enabled)
332     return DECLINED;   343     return DECLINED;
333   344
334   /* read sent pw */   345   /* read sent pw */
335   if ((res = ap_get_basic_auth_pw (r, (const char**)&(userinfo.pw))))   346   if ((res = ap_get_basic_auth_pw (r, (const char**)&(userinfo.pw))))
336     return res;   347     return res;
337   348
338   /* this is only set after get_basic_auth_pw was called */   349   /* this is only set after get_basic_auth_pw was called */
339   userinfo.name = r->connection->user;   350   userinfo.name = r->user;
340   351
341   /* initialize pam */   352   /* initialize pam */
342   if((res = pam_start(pam_servicename,   353   if((res = pam_start(pam_servicename,
343 userinfo.name,   354 userinfo.name,
344 &conv_info,   355 &conv_info,
345 &pamh)) != PAM_SUCCESS) {   356 &pamh)) != PAM_SUCCESS) {
346   357
347     ap_log_reason((char*)compat_pam_strerror(pamh, res), r->uri, r);   358     ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "PAM: Could not start pam service: %s",compat_pam_strerror(pamh, res));
348     return DECLINED;   359     return DECLINED;
349   }   360   }
350   361
351   /* set fail delay */   362   /* set fail delay */
352 #ifdef PAM_FAIL_DELAY   363 #ifdef PAM_FAIL_DELAY
353   pam_fail_delay(pamh, conf->fail_delay);   364   pam_fail_delay(pamh, conf->fail_delay);
354 #endif   365 #endif
355   366
356   /* set remote user information */   367   /* set remote user information */
357   /* this seems to cause segfaults in lots of cases -- disabled for now   368   /* this seems to cause segfaults in lots of cases -- disabled for now
358      pam_set_item(pamh, PAM_USER, userinfo.name);   369      pam_set_item(pamh, PAM_USER, userinfo.name);
359      pam_set_item(pamh, PAM_RHOST, get_remote_host(r->connection,   370      pam_set_item(pamh, PAM_RHOST, get_remote_host(r->connection,
360      conf,   371      conf,
361      REMOTE_NAME));   372      REMOTE_NAME));
362   */   373   */
363   374
364   /* try to authenticate user, log error on failure */   375   /* try to authenticate user, log error on failure */
365   if((res = pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK)) !=   376   if((res = pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK)) !=
366      PAM_SUCCESS ) {   377      PAM_SUCCESS ) {
367     ap_log_reason((char*)compat_pam_strerror(pamh, res), r->uri, r);   378      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
      379 "PAM: user '%s' - not authenticated: %s",r->user,compat_pam_strerror(pamh, res));
      380
368     if(conf->fall_through && (res == PAM_USER_UNKNOWN)) {   381     if(conf->fall_through && (res == PAM_USER_UNKNOWN)) {
369       /* we don't know about the user, but other auth modules might do */   382       /* we don't know about the user, but other auth modules might do */
370       pam_end(pamh, PAM_SUCCESS);   383       pam_end(pamh, PAM_SUCCESS);
371       return DECLINED;   384       return DECLINED;
372     } else {   385     } else {
373       pam_end(pamh, PAM_SUCCESS);   386       pam_end(pamh, PAM_SUCCESS);
374       ap_note_basic_auth_failure(r);   387       ap_note_basic_auth_failure(r);
375       return AUTH_REQUIRED;   388       return HTTP_UNAUTHORIZED;
376     } /* endif fall_through */   389     } /* endif fall_through */
377   } /* endif authenticate */   390   } /* endif authenticate */
378   391
379   /* check that the account is healthy */   392   /* check that the account is healthy */
380   if((res = pam_acct_mgmt(pamh, PAM_DISALLOW_NULL_AUTHTOK)) != PAM_SUCCESS) {   393   if((res = pam_acct_mgmt(pamh, PAM_DISALLOW_NULL_AUTHTOK)) != PAM_SUCCESS) {
381     ap_log_reason((char*)compat_pam_strerror(pamh, res), r->uri, r);   394      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
      395 "PAM: user '%s' - invalid account: %s",r->user,compat_pam_strerror(pamh, res));
382     pam_end(pamh, PAM_SUCCESS);   396     pam_end(pamh, PAM_SUCCESS);
383     return AUTH_REQUIRED;   397     return HTTP_UNAUTHORIZED;
384   }   398   }
385   399
386   pam_end(pamh, PAM_SUCCESS);   400   pam_end(pamh, PAM_SUCCESS);
387   return OK;   401   return OK;
388 }   402 }
389   403
390 /*   404 static void pam_register_hooks(apr_pool_t *p)
391  * Look if that user (as authenticated above) is allowed here   405 {
392  */   406     ap_hook_post_config(auth_pam_init, NULL, NULL, APR_HOOK_MIDDLE);
393   407     ap_hook_check_user_id(pam_auth_basic_user,NULL,NULL,APR_HOOK_MIDDLE);
394 static   408 }
395 int pam_check_auth (request_rec *r)      
396 {      
397   register int i = 0;      
398   char method_restricted = 0, *line = 0, *word = 0;      
399   auth_pam_dir_config *conf = (auth_pam_dir_config*)      
400     ap_get_module_config(r->per_dir_config, &pam_auth_module);      
401      
402 char *p_group = NULL;      
403      
404   /* check for allowed users/group */      
405   const array_header *reqs_arr = ap_requires (r);      
406   require_line *reqs = 0;      
407      
408   /* enabled? */      
409   if (!conf->enabled)      
410     return DECLINED;      
411      
412   /* if any valid user suffices return success */      
413   if (!reqs_arr)      
414     return (OK);      
415      
416   /* otherwise */      
417   reqs = (require_line*)reqs_arr->elts;      
418      
419   /* loop over requirement lines */      
420   for( i = 0; i < reqs_arr->nelts; i++) {      
421     /* if method of this requirement matches current method */      
422     if (reqs[i].method_mask & (1 << r->method_number)) {      
423       method_restricted = 1;      
424      
425       line = reqs[i].requirement;      
426       word = ap_getword(r->pool, (const char**)&line, ' ');      
427      
428       /* if any user is ok */      
429       if(!strcmp(word, valid_user))      
430         return OK;      
431      
432       /* loop over line */      
433       if(!strcmp(word, "user")) {      
434         while(*line) {      
435           word = ap_getword_conf(r->pool, (const char**)&line);      
436           /* if username matches remote username */      
437           if(!strcmp(r->connection->user, word))      
438             /* return success */      
439             return OK;      
440         }      
441       } /* end if user */      
442       else if(!strcmp(word, "group")) {      
443 struct group *grent;      
444 char **members;      
445      
446 if (!p_group)      
447 {      
448 struct passwd *pwent;      
449      
450 if ((pwent = getpwnam (r->connection->user)) && (grent = getgrgid (pwent->pw_gid)))      
451 p_group = grent->gr_name;      
452 }      
453      
454 while (*line)      
455 {      
456 word = ap_getword_conf(r->pool, (const char**)&line);      
457      
458 if (p_group && !strcmp (p_group, word))      
459 return OK;      
460      
461 if ((grent = getgrnam (word)) && grent->gr_mem)      
462 {      
463 members = grent->gr_mem;      
464      
465 while (*members)      
466 {      
467 if (!strcmp (*members, word))      
468 return OK;      
469      
470 members ++;      
471 }      
472 }      
473 }      
474       } /* end if group */      
475     }      
476   }      
477      
478   if (!method_restricted)      
479     return OK;      
480      
481   ap_note_basic_auth_failure (r);      
482   return AUTH_REQUIRED;      
483 }      
484   409
485 module pam_auth_module = {   410 module AP_MODULE_DECLARE_DATA pam_auth_module = {
486   STANDARD_MODULE_STUFF,   411   STANDARD20_MODULE_STUFF,
487   auth_pam_init, /* initializer */      
488   create_auth_pam_dir_config, /* dir config creater */   412   create_auth_pam_dir_config, /* dir config creater */
489   NULL, /* dir merger --- default is to override */   413   NULL, /* dir merger --- default is to override */
490   NULL, /* server config */   414   NULL, /* server config */
491   NULL, /* merge server config */   415   NULL, /* merge server config */
492   auth_pam_cmds, /* command table */   416   auth_pam_cmds, /* command table */
493   NULL, /* handlers */   417   pam_register_hooks, /* register hooks */
494   NULL, /* filename translation */      
495   pam_auth_basic_user, /* check_user_id */      
496   pam_check_auth, /* check auth */      
497   NULL, /* check access */      
498   NULL, /* type_checker */      
499   NULL, /* fixups */      
500   NULL /* logger */      
501 };   418 };
502   419
503   420

Generated by diff2html on Fri Jul 12 08:22:39 2002
Command-line:
/home/dirkx/diff2html mod_auth_pam.c mod_auth_pam2.c