home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 27 / IOPROG_27.ISO / SOFT / ADSDK.ZIP / Samples / ActiveDir / OtherWKO / vc / otherwko1.cpp < prev   
Encoding:
C/C++ Source or Header  |  1999-02-16  |  13.6 KB  |  438 lines

  1. // otherwko.cpp : Defines the entry point for the console application.
  2. //
  3. #include <wchar.h>
  4. #include <objbase.h>
  5. #include <activeds.h>
  6.  
  7. //Make sure you define UNICODE
  8. //Need to define version 5 for Windows 2000
  9. #define _WIN32_WINNT 0x0500
  10. //FOR LDAP API...Required for Beta 3 only.
  11. #include <winldap.h>
  12. //Need to link against the following LIBs:
  13. //wldap32.lib
  14.  
  15.  
  16. static GUID MyWKOTestObjectGUID = { /* df447b5e-aa5b-11d2-8d53-00c04f79ab81 */
  17.     0xdf447b5e,
  18.     0xaa5b,
  19.     0x11d2,
  20.     {0x8d, 0x53, 0x00, 0xc0, 0x4f, 0x79, 0xab, 0x81}
  21.   };
  22.  
  23.  
  24.  
  25. HRESULT GUIDtoBindableString (LPGUID pGUID, LPOLESTR *ppGUIDString);
  26.  
  27. HRESULT AddValueToOtherWKOProperty(LPOLESTR szContainerDN, //DN for container whose otherWellKnownObjects property to modify
  28.                                    LPGUID pWKOGUID, //WKO GUID for the well-known object.
  29.                                    LPOLESTR szWKOObjectDN //DN of the well-known object.
  30.                                    );
  31.  
  32.  
  33.  
  34.  
  35. void wmain( int argc, wchar_t *argv[ ])
  36. {
  37.  
  38. LPOLESTR pszBuffer = new OLECHAR[MAX_PATH*2];
  39.     wprintf(L"This program does the following:\n");
  40.     wprintf(L"1. Creates a container (MyWKOTestContainer) in the current Window 2000 domain.\n");
  41.     wprintf(L"2. Creates a container object (MyWKOTestObject) within the container.\n");
  42.     wprintf(L"3. Adds a value for the container object on the otherWellKnownObject property of the container.\n");
  43.     wprintf(L"4. Binds to the container object using WKGUID binding string.\n");
  44.     wprintf(L"5. Renames the container object using WKGUID binding string.\n");
  45.     wprintf(L"6. Binds to the container object using WKGUID binding string.\n");
  46.     wprintf(L"7. Optionally, cleans up by removing the container and container object.\n\n");
  47.     
  48.     
  49. //Intialize COM
  50. CoInitialize(NULL);
  51.  
  52. HRESULT hr = S_OK;
  53. IADs *pObject = NULL;
  54. IADsContainer *pDomain = NULL;
  55. IDispatch *pDisp = NULL;
  56. IDispatch *pDispNewObject = NULL;
  57. IADsContainer *pNewContainer = NULL;
  58. IADs *pIADsObject = NULL;
  59. IADs *pNewObject = NULL;
  60. IADs *pTestWKO1 = NULL;
  61. IADs *pTestWKO2 = NULL;
  62. VARIANT vartest;
  63. BSTR bstr;
  64.  
  65. LPOLESTR szNewContainerDN = new OLECHAR[MAX_PATH];
  66. LPOLESTR szPath = new OLECHAR[MAX_PATH];
  67. LPOLESTR szRelPath = new OLECHAR[MAX_PATH];
  68. LPOLESTR szGUIDString = NULL;
  69.  
  70. //Names of the container and child object.
  71. LPOLESTR szContainer = L"MyWKOTestContainer";
  72. LPOLESTR szNewObject = L"MyWKOTestObject";
  73.  
  74. LPOLESTR szNewObjectRenameRDN = L"cn=ObjectwithNEWNAME";
  75.  
  76. //Get rootDSE and the domain container's DN.
  77. VARIANT var;
  78. hr = ADsOpenObject(L"LDAP://rootDSE",
  79.                  NULL,
  80.                  NULL,
  81.                  ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  82.                  IID_IADs,
  83.                  (void**)&pObject);
  84. if (FAILED(hr))
  85. {
  86.    wprintf(L"Not Found. Could not bind to the domain.\n");
  87.    if (pObject)
  88.      pObject->Release();
  89.    return;
  90. }
  91.  
  92. hr = pObject->Get(L"defaultNamingContext",&var);
  93. if (SUCCEEDED(hr))
  94. {
  95.     //Build the ADsPath to the domain
  96.     wcscpy(szPath,L"LDAP://");
  97.     wcscat(szPath,var.bstrVal);
  98.     VariantClear(&var);
  99.     //Bind to the current domain.
  100.     hr = ADsOpenObject(szPath,
  101.                      NULL,
  102.                      NULL,
  103.                      ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  104.                      IID_IADsContainer,
  105.                      (void**)&pDomain);
  106.     if (SUCCEEDED(hr))
  107.     {
  108.       //Create the container.
  109.       wcscpy(szRelPath,L"cn=");
  110.       wcscat(szRelPath,szContainer);
  111.       hr = pDomain->Create(L"container", //ldapDisplayName of the class of the object to create.
  112.                              szRelPath, //relative path in RDN=value format
  113.                              &pDisp); //return an IDispatch pointer to the new object.
  114.       if (SUCCEEDED(hr))
  115.       {
  116.         //QI for an IADs interface.
  117.         hr = pDisp->QueryInterface(IID_IADs, (void **)&pIADsObject);
  118.         //Commit the new object to the directory.
  119.         hr = pIADsObject->SetInfo();
  120.         //QI for an IADsContainer interface.
  121.         hr = pDisp->QueryInterface(IID_IADsContainer, (void **)&pNewContainer);
  122.         if (SUCCEEDED(hr))
  123.         {
  124.           //Create the new container object in the container.
  125.           wcscpy(szRelPath,L"cn=");
  126.           wcscat(szRelPath,szNewObject);
  127.           hr = pNewContainer->Create(L"container", //ldapDisplayName of the class of the object to create.
  128.                      szRelPath, //relative path in RDN=value format
  129.                      &pDispNewObject); //return an IDispatch pointer to the new object.
  130.           if (SUCCEEDED(hr))
  131.           {
  132.             //Get the DN of the new container object
  133.             hr = pIADsObject->Get(L"distinguishedName", &var);
  134.             if (SUCCEEDED(hr))
  135.             {
  136.               wcscpy(szNewContainerDN, var.bstrVal);
  137.               VariantClear(&var);
  138.               wprintf(L"Created new container with DN: %s\n",szNewContainerDN);
  139.               hr = pDispNewObject->QueryInterface(IID_IADs, (void **)&pNewObject);
  140.               if (SUCCEEDED(hr))
  141.               {
  142.                 //Commit the new object to the directory.
  143.                 hr = pNewObject->SetInfo();
  144.                 //Get the DN for the new object
  145.                 hr = pNewObject->Get(L"distinguishedName", &var);
  146.                 if (SUCCEEDED(hr))
  147.                 {
  148.                     wprintf(L"Created new child object with DN: %s\n",var.bstrVal);
  149.                   //FOR BETA 3 only. Need to use LDAP API to set the otherWellKnownObjects property.
  150.                   wprintf(L"Call AddValueToOtherWKOProperty with:\n");
  151.                   wprintf(L"szContainer DN: %s\n",szNewContainerDN);
  152.                   GUIDtoBindableString (&MyWKOTestObjectGUID, &szGUIDString);
  153.                   wprintf(L"pWKOGUID (bindable string format): %s\n",szGUIDString);
  154.                   wprintf(L"szWKOObjectDN: %s\n",var.bstrVal);
  155.                   hr = AddValueToOtherWKOProperty(szNewContainerDN, //DN for container whose otherWellKnownObjects property to modify
  156.                                    &MyWKOTestObjectGUID, //WKO GUID for the well-known object.
  157.                                    var.bstrVal //DN of the well-known object.
  158.                                    );
  159.                   wprintf(L"AddValueToOtherWKOProperty returned: %x\n",hr);
  160.                   if (SUCCEEDED(hr))
  161.                   {
  162.                       //Now bind using WKGUID binding
  163.                       //Build the ADsPath to the well-known object
  164.                       wcscpy(szPath,L"LDAP://<WKGUID=");
  165.                       wcscat(szPath,szGUIDString);
  166.                       wcscat(szPath,L",");
  167.                       wcscat(szPath,szNewContainerDN);
  168.                         wcscat(szPath,L">");
  169.                       wprintf(L"Bind with the following WKGUID binding string: %s\n",szPath);
  170.                       hr = ADsOpenObject(szPath,
  171.                          NULL,
  172.                          NULL,
  173.                          ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  174.                          IID_IADs,
  175.                          (void**)&pTestWKO1);
  176.                       if (SUCCEEDED(hr))
  177.                       {
  178.                           hr = pTestWKO1->Get(L"distinguishedName",&vartest);
  179.                             if (SUCCEEDED(hr))
  180.                           {
  181.                               wprintf(L"Successfully bound to object. DN: %s\n",vartest.bstrVal);
  182.                               VariantClear(&vartest);
  183.                           }
  184.                       }
  185.                       else
  186.                           wprintf(L"Binding failed with hr: %x\n",hr);
  187.                       
  188.                       if (pTestWKO1)
  189.                           pTestWKO1->Release();
  190.                       //Bind again using the DN to get a regular ADsPath.
  191.                       wcscpy(szPath,L"LDAP://");
  192.                       wcscat(szPath,var.bstrVal);
  193.                       hr = ADsOpenObject(szPath,
  194.                          NULL,
  195.                          NULL,
  196.                          ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  197.                          IID_IADs,
  198.                          (void**)&pTestWKO1);
  199.                       hr = pTestWKO1->get_ADsPath(&bstr);
  200.                       //Rename the WKO object
  201.                       hr = pNewContainer->MoveHere(bstr,szNewObjectRenameRDN,NULL);
  202.                       FreeADsStr(bstr);
  203.                       if (pTestWKO1)
  204.                           pTestWKO1->Release();
  205.                       //Now AGAIN bind using WKGUID binding
  206.                       //Build the ADsPath to the well-known object
  207.                       wcscpy(szPath,L"LDAP://<WKGUID=");
  208.                       wcscat(szPath,szGUIDString);
  209.                       wcscat(szPath,L",");
  210.                       wcscat(szPath,szNewContainerDN);
  211.                         wcscat(szPath,L">");
  212.                       wprintf(L"Bind AGAIN with the following WKGUID binding string: %s\n",szPath);
  213.                       hr = ADsOpenObject(szPath,
  214.                          NULL,
  215.                          NULL,
  216.                          ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  217.                          IID_IADs,
  218.                          (void**)&pTestWKO2);
  219.                       if (SUCCEEDED(hr))
  220.                       {
  221.                           hr = pTestWKO2->Get(L"distinguishedName",&vartest);
  222.                             if (SUCCEEDED(hr))
  223.                           {
  224.                               wprintf(L"Successfully bound to object (Note the DN reflects the rename). DN: %s\n",vartest.bstrVal);
  225.                               VariantClear(&vartest);
  226.                           }
  227.                       }
  228.                       else
  229.                           wprintf(L"Binding failed with hr: %x\n",hr);
  230.                   }
  231.                   CoTaskMemFree(szGUIDString);
  232.                 }
  233.               }
  234.               if (pNewObject)
  235.                 pNewObject->Release();
  236.             }
  237.             VariantClear(&var);
  238.           }
  239.           if (pIADsObject)
  240.             pIADsObject->Release();
  241.           if (pDispNewObject)
  242.             pDispNewObject->Release();
  243.         }
  244.  
  245.         //Ask user if they want us to delete the test containers.
  246.         wprintf(L"Do you want to delete the test container and object (Y/N):");
  247.         _getws(pszBuffer);
  248.         if (0==wcsnicmp(L"Y", pszBuffer,1))
  249.         {
  250.             //Delete the object
  251.             //Delete the container
  252.             hr = pNewContainer->Delete(L"container",szNewObjectRenameRDN);
  253.             if (SUCCEEDED(hr))
  254.             {
  255.               wprintf(L"Successfully deleted test object.\n");
  256.               wcscpy(szRelPath,L"cn=");
  257.               wcscat(szRelPath,szContainer);
  258.               //Delete the container
  259.               hr = pDomain->Delete(L"container",szRelPath);
  260.               if (SUCCEEDED(hr))
  261.                 wprintf(L"Successfully deleted test container and its contents.\n");
  262.               else
  263.                 wprintf(L"Failed to delete test container and its contents. hr: %x\n",hr);
  264.             }
  265.             else
  266.               wprintf(L"Failed to delete test container and its contents. hr: %x\n",hr);
  267.         }
  268.  
  269.         if (pNewContainer)
  270.           pNewContainer->Release();
  271.       }
  272.       if (pDisp)
  273.           pDisp->Release();
  274.     }
  275.     if (pDomain)
  276.     pDomain->Release();
  277. }
  278. if (pObject)
  279.    pObject->Release();
  280.  
  281. //Uninitalize COM
  282. CoUninitialize();
  283.  
  284.     return;
  285. }
  286.  
  287. HRESULT AddValueToOtherWKOProperty(LPOLESTR szContainerDN, //DN for container whose otherWellKnownObjects property to modify
  288.                                    LPGUID pWKOGUID, //WKO GUID for the well-known object.
  289.                                    LPOLESTR szWKOObjectDN //DN of the well-known object.
  290.                                    )
  291. {
  292. HRESULT hr = E_FAIL;
  293. LPOLESTR szGUIDString = new OLECHAR[MAX_PATH];
  294. LPOLESTR szDNwithOctetString = new OLECHAR[MAX_PATH*2];
  295. DWORD dwReturn;
  296. //Connection handle
  297. LDAP *hConnect = NULL;
  298. //Specify NULL to bind to a DC in the current computer's domain.
  299. //LDAP_PORT is the default port, 389
  300. hConnect  = ldap_open(NULL,  LDAP_PORT);
  301. //Bind using the preferred authentication method on Windows 2000
  302. //and the logged on user's security context.
  303. dwReturn = ldap_bind_s( hConnect, NULL, NULL, LDAP_AUTH_NEGOTIATE );
  304. if (dwReturn==LDAP_SUCCESS)
  305. {
  306.  
  307.   //Create the WKO value to add.
  308.   GUIDtoBindableString (pWKOGUID, &szGUIDString);
  309.   DWORD dwGUIDSize = (wcslen(szGUIDString));
  310.   //Build the DNwithoctetstring
  311.   swprintf(szDNwithOctetString, L"B:%d:%s:%s", dwGUIDSize, szGUIDString,szWKOObjectDN); 
  312. //  ULONG ulBerSize = (wcslen(szDNwithOctetString));
  313.   //Build the BerVal
  314. //  PCHAR pByteVal = (PCHAR)szDNwithOctetString;
  315. //  berval berWKO;
  316. //  berWKO.bv_len = ulBerSize;
  317. //  berWKO.bv_val = pByteVal;
  318.   //Build the mod structure to add the value.
  319.   LDAPMod ldWKO;
  320.   //mod_values takes a NULL terminated array of WCHARs.
  321.   //We're adding a single value.
  322.   WCHAR *StrValues[] = {szDNwithOctetString , NULL };
  323.   //Operation
  324.   ldWKO.mod_op = LDAP_MOD_ADD;
  325.   //Attribute
  326.   ldWKO.mod_type = L"otherWellKnownObjects";
  327.   //Value to set.
  328.   ldWKO.mod_vals.modv_strvals = StrValues;
  329.   //mods is a NULL terminated array of LDAPMod structures.
  330.   //We're adding a single value.
  331.   LDAPMod *pMod[] = {&ldWKO,NULL};
  332.     
  333.   //Modify the object specified by szContainerDN.
  334.   dwReturn = ldap_modify_s(  hConnect,
  335.                              szContainerDN,
  336.                              pMod);
  337.   CoTaskMemFree(szGUIDString);
  338.  
  339.   if (dwReturn==LDAP_SUCCESS)
  340.       hr = S_OK;
  341. }
  342. return hr;
  343. }
  344.  
  345.  
  346.  
  347.  
  348.  
  349. HRESULT GUIDtoBindableString (LPGUID pGUID, LPOLESTR *ppGUIDString)
  350. {
  351. HRESULT hr = E_FAIL;
  352. if (!pGUID)
  353.   return E_INVALIDARG;
  354. //Build bindable GUID string
  355. LPOLESTR szDSGUID = new WCHAR [128];
  356. DWORD dwLen =  sizeof(*pGUID);
  357. LPBYTE lpByte = (LPBYTE) pGUID;
  358. //Copy a blank string to make it a zero length string.
  359. wcscpy( szDSGUID, L"" );
  360. //Loop through to add each byte to the string.
  361. for( DWORD dwItem = 0L; dwItem < dwLen ; dwItem++ )
  362. {
  363.   //Append to szDSGUID, double-byte, byte at dwItem index.
  364.   swprintf(szDSGUID + wcslen(szDSGUID), L"%02x", lpByte[dwItem]);
  365.   if( wcslen( szDSGUID ) > 128 )
  366.     break;
  367. }
  368. //Allocate memory for string
  369. *ppGUIDString = (OLECHAR *)CoTaskMemAlloc (sizeof(OLECHAR)*(wcslen(szDSGUID)+1));
  370. if (*ppGUIDString)
  371.   wcscpy(*ppGUIDString, szDSGUID);
  372. else
  373.   hr=E_FAIL;
  374. //Caller must free ppGUIDString using CoTaskMemFree.
  375. return hr;
  376. }
  377.  
  378.  
  379. // This function gets the specified well-known object for the current user's domain.
  380.  
  381. HRESULT GetWKOObject(LPOLESTR szBindableWKGUID, //IN. Bindable string GUID of well-known object.
  382.                           IADs **ppObject //OUT. Return a pointer to the specified well-known object.
  383.                           )
  384. {
  385. HRESULT hr = E_FAIL;
  386. //Get rootDSE and the domain container's DN.
  387. IADs *pObject = NULL;
  388. LPOLESTR szPath = new OLECHAR[MAX_PATH];
  389. VARIANT var;
  390. hr = ADsOpenObject(L"LDAP://rootDSE",
  391.                  NULL,
  392.                  NULL,
  393.                  ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  394.                  IID_IADs,
  395.                  (void**)&pObject);
  396.  
  397. //Get current domain DN.
  398. if (SUCCEEDED(hr))
  399. {
  400.     hr = pObject->Get(L"defaultNamingContext",&var);
  401.     if (SUCCEEDED(hr))
  402.     {
  403.         //Build the WKGUID binding string.
  404.         wcscpy(szPath,L"LDAP://");
  405.         wcscat(szPath,L"<WKGUID=");
  406.         wcscat(szPath,szBindableWKGUID);
  407.         wcscat(szPath,L",");
  408.         wcscat(szPath,var.bstrVal);
  409.         wcscat(szPath,L">");
  410.         //Print the binding string.
  411.         //wprintf(L"WKGUID binding string: %s\n",szPath);
  412.         VariantClear(&var);
  413.         //Bind to the well-known object.
  414.         hr = ADsOpenObject(szPath,
  415.                          NULL,
  416.                          NULL,
  417.                          ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  418.                          IID_IADs,
  419.                          (void**)ppObject);
  420.         if (FAILED(hr))
  421.         {
  422.             if (*ppObject)
  423.             {
  424.               (*ppObject)->Release();
  425.               (*ppObject) = NULL;
  426.             }
  427.         }
  428.     }
  429. }
  430. if (pObject)
  431.   pObject->Release();
  432.  
  433. return hr;
  434. }
  435.     
  436.  
  437.  
  438.