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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2