1 kumpf 1.1.2.1 //%////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
5 //
6 // 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 //
22 kumpf 1.1.2.1 //=============================================================================
23 //
24 // Author: Sushma Fernandes, Hewlett Packard Company (sushma_fernandes@hp.com)
25 //
26 // Modified By:
27 //
28 //%////////////////////////////////////////////////////////////////////////////
29
30
31 ///////////////////////////////////////////////////////////////////////////////
32 //
33 // This file implements the functionality required to manage password file.
34 //
35 ///////////////////////////////////////////////////////////////////////////////
36
37 #include <Pegasus/Common/FileSystem.h>
38 #include <Pegasus/Common/Destroyer.h>
39 #include <Pegasus/Common/Logger.h>
40 #include <Pegasus/Common/System.h>
41 #include <Pegasus/Common/Tracer.h>
42
43 kumpf 1.1.2.1 #include <Pegasus/Security/UserManager/UserFileHandler.h>
44 #include <Pegasus/Security/UserManager/UserExceptions.h>
45
46 PEGASUS_USING_STD;
47
48 PEGASUS_NAMESPACE_BEGIN
49
50 const char UserFileHandler::_PASSWD_FILE[] = "/cimserver.passwd";
51
52 const unsigned char UserFileHandler::_SALT_STRING[] =
53 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
54
55 //
56 // Generate random salt key for password encryption refer to crypt(3C)
57 //
58 void UserFileHandler::_GetSalt(char *salt)
59 {
60 long randNum;
61 Uint32 sec;
62 Uint32 milliSec;
63 const char METHOD_NAME[] = "PasswordFile::_GetSalt";
64 kumpf 1.1.2.1
65 PEG_FUNC_ENTER(TRC_USER_MANAGER,METHOD_NAME);
66
67 //
68 // Generate a random number and get the salt
69 //
70 System::getCurrentTime( sec, milliSec );
71
72 srand( (int) sec );
73 randNum = rand();
74
75 //
76 // Make sure the random number generated is between 0-63.
77 // refer to _SALT_STRING variable
78 //
79 *salt++ = _SALT_STRING[ randNum & 0x3f ];
80 randNum >>= 6;
81 *salt++ = _SALT_STRING[ randNum & 0x3f ];
82
83 salt[2] = '\0';
84
85 kumpf 1.1.2.1 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
86 }
87
88 //
89 // Constructor.
90 //
91 UserFileHandler::UserFileHandler()
92 {
93 const char METHOD_NAME[] = "UserFileHandler::UserFileHandler";
94
95 PEG_FUNC_ENTER(TRC_USER_MANAGER,METHOD_NAME);
96
97 // Get the value of environment variable PEGASUS_HOME
98 // The password file location is <$PEGASUS_HOME/cimserver.passwd>
99 const char* tmp = getenv("PEGASUS_HOME");
100
101 _passwordFileExists = false;
102 _passwdFileName = String(tmp);
103 _passwdFileName.append(String(_PASSWD_FILE));
104
105 _passwordFile = new PasswordFile(_passwdFileName);
106 kumpf 1.1.2.1
107 //
108 // check whether the password file is readable
109 //
110
111 if (!FileSystem::canRead(_passwdFileName))
112 {
113 // ATTN: Deal with this
114 //delete _passwordFile;
115 //throw FileNotReadable(_passwdFileName);
116 }
117 _passwordFileExists = true;
118
119 try
120 {
121 _loadAllUsers();
122 }
123 catch (Exception& e)
124 {
125 throw e;
126 }
127 kumpf 1.1.2.1
128 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
129 }
130
131
132 //
133 // Destructor.
134 //
135 UserFileHandler::~UserFileHandler()
136 {
137 const char METHOD_NAME[] = "UserFileHandler::~UserFileHandler";
138
139 PEG_FUNC_ENTER(TRC_USER_MANAGER,METHOD_NAME);
140
141 delete _passwordFile;
142
143 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
144 }
145
146 //
147 // Load all user names and password
148 kumpf 1.1.2.1 //
149 void UserFileHandler::_loadAllUsers ()
150 {
151 const char METHOD_NAME[] = "UserFileHandler::_loadAllUsers";
152
153 PEG_FUNC_ENTER(TRC_USER_MANAGER,METHOD_NAME);
154
155 try
156 {
157 _passwordTable.clear();
158 _passwordFile->load(_passwordTable);
159 }
160 catch (CannotOpenFile cof)
161 {
162 _passwordTable.clear();
163 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
164 throw cof;
165 }
166 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
167 }
168
169 kumpf 1.1.2.1 //
170 // Add user entry to file
171 //
172 void UserFileHandler::addUserEntry(
173 const String& userName,
174 const String& password)
175 {
176 char salt[3];
177 String encryptedPassword = String::EMPTY;
178 const char METHOD_NAME[] = "UserFileHandler::addUserEntry";
179
180 PEG_FUNC_ENTER(TRC_USER_MANAGER,METHOD_NAME);
181
182 // Check if the user already exists
183 if (_passwordTable.contains(userName))
184 {
185 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
186 throw DuplicateUser(userName);
187 }
188
189 // encrypt password
190 kumpf 1.1.2.1 _GetSalt(salt);
191
192 ArrayDestroyer<char> pw(password.allocateCString());
193
194 encryptedPassword = System::encryptPassword(pw.getPointer(),salt);
195
196 if (!_passwordTable.insert(userName,encryptedPassword))
197 {
198 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
199 throw PasswordCacheError();
200 }
201
202 // Store the new entry in the password file
203 try
204 {
205 _passwordFile->save(_passwordTable);
206 }
207 catch (CannotOpenFile& e)
208 {
209 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
210 throw e;
211 kumpf 1.1.2.1 }
212 catch (CannotRenameFile& e)
213 {
214 //
215 // reload password hash table from file
216 //
217 _loadAllUsers();
218
219 //
220 // creation of backup file failed
221 //
222
223 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
224 throw e;
225 }
226 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
227 }
228
229 //
230 // Modify user entry in file
231 //
232 kumpf 1.1.2.1 void UserFileHandler::modifyUserEntry(
233 const String& userName,
234 const String& password,
235 const String& newPassword )
236 {
237 char salt[3];
238 String encryptedPassword = String::EMPTY;
239 const char METHOD_NAME[] = "UserFileHandler::modifyUserEntry";
240
241 PEG_FUNC_ENTER(TRC_USER_MANAGER,METHOD_NAME);
242
243 //
244 // Check if the given password matches the passwd in the file
245 //
246 try
247 {
248 if ( !verifyCIMUserPassword (userName,password) )
249 {
250 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
251 throw PasswordMismatch(userName);
252 }
253 kumpf 1.1.2.1 }
254 catch (Exception& e)
255 {
256 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
257 throw e;
258 }
259
260 // encrypt new password
261 _GetSalt(salt);
262
263 ArrayDestroyer<char> npw(newPassword.allocateCString());
264
265 encryptedPassword = System::encryptPassword(npw.getPointer(),salt);
266
267 if (!_passwordTable.remove(userName))
268 {
269 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
270 throw PasswordCacheError();
271 }
272
273 if (!_passwordTable.insert(userName,encryptedPassword))
274 kumpf 1.1.2.1 {
275 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
276 throw PasswordCacheError();
277 }
278
279 // Store the modified entry in the password file
280 try
281 {
282 _passwordFile->save(_passwordTable);
283 }
284 catch (CannotOpenFile& e)
285 {
286 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
287 throw e;
288 }
289 catch (CannotRenameFile& e)
290 {
291 //
292 // reload password hash table from file
293 //
294 _loadAllUsers();
295 kumpf 1.1.2.1
296 //
297 // creation of backup file failed
298 //
299 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
300 throw e;
301 }
302 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
303 }
304
305 //
306 // Remove user entry from file
307 //
308 void UserFileHandler::removeUserEntry(const String& userName)
309 {
310 const char METHOD_NAME[] = "UserFileHandler::removeUserEntry";
311
312 PEG_FUNC_ENTER(TRC_USER_MANAGER,METHOD_NAME);
313
314 //Remove the existing user name and password from the table
315 if (!_passwordTable.remove(userName))
316 kumpf 1.1.2.1 {
317 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
318 throw InvalidUser(userName);
319 }
320
321 // Store the removed entry in the password file
322 try
323 {
324 _passwordFile->save(_passwordTable);
325 }
326 catch (CannotOpenFile& e)
327 {
328 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
329 throw e;
330 }
331 catch (CannotRenameFile& e)
332 {
333 //
334 // reload password hash table from file
335 //
336 _loadAllUsers();
337 kumpf 1.1.2.1
338 //
339 // creation of backup file failed
340 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
341 throw e;
342 }
343 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
344 }
345
346 //
347 // Get a list of all the user names.
348 //
349 void UserFileHandler::getAllUserNames(Array<String>& userNames)
350 {
351 const char METHOD_NAME[] = "UserFileHandler::getAllUserNames";
352
353 PEG_FUNC_ENTER(TRC_USER_MANAGER,METHOD_NAME);
354
355 userNames.clear();
356
357 for (PasswordTable::Iterator i = _passwordTable.start(); i; i++)
358 kumpf 1.1.2.1 {
359 userNames.append(i.key());
360 }
361 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
362 }
363
364 //
365 // Verify whether the specified CIM user is valid
366 //
367 Boolean UserFileHandler::verifyCIMUser (const String& userName)
368 {
369 const char METHOD_NAME[] = "UserFileHandler::verifyCIMUser";
370
371 PEG_FUNC_ENTER(TRC_USER_MANAGER,METHOD_NAME);
372
373 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
374 return _passwordTable.contains(userName);
375 }
376
377 //
378 // Verify whether the specified user's password is valid
379 kumpf 1.1.2.1 //
380 Boolean UserFileHandler::verifyCIMUserPassword (
381 const String& userName,
382 const String& password)
383 {
384 const char METHOD_NAME[] = "UserFileHandler::verifyCIMUserPassword";
385
386 PEG_FUNC_ENTER(TRC_USER_MANAGER,METHOD_NAME);
387
388 // Check if the user's password mathches the specified password
389 String curPassword = String::EMPTY;
390 String encryptedPassword = String::EMPTY;
391 String saltStr = String::EMPTY;
392
393 // Check if the user exists in the password table
394 if ( !_passwordTable.lookup(userName,curPassword) )
395 {
396 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
397 throw InvalidUser(userName);
398 }
399
400 kumpf 1.1.2.1 saltStr = curPassword.subString(0,2);
401 ArrayDestroyer<char> oldsalt(saltStr.allocateCString());
402 ArrayDestroyer<char> pw(password.allocateCString());
403
404 encryptedPassword =
405 System::encryptPassword(pw.getPointer(),oldsalt.getPointer());
406
407 if ( curPassword != encryptedPassword )
408 {
409 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
410 return false;
411 }
412
413 PEG_FUNC_EXIT(TRC_USER_MANAGER,METHOD_NAME);
414 return true;
415 }
416 PEGASUS_NAMESPACE_END
417
418
|