2

I've got a third-party vendor who is installing a series of Windows services to a (Windows 2008 R2) server in my control. Whilst attempting to run each service under its own least-privilege account, we have hit upon obligatory permissions issues. These only seem to be resolvable by running the service as Local System -- even membership of the local Administrators group is insufficient.

The issue appears to stem from some IPC-related code, which is built around a single .NET class, referenced by the individual services.

As far as I can tell from the IL disassembly (via Telerik JustDecompile), the IPC class derives from System.Windows.Forms.NativeWindow and sets up a WndProc override to handle a custom message.

Each service instantiates the IPC class with a given name parameter, which it passes as the NativeWindow's title and, when it needs to send to the other service, uses the Win32 API FindWindow method (called as Win32.FindWindow(null, targetName)) to determine the handle of the hidden NativeWindow of the target service, and calls PostMessage on that handle, to trigger the remote action.

The issue appears to be that, unless run as Local System, the call to FindWindow only returns a zero-handle, which the sending service perceives as the target service not being found. As mentioned, even when run as a member of Administrators, it still appears to return the zero value.

I thought this might be an issue with Session #0 isolation but, since this is all service-to-service IPC, rather than service-to-desktop, all executables are running in Session #0, anyway.

There's not much I'm going to be able to do about this -- business needs must, after all -- but, from a theoretical perspective:

  1. Am I right in thinking a global, named EventWaitHandle, with a while (true) { _h.WaitOne(); /* handle event */ }-style message loop, on its own thread, is the more-appropriate option for this kind of work?

  2. Is this a case of permissions to the window handle (do such things exist?) and, if so, could these be changed (e.g. with DuplicateHandle); or does a Windows privilege exist (e.g. in Local Security Policy / User Rights Assignment) that permits/overrides access to the handle? (I considered SeDebugPrivilege, but local Administrators already has that.)

  3. Is there anything that documents the inappropriateness of FindWindow/PostMessage for this kind of work (specifically for service-to-service IPC)? i.e. is this a known limitation for FindWindow, with which I might beat the third-party over the head?

1 Answer 1

2

This is a normal restriction in the Windows security model since NT3.x services that only the local service account is allowed access to the desktop when run as a service and it has other restrictions when you select that option.

On Windows Server since about 2003, there is also a service interaction policy you may have to adjust. You may have to reboot the machine to pick up this setting:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows

NoInteractiveServices = default is 1 until win2k3, change this to 0. On win2k8+ its default is 0.

This technote below also suggests a method using named pipes to connect a service to a windows app or background task that can run in the logged in session and send materials to the service over the pipe.

Here is a technote from Microsoft on the topic along with some cautions: https://msdn.microsoft.com/en-us/library/windows/desktop/ms683502(v=vs.85).aspx

There is a registry hack if you want to use a specific account but not sure it will be able to reach into any user's session unless it has admin permissions, I've never tested this use case.

HK Local Machine:

SYSTEM\CurrentControlSet\Services\your service

Key= "Type" Position 100h (If you logical 'or' with decimal 256 to set the bit)

Credit for this registry detail: http://www.codeproject.com/Articles/4891/Interact-With-Desktop-when-Installing-Windows-Serv

Not the answer you're looking for? Browse other questions tagged or ask your own question.