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.

664 lines
15 KiB

  1. // vdir.cpp : Implementation of CsmtpadmApp and DLL registration.
  2. #include "stdafx.h"
  3. #include <listmacr.h>
  4. #include "IADM.h"
  5. #include "imd.h"
  6. #include "inetcom.h"
  7. #include "smtpadm.h"
  8. #include "vdir.h"
  9. #include "oleutil.h"
  10. #include "metafact.h"
  11. #include "metautil.h"
  12. #include "smtpcmn.h"
  13. #include "smtpprop.h"
  14. // Must define THIS_FILE_* macros to use SmtpCreateException()
  15. #define THIS_FILE_HELP_CONTEXT 0
  16. #define THIS_FILE_PROG_ID _T("Smtpadm.VirtualDirectory.1")
  17. #define THIS_FILE_IID IID_ISmtpAdminVirtualDirectory
  18. typedef struct _VDIR_ENTRY {
  19. TCHAR szName[METADATA_MAX_NAME_LEN+2];
  20. TCHAR szDirectory[MAX_PATH + UNLEN + 3];
  21. TCHAR szUser[UNLEN+1];
  22. TCHAR szPassword[PWLEN+1];
  23. DWORD dwAccess;
  24. DWORD dwSslAccess;
  25. BOOL fLogAccess;
  26. LIST_ENTRY list;
  27. } VDIR_ENTRY, * PVDIR_ENTRY;
  28. /////////////////////////////////////////////////////////////////////////////
  29. //
  30. STDMETHODIMP CSmtpAdminVirtualDirectory::InterfaceSupportsErrorInfo(REFIID riid)
  31. {
  32. static const IID* arr[] =
  33. {
  34. &IID_ISmtpAdminVirtualDirectory,
  35. };
  36. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  37. {
  38. if (InlineIsEqualGUID(*arr[i],riid))
  39. return S_OK;
  40. }
  41. return S_FALSE;
  42. }
  43. CSmtpAdminVirtualDirectory::CSmtpAdminVirtualDirectory () :
  44. m_dwServiceInstance ( 0 ),
  45. m_lCount ( 0 )
  46. // CComBSTR's are initialized to NULL by default.
  47. {
  48. m_dwAccess = MD_ACCESS_READ | MD_ACCESS_WRITE;
  49. m_dwSslAccess = 0;
  50. InitializeListHead( &m_list );
  51. }
  52. CSmtpAdminVirtualDirectory::~CSmtpAdminVirtualDirectory ()
  53. {
  54. Clear();
  55. // All CComBSTR's are freed automatically.
  56. }
  57. void CSmtpAdminVirtualDirectory::Clear()
  58. {
  59. m_lCount = 0;
  60. m_fEnumerateCalled = FALSE;
  61. m_strName.Empty();
  62. m_strDirectory.Empty();
  63. m_strUser.Empty();
  64. m_strPassword.Empty();
  65. m_dwAccess = MD_ACCESS_READ | MD_ACCESS_WRITE;
  66. m_dwSslAccess = 0;
  67. // release memory
  68. PLIST_ENTRY pHead;
  69. PLIST_ENTRY pEntry;
  70. PLIST_ENTRY pTemp;
  71. PVDIR_ENTRY pCurVDir=NULL;
  72. for( pHead=&m_list, pEntry=pHead->Flink; pEntry!=pHead; )
  73. {
  74. pTemp = pEntry;
  75. pEntry= pEntry->Flink;
  76. pCurVDir = CONTAINING_RECORD(pTemp, VDIR_ENTRY, list);
  77. RemoveEntryList( pTemp );
  78. delete pCurVDir;
  79. }
  80. _ASSERT( IsListEmpty(&m_list) );
  81. }
  82. //////////////////////////////////////////////////////////////////////
  83. // Properties:
  84. //////////////////////////////////////////////////////////////////////
  85. // Which service to configure:
  86. STDMETHODIMP CSmtpAdminVirtualDirectory::get_Server ( BSTR * pstrServer )
  87. {
  88. return StdPropertyGet ( m_strServer, pstrServer );
  89. }
  90. STDMETHODIMP CSmtpAdminVirtualDirectory::put_Server ( BSTR strServer )
  91. {
  92. return StdPropertyPutServerName ( &m_strServer, strServer );
  93. }
  94. STDMETHODIMP CSmtpAdminVirtualDirectory::get_ServiceInstance ( long * plServiceInstance )
  95. {
  96. return StdPropertyGet ( m_dwServiceInstance, plServiceInstance );
  97. }
  98. STDMETHODIMP CSmtpAdminVirtualDirectory::put_ServiceInstance ( long lServiceInstance )
  99. {
  100. return StdPropertyPut ( (long *) &m_dwServiceInstance, lServiceInstance );
  101. }
  102. // enumeration
  103. STDMETHODIMP CSmtpAdminVirtualDirectory::get_Count ( long * plCount )
  104. {
  105. return StdPropertyGet ( m_lCount, plCount );
  106. }
  107. // VirtualDirectory property
  108. STDMETHODIMP CSmtpAdminVirtualDirectory::get_VirtualName ( BSTR * pstrName )
  109. {
  110. return StdPropertyGet ( m_strName, pstrName );
  111. }
  112. STDMETHODIMP CSmtpAdminVirtualDirectory::put_VirtualName ( BSTR strName )
  113. {
  114. return StdPropertyPut ( &m_strName, strName );
  115. }
  116. STDMETHODIMP CSmtpAdminVirtualDirectory::get_Directory ( BSTR * pstrPath )
  117. {
  118. return StdPropertyGet ( m_strDirectory, pstrPath );
  119. }
  120. STDMETHODIMP CSmtpAdminVirtualDirectory::put_Directory ( BSTR strPath )
  121. {
  122. return StdPropertyPut ( &m_strDirectory, strPath );
  123. }
  124. STDMETHODIMP CSmtpAdminVirtualDirectory::get_User ( BSTR * pstrUserName )
  125. {
  126. return StdPropertyGet ( m_strUser, pstrUserName );
  127. }
  128. STDMETHODIMP CSmtpAdminVirtualDirectory::put_User ( BSTR strUserName )
  129. {
  130. return StdPropertyPut ( &m_strUser, strUserName );
  131. }
  132. STDMETHODIMP CSmtpAdminVirtualDirectory::get_Password ( BSTR * pstrPassword )
  133. {
  134. return StdPropertyGet ( m_strPassword, pstrPassword );
  135. }
  136. STDMETHODIMP CSmtpAdminVirtualDirectory::put_Password ( BSTR strPassword )
  137. {
  138. return StdPropertyPut ( &m_strPassword, strPassword );
  139. }
  140. STDMETHODIMP CSmtpAdminVirtualDirectory::get_LogAccess( BOOL* pfLogAccess )
  141. {
  142. return StdPropertyGet ( m_fLogAccess, pfLogAccess );
  143. }
  144. STDMETHODIMP CSmtpAdminVirtualDirectory::put_LogAccess( BOOL fLogAccess )
  145. {
  146. return StdPropertyPut ( &m_fLogAccess, fLogAccess );
  147. }
  148. STDMETHODIMP CSmtpAdminVirtualDirectory::get_AccessPermission( long* plAccessPermission )
  149. {
  150. return StdPropertyGet ( m_dwAccess, plAccessPermission );
  151. }
  152. STDMETHODIMP CSmtpAdminVirtualDirectory::put_AccessPermission( long lAccessPermission )
  153. {
  154. return StdPropertyPut ( &m_dwAccess, lAccessPermission );
  155. }
  156. STDMETHODIMP CSmtpAdminVirtualDirectory::get_SslAccessPermission( long* plSslAccessPermission )
  157. {
  158. return StdPropertyGet ( m_dwSslAccess, plSslAccessPermission );
  159. }
  160. STDMETHODIMP CSmtpAdminVirtualDirectory::put_SslAccessPermission( long lSslAccessPermission )
  161. {
  162. return StdPropertyPut ( &m_dwSslAccess, lSslAccessPermission );
  163. }
  164. //////////////////////////////////////////////////////////////////////
  165. // Methods:
  166. //////////////////////////////////////////////////////////////////////
  167. // get /set property for current vdir
  168. STDMETHODIMP CSmtpAdminVirtualDirectory::GetHomeDirectory( )
  169. {
  170. TraceFunctEnter ( "CSmtpAdminVirtualDirectory::GetHomeDirectory" );
  171. m_strName.Empty();
  172. m_strName = _T("");
  173. return Get();
  174. }
  175. STDMETHODIMP CSmtpAdminVirtualDirectory::SetHomeDirectory( )
  176. {
  177. TraceFunctEnter ( "CSmtpAdminVirtualDirectory::SetHomeDirectory" );
  178. m_strName.Empty();
  179. m_strName = _T("");
  180. return Set();
  181. }
  182. STDMETHODIMP CSmtpAdminVirtualDirectory::Create ( )
  183. {
  184. TraceFunctEnter ( "CSmtpAdminVirtualDirectory::Create" );
  185. HRESULT hr = NOERROR;
  186. CComPtr<IMSAdminBase> pmetabase;
  187. TCHAR szPath[METADATA_MAX_NAME_LEN+2] = {0};
  188. if( !m_strName || !m_strDirectory )
  189. {
  190. FatalTrace ( (LPARAM) this, "No virtual directory to create!" );
  191. hr = E_POINTER;
  192. return hr;
  193. }
  194. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  195. if ( FAILED(hr) ) {
  196. return SmtpCreateExceptionFromHresult(hr);
  197. }
  198. CMetabaseKey hMB( pmetabase );
  199. GetMDRootPath( szPath, m_dwServiceInstance );
  200. hr = hMB.Open( szPath, METADATA_PERMISSION_WRITE );
  201. BAIL_ON_FAILURE(hr);
  202. hr = hMB.CreateChild(m_strName);
  203. BAIL_ON_FAILURE(hr);
  204. if( !SetVRootPropertyToMetabase( &hMB, m_strName, m_strDirectory, m_strUser, m_strPassword, m_dwAccess, m_dwSslAccess, m_fLogAccess) )
  205. {
  206. hr = SmtpCreateExceptionFromWin32Error( GetLastError() );
  207. goto Exit;
  208. }
  209. hr = hMB.Save();
  210. BAIL_ON_FAILURE(hr);
  211. Exit:
  212. if( FAILED(hr) )
  213. {
  214. hr = SmtpCreateExceptionFromHresult(hr);
  215. }
  216. TraceFunctLeave ();
  217. return hr;
  218. }
  219. STDMETHODIMP CSmtpAdminVirtualDirectory::Delete ( )
  220. {
  221. TraceFunctEnter ( "CSmtpAdminVirtualDirectory::Delete" );
  222. HRESULT hr = NOERROR;
  223. CComPtr<IMSAdminBase> pmetabase;
  224. TCHAR szPath[METADATA_MAX_NAME_LEN+2] = {0};
  225. if ( !m_strName ) {
  226. FatalTrace ( (LPARAM) this, "Bad dir name to delete" );
  227. return E_POINTER;
  228. }
  229. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  230. if ( FAILED(hr) ) {
  231. return hr;
  232. }
  233. GetMDRootPath( szPath, m_dwServiceInstance );
  234. CMetabaseKey hMB( pmetabase );
  235. hr = hMB.Open( szPath, METADATA_PERMISSION_WRITE);
  236. BAIL_ON_FAILURE(hr);
  237. hr = hMB.DestroyChild(m_strName);
  238. BAIL_ON_FAILURE(hr);
  239. hr = hMB.Save();
  240. BAIL_ON_FAILURE(hr);
  241. Exit:
  242. if( FAILED(hr) )
  243. {
  244. hr = SmtpCreateExceptionFromHresult(hr);
  245. }
  246. TraceFunctLeave ();
  247. return hr;
  248. }
  249. // get /set property for current vdir
  250. STDMETHODIMP CSmtpAdminVirtualDirectory::Get( )
  251. {
  252. TraceFunctEnter ( "CSmtpAdminVirtualDirectory::Get" );
  253. HRESULT hr = NOERROR;
  254. CComPtr<IMSAdminBase> pmetabase;
  255. TCHAR szPath[METADATA_MAX_NAME_LEN+2] = {0};
  256. TCHAR szDirectory[MAX_PATH + UNLEN + 3] = {0};
  257. TCHAR szUser[UNLEN+1] = {0};
  258. TCHAR szPassword[PWLEN+1] = {0};
  259. // zero out
  260. m_strDirectory = (BSTR)NULL;
  261. m_strUser = (BSTR)NULL;
  262. m_strPassword = (BSTR)NULL;
  263. if( !m_strName )
  264. {
  265. FatalTrace ( (LPARAM) this, "No virtual directory to create!" );
  266. hr = E_POINTER;
  267. return hr;
  268. }
  269. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  270. if ( FAILED(hr) ) {
  271. return hr;
  272. }
  273. CMetabaseKey hMB( pmetabase );
  274. GetMDVDirPath( szPath, m_dwServiceInstance, m_strName );
  275. hr = hMB.Open( szPath );
  276. if( FAILED(hr) )
  277. {
  278. hr = SmtpCreateExceptionFromWin32Error( GetLastError() );
  279. goto Exit;
  280. }
  281. if( !GetVRootPropertyFromMetabase( &hMB, _T(""), szDirectory, szUser, szPassword, &m_dwAccess, &m_dwSslAccess, &m_fLogAccess) )
  282. {
  283. hr = SmtpCreateExceptionFromWin32Error( GetLastError() );
  284. goto Exit;
  285. }
  286. m_strDirectory = szDirectory;
  287. m_strUser = szUser;
  288. m_strPassword = szPassword;
  289. Exit:
  290. TraceFunctLeave ();
  291. return hr;
  292. }
  293. STDMETHODIMP CSmtpAdminVirtualDirectory::Set( )
  294. {
  295. TraceFunctEnter ( "CSmtpAdminVirtualDirectory::Set" );
  296. HRESULT hr = NOERROR;
  297. CComPtr<IMSAdminBase> pmetabase;
  298. TCHAR szPath[METADATA_MAX_NAME_LEN+2] = {0};
  299. if( !m_strName || !m_strDirectory )
  300. {
  301. ErrorTrace ( (LPARAM) this, "No virtual directory to create!" );
  302. hr = E_POINTER;
  303. return hr;
  304. }
  305. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  306. if ( FAILED(hr) ) {
  307. return hr;
  308. }
  309. CMetabaseKey hMB( pmetabase );
  310. GetMDVDirPath( szPath, m_dwServiceInstance, m_strName );
  311. hr = hMB.Open( szPath,METADATA_PERMISSION_WRITE );
  312. BAIL_ON_FAILURE(hr);
  313. if( !SetVRootPropertyToMetabase( &hMB, _T(""), m_strDirectory, m_strUser, m_strPassword, m_dwAccess, m_dwSslAccess, m_fLogAccess) )
  314. {
  315. hr = SmtpCreateExceptionFromWin32Error( GetLastError() );
  316. return hr;
  317. }
  318. hr = hMB.Save();
  319. Exit:
  320. if( FAILED(hr) )
  321. {
  322. hr = SmtpCreateExceptionFromHresult(hr);
  323. }
  324. TraceFunctLeave ();
  325. return hr;
  326. }
  327. STDMETHODIMP CSmtpAdminVirtualDirectory::Enumerate( )
  328. {
  329. TraceFunctEnter ( "CSmtpAdminVirtualDirectory::Enumerate" );
  330. HRESULT hr = NOERROR;
  331. CComPtr<IMSAdminBase> pmetabase;
  332. TCHAR szPath[METADATA_MAX_NAME_LEN+2] = {0};
  333. DWORD dwAccess;
  334. DWORD dwSslAccess;
  335. BOOL fLogAccess;
  336. TCHAR szName[METADATA_MAX_NAME_LEN+2];
  337. TCHAR szDirectory[MAX_PATH + UNLEN + 3];
  338. TCHAR szUser[UNLEN+1];
  339. TCHAR szPassword[PWLEN+1];
  340. INT i;
  341. PVDIR_ENTRY pCurVDir=NULL;
  342. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  343. if ( FAILED(hr) ) {
  344. return hr;;
  345. }
  346. GetMDRootPath( szPath, m_dwServiceInstance );
  347. CMetabaseKey hMB( pmetabase );
  348. hr = hMB.Open( szPath );
  349. if( FAILED(hr) )
  350. {
  351. hr = SmtpCreateExceptionFromHresult( hr );
  352. goto Exit;
  353. }
  354. Clear(); // reset state, m_lCount = 0
  355. i = 0;
  356. while( SUCCEEDED( hMB.EnumObjects(_T(""), szName, i ++) ) )
  357. {
  358. if ( !GetVRootPropertyFromMetabase( &hMB, szName, szDirectory, szUser, szPassword, &dwAccess, &dwSslAccess, &fLogAccess) )
  359. {
  360. continue;
  361. }
  362. pCurVDir = new VDIR_ENTRY;
  363. if( !pCurVDir )
  364. {
  365. hr = E_OUTOFMEMORY;
  366. goto Exit;
  367. }
  368. lstrcpy( pCurVDir->szName, szName);
  369. lstrcpy( pCurVDir->szDirectory, szDirectory);
  370. lstrcpy( pCurVDir->szUser, szUser);
  371. lstrcpy( pCurVDir->szPassword, szPassword);
  372. pCurVDir-> dwAccess = dwAccess;
  373. pCurVDir-> dwSslAccess = dwSslAccess;
  374. pCurVDir-> fLogAccess = fLogAccess;
  375. InsertHeadList( &m_list, &(pCurVDir->list) );
  376. m_lCount ++;
  377. }
  378. // _ASSERT( GetLastError() == ERROR_NO_MORE_ITEMS );
  379. m_fEnumerateCalled = TRUE;
  380. Exit:
  381. TraceFunctLeave ();
  382. return hr;
  383. }
  384. STDMETHODIMP CSmtpAdminVirtualDirectory::GetNth ( long lIndex )
  385. {
  386. TraceFunctEnter ( "CSmtpAdminVirtualDirectory::GetNth" );
  387. if( lIndex < 0 || lIndex >= m_lCount )
  388. {
  389. TraceFunctLeave ();
  390. return SmtpCreateException ( IDS_SMTPEXCEPTION_INVALID_INDEX );
  391. }
  392. PLIST_ENTRY pEntry;
  393. PVDIR_ENTRY pVdir;
  394. INT i;
  395. if( !m_fEnumerateCalled )
  396. {
  397. TraceFunctLeave ();
  398. return SmtpCreateException ( IDS_SMTPEXCEPTION_INVALID_INDEX );
  399. }
  400. // zero out
  401. m_strName = (BSTR)NULL;
  402. m_strDirectory = (BSTR)NULL;
  403. m_strUser = (BSTR)NULL;
  404. m_strPassword = (BSTR)NULL;
  405. pEntry = &m_list;
  406. for( i=0; i<=lIndex; i++ )
  407. {
  408. pEntry=pEntry->Flink;
  409. _ASSERT( pEntry != & m_list);
  410. if( pEntry == & m_list )
  411. {
  412. TraceFunctLeave ();
  413. return SmtpCreateException ( IDS_SMTPEXCEPTION_INVALID_INDEX );
  414. }
  415. }
  416. pVdir = CONTAINING_RECORD(pEntry, VDIR_ENTRY, list);
  417. // automatically changed to UNICODE
  418. m_strName = pVdir->szName;
  419. m_strDirectory = pVdir->szDirectory;
  420. m_strUser = pVdir->szUser;
  421. m_strPassword = pVdir->szPassword;
  422. TraceFunctLeave ();
  423. return NOERROR;
  424. }
  425. BOOL CSmtpAdminVirtualDirectory::GetVRootPropertyFromMetabase(
  426. CMetabaseKey* hMB,
  427. const TCHAR* szName,
  428. TCHAR* szDirectory,
  429. TCHAR* szUser,
  430. TCHAR* szPassword,
  431. DWORD* pdwAccess,
  432. DWORD* pdwSslAccess,
  433. BOOL* pfLogAccess
  434. )
  435. {
  436. DWORD cb;
  437. DWORD dwDontLog = DEFAULT_LOG_TYPE;
  438. HRESULT hr = NOERROR;
  439. TraceFunctEnter ( "CSmtpAdminVirtualDirectory::GetVRootPropertyFromMetabase" );
  440. cb = (MAX_PATH + UNLEN + 3) * sizeof(TCHAR);
  441. hr = hMB->GetString( szName, MD_VR_PATH, szDirectory,cb,0 );
  442. if( FAILED(hr) )
  443. {
  444. szDirectory[0] = _T('\0');
  445. }
  446. StdGetMetabaseProp( hMB, MD_ACCESS_PERM, MD_ACCESS_READ | MD_ACCESS_WRITE,
  447. pdwAccess, szName );
  448. StdGetMetabaseProp( hMB, MD_SSL_ACCESS_PERM, 0,
  449. pdwSslAccess, szName );
  450. StdGetMetabaseProp( hMB, MD_DONT_LOG, DEFAULT_LOG_TYPE,
  451. &dwDontLog, szName );
  452. *pfLogAccess = !dwDontLog;
  453. cb = sizeof(TCHAR) * (UNLEN+1);
  454. hr = hMB->GetString(szName,MD_VR_USERNAME,szUser,cb);
  455. if( FAILED(hr) )
  456. {
  457. szUser[0] = _T('\0');
  458. }
  459. cb = sizeof(TCHAR) * (PWLEN+1);
  460. if ( (szUser[0] != _T('\0')) &&
  461. (szDirectory[0] == _T('\\')) &&
  462. (szDirectory[1] == _T('\\')) )
  463. {
  464. hr = hMB->GetString(szName,MD_VR_PASSWORD,szPassword,cb,METADATA_NO_ATTRIBUTES);
  465. if( FAILED(hr) )
  466. {
  467. DebugTrace( (LPARAM)this, "Error %d reading path from %s\n", GetLastError(), szName);
  468. szPassword[0] = _T('\0');
  469. }
  470. }
  471. return TRUE;
  472. }
  473. BOOL CSmtpAdminVirtualDirectory::SetVRootPropertyToMetabase(
  474. CMetabaseKey* hMB,
  475. const TCHAR* szName,
  476. const TCHAR* szDirectory,
  477. const TCHAR* szUser,
  478. const TCHAR* szPassword,
  479. DWORD dwAccess,
  480. DWORD dwSslAccess,
  481. BOOL fLogAccess
  482. )
  483. {
  484. DWORD dwDontLog = fLogAccess ? 0 : 1;
  485. HRESULT hr = NOERROR;
  486. hr = hMB->SetString( szName,MD_VR_PATH, szDirectory );
  487. BAIL_ON_FAILURE(hr);
  488. hr = hMB->SetDword( szName, MD_DONT_LOG, dwDontLog);
  489. BAIL_ON_FAILURE(hr);
  490. hr = hMB->SetDword( szName, MD_ACCESS_PERM, dwAccess );
  491. BAIL_ON_FAILURE(hr);
  492. hr = hMB->SetDword( szName, MD_SSL_ACCESS_PERM, dwSslAccess);
  493. BAIL_ON_FAILURE(hr);
  494. if( szUser[0] )
  495. {
  496. hr = hMB->SetString( szName, MD_VR_USERNAME, szUser);
  497. }
  498. if( szPassword[0] )
  499. {
  500. hr = hMB->SetString( szName, MD_VR_PASSWORD, szPassword, METADATA_INHERIT | METADATA_SECURE );
  501. }
  502. Exit:
  503. if( FAILED(hr) )
  504. {
  505. SetLastError(hr);
  506. return FALSE;
  507. }
  508. return TRUE;
  509. }