Hello,
I am a .NET newbie. I want to write Login Form similar to Windows Login Dialog in one of my applications say MyApp. Here are my requirements.
1. The login form contains Login ID, password and Realm fields.
2. The realm is a combo box which should list the following items
a. "MyApp SQL Server Database"
b. A List of all available NT domains which can authenticate a user/password from the machine on which MyApp is running.
c. Any Active Directory Servers which can validate a user name/password from the machine on which MyApp is running.
Now given these requirements, here are my questions
1. How to enumerate the names that I can show in the 2b and 2c using .NET
2. Assuming, the iteration is done, how can I validate the user name and password in the cases 2b and 2c.
I know the Win32 way of doing them and so can use unmanaged code to invoke those methods. But I want my app to be completely managed.
Please suggest me any pointers or info to proceed.
Thanx & Regards

Enumerating Domain/Realm for login Form
Paul James
Citius
Please list the win32 APIs you are using. We can then tell you if there is a managed alternative.
Anrijs Vitolins
Vijaye Raji
Hello Mike,
Here is a code fragment I used in one of my VC++6.0 apps.
If the DsEnumerateDomainTrustsA is present on the system, I use it. Otherwise, I use LsaEnumerateTrustedDomains.
long EnumerateTrustsNT(LSA_HANDLE PolicyHandle, CStringArray& astrServers)
{
LSA_ENUMERATION_HANDLE hEnum=0;
PLSA_TRUST_INFORMATION TrustInfo = NULL;
ULONG ulReturned = 0;
NTSTATUS Status = 0;
ULONG i;
WCHAR StringBuffer[256];
//Enumerate the trusted domains until there are no more to return.
do
{
Status = LsaEnumerateTrustedDomains(PolicyHandle,
&hEnum,
(void**)&TrustInfo,
32000,
&ulReturned
);
//Check the return status for errors.
if((Status != STATUS_SUCCESS) &&
(Status != STATUS_MORE_ENTRIES) &&
(Status != STATUS_NO_MORE_ENTRIES))
{
return astrServers.GetSize();
}
// Process the trusted domain information.
for (i=0;i<ulReturned; i++)
{
// LSA_Unicode strings may not be null terminated.
wcsncpy(StringBuffer, TrustInfo['i].Name.Buffer, TrustInfo['i].Name.Length);
astrServers.Add(StringBuffer);
}
// Free the buffer.
if (TrustInfo != NULL)
{
LsaFreeMemory(TrustInfo);
TrustInfo = NULL;
}
} while (Status != STATUS_NO_MORE_ENTRIES);
return astrServers.GetSize();
}
long CLogonDialog::EnumServers(CStringArray& astrServers)
{
DWORD dwTemp;
astrServers.RemoveAll();
astrServers.Add(_T(""));
dwTemp = MAX_PATH;
GetComputerName(astrServers[0].GetBuffer(MAX_PATH), &dwTemp);
astrServers[0].ReleaseBuffer();
PDS_DOMAIN_TRUSTSA pDSDT = NULL;
ULONG ulDSDT = 0;
CDynamicLibrary::LPDsEnumerateDomainTrustsA pFN = theDynLib.GetDsEnumerateDomainTrustsA();
if(NULL != pFN)
{
if(NO_ERROR == pFN(NULL, DS_DOMAIN_VALID_FLAGS, &pDSDT, &ulDSDT))
{
for(ULONG uItem = 0 ; uItem < ulDSDT ; ++uItem)
{
USES_CONVERSION;
astrServers.Add(A2T(pDSDT[uItem].NetbiosDomainName));
}
NetApiBufferFree(pDSDT);
}
}
else
{
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
WCHAR* SystemName = NULL;
USHORT SystemNameLength;
LSA_UNICODE_STRING lusSystemName;
NTSTATUS ntsResult;
LSA_HANDLE lsahPolicyHandle;
// Object attributes are reserved, so initialize to zeroes.
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
//Initialize an LSA_UNICODE_STRING to the server name.
SystemNameLength = USHORT(0);
lusSystemName.Buffer = SystemName;
lusSystemName.Length = USHORT(SystemNameLength * sizeof(WCHAR));
lusSystemName.MaximumLength= USHORT((SystemNameLength+1) * sizeof(WCHAR));
// Get a handle to the Policy object.
ntsResult = LsaOpenPolicy(NULL, //Name of the target system.
&ObjectAttributes,
POLICY_ALL_ACCESS, //Desired access permissions.
&lsahPolicyHandle //Receives the policy handle.
);
if (ntsResult == STATUS_SUCCESS)
{
EnumerateTrustsNT(lsahPolicyHandle, astrServers);
}
LsaClose(lsahPolicyHandle);
}
return astrServers.GetSize();
}
Thanx & Regards