Start windows service before LogonUI appears - windows

I've wrote a service, that should start before WinLogon launches LogonUI, but I can't find any solution to ensure it.
My service belongs to MS_WindowsLocalValidation group, that is located before, for instance, SmartCardGroup, which SCardSvr belongs to. I suppose, LogonUI needs some SCard functionality, so it should wait until this service starts, but it is just a guess. The obvious guess is that WinLogon waits for COM infrastructure launches, but I can't add my service to this group, because it uses COM, so it should start before my service too.
The question is: is there a way to ensure, that my service will start completely (will set its state to SERVICE_RUNNING) before LogonUI?
I found, that winlogon waits for a named event Global\\UMSServicesStarted, but during setup only :( Maybe there is something, that winlogon waits always before starting LogonUI?
Maybe there is some service, that winlogon depends explicitly on...

Related

Is a serviced component shared between user sessions on a terminal server, or is one process started for each user session?

I have some .NET code in a COM+/Enterprise Services serviced component. I communicate with this component from a WPF application and also from a legacy VBA application.
This arrangement works well when only one user is logged on to a machine. The component starts in its own process when either the .NET or the legacy application instantiates one of its COM objects.
The system also works for the first user to try to run it on a terminal server installation. However, when another user logs on, he/she is unable to use the application. I had hoped that each session would run in isolation, and that one host process would run per session. Am I wrong in this expectation?
In Component Services on the Activation tab my application is configured to run as a "Server application". On the Identity tab, "Interactive user" is selected. On the Security tab, "Enforce access checks for this application" is unchecked.
There isn't session isolation as you describe, instead process ownership limits what you have access to.
Your conclusion seems correct & you will need to determine a suitable mechanism to exchange data with the service.
I used WCF to create a service with a net named pipe listener https://learn.microsoft.com/en-us/dotnet/framework/wcf/index
The idea of using proxies to make rpc calls is attractive, but I found the proxy definitions and stubs to link it all together quite clumsy to use.
If you have events that may be triggered at either end then keeping client/service in sync becomes problematic.
AIUI you cannot invoke a rpc method that ends up invoking an rpc back at the originating end, although that could be a named pipe limitation.
If I was doing this again I would use a socket server in the service & the websocket protocol for biderectional data transfer, even though you might need to implement some thread handling to avoid the listener thread blocking whilst servicing requests.
Hard to find anything authoritative on this. For standard COM you can set the identity to 'Launching user'. The same is not available for COM+.
According to this archived post,
A COM+ application can be configured to run under the logged in account, or
a specified account. Under the application properties, see the Identity tab.
...
Once set however, it remains under that account until the application shuts
down, so you can't have multiple users using the same COM+ application under
different IDs.
That seems to match what is said in this knowledge base article too.
My conclusion is, I should probably accept that my component must run once per machine rather than once per session. It will need to be modified to accommodate this. Since it needs to start new processes in individual sessions, it will have to run as a Windows service under the Local System account (giving due attention to the security implications).

Stopped service does not release its resources?

I'm trying to deploy a patch to a service I created and replace the service file.
For that reason I need to stop the service so the file will be released.
I'm using sc \\remote stop svcname, then I query the service using sc \\remote query svcname until I see that it's state is STOPPED.
At this point the service file should be unlocked, and to be on the safe side I also delete the service using sc \\remote delete svcname.
Still, it doesn't seem to release the file and any deletion or change attempt fails.
I know one solution might be polling the file repeatedly, but I want to avoid this method.
Any suggestions?
Windows don't ensure the process providing the service terminates when the service is stopped (the process may provide more than one service). It just considers the service stopped when it handles the message sent to it.
So if the service process has a bug and does not properly release resources, they may still be locked. I would probably wait a little and than simply terminate the process.
There is also a tool from Microsoft called handle.exe (this is command-line version, they also have a GUI-one) that can list which processes hold the file open. It should be possible to get the same information programmatically, but I am not sure of the exact calls to make (and you need administrator privileges; you have to give them to the tool too). That way you can check whether the file is open, by which process and wait for it to terminate or force-terminate it if you didn't know which one it is.

How to list Windows Services from within a Service

sc query state= all works as expected from the command line.
From within another Service, sc query state= all doesn't print anything to that sub-process' stdout (captured by the parent, of course).
Is there a permission/privilege that the Service needs in order to list/start/stop the other servies?
A little background: I am making a service that periodically restarts some misbehaving services.
Well, for one don't do that, at least not in a blocking manner. In order for your own service to respond to the SCM (Service Control Manager) in order to return its status, the service has to be able to execute its dispatcher code. This means that if you call this program and wait for it to exit you'll wait indefinitely. One way to mitigate this would be to put this into a separate thread so it's not blocking your dispatching and your service will continue to talk to the SCM.
Alternatively (and probably better) you could use the EnumServicesStatusEx function to talk to the SCM and inquire about the statuses of other services yourself. The function itself doesn't mention anything about being blocking, so you'd have to figure out yourself whether it is and then use a thread again to prevent your service from stopping to talk to the SCM.
One last note: if those misbehaving services are yours, you should more likely fix the respective code. I've had a share of legacy code and had one misbehaving service which got its own helper application as "fault action" (can be configured in service configuration as SERVICE_CONFIG_FAILURE_ACTIONS) that would go about and restart the service whenever it crashed. Once I took that code over, figured out the cause and fixed it, the service was stable again and that application isn't really needed anymore.

How can I autostart a UI-application under windows that a non-admin user cannot close?

I have developed a C# Windows Forms application that runs in the background as a systray icon and does some stuff when it's clicked. It is supposed to launch when Windows starts and run continously, and a normal user without administrator rights shall not be allowed to shut it down.
What is the best way to do this? I initially intended to run it on the LocalSystem account through Task Scheduler, but then I learned (the hard way) about Session 0 isolation (i.e. the application will run but its UI elements do not show). When I run it with the logged in user, even if it runs elevated, the user can still shut it down through task manager (without requiring elevation).
Is there any way to give a process from LocalSystem access to the UI? I have a winlogon and a csrss process from LocalSystem running in session 1, so I guess it can be done, I just don't know how. Or is there maybe an easier way to disallow users to shut down a process of their own through the task manager? The only other option I can think of is to create an extra Windows Service that keeps polling if the app is running, and immediately launches it again if someone kills it - but that seems incredibly clumsy (also, I want it to stay dead when it crashed by itself, to avoid a single bug causing infinite loops of process creation).
Deponds on why they can't shut it down.
The natural way to go would to have created a service, started by a high priv account, and then had the desktop app just show what it was doing.
If there's something that they should see, but don't becasue they aren't running the service monitor app. (and acknowledge message back to the service), send them an email, send their boss an email, send yourself one and then go shout at them.....
Be a lot easier than trying to get the lid back on this tin of worms.
A nice way to make sure the desktop app is ruuning, would be simply to schedule it to run every X, but drop out immediately if it already is or the somethingwenthorriblywrong flkag is set.
Not worth writing a service to check if it's still there, as they could kill that as well, unless you want to make that a service they can't kill. :(
You are trying to be too draconian with this. Add some sort of auditing so you can see it dies or was shutdown, monitor that and deal with any adverse reports. It's a heck of a lot easier, and gives manage something to do...
You can run an administrative process in the user's logon session. One method would be to for a master process (a system service) to duplicate its own token, use SetTokenInformation to change the session associated with the token, and then call CreateProcessAsUser. The lpStartupInfo parameter can be used to associate the process with a particular window station and desktop. It may be necessary to explicitly change the permissions on the window station and desktop first.
HOWEVER, this is a bad idea from a security standpoint, because GUI applications are vulnerable to malicious messages sent from other processes on the same desktop ("shatter attacks").
It would be safer to run the process in the user's own context but apply an ACL to it. This can be done using the lpProcessAttributes parameter to CreateProcess or CreateProcessAsUser, or with the SetSecurityInfo function. I've never tried this, but it should in theory prevent the user from using task manager to close the process.
If you are creating the process from the user's context, then the user will be the owner, so a sufficiently knowledgeable person could change the permissions back in order to terminate the process. If you need to block this hole, using CreateProcessAsUser from a privileged master process (the token can be duplicated from one of the existing processes in the user's session) should (again, in theory) mean that the user is not the process owner.
Another potential issue: if you listen for messages indicating that the user is logging out (in order to exit) such a message could be faked. If you don't then you need to find some other way of exiting when the user logs out. You may need to experiment here, I'm not sure how the system will react.

Does COM activation of LocalServer32 EXE from the same user account share an existing process or not?

I have a COM server LocalServer32 EXE started when a client application calls c_com_ptr::CreateInstance (using ATL wrappers.)
On Windows 7, when a second client application running under the same user account also calls c_com_ptr::CreateInstance, a second copy of the EXE is launched running under the same user account. I was under the impression, from a past life, that the second client would share the first EXE.
Is the LocalServer32 process shared, or not? When, or when not? Googling for an answer gives me a huge noise to signal ratio and I can't find the answer.
My CLSID registry key has the LocalServer32 value giving the EXE path, ProgID, Programmable (empty string), TypeLib (GUID), and a VersionIndependentProgId. I have an AppID key.
I do not want to run the EXE as a service, and I don't mind that the process is not shared. I just want to know the rules so I know what to expect (on Windows Server 2003 onwards.)
EDIT: Following Chris' answer below, I examined the CoRegisterClassObject call in my server. I'm using ATL, and I overrode MyServer::RegisterClassObjects to hook into the calling chain to CAtlExeModuleT::RegisterClassObjects and see that ATL is using CLSCTX_LOCAL_SERVER and REGCLS_MULTIPLEUSE.
Changing this to CLSCTX_LOCAL_SERVER and REGCLS_SINGLEUSE causes more processes to be started, depending on the number of COM objects created by the client, as expected.
Still, going back to REGCLS_MULTIPLEUSE, I get one COM server process per COM client process, each server process containing all of the COM objects for its client, as expected, except that if two COM clients are running under the same user account, they each get their own server which is not how I understood REGCLS_MULTIPLEUSE.
Could the difference be that the clients themselves are actually Windows services? (They are.) When a Windows service process running as a user account creates a COM object under REGCLS_MULTIPLEUSE, is this treated differently, causing the observed behavior? Why am I getting more than one process? (And just to clarify, I do not want my COM server to run as a Windows service, but the clients that use it do run as Windows services.)
Also, running the clients as either Local System, or Network Service, REGCLS_MULTIPLEUSE works as I would have expected: only a single COM server EXE process is started. The multiple processes are started when the COM clients are Windows services running under user accounts.
The routing of out-of-process activation requests is controlled by the registration of class objects with the COM Service Control Manager. If the SCM has a usable registered class object, that will be used to service the request. If it doesn't, it will start an exe process instance of the COM server to get one. Whether multiple activation requests are routed to a single COM server exe process therefore depends on the following factors at least (I'm not sure if this is a complete list):
the activation flags specified by the COM server when it calls CoRegisterClassObject to register with the SCM can cause future activation requests to result in a new exe process instance being started, the simplest and commonest case being the use of the flag REGCLS_SINGLEUSE, which allows the registered class object to be used for a single activation only.
Depending on how the class is registered, activation requests from different security contexts may be serviced by different COM server exe instances (it seems this won't apply in your scenario as your client applications run under the same security contexts).

Resources