Source code of Windows XP (NT5)
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.

561 lines
12 KiB

  1. // server.cpp : Implementation of CWebAdminHelper
  2. #include "stdafx.h"
  3. #include "smtpadm.h"
  4. #include "webhelp.h"
  5. #include "webhlpr.h"
  6. // Must define THIS_FILE_* macros to use SmtpCreateException()
  7. #define THIS_FILE_HELP_CONTEXT 0
  8. #define THIS_FILE_PROG_ID _T("Smtpadm.WebAdminHelper.1")
  9. #define THIS_FILE_IID IID_IWebAdminHelper
  10. /////////////////////////////////////////////////////////////////////////////
  11. //
  12. STDMETHODIMP CWebAdminHelper::InterfaceSupportsErrorInfo(REFIID riid)
  13. {
  14. static const IID* arr[] =
  15. {
  16. &IID_IWebAdminHelper,
  17. };
  18. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  19. {
  20. if (InlineIsEqualGUID(*arr[i],riid))
  21. return S_OK;
  22. }
  23. return S_FALSE;
  24. }
  25. CWebAdminHelper::CWebAdminHelper ()
  26. {
  27. m_hSearchResults = NULL;
  28. InitAsyncTrace ( );
  29. }
  30. CWebAdminHelper::~CWebAdminHelper ()
  31. {
  32. TermAsyncTrace ( );
  33. }
  34. STDMETHODIMP
  35. CWebAdminHelper::EnumerateTrustedDomains (
  36. BSTR strServer,
  37. SAFEARRAY ** ppsaDomains
  38. )
  39. {
  40. HRESULT hr;
  41. LPWSTR mszDomains = NULL;
  42. SAFEARRAY * psaResult = NULL;
  43. LPWSTR wszCurrent;
  44. LPWSTR wszLocalDomain = NULL;
  45. long cDomains;
  46. SAFEARRAYBOUND rgsaBound[1];
  47. long i;
  48. CComVariant varLocalMachine;
  49. *ppsaDomains = NULL;
  50. hr = ::EnumerateTrustedDomains ( strServer, &mszDomains );
  51. BAIL_ON_FAILURE(hr);
  52. //
  53. // Count the domains:
  54. //
  55. cDomains = 0; // Always count the local machine
  56. wszCurrent = mszDomains;
  57. while ( wszCurrent && *wszCurrent ) {
  58. cDomains++;
  59. wszCurrent += lstrlen ( wszCurrent ) + 1;
  60. }
  61. _ASSERT ( cDomains > 0 );
  62. rgsaBound[0].lLbound = 0;
  63. rgsaBound[0].cElements = cDomains;
  64. psaResult = SafeArrayCreate ( VT_VARIANT, 1, rgsaBound );
  65. if ( !psaResult ) {
  66. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  67. }
  68. #if 0
  69. //
  70. // Add the local machine first:
  71. //
  72. wszLocalDomain = new WCHAR [ lstrlen ( _T("\\\\") ) + lstrlen ( strServer ) + 1 ];
  73. if ( wszLocalDomain == NULL ) {
  74. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  75. }
  76. wsprintf ( wszLocalDomain, _T("\\\\%s"), strServer );
  77. StringToUpper ( wszLocalDomain );
  78. i = 0;
  79. varLocalMachine = wszLocalDomain;
  80. hr = SafeArrayPutElement ( psaResult, &i, &varLocalMachine );
  81. BAIL_ON_FAILURE(hr);
  82. #endif
  83. //
  84. // Add the rest of the domains:
  85. //
  86. for ( wszCurrent = mszDomains, i = 0;
  87. wszCurrent && *wszCurrent && i < cDomains;
  88. wszCurrent += lstrlen ( wszCurrent ) + 1, i++ ) {
  89. CComVariant var;
  90. var = wszCurrent;
  91. SafeArrayPutElement ( psaResult, &i, &var );
  92. BAIL_ON_FAILURE(hr);
  93. }
  94. *ppsaDomains = psaResult;
  95. Exit:
  96. delete wszLocalDomain;
  97. if ( FAILED(hr) && psaResult ) {
  98. SafeArrayDestroy ( psaResult );
  99. }
  100. return hr;
  101. }
  102. STDMETHODIMP
  103. CWebAdminHelper::GetPrimaryNTDomain (
  104. BSTR strServer,
  105. BSTR * pstrPrimaryDomain
  106. )
  107. {
  108. HRESULT hr = NOERROR;
  109. LPWSTR wszPrimaryDomain = NULL;
  110. *pstrPrimaryDomain = NULL;
  111. hr = GetPrimaryDomain ( strServer, &wszPrimaryDomain );
  112. BAIL_ON_FAILURE(hr);
  113. *pstrPrimaryDomain = ::SysAllocString ( wszPrimaryDomain );
  114. if ( !*pstrPrimaryDomain ) {
  115. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  116. }
  117. Exit:
  118. if ( wszPrimaryDomain ) {
  119. delete [] wszPrimaryDomain;
  120. }
  121. return hr;
  122. }
  123. STDMETHODIMP
  124. CWebAdminHelper::DoesNTAccountExist (
  125. BSTR strServer,
  126. BSTR strAccountName,
  127. VARIANT_BOOL * pbAccountExists
  128. )
  129. {
  130. HRESULT hr;
  131. BOOL fExists = FALSE;
  132. hr = ::CheckNTAccount ( strServer, strAccountName, &fExists );
  133. BAIL_ON_FAILURE(hr);
  134. Exit:
  135. *pbAccountExists = fExists ? VARIANT_TRUE : VARIANT_FALSE;
  136. return hr;
  137. }
  138. STDMETHODIMP
  139. CWebAdminHelper::CreateNTAccount (
  140. BSTR strServer,
  141. BSTR strDomain,
  142. BSTR strUsername,
  143. BSTR strPassword
  144. )
  145. {
  146. HRESULT hr;
  147. hr = ::CreateNTAccount ( strServer, strDomain, strUsername, strPassword );
  148. return hr;
  149. }
  150. STDMETHODIMP
  151. CWebAdminHelper::IsValidEmailAddress (
  152. BSTR strEmailAddress,
  153. VARIANT_BOOL * pbValidAddress
  154. )
  155. {
  156. BOOL fIsValid;
  157. fIsValid = ::IsValidEmailAddress ( strEmailAddress );
  158. *pbValidAddress = fIsValid ? VARIANT_TRUE : VARIANT_FALSE;
  159. return NOERROR;
  160. }
  161. STDMETHODIMP
  162. CWebAdminHelper::ToSafeVariableName (
  163. BSTR strValue,
  164. BSTR * pstrSafeName
  165. )
  166. {
  167. HRESULT hr = NOERROR;
  168. DWORD cchRequired = 0;
  169. LPCWSTR wszValue;
  170. LPWSTR wszResult;
  171. BSTR strResult = NULL;
  172. *pstrSafeName = NULL;
  173. if ( strValue == NULL ) {
  174. goto Exit;
  175. }
  176. for ( wszValue = strValue, cchRequired = 0; *wszValue; wszValue++ ) {
  177. if ( iswalnum ( *wszValue ) ) {
  178. cchRequired++;
  179. }
  180. else {
  181. cchRequired += 7;
  182. }
  183. }
  184. strResult = ::SysAllocStringLen ( NULL, cchRequired );
  185. if ( !strResult ) {
  186. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  187. }
  188. for ( wszValue = strValue, wszResult = strResult; *wszValue; wszValue++ ) {
  189. if ( iswalnum ( *wszValue ) && *wszValue != _T('_') ) {
  190. *wszResult++ = *wszValue;
  191. }
  192. else {
  193. int cchCopied;
  194. cchCopied = wsprintf ( wszResult, _T("_%d_"), *wszValue );
  195. wszResult += cchCopied;
  196. }
  197. }
  198. *wszResult = NULL;
  199. *pstrSafeName = ::SysAllocString ( strResult );
  200. if ( !*pstrSafeName ) {
  201. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  202. }
  203. Exit:
  204. if ( strResult ) {
  205. ::SysFreeString ( strResult );
  206. }
  207. return hr;
  208. }
  209. STDMETHODIMP
  210. CWebAdminHelper::FromSafeVariableName (
  211. BSTR strSafeName,
  212. BSTR * pstrResult
  213. )
  214. {
  215. HRESULT hr = NOERROR;
  216. BSTR strResult = NULL;
  217. LPCWSTR wszValue;
  218. LPWSTR wszResult;
  219. *pstrResult = NULL;
  220. if ( strSafeName == NULL ) {
  221. goto Exit;
  222. }
  223. strResult = ::SysAllocString ( strSafeName );
  224. if ( !strResult ) {
  225. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  226. }
  227. for ( wszValue = strSafeName, wszResult = strResult; *wszValue; wszResult++ ) {
  228. if ( *wszValue != _T('_') ) {
  229. *wszResult = *wszValue++;
  230. }
  231. else {
  232. wszValue++;
  233. *wszResult = (WCHAR) _wtoi ( wszValue );
  234. wszValue = wcschr ( wszValue, _T('_') );
  235. _ASSERT ( wszValue != NULL );
  236. wszValue++;
  237. }
  238. }
  239. *wszResult = NULL;
  240. *pstrResult = ::SysAllocString ( strResult );
  241. if ( !*pstrResult ) {
  242. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  243. }
  244. Exit:
  245. ::SysFreeString ( strResult );
  246. return hr;
  247. }
  248. STDMETHODIMP
  249. CWebAdminHelper::AddToDL (
  250. IDispatch * pDispDL,
  251. BSTR strAdsPath
  252. )
  253. {
  254. HRESULT hr;
  255. CComPtr<IADsGroup> pGroup;
  256. hr = pDispDL->QueryInterface ( IID_IADsGroup, (void **) &pGroup );
  257. _ASSERT ( SUCCEEDED(hr) );
  258. BAIL_ON_FAILURE(hr);
  259. hr = pGroup->Add ( strAdsPath );
  260. BAIL_ON_FAILURE(hr);
  261. Exit:
  262. return hr;
  263. }
  264. STDMETHODIMP
  265. CWebAdminHelper::RemoveFromDL (
  266. IDispatch * pDispDL,
  267. BSTR strAdsPath
  268. )
  269. {
  270. HRESULT hr;
  271. CComPtr<IADsGroup> pGroup;
  272. hr = pDispDL->QueryInterface ( IID_IADsGroup, (void **) &pGroup );
  273. _ASSERT ( SUCCEEDED(hr) );
  274. BAIL_ON_FAILURE(hr);
  275. hr = pGroup->Remove ( strAdsPath );
  276. BAIL_ON_FAILURE(hr);
  277. Exit:
  278. return hr;
  279. }
  280. STDMETHODIMP
  281. CWebAdminHelper::ExecuteSearch (
  282. IDispatch * pDispRecipients,
  283. BSTR strQuery,
  284. long cMaxResultsHint
  285. )
  286. {
  287. HRESULT hr;
  288. LPWSTR rgwszAttributes [] = {
  289. { L"ADsPath" },
  290. { L"objectClass" },
  291. { L"mail" },
  292. { L"cn" },
  293. };
  294. ADS_SEARCHPREF_INFO rgSearchPrefs[3];
  295. DWORD cSearchPrefs = ARRAY_SIZE ( rgSearchPrefs );
  296. rgSearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  297. rgSearchPrefs[0].vValue.dwType = ADSTYPE_INTEGER;
  298. rgSearchPrefs[0].vValue.Integer = ADS_SCOPE_ONELEVEL;
  299. rgSearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
  300. rgSearchPrefs[1].vValue.dwType = ADSTYPE_INTEGER;
  301. rgSearchPrefs[1].vValue.Integer = 100;
  302. rgSearchPrefs[2].dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT;
  303. rgSearchPrefs[2].vValue.dwType = ADSTYPE_INTEGER;
  304. rgSearchPrefs[2].vValue.Integer = cMaxResultsHint + 10;
  305. if ( cMaxResultsHint == -1 || cMaxResultsHint == 0 ) {
  306. cSearchPrefs--;
  307. }
  308. hr = TerminateSearch ();
  309. _ASSERT ( SUCCEEDED(hr) );
  310. m_pSrch.Release ();
  311. hr = pDispRecipients->QueryInterface ( IID_IDirectorySearch, (void **) &m_pSrch);
  312. _ASSERT ( SUCCEEDED(hr) ); // Did you pass in a searchable object?
  313. BAIL_ON_FAILURE(hr);
  314. hr = m_pSrch->SetSearchPreference (
  315. rgSearchPrefs,
  316. cSearchPrefs
  317. );
  318. _ASSERT ( SUCCEEDED(hr) );
  319. BAIL_ON_FAILURE(hr);
  320. hr = m_pSrch->ExecuteSearch (
  321. strQuery,
  322. rgwszAttributes,
  323. ARRAY_SIZE ( rgwszAttributes ),
  324. &m_hSearchResults
  325. );
  326. BAIL_ON_FAILURE(hr);
  327. _ASSERT ( m_pSrch && m_hSearchResults );
  328. Exit:
  329. return hr;
  330. }
  331. #if 0
  332. STDMETHODIMP
  333. CWebAdminHelper::ExecuteSearch (
  334. IDispatch * pDispRecipients,
  335. BSTR strQuery,
  336. long cMaxResultsHint
  337. )
  338. {
  339. HRESULT hr;
  340. long LBound = 0;
  341. long UBound = -1;
  342. long cAttributes = 0;
  343. LPWSTR * rgwszAttributes = NULL;
  344. long iAttrib;
  345. long i;
  346. hr = TerminateSearch ();
  347. _ASSERT ( SUCCEEDED(hr) );
  348. m_pSrch.Release ();
  349. hr = pDispRecipients->QueryInterface ( IID_IDirectorySearch, (void **) &m_pSrch);
  350. _ASSERT ( SUCCEEDED(hr) ); // Did you pass in a searchable object?
  351. BAIL_ON_FAILURE(hr);
  352. _ASSERT ( SafeArrayGetDim ( psaColumns ) == 1 );
  353. hr = SafeArrayGetLBound ( psaColumns, 1, &LBound );
  354. _ASSERT ( SUCCEEDED(hr) );
  355. BAIL_ON_FAILURE(hr);
  356. hr = SafeArrayGetUBound ( psaColumns, 1, &UBound );
  357. _ASSERT ( SUCCEEDED(hr) );
  358. BAIL_ON_FAILURE(hr);
  359. cAttributes = UBound - LBound + 1;
  360. if ( cAttributes <= 0 ) {
  361. BAIL_WITH_FAILURE(hr,E_UNEXPECTED);
  362. }
  363. rgwszAttributes = new LPWSTR [ cAttributes ];
  364. if ( !rgwszAttributes ) {
  365. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  366. }
  367. ZeroMemory ( rgwszAttributes, cAttributes * sizeof ( rgwszAttributes[0] ) );
  368. for ( iAttrib = 0, i = LBound; i <= UBound; i++, iAttrib++ ) {
  369. CComVariant varElem;
  370. LPCWSTR wszElem;
  371. hr = SafeArrayGetElement ( psaColumns, &i, &varElem );
  372. BAIL_ON_FAILURE(hr);
  373. hr = varElem.ChangeType ( VT_BSTR );
  374. BAIL_ON_FAILURE(hr);
  375. wszElem = V_BSTR ( &varElem );
  376. rgwszAttributes[i] = new WCHAR [ lstrlen ( wszElem ) + 1 ];
  377. if ( rgwszAttributes[i] == NULL ) {
  378. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  379. }
  380. lstrcpy ( rgwszAttributes[i], wszElem );
  381. }
  382. hr = m_pSrch->ExecuteSearch (
  383. strQuery,
  384. rgwszAttributes,
  385. cAttributes,
  386. &m_hSearchResults
  387. );
  388. BAIL_ON_FAILURE(hr);
  389. _ASSERT ( m_pSrch && m_hSearchResults );
  390. Exit:
  391. for ( i = 0; rgwszAttributes && i < cAttributes; i++ ) {
  392. delete rgwszAttributes[i];
  393. }
  394. delete [] rgwszAttributes;
  395. return hr;
  396. }
  397. #endif
  398. STDMETHODIMP
  399. CWebAdminHelper::GetNextRow (
  400. VARIANT_BOOL * pbNextRow
  401. )
  402. {
  403. HRESULT hr;
  404. _ASSERT ( m_pSrch && m_hSearchResults );
  405. hr = m_pSrch->GetNextRow ( m_hSearchResults );
  406. *pbNextRow = (hr == S_OK) ? VARIANT_TRUE : VARIANT_FALSE;
  407. return hr;
  408. }
  409. STDMETHODIMP
  410. CWebAdminHelper::GetColumn (
  411. BSTR strColName,
  412. BSTR * pstrColValue
  413. )
  414. {
  415. HRESULT hr;
  416. ADS_SEARCH_COLUMN column;
  417. CComVariant varColumn;
  418. _ASSERT ( m_pSrch && m_hSearchResults );
  419. *pstrColValue = NULL;
  420. hr = m_pSrch->GetColumn ( m_hSearchResults, strColName, &column );
  421. BAIL_ON_FAILURE(hr);
  422. varColumn = column.pADsValues[0].PrintableString;
  423. *pstrColValue = SysAllocString ( V_BSTR ( &varColumn ) );
  424. if ( !*pstrColValue ) {
  425. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  426. }
  427. Exit:
  428. if ( column.pADsValues != NULL ) {
  429. HRESULT hrCheck;
  430. hrCheck = m_pSrch->FreeColumn ( &column );
  431. _ASSERT ( SUCCEEDED(hrCheck) );
  432. }
  433. return hr;
  434. }
  435. STDMETHODIMP
  436. CWebAdminHelper::TerminateSearch ( )
  437. {
  438. if ( m_hSearchResults ) {
  439. _ASSERT ( m_pSrch );
  440. m_pSrch->CloseSearchHandle ( m_hSearchResults );
  441. m_hSearchResults = NULL;
  442. }
  443. m_pSrch.Release ();
  444. return NOERROR;
  445. }