代码之家  ›  专栏  ›  技术社区  ›  crb

在C#/.NET中将用户名转换为SID字符串

  •  42
  • crb  · 技术社区  · 17 年前

    有一个关于 converting from a SID to an account name

    例如,如何将用户名转换为SID字符串,以找出哪个HKEY_USERS子项与给定名称的用户相关?

    3 回复  |  直到 9 年前
        1
  •  90
  •   Giorgi    16 年前

    播客告诉我,当问题还没有得到回答时,我应该提问和回答。来吧。

    NTAccount f = new NTAccount("username");
    SecurityIdentifier s = (SecurityIdentifier) f.Translate(typeof(SecurityIdentifier));
    String sidString = s.ToString();
    

    艰难之路,在无法实现的情况下也能实现,在.NET 1.1上也能实现:

    [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    public static extern bool LookupAccountName([In,MarshalAs(UnmanagedType.LPTStr)] string systemName, [In,MarshalAs(UnmanagedType.LPTStr)] string accountName, IntPtr sid, ref int cbSid, StringBuilder referencedDomainName, ref int cbReferencedDomainName, out int use);
    
    [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    internal static extern bool ConvertSidToStringSid(IntPtr sid, [In,Out,MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid);
    
    
    /// <summary>The method converts object name (user, group) into SID string.</summary>
    /// <param name="name">Object name in form domain\object_name.</param>
    /// <returns>SID string.</returns>
    public static string GetSid(string name) {
        IntPtr _sid = IntPtr.Zero; //pointer to binary form of SID string.
        int _sidLength = 0;   //size of SID buffer.
        int _domainLength = 0;  //size of domain name buffer.
        int _use;     //type of object.
        StringBuilder _domain = new StringBuilder(); //stringBuilder for domain name.
        int _error = 0;
        string _sidString = "";
    
        //first call of the function only returns the sizes of buffers (SDI, domain name)
        LookupAccountName(null, name, _sid, ref _sidLength, _domain, ref _domainLength, out _use);
        _error = Marshal.GetLastWin32Error();
    
        if (_error != 122) //error 122 (The data area passed to a system call is too small) - normal behaviour.
        {
            throw (new Exception(new Win32Exception(_error).Message));
        } else {
            _domain = new StringBuilder(_domainLength); //allocates memory for domain name
            _sid = Marshal.AllocHGlobal(_sidLength); //allocates memory for SID
            bool _rc = LookupAccountName(null, name, _sid, ref _sidLength, _domain, ref _domainLength, out _use);
    
            if (_rc == false) {
                _error = Marshal.GetLastWin32Error();
                Marshal.FreeHGlobal(_sid);
                throw (new Exception(new Win32Exception(_error).Message));
            } else {
                // converts binary SID into string
                _rc = ConvertSidToStringSid(_sid, ref _sidString);
    
                if (_rc == false) {
                    _error = Marshal.GetLastWin32Error();
                    Marshal.FreeHGlobal(_sid);
                    throw (new Exception(new Win32Exception(_error).Message));
                } else {
                    Marshal.FreeHGlobal(_sid);
                    return _sidString;
                }
            }
        }
    }
    
        2
  •  1
  •   crb    12 年前

    这个 LookupAccountName() 本机方法的优点是能够在远程计算机上执行,而.NET方法不能远程执行。

    虽然这个例子没有说明这一点 LookupAccountName(null) <-这是要在其上执行的远程系统。

        3
  •  0
  •   Danil    6 年前
    using System;
    using System.Management;
    using System.Windows.Forms;
    
    namespace WMISample
    {
    public class MyWMIQuery
    {
        public static void Main()
        {
            try
            {
                ManagementObjectSearcher searcher = 
                    new ManagementObjectSearcher("root\\CIMV2", 
                    "SELECT * FROM Win32_UserAccount where name='Galia'"); 
    
                foreach (ManagementObject queryObj in searcher.Get())
                {
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Win32_UserAccount instance");
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Name: {0}", queryObj["Name"]);
                    Console.WriteLine("SID: {0}", queryObj["SID"]);
                }
            }
            catch (ManagementException e)
            {
                MessageBox.Show("An error occurred while querying for WMI 
                data: " + e.Message);
            }
          }
        }
    }
    

    /////////远程:

                ConnectionOptions connection = new ConnectionOptions();
                connection.Username = userNameBox.Text;
                connection.Password = passwordBox.Text;
                connection.Authority = "ntlmdomain:WORKGROUP";
    
                ManagementScope scope = new ManagementScope(
                    "\\\\ASUS\\root\\CIMV2", connection);
                scope.Connect();
    
                ObjectQuery query= new ObjectQuery(
                    "SELECT * FROM Win32_UserAccount"); 
    
                ManagementObjectSearcher searcher = 
                    new ManagementObjectSearcher(scope, query);
    
                foreach (ManagementObject queryObj in searcher.Get())
                {
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Win32_UserAccount instance");
                    Console.WriteLine("-----------------------------------");
                }
    
        4
  •  0
  •   KUL    5 年前
    using System.Security.Principal;
    
    var curUser = WindowsIdentity.GetCurrent().User.Value;
    var otherUser = new WindowsIdentity("kul@mycompany.com").User.Value;