1 yi.zhou 1.1 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // 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 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 yi.zhou 1.1 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include <Pegasus/Common/Config.h>
35 #include <Pegasus/Common/Constants.h>
36 #include <Pegasus/Common/Logger.h>
37 #include <Pegasus/Common/Formatter.h>
38 #include <Pegasus/Common/CIMPropertyList.h>
39 #include <Pegasus/Common/InternalException.h>
|
40 ms.aruran 1.1.2.1 #include <Pegasus/Common/AuditLogger.h>
41
42 #ifdef PEGASUS_OS_DARWIN
43 # include <crt_externs.h>
44 #endif
45
46 #ifndef PEGASUS_OS_TYPE_WINDOWS
47 # include <unistd.h>
48 #endif
49
50 #ifdef PEGASUS_OS_VMS
51 # include <unixlib.h>
52 #endif
53
|
54 yi.zhou 1.1 #include <stdlib.h>
55
56 #ifndef PEGASUS_DISABLE_AUDIT_LOGGER
57
58 PEGASUS_USING_STD;
59
60 PEGASUS_NAMESPACE_BEGIN
61
|
62 ms.aruran 1.1.2.1 static const String providerModuleStatus [] = {
63 "Unknown", "Other", "OK", "Degraded",
|
64 yi.zhou 1.1 "Stressed", "Predictive Failure", "Error", "Non-Recoverable Error",
|
65 ms.aruran 1.1.2.1 "Starting", "Stopping", "Stopped", "In Service", "No Contact",
|
66 yi.zhou 1.1 "Lost Communication"};
67
68 Boolean AuditLogger::_auditLogFlag = false;
69
|
70 ms.aruran 1.1.2.1 AuditLogger::PEGASUS_AUDITLOGINITIALIZE_CALLBACK_T
71 AuditLogger::_auditLogInitializeCallback = 0;
|
72 yi.zhou 1.1
73 AuditLogger::PEGASUS_AUDITLOG_CALLBACK_T AuditLogger::_writeAuditMessageToFile =
74 AuditLogger::_writeAuditMessage;
75
76 void AuditLogger::logCurrentConfig(
77 const Array<String> & propertyNames,
78 const Array<String> & propertyValues)
79 {
80 for (Uint32 i = 0; i < propertyNames.size(); i++)
81 {
|
82 ms.aruran 1.1.2.1 String propertyStr = propertyNames[i] + "=" + propertyValues[i];
83
84 MessageLoaderParms msgParms("Common.AuditLogger.CURRENT_CONFIG",
85 "cimserver configuration $0", propertyStr);
|
86 yi.zhou 1.1
|
87 ms.aruran 1.1.2.1 _writeAuditMessageToFile(TYPE_CONFIGURATION,
88 SUBTYPE_CURRENT_CONFIGURATION,
89 EVENT_START_UP, Logger::INFORMATION, msgParms);
90 }
|
91 yi.zhou 1.1 }
92
93 void AuditLogger::logCurrentRegProvider(
94 const Array < CIMInstance > & instances)
95 {
|
96 ms.aruran 1.1.2.1 String moduleName;
|
97 yi.zhou 1.1 Array<Uint16> moduleStatus;
98 String statusValue;
99 Uint32 pos;
100
101 // get all the registered provider module names and status
102 for (Uint32 i = 0; i <instances.size(); i++)
103 {
104 instances[i].getProperty(instances[i].findProperty(
|
105 ms.aruran 1.1.2.1 _PROPERTY_PROVIDERMODULE_NAME)).getValue().get(moduleName);
|
106 yi.zhou 1.1
107 pos = instances[i].findProperty(_PROPERTY_OPERATIONALSTATUS);
108
109 if (pos == PEG_NOT_FOUND)
110 {
111 moduleStatus.append(0);
112 }
113 else
114 {
115 CIMValue theValue = instances[i].getProperty(pos).getValue();
116
117 if (theValue.isNull())
118 {
119 moduleStatus.append(0);
120 }
121 else
122 {
123 theValue.get(moduleStatus);
124 }
125 }
126
127 yi.zhou 1.1 statusValue = _getModuleStatusValue(moduleStatus);
128
|
129 ms.aruran 1.1.2.1 MessageLoaderParms msgParms(
130 "Common.AuditLogger.CURRENT_PROVIDER_REGISTRATION",
131 "Provider module \"$0\" has status \"$1\".",
132 moduleName, statusValue);
133
134 _writeAuditMessageToFile(TYPE_CONFIGURATION,
135 SUBTYPE_CURRENT_PROVIDER_REGISTRATION,
136 EVENT_START_UP, Logger::INFORMATION, msgParms);
|
137 yi.zhou 1.1 }
138 }
139
140 void AuditLogger::logCurrentEnvironmentVar()
141 {
|
142 ms.aruran 1.1.2.1 #ifdef PEGASUS_OS_DARWIN
143 char** envp = *_NSGetEnviron();
144 #else
145 char** envp = environ;
146 #endif
|
147 yi.zhou 1.1
148 Uint32 i = 0;
149
150 while (envp[i])
151 {
|
152 ms.aruran 1.1.2.1 MessageLoaderParms msgParms("Common.AuditLogger.CURRENT_ENV",
153 "cimserver environment variable: $0", envp[i]);
|
154 yi.zhou 1.1
|
155 ms.aruran 1.1.2.1 _writeAuditMessageToFile(TYPE_CONFIGURATION,
156 SUBTYPE_CURRENT_ENVIRONMENT_VARIABLES,
157 EVENT_START_UP, Logger::INFORMATION, msgParms);
|
158 yi.zhou 1.1
|
159 ms.aruran 1.1.2.1 i++;
160 }
|
161 yi.zhou 1.1 }
162
163 void AuditLogger::logSetConfigProperty(
164 const String & userName,
165 const String & propertyName,
166 const String & prePropertyValue,
167 const String & newPropertyValue,
168 Boolean isPlanned)
169 {
170 if (isPlanned)
171 {
172 MessageLoaderParms msgParms(
173 "Common.AuditLogger.SET_PLANNED_CONFIG_PROPERTY",
|
174 ms.aruran 1.1.2.1 "The planned value of property \"$0\" is modified from "
175 "value \"$1\" to value \"$2\" by user \"$3\".",
176 propertyName, prePropertyValue, newPropertyValue, userName);
177
178 _writeAuditMessageToFile(TYPE_CONFIGURATION,
179 SUBTYPE_CONFIGURATION_CHANGE,
180 EVENT_UPDATE, Logger::INFORMATION, msgParms);
|
181 yi.zhou 1.1 }
182 else
183 {
184 MessageLoaderParms msgParms(
185 "Common.AuditLogger.SET_CURRENT_CONFIG_PROPERTY",
|
186 ms.aruran 1.1.2.1 "The current value of property \"$0\" is modified from "
187 "value \"$1\" to value \"$2\" by user \"$3\".",
188 propertyName, prePropertyValue, newPropertyValue, userName);
189
190 _writeAuditMessageToFile(TYPE_CONFIGURATION,
191 SUBTYPE_CONFIGURATION_CHANGE,
192 EVENT_UPDATE, Logger::INFORMATION, msgParms);
193 }
194 }
|
195 yi.zhou 1.1
|
196 ms.aruran 1.1.2.1 void AuditLogger::logUpdateClassOperation(
197 const char* cimMethodName,
198 AuditEvent eventType,
199 const String& userName,
200 const String& ipAddr,
201 const CIMNamespaceName& nameSpace,
202 const CIMName& className,
203 CIMStatusCode statusCode)
204 {
205 MessageLoaderParms msgParms(
206 "Common.AuditLogger.OPERATION_UPDATE_CLASS",
207 "A CIM $0 operation on class \"$1\" in namespace \"$2\" by user "
208 "\"$3\" connected from system \"$4\" resulted in status \"$5\".",
209 cimMethodName,
210 className.getString(),
211 nameSpace.getString(),
212 userName,
213 ipAddr,
214 cimStatusCodeToString(statusCode));
215
216 _writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_SCHEMA_OPERATION,
217 ms.aruran 1.1.2.1 eventType, Logger::INFORMATION, msgParms);
218 }
219
220 void AuditLogger::logUpdateQualifierOperation(
221 const char* cimMethodName,
222 AuditEvent eventType,
223 const String& userName,
224 const String& ipAddr,
225 const CIMNamespaceName& nameSpace,
226 const CIMName& className,
227 CIMStatusCode statusCode)
228 {
229 MessageLoaderParms msgParms(
230 "Common.AuditLogger.OPERATION_UPDATE_QUALIFIER",
231 "A CIM $0 operation on qualifier \"$1\" in namespace \"$2\" by user "
232 "\"$3\" connected from system \"$4\" resulted in status \"$5\".",
233 cimMethodName,
234 className.getString(),
235 nameSpace.getString(),
236 userName,
237 ipAddr,
238 ms.aruran 1.1.2.1 cimStatusCodeToString(statusCode));
239
240 _writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_SCHEMA_OPERATION,
241 eventType, Logger::INFORMATION, msgParms);
242 }
243
244 void AuditLogger::logUpdateInstanceOperation(
245 const char* cimMethodName,
246 AuditEvent eventType,
247 const String& userName,
248 const String& ipAddr,
249 const CIMNamespaceName& nameSpace,
250 const CIMObjectPath& instanceName,
251 const String& moduleName,
252 const String& providerName,
253 CIMStatusCode statusCode)
254 {
255 if (providerName != String::EMPTY)
256 {
257 MessageLoaderParms msgParms(
258 "Common.AuditLogger.OPERATION_UPDATE_INSTANCE_WITH_PROVIDER",
259 ms.aruran 1.1.2.1 "A CIM $0 operation on instance \"$1\" in namespace \"$2\" by "
260 "user \"$3\" connected from system \"$4\" resulted in "
261 "status \"$5\". "
262 "The provider for this operation is \"$6\" in module \"$7\".",
263 cimMethodName,
264 CIMObjectPath("", CIMNamespaceName(), instanceName.getClassName(),
265 instanceName.getKeyBindings()).toString(),
266 nameSpace.getString(),
267 userName,
268 ipAddr,
269 cimStatusCodeToString(statusCode),
270 providerName,
271 moduleName);
272
273 _writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_INSTANCE_OPERATION,
274 eventType, Logger::INFORMATION, msgParms);
|
275 yi.zhou 1.1 }
|
276 ms.aruran 1.1.2.1 else
277 {
278 MessageLoaderParms msgParms(
279 "Common.AuditLogger.OPERATION_UPDATE_INSTANCE",
280 "A CIM $0 operation on instance \"$1\" in namespace \"$2\" by "
281 "user \"$3\" connected from system \"$4\" resulted in "
282 "status \"$5\". ",
283 cimMethodName,
284 CIMObjectPath("", CIMNamespaceName(), instanceName.getClassName(),
285 instanceName.getKeyBindings()).toString(),
286 nameSpace.getString(),
287 userName,
288 ipAddr,
289 cimStatusCodeToString(statusCode));
290
291 _writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_INSTANCE_OPERATION,
292 eventType, Logger::INFORMATION, msgParms);
293 }
294 }
295
296 void AuditLogger::logInvokeMethodOperation(
297 ms.aruran 1.1.2.1 const String& userName,
298 const String& ipAddr,
299 const CIMNamespaceName& nameSpace,
300 const CIMObjectPath& objectName,
301 const CIMName& methodName,
302 const String& moduleName,
303 const String& providerName,
304 CIMStatusCode statusCode)
305 {
306 if (providerName != String::EMPTY)
307 {
308 MessageLoaderParms msgParms(
309 "Common.AuditLogger.OPERATION_INVOKE_METHOD_WITH_PROVIDER",
310 "A CIM InvokeMethod operation on method \"$0\" of object \"$1\" "
311 "in namespace \"$2\" by user \"$3\" connected from system "
312 "\"$4\" resulted in status \"$5\". The provider for this "
313 "operation is \"$6\" in module \"$7\".",
314 methodName.getString(),
315 CIMObjectPath("", CIMNamespaceName(), objectName.getClassName(),
316 objectName.getKeyBindings()).toString(),
317 nameSpace.getString(),
318 ms.aruran 1.1.2.1 userName,
319 ipAddr,
320 cimStatusCodeToString(statusCode),
321 providerName,
322 moduleName);
323
324 _writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_INSTANCE_OPERATION,
325 EVENT_INVOKE, Logger::INFORMATION, msgParms);
326 }
327 else
328 {
329 MessageLoaderParms msgParms(
330 "Common.AuditLogger.OPERATION_INVOKE_METHOD",
331 "A CIM InvokeMethod operation on method \"$0\" of object \"$1\" "
332 "in namespace \"$2\" by user \"$3\" connected from system "
333 "\"$4\" resulted in status \"$5\".",
334 methodName.getString(),
335 CIMObjectPath("", CIMNamespaceName(), objectName.getClassName(),
336 objectName.getKeyBindings()).toString(),
337 nameSpace.getString(),
338 userName,
339 ms.aruran 1.1.2.1 ipAddr,
340 cimStatusCodeToString(statusCode));
341
342 _writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_INSTANCE_OPERATION,
343 EVENT_INVOKE, Logger::INFORMATION, msgParms);
344 }
345 }
346
347 void AuditLogger::logUpdateProvModuleStatus(
348 const String & moduleName,
349 const Array<Uint16> currentModuleStatus,
350 const Array<Uint16> newModuleStatus)
351 {
352 String currentModuleStatusValue =
353 _getModuleStatusValue(currentModuleStatus);
354
355 String newModuleStatusValue = _getModuleStatusValue(newModuleStatus);
356
357 MessageLoaderParms msgParms(
358 "Common.AuditLogger.UPDATE_PROVIDER_MODULE_STATUS",
359 "The operational status of module \"$0\" has changed from \"$1\""
360 ms.aruran 1.1.2.1 " to \"$2\".",
361 moduleName, currentModuleStatusValue, newModuleStatusValue);
362
363 _writeAuditMessageToFile(TYPE_CONFIGURATION,
364 SUBTYPE_PROVIDER_MODULE_STATUS_CHANGE,
365 EVENT_UPDATE, Logger::INFORMATION, msgParms);
366 }
367
368 void AuditLogger::logLocalAuthentication(
369 const String& userName,
370 Boolean successful)
371 {
372 CIMValue result(successful);
373
374 MessageLoaderParms msgParms(
375 "Common.AuditLogger.LOCAL_AUTHENTICATION",
376 "Local authentication attempt: "
377 "successful = $0, user = $1. ",
378 result.toString(),
379 userName);
380
381 ms.aruran 1.1.2.1 _writeAuditMessageToFile(
382 TYPE_AUTHENTICATION,
383 SUBTYPE_LOCAL_AUTHENTICATION,
384 successful ? EVENT_AUTH_SUCCESS : EVENT_AUTH_FAILURE,
385 successful ? Logger::INFORMATION : Logger::WARNING,
386 msgParms);
387 }
388
389 void AuditLogger::logBasicAuthentication(
390 const String& userName,
391 const String& ipAddr,
392 Boolean successful)
393 {
394 CIMValue result(successful);
395
396 MessageLoaderParms msgParms(
397 "Common.AuditLogger.BASIC_AUTHENTICATION",
398 "Basic authentication attempt: "
399 "successful = $0, user = $1, IP address = $2.",
400 result.toString(),
401 userName,
402 ms.aruran 1.1.2.1 ipAddr);
403
404 _writeAuditMessageToFile( TYPE_AUTHENTICATION,
405 SUBTYPE_BASIC_AUTHENTICATION,
406 successful ? EVENT_AUTH_SUCCESS : EVENT_AUTH_FAILURE,
407 successful ? Logger::INFORMATION: Logger::WARNING,
408 msgParms);
|
409 yi.zhou 1.1 }
410
411 void AuditLogger::setInitializeCallback(
412 PEGASUS_AUDITLOGINITIALIZE_CALLBACK_T auditLogInitializeCallback)
413 {
|
414 ms.aruran 1.1.2.1 _auditLogInitializeCallback = auditLogInitializeCallback;
|
415 yi.zhou 1.1 }
416
417 void AuditLogger::setEnabled(Boolean enabled)
418 {
|
419 ms.aruran 1.1.2.1 // Only write the enable/disable messages if we are set up to handle them
420 if (_auditLogInitializeCallback != 0)
|
421 yi.zhou 1.1 {
|
422 ms.aruran 1.1.2.1 if (enabled)
|
423 yi.zhou 1.1 {
|
424 ms.aruran 1.1.2.1 if (!_auditLogFlag)
425 {
426 _auditLogInitializeCallback();
427
428 MessageLoaderParms msgParms(
429 "Common.AuditLogger.ENABLE_AUDIT_LOG",
430 "Audit logging is enabled.");
431
432 _writeAuditMessageToFile(TYPE_CONFIGURATION,
433 SUBTYPE_CONFIGURATION_CHANGE,
434 EVENT_UPDATE, Logger::INFORMATION, msgParms);
435 }
|
436 yi.zhou 1.1 }
|
437 ms.aruran 1.1.2.1 else
|
438 yi.zhou 1.1 {
|
439 ms.aruran 1.1.2.1 if (_auditLogFlag)
440 {
441 MessageLoaderParms msgParms(
442 "Common.AuditLogger.DISABLE_AUDIT_LOG",
443 "Audit logging is disabled.");
444
445 _writeAuditMessageToFile(TYPE_CONFIGURATION,
446 SUBTYPE_CONFIGURATION_CHANGE,
447 EVENT_UPDATE, Logger::INFORMATION, msgParms);
448 }
|
449 yi.zhou 1.1 }
450 }
451
452 _auditLogFlag = enabled;
453 }
454
455 void AuditLogger::writeAuditLogToFileCallback(
456 PEGASUS_AUDITLOG_CALLBACK_T writeAuditLogToFileCallback)
457 {
458 _writeAuditMessageToFile = writeAuditLogToFileCallback;
459 }
460
461 void AuditLogger::_writeAuditMessage(
462 AuditType auditType,
463 AuditSubType auditSubType,
464 AuditEvent auditEvent,
465 Uint32 logLevel,
466 MessageLoaderParms & msgParms)
467 {
468 String localizedMsg = MessageLoader::getMessage(msgParms);
469
|
470 ms.aruran 1.1.2.1 String identifier = "cimserver audit";
|
471 yi.zhou 1.1
472 Logger::put(Logger::AUDIT_LOG, identifier, logLevel, localizedMsg);
473 }
474
475 String AuditLogger::_getModuleStatusValue(
476 const Array<Uint16> moduleStatus)
477 {
478 String moduleStatusValue, statusValue;
479 Uint32 moduleStatusSize = moduleStatus.size();
480
481 for (Uint32 j=0; j < moduleStatusSize; j++)
482 {
483 statusValue = providerModuleStatus[moduleStatus[j]];
484 moduleStatusValue.append(statusValue);
|
485 ms.aruran 1.1.2.1
|
486 yi.zhou 1.1 if (j < moduleStatusSize - 1)
487 {
488 moduleStatusValue.append(",");
489 }
490 }
491
|
492 ms.aruran 1.1.2.1 return moduleStatusValue;
|
493 yi.zhou 1.1 }
494
495 PEGASUS_NAMESPACE_END
496
497 #endif
|