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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2