簡體   English   中英

從會話ID獲取完整的Windows域名

[英]Get the full windows domain name from a session id

我正在研究需要監視Windows會話更改並在特定用戶登錄后自動啟動應用程序的服務應用程序。

這是它的工作方式,我有一個文件,其中包含以用戶主體名稱格式(user@domain.LOCAL)存儲的Windows用戶名列表。 我的服務將監視任何會話更改,並在其中一個用戶登錄后采取某些措施。

List<string> _UsersList;
 object _sessionCheckLock = new object();
        void OnCheckSession(int nSessionId, bool bIsLoggIn)
        {
            lock(_sessionCheckLock)
            {
                try
                {
                    string sUserName = string.Empty;
                    string sDomain = string.Empty;

                    IntPtr pUserName = IntPtr.Zero;
                    uint nBytesReturned = 0;
                    if (WTSQuerySessionInformation(IntPtr.Zero, (uint)nSessionId, WTS_INFO_CLASS.WTSUserName, out pUserName, out nBytesReturned) && (pUserName != IntPtr.Zero))
                    {
                        sUserName = Marshal.PtrToStringAnsi(pUserName);

                        WTSFreeMemory(pUserName);

                        IntPtr pDomain = IntPtr.Zero;
                        if(WTSQuerySessionInformation(IntPtr.Zero, (uint)nSessionId, WTS_INFO_CLASS.WTSDomainName, out pDomain, out nBytesReturned) && (pDomain != IntPtr.Zero))
                        {
                            sDomain = Marshal.PtrToStringAnsi(pDomain);
                            WTSFreeMemory(pDomain);
                        }
                        else
                        {

                        }

                        if (!string.IsNullOrEmpty(sUserName))
                        {
                          if(!string.IsNullOrEmpty(sDomain)
                          {
                              sUserName += "@" + sDomain;
                          }

                            foreach(string username in _UsersList)
                            {
                               if(string.Compare(sUsername, username, true)==0)
                               {
                                //Do a couple of things
                                return;
                               }
                            }

                        }
                    }
                    else
                    {
                        return;
                    }
                }
                catch (System.Exception ex)
                {

                }
            }
        }

上面的代碼是每當引發新的登錄事件時我調用的函數。 _UsersList是一個字符串列表,其中包含允許該服務使用的所有用戶名。 這里的問題是WTSQuerySessionInformationWTS_INFO_CLASS.WTSDomainName使用時不返回域的全名,因此比較失敗。例如,如果用戶列表中存在一個名為(username@DOMAIN.LOCAL)的用戶名並登錄,查詢會話的域名時,它僅返回(DOMAIN),而沒有.LOCAL附錄。 我需要找到一種方法來獲取完整的域名以匹配列表中的域名。

有人可以幫忙嗎

查看Cassia.Net,這是非常有用的。

您可以下載源代碼,我將其用於一個項目,在該項目中,我必須獲取所有已登錄到服務器的用戶。

決明子.NET Windows終端服務/遠程桌面服務庫

http://code.google.com/p/cassia/

希望能有所幫助

WTsmainName顯示用戶所屬的域-我找不到任何明確的文檔,但是我認為它獲取的是netBios名稱,而不是FQDN。 您應該能夠使用USERDNSDOMAIN和USERDOMAIN這兩個環境變量來保存這些值。

您也可以使用ADSI進行更詳細的查找,在此處查看線程

但這一切都說明了,除非您擁有一個令人難以置信的復雜林結構,並且用戶從樹中的許多不同域中登錄,否則...將轉換硬編碼到您的應用中可能會更快。 它們並不是經常更改的東西,從新域登錄的用戶也應該很少。

紅蛇,決明子真的有幫助嗎? 我遇到了與您相同的問題,但是Cassia似乎在下面使用了相同的WTSQuerySessionInformation調用,因此我仍然只得到了簡短的域名。

頁面上,我找到了對DsGetDcName函數的引用,我可以使用該函數使用WTSQuerySessionInformation給我的短域名獲取FQDN。 這是適合我的示例:

std::wstring GetSessionDomainName(DWORD sessionId)
{
    std::wstring domainName;
    LPWSTR buffer = NULL;
    DWORD bufferSize = 0;

    if(WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSDomainName, &buffer, &bufferSize))
    {
        PDOMAIN_CONTROLLER_INFOW domainControllerInfo = NULL;
        DWORD retVal = DsGetDcNameW(NULL, buffer, NULL, NULL, DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME, &domainControllerInfo);
        if (retVal == 0)
            domainName = domainControllerInfo->DnsForestName;

        WTSFreeMemory(buffer);
        NetApiBufferFree(domainControllerInfo);
    }

    return domainName;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM