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 david 1.13 #if defined(PEGASUS_OS_OS400)
39 #include "OS400ConvertChar.h"
40 #endif
|
41 mike 1.2
42 #include <Pegasus/Security/UserManager/PasswordFile.h>
43 #include <Pegasus/Security/UserManager/UserExceptions.h>
44
45
46 PEGASUS_USING_STD;
47
48 PEGASUS_NAMESPACE_BEGIN
49
50 const char COLON = ':';
51
52 /*
53 Password file header information
54 */
55 static const char* PasswordFileHeader [] = {
56 "########################################################################",
57 "## ##",
58 "## CIM Server Password file ##",
59 "## ##",
60 "########################################################################",
61 " ",
62 mike 1.2 "########################################################################",
63 "# #",
64 "# This is the password file for the CIMOM. The username/passowrd #",
65 "# in this file are loaded in to CIMOM by the User Manager Provider. #",
66 "# CIMOM updates this file with the changes . #",
67 "# #",
68 "# The password file stores the user information in username:password #",
69 "# format in order to be compatible with Apache's htpasswd generated #",
70 "# password file. #",
71 "# #",
72 "# The user must not edit this file, instead use #",
73 "# cimuser CLI to make any changes to the CIMOM user information. #",
74 "# #",
75 "########################################################################",
76 " "
77 };
78
79 static const int HEADER_SIZE = sizeof(PasswordFileHeader)/sizeof(PasswordFileHeader[0]);
80
81
82 ////////////////////////////////////////////////////////////////////////////////
83 mike 1.2 //
84 // PasswordFile Class
85 //
86 ////////////////////////////////////////////////////////////////////////////////
87
88
89
90 /**
91 Constructor.
92 */
93 PasswordFile::PasswordFile (const String& fileName)
94 {
|
95 kumpf 1.7 PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::PasswordFile");
|
96 mike 1.2
97 _passwordFile = fileName;
98
99 _passwordBackupFile = fileName + ".bak";
100
|
101 kumpf 1.3 try
102 {
103 PasswordTable pt;
104 load(pt);
105 }
106 catch( NoSuchFile& e )
|
107 mike 1.2 {
|
108 humberto 1.12 //l10n
109 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
110 //"Password file not found : $0.", _passwordFile);
111 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
112 //"Creating blank password file.");
113 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
114 "Security.UserManager.PasswordFile.PWD_FILE_NOT_FOUND",
|
115 kumpf 1.3 "Password file not found : $0.", _passwordFile);
|
116 humberto 1.12 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
117 "Security.UserManager.PasswordFile.CREATING_BLANK_PWD_FILE",
|
118 kumpf 1.3 "Creating blank password file.");
|
119 mike 1.2 PasswordTable pt;
120 save(pt);
121 }
|
122 kumpf 1.3 catch ( Exception& e)
123 {
124 throw e;
125 }
|
126 kumpf 1.7 PEG_METHOD_EXIT();
|
127 mike 1.2 }
128
129 /**
130 Destructor.
131 */
132 PasswordFile::~PasswordFile ()
133 {
|
134 kumpf 1.7 PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::~PasswordFile");
|
135 mike 1.2
|
136 kumpf 1.7 PEG_METHOD_EXIT();
|
137 mike 1.2 }
138
139 /**
140 Load the username and password from the password file.
141 */
142 void PasswordFile::load (PasswordTable& passwordTable)
143 {
144 String line;
145
|
146 kumpf 1.7 PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::load");
|
147 mike 1.2
|
148 kumpf 1.3 //
149 // Check if the backup file exists, if it does use the backup file
150 // If not try to use the password file
151 //
152 if (FileSystem::exists(_passwordBackupFile))
153 {
154 if (FileSystem::exists(_passwordFile))
155 {
156 if (! FileSystem::removeFile(_passwordFile))
157 {
158 throw CannotRemoveFile(_passwordFile);
159 }
160 }
|
161 humberto 1.12 //l10n
162 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
163 //"Trying to use the backup file : $0.", _passwordBackupFile);
164 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
165 "Security.UserManager.PasswordFile.TRYING_TO_BACKUP_FILE",
|
166 kumpf 1.3 "Trying to use the backup file : $0.", _passwordBackupFile);
167 if (! FileSystem::renameFile(_passwordBackupFile, _passwordFile))
168 {
|
169 humberto 1.12 //l10n
170 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
171 //"Unable to use the backup file : $0.", _passwordBackupFile);
172 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
173 "Security.UserManager.PasswordFile.CANNOT_USE_BACKUP_FILE",
174 "Unable to use the backup file : $0.", _passwordBackupFile);
|
175 kumpf 1.3 throw CannotRenameFile(_passwordBackupFile);
176 }
|
177 humberto 1.12 //l10n
178 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
179 //"Recovered using the backup file : $0.", _passwordBackupFile);
180 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
181 "Security.UserManager.PasswordFile.RECOVERED_USING_BACKUP_FILE",
|
182 kumpf 1.3 "Recovered using the backup file : $0.", _passwordBackupFile);
183 }
184 if (! FileSystem::exists(_passwordFile))
185 {
186 throw NoSuchFile(_passwordFile);
187 }
188
|
189 mike 1.2 //
190 // Open the password file
191 //
|
192 david 1.13 #if defined(PEGASUS_OS_OS400)
|
193 david 1.14 ifstream ifs(_passwordFile.getCStringUTF8(), PEGASUS_STD(_CCSID_T(1208)));
|
194 david 1.13 #else
|
195 david 1.14 ifstream ifs(_passwordFile.getCStringUTF8());
|
196 david 1.13 #endif
|
197 mike 1.2 if (!ifs)
198 {
|
199 humberto 1.12 //l10n
200 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
201 //"Error opening password file : $0.", _passwordFile);
202 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
203 "Security.UserManager.PasswordFile.ERROR_OPENING_PWD_FILE",
|
204 kumpf 1.3 "Error opening password file : $0.", _passwordFile);
205 return;
|
206 mike 1.2 }
207
208 //
209 // Read each line of the file
210 //
211 for (Uint32 lineNumber = 1; GetLine(ifs, line); lineNumber++)
212 {
213 // Get the userName and password
214
215 //
216 // Skip leading whitespace
217 //
|
218 kumpf 1.10 const Char16* p = line.getChar16Data();
|
219 mike 1.2
220 while (*p && isspace(*p))
221 {
222 p++;
223 }
224
225 if (!*p)
226 {
227 continue;
228 }
229
230 //
231 // Skip comment lines
232 //
233 if (*p == '#')
234 {
235 continue;
236 }
237
238 //
239 // Get the userName
240 mike 1.2 //
241 String userName = String::EMPTY;
242
|
243 kumpf 1.8 userName.append(*p++);
|
244 mike 1.2
245 while (isalnum(*p))
246 {
|
247 kumpf 1.8 userName.append(*p++);
|
248 mike 1.2 }
249
250 //
251 // Skip whitespace after user name
252 //
253 while (*p && isspace(*p))
254 {
255 p++;
256 }
257
258 //
259 // Expect a colon sign
260 //
261 if (*p != COLON)
262 {
263 //
264 // Did not find Colon, log a message and skip entry
|
265 humberto 1.12 //l10n
266 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
267 //"Error in reading password entry for : $0.", userName);
268 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
269 "Security.UserManager.PasswordFile.ERROR_READING_PWD_ENTRY",
270 "Error in reading password entry for : $0.", userName);
|
271 mike 1.2 continue;
272 }
273
274 p++;
275
276 //
277 // Skip whitespace after : sign
278 //
279 while (*p && isspace(*p))
280 {
281 p++;
282 }
283
284 //
285 // Get the password
286 //
287 String password = String::EMPTY;
288
289 while (*p)
290 {
|
291 kumpf 1.8 password.append(*p++);
|
292 mike 1.2 }
293
294 //
295 // Store the user name and password in the table
296 //
297 if (!passwordTable.insert(userName, password))
298 {
299 //
300 // Duplicate entry for user, ignore the new entry.
301 //
|
302 humberto 1.12 //l10n
303 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
304 //"Duplicate user: $0.", userName);
305 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
306 "Security.UserManager.PasswordFile.DUPLICATE_USER",
307 "Duplicate user: $0.", userName);
|
308 mike 1.2 }
309 }
310
311 ifs.close();
|
312 kumpf 1.7 PEG_METHOD_EXIT();
|
313 mike 1.2 }
314
315
316 /**
317 Save the username and password to the password file.
318 */
319 void PasswordFile::save (PasswordTable& passwordTable)
320 {
|
321 kumpf 1.7 PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::save");
|
322 mike 1.2
323 //
|
324 kumpf 1.3 // Check if backup password file exists, if it does remove the password file
325 // If it does not rename the password file to password backup file
|
326 mike 1.2 //
327 if (FileSystem::exists(_passwordBackupFile))
328 {
|
329 kumpf 1.3 if ( FileSystem::exists(_passwordFile))
|
330 mike 1.2 {
|
331 kumpf 1.3 if ( ! FileSystem::removeFile(_passwordFile))
332 {
|
333 humberto 1.12 //l10n
334 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
335 //"Cannot remove password file : $0.", _passwordFile);
336 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
337 "Security.UserManager.PasswordFile.CANNOT_REMOVE_PWD_FILE",
338 "Cannot remove password file : $0.", _passwordFile);
|
339 kumpf 1.3 throw CannotRemoveFile(_passwordFile);
340 }
|
341 mike 1.2 }
342 }
|
343 kumpf 1.3 else
|
344 mike 1.2 {
|
345 kumpf 1.3 if ( FileSystem::exists(_passwordFile))
|
346 mike 1.2 {
|
347 kumpf 1.3 if ( ! FileSystem::renameFile(_passwordFile, _passwordBackupFile))
348 {
|
349 humberto 1.12 //l10n
350 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
351 //"Cannot rename password file : $0.", _passwordFile);
352 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
353 "Security.UserManager.PasswordFile.CANNOT_RENAME_PWD_FILE",
354 "Cannot rename password file : $0.", _passwordFile);
|
355 kumpf 1.3 throw CannotRenameFile(_passwordFile);
356 }
|
357 mike 1.2 }
358 }
359
360 //
|
361 kumpf 1.3 // Open the password file for writing
|
362 mike 1.2 //
|
363 david 1.13 #if defined(PEGASUS_OS_OS400)
|
364 david 1.14 ofstream ofs(_passwordFile.getCStringUTF8(), PEGASUS_STD(_CCSID_T(1208)));
|
365 david 1.13 #else
|
366 david 1.14 ofstream ofs(_passwordFile.getCStringUTF8());
|
367 david 1.13 #endif
|
368 mike 1.2 if (!ofs)
369 {
|
370 kumpf 1.7 PEG_METHOD_EXIT();
|
371 mike 1.2 throw CannotOpenFile(getFileName());
372 }
373
374 ofs.clear();
375
376 //
377 // Write password file header information
378 //
379
380 for (int index = 0; index < HEADER_SIZE; index++)
381 {
382 ofs << PasswordFileHeader[index] << endl;
383 }
384
385 ofs << endl;
386
387 //
388 // Save user names and passwords to the new file
389 //
390 for (PasswordTable::Iterator i = passwordTable.start(); i; i++)
391 {
392 mike 1.2 ofs << i.key() << ":" << i.value() << endl;
393 }
394
395 ofs.close();
396
|
397 kumpf 1.3 if ( FileSystem::exists(_passwordBackupFile))
|
398 mike 1.2 {
|
399 kumpf 1.3 if ( ! FileSystem::removeFile(_passwordBackupFile))
|
400 mike 1.2 {
|
401 humberto 1.12 //l10n
402 //Logger::put(Logger::ERROR_LOG, System::CIMSERVER,
403 //Logger::SEVERE,
404 // "Cannot remove backup password file : $0.",
405 //_passwordBackupFile);
406 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
407 "Security.UserManager.PasswordFile.CANNOT_REMOVE_BACKUP_PWD_FILE",
408 "Cannot remove backup password file : $0.", _passwordBackupFile);
|
409 kumpf 1.3 throw CannotRemoveFile(_passwordBackupFile);
|
410 mike 1.2 }
411 }
|
412 kumpf 1.7 PEG_METHOD_EXIT();
|
413 mike 1.2 }
414
415 PEGASUS_NAMESPACE_END
416
|