1 martin 1.32 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.33 //
|
3 martin 1.32 // 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.33 //
|
10 martin 1.32 // 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.33 //
|
17 martin 1.32 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.33 //
|
20 martin 1.32 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.33 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.32 // 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.33 //
|
28 martin 1.32 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32
33 #include <cctype>
34 #include <fstream>
35
36 #include <Pegasus/Common/FileSystem.h>
37 #include <Pegasus/Common/Logger.h>
38 #include <Pegasus/Common/Tracer.h>
|
39 kumpf 1.27 #include <Pegasus/Common/Executor.h>
|
40 mike 1.2
41 #include <Pegasus/Security/UserManager/PasswordFile.h>
42 #include <Pegasus/Security/UserManager/UserExceptions.h>
43
44
45 PEGASUS_USING_STD;
46
47 PEGASUS_NAMESPACE_BEGIN
48
49 const char COLON = ':';
50
51 ////////////////////////////////////////////////////////////////////////////////
52 //
53 // PasswordFile Class
54 //
55 ////////////////////////////////////////////////////////////////////////////////
56
|
57 kumpf 1.29 /**
58 Constructor.
|
59 mike 1.2 */
|
60 kumpf 1.29 PasswordFile::PasswordFile(const String& fileName)
|
61 mike 1.2 {
|
62 kumpf 1.7 PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::PasswordFile");
|
63 mike 1.2
64 _passwordFile = fileName;
65
|
66 gs.keenan 1.24 #ifdef PEGASUS_OS_VMS
67 _passwordBackupFile = fileName + "_bak";
68 #else
|
69 mike 1.2 _passwordBackupFile = fileName + ".bak";
|
70 gs.keenan 1.24 #endif
|
71 mike 1.2
|
72 kumpf 1.3 try
73 {
|
74 kumpf 1.29 PasswordTable pt;
|
75 kumpf 1.3 load(pt);
76 }
|
77 kumpf 1.29 catch (const NoSuchFile&)
|
78 mike 1.2 {
|
79 humberto 1.12 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
|
80 kumpf 1.31 MessageLoaderParms(
81 "Security.UserManager.PasswordFile.PWD_FILE_NOT_FOUND",
82 "Password file not found : $0.", _passwordFile));
|
83 humberto 1.12 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
|
84 kumpf 1.31 MessageLoaderParms(
85 "Security.UserManager.PasswordFile.CREATING_BLANK_PWD_FILE",
86 "Creating blank password file."));
|
87 mike 1.2 PasswordTable pt;
88 save(pt);
89 }
|
90 kumpf 1.7 PEG_METHOD_EXIT();
|
91 mike 1.2 }
92
|
93 kumpf 1.29 /**
94 Destructor.
|
95 mike 1.2 */
|
96 kumpf 1.29 PasswordFile::~PasswordFile()
|
97 mike 1.2 {
|
98 kumpf 1.7 PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::~PasswordFile");
|
99 mike 1.2
|
100 kumpf 1.7 PEG_METHOD_EXIT();
|
101 mike 1.2 }
102
|
103 kumpf 1.29 /**
|
104 mike 1.2 Load the username and password from the password file.
105 */
|
106 kumpf 1.29 void PasswordFile::load(PasswordTable& passwordTable)
|
107 mike 1.2 {
108 String line;
109
|
110 kumpf 1.7 PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::load");
|
111 mike 1.2
|
112 kumpf 1.29 //
|
113 kumpf 1.3 // Check if the backup file exists, if it does use the backup file
114 // If not try to use the password file
115 //
116 if (FileSystem::exists(_passwordBackupFile))
117 {
|
118 humberto 1.12 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
|
119 kumpf 1.31 MessageLoaderParms(
120 "Security.UserManager.PasswordFile.TRYING_TO_BACKUP_FILE",
121 "Trying to use the backup file : $0.",
122 _passwordBackupFile));
|
123 kumpf 1.29 if (Executor::renameFile(
124 _passwordBackupFile.getCString(),
125 _passwordFile.getCString()) != 0)
126 {
127 Logger::put_l(
128 Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
|
129 kumpf 1.31 MessageLoaderParms(
130 "Security.UserManager.PasswordFile.CANNOT_USE_BACKUP_FILE",
131 "Unable to use the backup file : $0.",
132 _passwordBackupFile));
|
133 kumpf 1.29 throw CannotRenameFile(_passwordBackupFile);
134 }
|
135 humberto 1.12 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
|
136 kumpf 1.31 MessageLoaderParms(
137 "Security.UserManager.PasswordFile.RECOVERED_USING_BACKUP_FILE",
138 "Recovered using the backup file : $0.",
139 _passwordBackupFile));
|
140 kumpf 1.3 }
|
141 kumpf 1.29 if (!FileSystem::exists(_passwordFile))
|
142 kumpf 1.3 {
|
143 kumpf 1.29 throw NoSuchFile(_passwordFile);
|
144 kumpf 1.3 }
145
|
146 mike 1.2 //
147 // Open the password file
148 //
|
149 david 1.16 ifstream ifs(_passwordFile.getCString());
|
150 ouyang.jian 1.28
|
151 mike 1.2 if (!ifs)
152 {
|
153 humberto 1.12 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
|
154 kumpf 1.31 MessageLoaderParms(
155 "Security.UserManager.PasswordFile.ERROR_OPENING_PWD_FILE",
156 "Error opening password file : $0.",
157 _passwordFile));
|
158 kumpf 1.3 return;
|
159 mike 1.2 }
160
161 //
162 // Read each line of the file
163 //
164 for (Uint32 lineNumber = 1; GetLine(ifs, line); lineNumber++)
165 {
166 // Get the userName and password
167
168 //
169 // Skip leading whitespace
170 //
|
171 john.eisenbraun 1.33.2.1 const Char16* pLine = line.getChar16Data();
172 const Char16* pUserNameStart;
173 const Char16* pUserNameEnd;
174 const Char16* pColon;
175 const Char16* pPassword;
|
176 mike 1.2
|
177 john.eisenbraun 1.33.2.1 while (*pLine && isspace(*pLine))
|
178 mike 1.2 {
|
179 john.eisenbraun 1.33.2.1 pLine++;
|
180 mike 1.2 }
181
|
182 john.eisenbraun 1.33.2.1 if (!*pLine)
|
183 mike 1.2 {
184 continue;
185 }
186
187 //
188 // Get the userName
189 //
|
190 john.eisenbraun 1.33.2.1 pUserNameStart = pLine;
|
191 mike 1.2
|
192 john.eisenbraun 1.33.2.1 //
193 // Look for the password
194 //
195 pColon = pLine;
196 while (*pColon && (*pColon != COLON))
|
197 mike 1.2 {
|
198 john.eisenbraun 1.33.2.1 *pColon++;
|
199 mike 1.2 }
200 //
|
201 john.eisenbraun 1.33.2.1 // Expect a colon sign
|
202 mike 1.2 //
|
203 john.eisenbraun 1.33.2.1 if (*pColon != COLON)
|
204 mike 1.2 {
|
205 john.eisenbraun 1.33.2.1 // Did not find Colon, log a message and skip entry
206 Logger::put_l(
207 Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
208 MessageLoaderParms(
209 "Security.UserManager.PasswordFile.PWD_ENTRY_SYNTAX_ERROR",
210 "Syntax error in password entry at line : $0.",
211 lineNumber));
212 continue;
|
213 mike 1.2 }
214
215 //
|
216 john.eisenbraun 1.33.2.1 // Skip whitespace after user name
|
217 mike 1.2 //
|
218 john.eisenbraun 1.33.2.1 pUserNameEnd = pColon - 1;
219 while ((pUserNameEnd >= pUserNameStart) && isspace(*pUserNameEnd))
|
220 mike 1.2 {
|
221 john.eisenbraun 1.33.2.1 pUserNameEnd--;
222 }
223 pUserNameEnd++; // Point to one past the username
224
225 if (pUserNameStart == pUserNameEnd)
226 {
227 // Did not find a user name, log a message and skip entry
|
228 kumpf 1.29 Logger::put_l(
229 Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
|
230 kumpf 1.31 MessageLoaderParms(
|
231 john.eisenbraun 1.33.2.1 "Security.UserManager.PasswordFile.ERROR_READING_USR_ENTRY",
232 "User name not found in entry at line : $0.",
233 lineNumber));
|
234 kumpf 1.29 continue;
|
235 mike 1.2 }
236
|
237 john.eisenbraun 1.33.2.1 String userName(pUserNameStart, pUserNameEnd - pUserNameStart);
|
238 mike 1.2
239 //
240 // Skip whitespace after : sign
241 //
|
242 john.eisenbraun 1.33.2.1 pPassword = pColon + 1;
243 while (*pPassword && isspace(*pPassword))
|
244 mike 1.2 {
|
245 john.eisenbraun 1.33.2.1 pPassword++;
246 }
247
248 if (!*pPassword)
249 {
250 // Did not find a password, log a message and skip entry
251 Logger::put_l(
252 Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
253 MessageLoaderParms(
254 "Security.UserManager.PasswordFile.ERROR_READING_PWD_ENTRY",
255 "Error reading the password entry for user : $0.",
256 userName));
257 continue;
|
258 mike 1.2 }
259
260 //
261 // Get the password
262 //
|
263 john.eisenbraun 1.33.2.1 String password(pPassword);
|
264 mike 1.2
265 //
266 // Store the user name and password in the table
267 //
268 if (!passwordTable.insert(userName, password))
269 {
270 //
271 // Duplicate entry for user, ignore the new entry.
272 //
|
273 kumpf 1.29 Logger::put_l(
274 Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
|
275 kumpf 1.31 MessageLoaderParms(
276 "Security.UserManager.PasswordFile.DUPLICATE_USER",
277 "Duplicate user: $0.", userName));
|
278 mike 1.2 }
279 }
280
281 ifs.close();
|
282 kumpf 1.7 PEG_METHOD_EXIT();
|
283 mike 1.2 }
284
285
|
286 kumpf 1.29 /**
|
287 mike 1.2 Save the username and password to the password file.
288 */
|
289 joyce.j 1.23 void PasswordFile::save (const PasswordTable& passwordTable)
|
290 mike 1.2 {
|
291 kumpf 1.7 PEG_METHOD_ENTER(TRC_USER_MANAGER, "PasswordFile::save");
|
292 mike 1.2
293 //
|
294 kumpf 1.3 // Check if backup password file exists, if it does remove the password file
295 // If it does not rename the password file to password backup file
|
296 mike 1.2 //
297 if (FileSystem::exists(_passwordBackupFile))
298 {
|
299 kumpf 1.29 if (FileSystem::exists(_passwordFile))
300 {
|
301 kumpf 1.27 if (Executor::removeFile(_passwordFile.getCString()) != 0)
|
302 kumpf 1.29 {
303 Logger::put_l(
304 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
|
305 kumpf 1.31 MessageLoaderParms(
306 "Security.UserManager.PasswordFile."
307 "CANNOT_REMOVE_PWD_FILE",
308 "Cannot remove password file : $0.", _passwordFile));
|
309 kumpf 1.29 throw CannotRemoveFile(_passwordFile);
|
310 kumpf 1.3 }
|
311 mike 1.2 }
312 }
|
313 kumpf 1.3 else
|
314 mike 1.2 {
|
315 kumpf 1.29 if (FileSystem::exists(_passwordFile))
316 {
317 if (Executor::renameFile(_passwordFile.getCString(),
|
318 kumpf 1.27 _passwordBackupFile.getCString()) != 0)
|
319 kumpf 1.29 {
320 Logger::put_l(
321 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
|
322 kumpf 1.31 MessageLoaderParms(
323 "Security.UserManager.PasswordFile."
324 "CANNOT_RENAME_PWD_FILE",
325 "Cannot rename password file : $0.",
326 _passwordFile));
|
327 kumpf 1.29 throw CannotRenameFile(_passwordFile);
|
328 kumpf 1.3 }
|
329 mike 1.2 }
330 }
331
332 //
|
333 kumpf 1.3 // Open the password file for writing
|
334 mike 1.2 //
|
335 kumpf 1.27
336 FILE* ofs = Executor::openFile(_passwordFile.getCString(), 'w');
337
|
338 mike 1.2 if (!ofs)
339 {
|
340 kumpf 1.7 PEG_METHOD_EXIT();
|
341 kumpf 1.29 throw CannotOpenFile(getFileName());
|
342 mike 1.2 }
|
343 kumpf 1.29
|
344 mike 1.2 //
345 // Save user names and passwords to the new file
346 //
347 for (PasswordTable::Iterator i = passwordTable.start(); i; i++)
348 {
|
349 kumpf 1.27 CString key = i.key().getCString();
350 CString value = i.value().getCString();
351 fprintf(ofs, "%s:%s\n", (const char*)key, (const char*)value);
|
352 mike 1.2 }
353
|
354 kumpf 1.27 fclose(ofs);
|
355 mike 1.2
|
356 kumpf 1.29 if (FileSystem::exists(_passwordBackupFile))
|
357 mike 1.2 {
|
358 kumpf 1.29 if (Executor::removeFile(_passwordBackupFile.getCString()) != 0)
359 {
360 Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
|
361 kumpf 1.31 MessageLoaderParms(
362 "Security.UserManager.PasswordFile."
363 "CANNOT_REMOVE_BACKUP_PWD_FILE",
364 "Cannot remove backup password file : $0.",
365 _passwordBackupFile));
|
366 kumpf 1.29 throw CannotRemoveFile(_passwordBackupFile);
|
367 mike 1.2 }
368 }
|
369 kumpf 1.7 PEG_METHOD_EXIT();
|
370 mike 1.2 }
371
372 PEGASUS_NAMESPACE_END
|