Platform SDK: Active Directory, ADSI, and Directory Services

Getting the Domain Account-Style Name of a Group

Users, groups, computers, and other security principals can also be represented in domain account form. Domain account (the logon name used in previous versions of Windows NTŪ) has the following form:

domain\account

where domain is the name of the Windows NT domain that contains the user and account is the samAccountName property of the specified user. For example: Microsoft\jsmith.

The domain account form can be used to specify the trustee in an ACE in a security descriptor. It is also used for the logon name on computers running Windows version NT 4.0 and earlier.

//Need to include the following headers to use DsGetDcName
//#include <LMCONS.H>
//#include <dsgetdc.h>
//#include <lmapibuf.h>
//This function returns the previous version name of the security principal 
//specified by the distinguished name specified by szDN.
//The szDomain parameter should be NULL to use the current domain
//to get the name translation. Otherwise, you should specify the 
//domain you want to use as just the domain name (such as northwestdom) 
//or in dotted format (such as northwestdom.Microsoft.com).
HRESULT GetDownlevelName(LPOLESTR szDomainName, LPOLESTR szDN, LPOLESTR *ppNameString)
{
HRESULT hr = E_FAIL;
IADsNameTranslate *pNameTr = NULL;
IADs *pObject = NULL;
LPOLESTR szPath = new OLECHAR[MAX_PATH];
LPOLESTR szInitDomain = new OLECHAR[MAX_PATH];
BSTR szNameTr;
 
if ((!szDN)||(!ppNameString))
    return hr;
 
//Use the current domain if none is specified.
if (!szDomainName)
{
    //Call DsGetDcName to get the name of this computer's domain.
    PDOMAIN_CONTROLLER_INFO DomainControllerInfo = NULL;
    DWORD dReturn = 0L;
    dReturn = DsGetDcName(  NULL,
                NULL,
                NULL,
                NULL,
                DS_DIRECTORY_SERVICE_REQUIRED,
                &DomainControllerInfo
    );
    if (dReturn==NO_ERROR)
    {
        wcscpy(szInitDomain, DomainControllerInfo->DomainName);
        hr = S_OK;
    }
 
    //Free the buffer.
    if (DomainControllerInfo)
        NetApiBufferFree(DomainControllerInfo);
}
else
{
    wcscpy(szInitDomain, szDomainName);
    hr = S_OK;
}
 

if (SUCCEEDED(hr))
{
 
    //Create the COM object for the IADsNameTranslate object.
    hr  = CoCreateInstance( 
                                CLSID_NameTranslate,
                                NULL,
                                CLSCTX_INPROC_SERVER,
                                IID_IADsNameTranslate,
                                (void **)&pNameTr
                          );
    if (SUCCEEDED(hr))
    {
 
        //Initialize for the specified domain.
        hr = pNameTr->Init(ADS_NAME_INITTYPE_DOMAIN, szInitDomain);
        if (SUCCEEDED(hr))
        {
            hr = pNameTr->Set(ADS_NAME_TYPE_1779, szDN);
            hr = pNameTr->Get(ADS_NAME_TYPE_NT4, &szNameTr);
            if (SUCCEEDED(hr))
            {
                *ppNameString = (OLECHAR *)CoTaskMemAlloc (sizeof(OLECHAR)*(wcslen(szNameTr)+1));
                if (*ppNameString)
                    wcscpy(*ppNameString, szNameTr);
                else
                    hr=E_FAIL;
            }
        }
    }
    if (pNameTr)
       pNameTr->Release();
}
 
//Caller must call CoTaskMemFree to free ppNameString.
return hr;
}