nicoriff / ORMi

A Light-ORM for accesing WMI
MIT License
209 stars 28 forks source link

Cannot access namespace "TerminalServices" remotely (Access Denied) #25

Closed maordadush closed 3 years ago

maordadush commented 3 years ago

Hi,

This is what I try to do:

WMIHelper helper = new WMIHelper("root\CimV2\TerminalServices", "10.0.0.1", "contoso\user", "Hello"); List remoteApps = helper.Query().ToList();

System.Management.ManagementException HResult=0x80131501 Message=Access denied Source=System.Management StackTrace: at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode) at System.Management.ManagementObjectSearcher.Get() at ORMi.WMIHelper.Query[T]()

This is the cause of the issue:

To connect to the Root\CIMV2\TerminalServices namespace, the authentication level must include packet privacy. For C/C++ calls, this is an authentication level of RPC_C_AUTHN_LEVEL_PKT_PRIVACY. https://docs.microsoft.com/en-us/windows/win32/termserv/win32-terminalservicesetting?redirectedfrom=MSDN

Can you support packet privacy scenario?

Thanks!

ewisted commented 3 years ago

You can set the authentication level on the Scope property of the WMIHelper once instantiated. It would look like this in your case-

WMIHelper helper = new WMIHelper("root\CimV2\TerminalServices", "10.0.0.1", "contoso\user", "Hello");
helper.Scope.Options.Authentication = System.Management.AuthenticationLevel.PacketPrivacy;
List remoteApps = helper.Query().ToList();

@nicoriff it would be nice to have a default parameter in the constructor that could be overridden for situations like these. I added this in my fork, let me know if you would be interested in a pull request to add it to the main repo-

public WMIHelper(string scope, string hostname, string username, string password, AuthenticationLevel auth = AuthenticationLevel.Default)
{
    Scope = new ManagementScope(String.Format("\\\\{0}\\{1}", hostname, scope));
    Scope.Options = new ConnectionOptions
    {
          Impersonation = ImpersonationLevel.Impersonate,
          Authentication = auth,
          Username = username,
          Password = password
     };
}

Not a huge change, just a convenience sort of thing.

maordadush commented 3 years ago

@ewisted Thanks!

nicoriff commented 3 years ago

Just for the record... this is included in the new release 2.6.0 also available on NuGet. Thanks @ewisted !!

maordadush commented 3 years ago

@nicoriff Is it possible to support PacketPrivacy in WMIWatcher?

nicoriff commented 3 years ago

I assume that you can do:

Authentication = System.Management.AuthenticationLevel.PacketPrivacy;

That will solve it out right?.

Maybe we cann add it as an optional parameter.

maordadush commented 3 years ago

But is not a public member, am I wrong?

nicoriff commented 3 years ago

@maordadush I added support for ConnectionOptions on WMIWatcher constructor:

Example:

WMIWatcher watcher = new WMIWatcher("root\\CimV2", "SELECT * FROM Win32_ProcessStartTrace", new System.Management.ConnectionOptions { Authentication = System.Management.AuthenticationLevel.PacketPrivacy });

maordadush commented 3 years ago

Thanks!