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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2