Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Finding Trusted Domain Names

Posted on 1997-05-09
5
Medium Priority
?
493 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

 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

Question has a verified solution.

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

This article describes a technique for converting RTF (Rich Text Format) data to HTML and provides C++ source that does it all in just a few lines of code. Although RTF is coming to be considered a "legacy" format, it is still in common use... po…
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
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…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…

636 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