?
Solved

Finding Trusted Domain Names

Posted on 1997-05-09
5
Medium Priority
?
492 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 1

Accepted Solution

by:
ete earned 120 total points
ID: 1397223
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
ID: 1397224
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
ID: 1397225
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
ID: 1397226
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
ID: 1397227
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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is about how to put some of your C++ program's functionality into a standard DLL, and how to make working with the EXE and the DLL simple and seamless.   We'll be using Microsoft Visual Studio 2008 and we will cut out the noise; that i…
This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
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…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…

762 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