2012-02-03 95 views
8

如何檢查用戶是否有權啓動/停止特定的Windows服務,而無需實際停止或啓動它?如何檢查當前用戶是否有權重新啓動Windows服務?

這個問題不是關於授予用戶重新啓動服務的權限(例如使用subinacl.exe):我想檢查用戶是管理員還是他已經被授予重新啓動服務的權利。

+2

你有沒有找到你的問題的答案?我正在尋找類似的東西。謝謝 – 2013-04-23 18:59:40

+0

亞當:不幸的是,我沒有找到答案 – olorin 2013-04-25 07:01:02

+0

我知道這是一箇舊的,但會有任何有用的信息在這裏:http://stackoverflow.com/questions/4436558/start-stop-a-windows-非管理員用戶帳戶的服務?特別是使用subinacl實用程序來查詢用戶權限? http://ss64.com/nt/subinacl.html – Richard 2015-10-20 08:57:24

回答

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 2017-12-21 09:05:23

相關問題