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