1 karl 1.40 //%2006////////////////////////////////////////////////////////////////////////
|
2 kumpf 1.1 //
|
3 karl 1.34 // 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 karl 1.28 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.34 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.37 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.40 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 kumpf 1.1 //
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 kumpf 1.17 //
|
21 kumpf 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // 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 sage 1.2 #include <Pegasus/Common/Config.h>
|
35 kumpf 1.9 #include <Pegasus/Common/Constants.h>
|
36 kumpf 1.1 #include <Pegasus/Security/UserManager/UserManager.h>
37 #include <Pegasus/Common/HTTPMessage.h>
38 #include <Pegasus/Common/XmlWriter.h>
39 #include <Pegasus/Common/Tracer.h>
|
40 kumpf 1.46 #include <Pegasus/Common/MessageLoader.h>
|
41 kumpf 1.1 #include "CIMOperationRequestAuthorizer.h"
|
42 kumpf 1.46
|
43 marek 1.42 #ifdef PEGASUS_ZOS_SECURITY
44 // This include file will not be provided in the OpenGroup CVS for now.
45 // Do NOT try to include it in your compile
|
46 kumpf 1.46 # include <Pegasus/Common/safCheckzOS_inline.h>
|
47 marek 1.42 #endif
|
48 kumpf 1.1
49 PEGASUS_NAMESPACE_BEGIN
50
51 PEGASUS_USING_STD;
52
|
53 kumpf 1.30 //
54 // Set group name separator
55 //
56 const char CIMOperationRequestAuthorizer::_GROUPNAME_SEPARATOR = ',';
|
57 kumpf 1.1
58 CIMOperationRequestAuthorizer::CIMOperationRequestAuthorizer(
|
59 kumpf 1.46 MessageQueueService* outputQueue)
60 : Base(PEGASUS_QUEUENAME_OPREQAUTHORIZER),
61 _outputQueue(outputQueue),
62 _serverTerminating(false)
|
63 kumpf 1.1 {
|
64 kumpf 1.46 PEG_METHOD_ENTER(TRC_SERVER, "CIMOperationRequestAuthorizer::"
65 "CIMOperationRequestAuthorizer");
|
66 kumpf 1.1
|
67 kumpf 1.30 #ifdef PEGASUS_ENABLE_USERGROUP_AUTHORIZATION
|
68 kumpf 1.46 _authorizedUserGroups = _getAuthorizedUserGroups();
|
69 kumpf 1.30 #endif
70
|
71 kumpf 1.46 PEG_METHOD_EXIT();
|
72 kumpf 1.1 }
73
74 CIMOperationRequestAuthorizer::~CIMOperationRequestAuthorizer()
75 {
|
76 kumpf 1.46 PEG_METHOD_ENTER(TRC_SERVER, "CIMOperationRequestAuthorizer::"
77 "~CIMOperationRequestAuthorizer");
|
78 kumpf 1.1
|
79 kumpf 1.46 PEG_METHOD_EXIT();
|
80 kumpf 1.1 }
81
82 void CIMOperationRequestAuthorizer::sendResponse(
|
83 kumpf 1.46 Uint32 queueId,
84 Buffer& message)
|
85 kumpf 1.1 {
|
86 kumpf 1.46 PEG_METHOD_ENTER(TRC_SERVER, "CIMOperationRequestAuthorizer::sendResponse");
|
87 kumpf 1.1
|
88 kumpf 1.46 MessageQueue* queue = MessageQueue::lookup(queueId);
|
89 kumpf 1.1
|
90 kumpf 1.46 if (queue)
91 {
92 queue->enqueue(new HTTPMessage(message));
93 }
|
94 gerarda 1.27
|
95 kumpf 1.46 PEG_METHOD_EXIT();
|
96 kumpf 1.1 }
97
|
98 kumpf 1.7 // Code is duplicated in CIMOperationRequestDecoder
99 void CIMOperationRequestAuthorizer::sendIMethodError(
|
100 kumpf 1.46 Uint32 queueId,
101 HttpMethod httpMethod,
102 const String& messageId,
103 const CIMName& iMethodName,
104 const CIMException& cimException)
|
105 kumpf 1.1 {
|
106 kumpf 1.46 PEG_METHOD_ENTER(TRC_SERVER,
107 "CIMOperationRequestAuthorizer::sendIMethodError");
|
108 kumpf 1.1
|
109 kumpf 1.46 Buffer message;
110 message = XmlWriter::formatSimpleIMethodErrorRspMessage(
111 iMethodName,
112 messageId,
113 httpMethod,
114 cimException);
|
115 kumpf 1.7
|
116 kumpf 1.46 sendResponse(queueId, message);
|
117 kumpf 1.1
|
118 kumpf 1.46 PEG_METHOD_EXIT();
|
119 kumpf 1.1 }
120
|
121 kumpf 1.23 // Code is duplicated in CIMOperationRequestDecoder
122 void CIMOperationRequestAuthorizer::sendMethodError(
|
123 kumpf 1.46 Uint32 queueId,
124 HttpMethod httpMethod,
125 const String& messageId,
126 const CIMName& methodName,
127 const CIMException& cimException)
|
128 kumpf 1.23 {
|
129 kumpf 1.46 PEG_METHOD_ENTER(TRC_SERVER,
130 "CIMOperationRequestAuthorizer::sendMethodError");
|
131 kumpf 1.23
|
132 kumpf 1.46 Buffer message;
133 message = XmlWriter::formatSimpleMethodErrorRspMessage(
134 methodName,
135 messageId,
136 httpMethod,
137 cimException);
|
138 kumpf 1.23
|
139 kumpf 1.46 sendResponse(queueId, message);
|
140 kumpf 1.23
|
141 kumpf 1.46 PEG_METHOD_EXIT();
|
142 kumpf 1.23 }
143
|
144 kumpf 1.1 ////////////////////////////////////////////////////////////////////////////////
145
|
146 kumpf 1.46 void CIMOperationRequestAuthorizer::handleEnqueue(Message* request)
|
147 kumpf 1.1 {
148
|
149 kumpf 1.46 PEG_METHOD_ENTER(TRC_SERVER,
150 "CIMOperationRequestAuthorizer::handleEnqueue");
|
151 kumpf 1.12
|
152 kumpf 1.46 if (!request)
153 {
|
154 kumpf 1.12 PEG_METHOD_EXIT();
155 return;
|
156 kumpf 1.46 }
157
158 AutoPtr<CIMOperationRequestMessage> req(
159 dynamic_cast<CIMOperationRequestMessage*>(request));
160
161 PEGASUS_ASSERT(req.get());
|
162 kumpf 1.12
|
163 kumpf 1.46 //
164 // Get the HTTPConnection queue id
165 //
166 QueueIdStack qis = req->queueIds.copyAndPop();
167
168 Uint32 queueId = qis.top();
169
170 // Set the client's requested language into this service thread.
171 // This will allow functions in this service to return messages
172 // in the correct language.
173 if (req->thread_changed())
174 {
175 AutoPtr<AcceptLanguageList> langs(new AcceptLanguageList(
176 ((AcceptLanguageListContainer)req->operationContext.get(
177 AcceptLanguageListContainer::NAME)).getLanguages()));
178 Thread::setLanguages(langs.release());
179 }
180
181 //
182 // If CIMOM is shutting down, return "Service Unavailable" response
183 //
184 kumpf 1.46 if (_serverTerminating)
185 {
186 Buffer message;
187 message = XmlWriter::formatHttpErrorRspMessage(
188 HTTP_STATUS_SERVICEUNAVAILABLE,
189 String::EMPTY,
190 "CIM Server is shutting down.");
191
192 sendResponse(queueId, message);
193 PEG_METHOD_EXIT();
194 return;
195 }
196
197 String userName = ((IdentityContainer)(req->operationContext.get(
198 IdentityContainer::NAME))).getUserName();
199 String authType = req->authType;
200 CIMNamespaceName nameSpace = req->nameSpace;
|
201 kumpf 1.51 String cimMethodName;
|
202 kumpf 1.46
203 switch (req->getType())
204 {
205 case CIM_GET_CLASS_REQUEST_MESSAGE:
206 cimMethodName = "GetClass";
207 break;
208
209 case CIM_GET_INSTANCE_REQUEST_MESSAGE:
210 cimMethodName = "GetInstance";
211 break;
212
213 case CIM_DELETE_CLASS_REQUEST_MESSAGE:
214 cimMethodName = "DeleteClass";
215 break;
216
217 case CIM_DELETE_INSTANCE_REQUEST_MESSAGE:
218 cimMethodName = "DeleteInstance";
219 break;
220
221 case CIM_CREATE_CLASS_REQUEST_MESSAGE:
222 cimMethodName = "CreateClass";
223 kumpf 1.46 break;
224
225 case CIM_CREATE_INSTANCE_REQUEST_MESSAGE:
226 cimMethodName = "CreateInstance";
227 break;
228
229 case CIM_MODIFY_CLASS_REQUEST_MESSAGE:
230 cimMethodName = "ModifyClass";
231 break;
232
233 case CIM_MODIFY_INSTANCE_REQUEST_MESSAGE:
234 cimMethodName = "ModifyInstance";
235 break;
236
237 case CIM_ENUMERATE_CLASSES_REQUEST_MESSAGE:
238 cimMethodName = "EnumerateClasses";
239 break;
240
241 case CIM_ENUMERATE_CLASS_NAMES_REQUEST_MESSAGE:
242 cimMethodName = "EnumerateClassNames";
243 break;
244 kumpf 1.46
245 case CIM_ENUMERATE_INSTANCES_REQUEST_MESSAGE:
246 cimMethodName = "EnumerateInstances";
247 break;
248
249 case CIM_ENUMERATE_INSTANCE_NAMES_REQUEST_MESSAGE:
250 cimMethodName = "EnumerateInstanceNames";
251 break;
252
253 case CIM_EXEC_QUERY_REQUEST_MESSAGE:
254 cimMethodName = "ExecQuery";
255 break;
256
257 case CIM_ASSOCIATORS_REQUEST_MESSAGE:
258 cimMethodName = "Associators";
259 break;
260
261 case CIM_ASSOCIATOR_NAMES_REQUEST_MESSAGE:
262 cimMethodName = "AssociatorNames";
263 break;
264
265 kumpf 1.46 case CIM_REFERENCES_REQUEST_MESSAGE:
266 cimMethodName = "References";
267 break;
268
269 case CIM_REFERENCE_NAMES_REQUEST_MESSAGE:
270 cimMethodName = "ReferenceNames";
271 break;
272
273 case CIM_GET_PROPERTY_REQUEST_MESSAGE:
274 cimMethodName = "GetProperty";
275 break;
276
277 case CIM_SET_PROPERTY_REQUEST_MESSAGE:
278 cimMethodName = "SetProperty";
279 break;
280
281 case CIM_GET_QUALIFIER_REQUEST_MESSAGE:
282 cimMethodName = "GetQualifier";
283 break;
284
285 case CIM_SET_QUALIFIER_REQUEST_MESSAGE:
286 kumpf 1.46 cimMethodName = "SetQualifier";
287 break;
288
289 case CIM_DELETE_QUALIFIER_REQUEST_MESSAGE:
290 cimMethodName = "DeleteQualifier";
291 break;
292
293 case CIM_ENUMERATE_QUALIFIERS_REQUEST_MESSAGE:
294 cimMethodName = "EnumerateQualifiers";
295 break;
296
297 case CIM_INVOKE_METHOD_REQUEST_MESSAGE:
298 cimMethodName = "InvokeMethod";
299 break;
300
301 default:
302 PEGASUS_ASSERT(0);
303 break;
304 }
|
305 mday 1.5
|
306 marek 1.42 #ifdef PEGASUS_ZOS_SECURITY
|
307 kumpf 1.46 if (checkRequestTypeAuthorizationZOS(
308 req->getType(), userName, nameSpace) == false)
309 {
310 //
311 // user is not authorized, send an
312 // error message to the requesting client.
313 //
314 if (cimMethodName == "InvokeMethod")
315 {
316 sendMethodError(
317 queueId,
318 req->getHttpMethod(),
319 req->messageId,
320 ((CIMInvokeMethodRequestMessage*)req.get())->methodName,
321 PEGASUS_CIM_EXCEPTION_L(CIM_ERR_ACCESS_DENIED,
322 MessageLoaderParms(
|
323 kumpf 1.50 "Server.CIMOperationRequestAuthorizer."
324 "NAMESPACE_AUTHORIZATION_FAILED",
325 "User '$0' is not authorized to run '$1' in the "
326 "namespace '$2'",
|
327 sushma.fernandes 1.47 userName, cimMethodName, nameSpace.getString())));
|
328 kumpf 1.46 }
329 else
330 {
331 sendIMethodError(
332 queueId,
333 req->getHttpMethod(),
334 req->messageId,
335 cimMethodName,
336 PEGASUS_CIM_EXCEPTION_L(CIM_ERR_ACCESS_DENIED,
337 MessageLoaderParms(
|
338 kumpf 1.50 "Server.CIMOperationRequestAuthorizer."
339 "NAMESPACE_AUTHORIZATION_FAILED",
340 "User '$0' is not authorized to run '$1' in the "
341 "namespace '$2'",
|
342 sushma.fernandes 1.47 userName, cimMethodName, nameSpace.getString())));
|
343 kumpf 1.46 }
344 PEG_METHOD_EXIT();
345 return;
346 }
|
347 marek 1.42 #endif
348
|
349 kumpf 1.30 #ifdef PEGASUS_ENABLE_USERGROUP_AUTHORIZATION
|
350 kumpf 1.46 //
351 // If the user is not privileged and authorized user group is specified,
352 // then perform the user group authorization check.
353 //
354 try
355 {
356 if ( ! System::isPrivilegedUser(userName) )
357 {
358 Uint32 size = _authorizedUserGroups.size();
359
360 if (size > 0)
361 {
362 Boolean authorized = false;
363
364 //
365 // Check if the user name is in the authorized user groups.
366 //
367 for (Uint32 i = 0; i < size; i++)
368 {
369 //
370 // Check if the user is a member of the group
371 kumpf 1.46 //
372 if (System::isGroupMember(userName.getCString(),
373 _authorizedUserGroups[i].getCString()))
374 {
375 authorized = true;
376 break;
377 }
378 }
379
380 //
381 // If the user is not a member of any of the authorized
382 // user groups then generate error response.
383 //
384 if (!authorized)
385 {
|
386 marek 1.49 PEG_TRACE_STRING(TRC_SERVER, Tracer::LEVEL2,
|
387 kumpf 1.46 "Authorization Failed: User '" + userName +
388 "' is not a member of the authorized groups");
389
390 MessageLoaderParms msgLoaderParms(
391 "Server.CIMOperationRequestAuthorizer."
392 "NOT_IN_AUTHORIZED_GRP",
393 "User '$0' is not authorized to access CIM data.",
394 userName);
395
396 //
397 // user is not in the authorized user groups, send an
398 // error message to the requesting client.
399 //
400 if (cimMethodName == "InvokeMethod")
401 {
402 sendMethodError(
403 queueId,
404 req->getHttpMethod(),
405 req->messageId,
406 ((CIMInvokeMethodRequestMessage*)req.get())->
407 methodName,
408 kumpf 1.46 PEGASUS_CIM_EXCEPTION_L(CIM_ERR_ACCESS_DENIED,
409 msgLoaderParms));
410 PEG_METHOD_EXIT();
411 return;
412 }
413 else
414 {
415 sendIMethodError(
416 queueId,
417 req->getHttpMethod(),
418 req->messageId,
419 cimMethodName,
420 PEGASUS_CIM_EXCEPTION_L(CIM_ERR_ACCESS_DENIED,
421 msgLoaderParms));
422 PEG_METHOD_EXIT();
423 return;
424 }
425 }
426 }
427 }
428 }
429 kumpf 1.46 catch (InternalSystemError& ise)
430 {
431 sendIMethodError(
432 queueId,
433 req->getHttpMethod(),
434 req->messageId,
435 cimMethodName,
436 PEGASUS_CIM_EXCEPTION(CIM_ERR_ACCESS_DENIED, ise.getMessage()));
437 PEG_METHOD_EXIT();
438 return;
439 }
|
440 kumpf 1.30 #endif // #ifdef PEGASUS_ENABLE_USERGROUP_AUTHORIZATION
441
|
442 kumpf 1.46 //
443 // Get a config manager instance
444 //
445 ConfigManager* configManager = ConfigManager::getInstance();
446
447 //
448 // Do namespace authorization verification
449 //
450 if (ConfigManager::parseBooleanValue(
451 configManager->getCurrentValue("enableNamespaceAuthorization")))
452 {
453 //
454 // If the user is not privileged, perform the authorization check.
455 //
456 if (!System::isPrivilegedUser(userName))
457 {
458 UserManager* userManager = UserManager::getInstance();
|
459 mday 1.5
|
460 kumpf 1.46 if (!userManager ||
461 !userManager->verifyAuthorization(
462 userName, nameSpace, cimMethodName))
463 {
464 if (cimMethodName == "InvokeMethod")
465 {
466 sendMethodError(
467 queueId,
468 req->getHttpMethod(),
469 req->messageId,
470 ((CIMInvokeMethodRequestMessage*)req.get())->methodName,
471 PEGASUS_CIM_EXCEPTION_L(CIM_ERR_ACCESS_DENIED,
472 MessageLoaderParms(
|
473 kumpf 1.50 "Server.CIMOperationRequestAuthorizer."
474 "NAMESPACE_AUTHORIZATION_FAILED",
475 "User '$0' is not authorized to run '$1' in the "
476 "namespace '$2'",
477 userName, cimMethodName, nameSpace.getString())));
|
478 kumpf 1.46 }
479 else
480 {
481 sendIMethodError(
482 queueId,
483 req->getHttpMethod(),
484 req->messageId,
485 cimMethodName,
486 PEGASUS_CIM_EXCEPTION_L(CIM_ERR_ACCESS_DENIED,
487 MessageLoaderParms(
|
488 kumpf 1.50 "Server.CIMOperationRequestAuthorizer."
489 "NAMESPACE_AUTHORIZATION_FAILED",
490 "User '$0' is not authorized to run '$1' in "
491 "the namespace '$2'",
492 userName,
493 cimMethodName,
494 nameSpace.getString())));
|
495 kumpf 1.46 }
|
496 kumpf 1.22
|
497 kumpf 1.46 PEG_METHOD_EXIT();
498 return;
|
499 kumpf 1.23 }
|
500 kumpf 1.46 }
501 }
|
502 mday 1.5
|
503 kumpf 1.46 //
504 // Enqueue the request
505 //
506 _outputQueue->enqueue(req.release());
|
507 kumpf 1.1
|
508 kumpf 1.46 PEG_METHOD_EXIT();
|
509 mday 1.5 }
510
511 void CIMOperationRequestAuthorizer::handleEnqueue()
512 {
|
513 kumpf 1.46 PEG_METHOD_ENTER(TRC_SERVER,
514 "CIMOperationRequestAuthorizer::handleEnqueue");
|
515 kumpf 1.10
|
516 kumpf 1.46 Message* request = dequeue();
517 if (request)
518 handleEnqueue(request);
|
519 kumpf 1.10
|
520 kumpf 1.46 PEG_METHOD_EXIT();
|
521 kumpf 1.1 }
522
523 void CIMOperationRequestAuthorizer::setServerTerminating(Boolean flag)
524 {
|
525 kumpf 1.46 PEG_METHOD_ENTER(TRC_SERVER,
526 "CIMOperationRequestAuthorizer::setServerTerminating");
|
527 kumpf 1.1
|
528 kumpf 1.46 _serverTerminating = flag;
|
529 kumpf 1.1
|
530 kumpf 1.46 PEG_METHOD_EXIT();
|
531 kumpf 1.1 }
532
|
533 kumpf 1.30 Array<String> CIMOperationRequestAuthorizer::_getAuthorizedUserGroups()
534 {
|
535 kumpf 1.46 PEG_METHOD_ENTER(TRC_SERVER,
536 "CIMOperationRequestAuthorizer::getAuthorizedUserGroups");
|
537 kumpf 1.30
|
538 kumpf 1.46 Array<String> authorizedGroups;
|
539 kumpf 1.30
|
540 kumpf 1.51 String groupNames;
|
541 kumpf 1.30
|
542 kumpf 1.46 //
543 // Get a config manager instance
544 //
545 ConfigManager* configManager = ConfigManager::getInstance();
546
547 groupNames = configManager->getCurrentValue("authorizedUserGroups");
548
549 //
550 // Check if the group name is empty
551 //
|
552 kumpf 1.51 if (groupNames == String::EMPTY)
|
553 kumpf 1.46 {
554 PEG_METHOD_EXIT();
555 return authorizedGroups;
556 }
557
558 //
559 // Append _GROUPNAME_SEPARATOR to the end of the groups
560 //
561 groupNames.append(_GROUPNAME_SEPARATOR);
562
563 Uint32 position = 0;
564 String groupName;
565
566 while (groupNames != String::EMPTY)
567 {
568 //
569 // Get a group name from user groups
570 // User groups are separated by _GROUPNAME_SEPARATOR
571 //
572 position = groupNames.find(_GROUPNAME_SEPARATOR);
573 groupName = groupNames.subString(0,(position));
574 kumpf 1.46
575 authorizedGroups.append(groupName);
576
577 // Remove the searched group name
578 groupNames.remove(0, position + 1);
579 }
|
580 kumpf 1.30
|
581 kumpf 1.46 PEG_METHOD_EXIT();
|
582 kumpf 1.30
|
583 kumpf 1.46 return authorizedGroups;
584 }
|
585 kumpf 1.30
|
586 kumpf 1.1 PEGASUS_NAMESPACE_END
|