Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

471 lines
14 KiB

  1. #ifndef _WIN32_WINNT
  2. #define _WIN32_WINNT 0x0500
  3. #endif
  4. #define SECURITY_WIN32
  5. #include <atlbase.h>
  6. #include <iads.h>
  7. #include <adshlp.h>
  8. #include <security.h>
  9. #include <activeds.h>
  10. #include "uddi.h"
  11. #include "scp.h"
  12. using namespace std;
  13. wstring CUDDIServiceCxnPt::strRootDSE = L"";
  14. const LPWSTR CUDDIServiceCxnPt::UDDI_KEYWORD = L"UDDI";
  15. const LPWSTR CUDDIServiceCxnPt::UDDI_VERSION_KEYWORD = L"2.0";
  16. const LPWSTR CUDDIServiceCxnPt::VENDOR_KEYWORD = L"Microsoft Corporation";
  17. const LPWSTR CUDDIServiceCxnPt::VENDOR_GUID_KEYWORD = L"83C29870-1DFC-11D3-A193-0000F87A9099";
  18. const LPWSTR CUDDIServiceCxnPt::PRODUCT_KEYWORD = L"UDDI Services";
  19. const LPWSTR CUDDIServiceCxnPt::PRODUCT_GUID_KEYWORD = L"09A92664-D144-49DB-A600-2B3ED04BF639";
  20. const LPWSTR CUDDIServiceCxnPt::DISCOVERY_URL_KEYWORD = L"DiscoveryUrl";
  21. const LPWSTR CUDDIServiceCxnPt::DISCOVERYURL_GUID_KEYWORD = L"1276768A-1488-4C6F-A8D8-19556C6BE583";
  22. const LPWSTR CUDDIServiceCxnPt::DISCOVERYURL_SERVICE_CLASS_NAME = L"UddiDiscoveryUrl";
  23. const LPWSTR CUDDIServiceCxnPt::PUBLISH_KEYWORD = L"Publish API";
  24. const LPWSTR CUDDIServiceCxnPt::PUBLISH_GUID_KEYWORD = L"64C756D1-3374-4E00-AE83-EE12E38FAE63";
  25. const LPWSTR CUDDIServiceCxnPt::PUBLISH_SERVICE_CLASSNAME = L"UddiPublishUrl";
  26. const LPWSTR CUDDIServiceCxnPt::PUBLISH_KEY_V2 = L"A2F36B65-2D66-4088-ABC7-914D0E05EB9E";
  27. const LPWSTR CUDDIServiceCxnPt::INQUIRE_KEYWORD = L"Inquire API";
  28. const LPWSTR CUDDIServiceCxnPt::INQUIRE_GUID_KEYWORD = L"4CD7E4BC-648B-426D-9936-443EAAC8AE23";
  29. const LPWSTR CUDDIServiceCxnPt::INQUIRE_SERVICE_CLASS_NAME = L"UddiInquireUrl";
  30. const LPWSTR CUDDIServiceCxnPt::INQUIRE_KEY_V2 = L"AC104DCC-D623-452F-88A7-F8ACD94D9B2B";
  31. const LPWSTR CUDDIServiceCxnPt::ADD_WEB_REFERENCE_KEYWORD = L"Add Web Reference";
  32. const LPWSTR CUDDIServiceCxnPt::ADD_WEB_REFERENCE_GUID_KEYWORD = L"CE653789-F6D4-41B7-B7F4-31501831897D";
  33. const LPWSTR CUDDIServiceCxnPt::ADD_WEB_REFERENCE_SERVICE_CLASS_NAME = L"UddiAddWebReferenceUrl";
  34. const LPWSTR CUDDIServiceCxnPt::WEB_SITE_KEYWORD = L"Web Site";
  35. const LPWSTR CUDDIServiceCxnPt::WEB_SITE_GUID_KEYWORD = L"4CEC1CEF-1F68-4B23-8CB7-8BAA763AEB89";
  36. const LPWSTR CUDDIServiceCxnPt::WEB_SITE_SERVICE_CLASS_NAME = L"UddiWebSiteUrl";
  37. const LPWSTR CUDDIServiceCxnPt::WINDOWS_AUTHENTICATION_KEYWORD = L"WindowsAuthentication";
  38. const LPWSTR CUDDIServiceCxnPt::ANONYMOUS_AUTHENTICATION_KEYWORD = L"AnonymousAuthentication";
  39. const LPWSTR CUDDIServiceCxnPt::UDDI_AUTHENTICATION_KEYWORD = L"UddiAuthentication";
  40. const LPWSTR CUDDIServiceCxnPt::WINDOWS_AUTHENTICATION_GUID_KEYWORD = L"0C61E2C3-73C5-4743-8163-6647AF5B4B9E";
  41. const LPWSTR CUDDIServiceCxnPt::ANONYMOUS_AUTHENTICATION_GUID_KEYWORD = L"E4A56494-4946-4805-ACA5-546B8D08EEFD";
  42. const LPWSTR CUDDIServiceCxnPt::UDDI_AUTHENTICATION_GUID_KEYWORD = L"F358808C-E939-4813-A407-8873BFDC3D57";
  43. CUDDIServiceCxnPt::
  44. CUDDIServiceCxnPt( LPWSTR szName, LPWSTR szClassName )
  45. : strName( szName )
  46. , strClassName( szClassName )
  47. {
  48. }
  49. CUDDIServiceCxnPt::
  50. ~CUDDIServiceCxnPt()
  51. {
  52. }
  53. LPWSTR
  54. CUDDIServiceCxnPt::GetRootDSE()
  55. {
  56. if( 0 == strRootDSE.length() )
  57. {
  58. HRESULT hr = 0;
  59. CComPtr<IADs> pRoot = NULL;
  60. hr = ADsGetObject( L"LDAP://RootDSE", IID_IADs, (void**) &pRoot );
  61. if( FAILED(hr) )
  62. {
  63. throw CUDDIException( E_FAIL, L"Unable to acquire the root naming context. The domain may not exist or is not available." );
  64. }
  65. CComVariant var = 0;
  66. USES_CONVERSION;
  67. CComBSTR bstrDNC( L"defaultNamingContext" );
  68. pRoot->Get( bstrDNC, &var );
  69. strRootDSE = var.bstrVal;
  70. }
  71. return (LPWSTR) strRootDSE.c_str();
  72. }
  73. void
  74. CUDDIServiceCxnPt::AddDefaultKeywords()
  75. {
  76. keywords.push_back( VENDOR_KEYWORD );
  77. keywords.push_back( VENDOR_GUID_KEYWORD );
  78. keywords.push_back( PRODUCT_KEYWORD );
  79. keywords.push_back( PRODUCT_GUID_KEYWORD );
  80. keywords.push_back( UDDI_KEYWORD );
  81. keywords.push_back( UDDI_VERSION_KEYWORD );
  82. }
  83. void
  84. CUDDIServiceCxnPt::DeleteSiteContainer( LPWSTR pszName, BOOL bFailIfNotThere )
  85. {
  86. if( NULL == pszName || 0 == wcslen( pszName ) )
  87. {
  88. throw CUDDIException( E_INVALIDARG, L"Site container name must be specified" );
  89. }
  90. wstring strSitesPath;
  91. wstring strPath;
  92. try
  93. {
  94. strSitesPath = L",CN=Sites,CN=UDDI,CN=Microsoft,CN=System,";
  95. strSitesPath += GetRootDSE();
  96. strPath = L"LDAP://";
  97. if( NULL != pszName && 0 != _wcsnicmp( L"cn=", pszName, 3 ) )
  98. strPath += L"CN=";
  99. strPath += pszName;
  100. strPath += strSitesPath;
  101. }
  102. catch( ... )
  103. {
  104. throw CUDDIException( E_OUTOFMEMORY, L"Ran out of available memory in function: CUDDIServiceCxnPt::DeleteSiteContainer." );
  105. }
  106. //
  107. // Get a reference to the System container
  108. //
  109. CComPtr<IDirectoryObject> pSite = NULL;
  110. HRESULT hr = ADsGetObject( (LPWSTR) strPath.c_str(), IID_IDirectoryObject, (void**) &pSite );
  111. if( FAILED(hr) )
  112. {
  113. throw CUDDIException( hr, L"CUDDIServiceCxnPt::DeleteSiteContainer failed. Unable to acquire the site container" );
  114. }
  115. CComPtr<IADsDeleteOps> pDelete = NULL;
  116. hr = pSite->QueryInterface( IID_IADsDeleteOps, (void**) &pDelete );
  117. if( FAILED(hr) )
  118. {
  119. throw CUDDIException( hr, L"CUDDIServiceCxnPt::DeleteSiteContainer failed. Unable to acquire the IADsDeleteOps for site container" );
  120. }
  121. hr = pDelete->DeleteObject( 0 );
  122. if( FAILED(hr) )
  123. {
  124. throw CUDDIException( hr, L"CUDDIServiceCxnPt::DeleteSiteContainer failed on call to IADsDeleteObject::DeleteObject" );
  125. }
  126. }
  127. void
  128. CUDDIServiceCxnPt::Create( IDirectoryObject* pDirObject )
  129. {
  130. if( 0 == attributes.size() || 0 == keywords.size() )
  131. {
  132. throw CUDDIException( E_INVALIDARG, L"Error occurred in CUDDIServiceCxnPt::Create attributes and keywords must be present" );
  133. }
  134. if( NULL == pDirObject )
  135. {
  136. throw CUDDIException( E_INVALIDARG, L"The parent container was not specified for this service connection point." );
  137. }
  138. else
  139. {
  140. //
  141. // THE PURPOSE OF HAVING THIS CODE IN THE "IF" BLOCK IS TO
  142. // APPEASE PREFAST, OTHERWISE PREFAST THROWS ERROR ON THE USE
  143. // OF pDirObject WITHOUT CHECKING FOR NULL
  144. //
  145. ADSVALUE cn, objclass, serviceclass;
  146. //
  147. // Setup the container and class name values
  148. //
  149. cn.dwType = ADSTYPE_CASE_IGNORE_STRING;
  150. cn.CaseIgnoreString = (LPWSTR) strName.c_str();
  151. objclass.dwType = ADSTYPE_CASE_IGNORE_STRING;
  152. objclass.CaseIgnoreString = L"serviceConnectionPoint";
  153. serviceclass.dwType = ADSTYPE_CASE_IGNORE_STRING;
  154. serviceclass.CaseIgnoreString = (LPWSTR) strClassName.c_str();
  155. //
  156. // Populate the keywords values array
  157. //
  158. ADSVALUE* pKeywordValues = new ADSVALUE[ keywords.size() ];
  159. if( NULL == pKeywordValues )
  160. {
  161. throw CUDDIException( E_OUTOFMEMORY, L"Ran out of memory allocating memory for pKeywordValues." );
  162. }
  163. int n = 0;
  164. for( vector<wstring>::iterator iter = keywords.begin();
  165. iter != keywords.end(); iter++ )
  166. {
  167. pKeywordValues[ n ].CaseIgnoreString = (LPWSTR) (*iter).c_str();
  168. pKeywordValues[ n ].dwType = ADSTYPE_CASE_IGNORE_STRING;
  169. n++;
  170. }
  171. //
  172. // Create and populate the attribute array
  173. //
  174. size_t nAttribs = attributes.size();
  175. size_t nTotalAttributes = nAttribs + 4;
  176. ADSVALUE* pValues = new ADSVALUE[ nAttribs ];
  177. if( NULL == pValues )
  178. {
  179. delete [] pKeywordValues;
  180. throw CUDDIException( E_OUTOFMEMORY, L"Ran out of memory allocating memory for pValues." );
  181. }
  182. ADS_ATTR_INFO* pAttrs = new ADS_ATTR_INFO[ nTotalAttributes ];
  183. if( NULL == pAttrs )
  184. {
  185. delete [] pKeywordValues;
  186. delete [] pValues;
  187. throw CUDDIException( E_OUTOFMEMORY, L"Ran out of memory allocating memory for pAttrs." );
  188. }
  189. pAttrs[ nAttribs ].pszAttrName = L"cn";
  190. pAttrs[ nAttribs ].dwControlCode = ADS_ATTR_UPDATE;
  191. pAttrs[ nAttribs ].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  192. pAttrs[ nAttribs ].dwNumValues = 1;
  193. pAttrs[ nAttribs ].pADsValues = &cn;
  194. pAttrs[ nAttribs + 1 ].pszAttrName = L"objectClass";
  195. pAttrs[ nAttribs + 1 ].dwControlCode = ADS_ATTR_UPDATE;
  196. pAttrs[ nAttribs + 1 ].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  197. pAttrs[ nAttribs + 1 ].dwNumValues = 1;
  198. pAttrs[ nAttribs + 1 ].pADsValues = &objclass;
  199. pAttrs[ nAttribs + 2 ].pszAttrName = L"keywords";
  200. pAttrs[ nAttribs + 2 ].dwControlCode = ADS_ATTR_UPDATE;
  201. pAttrs[ nAttribs + 2 ].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  202. pAttrs[ nAttribs + 2 ].dwNumValues = (DWORD) keywords.size();
  203. pAttrs[ nAttribs + 2 ].pADsValues = pKeywordValues;
  204. pAttrs[ nAttribs + 3 ].pszAttrName = L"serviceClassName";
  205. pAttrs[ nAttribs + 3 ].dwControlCode = ADS_ATTR_UPDATE;
  206. pAttrs[ nAttribs + 3 ].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  207. pAttrs[ nAttribs + 3 ].dwNumValues = 1;
  208. pAttrs[ nAttribs + 3 ].pADsValues = &serviceclass;
  209. map<wstring, wstring>::iterator attributeIter = attributes.begin();
  210. for( size_t i=0; i<attributes.size(); i++ )
  211. {
  212. pValues[ i ].CaseIgnoreString = (LPWSTR) (*attributeIter).second.c_str();
  213. pValues[ i ].dwType = ADSTYPE_CASE_IGNORE_STRING;
  214. pAttrs[ i ].pszAttrName = (LPWSTR) (*attributeIter).first.c_str();
  215. pAttrs[ i ].dwControlCode = ADS_ATTR_UPDATE;
  216. pAttrs[ i ].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  217. pAttrs[ i ].dwNumValues = 1;
  218. pAttrs[ i ].pADsValues = &pValues[ i ];
  219. attributeIter++;
  220. }
  221. wstring strRDN( L"CN=" );
  222. strRDN += strName;
  223. CComPtr<IDispatch> pDisp = NULL;
  224. HRESULT hr = pDirObject->CreateDSObject( (LPWSTR) strRDN.c_str(), pAttrs, (DWORD) nTotalAttributes, &pDisp );
  225. delete [] pAttrs;
  226. delete [] pValues;
  227. delete [] pKeywordValues;
  228. if( FAILED(hr) )
  229. {
  230. throw CUDDIException( hr, L"CUDDIServiceCxnPt::Create failed in call to CreateDSObject" );
  231. }
  232. }
  233. }
  234. void
  235. CUDDIServiceCxnPt::CreateSiteContainer(
  236. LPWSTR pszName,
  237. LPWSTR pszDisplayName,
  238. IDirectoryObject** ppContainer )
  239. {
  240. //
  241. // Check pre-conditions
  242. //
  243. if( NULL == pszName || NULL == pszDisplayName ||
  244. NULL == ppContainer || 0 == wcslen( pszName ) ||
  245. 0 == wcslen( pszDisplayName ) )
  246. {
  247. throw CUDDIException( E_INVALIDARG, L"CUDDIServiceConnetionPoint::CreateSiteContainer failed. All arguments must be specified." );
  248. }
  249. HRESULT hr = NULL;
  250. //
  251. // Get a reference to the System container
  252. //
  253. wstring strSystemPath( L"LDAP://CN=System," );
  254. strSystemPath += GetRootDSE();
  255. CComPtr<IDirectoryObject> pSystem = NULL;
  256. hr = ADsGetObject( (LPWSTR) strSystemPath.c_str(), IID_IDirectoryObject, (void**) &pSystem );
  257. if( FAILED(hr) )
  258. {
  259. throw CUDDIException( hr, L"CUDDIServiceCxnPt::CreateSiteContainer failed. Unable to acquire the System container in Active Directory." );
  260. }
  261. //
  262. // Get a reference to the CN=Microsoft,CN=System container
  263. //
  264. wstring strMicrosoftPath( L"LDAP://CN=Microsoft,CN=System," );
  265. strMicrosoftPath += GetRootDSE();
  266. CComPtr<IDirectoryObject> pMicrosoft = NULL;
  267. hr = ADsGetObject( strMicrosoftPath.c_str(), IID_IDirectoryObject, (void**) &pMicrosoft );
  268. if( FAILED(hr) )
  269. {
  270. //
  271. // Create the Microsoft Container
  272. //
  273. CreateContainer( pSystem, L"CN=Microsoft", &pMicrosoft );
  274. }
  275. //
  276. // Get a reference to the CN=UDDI,CN=Microsoft,CN=System container
  277. //
  278. wstring strUddiPath( L"LDAP://CN=UDDI,CN=Microsoft,CN=System," );
  279. strUddiPath += GetRootDSE();
  280. CComPtr<IDirectoryObject> pUddi = NULL;
  281. hr = ADsGetObject( strUddiPath.c_str(), IID_IDirectoryObject, (void**) &pUddi );
  282. if( FAILED(hr) )
  283. {
  284. //
  285. // Create the UDDI Container
  286. //
  287. CreateContainer( pMicrosoft, L"CN=UDDI", &pUddi );
  288. }
  289. //
  290. // Get a reference to the CN=Sites,CN=UDDI,CN=Microsoft,CN=System container
  291. //
  292. wstring strSitesPath( L"LDAP://CN=Sites,CN=UDDI,CN=Microsoft,CN=System," );
  293. strSitesPath += GetRootDSE();
  294. CComPtr<IDirectoryObject> pSites = NULL;
  295. hr = ADsGetObject( strSitesPath.c_str(), IID_IDirectoryObject, (void**) &pSites );
  296. if( FAILED(hr) )
  297. {
  298. //
  299. // Create the Sites Container
  300. //
  301. CreateContainer( pUddi, L"CN=Sites", &pSites );
  302. }
  303. //
  304. // Get a reference to the CN=<Site Name>,CN=Sites,CN=UDDI,CN=Microsoft,CN=System container
  305. //
  306. wstring strSitePath( L"LDAP://CN=" );
  307. strSitePath += pszName;
  308. strSitePath += L",CN=Sites,CN=UDDI,CN=Microsoft,CN=System,";
  309. strSitePath += GetRootDSE();
  310. hr = ADsGetObject( strSitePath.c_str(), IID_IDirectoryObject, (void**) ppContainer );
  311. if( FAILED(hr) )
  312. {
  313. //
  314. // Create the Sites Container
  315. //
  316. wstring strSiteName( L"CN=" );
  317. strSiteName += pszName;
  318. CreateContainer( pSites, (LPWSTR) strSiteName.c_str(), ppContainer );
  319. }
  320. //
  321. // Set the display name on the site container
  322. //
  323. CComPtr<IADs> pADs = NULL;
  324. hr = (*ppContainer)->QueryInterface( IID_IADs, (void**) &pADs );
  325. if( FAILED(hr) )
  326. {
  327. throw CUDDIException( hr, L"CUDDIServiceCxnPt::CreateSiteContainer failed. Unable to acquire IADs interface pointer." );
  328. }
  329. CComBSTR bstrDispName( L"displayName" );
  330. hr = pADs->Put( bstrDispName, CComVariant( pszDisplayName ) );
  331. if( FAILED(hr) )
  332. {
  333. throw CUDDIException( hr, L"CUDDIServiceCxnPt::CreateSiteContainer failed. Attempt to Put displayName failed." );
  334. }
  335. CComBSTR bstrDesc( L"description" );
  336. hr = pADs->Put( bstrDesc, CComVariant( pszDisplayName ) );
  337. if( FAILED(hr) )
  338. {
  339. throw CUDDIException( hr, L"CUDDIServiceCxnPt::CreateSiteContainer failed. Attempt to Put displayName failed." );
  340. }
  341. hr = pADs->SetInfo();
  342. if( FAILED(hr) )
  343. {
  344. throw CUDDIException( hr, L"CUDDIServiceCxnPt::CreateSiteContainer failed. Attempt to SetInfo failed." );
  345. }
  346. }
  347. void
  348. CUDDIServiceCxnPt::CreateContainer(
  349. IDirectoryObject* pObj,
  350. LPWSTR szName,
  351. IDirectoryObject** ppContainer )
  352. {
  353. //
  354. // Check pre-conditions
  355. //
  356. if( NULL == pObj || NULL == ppContainer || NULL == szName )
  357. {
  358. throw CUDDIException( E_INVALIDARG, L"CUDDIServiceCxnPt::CreateContainer failed. All arguments must be specified." );
  359. }
  360. //
  361. // Create the value structure for the objectClass
  362. //
  363. HRESULT hr = 0;
  364. ADSVALUE classValue;
  365. ADS_ATTR_INFO attrInfo[] =
  366. {
  367. { L"objectClass", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &classValue, 1 },
  368. };
  369. DWORD dwAttrs = sizeof(attrInfo)/sizeof(ADS_ATTR_INFO);
  370. classValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
  371. classValue.CaseIgnoreString = L"container";
  372. //
  373. // Create the container as a child of the specified parent
  374. //
  375. IDispatch* pDisp = NULL;
  376. if( pObj )
  377. {
  378. hr = pObj->CreateDSObject( szName, attrInfo, dwAttrs, &pDisp );
  379. if( FAILED(hr) )
  380. {
  381. throw CUDDIException( hr, L"CreateContainer() failed on CreateDSObject" );
  382. }
  383. }
  384. //
  385. // QI for an IDirectoryObject interface
  386. //
  387. if( pDisp )
  388. {
  389. hr = pDisp->QueryInterface( IID_IDirectoryObject, (void**) ppContainer );
  390. pDisp->Release();
  391. if( FAILED(hr) )
  392. {
  393. throw CUDDIException( hr, L"QueryInterface failed looking for IDirectoryObject" );
  394. }
  395. }
  396. }