]> granicus.if.org Git - linux-pam/blob - modules/pam_radius/pam_radius.c
Relevant BUGIDs: 108297
[linux-pam] / modules / pam_radius / pam_radius.c
1 /*
2  * pam_radius 
3  *      Process an user session according to a RADIUS server response
4  *
5  * 1.0 - initial release - Linux ONLY
6  * 1.1 - revised and reorganized for libpwdb 0.54preB or higher
7  *     - removed the conf= parameter, since we use libpwdb exclusively now
8  *
9  * See end for Copyright information
10  */
11
12 #if !(defined(linux))
13 #error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!
14 #endif 
15
16 /* Module defines */
17 #define BUFFER_SIZE      1024
18 #define LONG_VAL_PTR(ptr) ((*(ptr)<<24)+(*((ptr)+1)<<16)+(*((ptr)+2)<<8)+(*((ptr)+3)))
19
20 #define PAM_SM_SESSION
21
22 #include "pam_radius.h"
23
24 #include <security/pam_modules.h>
25 #include <security/_pam_macros.h>
26
27 static time_t session_time;
28
29 /* we need to save these from open_session to close_session, since
30  * when close_session will be called we won't be root anymore and
31  * won't be able to access again the radius server configuration file
32  * -- cristiang */
33
34 static RADIUS_SERVER rad_server;
35 static char hostname[BUFFER_SIZE];
36 static char secret[BUFFER_SIZE];
37
38 /* logging */
39 static void _pam_log(int err, const char *format, ...)
40 {
41     va_list args;
42
43     va_start(args, format);
44     openlog("pam_radius", LOG_CONS|LOG_PID, LOG_AUTH);
45     vsyslog(err, format, args);
46     va_end(args);
47     closelog();
48 }
49
50 /* argument parsing */
51
52 #define PAM_DEBUG_ARG       0x0001
53
54 static int _pam_parse(int argc, const char **argv)
55 {
56      int ctrl=0;
57
58      /* step through arguments */
59      for (ctrl=0; argc-- > 0; ++argv) {
60
61           /* generic options */
62
63           if (!strcmp(*argv,"debug"))
64                ctrl |= PAM_DEBUG_ARG;
65           else {
66                _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
67           }
68      }
69
70      return ctrl;
71 }
72
73 /* now the session stuff */
74 PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
75                                    int argc, const char **argv)
76 {
77     int retval;
78     char *user_name;
79     int ctrl;
80         
81     ctrl = _pam_parse(argc, argv); 
82     retval = pam_get_item( pamh, PAM_USER, (void*) &user_name );
83     if ( user_name == NULL || retval != PAM_SUCCESS ) {
84         _pam_log(LOG_CRIT, "open_session - error recovering username");
85         return PAM_SESSION_ERR;
86      }
87         
88     if (ctrl & PAM_DEBUG_ARG)
89         _pam_log(LOG_DEBUG, "starting RADIUS user session for '%s'",
90                              user_name);
91
92     retval = get_server_entries(hostname, secret);
93     if ((retval != PWDB_RADIUS_SUCCESS) ||
94         !strlen(hostname) || !strlen(secret)) {
95         _pam_log(LOG_CRIT, "Could not determine the radius server to talk to");
96         return PAM_IGNORE;
97     }
98     session_time = time(NULL);
99     rad_server.hostname = hostname;
100     rad_server.secret = secret;
101     retval = radius_acct_start(rad_server, user_name);
102     if (retval != PWDB_RADIUS_SUCCESS) {
103         if (ctrl & PAM_DEBUG_ARG)
104             _pam_log(LOG_DEBUG, "ERROR communicating with the RADIUS server");
105         return PAM_IGNORE;
106     }
107
108     return PAM_SUCCESS;
109 }
110
111 PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags,
112                                     int argc, const char **argv)
113 {
114     int ctrl;
115     char *user_name;
116     int retval;
117
118     ctrl = _pam_parse(argc, argv); 
119     retval = pam_get_item( pamh, PAM_USER, (void*) &user_name );
120     if ( user_name == NULL || retval != PAM_SUCCESS ) {
121         _pam_log(LOG_CRIT, "open_session - error recovering username");
122         return PAM_SESSION_ERR;
123      }
124
125     if (ctrl & PAM_DEBUG_ARG)
126          _pam_log(LOG_DEBUG, "closing RADIUS user session for '%s'",
127                               user_name);
128
129     if (!strlen(hostname) || !strlen(secret)) {
130         _pam_log(LOG_CRIT, "Could not determine the radius server to talk to");
131         return PAM_IGNORE;
132     }
133     retval = radius_acct_stop(rad_server, user_name, 
134                               time(NULL) - session_time);
135     if (retval != PWDB_RADIUS_SUCCESS) {
136         if (ctrl & PAM_DEBUG_ARG)
137             _pam_log(LOG_DEBUG, "ERROR communicating with the RADIUS server");
138         return PAM_IGNORE;
139     }
140     
141     return PAM_SUCCESS;
142 }
143
144 #ifdef PAM_STATIC
145
146 /* static module data */
147
148 struct pam_module _pam_radius_modstruct = {
149      "pam_radius",
150      NULL,
151      NULL,
152      NULL,
153      pam_sm_open_session,
154      pam_sm_close_session,
155      NULL
156 };
157 #endif
158
159 /*
160  * Copyright (c) Cristian Gafton, 1996, <gafton@redhat.com>
161  *                                              All rights reserved.
162  *
163  * Redistribution and use in source and binary forms, with or without
164  * modification, are permitted provided that the following conditions
165  * are met:
166  * 1. Redistributions of source code must retain the above copyright
167  *    notice, and the entire permission notice in its entirety,
168  *    including the disclaimer of warranties.
169  * 2. Redistributions in binary form must reproduce the above copyright
170  *    notice, this list of conditions and the following disclaimer in the
171  *    documentation and/or other materials provided with the distribution.
172  * 3. The name of the author may not be used to endorse or promote
173  *    products derived from this software without specific prior
174  *    written permission.
175  * 
176  * ALTERNATIVELY, this product may be distributed under the terms of
177  * the GNU Public License, in which case the provisions of the GPL are
178  * required INSTEAD OF the above restrictions.  (This clause is
179  * necessary due to a potential bad interaction between the GPL and
180  * the restrictions contained in a BSD-style copyright.)
181  * 
182  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
183  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
184  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
185  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
186  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
187  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
188  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
189  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
190  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
191  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
192  * OF THE POSSIBILITY OF SUCH DAMAGE.
193  */