Exemplo n.º 1
0
static void _initConfigProperty(const String &propName, Uint32 value)
{
    char strValue[22];
    Uint32 n;
    const char *startP = Uint32ToString(
        strValue,
        value,
        n);
    ConfigManager::getInstance()->initCurrentValue(propName, String(startP, n));
}
Exemplo n.º 2
0
PEGASUS_NAMESPACE_BEGIN

////////////////////////////////////////////////////////////////////////////////
//
// Local routines:
//
////////////////////////////////////////////////////////////////////////////////

#ifdef PEGASUS_ENABLE_IPV6
static Boolean _MakeAddress(
    const char* hostname,
    int port,
    void **addrInfoRoot)
{
    if (!hostname)
        return false;

    struct sockaddr_in6 serveraddr;
    struct addrinfo  hints;
    struct addrinfo *result;

    memset(&hints, 0x00, sizeof(hints));
    hints.ai_family   = AF_UNSPEC ;
    hints.ai_socktype = SOCK_STREAM;

    // Giving hint as AI_NUMERICHOST to the getaddrinfo function avoids
    // name resolution done by getaddrinfo at DNS. This will improve
    // performance.

    // Check for valid IPv4 address.
    if (1 == HostAddress::convertTextToBinary(AF_INET, hostname, &serveraddr))
    {
        hints.ai_family = AF_INET;
        hints.ai_flags |= AI_NUMERICHOST;
    } // check for valid IPv6 address
    else if (1 == HostAddress::convertTextToBinary(AF_INET6, hostname,
         &serveraddr))
    {
        hints.ai_family = AF_INET6;
        hints.ai_flags |= AI_NUMERICHOST;
    }

    char scratch[22];
    Uint32 n;
    const char * portStr = Uint32ToString(scratch, port, n);
    if (System::getAddrInfo(hostname, portStr, &hints, &result))
    {
        return false;
    }
    *addrInfoRoot = result;
    return true;
}
Exemplo n.º 3
0
String ConfigFileSyntaxError::_formatMessage(
    const String& file,
    Uint32 line)
{
    char buffer[22];
    Uint32 n;
    const char * startNum=Uint32ToString(buffer,line,n);

    MessageLoaderParms parms(
        "Config.ConfigExceptions.CONFIG_FILE_SYNTAX_ERR",
        "Syntax error in configuration file: ");
    String result = MessageLoader::getMessage(parms);
    result.append(file);
    result.append("(");
    result.append(startNum,n);
    result.append(")");
    return result;
}
String ProviderIndicationCountTable::_generateKey(
    const String& providerModuleName,
    const String& providerName)
{
    PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
        "ProviderIndicationCountTable::_generateKey");

    String providerIndicationCountKey(providerName);
    providerIndicationCountKey.append(providerModuleName);
    providerIndicationCountKey.append(":");

    char buffer[22];
    Uint32 length;
    const char* providerNameSize =
        Uint32ToString(buffer, providerName.size(), length);
    providerIndicationCountKey.append(providerNameSize, length);

    PEG_METHOD_EXIT();
    return providerIndicationCountKey;
}
Exemplo n.º 5
0
int CIMServerProcess::cimserver_run(
    int argc,
    char** argv,
    Boolean shutdownOption,
    Boolean debugOutputOption)
{
    Boolean daemonOption = false;

#if defined (PEGASUS_OS_PASE) && !defined (PEGASUS_DEBUG)
    // PASE have itself regular for checking privileged user
    if (!System::isPrivilegedUser("*CURRENT  "))
    {
        MessageLoaderParms parms(
                "src.Server.cimserver.NO_AUTHORITY.PEGASUS_OS_PASE",
                "The caller should be a privileged user,"
                " or the server will not run.");
        cerr << MessageLoader::getMessage(parms) << endl;
        exit (1);
    }
    char jobName[11];
    // this function only can be found in PASE environment
    umeGetJobName(jobName, false);
    if (strncmp("QUMECIMOM ", jobName, 10) != 0
            && strncmp("QUMEENDCIM", jobName, 10) != 0)
    {
        MessageLoaderParms parms(
                "src.Server.cimserver.NOT_OFFICIAL_START.PEGASUS_OS_PASE",
                "cimserver can not be started by user.\nServer will not run.");
        cerr << MessageLoader::getMessage(parms) << endl;
        exit (1);
    }

    // Direct standard input, output, and error to /dev/null,
    // PASE run this job in background, any output in not allowed
    freopen("/dev/null", "r", stdin);
    freopen("/dev/null", "w", stdout);
    freopen("/dev/null", "w", stderr);
#endif

    //
    // Get an instance of the Config Manager.
    //
    ConfigManager* configManager = ConfigManager::getInstance();
    configManager->useConfigFiles = true;

    try
    {
        //
        // Get options (from command line and from configuration file); this
        // removes corresponding options and their arguments from the command
        // line.  NOTE: If shutdownOption=true, the contents of current config
        // file are not overwritten by the planned config file.
        //
        GetOptions(configManager, argc, argv, shutdownOption);

        //
        // Initialize the message home directory in the MessageLoader.
        // This is the default directory where the resource bundles are found.
        //
        MessageLoader::setPegasusMsgHome(ConfigManager::getHomedPath(
            ConfigManager::getInstance()->getCurrentValue("messageDir")));

#if !defined(PEGASUS_USE_SYSLOGS)
        String logsDirectory = ConfigManager::getHomedPath(
            configManager->getCurrentValue("logdir"));

        // Set up the Logger.  This does not open the logs.
        // Might be more logical to clean before set.
        Logger::setHomeDirectory(logsDirectory);
#endif


#ifdef PEGASUS_OS_PASE
        /* write job log to tell where pegasus log is.*/
        if(logsDirectory.size() > 0)
            // this function only can be found in PASE environment
            logPegasusDir2joblog(logsDirectory.getCString());
        else
            logPegasusDir2joblog(".");

        // set ccsid to unicode for entire job
        // ccsid is globolization mechanism in PASE environment
        if (_SETCCSID(1208) == -1)
        {
            MessageLoaderParms parms(
                    "src.Server.cimserver.SET_CCSID_ERROR.PEGASUS_OS_PASE",
                    "Failed to set CCSID, server will stop.");
            cerr << MessageLoader::getMessage(parms) << endl;
            Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::FATAL,
                    parms);
            exit (1);
        }

        char fullJobName[29];
        umeGetJobName(fullJobName, true);
        Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
                Logger::INFORMATION,
                MessageLoaderParms(
                    "src.Server.cimserver.SERVER_JOB_NAME.PEGASUS_OS_PASE",
                    "CIM Server's Job Name is: $0", fullJobName));
#endif

#ifdef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
        // Make sure at least one connection is enabled

        Boolean enableHttpConnection = ConfigManager::parseBooleanValue(
            configManager->getCurrentValue("enableHttpConnection"));
        Boolean enableHttpsConnection = ConfigManager::parseBooleanValue(
            configManager->getCurrentValue("enableHttpsConnection"));

        if (!enableHttpConnection && !enableHttpsConnection)
        {
            MessageLoaderParms parms(
                "src.Server.cimserver.HTTP_NOT_ENABLED_SERVER_NOT_STARTING",
                "Neither HTTP nor HTTPS connection is enabled."
                    "  CIMServer will not be started.");
            Logger::put_l(
                Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
                parms);
            cerr << MessageLoader::getMessage(parms) << endl;
            return 1;
        }
#endif

        //
        // Check to see if we should start Pegasus as a daemon
        //
        daemonOption = ConfigManager::parseBooleanValue(
            configManager->getCurrentValue("daemon"));

        if ((Executor::detectExecutor() == 0) && (daemonOption == false))
        {
            MessageLoaderParms parms(
                "src.Server.cimserver.PRIVSEP_REQUIRES_DAEMON",
                "Warning: The configuration setting daemon=false is ignored "
                    "with privilege separation enabled.");
            cerr << MessageLoader::getMessage(parms) << endl;
            daemonOption = true;
        }

        //
        // Check to see if we need to shutdown CIMOM
        //
        if (shutdownOption)
        {
#if defined(PEGASUS_OS_ZOS) && defined(PEGASUS_ZOS_SECURITY)
            // This checks whether user is authorized to stop the
            // CIM Server. When unauthorized a message is logged to
            // to the user and program exits.
            shutdownCheckProfileCIMSERVclassWBEM();
            // Depending on the success of the previous check we may not
            // reach this code!!!
#endif
            String configTimeout =
                configManager->getCurrentValue("shutdownTimeout");
            Uint32 timeoutValue =
                strtol(configTimeout.getCString(), (char **)0, 10);

            ServerShutdownClient serverShutdownClient(&_serverRunStatus);
            serverShutdownClient.shutdown(timeoutValue);

            MessageLoaderParms parms(
                "src.Server.cimserver.SERVER_STOPPED",
                "CIM Server stopped.");

            cout << MessageLoader::getMessage(parms) << endl;
            return 0;
        }

#if defined(PEGASUS_DEBUG) && !defined(PEGASUS_USE_SYSLOGS)
        // Leave this in until people get familiar with the logs.
        MessageLoaderParms parms("src.Server.cimserver.LOGS_DIRECTORY",
                                 "Logs Directory = ");
        cout << MessageLoader::getMessage(parms) << logsDirectory << endl;
#endif
    }
    catch (Exception& e)
    {
        MessageLoaderParms parms("src.Server.cimserver.SERVER_NOT_STARTED",
            "cimserver not started: $0", e.getMessage());
        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
            parms);
        cerr << MessageLoader::getMessage(parms) << endl;

        return 1;
    }

#if defined(PEGASUS_OS_ZOS) 
#  if defined(PEGASUS_ZOS_SECURITY)
    startupCheckBPXServer(true);
    startupCheckProfileCIMSERVclassWBEM();
    startupEnableMSC();
#  endif
    startupWaitForTCPIP();
#endif

#if defined(PEGASUS_DEBUG)
    // Put out startup up message.
    cout << _cimServerProcess->getProductName() << " " <<
        _cimServerProcess->getCompleteVersion() << endl;
#endif

    // Force initialization of hostname and fullyQualifiedHostName through
    // retrieving current value from Configuration Manager
    // - this will run getCurrentValue() in DefaultPropertyOwner.cpp
    configManager->getCurrentValue("hostname");
    configManager->getCurrentValue("fullyQualifiedHostName");

    // reset message loading to NON-process locale
    MessageLoader::_useProcessLocale = false;

    // Get the parent's PID before forking
    _serverRunStatus.setParentPid(System::getPID());

    // Do not fork when using privilege separation (executor will daemonize
    // itself later).
    if (daemonOption)
    {
        if (-1 == _cimServerProcess->cimserver_fork())
            return -1;
    }

    // Now we are after the fork...
    // Create a dummy Thread object that can be used to store the
    // AcceptLanguageList object for CIM requests that are serviced
    // by this thread (initial thread of server).  Need to do this
    // because this thread is not in a ThreadPool, but is used
    // to service CIM requests.
    // The run function for the dummy Thread should never be called,
    dummyInitialThread = new Thread(dummyThreadFunc, NULL, false);
    Thread::setCurrent(dummyInitialThread);
    try
    {
        Thread::setLanguages(LanguageParser::getDefaultAcceptLanguages());
    }
    catch (InvalidAcceptLanguageHeader& e)
    {
        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
            MessageLoaderParms(
                "src.Server.cimserver.FAILED_TO_SET_PROCESS_LOCALE",
                "Could not convert the system process locale into a valid "
                    "AcceptLanguage format."));
        Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
            e.getMessage());
    }

#ifndef PEGASUS_OS_TYPE_WINDOWS
    umask(S_IRWXG|S_IRWXO);
#endif

    // Start up the CIM Server

    try
    {
#if defined(PEGASUS_OS_TYPE_UNIX)
        //
        // Lock the CIMSERVER_LOCK_FILE during CIM Server start-up to prevent
        // concurrent writes to this file by multiple cimserver processes
        // starting at the same time.
        //
        CString startupLockFileName = ConfigManager::getHomedPath(
            PEGASUS_CIMSERVER_START_LOCK_FILE).getCString();

        // Make sure the start-up lock file exists
        FILE* startupLockFile;
        if ((startupLockFile = fopen(startupLockFileName, "w")) != 0)
        {
            fclose(startupLockFile);
        }

        AutoFileLock fileLock(startupLockFileName);
#endif

#if defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VMS)
        //
        // Check if a CIM Server is already running.  If so, print an error
        // message and notify the parent process (if there is one) to terminate
        //
        if (_serverRunStatus.isServerRunning())
        {
            MessageLoaderParms parms(
                "src.Server.cimserver.UNABLE_TO_START_SERVER_ALREADY_RUNNING",
                "Unable to start CIMServer. CIMServer is already running.");
            Logger::put_l(
                Logger::ERROR_LOG, System::CIMSERVER, Logger::INFORMATION,
                parms);
            cerr << MessageLoader::getMessage(parms) << endl;

            if (daemonOption)
            {
                _cimServerProcess->notify_parent(1);
            }

            return 1;
        }

        //
        // Declare ourselves as the running CIM Server process, and write our
        // PID to the PID file.
        //
        _serverRunStatus.setServerRunning();
#endif

        // Create and initialize the CIMServer object

        _cimServer = new CIMServer();

        Boolean enableHttpConnection = ConfigManager::parseBooleanValue(
            configManager->getCurrentValue("enableHttpConnection"));
        Boolean enableHttpsConnection = ConfigManager::parseBooleanValue(
            configManager->getCurrentValue("enableHttpsConnection"));

#ifdef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
        // Make sure at least one connection is enabled
        if (!enableHttpConnection && !enableHttpsConnection)
        {
            MessageLoaderParms parms(
                "src.Server.cimserver.HTTP_NOT_ENABLED_SERVER_NOT_STARTING",
                "Neither HTTP nor HTTPS connection is enabled.");
            throw Exception(parms);
        }
#endif

        Boolean addIP6Acceptor = false;
        Boolean addIP4Acceptor = false;

#ifdef PEGASUS_OS_TYPE_WINDOWS
        addIP4Acceptor = true;
#endif

#ifdef PEGASUS_ENABLE_IPV6
        // If IPv6 stack is disabled swicth to IPv4 stack.
        if (System::isIPv6StackActive())
        {
            addIP6Acceptor = true;
        }
        else
        {
            PEG_TRACE_CSTRING(TRC_SERVER,Tracer::LEVEL4,
                "IPv6 stack is not active, using IPv4 socket.");
        }
#endif
        if (!addIP6Acceptor)
        {
            addIP4Acceptor = true;
        }

        // The server HTTP and HTTPS ports are determined via this algorithm:
        // 1) If the user explicitly specified a port, use it.
        // 2) If the user did not specify a port, get the port from the
        //    services file.
        // 3) If no value is specified in the services file, use the IANA WBEM
        //    default port.
        // Note that 2 and 3 are done within the System::lookupPort method
        // An empty string from the ConfigManager implies that the user did not
        // specify a port.

        if (enableHttpConnection)
        {
            Uint32 portNumberHttp = 0;
            String httpPort = configManager->getCurrentValue("httpPort");
            if (httpPort.size() == 0)
            {
                //
                // Look up the WBEM-HTTP port number
                //
                portNumberHttp = System::lookupPort(
                    WBEM_HTTP_SERVICE_NAME, WBEM_DEFAULT_HTTP_PORT);
                _initConfigProperty("httpPort", portNumberHttp);
            }
            else
            {
                Uint64 longNumber;
                // use the current value which has been checked for validity at
                // load(fct. GetOptions), see DefaultPropertyOwner::isValid()
                StringConversion::decimalStringToUint64(
                    httpPort.getCString(),
                    longNumber);
                portNumberHttp = longNumber & 0xffff;
            }

            String listenOn = configManager->getCurrentValue("listenAddress");
            if(String::equalNoCase(listenOn, "All"))
            {
                if (addIP6Acceptor)
                {
                    _cimServer->addAcceptor(HTTPAcceptor::IPV6_CONNECTION,
                        portNumberHttp, false);
                }
                if (addIP4Acceptor)
                {
                    _cimServer->addAcceptor(HTTPAcceptor::IPV4_CONNECTION,
                        portNumberHttp, false);
                }
            }
            else // Restricted listening
            {
                _restrictListening(
                    configManager, listenOn, portNumberHttp, false);
            }

            // The port number is converted to a string to avoid the
            //  addition of localized characters (e.g., "5,988").
            char scratchBuffer[22];
            Uint32 n;
            const char * portNumberHttpStr = Uint32ToString(
                scratchBuffer, portNumberHttp, n);
            MessageLoaderParms parms(
                "src.Server.cimserver.LISTENING_ON_HTTP_PORT",
                "Listening on HTTP port $0.", portNumberHttpStr);
            Logger::put_l(
                Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
                parms);
#if defined(PEGASUS_DEBUG)
            cout << MessageLoader::getMessage(parms) << endl;
#endif
        }

        if (enableHttpsConnection)
        {
            Uint32 portNumberHttps = 0;
            String httpsPort = configManager->getCurrentValue("httpsPort");
            if (httpsPort.size() == 0)
            {
                //
                // Look up the WBEM-HTTPS port number
                //
                portNumberHttps = System::lookupPort(
                    WBEM_HTTPS_SERVICE_NAME, WBEM_DEFAULT_HTTPS_PORT);
                _initConfigProperty("httpsPort", portNumberHttps);
            }
            else
            {
                Uint64 longNumber;
                // use the current value which has been checked for validity at
                // load(fct. GetOptions), see DefaultPropertyOwner::isValid()
                StringConversion::decimalStringToUint64(
                    httpsPort.getCString(),
                    longNumber);
                portNumberHttps = longNumber & 0xffff;
            }

            String listenOn = configManager->getCurrentValue("listenAddress");
            if(String::equalNoCase(listenOn, "All"))
            {
                if (addIP6Acceptor)
                {
                    _cimServer->addAcceptor(HTTPAcceptor::IPV6_CONNECTION,
                        portNumberHttps, true);
                }
                if (addIP4Acceptor)
                {
                    _cimServer->addAcceptor(HTTPAcceptor::IPV4_CONNECTION,
                        portNumberHttps, true);
                }
            }
            else //Restricted
            {
                _restrictListening(
                    configManager, listenOn, portNumberHttps, true);
            }

            // The port number is converted to a string to avoid the
            //  addition of localized characters (e.g., "5,989").
            char scratchBuffer[22];
            Uint32 n;
            const char * portNumberHttpsStr = Uint32ToString(
                scratchBuffer, portNumberHttps, n);
            MessageLoaderParms parms(
                "src.Server.cimserver.LISTENING_ON_HTTPS_PORT",
                "Listening on HTTPS port $0.", portNumberHttpsStr);
            Logger::put_l(
                Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
                parms);
#if defined(PEGASUS_DEBUG)
            cout << MessageLoader::getMessage(parms) << endl;
#endif
        }

#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
        {
            _cimServer->addAcceptor(HTTPAcceptor::LOCAL_CONNECTION, 0, false);

            MessageLoaderParms parms(
                "src.Server.cimserver.LISTENING_ON_LOCAL",
                "Listening on local connection socket.");
            Logger::put_l(
                Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
                parms);
# if defined(PEGASUS_DEBUG)
            cout << MessageLoader::getMessage(parms) << endl;
# endif
        }
#endif

        _cimServer->bind();

        // notify parent process (if there is a parent process) to terminate
        // so user knows that there is cimserver ready to serve CIM requests.
        if (daemonOption)
        {
            _cimServerProcess->notify_parent(0);
        }

#if defined(PEGASUS_DEBUG)
        cout << "Started. " << endl;
#endif

        // Put server started message to the logger
        Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
            Logger::INFORMATION,
            MessageLoaderParms(
                "src.Server.cimserver.STARTED_VERSION",
                "Started $0 version $1.",
                _cimServerProcess->getProductName(),
                _cimServerProcess->getCompleteVersion()));

#if defined(PEGASUS_OS_TYPE_UNIX) && !defined(PEGASUS_OS_ZOS)
        if (daemonOption && !debugOutputOption)
        {
            // Direct standard input, output, and error to /dev/null,
            // since we are running as a daemon.
            close(STDIN_FILENO);
            open("/dev/null", O_RDONLY);
            close(STDOUT_FILENO);
            open("/dev/null", O_RDWR);
            close(STDERR_FILENO);
            open("/dev/null", O_RDWR);
        }
#endif
    }
    catch (Exception& e)
    {
        MessageLoaderParms parms("src.Server.cimserver.SERVER_NOT_STARTED",
            "cimserver not started: $0", e.getMessage());
        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
            parms);
        cerr << MessageLoader::getMessage(parms) << endl;

        deleteCIMServer();

        //
        // notify parent process (if there is a parent process) to terminate
        //
        if (daemonOption)
            _cimServerProcess->notify_parent(1);

        return 1;
    }

    // Run the main CIM Server loop

    try
    {
#if defined(PEGASUS_OS_ZOS)

        // ARM is a z/OS internal restart facility.
        // This is a z/OS specific change.

        // Instatiating the automatic restart manager for zOS
        ARM_zOS automaticRestartManager;

        // register to zOS ARM
        automaticRestartManager.Register();

#endif

#ifdef PEGASUS_ENABLE_SLP
        _cimServer->startSLPProvider();
#endif
        _cimServer->initComplete();

        //
        // Loop to call CIMServer's runForever() method until CIMServer
        // has been shutdown
        //
        while (!_cimServer->terminated())
        {
            _cimServer->runForever();
        }

        //
        // normal termination
        //

#if defined(PEGASUS_OS_ZOS)

        // ARM is a z/OS internal restart facility.
        // This is a z/OS specific change.

        // register to zOS ARM
        automaticRestartManager.DeRegister();

#endif

        // Put server shutdown message to the logger
        Logger::put_l(
            Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
            MessageLoaderParms(
                "src.Server.cimserver.STOPPED",
                "$0 stopped.", _cimServerProcess->getProductName()));
    }
    catch (Exception& e)
    {
        MessageLoaderParms parms(
            "src.Server.cimserver.ERROR",
            "Error: $0",
            e.getMessage());
        Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
            parms);
        cerr << MessageLoader::getMessage(parms) << endl;

        deleteCIMServer();
        return 1;
    }

    deleteCIMServer();
    return 0;
}
Exemplo n.º 6
0
HTTPConnection* HTTPConnector::connect(
    const String& host,
    const Uint32 portNumber,
    SSLContext * sslContext,
    Uint32 timeoutMilliseconds,
    MessageQueue* outputMessageQueue)
{
    PEG_METHOD_ENTER(TRC_HTTP, "HTTPConnector::connect()");

#ifdef PEGASUS_OS_PASE
    AutoPtr<PaseCcsid> ccsid;
#endif

    SocketHandle socket = PEGASUS_INVALID_SOCKET;
    // Use an AutoPtr to ensure the socket handle is closed on exception
    AutoPtr<SocketHandle, CloseSocketHandle> socketPtr(&socket);

#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
    if (0 == host.size())
    {
        // Set up the domain socket for a local connection

        sockaddr_un address;

#ifdef PEGASUS_OS_PASE
        // PASE needs ccsid 819 to perform domain socket operation
        int orig_ccsid;
        orig_ccsid = _SETCCSID(-1);
        if (orig_ccsid == -1)
        {
            PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                    "HTTPConnector::connect() Can not get current PASE CCSID.");
            orig_ccsid = 1208;
        }
        ccsid.reset(new PaseCcsid(819, orig_ccsid));
#endif

        memset(&address, 0, sizeof(address));
        address.sun_family = AF_UNIX;
        strcpy(address.sun_path, PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);

        socket = Socket::createSocket(AF_UNIX, SOCK_STREAM, 0);
        if (socket == PEGASUS_INVALID_SOCKET)
        {
            PEG_METHOD_EXIT();
            throw CannotCreateSocketException();
        }

        Socket::disableBlocking(socket);

        // Connect the socket to the address:

        if (!Socket::timedConnect(
                socket,
                reinterpret_cast<sockaddr*>(&address),
                sizeof(address),
                timeoutMilliseconds))
        {
            MessageLoaderParms parms(
                "Common.HTTPConnector.CONNECTION_FAILED_LOCAL_CIM_SERVER",
                "Cannot connect to local CIM server. Connection failed.");
            PEG_METHOD_EXIT();
            throw CannotConnectException(parms);
        }
    }
    else
#endif
    {
        // Set up the IP socket connection

        // Make the internet address:
#ifdef PEGASUS_ENABLE_IPV6
        struct addrinfo *addrInfo, *addrInfoRoot = NULL;
#else
        sockaddr_in address;
#endif
#ifdef PEGASUS_ENABLE_IPV6
        if (!_MakeAddress(
                 (const char*)host.getCString(),
                 portNumber,
                 (void**)(void*)&addrInfoRoot))
#else
        if (!_MakeAddress((const char*)host.getCString(), portNumber, address))
#endif
        {
            char scratch[22];
            Uint32 n;
            const char * portStr = Uint32ToString(scratch, portNumber, n);
            PEG_METHOD_EXIT();
            throw InvalidLocatorException(host+":"+String(portStr,n));
        }

#ifdef PEGASUS_ENABLE_IPV6
        addrInfo = addrInfoRoot;
        while (addrInfo)
        {
            // Create the socket:
            socket = Socket::createSocket(addrInfo->ai_family,
                addrInfo->ai_socktype, addrInfo->ai_protocol);
#else
            socket = Socket::createSocket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#endif
            if (socket == PEGASUS_INVALID_SOCKET)
            {
#ifdef PEGASUS_ENABLE_IPV6
                freeaddrinfo(addrInfoRoot);
#endif
                PEG_METHOD_EXIT();
                throw CannotCreateSocketException();
            }

#ifndef PEGASUS_OS_TYPE_WINDOWS
            // We need to ensure that the socket number is not higher than
            // what fits into FD_SETSIZE,because we else won't be able to select
            // on it and won't ever communicate correct on that socket.
            if (socket >= FD_SETSIZE)
            {
# ifdef PEGASUS_ENABLE_IPV6
                freeaddrinfo(addrInfoRoot);
# endif
                // the socket is useless to us, close it
                Socket::close(socket);

                PEG_TRACE(
                    (TRC_DISCARDED_DATA,
                     Tracer::LEVEL1,
                     "createSocket() returned too large socket number %d."
                         "Cannot connect to %s:%d. Connection failed.",
                     socket,
                     (const char*) host.getCString(),
                     portNumber));

                PEG_METHOD_EXIT();
                throw CannotCreateSocketException();
    }
#endif

            Socket::disableBlocking(socket);

            // Connect the socket to the address:
            if (!Socket::timedConnect(
                    socket,
#ifdef PEGASUS_ENABLE_IPV6
                    reinterpret_cast<sockaddr*>(addrInfo->ai_addr),
                    addrInfo->ai_addrlen,
#else
                    reinterpret_cast<sockaddr*>(&address),
                    sizeof(address),
#endif
                    timeoutMilliseconds))
            {
#ifdef PEGASUS_ENABLE_IPV6
                addrInfo = addrInfo->ai_next;
                if (addrInfo)
                {
                    Socket::close(socket);
                    continue;
                }
#endif
                char scratch[22];
                Uint32 n;
                const char * portStr = Uint32ToString(scratch, portNumber, n);
                MessageLoaderParms parms(
                    "Common.HTTPConnector.CONNECTION_FAILED_TO",
                    "Cannot connect to $0:$1. Connection failed.",
                    host,
                    portStr);
#ifdef PEGASUS_ENABLE_IPV6
                freeaddrinfo(addrInfoRoot);
#endif
                PEG_METHOD_EXIT();
                throw CannotConnectException(parms);
            }
#ifdef PEGASUS_ENABLE_IPV6
            break;
        }
        freeaddrinfo(addrInfoRoot);
#endif
    }

    // Create HTTPConnection object:

    SharedPtr<MP_Socket> mp_socket(new MP_Socket(socket, sslContext, 0));
    // mp_socket now has responsibility for closing the socket handle
    socketPtr.release();

    if (mp_socket->connect(timeoutMilliseconds) < 0)
    {
        char scratch[22];
        Uint32 n;
        const char * portStr = Uint32ToString(scratch, portNumber, n);
        MessageLoaderParms parms(
            "Common.HTTPConnector.CONNECTION_FAILED_TO",
            "Cannot connect to $0:$1. Connection failed.",
            host,
            portStr);
        PEG_METHOD_EXIT();
        throw CannotConnectException(parms);
    }

    AutoPtr<HTTPConnection> connection(new HTTPConnection(
        _monitor,
        mp_socket,
        String::EMPTY,
        0,
        outputMessageQueue));

    // Solicit events on this new connection's socket:
    int index;

    if (-1 == (index = _monitor->solicitSocketMessages(
            connection->getSocket(),
            connection->getQueueId(), MonitorEntry::TYPE_CONNECTION)))
    {
        PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
            "HTTPConnector::connect: Attempt to allocate entry in "
                "_entries table failed.");
        (connection->getMPSocket()).close();
    }

    connection->_entry_index = index;
    _rep->connections.append(connection.get());
    PEG_METHOD_EXIT();
    return connection.release();
}
PEGASUS_NAMESPACE_BEGIN

/*****************************************************************************
 *
 * The following are constants representing property names for the classes
 * managed by the Interop Provider. Where multiple classes have properties of
 * the same name, there will be a common CIMName object defined, and a macro
 * defined that points to the common CIMName object, but whose macro name
 * reflects the class in which the property is used.
 *
 *****************************************************************************/

//
// Constructor for the InteropProvider control provider
//
InteropProvider::InteropProvider(CIMRepository * rep) : repository(rep),
    hostName(System::getHostName()), providerInitialized(false),
    updateProfileCache(0),
    profileIds(Array<String>()), conformingElements(Array<CIMNameArray>()),
    elementNamespaces(Array<CIMNamespaceArray>())
{
    PEG_METHOD_ENTER(TRC_CONTROLPROVIDER,"InteropProvider::InteropProvider");

    ConfigManager *configManager = ConfigManager::getInstance();
#ifdef PEGASUS_ENABLE_SLP
    enableSLP = ConfigManager::parseBooleanValue(
        configManager->getCurrentValue("slp"));
#else
    enableSLP = false;
#endif

    httpPort = configManager->getCurrentValue("httpPort");
    if (httpPort.size() == 0)
    {
        Uint32 portNumberHttp = System::lookupPort(
            WBEM_HTTP_SERVICE_NAME, WBEM_DEFAULT_HTTP_PORT);
        char buffer[32];
        Uint32 n;
        const char *output = Uint32ToString(buffer, portNumberHttp, n);
        httpPort.assign(output, n);
    }

    httpsPort = configManager->getCurrentValue("httpsPort");
    if (httpsPort.size() == 0)
    {
        Uint32 portNumberHttps = System::lookupPort(
            WBEM_HTTPS_SERVICE_NAME, WBEM_DEFAULT_HTTPS_PORT);
        char buffer[32];
        Uint32 n;
        const char *output = Uint32ToString(buffer, portNumberHttps, n);
        httpsPort.assign(output, n);
    }


#ifndef PEGASUS_DISABLE_PERFINST
    try
    {
        initProvider();
    }
    catch(const Exception &)
    {
        // Provider initialization may fail if the repository is not
        // populated
    }
#endif

    PEG_METHOD_EXIT();
}
Exemplo n.º 8
0
PEGASUS_NAMESPACE_BEGIN

////////////////////////////////////////////////////////////////////////////////
//
// Local routines:
//
////////////////////////////////////////////////////////////////////////////////

static Boolean _MakeAddress(
    const char* hostname,
    int port,
    sockaddr_in& address,
    void **addrInfoRoot)
{
    if (!hostname)
        return false;

#ifdef PEGASUS_ENABLE_IPV6
    struct sockaddr_in6 serveraddr;
    struct addrinfo  hints;
    struct addrinfo *result;

    memset(&hints, 0x00, sizeof(hints));
    hints.ai_family   = AF_UNSPEC ;
    hints.ai_socktype = SOCK_STREAM;

    // Giving hint as AI_NUMERICHOST to the getaddrinfo function avoids
    // name resolution done by getaddrinfo at DNS. This will improve
    // performance.

    // Check for valid IPv4 address.
    if (1 == HostAddress::convertTextToBinary(AF_INET, hostname, &serveraddr))
    {
        hints.ai_family = AF_INET;
        hints.ai_flags |= AI_NUMERICHOST;
    } // check for valid IPv6 address
    else if (1 == HostAddress::convertTextToBinary(AF_INET6, hostname,
         &serveraddr))
    {
        hints.ai_family = AF_INET6;
        hints.ai_flags |= AI_NUMERICHOST;
    }

    char scratch[22];
    Uint32 n;
    const char * portStr = Uint32ToString(scratch, port, n);
    if (System::getAddrInfo(hostname, portStr, &hints, &result))
    {
        return false;
    }
    *addrInfoRoot = result;
#else

////////////////////////////////////////////////////////////////////////////////
// This code used to check if the first character of "hostname" was alphabetic
// to indicate hostname instead of IP address. But RFC 1123, section 2.1,
// relaxed this requirement to alphabetic character *or* digit. So bug 1462
// changed the flow here to call inet_addr first to check for a valid IP
// address in dotted decimal notation. If it's not a valid IP address, then
// try to validate it as a hostname.
// RFC 1123 states: The host SHOULD check the string syntactically for a
// dotted-decimal number before looking it up in the Domain Name System.
// Hence the call to inet_addr() first.
////////////////////////////////////////////////////////////////////////////////

    unsigned long tmp_addr = inet_addr((char *)hostname);
    struct hostent* hostEntry;

// Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
//       A better solution would be to use inet_aton() or equivalent, as
//       inet_addr() is now considered "obsolete".

    if (tmp_addr == 0xFFFFFFFF)  // if hostname is not an IP address
    {
        char hostEntryBuffer[8192];
        struct hostent hostEntryStruct;
        hostEntry = System::getHostByName(hostname,
            &hostEntryStruct,
            (char*) &hostEntryBuffer,
            sizeof (hostEntryBuffer));

        if (!hostEntry)
        {
            return false;
        }

        memset(&address, 0, sizeof(address));
        memcpy(&address.sin_addr, hostEntry->h_addr, hostEntry->h_length);
        address.sin_family = hostEntry->h_addrtype;
        address.sin_port = htons(port);
    }
    else    // else hostname *is* a dotted-decimal IP address
    {
        memset(&address, 0, sizeof(address));
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = tmp_addr;
        address.sin_port = htons(port);
    }
#endif // PEGASUS_ENABLE_IPV6

    return true;
}