home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 27 / IOPROG_27.ISO / SOFT / ADSDK.ZIP / Samples / ActiveDir / QueryUsers / vc / queryusers.cpp next >
Encoding:
C/C++ Source or Header  |  1999-04-05  |  13.2 KB  |  449 lines

  1. // attributes.cpp : Defines the entry point for the console application.
  2. //
  3. #include <objbase.h>
  4. #include <wchar.h>
  5. #include <activeds.h>
  6. //Make sure you define UNICODE
  7. //Need to define version 5 for Windows 2000
  8. #define _WIN32_WINNT 0x0500
  9.  
  10.  
  11. #include <sddl.h>
  12.  
  13. HRESULT FindUsers(IDirectorySearch *pContainerToSearch,  //IDirectorySearch pointer to the container to search.
  14.          LPOLESTR szFilter, //Filter for finding specific users.
  15.                             //NULL returns all user objects.
  16.          LPOLESTR *pszPropertiesToReturn, //Properties to return for user objects found
  17.                                         //NULL returns all set properties.
  18.          BOOL bIsVerbose //TRUE means display all properties for the found objects are displayed.
  19.                          //FALSE means only the RDN
  20.                             );
  21.  
  22.  
  23.  
  24.  
  25. void wmain( int argc, wchar_t *argv[ ])
  26. {
  27.  
  28. //Handle the command line arguments.
  29. LPOLESTR pszBuffer = new OLECHAR[MAX_PATH*2];
  30. wcscpy(pszBuffer, L"");
  31. BOOL bReturnVerbose = FALSE;
  32.  
  33. for (int i = 1;i<argc;i++)
  34. {
  35.     if (_wcsicmp(argv[i],L"/V") == 0)
  36.     {
  37.         bReturnVerbose = TRUE;
  38.     }
  39.     else if ((_wcsicmp(argv[i],L"/?") == 0)||
  40.              (_wcsicmp(argv[i],L"-?") == 0))
  41.     {
  42.         wprintf(L"This program queries for users in the current user's domain.\n");
  43.         wprintf(L"Syntax: queryusers [/V][querystring]\n");
  44.         wprintf(L"where /V specifies that all properties for the found users should be returned.\n");
  45.         wprintf(L"      querystring is the query criteria in ldap query format.\n");
  46.         wprintf(L"Defaults: If no /V is specified, the query returns only the RDN and DN of the items found.\n");
  47.         wprintf(L"          If no querystring is specified, the query returns all users.\n");
  48.         wprintf(L"Example: queryusers (sn=Smith)\n");
  49.         wprintf(L"Returns all users with surname Smith.\n");
  50.         return;
  51.     }
  52.     else
  53.     {
  54.         wcscpy(pszBuffer,argv[i]);
  55.     }
  56. }
  57. if (_wcsicmp(pszBuffer,L"") == 0)
  58.   wprintf(L"\nFinding all user objects...\n\n");
  59. else
  60.   wprintf(L"\nFinding user objects based on query: %s...\n\n", pszBuffer);
  61.     
  62. //Initialize COM
  63. CoInitialize(NULL);
  64. HRESULT hr = S_OK;
  65. //Get rootDSE and the current user's domain container DN.
  66. IADs *pObject = NULL;
  67. IDirectorySearch *pContainerToSearch = NULL;
  68. LPOLESTR szPath = new OLECHAR[MAX_PATH];
  69. VARIANT var;
  70. hr = ADsOpenObject(L"LDAP://rootDSE",
  71.                  NULL,
  72.                  NULL,
  73.                  ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  74.                  IID_IADs,
  75.                  (void**)&pObject);
  76. if (FAILED(hr))
  77. {
  78.    wprintf(L"Could not execute query. Could not bind to LDAP://rootDSE.\n");
  79.    if (pObject)
  80.      pObject->Release();
  81.    return;
  82. }
  83. if (SUCCEEDED(hr))
  84. {
  85.     hr = pObject->Get(L"defaultNamingContext",&var);
  86.     if (SUCCEEDED(hr))
  87.     {
  88.         //Build path to the domaon container.
  89.         wcscpy(szPath,L"LDAP://");
  90.         wcscat(szPath,var.bstrVal);
  91.         hr = ADsOpenObject(szPath,
  92.                          NULL,
  93.                          NULL,
  94.                          ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  95.                          IID_IDirectorySearch,
  96.                          (void**)&pContainerToSearch);
  97.  
  98.         if (SUCCEEDED(hr))
  99.         {
  100.             hr = FindUsers(pContainerToSearch, //IDirectorySearch pointer to Partitions container.
  101.                      pszBuffer,  
  102.                      NULL, //Return all properties
  103.                      bReturnVerbose 
  104.                  );
  105.             if (SUCCEEDED(hr))
  106.             {
  107.                 if (S_FALSE==hr)
  108.                    wprintf(L"No user object could be found.\n");
  109.             }
  110.             else if (0x8007203e==hr)
  111.                 wprintf(L"Could not execute query. An invalid filter was specified.\n");
  112.             else
  113.                 wprintf(L"Query failed to run. HRESULT: %x\n",hr);
  114.         }
  115.         else
  116.         {
  117.            wprintf(L"Could not execute query. Could not bind to the container.\n");
  118.         }
  119.         if (pContainerToSearch)
  120.            pContainerToSearch->Release();
  121.     }
  122.     VariantClear(&var);
  123. }
  124. if (pObject)
  125.     pObject->Release();
  126.  
  127. // Uninitialize COM
  128. CoUninitialize();
  129. return;
  130. }
  131.  
  132.  
  133.  
  134.  
  135.  
  136. HRESULT FindUsers(IDirectorySearch *pContainerToSearch,  //IDirectorySearch pointer to Partitions container.
  137.          LPOLESTR szFilter, //Filter for finding specific crossrefs.
  138.                             //NULL returns all attributeSchema objects.
  139.          LPOLESTR *pszPropertiesToReturn, //Properties to return for crossRef objects found
  140.                                         //NULL returns all set properties.
  141.          BOOL bIsVerbose //TRUE means all properties for the found objects are displayed.
  142.                          //FALSE means only the RDN
  143.                             )
  144. {
  145.     if (!pContainerToSearch)
  146.         return E_POINTER;
  147.     //Create search filter
  148.     LPOLESTR pszSearchFilter = new OLECHAR[MAX_PATH*2];
  149.  
  150.     //Add the filter.
  151.     wsprintf(pszSearchFilter, L"(&(objectClass=user)(objectCategory=person)%s)",szFilter);
  152.  
  153.     //Specify subtree search
  154.     ADS_SEARCHPREF_INFO SearchPrefs;
  155.     SearchPrefs.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  156.     SearchPrefs.vValue.dwType = ADSTYPE_INTEGER;
  157.     SearchPrefs.vValue.Integer = ADS_SCOPE_SUBTREE;
  158.     DWORD dwNumPrefs = 1;
  159.  
  160.     // COL for iterations
  161.     LPOLESTR pszColumn = NULL;    
  162.     ADS_SEARCH_COLUMN col;
  163.     HRESULT hr;
  164.     
  165.     // Interface Pointers
  166.     IADs    *pObj = NULL;
  167.     IADs    * pIADs = NULL;
  168.  
  169.     // Handle used for searching
  170.     ADS_SEARCH_HANDLE hSearch = NULL;
  171.     
  172.     // Set the search preference
  173.     hr = pContainerToSearch->SetSearchPreference( &SearchPrefs, dwNumPrefs);
  174.     if (FAILED(hr))
  175.         return hr;
  176.  
  177.     LPOLESTR pszBool = NULL;
  178.     DWORD dwBool;
  179.     PSID pObjectSID = NULL;
  180.     LPOLESTR szSID = NULL;
  181.     LPOLESTR szDSGUID = new WCHAR [39];
  182.     LPGUID pObjectGUID = NULL;
  183.     FILETIME filetime;
  184.     SYSTEMTIME systemtime;
  185.     DATE date;
  186.     VARIANT varDate;
  187.     LARGE_INTEGER liValue;
  188.     LPOLESTR *pszPropertyList = NULL;
  189.     LPOLESTR pszNonVerboseList[] = {L"name",L"distinguishedName"};
  190.  
  191.     LPOLESTR szName = new OLECHAR[MAX_PATH];
  192.     LPOLESTR szDN = new OLECHAR[MAX_PATH];
  193.  
  194.     int iCount = 0;
  195.     DWORD x = 0L;
  196.  
  197.  
  198.  
  199.     if (!bIsVerbose)
  200.     {
  201.          //Return non-verbose list properties only
  202.          hr = pContainerToSearch->ExecuteSearch(pszSearchFilter,
  203.                                   pszNonVerboseList,
  204.                                   sizeof(pszNonVerboseList)/sizeof(LPOLESTR),
  205.                                   &hSearch
  206.                                   );
  207.     }
  208.     else
  209.     {
  210.         if (!pszPropertiesToReturn)
  211.         {
  212.             //Return all properties.
  213.             hr = pContainerToSearch->ExecuteSearch(pszSearchFilter,
  214.                                   NULL,
  215.                                   0L,
  216.                                   &hSearch
  217.                                   );
  218.         }
  219.         else
  220.         {
  221.             //specified subset.
  222.             pszPropertyList = pszPropertiesToReturn;
  223.            //Return specified properties
  224.            hr = pContainerToSearch->ExecuteSearch(pszSearchFilter,
  225.                                   pszPropertyList,
  226.                                   sizeof(pszPropertyList)/sizeof(LPOLESTR),
  227.                                   &hSearch
  228.                                   );
  229.         }
  230.     }
  231.      if ( SUCCEEDED(hr) )
  232.     {    
  233.     // Call IDirectorySearch::GetNextRow() to retrieve the next row 
  234.     //of data
  235.       hr = pContainerToSearch->GetFirstRow( hSearch);
  236.       if (SUCCEEDED(hr))
  237.       {
  238.         while( hr != S_ADS_NOMORE_ROWS )
  239.         {
  240.             //Keep track of count.
  241.             iCount++;
  242.             if (bIsVerbose)
  243.               wprintf(L"----------------------------------\n");
  244.             // loop through the array of passed column names,
  245.             // print the data for each column
  246.  
  247.             while( pContainerToSearch->GetNextColumnName( hSearch, &pszColumn ) != S_ADS_NOMORE_COLUMNS )
  248.             {
  249.                 hr = pContainerToSearch->GetColumn( hSearch, pszColumn, &col );
  250.                 if ( SUCCEEDED(hr) )
  251.                 {
  252.                     // Print the data for the column and free the column
  253.                   if(bIsVerbose)
  254.                   {
  255.                     // Get the data for this column
  256.                     wprintf(L"%s\n",col.pszAttrName);
  257.                     switch (col.dwADsType)
  258.                     {
  259.                         case ADSTYPE_DN_STRING:
  260.                           for (x = 0; x< col.dwNumValues; x++)
  261.                           {
  262.                               wprintf(L"  %s\r\n",col.pADsValues[x].DNString);
  263.                           }
  264.                           break;
  265.                         case ADSTYPE_CASE_EXACT_STRING:        
  266.                         case ADSTYPE_CASE_IGNORE_STRING:        
  267.                         case ADSTYPE_PRINTABLE_STRING:        
  268.                         case ADSTYPE_NUMERIC_STRING:            
  269.                         case ADSTYPE_TYPEDNAME:                
  270.                         case ADSTYPE_FAXNUMBER:                
  271.                         case ADSTYPE_PATH:                    
  272.                         case ADSTYPE_OBJECT_CLASS:
  273.                           for (x = 0; x< col.dwNumValues; x++)
  274.                           {
  275.                               wprintf(L"  %s\r\n",col.pADsValues[x].CaseIgnoreString);
  276.                           }
  277.                           break;
  278.                         case ADSTYPE_BOOLEAN:
  279.                           for (x = 0; x< col.dwNumValues; x++)
  280.                           {
  281.                               dwBool = col.pADsValues[x].Boolean;
  282.                               pszBool = dwBool ? L"TRUE" : L"FALSE";
  283.                               wprintf(L"  %s\r\n",pszBool);
  284.                           }
  285.                           break;
  286.                         case ADSTYPE_INTEGER:
  287.                           for (x = 0; x< col.dwNumValues; x++)
  288.                           {
  289.                               wprintf(L"  %d\r\n",col.pADsValues[x].Integer);
  290.                           }
  291.                           break;
  292.                         case ADSTYPE_OCTET_STRING:
  293.                             if ( _wcsicmp(col.pszAttrName,L"objectSID") == 0 )
  294.                             {
  295.                               for (x = 0; x< col.dwNumValues; x++)
  296.                               {
  297.                                   pObjectSID = (PSID)(col.pADsValues[x].OctetString.lpValue);
  298.                                   //Convert SID to string.
  299.                                   ConvertSidToStringSid(pObjectSID, &szSID);
  300.                                   wprintf(L"  %s\r\n",szSID);
  301.                                   LocalFree(szSID);
  302.                               }
  303.                             }
  304.                             else if ( (_wcsicmp(col.pszAttrName,L"objectGUID") == 0) )
  305.                             {
  306.                               for (x = 0; x< col.dwNumValues; x++)
  307.                               {
  308.                                 //Cast to LPGUID
  309.                                 pObjectGUID = (LPGUID)(col.pADsValues[x].OctetString.lpValue);
  310.                                 //Convert GUID to string.
  311.                                 ::StringFromGUID2(*pObjectGUID, szDSGUID, 39); 
  312.                                 //Print the GUID
  313.                                 wprintf(L"  %s\r\n",szDSGUID);
  314.                               }
  315.                             }
  316.                             else
  317.                               wprintf(L"  Value of type Octet String. No Conversion.");
  318.                             break;
  319.                         case ADSTYPE_UTC_TIME:
  320.                           for (x = 0; x< col.dwNumValues; x++)
  321.                           {
  322.                             systemtime = col.pADsValues[x].UTCTime;
  323.                             if (SystemTimeToVariantTime(&systemtime,
  324.                                                         &date) != 0) 
  325.                             {
  326.                                 //Pack in variant.vt
  327.                                 varDate.vt = VT_DATE;
  328.                                 varDate.date = date;
  329.                                 VariantChangeType(&varDate,&varDate,VARIANT_NOVALUEPROP,VT_BSTR);
  330.                                 wprintf(L"  %s\r\n",varDate.bstrVal);
  331.                                 VariantClear(&varDate);
  332.                             }
  333.                             else
  334.                                 wprintf(L"  Could not convert UTC-Time.\n",pszColumn);
  335.                           }
  336.                           break;
  337.                         case ADSTYPE_LARGE_INTEGER:
  338.                           for (x = 0; x< col.dwNumValues; x++)
  339.                           {
  340.                             liValue = col.pADsValues[x].LargeInteger;
  341.                             filetime.dwLowDateTime = liValue.LowPart;
  342.                             filetime.dwHighDateTime = liValue.HighPart;
  343.                             if((filetime.dwHighDateTime==0) && (filetime.dwLowDateTime==0))
  344.                             {
  345.                                 wprintf(L"  No value set.\n");
  346.                             }
  347.                             else
  348.                             {
  349.                                 //Check for properties of type LargeInteger that represent time
  350.                                 //if TRUE, then convert to variant time.
  351.                                 if ((0==wcscmp(L"accountExpires", col.pszAttrName))|
  352.                                     (0==wcscmp(L"badPasswordTime", col.pszAttrName))||
  353.                                     (0==wcscmp(L"lastLogon", col.pszAttrName))||
  354.                                     (0==wcscmp(L"lastLogoff", col.pszAttrName))||
  355.                                     (0==wcscmp(L"lockoutTime", col.pszAttrName))||
  356.                                     (0==wcscmp(L"pwdLastSet", col.pszAttrName))
  357.                                    )
  358.                                 {
  359.                                     //Handle special case for Never Expires where low part is -1
  360.                                     if (filetime.dwLowDateTime==-1)
  361.                                     {
  362.                                         wprintf(L"  Never Expires.\n");
  363.                                     }
  364.                                     else
  365.                                     {
  366.                                         if (FileTimeToLocalFileTime(&filetime, &filetime) != 0) 
  367.                                         {
  368.                                             if (FileTimeToSystemTime(&filetime,
  369.                                                                  &systemtime) != 0)
  370.                                             {
  371.                                                 if (SystemTimeToVariantTime(&systemtime,
  372.                                                                             &date) != 0) 
  373.                                                 {
  374.                                                     //Pack in variant.vt
  375.                                                     varDate.vt = VT_DATE;
  376.                                                     varDate.date = date;
  377.                                                     VariantChangeType(&varDate,&varDate,VARIANT_NOVALUEPROP,VT_BSTR);
  378.                                                     wprintf(L"  %s\r\n",varDate.bstrVal);
  379.                                                     VariantClear(&varDate);
  380.                                                 }
  381.                                                 else
  382.                                                 {
  383.                                                     wprintf(L"  FileTimeToVariantTime failed\n");
  384.                                                 }
  385.                                             }
  386.                                             else
  387.                                             {
  388.                                                 wprintf(L"  FileTimeToSystemTime failed\n");
  389.                                             }
  390.  
  391.                                         }
  392.                                         else
  393.                                         {
  394.                                             wprintf(L"  FileTimeToLocalFileTime failed\n");
  395.                                         }
  396.                                     }
  397.                                 }
  398.                                 else
  399.                                 {
  400.                                     //Print the LargeInteger.
  401.                                     wprintf(L"  high: %d low: %d\r\n",filetime.dwHighDateTime, filetime.dwLowDateTime);
  402.                                 }
  403.                             }
  404.                           }
  405.                           break;
  406.                         case ADSTYPE_NT_SECURITY_DESCRIPTOR:
  407.                           for (x = 0; x< col.dwNumValues; x++)
  408.                           {
  409.                               wprintf(L"  Security descriptor.\n");
  410.                           }
  411.                           break;
  412.                         default:
  413.                           wprintf(L"Unknown type %d.\n",col.dwADsType);
  414.                     }
  415.                   }
  416.                   else
  417.                   {
  418.                     //Verbose handles only the two single-valued attributes: cn and ldapdisplayname
  419.                     //so this is a special case.
  420.                     if (0==wcscmp(L"name", pszColumn))
  421.                     {
  422.                       wcscpy(szName,col.pADsValues->CaseIgnoreString);
  423.                     }
  424.                     if (0==wcscmp(L"distinguishedName", pszColumn))
  425.                     {
  426.                       wcscpy(szDN,col.pADsValues->CaseIgnoreString);
  427.                     }
  428.                   }
  429.                   pContainerToSearch->FreeColumn( &col );
  430.                 }
  431.                 FreeADsMem( pszColumn );
  432.             }
  433.            if (!bIsVerbose)
  434.                wprintf(L"%s\n  DN: %s\n\n",szName,szDN);
  435.             //Get the next row
  436.            hr = pContainerToSearch->GetNextRow( hSearch);
  437.         }
  438.  
  439.       }
  440.       // Close the search handle to clean up
  441.       pContainerToSearch->CloseSearchHandle(hSearch);
  442.     } 
  443.     if (SUCCEEDED(hr) && 0==iCount)
  444.         hr = S_FALSE;
  445.  
  446.     return hr;
  447. }
  448.  
  449.