Does anyone know how to get SACL on a remote service using C #? I tried many different methods and basically nothing works. I can get DACL and SACL on the local computer, but getting on the remote machine is not possible.
I created a ServiceSecurity class that inherits from NativeObjectSecurity and acts like a RegistrySecurity class. Below are the two constructors that I have:
public ServiceSecurity(string serviceName, AccessControlSections includeSections) : base(true, ResourceType.Service, serviceName, includeSections, null, null) { } public ServiceSecurity(System.Runtime.InteropServices.SafeHandle handle, AccessControlSections includeSections) : base(true, ResourceType.Service, handle, includeSections) { }
The first uses the name of the service, and the second expects a handle to this service. Obviously, the former works just fine to get DACL and SACL, because it is all local, but to get to the remote machine, I use the ServiceController class to search for services on the remote machine. Upon receiving it, I pass the ServiceHandle property of the service to the ServiceSecurity class that I created, and at this point I get a Unauthorized Access exception that does not seem correct because my user account is the domain administrator for the domain and the local administrator in the target field. I also have the SeSecurityPrivilege , which should allow me access.
Does anyone have any ideas? It seems that the SafeHandle I am getting is wrong, but the SafeHandle properties say that it is not closed and that it is a valid handle, so I do not quite understand what is happening.
Here is the code I use to try to extract the data:
ServiceSecurity sSec = new ServiceSecurity(services[i].ServiceName, accessSections); string outputData = sSec.GetSecurityDescriptorSddlForm(accessSections);
The above will work for local permissions and audit settings (DACL and SACL). But it is designed to work on a local machine. If I do this instead:
ServiceSecurity sSec = new ServiceSecurity(services[i].ServiceHandle, accessSections); string outputData = sSec.GetSecurityDescriptorSddlForm(accessSections);
The ServiceSecurity constructor does not work on local and remote servers for SACL as follows, but still works for DACL:
System.UnauthorizedAccessException: Attempted to perform an unauthorized operation. at System.Security.AccessControl.Win32.GetSecurityInfo(ResourceType resourceType, String name, SafeHandle handle, AccessControlSections accessControlSections, RawSecurityDescriptor& resultSd) at System.Security.AccessControl.NativeObjectSecurity.CreateInternal(ResourceType resourceType, Boolean isContainer, String name, SafeHandle handle, AccessControlSections includeSections, Boolean createByName, ExceptionFromErrorCode exceptionFromErrorCode, Object exceptionContext) at System.Security.AccessControl.NativeObjectSecurity..ctor(Boolean isContainer, ResourceType resourceType, SafeHandle handle, AccessControlSections includeSections)
For accessSections, I specify only one of the AccessControlSections , whether audit or access and audit, seem to fail every time I pass a ServiceHandle .
Update: So maybe the question really should be, how do I get a handle to a service that has ACCESS_SYSTEM_SECURITY so that I can get the SACL?