(file) Return to CIMOperationRequestAuthorizer.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Server

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2