0

I am trying to write a Java API which uses JNA to communicate with WMI with remote machine (provided username and password).
For this I want to create COAUTHIDENTITY object and use it with CoSetProxyBlanket in Java.
The code I am trying to port is here.
Any help with this would be appreciated.

suraj1291993
  • 474
  • 1
  • 5
  • 15

1 Answers1

1

You can map the COAUTHIDENTITY structure in an interface class. It looks like WTypesBase which extends WTypes may be a good class name although you can put it anywhere.

The type mappings are simple: what you see as unsigned long can be NativeLong but since this is Windows-only code you can use int as we know it's 32-bit. The unsigned short * pointers are character arrays of 2-byte (wide) characters. Just use a Pointer for those.

So your structure heading should be:

class COAUTHIDENTITY extends Structure {
  public Pointer User;
  public int UserLength;
  public Pointer Domain;
  public int DomainLength;
  public Pointer Password;
  public int PasswordLength;
  public int Flags;
}

(Field order mappings are left as an exercise for the reader.)

Then to create it:

COAUTHIDENTITY auth = new COAUTHIDENTITY();

String user = "username"; // or get from the user
// Allocate memory for user including null terminator
auth.User = new Memory(Native.WCHAR_SIZE * (user.length() + 1));
// Set the widestring in memory
auth.User.setWideString(0, user);
auth.UserLength = user.length();

// Do the same for domain and password

auth.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
// Note: SEC_WINNT_AUTH_IDENTITY_ANSI = 1
Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
  • Thanks for your help. I am facing problem in the immediate next step in setting value to argument `pServerPrincName` for `CoSetProxyBlanket` API. Kindly refer [here](https://pastebin.com/ZSuiSciV) for the code snippet I am using. I tried using null, empty string as values for that argument. The value for that arguments is `COLE_DEFAULT_PRINCIPAL` which is of type OLECHAR. @Daniel – suraj1291993 Aug 20 '18 at 11:20
  • I am faced with error code 0x80070057 denoting I have provided wrong value as argument(s) for that API – suraj1291993 Aug 20 '18 at 11:27
  • You've correctly used `LPOLESTR` for that type, but it looks from the docs that you might want the Windows constant `COLE_DEFAULT_PRINCIPAL`. That's defined [here](https://github.com/tpn/winsdk-10/blob/master/Include/10.0.10240.0/um/ObjIdl.h) as a pointer to -1... which I'm not sure we can do with the `LPOLESTR` type. This is probably worthy of a new thread here, or a question on the JNA mailing list. You might try using a `Pointer` for that variable and manually setting its `peer` value to `-1`. (No idea if that will work but it's worth a shot!) – Daniel Widdis Aug 20 '18 at 16:28
  • 1
    Try this (totally untested, may crash your machine so save first): `Pointer p = new Pointer();` `Pointer.nativeValue(p, -1);` `LPOLESTR COLE_DEFAULT_PRINCIPAL = new LPOLESTR(p);` and then use that constant in the `CoSetProxyBlanket` call. I repeat, totally untested and may cause a crash! :) – Daniel Widdis Aug 20 '18 at 16:34
  • `Pointer pAuth = new Pointer(-1); Pointer.nativeValue(pAuth, -1); LPOLESTR COLE_DEFAULT_PRINCIPAL = new LPOLESTR(pAuth);`
    `hres = Ole32.INSTANCE.CoSetProxyBlanket(pSvc.getValue(), Ole32.RPC_C_AUTHN_DEFAULT, Ole32.RPC_C_AUTHZ_DEFAULT, COLE_DEFAULT_PRINCIPAL, Ole32.RPC_C_AUTHN_LEVEL_PKT_PRIVACY, Ole32.RPC_C_IMP_LEVEL_IMPERSONATE, auth.getPointer(), Ole32.EOAC_NONE);` I used this following code snippet, but I am still getting that same error.
    – suraj1291993 Aug 20 '18 at 17:36
  • Code can be found in the same link. – suraj1291993 Aug 20 '18 at 17:42
  • Don't use `getPointer()` on `auth`. Just pass the structure directly. I also see you trying to replace `int` with `DWORD`. That doesn't make a difference on the windows side, it's all 32-bit integers. – Daniel Widdis Aug 20 '18 at 17:50
  • Thanks. The suggestion you provided works. But in the next step, when trying to execute the WMI query, I am getting the error code 0x80070005 saying access denied. I am able to execute WMI query through powershell with same user credentials. (Code update in the same url) – suraj1291993 Aug 20 '18 at 19:08
  • Not sure the empty domain is allowed. In any case, you've gone far afield of this question and it's harder to answer in chat. Perhaps post your code in a new question showing how far you have got and see if others can advise -- you'll get more response on a new question. You're past the JNA modeling part and into WMI/COM credentials now and that's a different category of question. – Daniel Widdis Aug 20 '18 at 22:25
  • 1
    As per you suggestion I have raised it as a separate clarification [here](https://stackoverflow.com/questions/51941549/issue-when-executing-iwbemservices-execquery-when-executing-wmi-using-jna). Thanks – suraj1291993 Aug 21 '18 at 04:26