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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2