Client connection to WINMGMT needs to be encrypted for this operation. - When connecting through WBEM Services locator on local machine

2014-03-20
2014-03-21
  • Jesse Stockall

    Jesse Stockall - 2014-03-20

    I'm trying to invoke JoinDomainOrWorkgroup on Win32_ComputerSystem via j-Interop. When I connect the JIComServer to the WBEM locator of the target system everything works as expected. When I connect the JIComServer to the WBEM locator on the local machine I get the following exception.

    SWbemObjectEx - Client connection to WINMGMT needs to be encrypted for this operation. Please adjust your IWbemServices proxy security settings and retry [0X80041087]

    I'm trying to use the WBEM Services locator on the local machine since the registry keys are inaccessible by default on Windows 2k8r2 and newer systems so configuration is needed. We use this mechanism successfully to query WMI on freshly deployed systems.

    Thanks

    Jesse

    public static void main(String[] args) throws Exception {
    
        JISystem.getLogger().setLevel(Level.OFF);
        JISystem.setInBuiltLogHandler(false);
        JISystem.setAutoRegisteration(true);
    
        String target = "hostA";
        String localhost = "localhost";
        String domain = "example.com";
    
        /**
         * When true, connect the JIComServer to the WBEM service locator on localhost, then connect to the WMI provider on the target
         * 
         * When false, connect the JIComServer to the WBEM service locator on the target, then connect to the WMI provider via localhost
         */
        boolean localLocator = true;
        String locatorIP = localLocator ? localhost : target;
        String wmiIP = localLocator ? target : localhost;
    
        JISession  session = null;
        try {
            log.info("Connecting to WMI namespace on %s via locator %s", target, locatorIP); //$NON-NLS-1$
    
            session = JISession.createSession("", "administrator", "******");
            session.useNTLMv2(true);
            session.useSessionSecurity(true);
    
            // Connect to the WBEM Services Locator
            JIClsid id = JIClsid.valueOf("76a64158-cb41-11d1-8b02-00600806d9b6");
            JIComServer locator = new JIComServer(id, locatorIP, session);
    
            IJIDispatch locator_dispatch = (IJIDispatch) JIObjectFactory.narrowObject( locator.createInstance().queryInterface( IJIDispatch.IID ) );
    
            log.info("\tSuccesfully connected to WBEM Services Locator on %s", locatorIP); //$NON-NLS-1$
    
            // credentials are only used when connecting to the WMI provider remotely
            Object[] connectParams = new Object[] {  
                    new JIString(wmiIP),                         
                    new JIString("ROOT\\CIMV2"),
                    localLocator ? new JIString(target + "\\administrator") : JIVariant.OPTIONAL_PARAM(),  
                    localLocator ? new JIString("*******") : JIVariant.OPTIONAL_PARAM(),
                    JIVariant.OPTIONAL_PARAM(),
                    JIVariant.OPTIONAL_PARAM(),
                    Integer.valueOf(128), 
                    JIVariant.OPTIONAL_PARAM() };
    
            JIVariant[] connectResults = locator_dispatch.callMethodA("ConnectServer", connectParams); //$NON-NLS-1$
            IJIDispatch wbemServices_dispatch = (IJIDispatch) JIObjectFactory.narrowObject(connectResults[0].getObjectAsComObject());
    
            log.info("\tSuccesfully connected to WMI Provider on %s", target); //$NON-NLS-1$
    
            String wql = String.format("SELECT * FROM Win32_ComputerSystem where Name = '%s'", target); //$NON-NLS-1$
            Object[] queryParams = new Object[] { new JIString(wql), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(),  JIVariant.OPTIONAL_PARAM()};
            JIVariant[] queryResults = wbemServices_dispatch.callMethodA("ExecQuery", queryParams);
            IJIDispatch query_dispatch = (IJIDispatch) JIObjectFactory.narrowObject(queryResults[0].getObjectAsComObject());
    
            JIVariant queryEnum = query_dispatch.get("_NewEnum");
            IJIComObject co = queryEnum.getObjectAsComObject();
            co = co.queryInterface(IJIEnumVariant.IID);
            IJIEnumVariant enumVariant = (IJIEnumVariant) JIObjectFactory.narrowObject(co);
            Object[] next = enumVariant.next(1);
            JIArray nextArray = (JIArray) next[0];
            Object[] nextArrayObj = (Object[]) nextArray.getArrayInstance();
            IJIDispatch computerSystem_dispatch = (IJIDispatch) JIObjectFactory.narrowObject(((JIVariant) nextArrayObj[0]).getObjectAsComObject());
    
            log.info("\tSuccesfully obtained Win32ComputerSystem object for %s", target); //$NON-NLS-1$
    
            JIVariant methodsResult = computerSystem_dispatch.get("Methods_");
            IJIDispatch methods_dispatch = (IJIDispatch) JIObjectFactory.narrowObject(methodsResult.getObjectAsComObject());
    
            log.info("\tSuccesfully obtained mthods of Win32ComputerSystem"); //$NON-NLS-1$
    
            Object[] joinMethodParams = new Object[] { new JIString("JoinDomainOrWorkgroup"), new Integer(0) };
            JIVariant[] joinMethodResults = methods_dispatch.callMethodA("Item", joinMethodParams);
            IJIDispatch joinMethod_dispatch = (IJIDispatch) JIObjectFactory.narrowObject(joinMethodResults[0].getObjectAsComObject());
    
            log.info("\tSuccesfully obtained JoinDomainOrWorkgroup method of Win32ComputerSystem"); //$NON-NLS-1$
    
            JIVariant joinParams = joinMethod_dispatch.get("InParameters");
            IJIDispatch joinParams_dispatch = (IJIDispatch) JIObjectFactory.narrowObject(joinParams.getObjectAsComObject());
    
            log.info("\tSuccesfully obtained IN parameters of JoinDomainOrWorkgroup method"); //$NON-NLS-1$
    
            joinParams_dispatch.put("Name", new JIVariant(domain));
            joinParams_dispatch.put("Password", new JIVariant("******"));
            joinParams_dispatch.put("UserName", new JIVariant("example\\administrator"));
            joinParams_dispatch.put("AccountOU", JIVariant.NULL());
            joinParams_dispatch.put("FJoinOptions", new JIVariant(3));
    
            log.info("\tInvoking JoinDomainOrWorkgroup"); //$NON-NLS-1$
    
            Object[] methodParams = new Object[] { new JIString("JoinDomainOrWorkgroup"), new JIVariant(joinParams_dispatch), new Integer(0), JIVariant.NULL()};
    
            JIVariant[] result = computerSystem_dispatch.callMethodA("ExecMethod_", methodParams);
    
            log.info("\tSuccesfully invoked JoinDomainOrWorkgroup"); //$NON-NLS-1$
    
            // Get the return code.
            JIVariant resultVar = result[0];
            IJIDispatch resultDisp = (IJIDispatch) JIObjectFactory.narrowObject(resultVar.getObjectAsComObject());
            JIVariant returnValue = resultDisp.get("ReturnValue");
            int ret = returnValue.getObjectAsInt();
    
            log.info("\tJoinDomainOrWorkgroup returned %s ", ret);
        } catch (JIAutomationException e) {
            JIExcepInfo excepInfo = ((JIAutomationException)e).getExcepInfo();
            String desc = excepInfo.getExcepDesc();
            if (StringUtils.isNotEmpty(desc))
                desc = desc.substring(0, desc.length() - 5); // trim some junk off the end
            log.error("%s - %s [%#X]",  excepInfo.getExcepSource(), desc, excepInfo.getErrorCode()); //$NON-NLS-1$
        } catch (JIException e) {
            switch (e.getErrorCode()){
            case JIErrorCodes.ERROR_ACCESS_DENIED:      // Credentials Error
            case JIErrorCodes.WIN_AUTH_FAILURE:         // Logon failure: unknown user name or bad password.
                log.error("Authentication failure: %d", e.getErrorCode());
                break;
            case JIErrorCodes.RPC_SERVER_UNAVAILABLE:
                log.error("RPC Server Unavailable"); //$NON-NLS-1$
                break;
            default:                                    // Misc other error
                Throwable cause = e.getCause();
                if(cause instanceof ConnectException) {
                    log.error("Inaccessible host"); //$NON-NLS-1$
                } else {
                    log.error(e.getMessage());
                }
            }
        } finally {
            JISession.destroySession(session);
        }
    }
    
     
    Last edit: Jesse Stockall 2014-03-20
  • Jesse Stockall

    Jesse Stockall - 2014-03-21

    Found the solution looking in other forum posts. Need to set the AuthenticationLevel on the WBEM locator before connecting to the remote WMI provider.

    JIVariant variant = locator_dispatch.get("Security_");
    IJIDispatch security_dispatch = (IJIDispatch) JIObjectFactory.narrowObject(variant.getObjectAsComObject());
    security_dispatch.put("AuthenticationLevel", new JIVariant(6)); // WbemAuthenticationLevelPktPrivacy

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks