windows 获取机器 SID(包括主域控制器)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2254660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:55:13  来源:igfitidea点击:

get machine SID (including primary domain controller)

c#windowssid

提问by Tomá? Holan

I need to get machine SID (not computer account's SID) in C#. Computer is specified be host name, it is't necessarily local computer and it can be domain computer or workgroup computer. I using this helper class to call LookupAccountName API function:

我需要在 C# 中获取机器 SID(不是计算机帐户的 SID)。计算机被指定为主机名,它不一定是本地计算机,它可以是域计算机或工作组计算机。我使用这个助手类来调用 LookupAccountName API 函数:

    private static class Helper
    {
        internal enum SID_NAME_USE
        {
            SidTypeUser = 1,
            SidTypeGroup,
            SidTypeDomain,
            SidTypeAlias,
            SidTypeWellKnownGroup,
            SidTypeDeletedAccount,
            SidTypeInvalid,
            SidTypeUnknown,
            SidTypeComputer
        }

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool LookupAccountName(
            string systemName,
            string accountName,
            byte[] sid,
            ref int sidLen,
            System.Text.StringBuilder domainName,
            ref int domainNameLen,
            out SID_NAME_USE peUse);

        public static SecurityIdentifier LookupAccountName(
            string systemName,
            string accountName,
            out string strDomainName,
            out SID_NAME_USE accountType)
        {
            const int ERROR_INSUFFICIENT_BUFFER = 122;

            int lSidSize = 0;
            int lDomainNameSize = 0;

            //First get the required buffer sizes for SID and domain name.
            LookupAccountName(systemName,
                              accountName,
                              null,
                              ref lSidSize,
                              null,
                              ref lDomainNameSize,
                              out accountType);

            if (Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
            {
                //Allocate the buffers with actual sizes that are required
                //for SID and domain name.
                byte[] sid = new byte[lSidSize];
                var sbDomainName = new System.Text.StringBuilder(lDomainNameSize);

                if (LookupAccountName(systemName,
                                      accountName,
                                      sid,
                                      ref lSidSize,
                                      sbDomainName,
                                      ref lDomainNameSize,
                                      out accountType))
                {
                    strDomainName = sbDomainName.ToString();
                    return new SecurityIdentifier(sid, 0);
                }
            }

            throw new Win32Exception();
        }
    }

and using it like this:

并像这样使用它:

Helper.SID_NAME_USE accountType;
string refDomain;
SecurityIdentifier sid = Helper.LookupAccountName("falcon.mydomain.local", "falcon", out refDomain, out accountType);  //Domain computer

SecurityIdentifier sid = Helper.LookupAccountName("rat", "rat", out refDomain, out accountType);  //Workgroup computer

My only problem is, that this is not working if computer is primary domain controller (i need to obtain domain SID in that case).

我唯一的问题是,如果计算机是主域控制器,这将不起作用(在这种情况下我需要获取域 SID)。

回答by John Smith

It appears that for most computers you do the following:

对于大多数计算机,您似乎执行以下操作:

LookupAccountName("", "ComputerName", ...); ConvertSidToStringSid(...)

LookupAccountName("", "ComputerName", ...); ConvertSidToStringSid(...)

But for domain controllers you have to add a dollar sign to the computer name parameter, and then delete the last segment in the returned SID.

但是对于域控制器,您必须在计算机名称参数中添加一个美元符号,然后删除返回的 SID 中的最后一段。