2012-02-03 2 views
8

사용자가 특정 Windows 서비스를 실제로 중지하거나 시작하지 않고 시작/중지 할 권한이 있는지 어떻게 확인합니까?현재 사용자에게 Windows 서비스를 다시 시작할 권한이 있는지 어떻게 확인합니까?

예를 들어 subinacl.exe와 같이 서비스를 다시 시작할 수있는 권리를 부여하는 것에 관한 질문은 아닙니다. 사용자가 관리자인지 또는 서비스를 다시 시작할 권한이 이미 부여되었는지 확인하고 싶습니다 .

+2

혹시 질문에 대한 답변을 찾으셨습니까? 나는 비슷한 것을 찾고있다. 감사합니다 –

+0

아담 : 불행히도 아니, 대답을 찾지 못했습니다 – olorin

+0

나는 이것이 오래된 것을 알고 있지만 여기에 유용한 정보가있을 것입니다 : http://stackoverflow.com/questions/4436558/start-stop-a-windows- 관리자가 아닌 사용자로부터의 서비스 계정? 특히 subinacl 유틸리티를 사용하여 사용자 권한을 쿼리 하시겠습니까? http://ss64.com/nt/subinacl.html – Richard

답변

2

나는 마침내 길을 발견했다, 나는 미래의 참고를 위해 내 자신의 질문에 대답하고있다.

public static ServiceAccessFlags GetServiceAcces(ServiceController serviceController) 
{ 
    WindowsIdentity winId = WindowsIdentity.GetCurrent(TokenAccessLevels.Duplicate | TokenAccessLevels.Query); 
    return GetServiceAcces(serviceController, winId); 
} 

private static ServiceAccessFlags GetServiceAcces(ServiceController serviceController, WindowsIdentity windowsIdentity) 
{ 
    // see http://www.pinvoke.net/default.aspx/advapi32/QueryServiceObjectSecurity.html?DelayRedirect=1If 
    byte[] buffer = new byte[0]; 
    uint bufferSizeNeeded; 
    bool ok = QueryServiceObjectSecurity(serviceController.ServiceHandle, SecurityInfos.DiscretionaryAcl, buffer, 0, out bufferSizeNeeded); 
    if (!ok) 
    { 
    int err = Marshal.GetLastWin32Error(); 
    if (err == 122) // ERROR_INSUFFICIENT_BUFFER 
    { 
     // expected; now we know bufsize 
     buffer = new byte[bufferSizeNeeded]; 
     ok = QueryServiceObjectSecurity(serviceController.ServiceHandle, SecurityInfos.DiscretionaryAcl, buffer, bufferSizeNeeded, out bufferSizeNeeded); 
    } 
    else 
    { 
     throw new InvalidOperationException("error calling QueryServiceObjectSecurity() to get DACL for Service: error code=" + err); 
    } 
    } 
    if (!ok) 
    throw new InvalidOperationException("error calling QueryServiceObjectSecurity(2) to get DACL for Service: error code=" + Marshal.GetLastWin32Error()); 

    RawSecurityDescriptor rsd = new RawSecurityDescriptor(buffer, 0); 
    RawAcl racl = rsd.DiscretionaryAcl; 
    DiscretionaryAcl dacl = new DiscretionaryAcl(false, false, racl); 

    byte[] daclBuffer = new byte[dacl.BinaryLength]; 
    dacl.GetBinaryForm(daclBuffer, 0); 

    SecurityIdentifier sid = windowsIdentity.User; 
    byte[] sidBuffer = new byte[sid.BinaryLength]; 
    sid.GetBinaryForm(sidBuffer, 0); 

    TRUSTEE t = new TRUSTEE(); 
    BuildTrusteeWithSid(ref t, sidBuffer); 

    uint access = 0; 
    uint hr = GetEffectiveRightsFromAcl(daclBuffer, ref t, ref access); 

    ServiceAccessFlags serviceAccess = (ServiceAccessFlags)access; 

    int i = Marshal.Release(t.ptstrName); 

    return serviceAccess; 
} 

[DllImport("advapi32.dll")] 
private static extern uint GetEffectiveRightsFromAcl(byte[] pacl, ref TRUSTEE pTrustee, ref uint pAccessRights); 

private enum MULTIPLE_TRUSTEE_OPERATION 
{ 
    NO_MULTIPLE_TRUSTEE, 
    TRUSTEE_IS_IMPERSONATE 
} 

private enum TRUSTEE_FORM 
{ 
    TRUSTEE_IS_SID, 
    TRUSTEE_IS_NAME, 
    TRUSTEE_BAD_FORM, 
    TRUSTEE_IS_OBJECTS_AND_SID, 
    TRUSTEE_IS_OBJECTS_AND_NAME 
} 

private enum TRUSTEE_TYPE 
{ 
    TRUSTEE_IS_UNKNOWN, 
    TRUSTEE_IS_USER, 
    TRUSTEE_IS_GROUP, 
    TRUSTEE_IS_DOMAIN, 
    TRUSTEE_IS_ALIAS, 
    TRUSTEE_IS_WELL_KNOWN_GROUP, 
    TRUSTEE_IS_DELETED, 
    TRUSTEE_IS_INVALID, 
    TRUSTEE_IS_COMPUTER 
} 

private struct TRUSTEE 
{ 
    public IntPtr pMultipleTrustee; 
    public MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation; 
    public TRUSTEE_FORM TrusteeForm; 
    public TRUSTEE_TYPE TrusteeType; 
    public IntPtr ptstrName; 
} 

[DllImport("advapi32.dll", SetLastError = true)] 
private static extern void BuildTrusteeWithSid(
    ref TRUSTEE pTrustee, 
    byte[] sid 
); 

[DllImport("advapi32.dll", SetLastError = true)] 
static extern bool QueryServiceObjectSecurity(SafeHandle serviceHandle, System.Security.AccessControl.SecurityInfos secInfo, byte[] lpSecDesrBuf, uint bufSize, out uint bufSizeNeeded); 

[System.FlagsAttribute] 
public enum ServiceAccessFlags : uint 
{ 
    QueryConfig = 1, 
    ChangeConfig = 2, 
    QueryStatus = 4, 
    EnumerateDependents = 8, 
    Start = 16, 
    Stop = 32, 
    PauseContinue = 64, 
    Interrogate = 128, 
    UserDefinedControl = 256, 
    Delete = 65536, 
    ReadControl = 131072, 
    WriteDac = 262144, 
    WriteOwner = 524288, 
    Synchronize = 1048576, 
    AccessSystemSecurity = 16777216, 
    GenericAll = 268435456, 
    GenericExecute = 536870912, 
    GenericWrite = 1073741824, 
    GenericRead = 2147483648 
} 
+0

대단히 감사합니다! 향후 독자를위한 메모, 허가를 받았는지 확인하려면 권한이 있는지 확인해야합니다 (https://msdn.microsoft.com/en-us/library/windows/desktop/aa379312). % 28v = vs.85 % 29.aspx? f = 255 & MSPPError = -2147217396 "주의"절 참조. – astrowalker

관련 문제