(file) Return to UserFileHandler.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Security / UserManager

  1 kumpf 1.4 //%/////////////////////////////////////////////////////////////////////////////
  2 mike  1.2 //
  3 kumpf 1.4 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4 mike  1.2 // The Open Group, Tivoli Systems
  5           //
  6           // Permission is hereby granted, free of charge, to any person obtaining a copy
  7 kumpf 1.4 // 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 mike  1.2 // 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 kumpf 1.4 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14 mike  1.2 // 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 kumpf 1.4 // 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 mike  1.2 // 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.4 //==============================================================================
 23 mike  1.2 //
 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.3 #include <Pegasus/Config/ConfigManager.h>
 44           
 45 mike  1.2 #include <Pegasus/Security/UserManager/UserFileHandler.h>
 46           #include <Pegasus/Security/UserManager/UserExceptions.h>
 47           
 48           PEGASUS_USING_STD;
 49           
 50           PEGASUS_NAMESPACE_BEGIN
 51           
 52           const unsigned char   UserFileHandler::_SALT_STRING[] =         
 53                       "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 54           
 55 kumpf 1.3 const String UserFileHandler::_PROPERTY_NAME_PASSWORD_FILEPATH = 
 56           	    "passwordFilePath"; 
 57           
 58           // Initialize the mutex timeout to 5000 ms.
 59           const Uint32 UserFileHandler::_MUTEX_TIMEOUT = 5000;
 60           
 61 mike  1.2 //
 62           // Generate random salt key for password encryption refer to crypt(3C)
 63           //
 64           void UserFileHandler::_GetSalt(char *salt)
 65           {
 66               long 	randNum;
 67               Uint32 	sec;
 68               Uint32 	milliSec;
 69           
 70 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::_GetSalt");
 71 mike  1.2 
 72               //
 73               // Generate a random number and get the salt 
 74               //
 75               System::getCurrentTime( sec, milliSec );
 76           
 77               srand( (int) sec );
 78               randNum = rand();
 79           
 80               //
 81               // Make sure the random number generated is between 0-63. 
 82               // refer to _SALT_STRING variable
 83               //
 84               *salt++ = _SALT_STRING[ randNum & 0x3f ];
 85               randNum >>= 6;
 86               *salt++ = _SALT_STRING[ randNum & 0x3f ];
 87           
 88               salt[2] = '\0';
 89           
 90 kumpf 1.5     PEG_METHOD_EXIT();
 91 mike  1.2 }
 92           
 93           //
 94           // Constructor. 
 95           //
 96           UserFileHandler::UserFileHandler()
 97           {
 98 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::UserFileHandler");
 99 mike  1.2 
100 kumpf 1.3     //
101               // Get an instance of the ConfigManager.
102               //
103               ConfigManager*  configManager;
104               configManager = ConfigManager::getInstance();
105 mike  1.2 
106 kumpf 1.3     //
107               // Get the PasswordFilePath property from the Config Manager.
108               //
109               String passwdFile;
110               passwdFile = configManager->getCurrentValue(
111                                  _PROPERTY_NAME_PASSWORD_FILEPATH);
112 mike  1.2 
113 kumpf 1.3     //
114               // Construct a PasswordFile object.
115               //
116               _passwordFile   = new PasswordFile(passwdFile);
117 mike  1.2 
118               //
119 kumpf 1.3     // Load the user information in to the cache.
120 mike  1.2     //
121               try
122               {
123                   _loadAllUsers();
124               }
125               catch  (Exception& e)
126               {
127           	throw e;
128               }
129           
130 kumpf 1.3     //
131               // Initialize the mutex, mutex lock needs to be held for any updates
132               // to the password cache and password file.
133               //
134               _mutex = new Mutex;
135           
136 kumpf 1.5     PEG_METHOD_EXIT();
137 mike  1.2 }
138           
139           
140           //
141           // Destructor. 
142           //
143           UserFileHandler::~UserFileHandler()
144           {
145 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::~UserFileHandler");
146 mike  1.2 
147               delete _passwordFile;
148 kumpf 1.3     delete _mutex;
149 mike  1.2 
150 kumpf 1.5     PEG_METHOD_EXIT();
151 mike  1.2 }
152           
153           // 
154           // Load all user names and password
155           //
156           void UserFileHandler::_loadAllUsers ()
157           {
158 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::_loadAllUsers");
159 mike  1.2 
160               try
161               {
162                   _passwordTable.clear();
163                   _passwordFile->load(_passwordTable);
164               }
165               catch (CannotOpenFile cof)
166               {
167                   _passwordTable.clear();
168 kumpf 1.5         PEG_METHOD_EXIT();
169 mike  1.2         throw cof;
170               }
171 kumpf 1.5     PEG_METHOD_EXIT();
172 mike  1.2 }
173           
174 kumpf 1.3 void UserFileHandler::_Update(
175           			   char operation,
176           			   const String& userName,
177           			   const String& password)
178           {
179 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::_Update");
180 kumpf 1.3 
181               //
182               // Hold the mutex lock.
183               // This will allow any one of the update operations to be performed
184               // at any given time
185               //
186           
187               try
188               {
189                   _mutex->timed_lock(_MUTEX_TIMEOUT, pegasus_thread_self());
190               }
191               catch (TimeOut e)
192               {
193           	throw CIMException( CIM_ERR_FAILED, 
194           	"Timed out trying to perform requested operation."
195           	"Please re-try the operation again.");
196               }
197               catch (WaitFailed e)
198               {
199           	throw CIMException( CIM_ERR_FAILED, 
200           	"Timed out trying to perform requested operation."
201 kumpf 1.3 	"Please re-try the operation again.");
202               }
203               catch (Deadlock e)
204               {
205           	throw CIMException( CIM_ERR_FAILED, 
206           	"Deak lock encountered trying to perform requested operation."
207           	"Please re-try the operation again.");
208               }
209           
210               switch (operation)
211               {
212           	case ADD_USER:
213                           if (!_passwordTable.insert(userName,password))
214                           {
215                               _mutex->unlock();
216 kumpf 1.5                     PEG_METHOD_EXIT();
217 kumpf 1.3                     throw PasswordCacheError();
218                           }
219           		break; 
220           
221           	case MODIFY_USER:
222                           if (!_passwordTable.remove(userName))
223                           {
224                               _mutex->unlock();
225 kumpf 1.5                     PEG_METHOD_EXIT();
226 kumpf 1.3                     throw PasswordCacheError();
227                           }
228                           if (!_passwordTable.insert(userName,password))
229                           {
230                               _mutex->unlock();
231                               Logger::put(Logger::ERROR_LOG, "UserManager", 
232           			Logger::SEVERE, 
233           			"Error updating user information for : $0.",userName);
234 kumpf 1.5                     PEG_METHOD_EXIT();
235 kumpf 1.3                     throw PasswordCacheError();
236                           }
237           	        break; 
238           
239           	case REMOVE_USER:
240           
241                           //Remove the existing user name and password from the table
242                           if (!_passwordTable.remove(userName))
243                           {
244                               _mutex->unlock();
245 kumpf 1.5                     PEG_METHOD_EXIT();
246 kumpf 1.3                     throw InvalidUser(userName);
247                           }
248           	        break; 
249                   
250           	default:
251           		// Should never get here
252           		break;
253               }
254               
255               // Store the entry in the password file
256               try
257               {
258                   _passwordFile->save(_passwordTable);
259               }
260               catch (CannotOpenFile& e)
261               {
262                   _mutex->unlock();
263 kumpf 1.5         PEG_METHOD_EXIT();
264 kumpf 1.3         throw e;
265               }
266               catch (CannotRenameFile& e)
267               {
268                   //
269                   // reload password hash table from file
270                   //
271                   _loadAllUsers();
272           
273                   _mutex->unlock();
274 kumpf 1.5         PEG_METHOD_EXIT();
275 kumpf 1.3         throw e;
276               }
277               _mutex->unlock();
278 kumpf 1.5     PEG_METHOD_EXIT();
279 kumpf 1.3 }
280           
281           
282 mike  1.2 // 
283           // Add user entry to file
284           // 
285           void UserFileHandler::addUserEntry(
286           			    const String& userName, 
287           			    const String& password)
288           {
289               char 	salt[3];
290               String 	encryptedPassword = String::EMPTY;
291           
292 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::addUserEntry");
293 mike  1.2 
294               // Check if the user already exists
295               if (_passwordTable.contains(userName))
296               {
297 kumpf 1.5         PEG_METHOD_EXIT();
298 mike  1.2 	throw DuplicateUser(userName);
299               }
300           
301               // encrypt password
302               _GetSalt(salt);
303           
304               ArrayDestroyer<char> pw(password.allocateCString());
305           
306               encryptedPassword = System::encryptPassword(pw.getPointer(),salt);
307           
308 kumpf 1.3     // add the user to the cache and password file
309               _Update(ADD_USER,userName, encryptedPassword);
310 mike  1.2 
311 kumpf 1.5     PEG_METHOD_EXIT();
312 mike  1.2 }
313           
314           // 
315           // Modify user entry in file 
316           //
317           void UserFileHandler::modifyUserEntry(
318           	     const String& userName,
319           	     const String& password,
320           	     const String& newPassword )
321           {
322               char 	salt[3];
323               String 	encryptedPassword = String::EMPTY;
324           
325 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::modifyUserEntry");
326 mike  1.2 
327               //
328               // Check if the given password matches the passwd in the file
329               //
330               try
331               {
332                   if ( !verifyCIMUserPassword (userName,password) )
333                   {
334 kumpf 1.5             PEG_METHOD_EXIT();
335 mike  1.2 	    throw PasswordMismatch(userName);
336                   }
337               }
338               catch (Exception& e)
339               {
340 kumpf 1.5         PEG_METHOD_EXIT();
341 mike  1.2 	throw e;
342               }
343           
344               // encrypt new password
345               _GetSalt(salt);
346           
347               ArrayDestroyer<char> npw(newPassword.allocateCString());
348           
349               encryptedPassword = System::encryptPassword(npw.getPointer(),salt);
350           
351 kumpf 1.3     _Update(MODIFY_USER, userName, encryptedPassword);
352 mike  1.2 
353 kumpf 1.5     PEG_METHOD_EXIT();
354 mike  1.2 }
355           
356           // 
357           // Remove user entry from file 
358           // 
359           void UserFileHandler::removeUserEntry(const String& userName)
360           {
361 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::removeUserEntry");
362 mike  1.2 
363 kumpf 1.3     _Update(REMOVE_USER, userName);
364 mike  1.2 
365 kumpf 1.5     PEG_METHOD_EXIT();
366 mike  1.2 }
367           
368           //
369           // Get a list of all the user names.
370           //
371           void UserFileHandler::getAllUserNames(Array<String>& userNames)
372           {
373 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::getAllUserNames");
374 mike  1.2 
375               userNames.clear();
376           
377               for (PasswordTable::Iterator i = _passwordTable.start(); i; i++)
378               {
379                   userNames.append(i.key());
380               }
381 kumpf 1.5     PEG_METHOD_EXIT();
382 mike  1.2 }
383           
384           //
385           // Verify whether the specified CIM user is valid
386           //
387           Boolean UserFileHandler::verifyCIMUser (const String& userName)
388           {
389 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::verifyCIMUser");
390 mike  1.2 
391 kumpf 1.5     PEG_METHOD_EXIT();
392 mike  1.2     return _passwordTable.contains(userName);
393           }
394           
395           //
396           // Verify whether the specified user's password is valid
397           //
398           Boolean UserFileHandler::verifyCIMUserPassword (
399           			    const String& userName, 
400           			    const String& password)
401           {
402 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER,
403                                "UserFileHandler::verifyCIMUserPassword");
404 mike  1.2 
405               // Check if the user's password mathches the specified password
406               String curPassword 		= String::EMPTY;
407               String encryptedPassword 	= String::EMPTY;
408               String saltStr     		= String::EMPTY;
409           
410               // Check if the user exists in the password table
411               if ( !_passwordTable.lookup(userName,curPassword) )
412               {
413 kumpf 1.5         PEG_METHOD_EXIT();
414 mike  1.2         throw InvalidUser(userName);
415               }
416           
417               saltStr = curPassword.subString(0,2);
418               ArrayDestroyer<char> oldsalt(saltStr.allocateCString());
419               ArrayDestroyer<char> pw(password.allocateCString());
420           
421               encryptedPassword =
422                           System::encryptPassword(pw.getPointer(),oldsalt.getPointer());
423           
424               if ( curPassword != encryptedPassword )
425               {
426 kumpf 1.5         PEG_METHOD_EXIT();
427 mike  1.2         return false;
428               }
429           
430 kumpf 1.5     PEG_METHOD_EXIT();
431 mike  1.2     return true;
432           }
433           PEGASUS_NAMESPACE_END
434           
435           

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2