(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                    
208                        switch (operation)
209                        {
210 kumpf         1.23         case ADD_USER:
211 kumpf         1.3                  if (!_passwordTable.insert(userName,password))
212                                    {
213                                        _mutex->unlock();
214 kumpf         1.5                      PEG_METHOD_EXIT();
215 kumpf         1.3                      throw PasswordCacheError();
216                                    }
217 kumpf         1.23                 break;
218 kumpf         1.3  
219 kumpf         1.23         case MODIFY_USER:
220 kumpf         1.3                  if (!_passwordTable.remove(userName))
221                                    {
222                                        _mutex->unlock();
223 kumpf         1.5                      PEG_METHOD_EXIT();
224 kumpf         1.3                      throw PasswordCacheError();
225                                    }
226                                    if (!_passwordTable.insert(userName,password))
227                                    {
228                                        _mutex->unlock();
229 kumpf         1.23                     Logger::put_l(
230                                            Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
231 kumpf         1.27                         MessageLoaderParms(
232                                                "Security.UserManager.UserFileHandler."
233                                                    "ERROR_UPDATING_USER_INFO",
234                                                "Error updating the user information for user $0.",
235                                                userName));
236 kumpf         1.5                      PEG_METHOD_EXIT();
237 kumpf         1.3                      throw PasswordCacheError();
238                                    }
239 kumpf         1.23                 break;
240 kumpf         1.3  
241 kumpf         1.23         case REMOVE_USER:
242 kumpf         1.3  
243                                    //Remove the existing user name and password from the table
244                                    if (!_passwordTable.remove(userName))
245                                    {
246                                        _mutex->unlock();
247 kumpf         1.5                      PEG_METHOD_EXIT();
248 kumpf         1.3                      throw InvalidUser(userName);
249                                    }
250 kumpf         1.23                 break;
251 david.dillard 1.20 
252 kumpf         1.23         default:
253                                    // Should never get here
254                                    break;
255 kumpf         1.3      }
256 david.dillard 1.20 
257 kumpf         1.3      // Store the entry in the password file
258                        try
259                        {
260                            _passwordFile->save(_passwordTable);
261                        }
262 david.dillard 1.20     catch (const CannotOpenFile&)
263 kumpf         1.3      {
264                            _mutex->unlock();
265 kumpf         1.5          PEG_METHOD_EXIT();
266 david.dillard 1.20         throw;
267 kumpf         1.3      }
268 david.dillard 1.20     catch (const CannotRenameFile&)
269 kumpf         1.3      {
270                            //
271                            // reload password hash table from file
272                            //
273                            _loadAllUsers();
274                    
275                            _mutex->unlock();
276 kumpf         1.5          PEG_METHOD_EXIT();
277 david.dillard 1.20         throw;
278 kumpf         1.3      }
279                        _mutex->unlock();
280 kumpf         1.5      PEG_METHOD_EXIT();
281 kumpf         1.3  }
282                    
283                    
284 david.dillard 1.20 //
285 mike          1.2  // Add user entry to file
286 david.dillard 1.20 //
287 mike          1.2  void UserFileHandler::addUserEntry(
288 kumpf         1.23     const String& userName,
289                        const String& password)
290 mike          1.2  {
291 kumpf         1.23     char salt[3];
292                        String encryptedPassword;
293 mike          1.2  
294 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::addUserEntry");
295 mike          1.2  
296                        // Check if the user already exists
297                        if (_passwordTable.contains(userName))
298                        {
299 kumpf         1.5          PEG_METHOD_EXIT();
300 kumpf         1.23         throw DuplicateUser(userName);
301 mike          1.2      }
302                    
303                        // encrypt password
304                        _GetSalt(salt);
305                    
306 kumpf         1.7      encryptedPassword = System::encryptPassword(password.getCString(),salt);
307 mike          1.2  
308 kumpf         1.3      // add the user to the cache and password file
309                        _Update(ADD_USER,userName, encryptedPassword);
310 mike          1.2  
311 kumpf         1.5      PEG_METHOD_EXIT();
312 mike          1.2  }
313                    
314 david.dillard 1.20 //
315                    // Modify user entry in file
316 mike          1.2  //
317                    void UserFileHandler::modifyUserEntry(
318 kumpf         1.23     const String& userName,
319                        const String& password,
320                        const String& newPassword)
321 mike          1.2  {
322 kumpf         1.23     char salt[3];
323                        String encryptedPassword;
324 mike          1.2  
325 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::modifyUserEntry");
326 mike          1.2  
327                        //
328                        // Check if the given password matches the passwd in the file
329                        //
330 kumpf         1.24     if (!verifyCIMUserPassword(userName,password))
331 mike          1.2      {
332 kumpf         1.5          PEG_METHOD_EXIT();
333 kumpf         1.24         throw PasswordMismatch(userName);
334 mike          1.2      }
335                    
336                        // encrypt new password
337                        _GetSalt(salt);
338                    
339 kumpf         1.7      encryptedPassword = System::encryptPassword(newPassword.getCString(),salt);
340 mike          1.2  
341 kumpf         1.3      _Update(MODIFY_USER, userName, encryptedPassword);
342 mike          1.2  
343 kumpf         1.5      PEG_METHOD_EXIT();
344 mike          1.2  }
345                    
346 david.dillard 1.20 //
347                    // Remove user entry from file
348                    //
349 mike          1.2  void UserFileHandler::removeUserEntry(const String& userName)
350                    {
351 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::removeUserEntry");
352 mike          1.2  
353 kumpf         1.3      _Update(REMOVE_USER, userName);
354 mike          1.2  
355 kumpf         1.5      PEG_METHOD_EXIT();
356 mike          1.2  }
357                    
358                    //
359                    // Get a list of all the user names.
360                    //
361                    void UserFileHandler::getAllUserNames(Array<String>& userNames)
362                    {
363 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::getAllUserNames");
364 mike          1.2  
365                        userNames.clear();
366                    
367                        for (PasswordTable::Iterator i = _passwordTable.start(); i; i++)
368                        {
369                            userNames.append(i.key());
370                        }
371 kumpf         1.5      PEG_METHOD_EXIT();
372 mike          1.2  }
373                    
374                    //
375                    // Verify whether the specified CIM user is valid
376                    //
377                    Boolean UserFileHandler::verifyCIMUser (const String& userName)
378                    {
379 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER, "UserFileHandler::verifyCIMUser");
380 mike          1.2  
381 kumpf         1.5      PEG_METHOD_EXIT();
382 mike          1.2      return _passwordTable.contains(userName);
383                    }
384                    
385                    //
386                    // Verify whether the specified user's password is valid
387                    //
388 kumpf         1.23 Boolean UserFileHandler::verifyCIMUserPassword(
389                        const String& userName,
390                        const String& password)
391 mike          1.2  {
392 kumpf         1.5      PEG_METHOD_ENTER(TRC_USER_MANAGER,
393 kumpf         1.23         "UserFileHandler::verifyCIMUserPassword");
394 mike          1.2  
395                        // Check if the user's password mathches the specified password
396 kumpf         1.23     String curPassword;
397                        String encryptedPassword;
398                        String saltStr;
399 mike          1.2  
400                        // Check if the user exists in the password table
401                        if ( !_passwordTable.lookup(userName,curPassword) )
402                        {
403 kumpf         1.5          PEG_METHOD_EXIT();
404 mike          1.2          throw InvalidUser(userName);
405                        }
406                    
407                        saltStr = curPassword.subString(0,2);
408                    
409                        encryptedPassword =
410 kumpf         1.7          System::encryptPassword(password.getCString(),saltStr.getCString());
411 mike          1.2  
412 venkat.puvvada 1.26     if ( curPassword != encryptedPassword )
413 mike           1.2      {
414 kumpf          1.5          PEG_METHOD_EXIT();
415 mike           1.2          return false;
416                         }
417                     
418 kumpf          1.5      PEG_METHOD_EXIT();
419 mike           1.2      return true;
420                     }
421                     PEGASUS_NAMESPACE_END
422                     
423                     

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2