문제

질문이 있습니다 SID에서 계정 이름으로 변환합니다; 다른 방법으로는 없습니다.

예를 들어, 사용자 이름을 SID 문자열로 어떻게 변환하려면, 주어진 이름의 사용자와 어떤 hkey_users 하위 키가 어떤 hkey_users 서브 키를 찾을 수 있습니까?

도움이 되었습니까?

해결책

팟 캐스트는 내가 아직 답변되지 않았을 때 질문하고 답변해야한다고 말합니다. 여기에 간다.

.NET 2.0 이상의 쉬운 방법은 다음과 같습니다.

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;
            }
        }
    }
}

다른 팁

그만큼 LookupAccountName() 기본 방법은 원격 컴퓨터에서 실행할 수 있다는 장점이 있지만 .NET 메서드는 원격으로 실행할 수 없습니다.

예제는 그것을 보여주지 않지만 LookupAccountName(null) <- 이것은 실행할 원격 시스템입니다.

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);
        }
      }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top