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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2