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

  1 karl  1.21 //%2006////////////////////////////////////////////////////////////////////////
  2 mike  1.2  //
  3 karl  1.16 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6 karl  1.12 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.16 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.19 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.21 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 mike  1.2  //
 14            // Permission is hereby granted, free of charge, to any person obtaining a copy
 15 kumpf 1.4  // of this software and associated documentation files (the "Software"), to
 16            // deal in the Software without restriction, including without limitation the
 17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18 mike  1.2  // sell copies of the Software, and to permit persons to whom the Software is
 19            // furnished to do so, subject to the following conditions:
 20 karl  1.21 // 
 21 kumpf 1.4  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 mike  1.2  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24 kumpf 1.4  // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27 mike  1.2  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29            //
 30 kumpf 1.4  //==============================================================================
 31 mike  1.2  //
 32            // Author: Sushma Fernandes, Hewlett Packard Company (sushma_fernandes@hp.com)
 33            //
 34            // Modified By:
 35 a.arora 1.14 //              Amit K Arora, IBM (amita@in.ibm.com) for PEP#101
 36 a.arora 1.17 //              Josephine Eskaline Joyce (jojustin@in.ibm.com) for PEP#101
 37 joyce.j 1.18 //              Josephine Eskaline Joyce (jojustin@in.ibm.com) for Bug#2486
 38 david.dillard 1.20 //              David Dillard, VERITAS Software Corp.
 39                    //                  (david.dillard@veritas.com)
 40 mike          1.2  //
 41                    //%////////////////////////////////////////////////////////////////////////////
 42                    
 43                    
 44                    ///////////////////////////////////////////////////////////////////////////////
 45 david.dillard 1.20 //
 46                    // This file implements the functionality required to manage password file.
 47 mike          1.2  //
 48                    ///////////////////////////////////////////////////////////////////////////////
 49                    
 50                    #include <Pegasus/Common/FileSystem.h>
 51                    #include <Pegasus/Common/Logger.h>
 52                    #include <Pegasus/Common/System.h>
 53                    #include <Pegasus/Common/Tracer.h>
 54                    
 55 kumpf         1.3  #include <Pegasus/Config/ConfigManager.h>
 56                    
 57 mike          1.2  #include <Pegasus/Security/UserManager/UserFileHandler.h>
 58                    #include <Pegasus/Security/UserManager/UserExceptions.h>
 59 humberto      1.9  #include <Pegasus/Common/MessageLoader.h> //l10n
 60 mike          1.2  
 61                    PEGASUS_USING_STD;
 62                    
 63                    PEGASUS_NAMESPACE_BEGIN
 64                    
 65 david.dillard 1.20 const unsigned char   UserFileHandler::_SALT_STRING[] =
 66 mike          1.2              "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 67                    
 68 david.dillard 1.20 const String UserFileHandler::_PROPERTY_NAME_PASSWORD_FILEPATH =
 69                    	    "passwordFilePath";
 70 kumpf         1.3  
 71                    // Initialize the mutex timeout to 5000 ms.
 72                    const Uint32 UserFileHandler::_MUTEX_TIMEOUT = 5000;
 73                    
 74 mike          1.2  //
 75                    // Generate random salt key for password encryption refer to crypt(3C)
 76                    //
 77                    void UserFileHandler::_GetSalt(char *salt)
 78                    {
 79                        long 	randNum;
 80                        Uint32 	sec;
 81                        Uint32 	milliSec;
 82                    
 83 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::_GetSalt");
 84 mike          1.2  
 85                        //
 86 david.dillard 1.20     // Generate a random number and get the salt
 87 mike          1.2      //
 88                        System::getCurrentTime( sec, milliSec );
 89                    
 90                        srand( (int) sec );
 91 keith.petley  1.10 #ifdef PEGASUS_PLATFORM_SOLARIS_SPARC
 92                        Unit32	seed;
 93                        randNum = rand_r(*seed);
 94                    #else
 95 mike          1.2      randNum = rand();
 96 keith.petley  1.10 #endif
 97 mike          1.2  
 98                        //
 99 david.dillard 1.20     // Make sure the random number generated is between 0-63.
100 mike          1.2      // refer to _SALT_STRING variable
101                        //
102                        *salt++ = _SALT_STRING[ randNum & 0x3f ];
103                        randNum >>= 6;
104                        *salt++ = _SALT_STRING[ randNum & 0x3f ];
105                    
106 s.hills       1.11 	*salt = '\0';
107 mike          1.2  
108 kumpf         1.5      PEG_METHOD_EXIT();
109 mike          1.2  }
110                    
111                    //
112 david.dillard 1.20 // Constructor.
113 mike          1.2  //
114                    UserFileHandler::UserFileHandler()
115                    {
116 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::UserFileHandler");
117 mike          1.2  
118 kumpf         1.3      //
119                        // Get an instance of the ConfigManager.
120                        //
121 joyce.j       1.18     ConfigManager*  configManager;
122                        configManager = ConfigManager::getInstance();
123 mike          1.2  
124 kumpf         1.3      //
125                        // Get the PasswordFilePath property from the Config Manager.
126                        //
127                        String passwdFile;
128 kumpf         1.15     passwdFile = ConfigManager::getHomedPath(
129                            configManager->getCurrentValue(_PROPERTY_NAME_PASSWORD_FILEPATH));
130 mike          1.2  
131 kumpf         1.3      //
132                        // Construct a PasswordFile object.
133                        //
134 a.arora       1.14     _passwordFile.reset(new PasswordFile(passwdFile));
135 mike          1.2  
136                        //
137 kumpf         1.3      // Load the user information in to the cache.
138 mike          1.2      //
139                        try
140                        {
141                            _loadAllUsers();
142                        }
143 david.dillard 1.20     catch  (const Exception&)
144 mike          1.2      {
145 david.dillard 1.20         throw;
146 mike          1.2      }
147                    
148 kumpf         1.3      //
149                        // Initialize the mutex, mutex lock needs to be held for any updates
150                        // to the password cache and password file.
151                        //
152 a.arora       1.14     _mutex.reset(new Mutex);
153 kumpf         1.3  
154 kumpf         1.5      PEG_METHOD_EXIT();
155 mike          1.2  }
156                    
157                    
158                    //
159 david.dillard 1.20 // Destructor.
160 mike          1.2  //
161                    UserFileHandler::~UserFileHandler()
162                    {
163 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::~UserFileHandler");
164 mike          1.2  
165 kumpf         1.5      PEG_METHOD_EXIT();
166 mike          1.2  }
167                    
168 david.dillard 1.20 //
169 mike          1.2  // Load all user names and password
170                    //
171                    void UserFileHandler::_loadAllUsers ()
172                    {
173 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::_loadAllUsers");
174 mike          1.2  
175                        try
176                        {
177                            _passwordTable.clear();
178                            _passwordFile->load(_passwordTable);
179                        }
180 kumpf         1.13     catch (CannotOpenFile&)
181 mike          1.2      {
182                            _passwordTable.clear();
183 kumpf         1.5          PEG_METHOD_EXIT();
184 kumpf         1.13         throw;
185 mike          1.2      }
186 kumpf         1.5      PEG_METHOD_EXIT();
187 mike          1.2  }
188                    
189 kumpf         1.3  void UserFileHandler::_Update(
190                    			   char operation,
191                    			   const String& userName,
192                    			   const String& password)
193                    {
194 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::_Update");
195 kumpf         1.3  
196                        //
197                        // Hold the mutex lock.
198                        // This will allow any one of the update operations to be performed
199                        // at any given time
200                        //
201                    
202                        try
203                        {
204                            _mutex->timed_lock(_MUTEX_TIMEOUT, pegasus_thread_self());
205                        }
206 kumpf         1.13     catch (TimeOut&)
207 kumpf         1.3      {
208 humberto      1.9      	//l10n
209 david.dillard 1.20 	//throw PEGASUS_CIM_EXCEPTION( CIM_ERR_FAILED,
210 humberto      1.9  	//"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 kumpf         1.13     catch (WaitFailed&)
216 kumpf         1.3      {
217 humberto      1.9      //l10n
218 david.dillard 1.20 	//throw PEGASUS_CIM_EXCEPTION( CIM_ERR_FAILED,
219 humberto      1.9  	//"Timed out 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.TIMEOUT",
222                    									"Timed out trying to perform requested operation.Please re-try the operation again."));
223 kumpf         1.3      }
224 kumpf         1.13     catch (Deadlock&)
225 kumpf         1.3      {
226 humberto      1.9      //l10n
227 david.dillard 1.20 	//throw PEGASUS_CIM_EXCEPTION( CIM_ERR_FAILED,
228 humberto      1.9  	//"Deak lock encountered trying to perform requested operation."
229                    	//"Please re-try the operation again.");
230                    	throw PEGASUS_CIM_EXCEPTION_L( CIM_ERR_FAILED, MessageLoaderParms("Security.UserManager.UserFileHandler.DEADLOCK",
231                    						"Deak lock encountered trying to perform requested operation.Please re-try the operation again."));
232 kumpf         1.3      }
233                    
234                        switch (operation)
235                        {
236                    	case ADD_USER:
237                                    if (!_passwordTable.insert(userName,password))
238                                    {
239                                        _mutex->unlock();
240 kumpf         1.5                      PEG_METHOD_EXIT();
241 kumpf         1.3                      throw PasswordCacheError();
242                                    }
243 david.dillard 1.20 		break;
244 kumpf         1.3  
245                    	case MODIFY_USER:
246                                    if (!_passwordTable.remove(userName))
247                                    {
248                                        _mutex->unlock();
249 kumpf         1.5                      PEG_METHOD_EXIT();
250 kumpf         1.3                      throw PasswordCacheError();
251                                    }
252                                    if (!_passwordTable.insert(userName,password))
253                                    {
254                                        _mutex->unlock();
255 humberto      1.9                      //l10n
256 david.dillard 1.20                     //Logger::put(Logger::ERROR_LOG, System::CIMSERVER,
257                    					//Logger::SEVERE,
258 humberto      1.9  					//"Error updating user information for : $0.",userName);
259 david.dillard 1.20 					Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER,Logger::SEVERE,
260 humberto      1.9  						"Security.UserManager.UserFileHandler.ERROR_UPDATING_USER_INFO",
261                    						"Error updating user information for : $0.",userName);
262 kumpf         1.5                      PEG_METHOD_EXIT();
263 kumpf         1.3                      throw PasswordCacheError();
264                                    }
265 david.dillard 1.20 	        break;
266 kumpf         1.3  
267                    	case REMOVE_USER:
268                    
269                                    //Remove the existing user name and password from the table
270                                    if (!_passwordTable.remove(userName))
271                                    {
272                                        _mutex->unlock();
273 kumpf         1.5                      PEG_METHOD_EXIT();
274 kumpf         1.3                      throw InvalidUser(userName);
275                                    }
276 david.dillard 1.20 	        break;
277                    
278 kumpf         1.3  	default:
279                    		// Should never get here
280                    		break;
281                        }
282 david.dillard 1.20 
283 kumpf         1.3      // Store the entry in the password file
284                        try
285                        {
286                            _passwordFile->save(_passwordTable);
287                        }
288 david.dillard 1.20     catch (const CannotOpenFile&)
289 kumpf         1.3      {
290                            _mutex->unlock();
291 kumpf         1.5          PEG_METHOD_EXIT();
292 david.dillard 1.20         throw;
293 kumpf         1.3      }
294 david.dillard 1.20     catch (const CannotRenameFile&)
295 kumpf         1.3      {
296                            //
297                            // reload password hash table from file
298                            //
299                            _loadAllUsers();
300                    
301                            _mutex->unlock();
302 kumpf         1.5          PEG_METHOD_EXIT();
303 david.dillard 1.20         throw;
304 kumpf         1.3      }
305                        _mutex->unlock();
306 kumpf         1.5      PEG_METHOD_EXIT();
307 kumpf         1.3  }
308                    
309                    
310 david.dillard 1.20 //
311 mike          1.2  // Add user entry to file
312 david.dillard 1.20 //
313 mike          1.2  void UserFileHandler::addUserEntry(
314 david.dillard 1.20 			    const String& userName,
315 mike          1.2  			    const String& password)
316                    {
317                        char 	salt[3];
318                        String 	encryptedPassword = String::EMPTY;
319                    
320 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::addUserEntry");
321 mike          1.2  
322                        // Check if the user already exists
323                        if (_passwordTable.contains(userName))
324                        {
325 kumpf         1.5          PEG_METHOD_EXIT();
326 mike          1.2  	throw DuplicateUser(userName);
327                        }
328                    
329                        // encrypt password
330                        _GetSalt(salt);
331                    
332 kumpf         1.7      encryptedPassword = System::encryptPassword(password.getCString(),salt);
333 mike          1.2  
334 kumpf         1.3      // add the user to the cache and password file
335                        _Update(ADD_USER,userName, encryptedPassword);
336 mike          1.2  
337 kumpf         1.5      PEG_METHOD_EXIT();
338 mike          1.2  }
339                    
340 david.dillard 1.20 //
341                    // Modify user entry in file
342 mike          1.2  //
343                    void UserFileHandler::modifyUserEntry(
344                    	     const String& userName,
345                    	     const String& password,
346                    	     const String& newPassword )
347                    {
348                        char 	salt[3];
349                        String 	encryptedPassword = String::EMPTY;
350                    
351 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::modifyUserEntry");
352 mike          1.2  
353                        //
354                        // Check if the given password matches the passwd in the file
355                        //
356                        try
357                        {
358                            if ( !verifyCIMUserPassword (userName,password) )
359                            {
360 kumpf         1.5              PEG_METHOD_EXIT();
361 david.dillard 1.20             throw PasswordMismatch(userName);
362 mike          1.2          }
363                        }
364 david.dillard 1.20     catch (const Exception&)
365 mike          1.2      {
366 kumpf         1.5          PEG_METHOD_EXIT();
367 david.dillard 1.20         throw;
368 mike          1.2      }
369                    
370                        // encrypt new password
371                        _GetSalt(salt);
372                    
373 kumpf         1.7      encryptedPassword = System::encryptPassword(newPassword.getCString(),salt);
374 mike          1.2  
375 kumpf         1.3      _Update(MODIFY_USER, userName, encryptedPassword);
376 mike          1.2  
377 kumpf         1.5      PEG_METHOD_EXIT();
378 mike          1.2  }
379                    
380 david.dillard 1.20 //
381                    // Remove user entry from file
382                    //
383 mike          1.2  void UserFileHandler::removeUserEntry(const String& userName)
384                    {
385 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::removeUserEntry");
386 mike          1.2  
387 kumpf         1.3      _Update(REMOVE_USER, userName);
388 mike          1.2  
389 kumpf         1.5      PEG_METHOD_EXIT();
390 mike          1.2  }
391                    
392                    //
393                    // Get a list of all the user names.
394                    //
395                    void UserFileHandler::getAllUserNames(Array<String>& userNames)
396                    {
397 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::getAllUserNames");
398 mike          1.2  
399                        userNames.clear();
400                    
401                        for (PasswordTable::Iterator i = _passwordTable.start(); i; i++)
402                        {
403                            userNames.append(i.key());
404                        }
405 kumpf         1.5      PEG_METHOD_EXIT();
406 mike          1.2  }
407                    
408                    //
409                    // Verify whether the specified CIM user is valid
410                    //
411                    Boolean UserFileHandler::verifyCIMUser (const String& userName)
412                    {
413 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::verifyCIMUser");
414 mike          1.2  
415 kumpf         1.5      PEG_METHOD_EXIT();
416 mike          1.2      return _passwordTable.contains(userName);
417                    }
418                    
419                    //
420                    // Verify whether the specified user's password is valid
421                    //
422                    Boolean UserFileHandler::verifyCIMUserPassword (
423 david.dillard 1.20 			    const String& userName,
424 mike          1.2  			    const String& password)
425                    {
426 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER,
427                                         "UserFileHandler::verifyCIMUserPassword");
428 mike          1.2  
429                        // Check if the user's password mathches the specified password
430                        String curPassword 		= String::EMPTY;
431                        String encryptedPassword 	= String::EMPTY;
432                        String saltStr     		= String::EMPTY;
433                    
434                        // Check if the user exists in the password table
435                        if ( !_passwordTable.lookup(userName,curPassword) )
436                        {
437 kumpf         1.5          PEG_METHOD_EXIT();
438 mike          1.2          throw InvalidUser(userName);
439                        }
440                    
441                        saltStr = curPassword.subString(0,2);
442                    
443                        encryptedPassword =
444 kumpf         1.7          System::encryptPassword(password.getCString(),saltStr.getCString());
445 mike          1.2  
446                        if ( curPassword != encryptedPassword )
447                        {
448 kumpf         1.5          PEG_METHOD_EXIT();
449 mike          1.2          return false;
450                        }
451                    
452 kumpf         1.5      PEG_METHOD_EXIT();
453 mike          1.2      return true;
454                    }
455                    PEGASUS_NAMESPACE_END
456                    
457                    

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2