(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 kumpf 1.6 	throw PEGASUS_CIM_EXCEPTION( CIM_ERR_FAILED, 
194 kumpf 1.3 	"Timed out trying to perform requested operation."
195           	"Please re-try the operation again.");
196               }
197               catch (WaitFailed e)
198               {
199 kumpf 1.6 	throw PEGASUS_CIM_EXCEPTION( CIM_ERR_FAILED, 
200 kumpf 1.3 	"Timed out trying to perform requested operation."
201           	"Please re-try the operation again.");
202               }
203               catch (Deadlock e)
204               {
205 kumpf 1.6 	throw PEGASUS_CIM_EXCEPTION( CIM_ERR_FAILED, 
206 kumpf 1.3 	"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 kumpf 1.7     encryptedPassword = System::encryptPassword(password.getCString(),salt);
305 mike  1.2 
306 kumpf 1.3     // add the user to the cache and password file
307               _Update(ADD_USER,userName, encryptedPassword);
308 mike  1.2 
309 kumpf 1.5     PEG_METHOD_EXIT();
310 mike  1.2 }
311           
312           // 
313           // Modify user entry in file 
314           //
315           void UserFileHandler::modifyUserEntry(
316           	     const String& userName,
317           	     const String& password,
318           	     const String& newPassword )
319           {
320               char 	salt[3];
321               String 	encryptedPassword = String::EMPTY;
322           
323 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::modifyUserEntry");
324 mike  1.2 
325               //
326               // Check if the given password matches the passwd in the file
327               //
328               try
329               {
330                   if ( !verifyCIMUserPassword (userName,password) )
331                   {
332 kumpf 1.5             PEG_METHOD_EXIT();
333 mike  1.2 	    throw PasswordMismatch(userName);
334                   }
335               }
336               catch (Exception& e)
337               {
338 kumpf 1.5         PEG_METHOD_EXIT();
339 mike  1.2 	throw e;
340               }
341           
342               // encrypt new password
343               _GetSalt(salt);
344           
345 kumpf 1.7     encryptedPassword = System::encryptPassword(newPassword.getCString(),salt);
346 mike  1.2 
347 kumpf 1.3     _Update(MODIFY_USER, userName, encryptedPassword);
348 mike  1.2 
349 kumpf 1.5     PEG_METHOD_EXIT();
350 mike  1.2 }
351           
352           // 
353           // Remove user entry from file 
354           // 
355           void UserFileHandler::removeUserEntry(const String& userName)
356           {
357 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::removeUserEntry");
358 mike  1.2 
359 kumpf 1.3     _Update(REMOVE_USER, userName);
360 mike  1.2 
361 kumpf 1.5     PEG_METHOD_EXIT();
362 mike  1.2 }
363           
364           //
365           // Get a list of all the user names.
366           //
367           void UserFileHandler::getAllUserNames(Array<String>& userNames)
368           {
369 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::getAllUserNames");
370 mike  1.2 
371               userNames.clear();
372           
373               for (PasswordTable::Iterator i = _passwordTable.start(); i; i++)
374               {
375                   userNames.append(i.key());
376               }
377 kumpf 1.5     PEG_METHOD_EXIT();
378 mike  1.2 }
379           
380           //
381           // Verify whether the specified CIM user is valid
382           //
383           Boolean UserFileHandler::verifyCIMUser (const String& userName)
384           {
385 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::verifyCIMUser");
386 mike  1.2 
387 kumpf 1.5     PEG_METHOD_EXIT();
388 mike  1.2     return _passwordTable.contains(userName);
389           }
390           
391           //
392           // Verify whether the specified user's password is valid
393           //
394           Boolean UserFileHandler::verifyCIMUserPassword (
395           			    const String& userName, 
396           			    const String& password)
397           {
398 kumpf 1.5     PEG_METHOD_ENTER(TRC_USER_MANAGER,
399                                "UserFileHandler::verifyCIMUserPassword");
400 mike  1.2 
401               // Check if the user's password mathches the specified password
402               String curPassword 		= String::EMPTY;
403               String encryptedPassword 	= String::EMPTY;
404               String saltStr     		= String::EMPTY;
405           
406               // Check if the user exists in the password table
407               if ( !_passwordTable.lookup(userName,curPassword) )
408               {
409 kumpf 1.5         PEG_METHOD_EXIT();
410 mike  1.2         throw InvalidUser(userName);
411               }
412           
413               saltStr = curPassword.subString(0,2);
414           
415               encryptedPassword =
416 kumpf 1.7         System::encryptPassword(password.getCString(),saltStr.getCString());
417 mike  1.2 
418               if ( curPassword != encryptedPassword )
419               {
420 kumpf 1.5         PEG_METHOD_EXIT();
421 mike  1.2         return false;
422               }
423           
424 kumpf 1.5     PEG_METHOD_EXIT();
425 mike  1.2     return true;
426           }
427           PEGASUS_NAMESPACE_END
428           
429           

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2