Solved

Finding Trusted Domain Names

Posted on 1997-05-09
5
484 Views
Last Modified: 2013-12-04
I am sitting on a workstation called W. W is part of a
domain called D. The PDC of this domain is P. P trusts
another domain called T. Likewise, T trusts P.

Using the NetWkstaGetInfo, NetServerEnum, and NetUserEnum
calls, I can get the users on the W and on P.

How do I get the users (and thus global groups) on the
trusted domain(s), like T? How do I find out what domains
are trusted by P, and thus, the ones I want to get the
users and groups from.

The 3.51 File Manager does this in its Permissions tab
by letting you assign ACEs to a file based on SIDs from
the local system, the pdc, and any trusted domains. I
just don't see a call to get a list of trusted domains
for a PDC.

Thanks,
Jack
0
Comment
Question by:jacks
  • 3
  • 2
5 Comments
 
LVL 1

Accepted Solution

by:
ete earned 60 total points
Comment Utility
Hello jacks,

You can try a call to NetWkstaUserGetInfo() API. Give as the second parameter 1101, which specifies that WKSTA_USER_INFO_1101 structure. It is returned in the third parameter.

This structure contains only one element:

LPTSTR wkui1101_oth_domains

This will contain the names of the domains browsed by this workstation.

Regards
ETE
0
 

Author Comment

by:jacks
Comment Utility
Ete:

The NetWkstaUserGetInfo call with a 1101 level only returns
the trusted domains for the workstation, W. I need to find
the trusted domains of the PDC, P. Since NetWkstaUserGetInfo
does not take anything for parameter 1 besides NULL, there is
no way to tell it to return the trusted domains for P.

I tested this on my workstation, Viola, which is part of domain
Borg, which has PDC Peabody. Peabody trusts Void, and Void
trusts Peabody. A NetWkstaGetUserInfo run on Viola returns a
NULL string in the wkui1101_oth_domains field.

Is there something I am missing here, or do you have any other
ideas?

Thanks,
jacks
Jack Stansbury

0
 

Author Comment

by:jacks
Comment Utility
Ete:

The NetWkstaUserGetInfo call with a 1101 level only returns
the trusted domains for the workstation, W. I need to find
the trusted domains of the PDC, P. Since NetWkstaUserGetInfo
does not take anything for parameter 1 besides NULL, there is
no way to tell it to return the trusted domains for P.

I tested this on my workstation, Viola, which is part of domain
Borg, which has PDC Peabody. Peabody trusts Void, and Void
trusts Peabody. A NetWkstaGetUserInfo run on Viola returns a
NULL string in the wkui1101_oth_domains field.

Is there something I am missing here, or do you have any other
ideas?

Thanks,
jacks
Jack Stansbury

0
 
LVL 1

Expert Comment

by:ete
Comment Utility
Hello Jack

Your previous comment clarified your goal quite much and invited me to write two sample functions:

DxNetGetAllVisibleDomains()
DxNetGetAllTrustingDomains()

They are coded with MS Visual C++ 4.2 and naturally require unicode support to be turned on.

I will list the source code later. The first function lists all the accessible domains, including the one where you belong. The latter one lists the inter-domain trust accounts in a specified domain. Both take one argument, which can be NULL, empty string or any accesible domain.

The first sample functions lists all those Trust-related domains, whose PDC is currently available. This feature might be quite useful for your purposes (?).

The second function utilizes one interesting feature in NT internals. When trust relationship is established, a corresponding "hidden" user account is created. The user name is generated from the domain name by adding a dollar sign ($) at the end. Just clear it out to get the domain names.

When you can get the domain names, you can get the PDCs and the door is open for your program.

I do not have an NT wks at home, so the sample code is not fully tested. I have two NT 4.0 domains with trust relations, though, and I was testing the code with server version.

I hope this helps you
Best regards,
ETE

LISTING:

/***********************************************************************
 * Name                  DxNetGetAllVisibleDomains()
 *
 * Description      Lists all accessible domains
 *
 * APIs            ZeroMemory
 *              MultiByteToWideChar
 *              NetGetDCName
 *              NetServerEnum
 *              MessageBox
 *              GetFocus
 *              NetApiBufferFree
 *
 * Parameters       LPTSTR      -name of the domain from where
 *                           to start searching
 *
 * Returns            INT
 *
 * Comment      This sample can easily be transformed to an
 *              powerful search tool
 *
\***********************************************************************/
INT APIENTRY DxNetGetAllVisibleDomains(LPTSTR lptstrDomain)
{
    LPSERVER_INFO_101 lpServer_info_101 = NULL;

    LPWSTR          lpwstrPrimaryDC = NULL;
    NET_API_STATUS  iError          = 0;
    DWORD           dwParm_err      = 0;

    CHAR   chDomain[256]            = "";
    WCHAR  wchDomain[256];
    LPWSTR lpDomainOrNull           = NULL;

    DWORD dwServerType              = 0;
    DWORD dwEntriesRead             = 0;
    DWORD dwTotalEntries            = 0;
    DWORD dwResumeHandle            = 0;
    DWORD dwIndex                   = 0;

    ZeroMemory((PVOID)wchDomain, sizeof(wchDomain));

    //If Domain name given
    if(lptstrDomain)
    {
         //if it is not an empty string
         if(strcmp(chDomain, ""))
         {
            //Visual Basic compatibility
              strncpy(chDomain, (const char *)lptstrDomain, sizeof(chDomain));
        
              MultiByteToWideChar(CP_ACP,
                              0,
                            chDomain,
                                  strlen(chDomain)+1,
                           (LPWSTR)wchDomain,
                            sizeof(wchDomain));

              lpDomainOrNull = (LPWSTR)wchDomain;
         }
    }

    iError = NetGetDCName(NULL,                       /* Local Machine */
                          lpDomainOrNull,             /* Domain Name */
                         (LPBYTE *)&lpwstrPrimaryDC );/* returned PDC */

    if(iError != NERR_Success)
        return -10;

    //Changing the following flag allows you to search
    //for many different types of computers from the
    //network (PDC,BDC,SQL,NOVELL,PRINT,XENIX, W95, ETC

      dwServerType = SV_TYPE_DOMAIN_ENUM;
      iError       = ERROR_MORE_DATA;

    while(iError == ERROR_MORE_DATA)
    {
        iError = NetServerEnum(lpwstrPrimaryDC,
                               101,
                        (LPBYTE *)&lpServer_info_101,
                         1024,
                              (LPDWORD)&dwEntriesRead,
                        (LPDWORD)&dwTotalEntries,
                         dwServerType,
                         lpDomainOrNull,
                        (LPDWORD)&dwResumeHandle);

        if((iError == NERR_Success)||
           (iError == ERROR_MORE_DATA))
        {
             for(dwIndex = 0; dwIndex < dwEntriesRead; dwIndex++)
           {
                 MessageBox(GetFocus(),
                      lpServer_info_101[dwIndex].sv101_name,
                      L"Found Accessible Domain for given PDC",
                      MB_OK);
           }
      }
        NetApiBufferFree((LPVOID)lpServer_info_101);
    }

    NetApiBufferFree(lpwstrPrimaryDC);
   

    switch(iError)
    {
    case NERR_Success:
         break;

    case ERROR_ACCESS_DENIED:
         return -20;

    case NERR_InvalidComputer:
         return -30;

    case ERROR_NO_BROWSER_SERVERS_FOUND:
           return -40;

    default:
         return -100;
    }

      return 0;
}                       /* End of DxNetGetAllVisibleDomains() */

/***********************************************************************
 * Name                  DxNetGetAllTrustingDomains()
 *
 * Description      Retrieve the names of all the domain accounts, which are
 *              trusting on this domain
 *
 * APIs            ZeroMemory
 *              MultiByteToWideChar
 *              NetGetDCName
 *              NetUserEnum
 *              MessageBox
 *              GetFocus
 *              NetApiBufferFree
 *
 * Parameters       LPTSTR      -name of the domain from where
 *                           to start searching
 *
 * Returns            INT
 *
 * Comment      Inter-Domain trust accounts end in $-sign.
 *              Remove it out, and you have the trusting
 *              domain name
 *
\***********************************************************************/
INT APIENTRY DxNetGetAllTrustingDomains(LPTSTR lptstrDomain)
{
    LPUSER_INFO_2   lpUser_info_2   = NULL;
    LPWSTR          lpwstrPrimaryDC = NULL;
    NET_API_STATUS  iError          = 0;
    DWORD           dwParm_err      = 0;

    CHAR chDomain[256]              = "";
    WCHAR wchDomain[256];

    DWORD dwEntriesRead             = 0;
    DWORD dwTotalEntries            = 0;
    DWORD dwResumeHandle            = 0;
    DWORD dwIndex                   = 0;

    ZeroMemory((PVOID)wchDomain, sizeof(wchDomain));

    //If Domain name given
    if(lptstrDomain)
    {
       //Visual Basic compatibility
       strncpy(chDomain, (const char *)lptstrDomain, sizeof(chDomain));

       MultiByteToWideChar(CP_ACP,
                       0,
                     chDomain,
                           strlen(chDomain)+1,
                        (LPWSTR)wchDomain,
                     sizeof(wchDomain));
       //API calls in this sample accept also an empty string

    }
    iError = NetGetDCName(NULL,    
                         (LPWSTR)wchDomain,  
                         (LPBYTE *)&lpwstrPrimaryDC );

    if(iError != NERR_Success)
        return -10;

    iError = ERROR_MORE_DATA;


    while(iError == ERROR_MORE_DATA)
    {
        iError = NetUserEnum(lpwstrPrimaryDC,
                           2,
                         FILTER_INTERDOMAIN_TRUST_ACCOUNT,
                              (LPBYTE *)&lpUser_info_2,
                         UNLEN,
                              (LPDWORD)&dwEntriesRead,
                        (LPDWORD)&dwTotalEntries,
                        (LPDWORD)&dwResumeHandle);
        if((iError == NERR_Success)||
           (iError == ERROR_MORE_DATA))
        {
            for(dwIndex = 0; dwIndex < dwEntriesRead; dwIndex++)
          {
            MessageBox(GetFocus(),
                       lpUser_info_2[dwIndex].usri2_name,
                           L"Found a Domain Trust Account",
                     MB_OK);
          }
      }
        NetApiBufferFree((LPVOID)lpUser_info_2);
    }

    NetApiBufferFree(lpwstrPrimaryDC);
   
    switch(iError)
    {
    case NERR_Success:
         break;

    case ERROR_ACCESS_DENIED:
         return -20;

    case NERR_InvalidComputer:
         return -30;

    case NERR_NotPrimary:
         return -40;

    case NERR_SpeGroupOp:
         return -50;

    case NERR_UserNotFound:
         return -60;

    case NERR_BadPassword:
         return -70;

    case NERR_LastAdmin:
         return -80;

    case NERR_PasswordTooShort:
         return -90;

    default:
         return -100;
    }

      return 0;
}                       /* End of DxNetGetAllTrustingDomains() */


0
 
LVL 1

Expert Comment

by:ete
Comment Utility
Huh huh. The tabs and spacing on the source listing lines look terrible, but I hope you can cope with it...
ETE
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now