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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2