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

  1 mike  1.2 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3 kumpf 1.6 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4 mike  1.2 // The Open Group, Tivoli Systems
  5           //
  6           // Permission is hereby granted, free of charge, to any person obtaining a copy
  7           // of this software and associated documentation files (the "Software"), to
  8           // deal in the Software without restriction, including without limitation the
  9           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10           // sell copies of the Software, and to permit persons to whom the Software is
 11           // furnished to do so, subject to the following conditions:
 12 kumpf 1.6 // 
 13 mike  1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14           // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 15           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 16           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 17           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 18           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 19           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 20           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21           //
 22           //==============================================================================
 23           //
 24           // Author: Sushma Fernandes, Hewlett Packard Company (sushma_fernandes@hp.com)
 25           //
 26           // Modified By:
 27           //
 28           //%/////////////////////////////////////////////////////////////////////////////
 29           
 30           
 31           #include <cctype>
 32           #include <fstream>
 33           
 34 mike  1.2 #include <Pegasus/Common/FileSystem.h>
 35           #include <Pegasus/Common/Destroyer.h>
 36           #include <Pegasus/Common/Logger.h>
 37           #include <Pegasus/Common/Tracer.h>
 38           
 39           #include <Pegasus/Security/UserManager/PasswordFile.h>
 40           #include <Pegasus/Security/UserManager/UserExceptions.h>
 41           
 42           
 43           PEGASUS_USING_STD;
 44           
 45           PEGASUS_NAMESPACE_BEGIN
 46           
 47           const char COLON = ':';
 48           
 49           /*
 50               Password file header information
 51           */
 52           static const char* PasswordFileHeader [] = {
 53               "########################################################################",
 54               "##                                                                    ##",
 55 mike  1.2     "##                  CIM Server Password file                          ##",
 56               "##                                                                    ##",
 57               "########################################################################",
 58               " ",    
 59               "########################################################################",
 60               "#                                                                      #",
 61               "# This is the password file for the CIMOM. The username/passowrd       #",
 62               "# in this file are loaded in to CIMOM by the User Manager Provider.    #",
 63               "# CIMOM updates this file with the changes .                           #",
 64               "#                                                                      #",
 65               "# The password file stores the user information in username:password   #",
 66               "# format in order to be compatible with Apache's htpasswd generated    #",
 67               "# password file.                                                       #",
 68               "#                                                                      #",
 69               "# The user must not edit this file, instead use                        #",
 70               "# cimuser CLI to make any changes to the CIMOM user information.       #",
 71               "#                                                                      #",
 72               "########################################################################",
 73               " "
 74           };
 75           
 76 mike  1.2 static const int HEADER_SIZE = sizeof(PasswordFileHeader)/sizeof(PasswordFileHeader[0]);
 77           
 78           
 79           ////////////////////////////////////////////////////////////////////////////////
 80           //
 81           //  PasswordFile Class
 82           //
 83           ////////////////////////////////////////////////////////////////////////////////
 84           
 85           
 86           
 87           /** 
 88               Constructor. 
 89           */
 90           PasswordFile::PasswordFile (const String& fileName)
 91           {
 92 kumpf 1.7     PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::PasswordFile");
 93 mike  1.2 
 94               _passwordFile       = fileName;
 95           
 96               _passwordBackupFile = fileName + ".bak";
 97           
 98 kumpf 1.3     try
 99               {
100           	PasswordTable pt;
101                   load(pt);
102               }
103               catch( NoSuchFile& e )
104 mike  1.2     {
105 kumpf 1.3         Logger::put(Logger::ERROR_LOG, "UserManager", Logger::SEVERE,
106                       "Password file not found : $0.", _passwordFile);
107                   Logger::put(Logger::ERROR_LOG, "UserManager", Logger::INFORMATION,
108                       "Creating blank password file.");
109 mike  1.2         PasswordTable pt;
110                   save(pt);
111               }
112 kumpf 1.3     catch ( Exception& e)
113               {
114           	throw e;
115               }
116 kumpf 1.7     PEG_METHOD_EXIT();
117 mike  1.2 }
118           
119           /** 
120               Destructor. 
121           */
122           PasswordFile::~PasswordFile ()
123           {
124 kumpf 1.7     PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::~PasswordFile");
125 mike  1.2 
126 kumpf 1.7     PEG_METHOD_EXIT();
127 mike  1.2 }
128           
129           /** 
130               Load the username and password from the password file.
131           */
132           void PasswordFile::load (PasswordTable& passwordTable)
133           {
134               String line;
135           
136 kumpf 1.7     PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::load");
137 mike  1.2 
138 kumpf 1.3     // 
139               // Check if the backup file exists, if it does use the backup file
140               // If not try to use the password file
141               //
142               if (FileSystem::exists(_passwordBackupFile))
143               {
144           	if (FileSystem::exists(_passwordFile))
145           	{
146           	    if (! FileSystem::removeFile(_passwordFile))
147           	    {
148           		throw CannotRemoveFile(_passwordFile);
149                       }
150                   }
151                   Logger::put(Logger::ERROR_LOG, "UserManager", Logger::INFORMATION,
152                       "Trying to use the backup file : $0.", _passwordBackupFile);
153           	if (! FileSystem::renameFile(_passwordBackupFile, _passwordFile))
154           	{
155                       Logger::put(Logger::ERROR_LOG, "UserManager", Logger::INFORMATION,
156                       "Unable to use the backup file : $0.", _passwordBackupFile);
157           	    throw CannotRenameFile(_passwordBackupFile);
158                   }
159 kumpf 1.3         Logger::put(Logger::ERROR_LOG, "UserManager", Logger::INFORMATION,
160                       "Recovered using the backup file : $0.", _passwordBackupFile);
161               }
162               if (! FileSystem::exists(_passwordFile))
163               {
164           	throw NoSuchFile(_passwordFile);
165               }
166           
167 mike  1.2     //
168               // Open the password file
169               //
170               ArrayDestroyer<char> p(_passwordFile.allocateCString());
171               ifstream ifs(p.getPointer());
172               if (!ifs)
173               {
174 kumpf 1.3         Logger::put(Logger::ERROR_LOG, "UserManager", Logger::SEVERE,
175                       "Error opening password file : $0.", _passwordFile);
176                   return;
177 mike  1.2     }
178           
179               //
180               // Read each line of the file
181               //
182               for (Uint32 lineNumber = 1; GetLine(ifs, line); lineNumber++)
183               {
184                   // Get the userName and password
185           
186                   //
187                   // Skip leading whitespace
188                   //
189                   const Char16* p = line.getData();
190           
191                   while (*p && isspace(*p))
192                   {
193                       p++;
194                   }
195           
196                   if (!*p)
197                   {
198 mike  1.2             continue;
199                   }
200           
201                   //
202                   // Skip comment lines
203                   //
204                   if (*p == '#')
205                   {
206                       continue;
207                   }
208           
209                   //
210                   // Get the userName
211                   //
212                   String userName = String::EMPTY;
213           
214 kumpf 1.8         userName.append(*p++);
215 mike  1.2 
216                   while (isalnum(*p))
217                   {
218 kumpf 1.8             userName.append(*p++);
219 mike  1.2         }
220           
221                   //
222                   // Skip whitespace after user name
223                   //
224                   while (*p && isspace(*p))
225                   {
226                       p++;
227                   }
228           
229                   //
230                   // Expect a colon sign
231                   //
232                   if (*p != COLON) 
233                   {
234           	    //
235           	    // Did not find Colon, log a message and skip entry
236                       //
237                       Logger::put(Logger::ERROR_LOG, "CIMPassword", Logger::INFORMATION,
238 kumpf 1.3             "Error in reading password entry for : $0.", userName);
239 mike  1.2 	    continue;
240                   }
241           
242                   p++;
243           
244                   //
245                   // Skip whitespace after : sign
246                   //
247                   while (*p && isspace(*p))
248                   {
249                       p++;
250                   }
251           
252                   //
253                   // Get the password
254                   //
255                   String password = String::EMPTY;
256           
257                   while (*p)
258                   {
259 kumpf 1.8             password.append(*p++);
260 mike  1.2         }
261           
262                   //
263                   // Store the user name and password in the table
264                   //
265                   if (!passwordTable.insert(userName, password))
266                   {
267                       //
268                       // Duplicate entry for user, ignore the new entry.
269                       //
270                       Logger::put(Logger::ERROR_LOG, "CIMPassword", Logger::INFORMATION,
271 kumpf 1.3             "Duplicate user: $0.", userName);
272 mike  1.2         }
273               }
274           
275               ifs.close();
276 kumpf 1.7     PEG_METHOD_EXIT();
277 mike  1.2 }
278           
279           
280           /** 
281               Save the username and password to the password file.
282           */
283           void PasswordFile::save (PasswordTable& passwordTable)
284           {
285 kumpf 1.7     PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::save");
286 mike  1.2 
287               //
288 kumpf 1.3     // Check if backup password file exists, if it does remove the password file
289               // If it does not rename the password file to password backup file
290 mike  1.2     //
291               if (FileSystem::exists(_passwordBackupFile))
292               {
293 kumpf 1.3 	if ( FileSystem::exists(_passwordFile))
294 mike  1.2 	{
295 kumpf 1.3             if ( ! FileSystem::removeFile(_passwordFile))
296           	    {
297                           Logger::put(Logger::ERROR_LOG, "CIMPassword", Logger::SEVERE,
298                           "Cannot remove password file : $0.", _passwordFile);
299           	        throw CannotRemoveFile(_passwordFile);
300                       }
301 mike  1.2         }
302               }
303 kumpf 1.3     else
304 mike  1.2     {
305 kumpf 1.3 	if ( FileSystem::exists(_passwordFile))
306 mike  1.2 	{
307 kumpf 1.3             if ( ! FileSystem::renameFile(_passwordFile, _passwordBackupFile))
308           	    {
309                           Logger::put(Logger::ERROR_LOG, "CIMPassword", Logger::SEVERE,
310                           "Cannot rename password file : $0.", _passwordFile);
311           	        throw CannotRenameFile(_passwordFile);
312                       }
313 mike  1.2         }
314               }
315           
316               //
317 kumpf 1.3     // Open the password file for writing
318 mike  1.2     //
319 kumpf 1.3     ArrayDestroyer<char> p(_passwordFile.allocateCString());
320 mike  1.2     ofstream ofs(p.getPointer());
321               if (!ofs)
322               {
323 kumpf 1.7         PEG_METHOD_EXIT();
324 mike  1.2 	throw CannotOpenFile(getFileName());
325               }
326           	
327               ofs.clear();
328           
329               //
330               // Write password file header information
331               //
332               
333               for (int index = 0; index < HEADER_SIZE; index++)
334               {
335                   ofs << PasswordFileHeader[index] << endl;
336               }
337           
338               ofs << endl; 
339           
340               //
341               // Save user names and passwords to the new file
342               //
343               for (PasswordTable::Iterator i = passwordTable.start(); i; i++)
344               {
345 mike  1.2         ofs << i.key() << ":" << i.value() << endl;
346               }
347           
348               ofs.close();
349           
350 kumpf 1.3     if ( FileSystem::exists(_passwordBackupFile))
351 mike  1.2     {
352 kumpf 1.3 	if ( ! FileSystem::removeFile(_passwordBackupFile))
353 mike  1.2 	{
354 kumpf 1.3             Logger::put(Logger::ERROR_LOG, "CIMPassword", 
355           	    Logger::SEVERE,
356                       "Cannot remove backup password file : $0.",
357           	    _passwordBackupFile);
358           	    throw CannotRemoveFile(_passwordBackupFile);
359 mike  1.2         }
360               }
361 kumpf 1.7     PEG_METHOD_EXIT();
362 mike  1.2 }
363           
364           PEGASUS_NAMESPACE_END
365           

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2