1 kumpf 1.1 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.5 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
|
4 kumpf 1.1 // The Open Group, Tivoli Systems
5 //
|
6 kumpf 1.5 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
14 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
16 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21 kumpf 1.1 //
22 //==============================================================================
23 //
24 // Author: Nag Boranna, Hewlett-Packard Company(nagaraja_boranna@hp.com)
25 //
26 // Modified By:
27 //
28 //%/////////////////////////////////////////////////////////////////////////////
29
30 #include <Pegasus/Common/System.h>
31 #include <Pegasus/Common/Tracer.h>
32 #include <Pegasus/Common/Destroyer.h>
33 #include <Pegasus/Config/ConfigManager.h>
34
35 #include "PAMBasicAuthenticator.h"
36
37
38 PEGASUS_USING_STD;
39
40 PEGASUS_NAMESPACE_BEGIN
|
41 kumpf 1.3
42 #include <security/pam_appl.h>
|
43 kumpf 1.1
44
45 /**
46 Constant representing the Basic authentication challenge header.
47 */
48 static const String BASIC_CHALLENGE_HEADER = "WWW-Authenticate: Basic \"";
49
50
51 /** Service name for pam_start */
52 const char *service = "wbem";
53
|
54 kumpf 1.9 typedef struct
55 {
56 CString userPassword;
57 } APP_DATA;
58
|
59 kumpf 1.1
60 /* constructor. */
61 PAMBasicAuthenticator::PAMBasicAuthenticator()
62 {
63 PEG_METHOD_ENTER(TRC_AUTHENTICATION,
64 "PAMBasicAuthenticator::PAMBasicAuthenticator()");
65
66 //
67 // get the local system name
68 //
69 _realm.assign(System::getHostName());
70
71 //
72 // get the configured port number
73 //
74 ConfigManager* configManager = ConfigManager::getInstance();
75
|
76 kumpf 1.4 String port = configManager->getCurrentValue("httpPort");
|
77 kumpf 1.1
78 //
79 // Create realm that will be used for Basic challenges
80 //
81 _realm.append(":");
82 _realm.append(port);
83
84 PEG_METHOD_EXIT();
85 }
86
87 /* destructor. */
88 PAMBasicAuthenticator::~PAMBasicAuthenticator()
89 {
90 PEG_METHOD_ENTER(TRC_AUTHENTICATION,
91 "PAMBasicAuthenticator::~PAMBasicAuthenticator()");
92
93 PEG_METHOD_EXIT();
94 }
95
96 Boolean PAMBasicAuthenticator::authenticate(
97 const String& userName,
98 kumpf 1.1 const String& password)
99 {
100 PEG_METHOD_ENTER(TRC_AUTHENTICATION,
101 "PAMBasicAuthenticator::authenticate()");
102
|
103 kumpf 1.2 Boolean authenticated = false;
|
104 kumpf 1.1 struct pam_conv pconv;
105 pam_handle_t *phandle;
106 char *name;
|
107 kumpf 1.9 APP_DATA mydata;
108
109 //
110 // Store the password for PAM authentication
111 //
112 mydata.userPassword = password.getCString();
|
113 kumpf 1.1
114 pconv.conv = PAMBasicAuthenticator::PAMCallback;
|
115 kumpf 1.9 pconv.appdata_ptr = &mydata;
|
116 kumpf 1.8
117 // WARNING: Should only be uncommented for debugging in a secure environment.
118 // Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4,
119 // "PAMBasicAuthenticator::authenticate() - userName = %s; userPassword = %s",
|
120 kumpf 1.9 // (const char *)userName.getCString(), (const char *)password.getCString());
|
121 kumpf 1.1
122 //
|
123 kumpf 1.2 //Call pam_start since you need to before making any other PAM calls
|
124 kumpf 1.1 //
125 if ( ( pam_start(service,
|
126 kumpf 1.6 (const char *)userName.getCString(), &pconv, &phandle) ) != PAM_SUCCESS )
|
127 kumpf 1.1 {
128 PEG_METHOD_EXIT();
129 return (authenticated);
130 }
131
132 //
133 //Call pam_authenticate to authenticate the user
134 //
|
135 kumpf 1.2 if ( ( pam_authenticate(phandle, 0) ) == PAM_SUCCESS )
|
136 kumpf 1.1 {
|
137 kumpf 1.8 Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4,
138 "PAMBasicAuthenticator::authenticate() pam_authenticate successful.");
|
139 kumpf 1.2 //
140 //Call pam_acct_mgmt, to check if the user account is valid. This includes
141 //checking for password and account expiration, as well as verifying access
142 //hour restrictions.
143 //
144 if ( ( pam_acct_mgmt(phandle, 0) ) == PAM_SUCCESS )
145 {
|
146 kumpf 1.8 Tracer::trace(TRC_AUTHENTICATION, Tracer::LEVEL4,
147 "PAMBasicAuthenticator::authenticate() pam_acct_mgmt successful.");
|
148 kumpf 1.2 authenticated = true;
149 }
|
150 kumpf 1.1 }
151
152 //
153 //Call pam_end to end our PAM work
154 //
|
155 kumpf 1.2 pam_end(phandle, 0);
|
156 kumpf 1.1
157 PEG_METHOD_EXIT();
158
159 return (authenticated);
160 }
161
162 //
163 // Create authentication response header
164 //
165 String PAMBasicAuthenticator::getAuthResponseHeader()
166 {
167 PEG_METHOD_ENTER(TRC_AUTHENTICATION,
168 "PAMBasicAuthenticator::getAuthResponseHeader()");
169
170 //
171 // build response header using realm
172 //
173 String responseHeader = BASIC_CHALLENGE_HEADER;
174 responseHeader.append(_realm);
175 responseHeader.append("\"");
176
177 kumpf 1.1 PEG_METHOD_EXIT();
178
179 return (responseHeader);
180 }
181
|
182 kumpf 1.8 #if defined PEGASUS_OS_LINUX
183 Sint32 PAMBasicAuthenticator::PAMCallback(Sint32 num_msg, const struct pam_message **msg,
184 struct pam_response **resp, void *appdata_ptr)
185 #else
|
186 kumpf 1.1 Sint32 PAMBasicAuthenticator::PAMCallback(Sint32 num_msg, struct pam_message **msg,
187 struct pam_response **resp, void *appdata_ptr)
|
188 kumpf 1.8 #endif
|
189 kumpf 1.1 {
190 PEG_METHOD_ENTER(TRC_AUTHENTICATION,
191 "PAMBasicAuthenticator::PAMCallback()");
|
192 kumpf 1.9
193 //
194 // Copy the application specific data from the PAM structure.
195 //
196 APP_DATA *mydata;
197 mydata = (APP_DATA *) appdata_ptr;
198
|
199 kumpf 1.1 //
200 // Allocate the response buffers
201 //
202 if ( num_msg > 0 )
203 {
204 *resp = (struct pam_response *)malloc(sizeof(struct pam_response)*num_msg);
205
206 if ( *resp == NULL )
207 {
208 PEG_METHOD_EXIT();
209 return PAM_BUF_ERR;
210 }
211 }
212 else
213 {
214 PEG_METHOD_EXIT();
215 return PAM_CONV_ERR;
216 }
217
|
218 kumpf 1.8 for ( Sint32 i = 0; i < num_msg; i++ )
|
219 kumpf 1.1 {
220 switch ( msg[i]->msg_style )
221 {
222 case PAM_PROMPT_ECHO_OFF:
223 //
224 // copy the user password
225 //
226 resp[i]->resp = (char *)malloc(PAM_MAX_MSG_SIZE);
|
227 kumpf 1.9 strcpy(resp[i]->resp, mydata->userPassword);
|
228 kumpf 1.1 resp[i]->resp_retcode = 0;
229 break;
230
231 default:
232 PEG_METHOD_EXIT();
233 return PAM_CONV_ERR;
234 }
235 }
236
237 PEG_METHOD_EXIT();
238
239 return PAM_SUCCESS;
240 }
241
242 PEGASUS_NAMESPACE_END
|