Enumerating Domain/Realm for login Form

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


Answer this question

Enumerating Domain/Realm for login Form

  • Paul James

    System.Net does not provide a managed implementation; however, you will want to look into the System.DirectoryServices namespace as it might expose this functionality.

  • 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


  • Enumerating Domain/Realm for login Form