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

   1 martin 1.121 //%LICENSE////////////////////////////////////////////////////////////////
   2 martin 1.122 //
   3 martin 1.121 // 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.122 //
  10 martin 1.121 // 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.122 //
  17 martin 1.121 // The above copyright notice and this permission notice shall be included
  18              // in all copies or substantial portions of the Software.
  19 martin 1.122 //
  20 martin 1.121 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  21 martin 1.122 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22 martin 1.121 // 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.122 //
  28 martin 1.121 //////////////////////////////////////////////////////////////////////////
  29 mike   1.2   //
  30              //%/////////////////////////////////////////////////////////////////////////////
  31              
  32              #include <Pegasus/Common/Config.h>
  33 kumpf  1.28  #include <Pegasus/Common/Constants.h>
  34 mike   1.2   #include <cctype>
  35              #include <cstdio>
  36              #include <Pegasus/Common/XmlParser.h>
  37              #include <Pegasus/Common/XmlReader.h>
  38              #include <Pegasus/Common/XmlWriter.h>
  39              #include <Pegasus/Common/XmlConstants.h>
  40 kumpf  1.51  #include <Pegasus/Common/System.h>
  41 mike   1.2   #include <Pegasus/Common/Logger.h>
  42              #include <Pegasus/Common/Tracer.h>
  43 sage   1.41  #include <Pegasus/Common/StatisticalData.h>
  44 mike   1.2   #include "CIMOperationRequestDecoder.h"
  45 david  1.60  #include <Pegasus/Common/CommonUTF.h>
  46 humberto 1.59  #include <Pegasus/Common/MessageLoader.h>
  47 mike     1.120 #include <Pegasus/Common/BinaryCodec.h>
  48 marek    1.138 #include <Pegasus/Common/OperationContextInternal.h>
  49 marek    1.139 #include <Pegasus/General/CIMError.h>
  50                
  51                #ifdef PEGASUS_PAM_SESSION_SECURITY
  52                #include <Pegasus/Security/Authentication/PAMSessionBasicAuthenticator.h>
  53                #include <Pegasus/Security/Authentication/AuthenticationStatus.h>
  54                #endif
  55                
  56 humberto 1.59  
  57 mike     1.2   PEGASUS_USING_STD;
  58                
  59                PEGASUS_NAMESPACE_BEGIN
  60                
  61 karl     1.137 // throw CIM_ERR_NOT_SUPPORTED with no additional text
  62                void _throwCIMExceptionCIMErrNotSupported(const String& param = String::EMPTY)
  63                {
  64                    throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, param);
  65                }
  66                
  67                // Throw CIM_ERR_INVALID_PARAMETER with optional parameter name(s)
  68                void _throwCIMExceptionInvalidParameter(const String& param = String::EMPTY)
  69                {
  70                    throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, param);
  71                }
  72                
  73                // Common call for all cases where duplicate IparameterValues recieved
  74                // in a single operation. Throw InvalidParameter exception with optional
  75                // additional data.
  76                void _throwCIMExceptionDuplicateParameter(const String& name = String::EMPTY)
  77                {
  78                    _throwCIMExceptionInvalidParameter(name);
  79                }
  80                
  81                // Common call for cases where Invalid IParameterValue names recived
  82 karl     1.137 void _throwCIMExceptionInvalidIParamName(const String& param = String::EMPTY)
  83                {
  84                    _throwCIMExceptionCIMErrNotSupported(param);
  85                }
  86                
  87 marek    1.139 #ifdef PEGASUS_PAM_SESSION_SECURITY
  88                void CIMOperationRequestDecoder::_updateExpiredPassword(
  89                    Uint32 queueId,
  90                    HttpMethod httpMethod,
  91                    const String& messageId,
  92                    Boolean closeConnect,
  93                    const ContentLanguageList& httpContentLanguages,
  94                    CIMMessage * request,
  95                    const String& userName,
  96                    const String& oldPass)
  97                {
  98                    static CIMName meth = CIMName("UpdateExpiredPassword");
  99                    static CIMName clName = CIMName("PG_Account");
 100                    
 101                
 102                    // this has to be an invokeMethod and
 103                    if (CIM_INVOKE_METHOD_REQUEST_MESSAGE != request->getType())
 104                    {
 105                        sendHttpError(
 106                            queueId,
 107                            HTTP_STATUS_BADREQUEST,
 108 marek    1.139             "invalid header",
 109                            "Header \'Pragma: UpdateExpiredPassword\' not valid for this "
 110                                "CIMMethod.",
 111                            closeConnect);
 112                        
 113                        return;
 114                    }
 115                
 116                    CIMInvokeMethodRequestMessage* msg =
 117                        dynamic_cast<CIMInvokeMethodRequestMessage*>(request);
 118                
 119                    // class PG_Account
 120                    // method UpdateExpiredPassword
 121                    // InterOp namespace    
 122                    if ((!clName.equal(msg->className)) ||
 123                        (!(meth.equal(msg->methodName))) ||
 124                        (!msg->nameSpace.equal(PEGASUS_NAMESPACENAME_INTEROP.getString())))
 125                    {
 126                        // not of interest for us, chicken out
 127                        sendHttpError(
 128                            queueId,
 129 marek    1.139             HTTP_STATUS_BADREQUEST,
 130                            "invalid header",
 131                            "Header \'Pragma: UpdateExpiredPassword\' not valid for this "
 132                                "class, method or namespace.",
 133                            closeConnect);
 134                        return;
 135                    }
 136                    
 137                    String newPass;
 138                    Boolean found = false;
 139                
 140                    try
 141                    {
 142                        // Get new password from request - String-type Parameter UserPassword
 143                        Array<CIMParamValue> inParm = msg->inParameters;
 144                        for (Uint32 i=0; i < inParm.size(); i++)
 145                        {
 146                            CIMParamValue x = inParm[i];
 147                            if (String::equalNoCase(x.getParameterName(),"UserPassword"))
 148                            {
 149                                CIMValue passValue = x.getValue();
 150 marek    1.139                 passValue.get(newPass);
 151                                found = true;
 152                                break;
 153                            }
 154                        }
 155                    } catch(Exception &e)
 156                    {
 157                        // already know it is an invokeMethod, see checks above
 158                        sendMethodError(
 159                            queueId,
 160                            httpMethod,
 161                            messageId,
 162                            meth.getString(),
 163                            PEGASUS_CIM_EXCEPTION(
 164                                CIM_ERR_INVALID_PARAMETER, e.getMessage()),
 165                            closeConnect);
 166                        return;
 167                    }
 168                    if (!found)
 169                    {
 170                        sendMethodError(
 171 marek    1.139             queueId,
 172                            httpMethod,
 173                            messageId,
 174                            meth.getString(),
 175                            PEGASUS_CIM_EXCEPTION(
 176                                CIM_ERR_INVALID_PARAMETER, "Missing Parameter UserPassword"),
 177                            closeConnect);
 178                        return;
 179                    }
 180                    // Call password update function from PAMSession.h
 181                    AuthenticationStatus authStat =
 182                        PAMSessionBasicAuthenticator::updateExpiredPassword(
 183                            userName,
 184                            oldPass,
 185                            newPass);
 186                
 187                    if (authStat.isSuccess())
 188                    {
 189                        // Send success message
 190                        Buffer message;
 191                        Buffer emptyBody;
 192 marek    1.139 
 193                        message = XmlWriter::formatSimpleMethodRspMessage(
 194                            meth,
 195                            messageId,
 196                            httpMethod,
 197                            httpContentLanguages,
 198                            emptyBody,
 199                            0,
 200                            true,
 201                            true);
 202                
 203                        sendResponse(queueId, message,closeConnect);
 204                    }
 205                    else
 206                    {
 207                        sendHttpError(
 208                            queueId,
 209                            authStat.getHttpStatus(),
 210                            String::EMPTY,
 211                            authStat.getErrorDetail(),
 212                            closeConnect);
 213 marek    1.139     }
 214                }
 215                #endif
 216                
 217                
 218                
 219                
 220 mike     1.2   CIMOperationRequestDecoder::CIMOperationRequestDecoder(
 221 sahana.prabhakar 1.126     MessageQueue* outputQueue,
 222 kumpf            1.104     Uint32 returnQueueId)
 223                            : Base(PEGASUS_QUEUENAME_OPREQDECODER),
 224 mday             1.16        _outputQueue(outputQueue),
 225                              _returnQueueId(returnQueueId),
 226                              _serverTerminating(false)
 227 mike             1.2   {
 228                        }
 229                        
 230                        CIMOperationRequestDecoder::~CIMOperationRequestDecoder()
 231                        {
 232                        }
 233                        
 234                        void CIMOperationRequestDecoder::sendResponse(
 235 kumpf            1.104     Uint32 queueId,
 236                            Buffer& message,
 237                            Boolean closeConnect)
 238                        {
 239                            MessageQueue* queue = MessageQueue::lookup(queueId);
 240                        
 241                            if (queue)
 242                            {
 243                                AutoPtr<HTTPMessage> httpMessage(new HTTPMessage(message));
 244                                httpMessage->setCloseConnect(closeConnect);
 245                                queue->enqueue(httpMessage.release());
 246                            }
 247 mike             1.2   }
 248                        
 249 kumpf            1.18  void CIMOperationRequestDecoder::sendIMethodError(
 250 kumpf            1.104     Uint32 queueId,
 251                            HttpMethod httpMethod,
 252                            const String& messageId,
 253                            const String& iMethodName,
 254                            const CIMException& cimException,
 255                            Boolean closeConnect)
 256 mday             1.16  {
 257 mike             1.96      Buffer message;
 258 kumpf            1.19      message = XmlWriter::formatSimpleIMethodErrorRspMessage(
 259                                iMethodName,
 260                                messageId,
 261 kumpf            1.53          httpMethod,
 262 kumpf            1.35          cimException);
 263 kumpf            1.18  
 264 j.alex           1.95      sendResponse(queueId, message,closeConnect);
 265 kumpf            1.18  }
 266 mday             1.16  
 267 kumpf            1.18  void CIMOperationRequestDecoder::sendMethodError(
 268 kumpf            1.104     Uint32 queueId,
 269                            HttpMethod httpMethod,
 270                            const String& messageId,
 271                            const String& methodName,
 272                            const CIMException& cimException,
 273                            Boolean closeConnect)
 274 kumpf            1.18  {
 275 mike             1.96      Buffer message;
 276 kumpf            1.19      message = XmlWriter::formatSimpleMethodErrorRspMessage(
 277                                methodName,
 278                                messageId,
 279 kumpf            1.53          httpMethod,
 280 kumpf            1.35          cimException);
 281 chip             1.92  
 282 j.alex           1.95      sendResponse(queueId, message,closeConnect);
 283 mike             1.2   }
 284                        
 285 marek            1.139 void CIMOperationRequestDecoder::sendUserAccountExpired(
 286                            Uint32 queueId,
 287                            HttpMethod httpMethod,
 288                            const String& messageId,
 289                            const String& methodName,
 290                            Boolean closeConnect,
 291                            Boolean isIMethod)
 292                        {
 293                            Buffer message;
 294                        
 295                            CIMError errorInst;
 296                            errorInst.setErrorType(CIMError::ERROR_TYPE_OTHER);
 297                            errorInst.setOtherErrorType("Expired Password");
 298                            errorInst.setProbableCause(CIMError::PROBABLE_CAUSE_AUTHENTICATION_FAILURE);
 299                        
 300                            CIMException myExc(
 301                                CIM_ERR_ACCESS_DENIED,
 302                                "User Account Expired",
 303                                errorInst.getInstance());
 304                        
 305                            if (isIMethod)
 306 marek            1.139     {
 307                                message = XmlWriter::formatSimpleIMethodErrorRspMessage(
 308                                    methodName,
 309                                    messageId,
 310                                    httpMethod,
 311                                    myExc);
 312                            }
 313                            else
 314                            {
 315                                message = XmlWriter::formatSimpleMethodErrorRspMessage(
 316                                    methodName,
 317                                    messageId,
 318                                    httpMethod,
 319                                    myExc);
 320                            }
 321                                                  
 322                            sendResponse(queueId, message,closeConnect);
 323                        }
 324                        
 325 kumpf            1.33  void CIMOperationRequestDecoder::sendHttpError(
 326 kumpf            1.104     Uint32 queueId,
 327                            const String& status,
 328                            const String& cimError,
 329                            const String& pegasusError,
 330                            Boolean closeConnect)
 331 kumpf            1.21  {
 332 mike             1.96      Buffer message;
 333 kumpf            1.33      message = XmlWriter::formatHttpErrorRspMessage(
 334                                status,
 335                                cimError,
 336 kumpf            1.37          pegasusError);
 337 chip             1.92  
 338 j.alex           1.95      sendResponse(queueId, message,closeConnect);
 339 kumpf            1.26  }
 340                        
 341 kumpf            1.104 void CIMOperationRequestDecoder::handleEnqueue(Message* message)
 342 mike             1.2   {
 343 kumpf            1.104     if (!message)
 344                                return;
 345 mike             1.2   
 346 kumpf            1.104     switch (message->getType())
 347                            {
 348                                case HTTP_MESSAGE:
 349                                     handleHTTPMessage((HTTPMessage*)message);
 350                                     break;
 351 kumpf            1.112 
 352                                default:
 353                                    // Unexpected message type
 354 dl.meetei        1.136             PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
 355 kumpf            1.112             break;
 356 kumpf            1.104     }
 357 mday             1.16  
 358 kumpf            1.104     delete message;
 359 mday             1.16  }
 360 mike             1.2   
 361                        
 362 mday             1.16  void CIMOperationRequestDecoder::handleEnqueue()
 363                        {
 364 kumpf            1.104     Message* message = dequeue();
 365                            if (message)
 366                                handleEnqueue(message);
 367 mike             1.2   }
 368                        
 369                        //------------------------------------------------------------------------------
 370                        //
 371                        // From the HTTP/1.1 Specification (RFC 2626):
 372                        //
 373 chip             1.92  // Both types of message consist of a start-line, zero or more header fields
 374                        // (also known as "headers"), an empty line (i.e., a line with nothing
 375                        // preceding the CRLF) indicating the end of the header fields, and possibly
 376 mike             1.2   // a message-body.
 377                        //
 378                        // Example CIM request:
 379                        //
 380 chip             1.92  //     M-POST /cimom HTTP/1.1
 381                        //     HOST: www.erewhon.com
 382 marek            1.132 //     Content-Type: application/xml; charset=utf-8
 383 chip             1.92  //     Content-Length: xxxx
 384                        //     Man: http://www.dmtf.org/cim/operation ; ns=73
 385                        //     73-CIMOperation: MethodCall
 386                        //     73-CIMMethod: EnumerateInstances
 387                        //     73-CIMObject: root/cimv2
 388                        //
 389 mike             1.2   //------------------------------------------------------------------------------
 390                        
 391                        void CIMOperationRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage)
 392                        {
 393 kumpf            1.104     PEG_METHOD_ENTER(TRC_DISPATCHER,
 394                                "CIMOperationRequestDecoder::handleHTTPMessage()");
 395 kumpf            1.20  
 396 kumpf            1.104     // Set the Accept-Language into the thread for this service.
 397                            // This will allow all code in this thread to get
 398                            // the languages for the messages returned to the client.
 399 kumpf            1.114     Thread::setLanguages(httpMessage->acceptLanguages);
 400 kumpf            1.104 
 401                            // Save queueId:
 402                        
 403                            Uint32 queueId = httpMessage->queueId;
 404                        
 405 marek            1.139     // Save userName, userRole, userPass and authType:
 406 kumpf            1.104 
 407                            String userName;
 408 marek            1.138     String userRole;
 409 marek            1.139     String userPass;
 410                            Boolean isExpiredPassword = false;
 411                            Boolean updateExpiredPassword;
 412 kumpf            1.104     String authType;
 413                            Boolean closeConnect = httpMessage->getCloseConnect();
 414                        
 415                            PEG_TRACE((
 416                                TRC_HTTP,
 417 marek            1.118         Tracer::LEVEL4,
 418 kumpf            1.104         "CIMOperationRequestDecoder::handleHTTPMessage()- "
 419                                "httpMessage->getCloseConnect() returned %d",
 420                                closeConnect));
 421                        
 422 sushma.fernandes 1.109     userName = httpMessage->authInfo->getAuthenticatedUser();
 423                            authType = httpMessage->authInfo->getAuthType();
 424 marek            1.138     userRole = httpMessage->authInfo->getUserRole();
 425 marek            1.139     userPass = httpMessage->authInfo->getAuthenticatedPassword();
 426                        
 427                        #ifdef PEGASUS_PAM_SESSION_SECURITY
 428                            isExpiredPassword = httpMessage->authInfo->isExpiredPassword();
 429                        #endif
 430 kumpf            1.104 
 431                            // Parse the HTTP message:
 432                        
 433                            String startLine;
 434                            Array<HTTPHeader> headers;
 435                            char* content;
 436                            Uint32 contentLength;
 437                        
 438                            httpMessage->parse(startLine, headers, contentLength);
 439                        
 440                            // Parse the request line:
 441                        
 442                            String methodName;
 443                            String requestUri;
 444                            String httpVersion;
 445                            HttpMethod httpMethod = HTTP_METHOD__POST;
 446                        
 447                            HTTPMessage::parseRequestLine(
 448                                startLine, methodName, requestUri, httpVersion);
 449                        
 450                            //
 451 kumpf            1.104     //  Set HTTP method for the request
 452                            //
 453                            if (methodName == "M-POST")
 454                            {
 455                                httpMethod = HTTP_METHOD_M_POST;
 456                            }
 457                        
 458                            // Unsupported methods are caught in the HTTPAuthenticatorDelegator
 459                            PEGASUS_ASSERT(methodName == "M-POST" || methodName == "POST");
 460                        
 461                            //
 462                            //  Mismatch of method and version is caught in HTTPAuthenticatorDelegator
 463                            //
 464                            PEGASUS_ASSERT(!((httpMethod == HTTP_METHOD_M_POST) &&
 465                                             (httpVersion == "HTTP/1.0")));
 466 humberto         1.80  
 467 kumpf            1.104     // Process M-POST and POST messages:
 468 humberto         1.80  
 469 kumpf            1.104     if (httpVersion == "HTTP/1.1")
 470                            {
 471                                // Validate the presence of a "Host" header.  The HTTP/1.1 specification
 472                                // says this in section 14.23 regarding the Host header field:
 473                                //
 474                                //     All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad
 475                                //     Request) status code to any HTTP/1.1 request message which lacks
 476                                //     a Host header field.
 477                                //
 478                                // Note:  The Host header value is not validated.
 479                        
 480 kumpf            1.124         const char* hostHeader;
 481 kumpf            1.104         Boolean hostHeaderFound = HTTPMessage::lookupHeader(
 482                                    headers, "Host", hostHeader, false);
 483 mike             1.2   
 484 kumpf            1.104         if (!hostHeaderFound)
 485                                {
 486                                    MessageLoaderParms parms(
 487                                        "Server.CIMOperationRequestDecoder.MISSING_HOST_HEADER",
 488                                        "HTTP request message lacks a Host header field.");
 489                                    sendHttpError(
 490                                        queueId,
 491                                        HTTP_STATUS_BADREQUEST,
 492                                        "",
 493                                        MessageLoader::getMessage(parms),
 494                                        closeConnect);
 495                                    PEG_METHOD_EXIT();
 496                                    return;
 497                                }
 498                            }
 499 mike             1.2   
 500 kumpf            1.104     // Validate the "CIMOperation" header:
 501 mike             1.2   
 502 kumpf            1.124     const char* cimOperation;
 503 karl             1.135 
 504 kumpf            1.104     // If the CIMOperation header was missing, the HTTPAuthenticatorDelegator
 505                            // would not have passed the message to us.
 506 marek            1.134     PEGASUS_FCT_EXECUTE_AND_ASSERT(
 507                                true,
 508                                HTTPMessage::lookupHeader(headers, "CIMOperation", cimOperation, true));
 509 kumpf            1.104 
 510 kumpf            1.124     if (System::strcasecmp(cimOperation, "MethodCall") != 0)
 511 kumpf            1.104     {
 512                                // The Specification for CIM Operations over HTTP reads:
 513                                //     3.3.4. CIMOperation
 514                                //     If a CIM Server receives CIM Operation request with this
 515                                //     [CIMOperation] header, but with a missing value or a value
 516                                //     that is not "MethodCall", then it MUST fail the request with
 517                                //     status "400 Bad Request". The CIM Server MUST include a
 518                                //     CIMError header in the response with a value of
 519                                //     unsupported-operation.
 520                                MessageLoaderParms parms(
 521                                    "Server.CIMOperationRequestDecoder."
 522                                        "CIMOPERATION_VALUE_NOT_SUPPORTED",
 523                                    "CIMOperation value \"$0\" is not supported.",cimOperation);
 524                                sendHttpError(
 525                                    queueId,
 526                                    HTTP_STATUS_BADREQUEST,
 527                                    "unsupported-operation",
 528                                    MessageLoader::getMessage(parms),
 529                                    closeConnect);
 530                                PEG_METHOD_EXIT();
 531                                return;
 532 kumpf            1.104     }
 533                        
 534                            // Validate the "CIMBatch" header:
 535                        
 536 kumpf            1.124     const char* cimBatch;
 537                            if (HTTPMessage::lookupHeader(headers, "CIMBatch", cimBatch, true))
 538 kumpf            1.104     {
 539                                // The Specification for CIM Operations over HTTP reads:
 540                                //     3.3.9. CIMBatch
 541                                //     If a CIM Server receives CIM Operation Request for which the
 542                                //     CIMBatch header is present, but the Server does not support
 543                                //     Multiple Operations, then it MUST fail the request and
 544                                //     return a status of "501 Not Implemented".
 545                                sendHttpError(
 546                                    queueId,
 547                                    HTTP_STATUS_NOTIMPLEMENTED,
 548                                    "multiple-requests-unsupported",
 549                                    String::EMPTY,
 550                                    closeConnect);
 551                                PEG_METHOD_EXIT();
 552                                return;
 553                            }
 554                        
 555                            // Save these headers for later checking
 556                        
 557 kumpf            1.124     const char* cimProtocolVersion;
 558 kumpf            1.104     if (!HTTPMessage::lookupHeader(
 559                                headers, "CIMProtocolVersion", cimProtocolVersion, true))
 560                            {
 561                                // Mandated by the Specification for CIM Operations over HTTP
 562 kumpf            1.124         cimProtocolVersion = "1.0";
 563 kumpf            1.104     }
 564                        
 565 marek            1.139     // Validate if Pragma: UpdateExpiredPassword is set
 566                            updateExpiredPassword = false;
 567                        
 568                            String pragmaValue;
 569                            if(HTTPMessage::lookupHeader(headers,"Pragma",pragmaValue))
 570                            {
 571                                updateExpiredPassword = 
 572                                    (PEG_NOT_FOUND != pragmaValue.find("UpdateExpiredPassword"));
 573                            }
 574                        
 575 kumpf            1.124     String cimMethod;
 576 kumpf            1.104     if (HTTPMessage::lookupHeader(headers, "CIMMethod", cimMethod, true))
 577                            {
 578                                if (cimMethod == String::EMPTY)
 579                                {
 580                                    // This is not a valid value, and we use EMPTY to mean "absent"
 581                                    MessageLoaderParms parms(
 582                                        "Server.CIMOperationRequestDecoder.EMPTY_CIMMETHOD_VALUE",
 583                                        "Empty CIMMethod value.");
 584                                    sendHttpError(
 585                                        queueId,
 586                                        HTTP_STATUS_BADREQUEST,
 587                                        "header-mismatch",
 588                                        MessageLoader::getMessage(parms),
 589                                        closeConnect);
 590                                    PEG_METHOD_EXIT();
 591                                    return;
 592                                }
 593 mike             1.98  
 594 kumpf            1.104         try
 595                                {
 596                                    cimMethod = XmlReader::decodeURICharacters(cimMethod);
 597                                }
 598                                catch (const ParseError&)
 599                                {
 600                                    // The CIMMethod header value could not be decoded
 601                                    MessageLoaderParms parms(
 602                                        "Server.CIMOperationRequestDecoder."
 603                                            "CIMMETHOD_VALUE_SYNTAX_ERROR",
 604                                        "CIMMethod value syntax error.");
 605                                    sendHttpError(
 606                                        queueId,
 607                                        HTTP_STATUS_BADREQUEST,
 608                                        "header-mismatch",
 609                                        MessageLoader::getMessage(parms),
 610                                        closeConnect);
 611                                    PEG_METHOD_EXIT();
 612                                    return;
 613                                }
 614                            }
 615 mike             1.2   
 616 kumpf            1.124     String cimObject;
 617 kumpf            1.104     if (HTTPMessage::lookupHeader(headers, "CIMObject", cimObject, true))
 618                            {
 619                                if (cimObject == String::EMPTY)
 620                                {
 621                                    // This is not a valid value, and we use EMPTY to mean "absent"
 622                                    MessageLoaderParms parms(
 623                                        "Server.CIMOperationRequestDecoder.EMPTY_CIMOBJECT_VALUE",
 624                                        "Empty CIMObject value.");
 625                                    sendHttpError(
 626                                        queueId,
 627                                        HTTP_STATUS_BADREQUEST,
 628                                        "header-mismatch",
 629                                        MessageLoader::getMessage(parms),
 630                                        closeConnect);
 631                                    PEG_METHOD_EXIT();
 632                                    return;
 633                                }
 634 mike             1.2   
 635 kumpf            1.104         try
 636                                {
 637                                    cimObject = XmlReader::decodeURICharacters(cimObject);
 638                                }
 639                                catch (const ParseError&)
 640                                {
 641                                    // The CIMObject header value could not be decoded
 642                                    MessageLoaderParms parms(
 643                                        "Server.CIMOperationRequestDecoder."
 644                                            "CIMOBJECT_VALUE_SYNTAX_ERROR",
 645                                        "CIMObject value syntax error.");
 646                                    sendHttpError(
 647                                        queueId,
 648                                        HTTP_STATUS_BADREQUEST,
 649                                        "header-mismatch",
 650                                        MessageLoader::getMessage(parms),
 651                                        closeConnect);
 652                                    PEG_METHOD_EXIT();
 653                                    return;
 654                                }
 655                            }
 656 mike             1.2   
 657 kumpf            1.104     // Validate the "Content-Type" header:
 658 mike             1.2   
 659 kumpf            1.124     const char* cimContentType;
 660 kumpf            1.104     Boolean contentTypeHeaderFound = HTTPMessage::lookupHeader(
 661                                headers, "Content-Type", cimContentType, true);
 662 kumpf            1.115     String type;
 663                            String charset;
 664 mike             1.120     Boolean binaryRequest = false;
 665 kumpf            1.115 
 666 kumpf            1.123     if (!contentTypeHeaderFound ||
 667 kumpf            1.115         !HTTPMessage::parseContentTypeHeader(cimContentType, type, charset) ||
 668 marek            1.127         (((!String::equalNoCase(type, "application/xml") &&
 669 kumpf            1.115          !String::equalNoCase(type, "text/xml")) ||
 670 kumpf            1.123         !String::equalNoCase(charset, "utf-8"))
 671                                && !(binaryRequest = String::equalNoCase(type,
 672 mike             1.120             "application/x-openpegasus"))
 673 marek            1.127         ))
 674 kumpf            1.104     {
 675 j.alex           1.95          MessageLoaderParms parms(
 676 kumpf            1.104             "Server.CIMOperationRequestDecoder.CIMCONTENTTYPE_SYNTAX_ERROR",
 677 kumpf            1.105             "HTTP Content-Type header error.");
 678 j.alex           1.95          sendHttpError(
 679                                    queueId,
 680                                    HTTP_STATUS_BADREQUEST,
 681 kumpf            1.105             "",
 682 j.alex           1.95              MessageLoader::getMessage(parms),
 683                                    closeConnect);
 684 kumpf            1.104         PEG_METHOD_EXIT();
 685                                return;
 686                            }
 687 marek            1.130     // Calculate the beginning of the content from the message size and
 688                            // the content length.
 689                            if (binaryRequest)
 690                            {
 691                                // binary the "Content" also contains a few padding '\0' to align
 692                                // data structures to 8byte boundary
 693                                // the padding '\0' are also part of the counted contentLength
 694                                Uint32 headerEnd = httpMessage->message.size() - contentLength;
 695                                Uint32 binContentStart = CIMBuffer::round(headerEnd);
 696                        
 697                                contentLength = contentLength - (binContentStart - headerEnd);
 698                                content = (char*) httpMessage->message.getData() + binContentStart;
 699                            }
 700                            else
 701                            {
 702                                content = (char*) httpMessage->message.getData() +
 703                                    httpMessage->message.size() - contentLength;
 704                            }
 705                        
 706 kumpf            1.104     // Validating content falls within UTF8
 707                            // (required to be complaint with section C12 of Unicode 4.0 spec,
 708                            // chapter 3.)
 709 marek            1.130     if (!binaryRequest)
 710 kumpf            1.104     {
 711                                Uint32 count = 0;
 712                                while(count<contentLength)
 713                                {
 714                                    if (!(isUTF8((char*)&content[count])))
 715                                    {
 716                                        MessageLoaderParms parms(
 717                                            "Server.CIMOperationRequestDecoder.INVALID_UTF8_CHARACTER",
 718                                            "Invalid UTF-8 character detected.");
 719                                        sendHttpError(
 720                                            queueId,
 721                                            HTTP_STATUS_BADREQUEST,
 722                                            "request-not-valid",
 723                                            MessageLoader::getMessage(parms),
 724                                            closeConnect);
 725                        
 726                                        PEG_METHOD_EXIT();
 727 mike             1.120                 return;
 728 kumpf            1.104             }
 729                                    UTF8_NEXT(content,count);
 730                                }
 731                            }
 732                        
 733 kumpf            1.123     // Check for "Accept: application/x-openpegasus" HTTP header to see if
 734 mike             1.120     // client can accept binary responses.
 735                        
 736                            bool binaryResponse;
 737                        
 738                            if (HTTPMessage::lookupHeader(headers, "Accept", type, true) &&
 739                                String::equalNoCase(type, "application/x-openpegasus"))
 740                            {
 741                                binaryResponse = true;
 742                            }
 743                            else
 744                            {
 745                                binaryResponse = false;
 746                            }
 747 marek            1.129     httpMessage->binaryResponse=binaryResponse;
 748 mike             1.120 
 749 kumpf            1.104     // If it is a method call, then dispatch it to be handled:
 750                        
 751                            handleMethodCall(
 752                                queueId,
 753                                httpMethod,
 754                                content,
 755                                contentLength,
 756                                cimProtocolVersion,
 757                                cimMethod,
 758                                cimObject,
 759                                authType,
 760                                userName,
 761 marek            1.138         userRole,
 762 marek            1.139         userPass,
 763                                isExpiredPassword,
 764                                updateExpiredPassword,
 765 kumpf            1.104         httpMessage->ipAddress,
 766                                httpMessage->acceptLanguages,
 767                                httpMessage->contentLanguages,
 768 mike             1.120         closeConnect,
 769                                binaryRequest,
 770                                binaryResponse);
 771 kumpf            1.104 
 772                            PEG_METHOD_EXIT();
 773                        }
 774                        
 775                        void CIMOperationRequestDecoder::handleMethodCall(
 776                            Uint32 queueId,
 777                            HttpMethod httpMethod,
 778                            char* content,
 779                            Uint32 contentLength,    // used for statistics only
 780 kumpf            1.124     const char* cimProtocolVersionInHeader,
 781 kumpf            1.104     const String& cimMethodInHeader,
 782                            const String& cimObjectInHeader,
 783                            const String& authType,
 784                            const String& userName,
 785 marek            1.138     const String& userRole,
 786 marek            1.139     const String& userPass,
 787                            Boolean isExpiredPassword,
 788                            Boolean updateExpiredPassword,
 789 kumpf            1.104     const String& ipAddress,
 790                            const AcceptLanguageList& httpAcceptLanguages,
 791                            const ContentLanguageList& httpContentLanguages,
 792 mike             1.120     Boolean closeConnect,
 793                            Boolean binaryRequest,
 794                            Boolean binaryResponse)
 795 kumpf            1.104 {
 796                            PEG_METHOD_ENTER(TRC_DISPATCHER,
 797                                "CIMOperationRequestDecoder::handleMethodCall()");
 798                        
 799                            //
 800                            // If CIMOM is shutting down, return "Service Unavailable" response
 801                            //
 802                            if (_serverTerminating)
 803                            {
 804 j.alex           1.95          MessageLoaderParms parms(
 805 kumpf            1.104             "Server.CIMOperationRequestDecoder.CIMSERVER_SHUTTING_DOWN",
 806                                    "CIM Server is shutting down.");
 807 j.alex           1.95          sendHttpError(
 808                                    queueId,
 809 kumpf            1.104             HTTP_STATUS_SERVICEUNAVAILABLE,
 810                                    String::EMPTY,
 811 j.alex           1.95              MessageLoader::getMessage(parms),
 812                                    closeConnect);
 813 kumpf            1.104         PEG_METHOD_EXIT();
 814                                return;
 815                            }
 816                        
 817 thilo.boehm      1.119     PEG_TRACE((TRC_XML,Tracer::LEVEL4,
 818 marek            1.116         "CIMOperationRequestdecoder - XML content: %s",
 819                                content));
 820 kumpf            1.104 
 821 mike             1.120     //
 822                            // Handle binary messages:
 823                            //
 824 kumpf            1.104 
 825                            AutoPtr<CIMOperationRequestMessage> request;
 826 marek            1.139     String messageId;
 827                            Boolean isIMethodCall = true;
 828 kumpf            1.104 
 829 mike             1.120     if (binaryRequest)
 830 kumpf            1.104     {
 831 marek            1.130         CIMBuffer buf(content, contentLength);
 832                                CIMBufferReleaser buf_(buf);
 833 mike             1.120 
 834                                request.reset(BinaryCodec::decodeRequest(buf, queueId, _returnQueueId));
 835                        
 836                                if (!request.get())
 837                                {
 838                                    sendHttpError(
 839                                        queueId,
 840                                        HTTP_STATUS_BADREQUEST,
 841                                        "Corrupt binary request message",
 842                                        String::EMPTY,
 843                                        closeConnect);
 844                                    PEG_METHOD_EXIT();
 845                                    return;
 846                                }
 847                            }
 848                            else try
 849                            {
 850                                XmlParser parser(content);
 851                                XmlEntry entry;
 852                                const char* cimMethodName = "";
 853                        
 854 kumpf            1.104         //
 855                                // Process <?xml ... >
 856                                //
 857                        
 858                                // These values are currently unused
 859                                const char* xmlVersion = 0;
 860                                const char* xmlEncoding = 0;
 861 mike             1.2   
 862 kumpf            1.104         XmlReader::getXmlDeclaration(parser, xmlVersion, xmlEncoding);
 863 mike             1.2   
 864 kumpf            1.104         // Expect <CIM ...>
 865 chip             1.92  
 866 kumpf            1.104         const char* cimVersion = 0;
 867                                const char* dtdVersion = 0;
 868 mike             1.2   
 869 kumpf            1.104         XmlReader::getCimStartTag(parser, cimVersion, dtdVersion);
 870 mike             1.2   
 871 karl             1.108         if (!XmlReader::isSupportedCIMVersion(cimVersion))
 872 kumpf            1.104         {
 873                                    MessageLoaderParms parms(
 874                                        "Server.CIMOperationRequestDecoder.CIM_VERSION_NOT_SUPPORTED",
 875                                        "CIM version \"$0\" is not supported.",
 876                                         cimVersion);
 877                                    sendHttpError(
 878                                        queueId,
 879                                        HTTP_STATUS_NOTIMPLEMENTED,
 880                                        "unsupported-cim-version",
 881                                        MessageLoader::getMessage(parms),
 882                                        closeConnect);
 883 kumpf            1.23              PEG_METHOD_EXIT();
 884                                    return;
 885 kumpf            1.104         }
 886 kumpf            1.23  
 887 karl             1.108         if (!XmlReader::isSupportedDTDVersion(dtdVersion))
 888 kumpf            1.104         {
 889                                    MessageLoaderParms parms(
 890                                        "Server.CIMOperationRequestDecoder.DTD_VERSION_NOT_SUPPORTED",
 891                                        "DTD version \"$0\" is not supported.",
 892                                        dtdVersion);
 893                                    sendHttpError(
 894 j.alex           1.95                  queueId,
 895 kumpf            1.104                 HTTP_STATUS_NOTIMPLEMENTED,
 896                                        "unsupported-dtd-version",
 897                                        MessageLoader::getMessage(parms),
 898 j.alex           1.95                  closeConnect);
 899 kumpf            1.20              PEG_METHOD_EXIT();
 900 kumpf            1.34              return;
 901 kumpf            1.104         }
 902                        
 903                                // Expect <MESSAGE ...>
 904                        
 905                                String protocolVersion;
 906 kumpf            1.73  
 907 kumpf            1.104         if (!XmlReader::getMessageStartTag(
 908                                         parser, messageId, protocolVersion))
 909                                {
 910                                    MessageLoaderParms mlParms(
 911                                        "Server.CIMOperationRequestDecoder.EXPECTED_MESSAGE_ELEMENT",
 912                                        "expected MESSAGE element");
 913 mday             1.16  
 914 kumpf            1.104             throw XmlValidationError(parser.getLine(), mlParms);
 915                                }
 916 mday             1.16  
 917 kumpf            1.104         // Validate that the protocol version in the header matches the XML
 918                                if (!String::equalNoCase(protocolVersion, cimProtocolVersionInHeader))
 919                                {
 920 j.alex           1.95              MessageLoaderParms parms(
 921 kumpf            1.104                 "Server.CIMOperationRequestDecoder."
 922                                            "CIMPROTOCOL_VERSION_MISMATCH",
 923                                        "CIMProtocolVersion value \"$0\" does not match CIM request "
 924                                            "protocol version \"$1\".",
 925                                        cimProtocolVersionInHeader,
 926                                        protocolVersion);
 927 j.alex           1.95              sendHttpError(
 928                                        queueId,
 929                                        HTTP_STATUS_BADREQUEST,
 930                                        "header-mismatch",
 931                                        MessageLoader::getMessage(parms),
 932                                        closeConnect);
 933 kumpf            1.39              PEG_METHOD_EXIT();
 934                                    return;
 935 kumpf            1.104         }
 936 kumpf            1.39  
 937 karl             1.108         // Accept protocol version 1.x (see Bugzilla 1556)
 938                                if (!XmlReader::isSupportedProtocolVersion(protocolVersion))
 939 kumpf            1.104         {
 940                                    // See Specification for CIM Operations over HTTP section 4.3
 941 j.alex           1.95              MessageLoaderParms parms(
 942 kumpf            1.104                 "Server.CIMOperationRequestDecoder."
 943                                            "CIMPROTOCOL_VERSION_NOT_SUPPORTED",
 944                                        "CIMProtocolVersion \"$0\" is not supported.",
 945                                             protocolVersion);
 946 j.alex           1.95              sendHttpError(
 947                                        queueId,
 948 kumpf            1.104                 HTTP_STATUS_NOTIMPLEMENTED,
 949                                        "unsupported-protocol-version",
 950 j.alex           1.95                  MessageLoader::getMessage(parms),
 951                                        closeConnect);
 952 kumpf            1.23              PEG_METHOD_EXIT();
 953                                    return;
 954 kumpf            1.104         }
 955 kumpf            1.23  
 956 kumpf            1.104         if (XmlReader::testStartTag(parser, entry, "MULTIREQ"))
 957                                {
 958                                    // We wouldn't have gotten here if CIMBatch header was specified,
 959                                    // so this must be indicative of a header mismatch
 960 j.alex           1.95              MessageLoaderParms parms(
 961 kumpf            1.104                 "Server.CIMOperationRequestDecoder."
 962                                            "MULTI_REQUEST_MISSING_CIMBATCH_HTTP_HEADER",
 963                                        "Multi-request is missing CIMBatch HTTP header");
 964 j.alex           1.95              sendHttpError(
 965                                        queueId,
 966                                        HTTP_STATUS_BADREQUEST,
 967                                        "header-mismatch",
 968                                        MessageLoader::getMessage(parms),
 969                                        closeConnect);
 970 kumpf            1.23              PEG_METHOD_EXIT();
 971                                    return;
 972 kumpf            1.104             // Future: When MULTIREQ is supported, must ensure CIMMethod and
 973                                    // CIMObject headers are absent, and CIMBatch header is present.
 974                                }
 975                        
 976                                // Expect <SIMPLEREQ ...>
 977                        
 978                                XmlReader::expectStartTag(parser, entry, "SIMPLEREQ");
 979                        
 980                                // Check for <IMETHODCALL ...>
 981                        
 982                                if (XmlReader::getIMethodCallStartTag(parser, cimMethodName))
 983                                {
 984 marek            1.139             isIMethodCall = true;
 985 kumpf            1.104             // The Specification for CIM Operations over HTTP reads:
 986                                    //     3.3.6. CIMMethod
 987                                    //
 988                                    //     This header MUST be present in any CIM Operation Request
 989                                    //     message that contains a Simple Operation Request.
 990                                    //
 991                                    //     It MUST NOT be present in any CIM Operation Response message,
 992                                    //     nor in any CIM Operation Request message that is not a
 993                                    //     Simple Operation Request.
 994                                    //
 995                                    //     The name of the CIM method within a Simple Operation Request
 996                                    //     is defined to be the value of the NAME attribute of the
 997                                    //     <METHODCALL> or <IMETHODCALL> element.
 998                                    //
 999                                    //     If a CIM Server receives a CIM Operation Request for which
1000                                    //     either:
1001                                    //
1002                                    //     - The CIMMethod header is present but has an invalid value,
1003                                    //       or;
1004                                    //     - The CIMMethod header is not present but the Operation
1005                                    //       Request Message is a Simple Operation Request, or;
1006 kumpf            1.104             //     - The CIMMethod header is present but the Operation Request
1007                                    //       Message is not a Simple Operation Request, or;
1008                                    //     - The CIMMethod header is present, the Operation Request
1009                                    //       Message is a Simple Operation Request, but the
1010                                    //       CIMIdentifier value (when unencoded) does not match the
1011                                    //       unique method name within the Simple Operation Request,
1012                                    //
1013                                    //     then it MUST fail the request and return a status of
1014                                    //     "400 Bad Request" (and MUST include a CIMError header in the
1015                                    //     response with a value of header-mismatch), subject to the
1016                                    //     considerations specified in Errors.
1017                                    if (!String::equalNoCase(cimMethodName, cimMethodInHeader))
1018                                    {
1019                                        // ATTN-RK-P3-20020304: How to decode cimMethodInHeader?
1020                                        if (cimMethodInHeader == String::EMPTY)
1021                                        {
1022                                            MessageLoaderParms parms(
1023                                                "Server.CIMOperationRequestDecoder."
1024                                                    "MISSING_CIMMETHOD_HTTP_HEADER",
1025                                                "Missing CIMMethod HTTP header.");
1026                                            sendHttpError(
1027 kumpf            1.104                         queueId,
1028                                                HTTP_STATUS_BADREQUEST,
1029                                                "header-mismatch",
1030                                                MessageLoader::getMessage(parms),
1031                                                closeConnect);
1032                                        }
1033                                        else
1034                                        {
1035                                            MessageLoaderParms parms(
1036                                                "Server.CIMOperationRequestDecoder."
1037                                                     "CIMMETHOD_VALUE_DOES_NOT_MATCH_REQUEST_METHOD",
1038                                                "CIMMethod value \"$0\" does not match CIM request "
1039                                                     "method \"$1\".",
1040                                                cimMethodInHeader,
1041                                                cimMethodName);
1042                                            sendHttpError(
1043                                                queueId,
1044                                                HTTP_STATUS_BADREQUEST,
1045                                                "header-mismatch",
1046                                                MessageLoader::getMessage(parms),
1047                                                closeConnect);
1048 kumpf            1.104                 }
1049                                        PEG_METHOD_EXIT();
1050                                        return;
1051                                    }
1052 kumpf            1.23  
1053 kumpf            1.104             // Expect <LOCALNAMESPACEPATH ...>
1054                        
1055                                    String nameSpace;
1056                        
1057                                    if (!XmlReader::getLocalNameSpacePathElement(parser, nameSpace))
1058                                    {
1059                                        MessageLoaderParms mlParms(
1060                                            "Server.CIMOperationRequestDecoder."
1061                                                "EXPECTED_LOCALNAMESPACEPATH_ELEMENT",
1062                                            "expected LOCALNAMESPACEPATH element");
1063                                        throw XmlValidationError(parser.getLine(), mlParms);
1064                                    }
1065                        
1066                                    // The Specification for CIM Operations over HTTP reads:
1067                                    //     3.3.7. CIMObject
1068                                    //
1069                                    //     This header MUST be present in any CIM Operation Request
1070                                    //     message that contains a Simple Operation Request.
1071                                    //
1072                                    //     It MUST NOT be present in any CIM Operation Response message,
1073                                    //     nor in any CIM Operation Request message that is not a
1074 kumpf            1.104             //     Simple Operation Request.
1075                                    //
1076                                    //     The header identifies the CIM object (which MUST be a Class
1077                                    //     or Instance for an extrinsic method, or a Namespace for an
1078                                    //     intrinsic method) on which the method is to be invoked, using
1079                                    //     a CIM object path encoded in an HTTP-safe representation.
1080                                    //
1081                                    //     If a CIM Server receives a CIM Operation Request for which
1082                                    //     either:
1083                                    //
1084                                    //     - The CIMObject header is present but has an invalid value,
1085                                    //       or;
1086                                    //     - The CIMObject header is not present but the Operation
1087                                    //       Request Message is a Simple Operation Request, or;
1088                                    //     - The CIMObject header is present but the Operation Request
1089                                    //       Message is not a Simple Operation Request, or;
1090                                    //     - The CIMObject header is present, the Operation Request
1091                                    //       Message is a Simple Operation Request, but the ObjectPath
1092                                    //       value does not match (where match is defined in the section
1093                                    //       section on Encoding CIM Object Paths) the Operation Request
1094                                    //       Message,
1095 kumpf            1.104             //
1096                                    //     then it MUST fail the request and return a status of
1097                                    //     "400 Bad Request" (and MUST include a CIMError header in the
1098                                    //     response with a value of header-mismatch), subject to the
1099                                    //     considerations specified in Errors.
1100                                    if (!String::equalNoCase(nameSpace, cimObjectInHeader))
1101                                    {
1102                                        if (cimObjectInHeader == String::EMPTY)
1103                                        {
1104                                            MessageLoaderParms parms(
1105                                                "Server.CIMOperationRequestDecoder."
1106                                                    "MISSING_CIMOBJECT_HTTP_HEADER",
1107                                                "Missing CIMObject HTTP header.");
1108                                            sendHttpError(
1109                                                queueId,
1110                                                HTTP_STATUS_BADREQUEST,
1111                                                "header-mismatch",
1112                                                MessageLoader::getMessage(parms),
1113                                                closeConnect);
1114                                        }
1115                                        else
1116 kumpf            1.104                 {
1117                                            MessageLoaderParms parms(
1118                                                "Server.CIMOperationRequestDecoder."
1119 kumpf            1.113                             "CIMOBJECT_VALUE_DOES_NOT_MATCH_REQUEST_OBJECT",
1120 kumpf            1.104                         "CIMObject value \"$0\" does not match CIM request "
1121                                                    "object \"$1\".",
1122                                                cimObjectInHeader,
1123                                                nameSpace);
1124                                            sendHttpError(
1125                                                queueId,
1126                                                HTTP_STATUS_BADREQUEST,
1127                                                "header-mismatch",
1128                                                MessageLoader::getMessage(parms),
1129                                                closeConnect);
1130                                        }
1131                                        PEG_METHOD_EXIT();
1132                                        return;
1133                                    }
1134                        
1135                                    // This try block only catches CIMExceptions, because they must be
1136                                    // responded to with a proper IMETHODRESPONSE.  Other exceptions are
1137                                    // caught in the outer try block.
1138                                    try
1139                                    {
1140                                        // Delegate to appropriate method to handle:
1141 kumpf            1.104 
1142                                        if (System::strcasecmp(cimMethodName, "GetClass") == 0)
1143                                            request.reset(decodeGetClassRequest(
1144                                                queueId, parser, messageId, nameSpace));
1145                                        else if (System::strcasecmp(cimMethodName, "GetInstance") == 0)
1146                                            request.reset(decodeGetInstanceRequest(
1147                                                queueId, parser, messageId, nameSpace));
1148                                        else if (System::strcasecmp(
1149                                                     cimMethodName, "EnumerateClassNames") == 0)
1150                                            request.reset(decodeEnumerateClassNamesRequest(
1151                                                queueId, parser, messageId, nameSpace));
1152                                        else if (System::strcasecmp(cimMethodName, "References") == 0)
1153                                            request.reset(decodeReferencesRequest(
1154                                                queueId, parser, messageId, nameSpace));
1155                                        else if (System::strcasecmp(
1156                                                     cimMethodName, "ReferenceNames") == 0)
1157                                            request.reset(decodeReferenceNamesRequest(
1158                                                queueId, parser, messageId, nameSpace));
1159                                        else if (System::strcasecmp(
1160                                                     cimMethodName, "AssociatorNames") == 0)
1161                                            request.reset(decodeAssociatorNamesRequest(
1162 kumpf            1.104                         queueId, parser, messageId, nameSpace));
1163                                        else if (System::strcasecmp(cimMethodName, "Associators") == 0)
1164                                            request.reset(decodeAssociatorsRequest(
1165                                                queueId, parser, messageId, nameSpace));
1166                                        else if (System::strcasecmp(
1167                                                     cimMethodName, "CreateInstance") == 0)
1168                                            request.reset(decodeCreateInstanceRequest(
1169                                                queueId, parser, messageId, nameSpace));
1170                                        else if (System::strcasecmp(
1171                                                     cimMethodName, "EnumerateInstanceNames")==0)
1172                                            request.reset(decodeEnumerateInstanceNamesRequest(
1173                                                queueId, parser, messageId, nameSpace));
1174                                        else if (System::strcasecmp(
1175                                                     cimMethodName, "DeleteQualifier") == 0)
1176                                            request.reset(decodeDeleteQualifierRequest(
1177                                                queueId, parser, messageId, nameSpace));
1178                                        else if (System::strcasecmp(cimMethodName, "GetQualifier") == 0)
1179                                            request.reset(decodeGetQualifierRequest(
1180                                                queueId, parser, messageId, nameSpace));
1181                                        else if (System::strcasecmp(cimMethodName, "SetQualifier") == 0)
1182                                            request.reset(decodeSetQualifierRequest(
1183 kumpf            1.104                         queueId, parser, messageId, nameSpace));
1184                                        else if (System::strcasecmp(
1185                                                     cimMethodName, "EnumerateQualifiers") == 0)
1186                                            request.reset(decodeEnumerateQualifiersRequest(
1187                                                queueId, parser, messageId, nameSpace));
1188                                        else if (System::strcasecmp(
1189                                                     cimMethodName, "EnumerateClasses") == 0)
1190                                            request.reset(decodeEnumerateClassesRequest(
1191                                                queueId, parser, messageId, nameSpace));
1192                                        else if (System::strcasecmp(
1193                                                     cimMethodName, "EnumerateInstances") == 0)
1194                                            request.reset(decodeEnumerateInstancesRequest(
1195                                                queueId, parser, messageId, nameSpace));
1196                                        else if (System::strcasecmp(cimMethodName, "CreateClass") == 0)
1197                                            request.reset(decodeCreateClassRequest(
1198                                                queueId, parser, messageId, nameSpace));
1199                                        else if (System::strcasecmp(cimMethodName, "ModifyClass") == 0)
1200                                            request.reset(decodeModifyClassRequest(
1201                                                queueId, parser, messageId, nameSpace));
1202                                        else if (System::strcasecmp(
1203                                                     cimMethodName, "ModifyInstance") == 0)
1204 kumpf            1.104                     request.reset(decodeModifyInstanceRequest(
1205                                                queueId, parser, messageId, nameSpace));
1206                                        else if (System::strcasecmp(cimMethodName, "DeleteClass") == 0)
1207                                            request.reset(decodeDeleteClassRequest(
1208                                                queueId, parser, messageId, nameSpace));
1209                                        else if (System::strcasecmp(
1210                                                     cimMethodName, "DeleteInstance") == 0)
1211                                            request.reset(decodeDeleteInstanceRequest(
1212                                                queueId, parser, messageId, nameSpace));
1213                                        else if (System::strcasecmp(cimMethodName, "GetProperty") == 0)
1214                                            request.reset(decodeGetPropertyRequest(
1215                                                queueId, parser, messageId, nameSpace));
1216                                        else if (System::strcasecmp(cimMethodName, "SetProperty") == 0)
1217                                            request.reset(decodeSetPropertyRequest(
1218                                                queueId, parser, messageId, nameSpace));
1219                                        else if (System::strcasecmp(cimMethodName, "ExecQuery") == 0)
1220                                            request.reset(decodeExecQueryRequest(
1221                                                queueId, parser, messageId, nameSpace));
1222                                        else
1223                                        {
1224                                            throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
1225 kumpf            1.104                         MessageLoaderParms(
1226                                                    "Server.CIMOperationRequestDecoder."
1227                                                        "UNRECOGNIZED_INTRINSIC_METHOD",
1228                                                    "Unrecognized intrinsic method: $0",
1229                                                    cimMethodName));
1230                                        }
1231                                    }
1232                                    catch (CIMException& e)
1233                                    {
1234                                        sendIMethodError(
1235                                            queueId,
1236                                            httpMethod,
1237                                            messageId,
1238                                            cimMethodName,
1239                                            e,
1240                                            closeConnect);
1241                        
1242                                        PEG_METHOD_EXIT();
1243                                        return;
1244                                    }
1245                                    catch (XmlException&)
1246 kumpf            1.104             {
1247                                        // XmlExceptions are handled below
1248                                        throw;
1249                                    }
1250                                    catch (Exception& e)
1251                                    {
1252                                        // Caught an unexpected exception from decoding.  Since we must
1253                                        // have had a problem reconstructing a CIM object, we'll treat
1254                                        // it as an invalid parameter
1255                                        sendIMethodError(
1256                                            queueId,
1257                                            httpMethod,
1258                                            messageId,
1259                                            cimMethodName,
1260                                            PEGASUS_CIM_EXCEPTION(
1261                                                CIM_ERR_INVALID_PARAMETER, e.getMessage()),
1262                                            closeConnect);
1263                        
1264                                        PEG_METHOD_EXIT();
1265                                        return;
1266                                    }
1267 kumpf            1.104 
1268                                    // Expect </IMETHODCALL>
1269                        
1270                                    XmlReader::expectEndTag(parser, "IMETHODCALL");
1271                                }
1272                                // Expect <METHODCALL ...>
1273                                else if (XmlReader::getMethodCallStartTag(parser, cimMethodName))
1274                                {
1275                                    CIMObjectPath reference;
1276 marek            1.139             isIMethodCall = false;
1277 kumpf            1.104 
1278                                    // The Specification for CIM Operations over HTTP reads:
1279                                    //     3.3.6. CIMMethod
1280                                    //
1281                                    //     This header MUST be present in any CIM Operation Request
1282                                    //     message that contains a Simple Operation Request.
1283                                    //
1284                                    //     It MUST NOT be present in any CIM Operation Response message,
1285                                    //     nor in any CIM Operation Request message that is not a
1286                                    //     Simple Operation Request.
1287                                    //
1288                                    //     The name of the CIM method within a Simple Operation Request
1289                                    //     is defined to be the value of the NAME attribute of the
1290                                    //     <METHODCALL> or <IMETHODCALL> element.
1291                                    //
1292                                    //     If a CIM Server receives a CIM Operation Request for which
1293                                    //     either:
1294                                    //
1295                                    //     - The CIMMethod header is present but has an invalid value,
1296                                    //       or;
1297                                    //     - The CIMMethod header is not present but the Operation
1298 kumpf            1.104             //       Request Message is a Simple Operation Request, or;
1299                                    //     - The CIMMethod header is present but the Operation Request
1300                                    //       Message is not a Simple Operation Request, or;
1301                                    //     - The CIMMethod header is present, the Operation Request
1302                                    //       Message is a Simple Operation Request, but the
1303                                    //       CIMIdentifier value (when unencoded) does not match the
1304                                    //       unique method name within the Simple Operation Request,
1305                                    //
1306                                    //     then it MUST fail the request and return a status of
1307                                    //     "400 Bad Request" (and MUST include a CIMError header in the
1308                                    //     response with a value of header-mismatch), subject to the
1309                                    //     considerations specified in Errors.
1310                        
1311                                    // Extrinic methods can have UTF-8!
1312                                    String cimMethodNameUTF16(cimMethodName);
1313                                    if (cimMethodNameUTF16 != cimMethodInHeader)
1314                                    {
1315                                        // ATTN-RK-P3-20020304: How to decode cimMethodInHeader?
1316                                        if (cimMethodInHeader == String::EMPTY)
1317                                        {
1318                                            MessageLoaderParms parms(
1319 kumpf            1.104                         "Server.CIMOperationRequestDecoder."
1320                                                    "MISSING_CIMMETHOD_HTTP_HEADER",
1321                                                "Missing CIMMethod HTTP header.");
1322                                            sendHttpError(
1323                                                queueId,
1324                                                HTTP_STATUS_BADREQUEST,
1325                                                "header-mismatch",
1326                                                MessageLoader::getMessage(parms),
1327                                                closeConnect);
1328                                        }
1329                                        else
1330                                        {
1331                                            MessageLoaderParms parms(
1332                                                "Server.CIMOperationRequestDecoder."
1333                                                    "CIMMETHOD_VALUE_DOES_NOT_MATCH_REQUEST_METHOD",
1334                                                "CIMMethod value \"$0\" does not match CIM request "
1335                                                    "method \"$1\".",
1336                                                (const char*)cimMethodInHeader.getCString(),
1337                                                cimMethodName);
1338                                            sendHttpError(
1339                                                queueId,
1340 kumpf            1.104                         HTTP_STATUS_BADREQUEST,
1341                                                "header-mismatch",
1342                                                MessageLoader::getMessage(parms),
1343                                                closeConnect);
1344                                        }
1345                                        PEG_METHOD_EXIT();
1346                                        return;
1347                                    }
1348                        
1349                                    //
1350                                    // Check for <LOCALINSTANCEPATHELEMENT> or <LOCALCLASSPATHELEMENT>
1351                                    //
1352                                    if (!(XmlReader::getLocalInstancePathElement(parser, reference) ||
1353                                          XmlReader::getLocalClassPathElement(parser, reference)))
1354                                    {
1355                                        MessageLoaderParms parms(
1356                                            "Common.XmlConstants.MISSING_ELEMENT_LOCALPATH",
1357                                            MISSING_ELEMENT_LOCALPATH);
1358                                        // this throw is not updated with MLP because
1359                                        // MISSING_ELEMENT_LOCALPATH is a hardcoded variable,
1360                                        // not a message
1361 kumpf            1.104                 throw XmlValidationError(parser.getLine(), parms);
1362                                    }
1363                        
1364                                    // The Specification for CIM Operations over HTTP reads:
1365                                    //     3.3.7. CIMObject
1366                                    //
1367                                    //     This header MUST be present in any CIM Operation Request
1368                                    //     message that contains a Simple Operation Request.
1369                                    //
1370                                    //     It MUST NOT be present in any CIM Operation Response message,
1371                                    //     nor in any CIM Operation Request message that is not a
1372                                    //     Simple Operation Request.
1373                                    //
1374                                    //     The header identifies the CIM object (which MUST be a Class
1375                                    //     or Instance for an extrinsic method, or a Namespace for an
1376                                    //     intrinsic method) on which the method is to be invoked, using
1377                                    //     a CIM object path encoded in an HTTP-safe representation.
1378                                    //
1379                                    //     If a CIM Server receives a CIM Operation Request for which
1380                                    //     either:
1381                                    //
1382 kumpf            1.104             //     - The CIMObject header is present but has an invalid value,
1383                                    //       or;
1384                                    //     - The CIMObject header is not present but the Operation
1385                                    //       Request Message is a Simple Operation Request, or;
1386                                    //     - The CIMObject header is present but the Operation Request
1387                                    //       Message is not a Simple Operation Request, or;
1388                                    //     - The CIMObject header is present, the Operation Request
1389                                    //       Message is a Simple Operation Request, but the ObjectPath
1390                                    //       value does not match (where match is defined in the section
1391                                    //       section on Encoding CIM Object Paths) the Operation Request
1392                                    //       Message,
1393                                    //
1394                                    //     then it MUST fail the request and return a status of
1395                                    //     "400 Bad Request" (and MUST include a CIMError header in the
1396                                    //     response with a value of header-mismatch), subject to the
1397                                    //     considerations specified in Errors.
1398                                    if (cimObjectInHeader == String::EMPTY)
1399                                    {
1400                                        MessageLoaderParms parms(
1401                                            "Server.CIMOperationRequestDecoder."
1402                                                "MISSING_CIMOBJECT_HTTP_HEADER",
1403 kumpf            1.104                     "Missing CIMObject HTTP header.");
1404                                        sendHttpError(
1405                                            queueId,
1406                                            HTTP_STATUS_BADREQUEST,
1407                                            "header-mismatch",
1408                                            MessageLoader::getMessage(parms),
1409                                            closeConnect);
1410                                        PEG_METHOD_EXIT();
1411                                        return;
1412                                    }
1413                        
1414                                    CIMObjectPath headerObjectReference;
1415                                    try
1416                                    {
1417                                        headerObjectReference.set(cimObjectInHeader);
1418                                    }
1419                                    catch (Exception&)
1420                                    {
1421                                        MessageLoaderParms parms(
1422                                            "Server.CIMOperationRequestDecoder."
1423                                                "COULD_NOT_PARSE_CIMOBJECT_VALUE",
1424 kumpf            1.104                     "Could not parse CIMObject value \"$0\".",
1425                                            cimObjectInHeader);
1426                                        sendHttpError(
1427                                            queueId,
1428                                            HTTP_STATUS_BADREQUEST,
1429                                            "header-mismatch",
1430                                            MessageLoader::getMessage(parms),
1431                                            closeConnect);
1432                                        PEG_METHOD_EXIT();
1433                                        return;
1434                                    }
1435                        
1436                                    if (!reference.identical(headerObjectReference))
1437                                    {
1438                                        MessageLoaderParms parms(
1439                                            "Server.CIMOperationRequestDecoder."
1440 kumpf            1.113                         "CIMOBJECT_VALUE_DOES_NOT_MATCH_REQUEST_OBJECT",
1441 kumpf            1.104                     "CIMObject value \"$0\" does not match CIM request "
1442                                                "object \"$1\".",
1443                                            cimObjectInHeader,
1444 kumpf            1.113                     reference.toString());
1445 kumpf            1.104                 sendHttpError(
1446                                            queueId,
1447                                            HTTP_STATUS_BADREQUEST,
1448                                            "header-mismatch",
1449                                            MessageLoader::getMessage(parms),
1450                                            closeConnect);
1451                                        PEG_METHOD_EXIT();
1452                                        return;
1453                                    }
1454                        
1455                                    // This try block only catches CIMExceptions, because they must be
1456                                    // responded to with a proper METHODRESPONSE.  Other exceptions are
1457                                    // caught in the outer try block.
1458                                    try
1459                                    {
1460                                        // Delegate to appropriate method to handle:
1461                        
1462                                        request.reset(decodeInvokeMethodRequest(
1463                                           queueId,
1464                                           parser,
1465                                           messageId,
1466 kumpf            1.104                    reference,
1467                                           cimMethodNameUTF16)); // contains UTF-16 converted from UTF-8
1468                                    }
1469                                    catch (CIMException& e)
1470                                    {
1471                                        sendMethodError(
1472                                            queueId,
1473                                            httpMethod,
1474                                            messageId,
1475                                            cimMethodNameUTF16, // contains UTF-16 converted from UTF-8
1476                                            e,
1477                                            closeConnect);
1478                        
1479                                        PEG_METHOD_EXIT();
1480                                        return;
1481                                    }
1482                                    catch (XmlException&)
1483                                    {
1484                                        // XmlExceptions are handled below
1485                                        throw;
1486                                    }
1487 kumpf            1.104             catch (Exception& e)
1488                                    {
1489                                        // Caught an unexpected exception from decoding.  Since we must
1490                                        // have had a problem reconstructing a CIM object, we'll treata
1491                                        // it as an invalid parameter
1492                                        sendMethodError(
1493                                            queueId,
1494                                            httpMethod,
1495                                            messageId,
1496                                            cimMethodNameUTF16, // contains UTF-16 converted from UTF-8
1497                                            PEGASUS_CIM_EXCEPTION(
1498                                                CIM_ERR_INVALID_PARAMETER, e.getMessage()),
1499                                            closeConnect);
1500                        
1501                                        PEG_METHOD_EXIT();
1502                                        return;
1503                                    }
1504 kumpf            1.73  
1505 kumpf            1.104             // Expect </METHODCALL>
1506 mday             1.16  
1507 kumpf            1.104             XmlReader::expectEndTag(parser, "METHODCALL");
1508                                }
1509                                else
1510                                {
1511                                    MessageLoaderParms mlParms(
1512                                       "Server.CIMOperationRequestDecoder.EXPECTED_IMETHODCALL_ELEMENT",
1513                                       "expected IMETHODCALL or METHODCALL element");
1514                                    throw XmlValidationError(parser.getLine(),mlParms);
1515                                }
1516                        
1517                                // Expect </SIMPLEREQ>
1518                        
1519                                XmlReader::expectEndTag(parser, "SIMPLEREQ");
1520                        
1521                                // Expect </MESSAGE>
1522                        
1523                                XmlReader::expectEndTag(parser, "MESSAGE");
1524                        
1525                                // Expect </CIM>
1526                        
1527                                XmlReader::expectEndTag(parser, "CIM");
1528 kumpf            1.104     }
1529                            catch (XmlValidationError& e)
1530                            {
1531 thilo.boehm      1.119         PEG_TRACE((TRC_XML,Tracer::LEVEL1,
1532 kumpf            1.104             "CIMOperationRequestDecoder::handleMethodCall - "
1533 marek            1.116                 "XmlValidationError exception has occurred. Message: %s",
1534                                    (const char*) e.getMessage().getCString()));
1535 kumpf            1.24  
1536 kumpf            1.104         sendHttpError(
1537                                    queueId,
1538                                    HTTP_STATUS_BADREQUEST,
1539                                    "request-not-valid",
1540                                    e.getMessage(),
1541                                    closeConnect);
1542                                PEG_METHOD_EXIT();
1543                                return;
1544                            }
1545                            catch (XmlSemanticError& e)
1546                            {
1547 thilo.boehm      1.119         PEG_TRACE((TRC_XML,Tracer::LEVEL1,
1548 kumpf            1.104             "CIMOperationRequestDecoder::handleMethodCall - "
1549 marek            1.116                 "XmlSemanticError exception has occurred. Message: %s",
1550                                    (const char*) e.getMessage().getCString()));
1551 mday             1.16  
1552 kumpf            1.104         // ATTN-RK-P2-20020404: Is this the correct response for these errors?
1553                                sendHttpError(
1554                                    queueId,
1555                                    HTTP_STATUS_BADREQUEST,
1556                                    "request-not-valid",
1557                                    e.getMessage(),
1558                                    closeConnect);
1559                                PEG_METHOD_EXIT();
1560                                return;
1561                            }
1562                            catch (XmlException& e)
1563                            {
1564 thilo.boehm      1.119         PEG_TRACE((TRC_XML,Tracer::LEVEL1,
1565 kumpf            1.104             "CIMOperationRequestDecoder::handleMethodCall - "
1566 marek            1.116                 "XmlException has occurred. Message: %s",
1567                                    (const char*) e.getMessage().getCString()));
1568 kumpf            1.104 
1569                                sendHttpError(
1570                                    queueId,
1571                                    HTTP_STATUS_BADREQUEST,
1572                                    "request-not-well-formed",
1573                                    e.getMessage(),
1574                                    closeConnect);
1575                                PEG_METHOD_EXIT();
1576                                return;
1577                            }
1578 marek            1.133     catch (TooManyElementsException& e)
1579                            {
1580                                PEG_TRACE((TRC_XML,Tracer::LEVEL1,
1581                                    "CIMOperationRequestDecoder::handleMethodCall - "
1582                                        "TooManyElementsException has occurred. Message: %s",
1583                                    (const char*) e.getMessage().getCString()));
1584                        
1585                                sendHttpError(
1586                                    queueId,
1587                                    HTTP_STATUS_BADREQUEST,
1588                                    "request-with-too-many-elements",
1589                                    e.getMessage(),
1590                                    closeConnect);
1591                                PEG_METHOD_EXIT();
1592                                return;
1593                            }
1594 kumpf            1.104     catch (Exception& e)
1595                            {
1596                                // Don't know why I got this exception.  Seems like a bad thing.
1597                                // Any exceptions we're expecting should be caught separately and
1598                                // dealt with appropriately.  This is a last resort.
1599                                sendHttpError(
1600                                    queueId,
1601                                    HTTP_STATUS_INTERNALSERVERERROR,
1602                                    String::EMPTY,
1603                                    e.getMessage(),
1604                                    closeConnect);
1605                                PEG_METHOD_EXIT();
1606                                return;
1607                            }
1608                            catch (...)
1609                            {
1610                                // Don't know why I got whatever this is.  Seems like a bad thing.
1611                                // Any exceptions we're expecting should be caught separately and
1612                                // dealt with appropriately.  This is a last resort.
1613                                sendHttpError(
1614                                    queueId,
1615 kumpf            1.104             HTTP_STATUS_INTERNALSERVERERROR,
1616                                    String::EMPTY,
1617                                    String::EMPTY,
1618                                    closeConnect);
1619                                PEG_METHOD_EXIT();
1620                                return;
1621                            }
1622                        
1623                            STAT_BYTESREAD
1624                        
1625                            request->authType = authType;
1626                            request->userName = userName;
1627                            request->ipAddress = ipAddress;
1628                            request->setHttpMethod (httpMethod);
1629 mike             1.120     request->binaryResponse = binaryResponse;
1630 sage             1.41  
1631 chuck            1.58  //l10n start
1632                        // l10n TODO - might want to move A-L and C-L to Message
1633                        // to make this more maintainable
1634 kumpf            1.104     // Add the language headers to the request
1635                            CIMMessage* cimmsg = dynamic_cast<CIMMessage*>(request.get());
1636                            if (cimmsg != NULL)
1637                            {
1638                                cimmsg->operationContext.insert(IdentityContainer(userName));
1639 marek            1.138         cimmsg->operationContext.insert(UserRoleContainer(userRole));
1640 kumpf            1.104         cimmsg->operationContext.set(
1641                                    AcceptLanguageListContainer(httpAcceptLanguages));
1642                                cimmsg->operationContext.set(
1643                                    ContentLanguageListContainer(httpContentLanguages));
1644                            }
1645                            else
1646                            {
1647                                ;    // l10n TODO - error back to client here
1648                            }
1649 chip             1.92  // l10n end
1650 chuck            1.58  
1651 marek            1.139 #ifdef PEGASUS_PAM_SESSION_SECURITY
1652                        
1653                            // Whatever happens on the authentication, we need to check for
1654                            // a change of an expired password
1655                            // Since the definition for password updates is not completely
1656                            // defined in DMTF yet, keep this feature PAM_SESSION only
1657                            // This also only works with CIM-XML right now.
1658                            if (isExpiredPassword)
1659                            {
1660                                // only try password update if req. Pragma is set
1661                                if (updateExpiredPassword)
1662                                {
1663                                    // update expired password
1664                                    // fct. _updateExpiredPassword returns false 
1665                                    //        if the request was NOT for PG_Account etc.
1666                                    _updateExpiredPassword(
1667                                        queueId,
1668                                        httpMethod,
1669                                        messageId,
1670                                        closeConnect,
1671                                        httpContentLanguages,
1672 marek            1.139                 cimmsg,
1673                                        userName,
1674                                        userPass);
1675                                }
1676                                else
1677                                {
1678                                    sendUserAccountExpired(
1679                                        queueId,
1680                                        httpMethod,
1681                                        messageId,
1682                                        cimMethodInHeader,
1683                                        closeConnect,
1684                                        isIMethodCall);
1685                                }
1686                                PEG_METHOD_EXIT();
1687                                return;
1688                            }
1689                        #endif
1690                        
1691 kumpf            1.104     request->setCloseConnect(closeConnect);
1692                            _outputQueue->enqueue(request.release());
1693 chip             1.92  
1694 kumpf            1.104     PEG_METHOD_EXIT();
1695 mike             1.2   }
1696 karl             1.137 /**************************************************************************
1697                        **
1698                        **  Decode CIM Operation Type Common IParameter types.
1699                        **  Each class defines processing for a particular IPARAM type
1700                        **  (ex. boolean)or parameter name (i.e. propertyListIParam)
1701                        **  Each struct defines:
1702                        **      got - Boolean defines whether this parameter has been found
1703                        **      value - The value container for this type
1704                        **      iParamFound(...) - function sets the duplicate flag and the got flag
1705                        **      get - Function to get the defined parameter from the
1706                        **            parser
1707                        **      NOTE: at least one has multiple get.. functions.
1708                        ** NOTE: Some of these are defined for a particular attribute (ex.
1709                        **      propertyListIparam) so the attribute name is integrated into the
1710                        **      methods and others for a whole class of attributes (Boolean,
1711                        **      String,ClassName etc.) so the attribute name is defined as part
1712                        **      of the constructor.
1713                        ***************************************************************************/
1714                        // Common xml attribute accessor for all boolean attributes.   The
1715                        // attribute name is defined in the constructor.
1716                        // The usage pattern is:
1717 karl             1.137 //    Boolean duplicate;     // Flag to indicate multiple calls
1718                        //
1719                        //    booleanIParam xyz("xyz"); default is false for attribute xyz
1720                        //
1721                        //    if(xyz.get(parser, name, emptyTag)   // parses to test if name == xyz
1722                        //        iParamFound(duplicate);          // set flag to indicate exists etc.
1723                        class booleanIParam
1724                        {
1725                        public:
1726                            Boolean got;
1727                            Boolean value;
1728                        
1729                            // constructor with default value = false
1730                            booleanIParam(const char* name): got(false),value(false),iParamName(name){}
1731                        
1732                            // constructor with initial value specifically set from the input
1733                            booleanIParam(const char* name, Boolean _value):
1734                                got(false),value(_value),iParamName(name){}
1735                        
1736                            ~booleanIParam(){}
1737                        
1738 karl             1.137     void iParamFound(Boolean& duplicate)
1739                            {
1740                                duplicate = got;
1741                                got = true;
1742                            }
1743                        
1744                            // get the value of the parameter if the parameter if it exists.
1745                            // Note that the attribute name is defined in the constructor
1746                            // Value is required.
1747                            // @param parser
1748                            // @param testName attribute name from parse.
1749                            // @emptyTag returns true if emptyTag returned true from parser
1750                            Boolean get(XmlParser& parser, const char * testName,  Boolean& emptyTag)
1751                            {
1752                                if (System::strcasecmp(iParamName.getCString(), testName) == 0)
1753                                {
1754                                    XmlReader::rejectNullIParamValue(parser, emptyTag,
1755                                                                     iParamName.getCString());
1756                                    XmlReader::getBooleanValueElement(parser, value, true);
1757                                    return true;
1758                                }
1759 karl             1.137         return false;
1760                            }
1761                            private:
1762                            String iParamName;
1763                            // hide unused default constructor and assign, copy constructors
1764                            booleanIParam();
1765                            booleanIParam(const booleanIParam&);
1766                            booleanIParam& operator = (const booleanIParam&);
1767                        };
1768                        
1769                        // decode Iparam to CIMName representing class names.  This struct
1770                        // has two get functions:
1771                        //     get - parse where the parameter value is required
1772                        //     getOptional - parse where the parameter value is optional
1773                        
1774                        class classNameIParam
1775                        {
1776                        public:
1777                            Boolean got;
1778                            CIMName value;
1779                        
1780 karl             1.137     // Set the flag to inidcate that this IParam has been gotten and also
1781                            // set the flag defined by the duplicate parameter
1782                            // @param duplicate Boolean that is set to previous value of the got
1783                            // variable indicating whether this is second call to this IParam
1784                            void iParamFound(Boolean& duplicate)
1785                            {
1786                                duplicate = got;
1787                                got = true;
1788                            }
1789                        
1790                            // construct an IParam definition with name.
1791                            // @param name const char* defining name of IParam to match
1792                            // @return true if IParam found with _attrName
1793                            classNameIParam(const char* name): got(false), iParamName(name){}
1794                        
1795                            ~classNameIParam(){}
1796                        
1797                            // Get Required value element.Test for name parameter as IParam with
1798                            // name and if found, if value not NULL, parse the className and
1799                            // set into value
1800                            Boolean get(XmlParser& parser, const char* name, Boolean& emptyTag)
1801 karl             1.137     {
1802                                if (System::strcasecmp(name,iParamName.getCString()) == 0)
1803                                {
1804                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
1805                                    XmlReader::getClassNameElement(parser, value, true);
1806                                    return true;
1807                                }
1808                                return false;
1809                            }
1810                            // Get Iparam with optional value.
1811                            Boolean getOptional(XmlParser& parser, const char* name,
1812                                                Boolean& emptyTag)
1813                            {
1814                                if (System::strcasecmp(name, iParamName.getCString()) == 0)
1815                                {
1816                                    //  value may be NULL
1817                                    if (!emptyTag)
1818                                    {
1819                                        XmlReader::getClassNameElement(parser, value, false);
1820                                    }
1821                                    return true;
1822 karl             1.137         }
1823                                return false;
1824                            }
1825                        private:
1826                            String iParamName;
1827                            // hide unused default constructor and assign, copy constructors
1828                            classNameIParam();
1829                            classNameIParam(const classNameIParam&);
1830                            classNameIParam& operator = (const classNameIParam&);
1831                        };
1832                        
1833                        // test for "InstanceName" iParam and if found, return CIMObjectPath
1834                        // in value
1835                        class instanceNameIParam
1836                        {
1837                        public:
1838                            Boolean got;
1839                            CIMObjectPath value;
1840                        
1841                            void iParamFound(Boolean& duplicate)
1842                            {
1843 karl             1.137         duplicate = got;
1844                                got = true;
1845                            }
1846                            instanceNameIParam(): got(false){}
1847                        
1848                            ~instanceNameIParam(){}
1849                        
1850                            Boolean get(XmlParser& parser, const char * name, Boolean& emptyTag)
1851                            {
1852                                if (System::strcasecmp(name, "InstanceName") == 0)
1853                                {
1854                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
1855                                    XmlReader::getInstanceNameElement(parser, value);
1856                                    return true;
1857                                }
1858                                return false;
1859                            }
1860                        private:
1861                            // hide unused assign, copy constructors
1862                            instanceNameIParam(const instanceNameIParam&);
1863                            instanceNameIParam& operator = (const instanceNameIParam&);
1864 karl             1.137 };
1865                        
1866                        // test for "ObjectName" attribute and if found, return CIMObjectPath
1867                        // This struct has an extra attribute, the flag isClassNameElement which
1868                        // returns true if the objectName was a classPath and not an instance
1869                        // path.
1870                        // If Xmlreader returns true, this is class only element, no
1871                        //  key bindings. That state must be set into the request
1872                        //  message (ex. objectName.isClassElement)
1873                        class objectNameIParam
1874                        {
1875                        public:
1876                            Boolean got;
1877                            CIMObjectPath value;
1878                            Boolean isClassNameElement;
1879                        
1880                            void iParamFound(Boolean& duplicate)
1881                            {
1882                                duplicate = got;
1883                                got = true;
1884                            }
1885 karl             1.137 
1886                            objectNameIParam(): got(false), isClassNameElement(false){}
1887                        
1888                            ~objectNameIParam(){}
1889                        
1890                            Boolean get(XmlParser& parser, const char * name, Boolean& emptyTag)
1891                            {
1892                                if (System::strcasecmp(name, "ObjectName") == 0)
1893                                {
1894                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
1895                                    isClassNameElement =
1896                                        XmlReader::getObjectNameElement(parser, value);
1897                                    return true;
1898                                }
1899                                return false;
1900                            }
1901                        private:
1902                            // hide unused assign, copy constructors
1903                            objectNameIParam(const objectNameIParam&);
1904                            objectNameIParam& operator = (const objectNameIParam&);
1905                        };
1906 karl             1.137 
1907                        // test for "PropertyList" attribute and, if found, return property list
1908                        // in the value element.
1909                        class propertyListIParam
1910                        {
1911                        public:
1912                            Boolean got;
1913                            CIMPropertyList value;
1914                        
1915                            void iParamFound(Boolean& duplicate)
1916                            {
1917                                duplicate = got;
1918                                got = true;
1919                            }
1920                        
1921                            // construct a propertyListIParam object
1922                            propertyListIParam(): got(false){}
1923                        
1924                            ~propertyListIParam(){}
1925                        
1926                            Boolean get(XmlParser& parser, const char* name, Boolean& emptyTag)
1927 karl             1.137     {
1928                                if (System::strcasecmp(name, "PropertyList") == 0)
1929                                {
1930                                    if (!emptyTag)
1931                                    {
1932                                        CIMValue pl;
1933                                        if (XmlReader::getValueArrayElement(parser, CIMTYPE_STRING, pl))
1934                                        {
1935                                            Array<String> propertyListArray;
1936                                            pl.get(propertyListArray);
1937                                            // NOTE: Cannot use the propertyList.set(...) method
1938                                            // here because set does not create propertyList tags
1939                                            value.append(propertyListArray);
1940                                        }
1941                                    }
1942                                    return true;
1943                                }
1944                                return false;
1945                            }
1946                        
1947                            // This version of the get function usees the propertyList set function
1948 karl             1.137     // to set the property list array into the propertyList object.  It
1949                            // can only be used for those Operations where the propertylist is NOT
1950                            // used by the Server in the response (i.e. getClass and modifyInstance).
1951                            //
1952                            Boolean getSpecial(XmlParser& parser, const char* name, Boolean& emptyTag)
1953                            {
1954                                if (System::strcasecmp(name, "PropertyList") == 0)
1955                                {
1956                                    if (!emptyTag)
1957                                    {
1958                                        CIMValue pl;
1959                                        if (XmlReader::getValueArrayElement(parser, CIMTYPE_STRING, pl))
1960                                        {
1961                                            Array<String> propertyListArray;
1962                                            pl.get(propertyListArray);
1963                                            Array<CIMName> cimNameArray;
1964                                            // Map the strings to CIMNames.
1965                                            for (Uint32 i = 0; i < propertyListArray.size(); i++)
1966                                            {
1967                                                cimNameArray.append(propertyListArray[i]);
1968                                            }
1969 karl             1.137                     // use set to put list into property list without
1970                                            // setting propertyList tags.
1971                                            value.set(cimNameArray);
1972                                        }
1973                                    }
1974                                    return true;
1975                                }
1976                                return false;
1977                            }
1978                        private:
1979                            // hide unused default assign, copy constructors
1980                            propertyListIParam(const propertyListIParam&);
1981                            propertyListIParam& operator = (const propertyListIParam&);
1982                        };
1983                        
1984                        // Attribute decoder for String Parameters
1985                        // The constructor MUST include the attribute name.
1986                        // The second defines whether a value is required.
1987                        // If true and there is no value, the XmlReader does an exception.
1988                        class stringIParam
1989                        {
1990 karl             1.137 public:
1991                            Boolean got;
1992                            String value;
1993                        
1994                            // constructor with definition of iParam name and default for the
1995                            // required flag.
1996                            // @param name const char* with name of IParam to match
1997                        ////  stringIParam(const char* name):
1998                        ////      got(false), iParamName(name), valueRequired(false){}
1999                        
2000                            // constructor with definition of attribute and default for the
2001                            // required flag.
2002                            // @param name const char* with name of IParam to match
2003                            // @param valueRequired Boolean that defines whether value is required
2004                            stringIParam(const char* name, Boolean _valueRequired):
2005                                got(false), iParamName(name), valueRequired(_valueRequired){}
2006                        
2007                            ~stringIParam(){}
2008                        
2009                            void iParamFound(Boolean& duplicate)
2010                            {
2011 karl             1.137         duplicate = got;
2012                                got = true;
2013                            }
2014                        
2015                            // get the attribute if it exists. The attribute name is defined in
2016                            // the constructor
2017                            // @param parser
2018                            // @param testName attribute name from parse.
2019                            // @emptyTag returns true if emptyTag returned true from parser
2020                            // @return Returns true if testName matches the IParam defined by current
2021                            // position in the parser
2022                            Boolean get(XmlParser& parser, const char * testName,  Boolean& emptyTag)
2023                            {
2024                                if (System::strcasecmp(iParamName.getCString(), testName) == 0)
2025                                {
2026                                    if (!emptyTag)
2027                                    {
2028                                        XmlReader::getStringValueElement(parser, value, valueRequired);
2029                                    }
2030                                    return true;
2031                                }
2032 karl             1.137         return false;
2033                            }
2034                        private:
2035                            String iParamName;
2036                            Boolean valueRequired;
2037                            stringIParam();
2038                            stringIParam(const stringIParam&);
2039                            stringIParam& operator = (const stringIParam&);
2040                        };
2041                        
2042                        
2043                        /************************************************************************
2044                        **
2045                        **      Common functions used by the decoders to avoid duplicate code.
2046                        **
2047                        **************************************************************************/
2048                        // test for valid end of XML and duplicate parameters on input
2049                        // This function returns if OK or executes appropriate exceptions if there
2050                        // is either a duplicate (duplicateParameter == true) or the
2051                        // end tag IPARAMVALUE is not found.
2052                        void _checkMissingEndTagOrDuplicateParamValue(
2053 karl             1.137     XmlParser& parser, Boolean duplicateParameter, Boolean emptyTag)
2054                        {
2055                            if (!emptyTag)
2056                            {
2057                                XmlReader::expectEndTag(parser, "IPARAMVALUE");
2058                            }
2059                        
2060                            if (duplicateParameter)
2061                            {
2062                                _throwCIMExceptionDuplicateParameter();
2063                            }
2064                        }
2065                        
2066                        // test if Required paramters exist (i.e. the got variable is
2067                        // true. Generates exception if exist == false
2068                        void _testRequiredParametersExist(Boolean exist)
2069                        {
2070                            if (!exist)
2071                            {
2072                                _throwCIMExceptionInvalidParameter();
2073                            }
2074 karl             1.137 }
2075                        /**************************************************************************
2076                        **
2077                        **  Decode each CIMOperation type, processing the parameters for that type
2078                        **  and producing either a CIMMessage of the appropriate type or
2079                        **  an exception.
2080                        **
2081                        ***************************************************************************/
2082 mike             1.2   
2083 kumpf            1.104 CIMCreateClassRequestMessage*
2084                            CIMOperationRequestDecoder::decodeCreateClassRequest(
2085                                Uint32 queueId,
2086                                XmlParser& parser,
2087                                const String& messageId,
2088                                const CIMNamespaceName& nameSpace)
2089                        {
2090                            STAT_GETSTARTTIME
2091                        
2092                            CIMClass newClass;
2093 karl             1.137     Boolean gotNewClass = false;
2094                        
2095                            Boolean emptyTag;
2096 kumpf            1.104     Boolean duplicateParameter = false;
2097                        
2098                            for (const char* name;
2099                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2100                            {
2101                                if (System::strcasecmp(name, "NewClass") == 0)
2102                                {
2103                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2104 kumpf            1.106             if (!XmlReader::getClassElement(parser, newClass))
2105                                    {
2106 karl             1.137                 _throwCIMExceptionInvalidParameter("NewClass");
2107 kumpf            1.106             }
2108 karl             1.137             duplicateParameter = gotNewClass;
2109                                    gotNewClass = true;
2110 kumpf            1.104         }
2111                                else
2112                                {
2113 karl             1.137             _throwCIMExceptionInvalidIParamName();
2114 kumpf            1.104         }
2115 sage             1.41  
2116 karl             1.137         // generate exception if endtag error or duplicate attributes
2117                                _checkMissingEndTagOrDuplicateParamValue(
2118                                    parser, duplicateParameter, emptyTag);
2119 kumpf            1.104     }
2120                        
2121 karl             1.137     _testRequiredParametersExist(gotNewClass);
2122 kumpf            1.104 
2123                            AutoPtr<CIMCreateClassRequestMessage> request(
2124                                new CIMCreateClassRequestMessage(
2125                                    messageId,
2126                                    nameSpace,
2127                                    newClass,
2128                                    QueueIdStack(queueId, _returnQueueId)));
2129                        
2130                            STAT_SERVERSTART
2131                        
2132                            return request.release();
2133 mike             1.2   }
2134                        
2135                        CIMGetClassRequestMessage* CIMOperationRequestDecoder::decodeGetClassRequest(
2136 kumpf            1.104     Uint32 queueId,
2137                            XmlParser& parser,
2138                            const String& messageId,
2139                            const CIMNamespaceName& nameSpace)
2140                        {
2141 karl             1.137     STAT_GETSTARTTIME
2142 kumpf            1.104 
2143 karl             1.137     // GetClass Parameters
2144                            classNameIParam className("ClassName");
2145                            booleanIParam localOnly("localOnly",true);
2146                            booleanIParam includeQualifiers("IncludeQualifiers", true);
2147                            booleanIParam includeClassOrigin("IncludeClassOrigin");
2148                            propertyListIParam propertyList;
2149 kumpf            1.104 
2150                            Boolean duplicateParameter = false;
2151                            Boolean emptyTag;
2152                        
2153                            for (const char* name;
2154                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2155                            {
2156 karl             1.137         if(className.get(parser, name, emptyTag))
2157 kumpf            1.104         {
2158 karl             1.137             className.iParamFound(duplicateParameter);
2159 kumpf            1.104         }
2160 karl             1.137         else if(localOnly.get(parser, name, emptyTag))
2161 kumpf            1.104         {
2162 karl             1.137             localOnly.iParamFound(duplicateParameter);
2163 kumpf            1.104         }
2164 karl             1.137         else if(includeQualifiers.get(parser, name, emptyTag))
2165 kumpf            1.104         {
2166 karl             1.137             includeQualifiers.iParamFound(duplicateParameter);
2167 kumpf            1.104         }
2168 karl             1.137         else if(includeClassOrigin.get(parser, name,  emptyTag))
2169 kumpf            1.104         {
2170 karl             1.137             includeClassOrigin.iParamFound(duplicateParameter);
2171 kumpf            1.104         }
2172 karl             1.137         else if(propertyList.getSpecial(parser, name, emptyTag))
2173 kumpf            1.104         {
2174 karl             1.137             propertyList.iParamFound(duplicateParameter);
2175 kumpf            1.104         }
2176                                else
2177                                {
2178 karl             1.137             _throwCIMExceptionInvalidIParamName();
2179 kumpf            1.104         }
2180 karl             1.137         // generate exception if endtag error or duplicate attributes
2181                                _checkMissingEndTagOrDuplicateParamValue(
2182                                    parser, duplicateParameter, emptyTag);
2183 kumpf            1.104     }
2184                        
2185 karl             1.137     // test for required parameters
2186                            _testRequiredParametersExist(className.got);
2187 kumpf            1.104 
2188 karl             1.137     // Build message
2189 kumpf            1.104     AutoPtr<CIMGetClassRequestMessage> request(new CIMGetClassRequestMessage(
2190                                messageId,
2191                                nameSpace,
2192 karl             1.137         className.value,
2193                                localOnly.value,
2194                                includeQualifiers.value,
2195                                includeClassOrigin.value,
2196                                propertyList.value,
2197 kumpf            1.104         QueueIdStack(queueId, _returnQueueId)));
2198                        
2199                            STAT_SERVERSTART
2200                        
2201                            return request.release();
2202                        }
2203                        
2204                        CIMModifyClassRequestMessage*
2205                            CIMOperationRequestDecoder::decodeModifyClassRequest(
2206                                Uint32 queueId,
2207                                XmlParser& parser,
2208                                const String& messageId,
2209                                const CIMNamespaceName& nameSpace)
2210                        {
2211                            STAT_GETSTARTTIME
2212                        
2213                            CIMClass modifiedClass;
2214                            Boolean gotClass = false;
2215 karl             1.137 
2216 kumpf            1.104     Boolean emptyTag;
2217 karl             1.137     Boolean duplicateParameter = false;
2218 kumpf            1.104 
2219                            for (const char* name;
2220                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2221                            {
2222                                if (System::strcasecmp(name, "ModifiedClass") == 0)
2223                                {
2224                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2225 kumpf            1.106             if (!XmlReader::getClassElement(parser, modifiedClass))
2226                                    {
2227 karl             1.137                 _throwCIMExceptionInvalidParameter("ModifiedClass");
2228 kumpf            1.106             }
2229 kumpf            1.104             duplicateParameter = gotClass;
2230                                    gotClass = true;
2231                                }
2232                                else
2233                                {
2234 karl             1.137             _throwCIMExceptionInvalidIParamName();
2235 kumpf            1.104         }
2236                        
2237 karl             1.137         // generate exception if endtag error or duplicate attributes
2238                                _checkMissingEndTagOrDuplicateParamValue(
2239                                    parser, duplicateParameter, emptyTag);
2240 kumpf            1.104     }
2241                        
2242 karl             1.137     _testRequiredParametersExist(gotClass);
2243 kumpf            1.104 
2244                            AutoPtr<CIMModifyClassRequestMessage> request(
2245                                new CIMModifyClassRequestMessage(
2246                                    messageId,
2247                                    nameSpace,
2248                                    modifiedClass,
2249                                    QueueIdStack(queueId, _returnQueueId)));
2250                        
2251                            STAT_SERVERSTART
2252                        
2253                            return request.release();
2254                        }
2255                        
2256                        CIMEnumerateClassNamesRequestMessage*
2257                            CIMOperationRequestDecoder::decodeEnumerateClassNamesRequest(
2258                                Uint32 queueId,
2259                                XmlParser& parser,
2260                                const String& messageId,
2261                                const CIMNamespaceName& nameSpace)
2262                        {
2263                            STAT_GETSTARTTIME
2264 kumpf            1.104 
2265 karl             1.137     classNameIParam className("ClassName");
2266                            booleanIParam deepInheritance("DeepInheritance");
2267                        
2268 kumpf            1.104     Boolean duplicateParameter = false;
2269                            Boolean emptyTag;
2270                        
2271                            for (const char* name;
2272                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2273                            {
2274 karl             1.137         if(className.getOptional(parser, name, emptyTag))
2275 kumpf            1.104         {
2276 karl             1.137             className.iParamFound(duplicateParameter);
2277 kumpf            1.104         }
2278 karl             1.137         else if(deepInheritance.get(parser, name, emptyTag))
2279 kumpf            1.104         {
2280 karl             1.137             deepInheritance.iParamFound(duplicateParameter);
2281 kumpf            1.104         }
2282                                else
2283                                {
2284 karl             1.137             _throwCIMExceptionInvalidIParamName();
2285 kumpf            1.104         }
2286                        
2287 karl             1.137         // generate exception if endtag error or duplicate attributes
2288                                _checkMissingEndTagOrDuplicateParamValue(
2289                                    parser, duplicateParameter, emptyTag);
2290                            }
2291 kumpf            1.104 
2292 karl             1.137     // NOTE: className not required for this operation
2293 kumpf            1.104 
2294                            AutoPtr<CIMEnumerateClassNamesRequestMessage> request(
2295                                new CIMEnumerateClassNamesRequestMessage(
2296                                    messageId,
2297                                    nameSpace,
2298 karl             1.137             className.value,
2299                                    deepInheritance.value,
2300 kumpf            1.104             QueueIdStack(queueId, _returnQueueId)));
2301                        
2302                            STAT_SERVERSTART
2303                        
2304                            return request.release();
2305                        }
2306                        
2307                        CIMEnumerateClassesRequestMessage*
2308                            CIMOperationRequestDecoder::decodeEnumerateClassesRequest(
2309                                Uint32 queueId,
2310                                XmlParser& parser,
2311                                const String& messageId,
2312                                const CIMNamespaceName& nameSpace)
2313                        {
2314                            STAT_GETSTARTTIME
2315                        
2316 karl             1.137     // EnumerateClasses Parameters
2317                            classNameIParam className("ClassName");
2318                            booleanIParam deepInheritance("deepInheritance");
2319                            booleanIParam localOnly("localOnly",true);
2320                            booleanIParam includeQualifiers("IncludeQualifiers", true);
2321                            booleanIParam includeClassOrigin("IncludeClassOrigin");
2322                        
2323 kumpf            1.104     Boolean duplicateParameter = false;
2324                            Boolean emptyTag;
2325                        
2326                            for (const char* name;
2327                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2328                            {
2329 karl             1.137         if(className.getOptional(parser, name, emptyTag))
2330 kumpf            1.104         {
2331 karl             1.137             className.iParamFound(duplicateParameter);
2332 kumpf            1.104         }
2333 karl             1.137         else if(deepInheritance.get(parser, name, emptyTag))
2334 kumpf            1.104         {
2335 karl             1.137             deepInheritance.iParamFound(duplicateParameter);
2336 kumpf            1.104         }
2337 karl             1.137         else if(localOnly.get(parser, name, emptyTag))
2338 kumpf            1.104         {
2339 karl             1.137             localOnly.iParamFound(duplicateParameter);
2340 kumpf            1.104         }
2341 karl             1.137         else if(includeQualifiers.get(parser, name, emptyTag))
2342 kumpf            1.104         {
2343 karl             1.137             includeQualifiers.iParamFound(duplicateParameter);
2344 kumpf            1.104         }
2345 karl             1.137         else if(includeClassOrigin.get(parser, name,  emptyTag))
2346 kumpf            1.104         {
2347 karl             1.137             includeClassOrigin.iParamFound(duplicateParameter);
2348 kumpf            1.104         }
2349                                else
2350                                {
2351 karl             1.137             _throwCIMExceptionInvalidIParamName();
2352 kumpf            1.104         }
2353                        
2354 karl             1.137         // generate exception if endtag error or duplicate attributes
2355                                _checkMissingEndTagOrDuplicateParamValue(
2356                                    parser, duplicateParameter, emptyTag);
2357                            }
2358 kumpf            1.104 
2359 karl             1.137     // NOTE: Class name not required for this enumerate.
2360 kumpf            1.104 
2361                            AutoPtr<CIMEnumerateClassesRequestMessage> request(
2362                                new CIMEnumerateClassesRequestMessage(
2363                                    messageId,
2364                                    nameSpace,
2365 karl             1.137             className.value,
2366                                    deepInheritance.value,
2367                                    localOnly.value,
2368                                    includeQualifiers.value,
2369                                    includeClassOrigin.value,
2370 kumpf            1.104             QueueIdStack(queueId, _returnQueueId)));
2371                        
2372                            STAT_SERVERSTART
2373                        
2374                            return request.release();
2375                        }
2376                        
2377                        CIMDeleteClassRequestMessage*
2378                            CIMOperationRequestDecoder::decodeDeleteClassRequest(
2379                                Uint32 queueId,
2380                                XmlParser& parser,
2381                                const String& messageId,
2382                                const CIMNamespaceName& nameSpace)
2383                        {
2384                            STAT_GETSTARTTIME
2385                        
2386 karl             1.137     classNameIParam className("ClassName");
2387                        
2388 kumpf            1.104     Boolean duplicateParameter = false;
2389                            Boolean emptyTag;
2390                        
2391                            for (const char* name;
2392                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2393                            {
2394 karl             1.137         if(className.get(parser, name, emptyTag))
2395 kumpf            1.104         {
2396 karl             1.137             className.iParamFound(duplicateParameter);
2397 kumpf            1.104         }
2398                                else
2399                                {
2400 karl             1.137             _throwCIMExceptionInvalidIParamName();
2401 kumpf            1.104         }
2402                        
2403 karl             1.137         // generate exception if endtag error or duplicate attributes
2404                                _checkMissingEndTagOrDuplicateParamValue(
2405                                    parser, duplicateParameter, emptyTag);
2406 kumpf            1.104     }
2407                        
2408 karl             1.137     _testRequiredParametersExist(className.got);
2409 kumpf            1.104 
2410                            AutoPtr<CIMDeleteClassRequestMessage> request(
2411                                new CIMDeleteClassRequestMessage(
2412                                    messageId,
2413                                    nameSpace,
2414 karl             1.137             className.value,
2415 kumpf            1.104             QueueIdStack(queueId, _returnQueueId)));
2416                        
2417                            STAT_SERVERSTART
2418                        
2419                            return request.release();
2420                        }
2421                        
2422                        CIMCreateInstanceRequestMessage*
2423                            CIMOperationRequestDecoder::decodeCreateInstanceRequest(
2424                                Uint32 queueId,
2425                                XmlParser& parser,
2426                                const String& messageId,
2427                                const CIMNamespaceName& nameSpace)
2428                        {
2429                            STAT_GETSTARTTIME
2430                        
2431                            CIMInstance newInstance;
2432                            Boolean gotInstance = false;
2433 karl             1.137 
2434 kumpf            1.104     Boolean emptyTag;
2435 karl             1.137     Boolean duplicateParameter = false;
2436 kumpf            1.104 
2437                            for (const char* name;
2438                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2439                            {
2440                                if (System::strcasecmp(name, "NewInstance") == 0)
2441                                {
2442                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2443                                    XmlReader::getInstanceElement(parser, newInstance);
2444                                    duplicateParameter = gotInstance;
2445                                    gotInstance = true;
2446                                }
2447                                else
2448                                {
2449 karl             1.137             _throwCIMExceptionInvalidIParamName();
2450 kumpf            1.104         }
2451                        
2452 karl             1.137         // generate exception if endtag error or duplicate attributes
2453                                _checkMissingEndTagOrDuplicateParamValue(
2454                                    parser, duplicateParameter, emptyTag);
2455                            }
2456 kumpf            1.104 
2457                        
2458 karl             1.137     _testRequiredParametersExist(gotInstance);
2459 kumpf            1.104 
2460                            AutoPtr<CIMCreateInstanceRequestMessage> request(
2461                                new CIMCreateInstanceRequestMessage(
2462                                    messageId,
2463                                    nameSpace,
2464                                    newInstance,
2465                                    QueueIdStack(queueId, _returnQueueId)));
2466                        
2467                            STAT_SERVERSTART
2468                        
2469                            return request.release();
2470                        }
2471                        
2472                        CIMGetInstanceRequestMessage*
2473                            CIMOperationRequestDecoder::decodeGetInstanceRequest(
2474                                Uint32 queueId,
2475                                XmlParser& parser,
2476                                const String& messageId,
2477                                const CIMNamespaceName& nameSpace)
2478                        {
2479                            STAT_GETSTARTTIME
2480 kumpf            1.104 
2481 karl             1.137     instanceNameIParam instanceName;
2482                            // This attribute is accepted for compatibility reasons, but is
2483                            // not honored because it is deprecated.
2484                            booleanIParam localOnly("localOnly",true);
2485                            booleanIParam includeQualifiers("IncludeQualifiers");
2486                            booleanIParam includeClassOrigin("IncludeClassOrigin");
2487                            propertyListIParam propertyList;
2488                        
2489 kumpf            1.104     Boolean duplicateParameter = false;
2490                            Boolean emptyTag;
2491                        
2492                            for (const char* name;
2493                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2494                            {
2495 karl             1.137         if(instanceName.get(parser, name, emptyTag))
2496 kumpf            1.104         {
2497 karl             1.137             instanceName.iParamFound(duplicateParameter);
2498 kumpf            1.104         }
2499 karl             1.137         // localOnly is accepted for compatibility reasons, but is
2500                                // not honored because it is deprecated.
2501                                else if(localOnly.get(parser, name, emptyTag))
2502 kumpf            1.104         {
2503 karl             1.137             localOnly.iParamFound(duplicateParameter);
2504 kumpf            1.104         }
2505 karl             1.137         else if(includeQualifiers.get(parser, name, emptyTag))
2506 kumpf            1.104         {
2507 karl             1.137             includeQualifiers.iParamFound(duplicateParameter);
2508 kumpf            1.104         }
2509 karl             1.137         else if(includeClassOrigin.get(parser, name,  emptyTag))
2510 kumpf            1.104         {
2511 karl             1.137             includeClassOrigin.iParamFound(duplicateParameter);
2512 kumpf            1.104         }
2513 karl             1.137         else if(propertyList.get(parser, name, emptyTag))
2514 kumpf            1.104         {
2515 karl             1.137             propertyList.iParamFound(duplicateParameter);
2516 kumpf            1.104         }
2517                                else
2518                                {
2519 karl             1.137             _throwCIMExceptionInvalidIParamName();
2520 kumpf            1.104         }
2521                        
2522 karl             1.137         // generate exception if endtag error or duplicate attributes
2523                                _checkMissingEndTagOrDuplicateParamValue(
2524                                    parser, duplicateParameter, emptyTag);
2525 kumpf            1.104     }
2526                        
2527 karl             1.137     _testRequiredParametersExist(instanceName.got);
2528 kumpf            1.104 
2529                            AutoPtr<CIMGetInstanceRequestMessage> request(
2530                                new CIMGetInstanceRequestMessage(
2531                                    messageId,
2532                                    nameSpace,
2533 karl             1.137             instanceName.value,
2534 h.sterling       1.97  #ifdef PEGASUS_DISABLE_INSTANCE_QUALIFIERS
2535 kumpf            1.104             false,
2536 h.sterling       1.97  #else
2537 karl             1.137             includeQualifiers.value,
2538 h.sterling       1.97  #endif
2539 karl             1.137             includeClassOrigin.value,
2540                                    propertyList.value,
2541 kumpf            1.104             QueueIdStack(queueId, _returnQueueId)));
2542                        
2543                            STAT_SERVERSTART
2544                        
2545                            return request.release();
2546                        }
2547                        
2548 karl             1.137 
2549 kumpf            1.104 CIMModifyInstanceRequestMessage*
2550                            CIMOperationRequestDecoder::decodeModifyInstanceRequest(
2551                                Uint32 queueId,
2552                                XmlParser& parser,
2553                                const String& messageId,
2554                                const CIMNamespaceName& nameSpace)
2555                        {
2556                            STAT_GETSTARTTIME
2557                        
2558                            CIMInstance modifiedInstance;
2559                            Boolean gotInstance = false;
2560 karl             1.137 
2561                            booleanIParam includeQualifiers("IncludeQualifiers", true);
2562                            propertyListIParam propertyList;
2563                        
2564 kumpf            1.104     Boolean emptyTag;
2565 karl             1.137     Boolean duplicateParameter = false;
2566 kumpf            1.104 
2567                            for (const char* name;
2568                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2569                            {
2570                                if (System::strcasecmp(name, "ModifiedInstance") == 0)
2571                                {
2572                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2573                                    XmlReader::getNamedInstanceElement(parser, modifiedInstance);
2574                                    duplicateParameter = gotInstance;
2575                                    gotInstance = true;
2576                                }
2577 karl             1.137         else if(includeQualifiers.get(parser, name, emptyTag))
2578 kumpf            1.104         {
2579 karl             1.137             includeQualifiers.iParamFound(duplicateParameter);
2580 kumpf            1.104         }
2581 karl             1.137         else if(propertyList.getSpecial(parser, name, emptyTag))
2582 kumpf            1.104         {
2583 karl             1.137             propertyList.iParamFound(duplicateParameter);
2584 kumpf            1.104         }
2585                                else
2586                                {
2587 karl             1.137             _throwCIMExceptionInvalidIParamName();
2588 kumpf            1.104         }
2589                        
2590 karl             1.137         _checkMissingEndTagOrDuplicateParamValue(
2591                                    parser, duplicateParameter, emptyTag);
2592 kumpf            1.104     }
2593                        
2594 karl             1.137     _testRequiredParametersExist(gotInstance);
2595 kumpf            1.104 
2596                            AutoPtr<CIMModifyInstanceRequestMessage> request(
2597                                new CIMModifyInstanceRequestMessage(
2598                                    messageId,
2599                                    nameSpace,
2600                                    modifiedInstance,
2601 karl             1.137             includeQualifiers.value,
2602                                    propertyList.value,
2603 kumpf            1.104             QueueIdStack(queueId, _returnQueueId)));
2604                        
2605                            STAT_SERVERSTART
2606                        
2607                            return request.release();
2608                        }
2609                        
2610                        CIMEnumerateInstancesRequestMessage*
2611                            CIMOperationRequestDecoder::decodeEnumerateInstancesRequest(
2612                                Uint32 queueId,
2613                                XmlParser& parser,
2614                                const String& messageId,
2615                                const CIMNamespaceName& nameSpace)
2616                        {
2617                            STAT_GETSTARTTIME
2618                        
2619 karl             1.137     // EnumerateInstance Parameters
2620                            classNameIParam className("ClassName");
2621                            booleanIParam deepInheritance("DeepInheritance", true);
2622                            // localOnly is accepted for compatibility reasons, but is
2623                            // not honored because it is deprecated.
2624                            booleanIParam localOnly("localOnly", true);
2625                            booleanIParam includeQualifiers("IncludeQualifiers");
2626                            booleanIParam includeClassOrigin("IncludeClassOrigin");
2627                            propertyListIParam propertyList;
2628                        
2629 kumpf            1.104     Boolean duplicateParameter = false;
2630                            Boolean emptyTag;
2631                        
2632                            for (const char* name;
2633                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2634                            {
2635 karl             1.137         if(className.get(parser, name, emptyTag))
2636 kumpf            1.104         {
2637 karl             1.137             className.iParamFound(duplicateParameter);
2638 kumpf            1.104         }
2639 karl             1.137         else if(deepInheritance.get(parser, name, emptyTag))
2640 kumpf            1.104         {
2641 karl             1.137             deepInheritance.iParamFound(duplicateParameter);
2642 kumpf            1.104         }
2643 karl             1.137         // This attribute is accepted for compatibility reasons, but is
2644                                // not honored because it is deprecated.
2645                                else if(localOnly.get(parser, name, emptyTag))
2646 kumpf            1.104         {
2647 karl             1.137             localOnly.iParamFound(duplicateParameter);
2648 kumpf            1.104         }
2649 karl             1.137         else if(includeQualifiers.get(parser, name, emptyTag))
2650 kumpf            1.104         {
2651 karl             1.137             includeQualifiers.iParamFound(duplicateParameter);
2652 kumpf            1.104         }
2653 karl             1.137         else if(includeClassOrigin.get(parser, name,  emptyTag))
2654 kumpf            1.104         {
2655 karl             1.137             includeClassOrigin.iParamFound(duplicateParameter);
2656 kumpf            1.104         }
2657 karl             1.137         else if(propertyList.get(parser, name, emptyTag))
2658 kumpf            1.104         {
2659 karl             1.137             propertyList.iParamFound(duplicateParameter);
2660 kumpf            1.104         }
2661 karl             1.137         else
2662 kumpf            1.104         {
2663 karl             1.137             _throwCIMExceptionInvalidIParamName();
2664 kumpf            1.104         }
2665                        
2666 karl             1.137         // generate exception if endtag error or duplicate attributes
2667                                _checkMissingEndTagOrDuplicateParamValue(
2668                                    parser, duplicateParameter, emptyTag);
2669 kumpf            1.104     }
2670                        
2671 karl             1.137     _testRequiredParametersExist(className.got);
2672 karl             1.135 
2673 kumpf            1.104     AutoPtr<CIMEnumerateInstancesRequestMessage> request(
2674                                new CIMEnumerateInstancesRequestMessage(
2675                                    messageId,
2676                                    nameSpace,
2677 karl             1.137             className.value,
2678                                    deepInheritance.value,
2679 h.sterling       1.97  #ifdef PEGASUS_DISABLE_INSTANCE_QUALIFIERS
2680 kumpf            1.104             false,
2681 h.sterling       1.97  #else
2682 karl             1.137             includeQualifiers.value,
2683 h.sterling       1.97  #endif
2684 karl             1.137             includeClassOrigin.value,
2685                                    propertyList.value,
2686 kumpf            1.104             QueueIdStack(queueId, _returnQueueId)));
2687                        
2688                            STAT_SERVERSTART
2689                        
2690                            return request.release();
2691                        }
2692                        
2693                        CIMEnumerateInstanceNamesRequestMessage*
2694                            CIMOperationRequestDecoder::decodeEnumerateInstanceNamesRequest(
2695                                Uint32 queueId,
2696                                XmlParser& parser,
2697                                const String& messageId,
2698                                const CIMNamespaceName& nameSpace)
2699                        {
2700                            STAT_GETSTARTTIME
2701                        
2702 karl             1.137     classNameIParam className("ClassName");
2703                        
2704 kumpf            1.104     Boolean duplicateParameter = false;
2705                            Boolean emptyTag;
2706                        
2707                            for (const char* name;
2708                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2709                            {
2710 karl             1.137         if(className.get(parser, name, emptyTag))
2711 kumpf            1.104         {
2712 karl             1.137             className.iParamFound(duplicateParameter);
2713 kumpf            1.104         }
2714                                else
2715                                {
2716 karl             1.137             _throwCIMExceptionInvalidIParamName();
2717 kumpf            1.104         }
2718                        
2719 karl             1.137         // generate exception if endtag error or duplicate attributes
2720                                _checkMissingEndTagOrDuplicateParamValue(
2721                                    parser, duplicateParameter, emptyTag);
2722 kumpf            1.104     }
2723                        
2724 karl             1.137     _testRequiredParametersExist(className.got);
2725 kumpf            1.104 
2726                            AutoPtr<CIMEnumerateInstanceNamesRequestMessage> request(
2727                                new CIMEnumerateInstanceNamesRequestMessage(
2728                                    messageId,
2729                                    nameSpace,
2730 karl             1.137             className.value,
2731 kumpf            1.104             QueueIdStack(queueId, _returnQueueId)));
2732                        
2733                            STAT_SERVERSTART
2734                        
2735                            return request.release();
2736                        }
2737                        
2738                        CIMDeleteInstanceRequestMessage*
2739                            CIMOperationRequestDecoder::decodeDeleteInstanceRequest(
2740                                Uint32 queueId,
2741                                XmlParser& parser,
2742                                const String& messageId,
2743                                const CIMNamespaceName& nameSpace)
2744                        {
2745                            STAT_GETSTARTTIME
2746                        
2747 karl             1.137     instanceNameIParam instanceName;
2748                        
2749 kumpf            1.104     Boolean duplicateParameter = false;
2750                            Boolean emptyTag;
2751                        
2752                            for (const char* name;
2753                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2754                            {
2755 karl             1.137         if(instanceName.get(parser, name, emptyTag))
2756 kumpf            1.104         {
2757 karl             1.137             instanceName.iParamFound(duplicateParameter);
2758 kumpf            1.104         }
2759                                else
2760                                {
2761 karl             1.137             _throwCIMExceptionInvalidIParamName();
2762 kumpf            1.104         }
2763                        
2764 karl             1.137         // generate exception if endtag error or duplicate attributes
2765                                _checkMissingEndTagOrDuplicateParamValue(
2766                                    parser, duplicateParameter, emptyTag);
2767 kumpf            1.104     }
2768                        
2769 karl             1.137     _testRequiredParametersExist(instanceName.got);
2770 kumpf            1.104 
2771                            AutoPtr<CIMDeleteInstanceRequestMessage> request(
2772                                new CIMDeleteInstanceRequestMessage(
2773                                    messageId,
2774                                    nameSpace,
2775 karl             1.137             instanceName.value,
2776 kumpf            1.104             QueueIdStack(queueId, _returnQueueId)));
2777                        
2778                            STAT_SERVERSTART
2779                        
2780                            return request.release();
2781                        }
2782                        
2783                        CIMSetQualifierRequestMessage*
2784                            CIMOperationRequestDecoder::decodeSetQualifierRequest(
2785                                Uint32 queueId,
2786                                XmlParser& parser,
2787                                const String& messageId,
2788                                const CIMNamespaceName& nameSpace)
2789                        {
2790                            STAT_GETSTARTTIME
2791                        
2792                            CIMQualifierDecl qualifierDeclaration;
2793                            Boolean duplicateParameter = false;
2794                            Boolean gotQualifierDeclaration = false;
2795                            Boolean emptyTag;
2796                        
2797 kumpf            1.104     for (const char* name;
2798                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2799                            {
2800                                if (System::strcasecmp(name, "QualifierDeclaration") == 0)
2801                                {
2802                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2803                                    XmlReader::getQualifierDeclElement(parser, qualifierDeclaration);
2804                                    duplicateParameter = gotQualifierDeclaration;
2805                                    gotQualifierDeclaration = true;
2806                                }
2807                                else
2808                                {
2809 karl             1.137             _throwCIMExceptionInvalidIParamName();
2810 kumpf            1.104         }
2811                        
2812 karl             1.137         // generate exception if endtag error or duplicate attributes
2813                                _checkMissingEndTagOrDuplicateParamValue(
2814                                    parser, duplicateParameter, emptyTag);
2815 kumpf            1.104     }
2816                        
2817 karl             1.137     _testRequiredParametersExist(gotQualifierDeclaration);
2818 kumpf            1.104 
2819                            AutoPtr<CIMSetQualifierRequestMessage> request(
2820                                new CIMSetQualifierRequestMessage(
2821                                    messageId,
2822                                    nameSpace,
2823                                    qualifierDeclaration,
2824                                    QueueIdStack(queueId, _returnQueueId)));
2825                        
2826                            STAT_SERVERSTART
2827                        
2828                            return request.release();
2829                        }
2830                        
2831                        CIMGetQualifierRequestMessage*
2832                            CIMOperationRequestDecoder::decodeGetQualifierRequest(
2833                                Uint32 queueId,
2834                                XmlParser& parser,
2835                                const String& messageId,
2836                                const CIMNamespaceName& nameSpace)
2837                        {
2838                            STAT_GETSTARTTIME
2839 kumpf            1.104 
2840                            String qualifierNameString;
2841                            CIMName qualifierName;
2842                            Boolean duplicateParameter = false;
2843                            Boolean gotQualifierName = false;
2844                            Boolean emptyTag;
2845                        
2846                            for (const char* name;
2847                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2848                            {
2849                                if (System::strcasecmp(name, "QualifierName") == 0)
2850                                {
2851                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2852                                    XmlReader::getStringValueElement(parser, qualifierNameString, true);
2853                                    qualifierName = qualifierNameString;
2854                                    duplicateParameter = gotQualifierName;
2855                                    gotQualifierName = true;
2856                                }
2857                                else
2858                                {
2859 karl             1.137             _throwCIMExceptionInvalidIParamName();
2860 kumpf            1.104         }
2861                        
2862 karl             1.137         // generate exception if endtag error or duplicate attributes
2863                                _checkMissingEndTagOrDuplicateParamValue(
2864                                    parser, duplicateParameter, emptyTag);
2865 kumpf            1.104     }
2866                        
2867 karl             1.137     _testRequiredParametersExist(gotQualifierName);
2868 kumpf            1.104 
2869                            AutoPtr<CIMGetQualifierRequestMessage> request(
2870                                new CIMGetQualifierRequestMessage(
2871                                    messageId,
2872                                    nameSpace,
2873                                    qualifierName,
2874                                    QueueIdStack(queueId, _returnQueueId)));
2875                        
2876                            STAT_SERVERSTART
2877                        
2878                            return request.release();
2879                        }
2880                        
2881                        CIMEnumerateQualifiersRequestMessage*
2882                            CIMOperationRequestDecoder::decodeEnumerateQualifiersRequest(
2883                                Uint32 queueId,
2884                                XmlParser& parser,
2885                                const String& messageId,
2886                                const CIMNamespaceName& nameSpace)
2887                        {
2888                            STAT_GETSTARTTIME
2889 kumpf            1.104     Boolean emptyTag;
2890                        
2891                            for (const char* name;
2892                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2893                            {
2894                                // No IPARAMVALUEs are defined for this operation
2895 karl             1.137         _throwCIMExceptionInvalidIParamName();
2896 kumpf            1.104     }
2897                        
2898                            AutoPtr<CIMEnumerateQualifiersRequestMessage> request(
2899                                new CIMEnumerateQualifiersRequestMessage(
2900                                    messageId,
2901                                    nameSpace,
2902                                    QueueIdStack(queueId, _returnQueueId)));
2903                        
2904                            STAT_SERVERSTART
2905                        
2906                            return request.release();
2907                        }
2908                        
2909                        CIMDeleteQualifierRequestMessage*
2910                            CIMOperationRequestDecoder::decodeDeleteQualifierRequest(
2911                                Uint32 queueId,
2912                                XmlParser& parser,
2913                                const String& messageId,
2914                                const CIMNamespaceName& nameSpace)
2915                        {
2916                            STAT_GETSTARTTIME
2917 kumpf            1.104 
2918                            String qualifierNameString;
2919                            CIMName qualifierName;
2920                            Boolean gotQualifierName = false;
2921 karl             1.137 
2922 kumpf            1.104     Boolean emptyTag;
2923 karl             1.137     Boolean duplicateParameter = false;
2924 kumpf            1.104 
2925                            for (const char* name;
2926                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2927                            {
2928                                if (System::strcasecmp(name, "QualifierName") == 0)
2929                                {
2930                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2931                                    XmlReader::getStringValueElement(parser, qualifierNameString, true);
2932                                    qualifierName = qualifierNameString;
2933                                    duplicateParameter = gotQualifierName;
2934                                    gotQualifierName = true;
2935                                }
2936                                else
2937                                {
2938 karl             1.137             _throwCIMExceptionInvalidIParamName();
2939 kumpf            1.104         }
2940                        
2941                        
2942 karl             1.137         // generate exception if endtag error or duplicate attributes
2943                                _checkMissingEndTagOrDuplicateParamValue(
2944                                    parser, duplicateParameter, emptyTag);
2945 kumpf            1.104     }
2946                        
2947 karl             1.137     _testRequiredParametersExist(gotQualifierName);
2948 kumpf            1.104 
2949                            AutoPtr<CIMDeleteQualifierRequestMessage> request(
2950                                new CIMDeleteQualifierRequestMessage(
2951                                    messageId,
2952                                    nameSpace,
2953                                    qualifierName,
2954                                    QueueIdStack(queueId, _returnQueueId)));
2955                        
2956                            STAT_SERVERSTART
2957                        
2958                            return request.release();
2959                        }
2960                        
2961                        CIMReferenceNamesRequestMessage*
2962                            CIMOperationRequestDecoder::decodeReferenceNamesRequest(
2963                                Uint32 queueId,
2964                                XmlParser& parser,
2965                                const String& messageId,
2966                                const CIMNamespaceName& nameSpace)
2967                        {
2968                            STAT_GETSTARTTIME
2969 karl             1.137     objectNameIParam objectName;
2970                            classNameIParam resultClass("ResultClass");
2971                            stringIParam role("role", false);
2972 kumpf            1.104 
2973 karl             1.137     Boolean duplicateParameter = false;
2974 kumpf            1.104     Boolean emptyTag;
2975                        
2976                            for (const char* name;
2977 karl             1.137         XmlReader::getIParamValueTag(parser, name, emptyTag); )
2978 kumpf            1.104     {
2979 karl             1.137         if(objectName.get(parser, name, emptyTag))
2980 kumpf            1.104         {
2981 karl             1.137             objectName.iParamFound(duplicateParameter);
2982 kumpf            1.104         }
2983 karl             1.137         else if (resultClass.getOptional(parser, name, emptyTag))
2984 kumpf            1.104         {
2985 karl             1.137             resultClass.iParamFound(duplicateParameter);
2986 kumpf            1.104         }
2987 karl             1.137         else if(role.get(parser, name, emptyTag))
2988 kumpf            1.104         {
2989 karl             1.137             role.iParamFound(duplicateParameter);
2990 kumpf            1.104         }
2991                                else
2992                                {
2993 karl             1.137             _throwCIMExceptionInvalidIParamName();
2994 kumpf            1.104         }
2995                        
2996 karl             1.137         // generate exception if endtag error or duplicate attributes
2997                                _checkMissingEndTagOrDuplicateParamValue(
2998                                    parser, duplicateParameter, emptyTag);
2999 kumpf            1.104     }
3000                        
3001 karl             1.137     _testRequiredParametersExist(objectName.got);
3002 kumpf            1.104 
3003                            AutoPtr<CIMReferenceNamesRequestMessage> request(
3004                                new CIMReferenceNamesRequestMessage(
3005                                    messageId,
3006                                    nameSpace,
3007 karl             1.137             objectName.value,
3008                                    resultClass.value,
3009                                    role.value,
3010 karl             1.135             QueueIdStack(queueId, _returnQueueId),
3011 karl             1.137             objectName.isClassNameElement));
3012 kumpf            1.104 
3013                            STAT_SERVERSTART
3014                        
3015                            return request.release();
3016                        }
3017                        
3018                        CIMReferencesRequestMessage*
3019                            CIMOperationRequestDecoder::decodeReferencesRequest(
3020                                Uint32 queueId,
3021                                XmlParser& parser,
3022                                const String& messageId,
3023                                const CIMNamespaceName& nameSpace)
3024                        {
3025                            STAT_GETSTARTTIME
3026                        
3027 karl             1.137     objectNameIParam objectName;
3028                            classNameIParam resultClass("ResultClass");
3029                            stringIParam role("role", false);
3030                            booleanIParam includeQualifiers("IncludeQualifiers");
3031                            booleanIParam includeClassOrigin("IncludeClassOrigin");
3032                            propertyListIParam propertyList;
3033                        
3034                            Boolean duplicateParameter = false;
3035 kumpf            1.104     Boolean emptyTag;
3036                        
3037                            for (const char* name;
3038                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3039                            {
3040 karl             1.137         if(objectName.get(parser, name, emptyTag))
3041 kumpf            1.104         {
3042 karl             1.137             objectName.iParamFound(duplicateParameter);
3043 kumpf            1.104         }
3044 karl             1.137         else if(role.get(parser, name, emptyTag))
3045 kumpf            1.104         {
3046 karl             1.137             role.iParamFound(duplicateParameter);
3047 kumpf            1.104         }
3048 karl             1.137         else if (resultClass.getOptional(parser, name, emptyTag))
3049 kumpf            1.104         {
3050 karl             1.137             resultClass.iParamFound(duplicateParameter);
3051 kumpf            1.104         }
3052 karl             1.137         else if(includeQualifiers.get(parser, name, emptyTag))
3053 kumpf            1.104         {
3054 karl             1.137             includeQualifiers.iParamFound(duplicateParameter);
3055 kumpf            1.104         }
3056 karl             1.137         else if(includeClassOrigin.get(parser, name,  emptyTag))
3057 kumpf            1.104         {
3058 karl             1.137             includeClassOrigin.iParamFound(duplicateParameter);
3059 kumpf            1.104         }
3060 karl             1.137         else if(propertyList.get(parser, name, emptyTag))
3061 kumpf            1.104         {
3062 karl             1.137             propertyList.iParamFound(duplicateParameter);
3063 kumpf            1.104         }
3064                                else
3065                                {
3066 karl             1.137             _throwCIMExceptionInvalidIParamName();
3067 kumpf            1.104         }
3068                        
3069 karl             1.137         // generate exception if endtag error or duplicate attributes
3070                                _checkMissingEndTagOrDuplicateParamValue(
3071                                    parser, duplicateParameter, emptyTag);
3072 kumpf            1.104     }
3073                        
3074 karl             1.137     _testRequiredParametersExist(objectName.got);
3075 kumpf            1.104 
3076                            AutoPtr<CIMReferencesRequestMessage> request(
3077                                new CIMReferencesRequestMessage(
3078                                    messageId,
3079                                    nameSpace,
3080 karl             1.137             objectName.value,
3081                                    resultClass.value,
3082                                    role.value,
3083                                    includeQualifiers.value,
3084                                    includeClassOrigin.value,
3085                                    propertyList.value,
3086 karl             1.135             QueueIdStack(queueId, _returnQueueId),
3087 karl             1.137             objectName.isClassNameElement));
3088 kumpf            1.104 
3089                            STAT_SERVERSTART
3090                        
3091                            return request.release();
3092                        }
3093                        
3094                        CIMAssociatorNamesRequestMessage*
3095                            CIMOperationRequestDecoder::decodeAssociatorNamesRequest(
3096                                Uint32 queueId,
3097                                XmlParser& parser,
3098                                const String& messageId,
3099                                const CIMNamespaceName& nameSpace)
3100                        {
3101                            STAT_GETSTARTTIME
3102                        
3103 karl             1.137     objectNameIParam objectName;
3104                            classNameIParam assocClass("AssocClass");
3105                            classNameIParam resultClass("ResultClass");
3106                            stringIParam role("role", false);
3107                            stringIParam resultRole("Resultrole", false);
3108                        
3109 kumpf            1.104     Boolean emptyTag;
3110 karl             1.137     Boolean duplicateParameter = false;
3111 kumpf            1.104 
3112                            for (const char* name;
3113                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3114                            {
3115 karl             1.137         if(objectName.get(parser, name, emptyTag))
3116 kumpf            1.104         {
3117 karl             1.137             objectName.iParamFound(duplicateParameter);
3118 kumpf            1.104         }
3119 karl             1.137         else if (assocClass.getOptional(parser, name, emptyTag))
3120 kumpf            1.104         {
3121 karl             1.137             assocClass.iParamFound(duplicateParameter);
3122 kumpf            1.104         }
3123 karl             1.137         else if (resultClass.getOptional(parser, name, emptyTag))
3124 kumpf            1.104         {
3125 karl             1.137             resultClass.iParamFound(duplicateParameter);
3126 kumpf            1.104         }
3127 karl             1.137         else if(role.get(parser, name, emptyTag))
3128 kumpf            1.104         {
3129 karl             1.137             role.iParamFound(duplicateParameter);
3130 kumpf            1.104         }
3131 karl             1.137         else if(resultRole.get(parser, name, emptyTag))
3132 kumpf            1.104         {
3133 karl             1.137             resultRole.iParamFound(duplicateParameter);
3134 kumpf            1.104         }
3135                                else
3136                                {
3137 karl             1.137             _throwCIMExceptionInvalidIParamName();
3138 kumpf            1.104 
3139                                }
3140                        
3141 karl             1.137         // generate exception if endtag error or duplicate attributes
3142                                _checkMissingEndTagOrDuplicateParamValue(
3143                                    parser, duplicateParameter, emptyTag);
3144 kumpf            1.104     }
3145                        
3146 karl             1.137     _testRequiredParametersExist(objectName.got);
3147 kumpf            1.104 
3148                            AutoPtr<CIMAssociatorNamesRequestMessage> request(
3149                                new CIMAssociatorNamesRequestMessage(
3150                                    messageId,
3151                                    nameSpace,
3152 karl             1.137             objectName.value,
3153                                    assocClass.value,
3154                                    resultClass.value,
3155                                    role.value,
3156                                    resultRole.value,
3157 karl             1.135             QueueIdStack(queueId, _returnQueueId),
3158 karl             1.137             objectName.isClassNameElement));
3159 kumpf            1.104 
3160                            STAT_SERVERSTART
3161                        
3162                            return request.release();
3163                        }
3164                        
3165                        CIMAssociatorsRequestMessage*
3166                            CIMOperationRequestDecoder::decodeAssociatorsRequest(
3167                                Uint32 queueId,
3168                                XmlParser& parser,
3169                                const String& messageId,
3170                                const CIMNamespaceName& nameSpace)
3171                        {
3172                            STAT_GETSTARTTIME
3173                        
3174 karl             1.137     // Associator Operation Parameters
3175                            objectNameIParam objectName;
3176                            classNameIParam assocClass("AssocClass");
3177                            classNameIParam resultClass("ResultClass");
3178                            stringIParam resultRole("Resultrole", false);
3179                            stringIParam role("role", false);
3180                            booleanIParam includeQualifiers("IncludeQualifiers");
3181                            booleanIParam includeClassOrigin("IncludeClassOrigin");
3182                            propertyListIParam propertyList;
3183                        
3184                            Boolean duplicateParameter = false;
3185 kumpf            1.104     Boolean emptyTag;
3186                        
3187                            for (const char* name;
3188                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3189                            {
3190 karl             1.137         if(objectName.get(parser, name, emptyTag))
3191 kumpf            1.104         {
3192 karl             1.137             objectName.iParamFound(duplicateParameter);
3193 kumpf            1.104         }
3194 karl             1.137         else if (assocClass.getOptional(parser, name, emptyTag))
3195 kumpf            1.104         {
3196 karl             1.137             assocClass.iParamFound(duplicateParameter);
3197 kumpf            1.104         }
3198 karl             1.137         else if (resultClass.getOptional(parser, name, emptyTag))
3199 kumpf            1.104         {
3200 karl             1.137             resultClass.iParamFound(duplicateParameter);
3201 kumpf            1.104         }
3202 karl             1.137         else if(role.get(parser, name, emptyTag))
3203 kumpf            1.104         {
3204 karl             1.137             role.iParamFound(duplicateParameter);
3205 kumpf            1.104         }
3206 karl             1.137         else if(resultRole.get(parser, name, emptyTag))
3207 kumpf            1.104         {
3208 karl             1.137             resultRole.iParamFound(duplicateParameter);
3209 kumpf            1.104         }
3210 karl             1.137         else if(includeQualifiers.get(parser, name, emptyTag))
3211 kumpf            1.104         {
3212 karl             1.137             includeQualifiers.iParamFound(duplicateParameter);
3213 kumpf            1.104         }
3214 karl             1.137         else if(includeClassOrigin.get(parser, name,  emptyTag))
3215 kumpf            1.104         {
3216 karl             1.137             includeClassOrigin.iParamFound(duplicateParameter);
3217 kumpf            1.104         }
3218 karl             1.137         else if(propertyList.get(parser, name, emptyTag))
3219 kumpf            1.104         {
3220 karl             1.137             propertyList.iParamFound(duplicateParameter);
3221 kumpf            1.104         }
3222                                else
3223                                {
3224 karl             1.137             _throwCIMExceptionInvalidIParamName();
3225 kumpf            1.104         }
3226                        
3227 karl             1.137         // generate exception if endtag error or duplicate attributes
3228                                _checkMissingEndTagOrDuplicateParamValue(
3229                                    parser, duplicateParameter, emptyTag);
3230 kumpf            1.104     }
3231                        
3232 karl             1.137     _testRequiredParametersExist(objectName.got);
3233 kumpf            1.104 
3234                            AutoPtr<CIMAssociatorsRequestMessage> request(
3235                                new CIMAssociatorsRequestMessage(
3236                                    messageId,
3237                                    nameSpace,
3238 karl             1.137             objectName.value,
3239                                    assocClass.value,
3240                                    resultClass.value,
3241                                    role.value,
3242                                    resultRole.value,
3243                                    includeQualifiers.value,
3244                                    includeClassOrigin.value,
3245                                    propertyList.value,
3246 karl             1.135             QueueIdStack(queueId, _returnQueueId),
3247 karl             1.137             objectName.isClassNameElement));
3248 kumpf            1.104 
3249                            STAT_SERVERSTART
3250                        
3251                            return request.release();
3252                        }
3253                        
3254                        CIMGetPropertyRequestMessage*
3255                            CIMOperationRequestDecoder::decodeGetPropertyRequest(
3256                                Uint32 queueId,
3257                                XmlParser& parser,
3258                                const String& messageId,
3259                                const CIMNamespaceName& nameSpace)
3260                        {
3261                            STAT_GETSTARTTIME
3262                        
3263                            CIMObjectPath instanceName;
3264                            String propertyName;
3265                            Boolean duplicateParameter = false;
3266                            Boolean gotInstanceName = false;
3267                            Boolean gotPropertyName = false;
3268                            Boolean emptyTag;
3269 kumpf            1.104 
3270                            for (const char* name;
3271                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3272                            {
3273                                if (System::strcasecmp(name, "InstanceName") == 0)
3274                                {
3275                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
3276                                    XmlReader::getInstanceNameElement(parser, instanceName);
3277                                    duplicateParameter = gotInstanceName;
3278                                    gotInstanceName = true;
3279                                }
3280                                else if (System::strcasecmp(name, "PropertyName") == 0)
3281                                {
3282                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
3283                                    XmlReader::getStringValueElement(parser, propertyName, true);
3284                                    duplicateParameter = gotPropertyName;
3285                                    gotPropertyName = true;
3286                                }
3287                                else
3288                                {
3289 karl             1.137             _throwCIMExceptionInvalidIParamName();
3290 kumpf            1.104         }
3291                        
3292 karl             1.137         // generate exception if endtag error or duplicate attributes
3293                                _checkMissingEndTagOrDuplicateParamValue(
3294                                    parser, duplicateParameter, emptyTag);
3295 kumpf            1.104     }
3296                        
3297 karl             1.137     _testRequiredParametersExist(gotInstanceName && gotPropertyName);
3298 kumpf            1.104 
3299                            AutoPtr<CIMGetPropertyRequestMessage> request(
3300                                new CIMGetPropertyRequestMessage(
3301                                    messageId,
3302                                    nameSpace,
3303                                    instanceName,
3304                                    propertyName,
3305                                    QueueIdStack(queueId, _returnQueueId)));
3306                        
3307                            STAT_SERVERSTART
3308                        
3309                            return request.release();
3310                        }
3311                        
3312                        CIMSetPropertyRequestMessage*
3313                            CIMOperationRequestDecoder::decodeSetPropertyRequest(
3314                                Uint32 queueId,
3315                                XmlParser& parser,
3316                                const String& messageId,
3317                                const CIMNamespaceName& nameSpace)
3318                        {
3319 kumpf            1.104     STAT_GETSTARTTIME
3320                        
3321                            CIMObjectPath instanceName;
3322                            String propertyName;
3323                            CIMValue propertyValue;
3324                            Boolean duplicateParameter = false;
3325                            Boolean gotInstanceName = false;
3326                            Boolean gotPropertyName = false;
3327                            Boolean gotNewValue = false;
3328                            Boolean emptyTag;
3329                        
3330                            for (const char* name;
3331                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3332                            {
3333                                if (System::strcasecmp(name, "InstanceName") == 0)
3334                                {
3335                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
3336                                    XmlReader::getInstanceNameElement(parser, instanceName);
3337                                    duplicateParameter = gotInstanceName;
3338                                    gotInstanceName = true;
3339                                }
3340 kumpf            1.104         else if (System::strcasecmp(name, "PropertyName") == 0)
3341                                {
3342                                    XmlReader::rejectNullIParamValue(parser, emptyTag, name);
3343                                    XmlReader::getStringValueElement(parser, propertyName, true);
3344                                    duplicateParameter = gotPropertyName;
3345                                    gotPropertyName = true;
3346                                }
3347                                else if (System::strcasecmp(name, "NewValue") == 0)
3348                                {
3349                                    if (emptyTag || !XmlReader::getPropertyValue(parser, propertyValue))
3350                                    {
3351                                        propertyValue.setNullValue(CIMTYPE_STRING, false);
3352                                    }
3353                                    duplicateParameter = gotNewValue;
3354                                    gotNewValue = true;
3355                                }
3356                                else
3357                                {
3358 karl             1.137             _throwCIMExceptionInvalidIParamName();
3359 kumpf            1.104         }
3360                        
3361 karl             1.137         // generate exception if endtag error or duplicate attributes
3362                                _checkMissingEndTagOrDuplicateParamValue(
3363                                    parser, duplicateParameter, emptyTag);
3364 kumpf            1.104     }
3365                        
3366 karl             1.137     _testRequiredParametersExist(gotInstanceName && gotPropertyName);
3367 kumpf            1.104 
3368                            AutoPtr<CIMSetPropertyRequestMessage> request(
3369                                new CIMSetPropertyRequestMessage(
3370                                    messageId,
3371                                    nameSpace,
3372                                    instanceName,
3373                                    propertyName,
3374                                    propertyValue,
3375                                    QueueIdStack(queueId, _returnQueueId)));
3376 kumpf            1.29  
3377 kumpf            1.104     STAT_SERVERSTART
3378 sage             1.41  
3379 kumpf            1.104     return request.release();
3380 kumpf            1.29  }
3381                        
3382                        CIMExecQueryRequestMessage* CIMOperationRequestDecoder::decodeExecQueryRequest(
3383 kumpf            1.104     Uint32 queueId,
3384                            XmlParser& parser,
3385                            const String& messageId,
3386                            const CIMNamespaceName& nameSpace)
3387                        {
3388                            STAT_GETSTARTTIME
3389                        
3390 karl             1.137     // define execQuery parameters.  Values are required parameters exist.
3391                            stringIParam queryLanguage("QueryLanguage", true);
3392                            stringIParam query("Query", true);
3393                        
3394                            Boolean emptyTag;
3395 kumpf            1.104     Boolean duplicateParameter = false;
3396                        
3397                            for (const char* name;
3398                                 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3399                            {
3400 karl             1.137         if(queryLanguage.get(parser, name, emptyTag))
3401 kumpf            1.104         {
3402 karl             1.137             queryLanguage.iParamFound(duplicateParameter);
3403 kumpf            1.104         }
3404 karl             1.137         else if(query.get(parser, name, emptyTag))
3405 kumpf            1.104         {
3406 karl             1.137             query.iParamFound(duplicateParameter);
3407 kumpf            1.104         }
3408                                else
3409                                {
3410 karl             1.137             _throwCIMExceptionInvalidIParamName();
3411 kumpf            1.104         }
3412                        
3413 karl             1.137         // generate exception if endtag error or duplicate attributes
3414                                _checkMissingEndTagOrDuplicateParamValue(parser,
3415                                    duplicateParameter, emptyTag);
3416 kumpf            1.104     }
3417                        
3418 karl             1.137     _testRequiredParametersExist(queryLanguage.got && query.got);
3419 kumpf            1.104 
3420                            AutoPtr<CIMExecQueryRequestMessage> request(
3421                                new CIMExecQueryRequestMessage(
3422                                    messageId,
3423                                    nameSpace,
3424 karl             1.137             queryLanguage.value,
3425                                    query.value,
3426 kumpf            1.104             QueueIdStack(queueId, _returnQueueId)));
3427                        
3428                            STAT_SERVERSTART
3429                        
3430                            return request.release();
3431                        }
3432                        
3433                        CIMInvokeMethodRequestMessage*
3434                            CIMOperationRequestDecoder::decodeInvokeMethodRequest(
3435                                Uint32 queueId,
3436                                XmlParser& parser,
3437                                const String& messageId,
3438                                const CIMObjectPath& reference,
3439                                const String& cimMethodName)
3440                        {
3441                            STAT_GETSTARTTIME
3442                        
3443                            CIMParamValue paramValue;
3444                            Array<CIMParamValue> inParameters;
3445                        
3446                            while (XmlReader::getParamValueElement(parser, paramValue))
3447 kumpf            1.104     {
3448                                inParameters.append(paramValue);
3449                            }
3450                        
3451                            AutoPtr<CIMInvokeMethodRequestMessage> request(
3452                                new CIMInvokeMethodRequestMessage(
3453                                    messageId,
3454                                    reference.getNameSpace(),
3455                                    reference,
3456                                    cimMethodName,
3457                                    inParameters,
3458                                    QueueIdStack(queueId, _returnQueueId)));
3459 kumpf            1.9   
3460 kumpf            1.104     STAT_SERVERSTART
3461 mike             1.2   
3462 kumpf            1.104     return request.release();
3463 mike             1.2   }
3464                        
3465                        void CIMOperationRequestDecoder::setServerTerminating(Boolean flag)
3466                        {
3467 kumpf            1.104     _serverTerminating = flag;
3468 mike             1.2   }
3469                        
3470                        PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2