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.

2668 lines
76 KiB

  1. // server.cpp : Implementation of CnntpadmApp and DLL registration.
  2. #include "stdafx.h"
  3. #include <lmcons.h>
  4. #include <sddl.h>
  5. #include "nntpcmn.h"
  6. #include "oleutil.h"
  7. #include "cmultisz.h"
  8. #include "metautil.h"
  9. #include "metakey.h"
  10. #include "server.h"
  11. // Must define THIS_FILE_* macros to use NntpCreateException()
  12. #define THIS_FILE_HELP_CONTEXT 0
  13. #define THIS_FILE_PROG_ID _T("Nntpadm.VirtualServer.1")
  14. #define THIS_FILE_IID IID_INntpVirtualServer
  15. // Bitmasks for changed fields:
  16. #define CHNG_ARTICLETIMELIMIT 0x00000001
  17. #define CHNG_HISTORYEXPIRATION 0x00000002
  18. #define CHNG_HONORCLIENTMSGIDS 0x00000004
  19. #define CHNG_SMTPSERVER 0x00000008
  20. #define CHNG_ALLOWCLIENTPOSTS 0x00000010
  21. #define CHNG_ALLOWFEEDPOSTS 0x00000020
  22. #define CHNG_ALLOWCONTROLMSGS 0x00000040
  23. #define CHNG_DEFAULTMODERATORDOMAIN 0x00000080
  24. #define CHNG_COMMANDLOGMASK 0x00000100
  25. #define CHNG_DISABLENEWNEWS 0x00000200
  26. #define CHNG_NEWSCRAWLERTIME 0x00000400
  27. #define CHNG_SHUTDOWNLATENCY 0x00000800
  28. #define CHNG_CLIENTPOSTHARDLIMIT 0x00001000
  29. #define CHNG_CLIENTPOSTSOFTLIMIT 0x00002000
  30. #define CHNG_FEEDPOSTHARDLIMIT 0x00004000
  31. #define CHNG_FEEDPOSTSOFTLIMIT 0x00008000
  32. #define CHNG_GROUPHELPFILE 0x00010000
  33. #define CHNG_GROUPLISTFILE 0x00020000
  34. #define CHNG_ARTICLETABLEFILE 0x00040000
  35. #define CHNG_HISTORYTABLEFILE 0x00080000
  36. #define CHNG_MODERATORFILE 0x00100000
  37. #define CHNG_XOVERTABLEFILE 0x00200000
  38. #define CHNG_DISPLAYNAME 0x00400000
  39. #define CHNG_ERRORCONTROL 0x00800000
  40. #define CHNG_CLEANBOOT 0x01000000
  41. #define CHNG_UUCPNAME 0x02000000
  42. #define CHNG_ORGANIZATION 0x04000000
  43. #define CHNG_AUTOSTART 0x08000000
  44. #define CHNG_COMMENT 0x10000000
  45. #define CHNG_BINDING 0x20000000
  46. #define CHNG_SECUREPORT 0x40000000
  47. #define CHNG_MAXCONNECTIONS 0x80000000
  48. #define CHNG2_CONNECTIONTIMEOUT 0x00000001
  49. #define CHNG2_ANONYMOUSUSERNAME 0x00000002
  50. #define CHNG2_ANONYMOUSUSERPASS 0x00000004
  51. #define CHNG2_PICKUPDIRECTORY 0x00000008
  52. #define CHNG2_FAILEDPICKUPDIRECTORY 0x00000010
  53. #define CHNG2_HOMEDIRECTORY 0x00000020
  54. #define CHNG2_NTAUTHENTICATION_PROVIDERS 0x00000040
  55. #define CHNG2_AUTHORIZATION 0x00000080
  56. #define CHNG2_ENABLELOGGING 0x00000100
  57. #define CHNG2_SSLACCESS 0x00000200
  58. #define CHNG2_AUTOSYNCPASSWORD 0x00000400
  59. #define CHNG2_ADMINEMAIL 0x00000800
  60. #define CHNG2_CLUSTERENABLED 0x00001000
  61. #define CHNG2_ADMINACL 0x00002000
  62. #define NNTP_DEF_ADMIN_EMAIL _T( "" )
  63. #define NNTP_DEF_NTAUTHENTICATION_PROVIDERS _T("NTLM\0")
  64. #define NNTP_DEF_AUTHORIZATION ( 0 )
  65. #define NNTP_DEF_ENABLE_LOGGING ( FALSE )
  66. #define NNTP_DEF_SECURE_BINDINGS ( _T("\0") )
  67. // Parameter ranges:
  68. #define MAXLEN_SERVER ( 256 )
  69. #define MIN_ARTICLETIMELIMIT ( (DWORD) 0 )
  70. #define MAX_ARTICLETIMELIMIT ( (DWORD) -1 )
  71. #define MIN_HISTORYEXPIRATION ( (DWORD) 0 )
  72. #define MAX_HISTORYEXPIRATION ( (DWORD) -1 )
  73. #define MAXLEN_SMTPSERVER ( 256 )
  74. #define MAXLEN_DEFAULTMODERATORDOMAIN ( 256 )
  75. #define MIN_COMMANDLOGMASK ( (DWORD) 0 )
  76. #define MAX_COMMANDLOGMASK ( (DWORD) -1 )
  77. #define MIN_NEWSCRAWLERTIME ( (DWORD) 1 )
  78. #define MAX_NEWSCRAWLERTIME ( (DWORD) -1 )
  79. #define MIN_SHUTDOWNLATENCY ( (DWORD) 1 )
  80. #define MAX_SHUTDOWNLATENCY ( (DWORD) -1 )
  81. //
  82. // Administrator ACL:
  83. //
  84. static HRESULT AclToAdministrators ( LPCTSTR strServer, PSECURITY_DESCRIPTOR pSDRelative, SAFEARRAY ** ppsaAdmins );
  85. static HRESULT AdministratorsToAcl ( LPCTSTR strServer, SAFEARRAY * psaAdmins, PSECURITY_DESCRIPTOR* ppSD, DWORD * pcbSD );
  86. static HRESULT SidToString ( LPCWSTR strSystemName, PSID pSID, BSTR * pStr );
  87. static HRESULT StringToSid ( LPCWSTR strSystemName, LPWSTR str, PSID * ppSID );
  88. /////////////////////////////////////////////////////////////////////////////
  89. //
  90. CNntpVirtualServer::CNntpVirtualServer () :
  91. m_dwServiceInstance ( 0 ),
  92. m_dwClientPostHardLimit ( 0 ),
  93. m_dwClientPostSoftLimit ( 0 ),
  94. m_dwFeedPostHardLimit ( 0 ),
  95. m_dwFeedPostSoftLimit ( 0 ),
  96. m_dwEncryptionCapabilities ( 0 ),
  97. m_fAutoSyncPassword ( FALSE ),
  98. m_fErrorControl ( FALSE ),
  99. m_fCleanBoot ( FALSE ),
  100. m_fAutoStart ( FALSE ),
  101. m_psaAdmins ( NULL ),
  102. m_State ( NNTP_SERVER_STATE_UNKNOWN ),
  103. m_dwWin32ErrorCode ( NOERROR ),
  104. m_pPrivateBindings ( NULL ),
  105. m_pPrivateIpAccess ( NULL ),
  106. // m_pPrivateHomeDirectory ( NULL ),
  107. m_fGotProperties ( FALSE ),
  108. m_fClusterEnabled ( FALSE ),
  109. m_bvChangedFields ( 0 ),
  110. m_bvChangedFields2 ( 0 )
  111. // CComBSTR's are initialized to NULL by default.
  112. {
  113. InitAsyncTrace ( );
  114. // Create the Ip Access collection:
  115. CComObject<CTcpAccess> * pIpAccess;
  116. CComObject<CTcpAccess>::CreateInstance ( &pIpAccess );
  117. pIpAccess->QueryInterface ( IID_ITcpAccess, (void **) &m_pIpAccess );
  118. m_pPrivateIpAccess = pIpAccess;
  119. }
  120. CNntpVirtualServer::~CNntpVirtualServer ()
  121. {
  122. // All CComBSTR's are freed automatically.
  123. if ( m_psaAdmins ) {
  124. SafeArrayDestroy ( m_psaAdmins );
  125. }
  126. TermAsyncTrace ( );
  127. }
  128. STDMETHODIMP CNntpVirtualServer::InterfaceSupportsErrorInfo(REFIID riid)
  129. {
  130. static const IID* arr[] =
  131. {
  132. &IID_INntpVirtualServer,
  133. };
  134. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  135. {
  136. if (InlineIsEqualGUID(*arr[i],riid))
  137. return S_OK;
  138. }
  139. return S_FALSE;
  140. }
  141. // Which service to configure:
  142. STDMETHODIMP CNntpVirtualServer::get_Server ( BSTR * pstrServer )
  143. {
  144. return StdPropertyGet ( m_strServer, pstrServer );
  145. }
  146. STDMETHODIMP CNntpVirtualServer::put_Server ( BSTR strServer )
  147. {
  148. VALIDATE_STRING ( strServer, MAXLEN_SERVER );
  149. // If the server name changes, that means the client will have to
  150. // call Get again:
  151. // I assume this here:
  152. _ASSERT ( sizeof (DWORD) == sizeof (int) );
  153. return StdPropertyPutServerName ( &m_strServer, strServer, (DWORD *) &m_fGotProperties, 1 );
  154. }
  155. STDMETHODIMP CNntpVirtualServer::get_ServiceInstance ( long * plServiceInstance )
  156. {
  157. return StdPropertyGet ( m_dwServiceInstance, plServiceInstance );
  158. }
  159. STDMETHODIMP CNntpVirtualServer::put_ServiceInstance ( long lServiceInstance )
  160. {
  161. // If the service instance changes, that means the client will have to
  162. // call Get again:
  163. // I assume this here:
  164. _ASSERT ( sizeof (DWORD) == sizeof (int) );
  165. return StdPropertyPut ( &m_dwServiceInstance, lServiceInstance, (DWORD *) &m_fGotProperties, 1 );
  166. }
  167. // Other admin interfaces for virtual servers:
  168. STDMETHODIMP CNntpVirtualServer::get_FeedsAdmin ( IDispatch ** ppIDispatch )
  169. {
  170. HRESULT hr = NOERROR;
  171. CComPtr<INntpAdminFeeds> pINntpAdminFeeds;
  172. CComBSTR strTemp = _T("");
  173. if (!strTemp)
  174. {
  175. hr = E_OUTOFMEMORY;
  176. goto Error;
  177. }
  178. hr = StdPropertyHandoffIDispatch (
  179. CLSID_CNntpAdminFeeds,
  180. IID_INntpAdminFeeds,
  181. &pINntpAdminFeeds,
  182. ppIDispatch
  183. );
  184. if ( FAILED(hr) ) {
  185. goto Error;
  186. }
  187. // Set default properties:
  188. hr = pINntpAdminFeeds->put_Server ( m_strServer ? m_strServer : strTemp );
  189. if ( FAILED (hr) ) {
  190. goto Error;
  191. }
  192. hr = pINntpAdminFeeds->put_ServiceInstance ( m_dwServiceInstance );
  193. if ( FAILED (hr) ) {
  194. goto Error;
  195. }
  196. return hr;
  197. Error:
  198. SAFE_RELEASE ( *ppIDispatch );
  199. *ppIDispatch = NULL;
  200. return hr;
  201. // Destructor releases pINntpAdminFeeds
  202. }
  203. STDMETHODIMP CNntpVirtualServer::get_GroupsAdmin ( IDispatch ** ppIDispatch )
  204. {
  205. HRESULT hr = NOERROR;
  206. CComPtr<INntpAdminGroups> pINntpAdminGroups;
  207. CComBSTR strTemp = _T("");
  208. if (!strTemp)
  209. {
  210. hr = E_OUTOFMEMORY;
  211. goto Error;
  212. }
  213. hr = StdPropertyHandoffIDispatch (
  214. CLSID_CNntpAdminGroups,
  215. IID_INntpAdminGroups,
  216. &pINntpAdminGroups,
  217. ppIDispatch
  218. );
  219. if ( FAILED(hr) ) {
  220. goto Error;
  221. }
  222. // Set default properties:
  223. hr = pINntpAdminGroups->put_Server ( m_strServer ? m_strServer : strTemp );
  224. if ( FAILED (hr) ) {
  225. goto Error;
  226. }
  227. hr = pINntpAdminGroups->put_ServiceInstance ( m_dwServiceInstance );
  228. if ( FAILED (hr) ) {
  229. goto Error;
  230. }
  231. return hr;
  232. Error:
  233. SAFE_RELEASE ( *ppIDispatch );
  234. *ppIDispatch = NULL;
  235. return hr;
  236. // Destructor releases pINntpAdminGroups
  237. }
  238. STDMETHODIMP CNntpVirtualServer::get_ExpirationAdmin ( IDispatch ** ppIDispatch )
  239. {
  240. HRESULT hr = NOERROR;
  241. CComPtr<INntpAdminExpiration> pINntpAdminExpiration;
  242. CComBSTR strTemp = _T("");
  243. if (!strTemp)
  244. {
  245. hr = E_OUTOFMEMORY;
  246. goto Error;
  247. }
  248. hr = StdPropertyHandoffIDispatch (
  249. CLSID_CNntpAdminExpiration,
  250. IID_INntpAdminExpiration,
  251. &pINntpAdminExpiration,
  252. ppIDispatch
  253. );
  254. if ( FAILED(hr) ) {
  255. goto Error;
  256. }
  257. // Set default properties:
  258. hr = pINntpAdminExpiration->put_Server ( m_strServer ? m_strServer : strTemp );
  259. if ( FAILED (hr) ) {
  260. goto Error;
  261. }
  262. hr = pINntpAdminExpiration->put_ServiceInstance ( m_dwServiceInstance );
  263. if ( FAILED (hr) ) {
  264. goto Error;
  265. }
  266. return hr;
  267. Error:
  268. SAFE_RELEASE ( *ppIDispatch );
  269. *ppIDispatch = NULL;
  270. return hr;
  271. // Destructor releases pINntpAdminExpiration
  272. }
  273. STDMETHODIMP CNntpVirtualServer::get_SessionsAdmin ( IDispatch ** ppIDispatch )
  274. {
  275. HRESULT hr = NOERROR;
  276. CComPtr<INntpAdminSessions> pINntpAdminSessions;
  277. CComBSTR strTemp = _T("");
  278. if (!strTemp)
  279. {
  280. hr = E_OUTOFMEMORY;
  281. goto Error;
  282. }
  283. hr = StdPropertyHandoffIDispatch (
  284. CLSID_CNntpAdminSessions,
  285. IID_INntpAdminSessions,
  286. &pINntpAdminSessions,
  287. ppIDispatch
  288. );
  289. if ( FAILED(hr) ) {
  290. goto Error;
  291. }
  292. // Set default properties:
  293. hr = pINntpAdminSessions->put_Server ( m_strServer ? m_strServer : strTemp );
  294. if ( FAILED (hr) ) {
  295. goto Error;
  296. }
  297. hr = pINntpAdminSessions->put_ServiceInstance ( m_dwServiceInstance );
  298. if ( FAILED (hr) ) {
  299. goto Error;
  300. }
  301. return hr;
  302. Error:
  303. SAFE_RELEASE ( *ppIDispatch );
  304. *ppIDispatch = NULL;
  305. return hr;
  306. // Destructor releases pINntpAdminSessions
  307. }
  308. STDMETHODIMP CNntpVirtualServer::get_RebuildAdmin ( IDispatch ** ppIDispatch )
  309. {
  310. HRESULT hr = NOERROR;
  311. CComPtr<INntpAdminRebuild> pINntpAdminRebuild;
  312. CComBSTR strTemp = _T("");
  313. if (!strTemp)
  314. {
  315. hr = E_OUTOFMEMORY;
  316. goto Error;
  317. }
  318. hr = StdPropertyHandoffIDispatch (
  319. CLSID_CNntpAdminRebuild,
  320. IID_INntpAdminRebuild,
  321. &pINntpAdminRebuild,
  322. ppIDispatch
  323. );
  324. if ( FAILED(hr) ) {
  325. goto Error;
  326. }
  327. // Set default properties:
  328. hr = pINntpAdminRebuild->put_Server ( m_strServer ? m_strServer : strTemp );
  329. if ( FAILED (hr) ) {
  330. goto Error;
  331. }
  332. hr = pINntpAdminRebuild->put_ServiceInstance ( m_dwServiceInstance );
  333. if ( FAILED (hr) ) {
  334. goto Error;
  335. }
  336. return hr;
  337. Error:
  338. SAFE_RELEASE ( *ppIDispatch );
  339. *ppIDispatch = NULL;
  340. return hr;
  341. // Destructor releases pINntpAdminRebuild
  342. }
  343. STDMETHODIMP CNntpVirtualServer::get_VirtualRoots ( INntpVirtualRoots ** ppVirtualRoots )
  344. {
  345. HRESULT hr = NOERROR;
  346. CComObject<CNntpVirtualRoots> * pVRoots = NULL;
  347. *ppVirtualRoots = NULL;
  348. hr = CComObject<CNntpVirtualRoots>::CreateInstance ( &pVRoots );
  349. if ( FAILED(hr) ) {
  350. goto Error;
  351. }
  352. // Set default properties:
  353. pVRoots->m_strServer = m_strServer;
  354. pVRoots->m_dwServiceInstance = m_dwServiceInstance;
  355. if ( m_strServer && !pVRoots->m_strServer ) {
  356. hr = E_OUTOFMEMORY;
  357. goto Error;
  358. }
  359. hr = pVRoots->QueryInterface ( IID_INntpVirtualRoots, (void **) ppVirtualRoots );
  360. Error:
  361. if ( FAILED(hr) ) {
  362. delete pVRoots;
  363. }
  364. return hr;
  365. // Destructor releases pINntpAdminRebuild
  366. }
  367. STDMETHODIMP CNntpVirtualServer::get_VirtualRootsDispatch ( IDispatch ** ppVirtualRoots )
  368. {
  369. HRESULT hr;
  370. CComPtr<INntpVirtualRoots> pVRoots;
  371. hr = get_VirtualRoots ( &pVRoots );
  372. BAIL_ON_FAILURE ( hr );
  373. hr = pVRoots->QueryInterface ( IID_IDispatch, (void **) ppVirtualRoots );
  374. BAIL_ON_FAILURE ( hr );
  375. Exit:
  376. return hr;
  377. }
  378. STDMETHODIMP CNntpVirtualServer::get_TcpAccess ( ITcpAccess ** ppTcpAccess )
  379. {
  380. return m_pIpAccess->QueryInterface ( IID_ITcpAccess, (void **) ppTcpAccess );
  381. }
  382. // Server overridable Properties:
  383. STDMETHODIMP CNntpVirtualServer::get_ArticleTimeLimit ( long * plArticleTimeLimit )
  384. {
  385. return StdPropertyGet ( m_dwArticleTimeLimit, plArticleTimeLimit );
  386. }
  387. STDMETHODIMP CNntpVirtualServer::put_ArticleTimeLimit ( long lArticleTimeLimit )
  388. {
  389. return StdPropertyPut ( &m_dwArticleTimeLimit, lArticleTimeLimit, &m_bvChangedFields, CHNG_ARTICLETIMELIMIT );
  390. }
  391. STDMETHODIMP CNntpVirtualServer::get_HistoryExpiration ( long * plHistoryExpiration )
  392. {
  393. return StdPropertyGet ( m_dwHistoryExpiration, plHistoryExpiration );
  394. }
  395. STDMETHODIMP CNntpVirtualServer::put_HistoryExpiration ( long lHistoryExpiration )
  396. {
  397. return StdPropertyPut ( &m_dwHistoryExpiration, lHistoryExpiration, &m_bvChangedFields, CHNG_HISTORYEXPIRATION );
  398. }
  399. STDMETHODIMP CNntpVirtualServer::get_HonorClientMsgIDs ( BOOL * pfHonorClientMsgIDs )
  400. {
  401. return StdPropertyGet ( m_fHonorClientMsgIDs, pfHonorClientMsgIDs );
  402. }
  403. STDMETHODIMP CNntpVirtualServer::put_HonorClientMsgIDs ( BOOL fHonorClientMsgIDs )
  404. {
  405. return StdPropertyPut ( &m_fHonorClientMsgIDs, fHonorClientMsgIDs, &m_bvChangedFields, CHNG_HONORCLIENTMSGIDS );
  406. }
  407. STDMETHODIMP CNntpVirtualServer::get_SmtpServer ( BSTR * pstrSmtpServer )
  408. {
  409. return StdPropertyGet ( m_strSmtpServer, pstrSmtpServer );
  410. }
  411. STDMETHODIMP CNntpVirtualServer::put_SmtpServer ( BSTR strSmtpServer )
  412. {
  413. return StdPropertyPut ( &m_strSmtpServer, strSmtpServer, &m_bvChangedFields, CHNG_SMTPSERVER );
  414. }
  415. STDMETHODIMP CNntpVirtualServer::get_AdminEmail ( BSTR * pstrAdminEmail )
  416. {
  417. return StdPropertyGet ( m_strAdminEmail, pstrAdminEmail );
  418. }
  419. STDMETHODIMP CNntpVirtualServer::put_AdminEmail ( BSTR strAdminEmail )
  420. {
  421. return StdPropertyPut ( &m_strAdminEmail, strAdminEmail, &m_bvChangedFields2, CHNG2_ADMINEMAIL );
  422. }
  423. STDMETHODIMP CNntpVirtualServer::get_AllowClientPosts ( BOOL * pfAllowClientPosts )
  424. {
  425. return StdPropertyGet ( m_fAllowClientPosts, pfAllowClientPosts );
  426. }
  427. STDMETHODIMP CNntpVirtualServer::put_AllowClientPosts ( BOOL fAllowClientPosts )
  428. {
  429. return StdPropertyPut ( &m_fAllowClientPosts, fAllowClientPosts, &m_bvChangedFields, CHNG_ALLOWCLIENTPOSTS );
  430. }
  431. STDMETHODIMP CNntpVirtualServer::get_AllowFeedPosts ( BOOL * pfAllowFeedPosts )
  432. {
  433. return StdPropertyGet ( m_fAllowFeedPosts, pfAllowFeedPosts );
  434. }
  435. STDMETHODIMP CNntpVirtualServer::put_AllowFeedPosts ( BOOL fAllowFeedPosts )
  436. {
  437. return StdPropertyPut ( &m_fAllowFeedPosts, fAllowFeedPosts, &m_bvChangedFields, CHNG_ALLOWFEEDPOSTS );
  438. }
  439. STDMETHODIMP CNntpVirtualServer::get_AllowControlMsgs ( BOOL * pfAllowControlMsgs )
  440. {
  441. return StdPropertyGet ( m_fAllowControlMsgs, pfAllowControlMsgs );
  442. }
  443. STDMETHODIMP CNntpVirtualServer::put_AllowControlMsgs ( BOOL fAllowControlMsgs )
  444. {
  445. return StdPropertyPut ( &m_fAllowControlMsgs, fAllowControlMsgs, &m_bvChangedFields, CHNG_ALLOWCONTROLMSGS );
  446. }
  447. STDMETHODIMP CNntpVirtualServer::get_DefaultModeratorDomain ( BSTR * pstrDefaultModeratorDomain )
  448. {
  449. return StdPropertyGet ( m_strDefaultModeratorDomain, pstrDefaultModeratorDomain );
  450. }
  451. STDMETHODIMP CNntpVirtualServer::put_DefaultModeratorDomain ( BSTR strDefaultModeratorDomain )
  452. {
  453. return StdPropertyPut ( &m_strDefaultModeratorDomain, strDefaultModeratorDomain, &m_bvChangedFields, CHNG_DEFAULTMODERATORDOMAIN );
  454. }
  455. STDMETHODIMP CNntpVirtualServer::get_CommandLogMask ( long * plCommandLogMask )
  456. {
  457. return StdPropertyGet ( m_dwCommandLogMask, plCommandLogMask );
  458. }
  459. STDMETHODIMP CNntpVirtualServer::put_CommandLogMask ( long lCommandLogMask )
  460. {
  461. return StdPropertyPut ( &m_dwCommandLogMask, lCommandLogMask, &m_bvChangedFields, CHNG_COMMANDLOGMASK );
  462. }
  463. STDMETHODIMP CNntpVirtualServer::get_DisableNewnews ( BOOL * pfDisableNewnews )
  464. {
  465. return StdPropertyGet ( m_fDisableNewnews, pfDisableNewnews );
  466. }
  467. STDMETHODIMP CNntpVirtualServer::put_DisableNewnews ( BOOL fDisableNewnews )
  468. {
  469. return StdPropertyPut ( &m_fDisableNewnews, fDisableNewnews, &m_bvChangedFields, CHNG_DISABLENEWNEWS );
  470. }
  471. STDMETHODIMP CNntpVirtualServer::get_ExpireRunFrequency ( long * plExpireRunFrequency )
  472. {
  473. return StdPropertyGet ( m_dwExpireRunFrequency, plExpireRunFrequency );
  474. }
  475. STDMETHODIMP CNntpVirtualServer::put_ExpireRunFrequency ( long lExpireRunFrequency )
  476. {
  477. return StdPropertyPut ( &m_dwExpireRunFrequency, lExpireRunFrequency, &m_bvChangedFields, CHNG_NEWSCRAWLERTIME );
  478. }
  479. STDMETHODIMP CNntpVirtualServer::get_ShutdownLatency ( long * plShutdownLatency )
  480. {
  481. return StdPropertyGet ( m_dwShutdownLatency, plShutdownLatency );
  482. }
  483. STDMETHODIMP CNntpVirtualServer::put_ShutdownLatency ( long lShutdownLatency )
  484. {
  485. return StdPropertyPut ( &m_dwShutdownLatency, lShutdownLatency, &m_bvChangedFields, CHNG_SHUTDOWNLATENCY );
  486. }
  487. STDMETHODIMP CNntpVirtualServer::get_ClientPostHardLimit ( long * plClientPostHardLimit )
  488. {
  489. return StdPropertyGet ( m_dwClientPostHardLimit, plClientPostHardLimit );
  490. }
  491. STDMETHODIMP CNntpVirtualServer::put_ClientPostHardLimit ( long lClientPostHardLimit )
  492. {
  493. return StdPropertyPut ( &m_dwClientPostHardLimit, lClientPostHardLimit, &m_bvChangedFields, CHNG_CLIENTPOSTHARDLIMIT );
  494. }
  495. STDMETHODIMP CNntpVirtualServer::get_ClientPostSoftLimit ( long * plClientPostSoftLimit )
  496. {
  497. return StdPropertyGet ( m_dwClientPostSoftLimit, plClientPostSoftLimit );
  498. }
  499. STDMETHODIMP CNntpVirtualServer::put_ClientPostSoftLimit ( long lClientPostSoftLimit )
  500. {
  501. return StdPropertyPut ( &m_dwClientPostSoftLimit, lClientPostSoftLimit, &m_bvChangedFields, CHNG_CLIENTPOSTSOFTLIMIT );
  502. }
  503. STDMETHODIMP CNntpVirtualServer::get_FeedPostHardLimit ( long * plFeedPostHardLimit )
  504. {
  505. return StdPropertyGet ( m_dwFeedPostHardLimit, plFeedPostHardLimit );
  506. }
  507. STDMETHODIMP CNntpVirtualServer::put_FeedPostHardLimit ( long lFeedPostHardLimit )
  508. {
  509. return StdPropertyPut ( &m_dwFeedPostHardLimit, lFeedPostHardLimit, &m_bvChangedFields, CHNG_FEEDPOSTHARDLIMIT );
  510. }
  511. STDMETHODIMP CNntpVirtualServer::get_FeedPostSoftLimit ( long * plFeedPostSoftLimit )
  512. {
  513. return StdPropertyGet ( m_dwFeedPostSoftLimit, plFeedPostSoftLimit );
  514. }
  515. STDMETHODIMP CNntpVirtualServer::put_FeedPostSoftLimit ( long lFeedPostSoftLimit )
  516. {
  517. return StdPropertyPut ( &m_dwFeedPostSoftLimit, lFeedPostSoftLimit, &m_bvChangedFields, CHNG_FEEDPOSTSOFTLIMIT );
  518. }
  519. STDMETHODIMP CNntpVirtualServer::get_EnableLogging ( BOOL * pfEnableLogging )
  520. {
  521. return StdPropertyGet ( m_fEnableLogging, pfEnableLogging );
  522. }
  523. STDMETHODIMP CNntpVirtualServer::put_EnableLogging ( BOOL fEnableLogging )
  524. {
  525. return StdPropertyPut ( &m_fEnableLogging, fEnableLogging, &m_bvChangedFields2, CHNG2_ENABLELOGGING );
  526. }
  527. // Service-specific properties:
  528. STDMETHODIMP CNntpVirtualServer::get_Organization ( BSTR * pstrOrganization )
  529. {
  530. return StdPropertyGet ( m_strOrganization, pstrOrganization );
  531. }
  532. STDMETHODIMP CNntpVirtualServer::put_Organization ( BSTR strOrganization )
  533. {
  534. return StdPropertyPut ( &m_strOrganization, strOrganization, &m_bvChangedFields, CHNG_ORGANIZATION );
  535. }
  536. STDMETHODIMP CNntpVirtualServer::get_UucpName ( BSTR * pstrUucpName )
  537. {
  538. return StdPropertyGet ( m_strUucpName, pstrUucpName );
  539. }
  540. STDMETHODIMP CNntpVirtualServer::put_UucpName ( BSTR strUucpName )
  541. {
  542. return StdPropertyPut ( &m_strUucpName, strUucpName, &m_bvChangedFields, CHNG_UUCPNAME );
  543. }
  544. STDMETHODIMP CNntpVirtualServer::get_GroupHelpFile ( BSTR * pstrGroupHelpFile )
  545. {
  546. return StdPropertyGet ( m_strGroupHelpFile, pstrGroupHelpFile );
  547. }
  548. STDMETHODIMP CNntpVirtualServer::put_GroupHelpFile ( BSTR strGroupHelpFile )
  549. {
  550. return StdPropertyPut ( &m_strGroupHelpFile, strGroupHelpFile, &m_bvChangedFields, CHNG_GROUPHELPFILE );
  551. }
  552. STDMETHODIMP CNntpVirtualServer::get_GroupListFile ( BSTR * pstrGroupListFile )
  553. {
  554. return StdPropertyGet ( m_strGroupListFile, pstrGroupListFile );
  555. }
  556. STDMETHODIMP CNntpVirtualServer::put_GroupListFile ( BSTR strGroupListFile )
  557. {
  558. return StdPropertyPut ( &m_strGroupListFile, strGroupListFile, &m_bvChangedFields, CHNG_GROUPLISTFILE );
  559. }
  560. STDMETHODIMP CNntpVirtualServer::get_GroupVarListFile( BSTR *pstrGroupListFile )
  561. {
  562. return StdPropertyGet( m_strGroupVarListFile, pstrGroupListFile );
  563. }
  564. STDMETHODIMP CNntpVirtualServer::put_GroupVarListFile( BSTR strGroupVarListFile )
  565. {
  566. return StdPropertyPut ( &m_strGroupVarListFile, strGroupVarListFile, &m_bvChangedFields, CHNG_GROUPLISTFILE );
  567. }
  568. STDMETHODIMP CNntpVirtualServer::get_ArticleTableFile ( BSTR * pstrArticleTableFile )
  569. {
  570. return StdPropertyGet ( m_strArticleTableFile, pstrArticleTableFile );
  571. }
  572. STDMETHODIMP CNntpVirtualServer::put_ArticleTableFile ( BSTR strArticleTableFile )
  573. {
  574. return StdPropertyPut ( &m_strArticleTableFile, strArticleTableFile, &m_bvChangedFields, CHNG_ARTICLETABLEFILE );
  575. }
  576. STDMETHODIMP CNntpVirtualServer::get_HistoryTableFile ( BSTR * pstrHistoryTableFile )
  577. {
  578. return StdPropertyGet ( m_strHistoryTableFile, pstrHistoryTableFile );
  579. }
  580. STDMETHODIMP CNntpVirtualServer::put_HistoryTableFile ( BSTR strHistoryTableFile )
  581. {
  582. return StdPropertyPut ( &m_strHistoryTableFile, strHistoryTableFile, &m_bvChangedFields, CHNG_HISTORYTABLEFILE );
  583. }
  584. STDMETHODIMP CNntpVirtualServer::get_ModeratorFile ( BSTR * pstrModeratorFile )
  585. {
  586. return StdPropertyGet ( m_strModeratorFile, pstrModeratorFile );
  587. }
  588. STDMETHODIMP CNntpVirtualServer::put_ModeratorFile ( BSTR strModeratorFile )
  589. {
  590. return StdPropertyPut ( &m_strModeratorFile, strModeratorFile, &m_bvChangedFields, CHNG_MODERATORFILE );
  591. }
  592. STDMETHODIMP CNntpVirtualServer::get_XOverTableFile ( BSTR * pstrXOverTableFile )
  593. {
  594. return StdPropertyGet ( m_strXOverTableFile, pstrXOverTableFile );
  595. }
  596. STDMETHODIMP CNntpVirtualServer::put_XOverTableFile ( BSTR strXOverTableFile )
  597. {
  598. return StdPropertyPut ( &m_strXOverTableFile, strXOverTableFile, &m_bvChangedFields, CHNG_XOVERTABLEFILE );
  599. }
  600. STDMETHODIMP CNntpVirtualServer::get_AutoStart ( BOOL * pfAutoStart )
  601. {
  602. return StdPropertyGet ( m_fAutoStart, pfAutoStart );
  603. }
  604. STDMETHODIMP CNntpVirtualServer::put_AutoStart ( BOOL fAutoStart )
  605. {
  606. return StdPropertyPut ( &m_fAutoStart, fAutoStart, &m_bvChangedFields, CHNG_AUTOSTART );
  607. }
  608. STDMETHODIMP CNntpVirtualServer::get_Comment ( BSTR * pstrComment )
  609. {
  610. if ( m_strComment.Length() == 0 ) return StdPropertyGet( m_strUucpName, pstrComment );
  611. else return StdPropertyGet ( m_strComment, pstrComment );
  612. }
  613. STDMETHODIMP CNntpVirtualServer::put_Comment ( BSTR strComment )
  614. {
  615. return StdPropertyPut ( &m_strComment, strComment, &m_bvChangedFields, CHNG_COMMENT );
  616. }
  617. STDMETHODIMP CNntpVirtualServer::get_Bindings ( INntpServerBindings ** ppBindings )
  618. {
  619. TraceQuietEnter ( "CNntpVirtualServer::get_Bindings" );
  620. HRESULT hr = NOERROR;
  621. if ( !m_pBindings ) {
  622. ErrorTrace ( 0, "Didn't call get first" );
  623. hr = NntpCreateException ( IDS_NNTPEXCEPTION_DIDNT_CALL_GET );
  624. goto Exit;
  625. }
  626. else {
  627. hr = m_pBindings->QueryInterface ( IID_INntpServerBindings, (void **) ppBindings );
  628. _ASSERT ( SUCCEEDED(hr) );
  629. }
  630. Exit:
  631. TRACE_HRESULT(hr);
  632. TraceFunctLeave ();
  633. return hr;
  634. }
  635. STDMETHODIMP CNntpVirtualServer::get_BindingsDispatch ( IDispatch ** ppBindings )
  636. {
  637. HRESULT hr = NOERROR;
  638. CComPtr<INntpServerBindings> pBindings;
  639. hr = get_Bindings ( &pBindings );
  640. if ( FAILED(hr) ) {
  641. goto Exit;
  642. }
  643. hr = pBindings->QueryInterface ( IID_IDispatch, (void **) ppBindings );
  644. if ( FAILED(hr) ) {
  645. goto Exit;
  646. }
  647. Exit:
  648. return hr;
  649. }
  650. STDMETHODIMP CNntpVirtualServer::get_SecurePort ( long * pdwSecurePort )
  651. {
  652. return StdPropertyGet ( m_dwSecurePort, pdwSecurePort );
  653. }
  654. STDMETHODIMP CNntpVirtualServer::put_SecurePort ( long dwSecurePort )
  655. {
  656. return StdPropertyPut ( &m_dwSecurePort, dwSecurePort, &m_bvChangedFields, CHNG_SECUREPORT );
  657. }
  658. STDMETHODIMP CNntpVirtualServer::get_MaxConnections ( long * pdwMaxConnections )
  659. {
  660. return StdPropertyGet ( m_dwMaxConnections, pdwMaxConnections );
  661. }
  662. STDMETHODIMP CNntpVirtualServer::put_MaxConnections ( long dwMaxConnections )
  663. {
  664. return StdPropertyPut ( &m_dwMaxConnections, dwMaxConnections, &m_bvChangedFields, CHNG_MAXCONNECTIONS );
  665. }
  666. STDMETHODIMP CNntpVirtualServer::get_ConnectionTimeout ( long * pdwConnectionTimeout )
  667. {
  668. return StdPropertyGet ( m_dwConnectionTimeout, pdwConnectionTimeout );
  669. }
  670. STDMETHODIMP CNntpVirtualServer::put_ConnectionTimeout ( long dwConnectionTimeout )
  671. {
  672. return StdPropertyPut ( &m_dwConnectionTimeout, dwConnectionTimeout, &m_bvChangedFields2, CHNG2_CONNECTIONTIMEOUT );
  673. }
  674. STDMETHODIMP CNntpVirtualServer::get_AnonymousUserName ( BSTR * pstrAnonymousUserName )
  675. {
  676. return StdPropertyGet ( m_strAnonymousUserName, pstrAnonymousUserName );
  677. }
  678. STDMETHODIMP CNntpVirtualServer::put_AnonymousUserName ( BSTR strAnonymousUserName )
  679. {
  680. return StdPropertyPut ( &m_strAnonymousUserName, strAnonymousUserName, &m_bvChangedFields2, CHNG2_ANONYMOUSUSERNAME );
  681. }
  682. STDMETHODIMP CNntpVirtualServer::get_AnonymousUserPass ( BSTR * pstrAnonymousUserPass )
  683. {
  684. return StdPropertyGet ( m_strAnonymousUserPass, pstrAnonymousUserPass );
  685. }
  686. STDMETHODIMP CNntpVirtualServer::put_AnonymousUserPass ( BSTR strAnonymousUserPass )
  687. {
  688. return StdPropertyPut ( &m_strAnonymousUserPass, strAnonymousUserPass, &m_bvChangedFields2, CHNG2_ANONYMOUSUSERPASS );
  689. }
  690. STDMETHODIMP CNntpVirtualServer::get_AutoSyncPassword ( BOOL * pfAutoSyncPassword )
  691. {
  692. return StdPropertyGet ( m_fAutoSyncPassword, pfAutoSyncPassword );
  693. }
  694. STDMETHODIMP CNntpVirtualServer::put_AutoSyncPassword ( BOOL fAutoSyncPassword )
  695. {
  696. return StdPropertyPut ( &m_fAutoSyncPassword, fAutoSyncPassword, &m_bvChangedFields2, CHNG2_AUTOSYNCPASSWORD );
  697. }
  698. STDMETHODIMP CNntpVirtualServer::get_PickupDirectory ( BSTR * pstrPickupDirectory )
  699. {
  700. return StdPropertyGet ( m_strPickupDirectory, pstrPickupDirectory );
  701. }
  702. STDMETHODIMP CNntpVirtualServer::put_PickupDirectory ( BSTR strPickupDirectory )
  703. {
  704. return StdPropertyPut ( &m_strPickupDirectory, strPickupDirectory, &m_bvChangedFields2, CHNG2_PICKUPDIRECTORY );
  705. }
  706. STDMETHODIMP CNntpVirtualServer::get_FailedPickupDirectory ( BSTR * pstrFailedPickupDirectory )
  707. {
  708. return StdPropertyGet ( m_strFailedPickupDirectory, pstrFailedPickupDirectory );
  709. }
  710. STDMETHODIMP CNntpVirtualServer::put_FailedPickupDirectory ( BSTR strFailedPickupDirectory )
  711. {
  712. return StdPropertyPut ( &m_strFailedPickupDirectory, strFailedPickupDirectory, &m_bvChangedFields2, CHNG2_FAILEDPICKUPDIRECTORY );
  713. }
  714. STDMETHODIMP CNntpVirtualServer::get_AuthAnonymous ( BOOL * pfAuthAnonymous )
  715. {
  716. return StdPropertyGetBit ( m_bvAuthorization, MD_AUTH_ANONYMOUS, pfAuthAnonymous );
  717. }
  718. STDMETHODIMP CNntpVirtualServer::put_AuthAnonymous ( BOOL fAuthAnonymous )
  719. {
  720. return StdPropertyPutBit ( &m_bvAuthorization, MD_AUTH_ANONYMOUS, fAuthAnonymous );
  721. }
  722. STDMETHODIMP CNntpVirtualServer::get_AuthBasic ( BOOL * pfAuthBasic )
  723. {
  724. return StdPropertyGetBit ( m_bvAuthorization, MD_AUTH_BASIC, pfAuthBasic );
  725. }
  726. STDMETHODIMP CNntpVirtualServer::put_AuthBasic ( BOOL fAuthBasic )
  727. {
  728. return StdPropertyPutBit ( &m_bvAuthorization, MD_AUTH_BASIC, fAuthBasic );
  729. }
  730. STDMETHODIMP CNntpVirtualServer::get_AuthMCISBasic ( BOOL * pfAuthMCISBasic )
  731. {
  732. *pfAuthMCISBasic = FALSE;
  733. return NOERROR;
  734. // return StdPropertyGetBit ( m_bvAuthorization, MD_AUTH_MCIS_BASIC, pfAuthMCISBasic );
  735. }
  736. STDMETHODIMP CNntpVirtualServer::put_AuthMCISBasic ( BOOL fAuthMCISBasic )
  737. {
  738. return NOERROR;
  739. // return StdPropertyPutBit ( &m_bvAuthorization, MD_AUTH_MCIS_BASIC, fAuthMCISBasic );
  740. }
  741. STDMETHODIMP CNntpVirtualServer::get_AuthNT ( BOOL * pfAuthNT )
  742. {
  743. return StdPropertyGetBit ( m_bvAuthorization, MD_AUTH_NT, pfAuthNT );
  744. }
  745. STDMETHODIMP CNntpVirtualServer::put_AuthNT ( BOOL fAuthNT )
  746. {
  747. return StdPropertyPutBit ( &m_bvAuthorization, MD_AUTH_NT, fAuthNT );
  748. }
  749. STDMETHODIMP CNntpVirtualServer::get_SSLNegotiateCert ( BOOL * pfNegotiateCert )
  750. {
  751. return StdPropertyGetBit ( m_bvSslAccess, MD_ACCESS_NEGO_CERT, pfNegotiateCert );
  752. }
  753. STDMETHODIMP CNntpVirtualServer::put_SSLNegotiateCert ( BOOL fNegotiateCert )
  754. {
  755. return StdPropertyPutBit ( &m_bvSslAccess, MD_ACCESS_NEGO_CERT, fNegotiateCert ); // , &m_bvChangedFields2, CHNG2_SSLACCESS );
  756. }
  757. STDMETHODIMP CNntpVirtualServer::get_SSLRequireCert ( BOOL * pfRequireCert )
  758. {
  759. return StdPropertyGetBit ( m_bvSslAccess, MD_ACCESS_REQUIRE_CERT, pfRequireCert );
  760. }
  761. STDMETHODIMP CNntpVirtualServer::put_SSLRequireCert ( BOOL fRequireCert )
  762. {
  763. return StdPropertyPutBit ( &m_bvSslAccess, MD_ACCESS_REQUIRE_CERT, fRequireCert ); // , &m_bvChangedFields2, CHNG2_SSLACCESS );
  764. }
  765. STDMETHODIMP CNntpVirtualServer::get_SSLMapCert ( BOOL * pfMapCert )
  766. {
  767. return StdPropertyGetBit ( m_bvSslAccess, MD_ACCESS_MAP_CERT, pfMapCert );
  768. }
  769. STDMETHODIMP CNntpVirtualServer::put_SSLMapCert ( BOOL fMapCert )
  770. {
  771. return StdPropertyPutBit ( &m_bvSslAccess, MD_ACCESS_MAP_CERT, fMapCert ); // , &m_bvChangedFields2, CHNG2_SSLACCESS );
  772. }
  773. /*
  774. STDMETHODIMP CNntpVirtualServer::get_AuthenticationProviders ( SAFEARRAY ** ppsastrProviders )
  775. {
  776. return StdPropertyGet ( &m_mszProviders, ppsastrProviders );
  777. }
  778. STDMETHODIMP CNntpVirtualServer::put_AuthenticationProviders ( SAFEARRAY * psastrProviders )
  779. {
  780. return StdPropertyPut ( &m_mszProviders, psastrProviders );
  781. }
  782. STDMETHODIMP CNntpVirtualServer::get_AuthenticationProvidersVariant ( SAFEARRAY ** ppsavarAuthProviders )
  783. {
  784. HRESULT hr;
  785. SAFEARRAY * psastrAuthProviders = NULL;
  786. hr = get_AuthenticationProviders ( &psastrAuthProviders );
  787. if ( FAILED(hr) ) {
  788. goto Exit;
  789. }
  790. hr = StringArrayToVariantArray ( psastrAuthProviders, ppsavarAuthProviders );
  791. Exit:
  792. if ( psastrAuthProviders ) {
  793. SafeArrayDestroy ( psastrAuthProviders );
  794. }
  795. return hr;
  796. }
  797. STDMETHODIMP CNntpVirtualServer::put_AuthenticationProvidersVariant ( SAFEARRAY * psavarAuthProviders )
  798. {
  799. HRESULT hr;
  800. SAFEARRAY * psastrAuthProviders = NULL;
  801. hr = VariantArrayToStringArray ( psavarAuthProviders, &psastrAuthProviders );
  802. if ( FAILED(hr) ) {
  803. goto Exit;
  804. }
  805. hr = put_AuthenticationProviders ( psastrAuthProviders );
  806. Exit:
  807. if ( psastrAuthProviders ) {
  808. SafeArrayDestroy ( psastrAuthProviders );
  809. }
  810. return hr;
  811. }
  812. */
  813. STDMETHODIMP CNntpVirtualServer::get_Administrators ( SAFEARRAY ** ppsastrAdmins )
  814. {
  815. TraceFunctEnter ( "CNntpVS::get_Administrators" );
  816. HRESULT hr = NOERROR;
  817. if ( m_psaAdmins ) {
  818. hr = SafeArrayCopy ( m_psaAdmins, ppsastrAdmins );
  819. }
  820. else {
  821. *ppsastrAdmins = NULL;
  822. hr = NOERROR;
  823. }
  824. TraceFunctLeave ();
  825. return hr;
  826. }
  827. STDMETHODIMP CNntpVirtualServer::put_Administrators ( SAFEARRAY * psastrAdmins )
  828. {
  829. TraceFunctEnter ( "CNntpVS::put_Administrators" );
  830. HRESULT hr = NOERROR;
  831. if ( m_psaAdmins ) {
  832. SafeArrayDestroy ( m_psaAdmins );
  833. }
  834. if ( psastrAdmins ) {
  835. hr = SafeArrayCopy ( psastrAdmins, &m_psaAdmins );
  836. }
  837. else {
  838. m_psaAdmins = NULL;
  839. hr = NOERROR;
  840. }
  841. m_bvChangedFields2 |= CHNG2_ADMINACL;
  842. TraceFunctLeave ();
  843. return hr;
  844. }
  845. STDMETHODIMP CNntpVirtualServer::get_AdministratorsVariant ( SAFEARRAY ** ppsavarAdmins )
  846. {
  847. HRESULT hr;
  848. SAFEARRAY * psastrAdmins = NULL;
  849. hr = get_Administrators ( &psastrAdmins );
  850. if ( FAILED(hr) ) {
  851. goto Exit;
  852. }
  853. hr = StringArrayToVariantArray ( psastrAdmins, ppsavarAdmins );
  854. Exit:
  855. if ( psastrAdmins ) {
  856. SafeArrayDestroy ( psastrAdmins );
  857. }
  858. return hr;
  859. }
  860. STDMETHODIMP CNntpVirtualServer::put_AdministratorsVariant ( SAFEARRAY * psavarAdmins )
  861. {
  862. HRESULT hr;
  863. SAFEARRAY * psastrAdmins = NULL;
  864. hr = VariantArrayToStringArray ( psavarAdmins, &psastrAdmins );
  865. if ( FAILED(hr) ) {
  866. goto Exit;
  867. }
  868. hr = put_Administrators ( psastrAdmins );
  869. Exit:
  870. if ( psastrAdmins ) {
  871. SafeArrayDestroy ( psastrAdmins );
  872. }
  873. return hr;
  874. }
  875. STDMETHODIMP CNntpVirtualServer::get_ClusterEnabled ( BOOL *pfClusterEnabled )
  876. {
  877. return StdPropertyGet ( m_fClusterEnabled, pfClusterEnabled );
  878. }
  879. STDMETHODIMP CNntpVirtualServer::put_ClusterEnabled ( BOOL fClusterEnabled )
  880. {
  881. return StdPropertyPut ( &m_fClusterEnabled, fClusterEnabled, &m_bvChangedFields2, CHNG2_CLUSTERENABLED);
  882. }
  883. STDMETHODIMP CNntpVirtualServer::get_State ( NNTP_SERVER_STATE * pState )
  884. {
  885. if ( pState == NULL ) {
  886. return E_POINTER;
  887. }
  888. *pState = m_State;
  889. return NOERROR;
  890. }
  891. STDMETHODIMP CNntpVirtualServer::get_Win32ErrorCode ( long * plWin32ErrorCode )
  892. {
  893. return StdPropertyGet ( m_dwWin32ErrorCode, plWin32ErrorCode );
  894. }
  895. /*
  896. STDMETHODIMP CNntpVirtualServer::get_DisplayName ( BSTR * pstrDisplayName )
  897. {
  898. return StdPropertyGet ( m_strDisplayName, pstrDisplayName );
  899. }
  900. STDMETHODIMP CNntpVirtualServer::put_DisplayName ( BSTR strDisplayName )
  901. {
  902. return StdPropertyPut ( &m_strDisplayName, strDisplayName );
  903. }
  904. STDMETHODIMP CNntpVirtualServer::get_ErrorControl ( BOOL * pfErrorControl )
  905. {
  906. return StdPropertyGet ( m_fErrorControl, pfErrorControl );
  907. }
  908. STDMETHODIMP CNntpVirtualServer::put_ErrorControl ( BOOL fErrorControl )
  909. {
  910. return StdPropertyPut ( &m_fErrorControl, fErrorControl );
  911. }
  912. STDMETHODIMP CNntpVirtualServer::get_CleanBoot ( BOOL * pfCleanBoot )
  913. {
  914. return StdPropertyGet ( m_fCleanBoot, pfCleanBoot );
  915. }
  916. STDMETHODIMP CNntpVirtualServer::put_CleanBoot ( BOOL fCleanBoot )
  917. {
  918. return StdPropertyPut ( &m_fCleanBoot, fCleanBoot );
  919. }
  920. STDMETHODIMP CNntpVirtualServer::get_EncryptionCapabilitiesMask ( long * plEncryptionCapabilitiesMask )
  921. {
  922. return StdPropertyGet ( m_dwEncryptionCapabilities, plEncryptionCapabilitiesMask );
  923. }
  924. STDMETHODIMP CNntpVirtualServer::put_EncryptionCapabilitiesMask ( long lEncryptionCapabilitiesMask )
  925. {
  926. return StdPropertyPut ( &m_dwEncryptionCapabilities, lEncryptionCapabilitiesMask, &m_bvChangedFields, CHNG_ENCRYPTIONCAPABILITIES );
  927. }
  928. */
  929. //////////////////////////////////////////////////////////////////////
  930. // Methods:
  931. //////////////////////////////////////////////////////////////////////
  932. //$-------------------------------------------------------------------
  933. //
  934. // CNntpVirtualServer::Get
  935. //
  936. // Description:
  937. //
  938. // Gets server properties from the metabase.
  939. //
  940. // Parameters:
  941. //
  942. // (property) m_strServer
  943. // (property) m_dwServiceInstance - which NNTP to talk to.
  944. // pErr - Resulting error code. This can be translated to a
  945. // string through the INntpAdmin interface.
  946. //
  947. // Returns:
  948. //
  949. // E_POINTER, DISP_E_EXCEPTION, E_OUTOFMEMORY or NOERROR.
  950. // Additional error conditions are returned through the pErr value.
  951. //
  952. //--------------------------------------------------------------------
  953. STDMETHODIMP CNntpVirtualServer::Get ( )
  954. {
  955. TraceFunctEnter ( "CNntpVirtualServer::Get" );
  956. HRESULT hr = NOERROR;
  957. CComPtr<IMSAdminBase> pmetabase;
  958. CComObject<CNntpServerBindings> * pBindings = NULL;
  959. // Validate Server & Service Instance:
  960. // Create the bindings collection:
  961. m_pBindings.Release ();
  962. hr = CComObject<CNntpServerBindings>::CreateInstance ( &pBindings );
  963. if ( FAILED(hr) ) {
  964. FatalTrace ( (LPARAM) this, "Could not create bindings collection" );
  965. goto Exit;
  966. }
  967. hr = pBindings->QueryInterface ( IID_INntpServerBindings, (void **) &m_pBindings );
  968. _ASSERT ( SUCCEEDED(hr) );
  969. if ( FAILED(hr) ) {
  970. goto Exit;
  971. }
  972. m_pPrivateBindings = pBindings;
  973. // Talk to the metabase:
  974. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  975. if ( FAILED(hr) ) {
  976. goto Exit;
  977. }
  978. hr = GetPropertiesFromMetabase ( pmetabase );
  979. if ( FAILED(hr) ) {
  980. goto Exit;
  981. }
  982. StateTrace ( 0, "Successfully got service properties" );
  983. m_fGotProperties = TRUE;
  984. m_bvChangedFields = 0;
  985. m_bvChangedFields2 = 0;
  986. Exit:
  987. TRACE_HRESULT(hr);
  988. TraceFunctLeave ();
  989. return hr;
  990. // CComPtr automatically releases the metabase handle.
  991. }
  992. //$-------------------------------------------------------------------
  993. //
  994. // CNntpVirtualServer::Set
  995. //
  996. // Description:
  997. //
  998. // Sends server properties to the metabase.
  999. //
  1000. // Parameters:
  1001. //
  1002. // (property) m_strServer
  1003. // fFailIfChanged - return an error if the metabase has changed?
  1004. // pErr - Resulting error code. This can be translated to a
  1005. // string through the INntpAdmin interface.
  1006. //
  1007. // Returns:
  1008. //
  1009. // E_POINTER, DISP_E_EXCEPTION, E_OUTOFMEMORY or NOERROR.
  1010. // Additional error conditions are returned through the pErr value.
  1011. //
  1012. //--------------------------------------------------------------------
  1013. STDMETHODIMP CNntpVirtualServer::Set ( BOOL fFailIfChanged)
  1014. {
  1015. TraceFunctEnter ( "CNntpVirtualServer::Set" );
  1016. HRESULT hr = NOERROR;
  1017. CComPtr<IMSAdminBase> pmetabase;
  1018. // Make sure the client call Get first:
  1019. if ( !m_fGotProperties ) {
  1020. ErrorTrace ( 0, "Didn't call get first" );
  1021. return NntpCreateException ( IDS_NNTPEXCEPTION_DIDNT_CALL_GET );
  1022. }
  1023. // Validate Server & Service Instance:
  1024. if ( m_dwServiceInstance == 0 ) {
  1025. return NntpCreateException ( IDS_NNTPEXCEPTION_SERVICE_INSTANCE_CANT_BE_ZERO );
  1026. }
  1027. if ( !m_fGotProperties ) {
  1028. return NntpCreateException ( IDS_NNTPEXCEPTION_DIDNT_CALL_GET );
  1029. }
  1030. // Validate data members:
  1031. if ( !ValidateStrings () ) {
  1032. // !!!magnush - what about the case when any strings are NULL?
  1033. hr = E_OUTOFMEMORY;
  1034. goto Exit;
  1035. }
  1036. if ( !ValidateProperties ( ) ) {
  1037. hr = RETURNCODETOHRESULT ( ERROR_INVALID_PARAMETER );
  1038. goto Exit;
  1039. }
  1040. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  1041. if ( FAILED(hr) ) {
  1042. goto Exit;
  1043. }
  1044. hr = SendPropertiesToMetabase ( fFailIfChanged, pmetabase );
  1045. if ( FAILED(hr) ) {
  1046. goto Exit;
  1047. }
  1048. StateTrace ( 0, "Successfully set service properties" );
  1049. Exit:
  1050. TRACE_HRESULT(hr);
  1051. TraceFunctLeave ();
  1052. return hr;
  1053. }
  1054. HRESULT CNntpVirtualServer::ControlService (
  1055. IMSAdminBase * pMetabase,
  1056. DWORD ControlCode,
  1057. DWORD dwDesiredState,
  1058. DWORD dwPendingState
  1059. )
  1060. {
  1061. TraceFunctEnter ( "CNntpVirtualServer::ControlService" );
  1062. HRESULT hr = NOERROR;
  1063. DWORD dwCurrentState = dwPendingState;
  1064. DWORD dwOldState = dwPendingState;
  1065. DWORD dwSleepTotal = 0;
  1066. hr = CheckServiceState ( pMetabase, &dwCurrentState );
  1067. BAIL_ON_FAILURE(hr);
  1068. if ( dwCurrentState == dwDesiredState ) {
  1069. // Nothing to do...
  1070. goto Exit;
  1071. }
  1072. dwOldState = dwCurrentState;
  1073. //
  1074. // Special case: trying to start a paused service:
  1075. //
  1076. if ( dwDesiredState == MD_SERVER_STATE_STARTED &&
  1077. dwCurrentState == MD_SERVER_STATE_PAUSED ) {
  1078. ControlCode = MD_SERVER_COMMAND_CONTINUE;
  1079. dwPendingState = MD_SERVER_STATE_CONTINUING;
  1080. }
  1081. hr = WriteStateCommand ( pMetabase, ControlCode );
  1082. BAIL_ON_FAILURE(hr);
  1083. for ( dwSleepTotal = 0, dwCurrentState = dwPendingState;
  1084. (dwCurrentState == dwPendingState || dwCurrentState == dwOldState) && (dwSleepTotal < MAX_SLEEP_INST);
  1085. dwSleepTotal += SLEEP_INTERVAL
  1086. ) {
  1087. Sleep ( SLEEP_INTERVAL );
  1088. hr = CheckServiceState ( pMetabase, &dwCurrentState );
  1089. BAIL_ON_FAILURE(hr);
  1090. if ( m_dwWin32ErrorCode != NOERROR ) {
  1091. //
  1092. // The service gave an error code.
  1093. //
  1094. break;
  1095. }
  1096. }
  1097. if ( dwSleepTotal >= MAX_SLEEP_INST ) {
  1098. hr = HRESULT_FROM_WIN32 ( ERROR_SERVICE_REQUEST_TIMEOUT );
  1099. goto Exit;
  1100. }
  1101. Exit:
  1102. m_State = TranslateServerState ( dwCurrentState );
  1103. TraceFunctLeave ();
  1104. return hr;
  1105. }
  1106. HRESULT CNntpVirtualServer::WriteStateCommand ( IMSAdminBase * pMetabase, DWORD ControlCode )
  1107. {
  1108. HRESULT hr = NOERROR;
  1109. CMetabaseKey metabase ( pMetabase );
  1110. WCHAR wszInstancePath [ METADATA_MAX_NAME_LEN ];
  1111. GetMDInstancePath ( wszInstancePath, m_dwServiceInstance );
  1112. hr = metabase.Open ( wszInstancePath, METADATA_PERMISSION_WRITE );
  1113. hr = StdPutMetabaseProp ( &metabase, MD_WIN32_ERROR, NOERROR, _T(""), IIS_MD_UT_SERVER, METADATA_VOLATILE );
  1114. BAIL_ON_FAILURE (hr);
  1115. hr = StdPutMetabaseProp ( &metabase, MD_SERVER_COMMAND, ControlCode );
  1116. BAIL_ON_FAILURE (hr);
  1117. hr = metabase.Save ();
  1118. BAIL_ON_FAILURE(hr);
  1119. Exit:
  1120. return hr;
  1121. }
  1122. HRESULT CNntpVirtualServer::CheckServiceState ( IMSAdminBase * pMetabase, DWORD * pdwState )
  1123. {
  1124. HRESULT hr = NOERROR;
  1125. CMetabaseKey metabase ( pMetabase );
  1126. WCHAR wszInstancePath [ METADATA_MAX_NAME_LEN ];
  1127. *pdwState = MD_SERVER_STATE_INVALID;
  1128. GetMDInstancePath ( wszInstancePath, m_dwServiceInstance );
  1129. hr = metabase.Open ( wszInstancePath );
  1130. BAIL_ON_FAILURE(hr);
  1131. m_dwWin32ErrorCode = NOERROR;
  1132. metabase.GetDword ( MD_SERVER_STATE, pdwState );
  1133. metabase.GetDword ( MD_WIN32_ERROR, &m_dwWin32ErrorCode );
  1134. Exit:
  1135. return hr;
  1136. }
  1137. STDMETHODIMP CNntpVirtualServer::Start ( )
  1138. {
  1139. TraceFunctEnter ( "CNntpVirtualServer::Start" );
  1140. HRESULT hr = NOERROR;
  1141. CComPtr<IMSAdminBase> pmetabase;
  1142. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  1143. if ( FAILED(hr) ) {
  1144. goto Exit;
  1145. }
  1146. hr = ControlService (
  1147. pmetabase,
  1148. MD_SERVER_COMMAND_START,
  1149. MD_SERVER_STATE_STARTED,
  1150. MD_SERVER_STATE_STARTING
  1151. );
  1152. Exit:
  1153. TraceFunctLeave ();
  1154. return hr;
  1155. }
  1156. STDMETHODIMP CNntpVirtualServer::Pause ( )
  1157. {
  1158. TraceFunctEnter ( "CNntpVirtualServer::Start" );
  1159. HRESULT hr = NOERROR;
  1160. CComPtr<IMSAdminBase> pmetabase;
  1161. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  1162. if ( FAILED(hr) ) {
  1163. goto Exit;
  1164. }
  1165. hr = ControlService (
  1166. pmetabase,
  1167. MD_SERVER_COMMAND_PAUSE,
  1168. MD_SERVER_STATE_PAUSED,
  1169. MD_SERVER_STATE_PAUSING
  1170. );
  1171. Exit:
  1172. TraceFunctLeave ();
  1173. return hr;
  1174. }
  1175. STDMETHODIMP CNntpVirtualServer::Continue ( )
  1176. {
  1177. TraceFunctEnter ( "CNntpVirtualServer::Start" );
  1178. HRESULT hr = NOERROR;
  1179. CComPtr<IMSAdminBase> pmetabase;
  1180. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  1181. if ( FAILED(hr) ) {
  1182. goto Exit;
  1183. }
  1184. hr = ControlService (
  1185. pmetabase,
  1186. MD_SERVER_COMMAND_CONTINUE,
  1187. MD_SERVER_STATE_STARTED,
  1188. MD_SERVER_STATE_CONTINUING
  1189. );
  1190. Exit:
  1191. TraceFunctLeave ();
  1192. return hr;
  1193. }
  1194. STDMETHODIMP CNntpVirtualServer::Stop ( )
  1195. {
  1196. TraceFunctEnter ( "CNntpVirtualServer::Start" );
  1197. HRESULT hr = NOERROR;
  1198. CComPtr<IMSAdminBase> pmetabase;
  1199. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
  1200. if ( FAILED(hr) ) {
  1201. goto Exit;
  1202. }
  1203. hr = ControlService (
  1204. pmetabase,
  1205. MD_SERVER_COMMAND_STOP,
  1206. MD_SERVER_STATE_STOPPED,
  1207. MD_SERVER_STATE_STOPPING
  1208. );
  1209. Exit:
  1210. TraceFunctLeave ();
  1211. return hr;
  1212. }
  1213. //$-------------------------------------------------------------------
  1214. //
  1215. // CNntpVirtualServer::GetPropertiesFromMetabase
  1216. //
  1217. // Description:
  1218. //
  1219. // Asks the metabase for each property in this class.
  1220. // This class's properties come from /LM/NntpSvc/
  1221. //
  1222. // Parameters:
  1223. //
  1224. // pMetabase - The metabase object
  1225. // pErr - Resulting error code.
  1226. //
  1227. // Returns:
  1228. //
  1229. // E_OUTOFMEMORY or an error code in pErr.
  1230. //
  1231. //--------------------------------------------------------------------
  1232. HRESULT CNntpVirtualServer::GetPropertiesFromMetabase ( IMSAdminBase * pMetabase)
  1233. {
  1234. TraceFunctEnter ( "CNntpVirtualServer::GetPropertiesFromMetabase" );
  1235. HRESULT hr = NOERROR;
  1236. CMetabaseKey metabase ( pMetabase );
  1237. WCHAR wszInstancePath [ METADATA_MAX_NAME_LEN ];
  1238. DWORD dwServerState = MD_SERVER_STATE_STOPPED;
  1239. CMultiSz mszBindings;
  1240. CMultiSz mszSecureBindings;
  1241. PSECURITY_DESCRIPTOR pSD = NULL;
  1242. DWORD cbSD = 0;
  1243. BOOL fRet;
  1244. GetMDInstancePath ( wszInstancePath, m_dwServiceInstance );
  1245. hr = metabase.Open ( wszInstancePath );
  1246. if ( FAILED(hr) ) {
  1247. ErrorTraceX ( (LPARAM) this, "Failed to open service instance key, %x", hr );
  1248. // Return some kind of error code here:
  1249. // hr = NntpCreateExceptionFromWin32Error ( hr );
  1250. goto Exit;
  1251. }
  1252. fRet = TRUE;
  1253. // Overridable server properties:
  1254. fRet = StdGetMetabaseProp ( &metabase, MD_ARTICLE_TIME_LIMIT, NNTP_DEF_ARTICLETIMELIMIT, &m_dwArticleTimeLimit ) && fRet;
  1255. fRet = StdGetMetabaseProp ( &metabase, MD_HISTORY_EXPIRATION, NNTP_DEF_HISTORYEXPIRATION, &m_dwHistoryExpiration ) && fRet;
  1256. fRet = StdGetMetabaseProp ( &metabase, MD_HONOR_CLIENT_MSGIDS, NNTP_DEF_HONORCLIENTMSGIDS, &m_fHonorClientMsgIDs ) && fRet;
  1257. fRet = StdGetMetabaseProp ( &metabase, MD_SMTP_SERVER, NNTP_DEF_SMTPSERVER, &m_strSmtpServer ) && fRet;
  1258. fRet = StdGetMetabaseProp ( &metabase, MD_ADMIN_EMAIL, NNTP_DEF_ADMIN_EMAIL, &m_strAdminEmail ) && fRet;
  1259. fRet = StdGetMetabaseProp ( &metabase, MD_ALLOW_CLIENT_POSTS, NNTP_DEF_ALLOWCLIENTPOSTS, &m_fAllowClientPosts ) && fRet;
  1260. fRet = StdGetMetabaseProp ( &metabase, MD_ALLOW_FEED_POSTS, NNTP_DEF_ALLOWFEEDPOSTS, &m_fAllowFeedPosts ) && fRet;
  1261. fRet = StdGetMetabaseProp ( &metabase, MD_ALLOW_CONTROL_MSGS, NNTP_DEF_ALLOWCONTROLMSGS, &m_fAllowControlMsgs ) && fRet;
  1262. fRet = StdGetMetabaseProp ( &metabase, MD_DEFAULT_MODERATOR, NNTP_DEF_DEFAULTMODERATORDOMAIN, &m_strDefaultModeratorDomain ) && fRet;
  1263. fRet = StdGetMetabaseProp ( &metabase, MD_NNTP_COMMAND_LOG_MASK, NNTP_DEF_COMMANDLOGMASK, &m_dwCommandLogMask ) && fRet;
  1264. fRet = StdGetMetabaseProp ( &metabase, MD_DISABLE_NEWNEWS, NNTP_DEF_DISABLENEWNEWS, &m_fDisableNewnews ) && fRet;
  1265. fRet = StdGetMetabaseProp ( &metabase, MD_NEWS_CRAWLER_TIME, NNTP_DEF_NEWSCRAWLERTIME, &m_dwExpireRunFrequency ) && fRet;
  1266. fRet = StdGetMetabaseProp ( &metabase, MD_SHUTDOWN_LATENCY, NNTP_DEF_SHUTDOWNLATENCY, &m_dwShutdownLatency ) && fRet;
  1267. fRet = StdGetMetabaseProp ( &metabase, MD_LOG_TYPE, NNTP_DEF_ENABLE_LOGGING, &m_fEnableLogging ) && fRet;
  1268. fRet = StdGetMetabaseProp ( &metabase, MD_CLIENT_POST_HARD_LIMIT, NNTP_DEF_CLIENTPOSTHARDLIMIT, &m_dwClientPostHardLimit ) && fRet;
  1269. fRet = StdGetMetabaseProp ( &metabase, MD_CLIENT_POST_SOFT_LIMIT, NNTP_DEF_CLIENTPOSTSOFTLIMIT, &m_dwClientPostSoftLimit ) && fRet;
  1270. fRet = StdGetMetabaseProp ( &metabase, MD_FEED_POST_HARD_LIMIT, NNTP_DEF_FEEDPOSTHARDLIMIT, &m_dwFeedPostHardLimit ) && fRet;
  1271. fRet = StdGetMetabaseProp ( &metabase, MD_FEED_POST_SOFT_LIMIT, NNTP_DEF_FEEDPOSTSOFTLIMIT, &m_dwFeedPostSoftLimit ) && fRet;
  1272. // Service-specific properties:
  1273. fRet = StdGetMetabaseProp ( &metabase, MD_GROUP_HELP_FILE, NNTP_DEF_GROUPHELPFILE, &m_strGroupHelpFile ) && fRet;
  1274. fRet = StdGetMetabaseProp ( &metabase, MD_GROUP_LIST_FILE, NNTP_DEF_GROUPLISTFILE, &m_strGroupListFile ) && fRet;
  1275. fRet = StdGetMetabaseProp ( &metabase, MD_GROUPVAR_LIST_FILE, NNTP_DEF_GROUPVARLISTFILE, &m_strGroupVarListFile) && fRet;
  1276. fRet = StdGetMetabaseProp ( &metabase, MD_ARTICLE_TABLE_FILE, NNTP_DEF_ARTICLETABLEFILE, &m_strArticleTableFile ) && fRet;
  1277. fRet = StdGetMetabaseProp ( &metabase, MD_HISTORY_TABLE_FILE, NNTP_DEF_HISTORYTABLEFILE, &m_strHistoryTableFile ) && fRet;
  1278. fRet = StdGetMetabaseProp ( &metabase, MD_MODERATOR_FILE, NNTP_DEF_MODERATORFILE, &m_strModeratorFile ) && fRet;
  1279. fRet = StdGetMetabaseProp ( &metabase, MD_XOVER_TABLE_FILE, NNTP_DEF_XOVERTABLEFILE, &m_strXOverTableFile ) && fRet;
  1280. fRet = StdGetMetabaseProp ( &metabase, MD_NNTP_UUCP_NAME, NNTP_DEF_UUCPNAME, &m_strUucpName ) && fRet;
  1281. fRet = StdGetMetabaseProp ( &metabase, MD_NNTP_ORGANIZATION, NNTP_DEF_ORGANIZATION, &m_strOrganization ) && fRet;
  1282. fRet = StdGetMetabaseProp ( &metabase, MD_SERVER_AUTOSTART, NNTP_DEF_AUTOSTART, &m_fAutoStart ) && fRet;
  1283. fRet = StdGetMetabaseProp ( &metabase, MD_SERVER_COMMENT, NNTP_DEF_COMMENT, &m_strComment ) && fRet;
  1284. #if 0
  1285. fRet = StdGetMetabaseProp ( &metabase, MD_SECURE_PORT, NNTP_DEF_SECUREPORT, &m_dwSecurePort ) && fRet;
  1286. #endif
  1287. fRet = StdGetMetabaseProp ( &metabase, MD_MAX_CONNECTIONS, NNTP_DEF_MAXCONNECTIONS, &m_dwMaxConnections ) && fRet;
  1288. fRet = StdGetMetabaseProp ( &metabase, MD_CONNECTION_TIMEOUT, NNTP_DEF_CONNECTIONTIMEOUT, &m_dwConnectionTimeout ) && fRet;
  1289. fRet = StdGetMetabaseProp ( &metabase, MD_ANONYMOUS_USER_NAME, NNTP_DEF_ANONYMOUSUSERNAME, &m_strAnonymousUserName ) && fRet;
  1290. if ( fRet && !StdGetMetabaseProp ( &metabase, MD_ANONYMOUS_PWD, NNTP_DEF_ANONYMOUSUSERPASS, &m_strAnonymousUserPass, _T(""), IIS_MD_UT_FILE, METADATA_INHERIT | METADATA_SECURE ) ) {
  1291. m_strAnonymousUserPass = _T("");
  1292. fRet = TRUE;
  1293. }
  1294. fRet = StdGetMetabaseProp ( &metabase, MD_ANONYMOUS_USE_SUBAUTH, FALSE, &m_fAutoSyncPassword ) && fRet;
  1295. fRet = StdGetMetabaseProp ( &metabase, MD_PICKUP_DIRECTORY, NNTP_DEF_PICKUPDIRECTORY, &m_strPickupDirectory ) && fRet;
  1296. fRet = StdGetMetabaseProp ( &metabase, MD_FAILED_PICKUP_DIRECTORY, NNTP_DEF_FAILEDPICKUPDIRECTORY, &m_strFailedPickupDirectory ) && fRet;
  1297. fRet = StdGetMetabaseProp ( &metabase, MD_SERVER_STATE, MD_SERVER_STATE_INVALID, &dwServerState ) && fRet;
  1298. fRet = StdGetMetabaseProp ( &metabase, MD_SERVER_BINDINGS, NNTP_DEF_BINDINGS, &mszBindings ) && fRet;
  1299. fRet = StdGetMetabaseProp ( &metabase, MD_SECURE_BINDINGS, NNTP_DEF_SECURE_BINDINGS, &mszSecureBindings ) && fRet;
  1300. fRet = StdGetMetabaseProp ( &metabase, MD_WIN32_ERROR, NOERROR, &m_dwWin32ErrorCode,
  1301. _T(""), IIS_MD_UT_SERVER, METADATA_VOLATILE) && fRet;
  1302. fRet = StdGetMetabaseProp ( &metabase, MD_AUTHORIZATION, NNTP_DEF_AUTHORIZATION, &m_bvAuthorization ) && fRet;
  1303. fRet = StdGetMetabaseProp ( &metabase, MD_SSL_ACCESS_PERM, 0, &m_bvSslAccess ) && fRet;
  1304. // fRet = StdGetMetabaseProp ( &metabase, MD_NTAUTHENTICATION_PROVIDERS, NNTP_DEF_NTAUTHENTICATION_PROVIDERS, &m_mszProviders ) && fRet;
  1305. fRet = StdGetMetabaseProp ( &metabase, MD_CLUSTER_ENABLED, NNTP_DEF_CLUSTERENABLED, &m_fClusterEnabled ) && fRet;
  1306. // Get the admin ACL
  1307. pSD = NULL;
  1308. cbSD = 0;
  1309. hr = metabase.GetDataSize ( _T(""), MD_ADMIN_ACL, BINARY_METADATA, &cbSD );
  1310. if ( SUCCEEDED(hr) ) {
  1311. _ASSERT ( cbSD != 0 );
  1312. pSD = (PSECURITY_DESCRIPTOR) new char [ cbSD ];
  1313. hr = metabase.GetBinary ( MD_ADMIN_ACL, pSD, cbSD );
  1314. }
  1315. hr = NOERROR;
  1316. //
  1317. // Get the tcp access restrictions:
  1318. //
  1319. hr = m_pPrivateIpAccess->GetFromMetabase ( &metabase );
  1320. BAIL_ON_FAILURE(hr);
  1321. // Check all property strings:
  1322. // If any string is NULL, it is because we failed to allocate memory:
  1323. if ( !ValidateStrings () || !mszBindings) {
  1324. hr = E_OUTOFMEMORY;
  1325. goto Exit;
  1326. }
  1327. // We can only fail from memory allocations:
  1328. _ASSERT ( fRet );
  1329. // Extract the server state:
  1330. m_State = TranslateServerState ( dwServerState );
  1331. // Save the last changed time for this key:
  1332. m_ftLastChanged.dwHighDateTime = 0;
  1333. m_ftLastChanged.dwLowDateTime = 0;
  1334. hr = pMetabase->GetLastChangeTime ( metabase.QueryHandle(), _T(""), &m_ftLastChanged, FALSE );
  1335. if ( FAILED (hr) ) {
  1336. ErrorTraceX ( (LPARAM) this, "Failed to get last change time: %x", hr );
  1337. // Ignore this error.
  1338. hr = NOERROR;
  1339. }
  1340. metabase.Close();
  1341. // Extract the bindings:
  1342. hr = MDBindingsToIBindings ( &mszBindings, TRUE, m_pBindings );
  1343. BAIL_ON_FAILURE(hr);
  1344. hr = MDBindingsToIBindings ( &mszSecureBindings, FALSE, m_pBindings );
  1345. BAIL_ON_FAILURE(hr);
  1346. // Extract the Administrator list:
  1347. if ( m_psaAdmins ) {
  1348. SafeArrayDestroy ( m_psaAdmins );
  1349. m_psaAdmins = NULL;
  1350. }
  1351. if ( pSD ) {
  1352. hr = AclToAdministrators ( m_strServer, pSD, &m_psaAdmins );
  1353. BAIL_ON_FAILURE(hr);
  1354. }
  1355. // Validate the data received from the metabase:
  1356. _ASSERT ( ValidateStrings () );
  1357. _ASSERT ( ValidateProperties( ) );
  1358. if ( !ValidateProperties( ) ) {
  1359. CorrectProperties ();
  1360. }
  1361. Exit:
  1362. delete (char*) pSD;
  1363. TraceFunctLeave ();
  1364. return hr;
  1365. // MB automatically closes its handle
  1366. }
  1367. //$-------------------------------------------------------------------
  1368. //
  1369. // CNntpVirtualServer::SendPropertiesToMetabase
  1370. //
  1371. // Description:
  1372. //
  1373. // Saves each property to the metabase.
  1374. // This class's properties go into /LM/NntpSvc/
  1375. //
  1376. // Parameters:
  1377. //
  1378. // fFailIfChanged - Return a failure code if the metabase
  1379. // has changed since last get.
  1380. // pMetabase - the metabase object.
  1381. // pErr - resulting error code.
  1382. //
  1383. // Returns:
  1384. //
  1385. // E_OUTOFMEMORY or resulting error code in pErr.
  1386. //
  1387. //--------------------------------------------------------------------
  1388. HRESULT CNntpVirtualServer::SendPropertiesToMetabase (
  1389. BOOL fFailIfChanged,
  1390. IMSAdminBase * pMetabase
  1391. )
  1392. {
  1393. TraceFunctEnter ( "CNntpVirtualServer::SendPropertiesToMetabase" );
  1394. HRESULT hr = NOERROR;
  1395. CMetabaseKey metabase ( pMetabase );
  1396. WCHAR wszInstancePath [ METADATA_MAX_NAME_LEN ];
  1397. CMultiSz mszBindings;
  1398. CMultiSz mszSecureBindings;
  1399. BOOL fRet;
  1400. //
  1401. // Set the admin acl:
  1402. //
  1403. PSECURITY_DESCRIPTOR pSD = NULL;
  1404. DWORD cbSD = 0;
  1405. if ( m_bvChangedFields2 & CHNG2_ADMINACL ) {
  1406. if ( m_psaAdmins ) {
  1407. hr = AdministratorsToAcl ( m_strServer, m_psaAdmins, &pSD, &cbSD );
  1408. BAIL_ON_FAILURE(hr);
  1409. }
  1410. }
  1411. //
  1412. // Open the metabase key:
  1413. //
  1414. GetMDInstancePath ( wszInstancePath, m_dwServiceInstance );
  1415. hr = metabase.Open ( wszInstancePath, METADATA_PERMISSION_WRITE );
  1416. if ( FAILED(hr) ) {
  1417. ErrorTraceX ( (LPARAM) this, "Failed to open instance key, %x", hr );
  1418. // !!!magnush - Should we return a simple Service doesn't exist error code?
  1419. // hr = NntpCreateExceptionFromWin32Error ( GetLastError () );
  1420. goto Exit;
  1421. }
  1422. // Does the client care if the key has changed?
  1423. if ( fFailIfChanged ) {
  1424. // Did the key change?
  1425. if ( HasKeyChanged ( pMetabase, metabase.QueryHandle(), &m_ftLastChanged ) ) {
  1426. StateTrace ( (LPARAM) this, "Metabase has changed, not setting properties" );
  1427. // !!!magnush - Return the appropriate error code:
  1428. hr = E_FAIL;
  1429. goto Exit;
  1430. }
  1431. }
  1432. // Extract the bindings:
  1433. hr = IBindingsToMDBindings ( m_pBindings, TRUE, &mszBindings );
  1434. BAIL_ON_FAILURE(hr);
  1435. hr = IBindingsToMDBindings ( m_pBindings, FALSE, &mszSecureBindings );
  1436. BAIL_ON_FAILURE(hr);
  1437. //
  1438. // The general procedure here is to keep setting metabase properties
  1439. // as long as nothing has gone wrong. This is done by short-circuiting
  1440. // the statement by ANDing it with the status code. This makes the code
  1441. // much more concise.
  1442. //
  1443. fRet = TRUE;
  1444. // Overridable server properties:
  1445. if ( m_bvChangedFields & CHNG_ARTICLETIMELIMIT ) {
  1446. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ARTICLE_TIME_LIMIT, m_dwArticleTimeLimit );
  1447. }
  1448. if ( m_bvChangedFields & CHNG_HISTORYEXPIRATION ) {
  1449. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_HISTORY_EXPIRATION, m_dwHistoryExpiration );
  1450. }
  1451. if ( m_bvChangedFields & CHNG_HONORCLIENTMSGIDS ) {
  1452. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_HONOR_CLIENT_MSGIDS, m_fHonorClientMsgIDs );
  1453. }
  1454. if ( m_bvChangedFields & CHNG_SMTPSERVER ) {
  1455. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SMTP_SERVER, m_strSmtpServer );
  1456. }
  1457. if ( m_bvChangedFields2 & CHNG2_ADMINEMAIL) {
  1458. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ADMIN_EMAIL, m_strAdminEmail );
  1459. }
  1460. if ( m_bvChangedFields & CHNG_ALLOWCLIENTPOSTS ) {
  1461. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ALLOW_CLIENT_POSTS, m_fAllowClientPosts );
  1462. }
  1463. if ( m_bvChangedFields & CHNG_ALLOWFEEDPOSTS ) {
  1464. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ALLOW_FEED_POSTS, m_fAllowFeedPosts );
  1465. }
  1466. if ( m_bvChangedFields & CHNG_ALLOWCONTROLMSGS ) {
  1467. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ALLOW_CONTROL_MSGS, m_fAllowControlMsgs );
  1468. }
  1469. if ( m_bvChangedFields & CHNG_DEFAULTMODERATORDOMAIN ) {
  1470. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_DEFAULT_MODERATOR, m_strDefaultModeratorDomain );
  1471. }
  1472. if ( m_bvChangedFields & CHNG_COMMANDLOGMASK ) {
  1473. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_NNTP_COMMAND_LOG_MASK,m_dwCommandLogMask );
  1474. }
  1475. if ( m_bvChangedFields & CHNG_DISABLENEWNEWS ) {
  1476. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_DISABLE_NEWNEWS, m_fDisableNewnews );
  1477. }
  1478. if ( m_bvChangedFields & CHNG_NEWSCRAWLERTIME ) {
  1479. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_NEWS_CRAWLER_TIME, m_dwExpireRunFrequency );
  1480. }
  1481. if ( m_bvChangedFields & CHNG_SHUTDOWNLATENCY ) {
  1482. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SHUTDOWN_LATENCY, m_dwShutdownLatency );
  1483. }
  1484. if ( m_bvChangedFields & CHNG_CLIENTPOSTHARDLIMIT ) {
  1485. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_CLIENT_POST_HARD_LIMIT, m_dwClientPostHardLimit );
  1486. }
  1487. if ( m_bvChangedFields & CHNG_CLIENTPOSTSOFTLIMIT ) {
  1488. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_CLIENT_POST_SOFT_LIMIT, m_dwClientPostSoftLimit );
  1489. }
  1490. if ( m_bvChangedFields & CHNG_FEEDPOSTHARDLIMIT ) {
  1491. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_FEED_POST_HARD_LIMIT, m_dwFeedPostHardLimit );
  1492. }
  1493. if ( m_bvChangedFields & CHNG_FEEDPOSTSOFTLIMIT ) {
  1494. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_FEED_POST_SOFT_LIMIT, m_dwFeedPostSoftLimit );
  1495. }
  1496. if ( m_bvChangedFields2 & CHNG2_ENABLELOGGING ) {
  1497. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_LOG_TYPE, m_fEnableLogging );
  1498. }
  1499. // Service specific properties:
  1500. if ( m_bvChangedFields & CHNG_GROUPHELPFILE ) {
  1501. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_GROUP_HELP_FILE, m_strGroupHelpFile );
  1502. }
  1503. if ( m_bvChangedFields & CHNG_GROUPLISTFILE ) {
  1504. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_GROUP_LIST_FILE, m_strGroupListFile );
  1505. // BUGBUG: we share this change field, since Magnus didn't leave more space for
  1506. // change bit
  1507. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_GROUPVAR_LIST_FILE, m_strGroupVarListFile );
  1508. }
  1509. if ( m_bvChangedFields & CHNG_ARTICLETABLEFILE ) {
  1510. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ARTICLE_TABLE_FILE, m_strArticleTableFile );
  1511. }
  1512. if ( m_bvChangedFields & CHNG_HISTORYTABLEFILE ) {
  1513. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_HISTORY_TABLE_FILE, m_strHistoryTableFile );
  1514. }
  1515. if ( m_bvChangedFields & CHNG_MODERATORFILE ) {
  1516. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_MODERATOR_FILE, m_strModeratorFile );
  1517. }
  1518. if ( m_bvChangedFields & CHNG_XOVERTABLEFILE ) {
  1519. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_XOVER_TABLE_FILE, m_strXOverTableFile );
  1520. }
  1521. if ( m_bvChangedFields & CHNG_UUCPNAME ) {
  1522. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_NNTP_UUCP_NAME, m_strUucpName );
  1523. }
  1524. if ( m_bvChangedFields & CHNG_ORGANIZATION ) {
  1525. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_NNTP_ORGANIZATION, m_strOrganization );
  1526. }
  1527. if ( m_bvChangedFields & CHNG_AUTOSTART ) {
  1528. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SERVER_AUTOSTART, m_fAutoStart );
  1529. }
  1530. if ( m_bvChangedFields & CHNG_COMMENT ) {
  1531. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SERVER_COMMENT, m_strComment );
  1532. }
  1533. #if 0
  1534. if ( m_bvChangedFields & CHNG_SECUREPORT ) {
  1535. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SECURE_PORT, m_dwSecurePort );
  1536. }
  1537. #endif
  1538. if ( m_bvChangedFields & CHNG_MAXCONNECTIONS ) {
  1539. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_MAX_CONNECTIONS, m_dwMaxConnections );
  1540. }
  1541. if ( m_bvChangedFields2 & CHNG2_CONNECTIONTIMEOUT ) {
  1542. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_CONNECTION_TIMEOUT, m_dwConnectionTimeout );
  1543. }
  1544. if ( m_bvChangedFields2 & CHNG2_ANONYMOUSUSERNAME ) {
  1545. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ANONYMOUS_USER_NAME, m_strAnonymousUserName, _T(""), IIS_MD_UT_FILE );
  1546. }
  1547. if ( m_bvChangedFields2 & CHNG2_ANONYMOUSUSERPASS ) {
  1548. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ANONYMOUS_PWD, m_strAnonymousUserPass, _T(""), IIS_MD_UT_FILE, METADATA_INHERIT | METADATA_SECURE );
  1549. }
  1550. if ( m_bvChangedFields2 & CHNG2_AUTOSYNCPASSWORD ) {
  1551. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ANONYMOUS_USE_SUBAUTH, m_fAutoSyncPassword, _T(""), IIS_MD_UT_FILE );
  1552. }
  1553. if ( m_bvChangedFields2 & CHNG2_PICKUPDIRECTORY ) {
  1554. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_PICKUP_DIRECTORY, m_strPickupDirectory );
  1555. }
  1556. if ( m_bvChangedFields2 & CHNG2_FAILEDPICKUPDIRECTORY ) {
  1557. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_FAILED_PICKUP_DIRECTORY, m_strFailedPickupDirectory );
  1558. }
  1559. if ( m_bvChangedFields2 & CHNG2_CLUSTERENABLED ) {
  1560. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_CLUSTER_ENABLED, m_fClusterEnabled );
  1561. }
  1562. // if ( m_bvChangedFields & CHNG_AUTHORIZATION ) {
  1563. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_AUTHORIZATION, m_bvAuthorization, _T(""), IIS_MD_UT_FILE );
  1564. // }
  1565. // if ( m_bvChangedFields & CHNG2_SSLACCESS ) {
  1566. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SSL_ACCESS_PERM, m_bvSslAccess, _T(""), IIS_MD_UT_FILE );
  1567. // }
  1568. // if ( m_bvChangedFields & CHNG_NTAUTHENTICATION_PROVIDERS ) {
  1569. // fRet = fRet && StdPutMetabaseProp ( &metabase, MD_NTAUTHENTICATION_PROVIDERS, &m_mszProviders );
  1570. // }
  1571. // if ( m_bvChangedFields & CHNG_BINDINGS ) {
  1572. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SERVER_BINDINGS, &mszBindings );
  1573. // }
  1574. // if ( m_bvChangedFields & CHNG_SECURE_BINDINGS ) {
  1575. fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SECURE_BINDINGS, &mszSecureBindings );
  1576. // }
  1577. if ( m_bvChangedFields2 & CHNG2_ADMINACL ) {
  1578. if ( pSD ) {
  1579. if (fRet) {
  1580. hr = metabase.SetBinary ( MD_ADMIN_ACL, pSD, cbSD,
  1581. METADATA_INHERIT | METADATA_REFERENCE | METADATA_SECURE, IIS_MD_UT_FILE );
  1582. if (FAILED(hr)) {
  1583. fRet = FALSE;
  1584. goto Exit;
  1585. }
  1586. }
  1587. }
  1588. else {
  1589. pMetabase->DeleteData ( metabase.QueryHandle(), _T(""), MD_ADMIN_ACL, BINARY_METADATA );
  1590. }
  1591. }
  1592. // if ( m_bvChangedFields & CHNG_IPACCESS ) {
  1593. hr = m_pPrivateIpAccess->SendToMetabase ( &metabase );
  1594. BAIL_ON_FAILURE(hr);
  1595. // }
  1596. if ( !fRet ) {
  1597. hr = RETURNCODETOHRESULT ( GetLastError () );
  1598. goto Exit;
  1599. }
  1600. // Save the data to the metabase:
  1601. hr = metabase.Save ();
  1602. BAIL_ON_FAILURE(hr);
  1603. // Save the last changed time for this key:
  1604. m_ftLastChanged.dwHighDateTime = 0;
  1605. m_ftLastChanged.dwLowDateTime = 0;
  1606. hr = pMetabase->GetLastChangeTime ( metabase.QueryHandle(), _T(""), &m_ftLastChanged, FALSE );
  1607. if ( FAILED (hr) ) {
  1608. ErrorTraceX ( (LPARAM) this, "Failed to get last change time: %x", hr );
  1609. // Ignore this error.
  1610. hr = NOERROR;
  1611. }
  1612. Exit:
  1613. delete (char *) pSD;
  1614. TraceFunctLeave ();
  1615. return hr;
  1616. // MB automatically closes its handle
  1617. }
  1618. //$-------------------------------------------------------------------
  1619. //
  1620. // CNntpVirtualServer::ValidateStrings
  1621. //
  1622. // Description:
  1623. //
  1624. // Checks to make sure each string property is non-null.
  1625. //
  1626. // Returns:
  1627. //
  1628. // FALSE if any string property is NULL.
  1629. //
  1630. //--------------------------------------------------------------------
  1631. BOOL CNntpVirtualServer::ValidateStrings ( ) const
  1632. {
  1633. TraceFunctEnter ( "CNntpVirtualServer::ValidateStrings" );
  1634. // Check all property strings:
  1635. // If any string is NULL, return FALSE:
  1636. if (
  1637. !m_strSmtpServer ||
  1638. !m_strDefaultModeratorDomain ||
  1639. !m_strGroupHelpFile ||
  1640. !m_strGroupListFile ||
  1641. !m_strGroupVarListFile ||
  1642. !m_strArticleTableFile ||
  1643. !m_strHistoryTableFile ||
  1644. !m_strModeratorFile ||
  1645. !m_strXOverTableFile ||
  1646. !m_strUucpName ||
  1647. !m_strOrganization ||
  1648. !m_strComment ||
  1649. !m_strAnonymousUserName ||
  1650. !m_strAnonymousUserPass ||
  1651. !m_strPickupDirectory ||
  1652. !m_strFailedPickupDirectory
  1653. ) {
  1654. ErrorTrace ( (LPARAM) this, "String validation failed" );
  1655. TraceFunctLeave ();
  1656. return FALSE;
  1657. }
  1658. _ASSERT ( IS_VALID_STRING ( m_strSmtpServer ) );
  1659. _ASSERT ( IS_VALID_STRING ( m_strDefaultModeratorDomain ) );
  1660. _ASSERT ( IS_VALID_STRING ( m_strGroupHelpFile ) );
  1661. _ASSERT ( IS_VALID_STRING ( m_strGroupListFile ) );
  1662. _ASSERT ( IS_VALID_STRING ( m_strGroupVarListFile ) );
  1663. _ASSERT ( IS_VALID_STRING ( m_strArticleTableFile ) );
  1664. _ASSERT ( IS_VALID_STRING ( m_strHistoryTableFile ) );
  1665. _ASSERT ( IS_VALID_STRING ( m_strModeratorFile ) );
  1666. _ASSERT ( IS_VALID_STRING ( m_strXOverTableFile ) );
  1667. _ASSERT ( IS_VALID_STRING ( m_strUucpName ) );
  1668. _ASSERT ( IS_VALID_STRING ( m_strOrganization ) );
  1669. _ASSERT ( IS_VALID_STRING ( m_strComment ) );
  1670. _ASSERT ( IS_VALID_STRING ( m_strAnonymousUserName ) );
  1671. _ASSERT ( IS_VALID_STRING ( m_strAnonymousUserPass ) );
  1672. _ASSERT ( IS_VALID_STRING ( m_strPickupDirectory ) );
  1673. _ASSERT ( IS_VALID_STRING ( m_strFailedPickupDirectory ) );
  1674. TraceFunctLeave ();
  1675. return TRUE;
  1676. }
  1677. //$-------------------------------------------------------------------
  1678. //
  1679. // CNntpVirtualServer::ValidateProperties
  1680. //
  1681. // Description:
  1682. //
  1683. // Checks to make sure all parameters are valid.
  1684. //
  1685. // Parameters:
  1686. //
  1687. // pErr - resulting error code.
  1688. //
  1689. // Returns:
  1690. //
  1691. // FALSE if any property was not valid. In this case pErr
  1692. // will contain an error that describes the invalid condition.
  1693. //
  1694. //--------------------------------------------------------------------
  1695. BOOL CNntpVirtualServer::ValidateProperties ( ) const
  1696. {
  1697. BOOL fRet = TRUE;
  1698. _ASSERT ( ValidateStrings () );
  1699. fRet = fRet && PV_MinMax ( m_dwArticleTimeLimit, MIN_ARTICLETIMELIMIT, MAX_ARTICLETIMELIMIT );
  1700. fRet = fRet && PV_MinMax ( m_dwHistoryExpiration, MIN_HISTORYEXPIRATION, MAX_HISTORYEXPIRATION );
  1701. fRet = fRet && PV_Boolean ( m_fHonorClientMsgIDs );
  1702. fRet = fRet && PV_MaxChars ( m_strSmtpServer, MAXLEN_SMTPSERVER );
  1703. fRet = fRet && PV_Boolean ( m_fAllowClientPosts );
  1704. fRet = fRet && PV_Boolean ( m_fAllowFeedPosts );
  1705. fRet = fRet && PV_Boolean ( m_fAllowControlMsgs );
  1706. fRet = fRet && PV_MaxChars ( m_strDefaultModeratorDomain, MAXLEN_DEFAULTMODERATORDOMAIN );
  1707. fRet = fRet && PV_MinMax ( m_dwCommandLogMask, MIN_COMMANDLOGMASK, MAX_COMMANDLOGMASK );
  1708. fRet = fRet && PV_Boolean ( m_fDisableNewnews );
  1709. fRet = fRet && PV_MinMax ( m_dwExpireRunFrequency, MIN_NEWSCRAWLERTIME, MAX_NEWSCRAWLERTIME );
  1710. fRet = fRet && PV_MinMax ( m_dwShutdownLatency, MIN_SHUTDOWNLATENCY, MAX_SHUTDOWNLATENCY );
  1711. fRet = fRet && PV_Boolean ( m_fAutoStart );
  1712. fRet = fRet && PV_Boolean ( m_fClusterEnabled );
  1713. return fRet;
  1714. }
  1715. void CNntpVirtualServer::CorrectProperties ( )
  1716. {
  1717. if ( m_strServer && !PV_MaxChars ( m_strServer, MAXLEN_SERVER ) ) {
  1718. m_strServer[ MAXLEN_SERVER - 1 ] = NULL;
  1719. }
  1720. if ( !PV_MinMax ( m_dwArticleTimeLimit, MIN_ARTICLETIMELIMIT, MAX_ARTICLETIMELIMIT ) ) {
  1721. m_dwArticleTimeLimit = NNTP_DEF_ARTICLETIMELIMIT;
  1722. }
  1723. if ( !PV_MinMax ( m_dwHistoryExpiration, MIN_HISTORYEXPIRATION, MAX_HISTORYEXPIRATION ) ) {
  1724. m_dwHistoryExpiration = NNTP_DEF_HISTORYEXPIRATION;
  1725. }
  1726. if ( !PV_Boolean ( m_fHonorClientMsgIDs ) ) {
  1727. m_fHonorClientMsgIDs = !!m_fHonorClientMsgIDs;
  1728. }
  1729. if ( !PV_MaxChars ( m_strSmtpServer, MAXLEN_SMTPSERVER ) ) {
  1730. m_strSmtpServer[ MAXLEN_SMTPSERVER - 1 ] = NULL;
  1731. }
  1732. if ( !PV_Boolean ( m_fAllowClientPosts ) ) {
  1733. m_fAllowClientPosts = !!m_fAllowClientPosts;
  1734. }
  1735. if ( !PV_Boolean ( m_fAllowFeedPosts ) ) {
  1736. m_fAllowFeedPosts = !!m_fAllowFeedPosts;
  1737. }
  1738. if ( !PV_Boolean ( m_fAllowControlMsgs ) ) {
  1739. m_fAllowControlMsgs = !!m_fAllowControlMsgs;
  1740. }
  1741. if ( !PV_MaxChars ( m_strDefaultModeratorDomain, MAXLEN_DEFAULTMODERATORDOMAIN ) ) {
  1742. m_strDefaultModeratorDomain[ MAXLEN_DEFAULTMODERATORDOMAIN - 1] = NULL;
  1743. }
  1744. if ( !PV_MinMax ( m_dwCommandLogMask, MIN_COMMANDLOGMASK, MAX_COMMANDLOGMASK ) ) {
  1745. m_dwCommandLogMask = NNTP_DEF_COMMANDLOGMASK;
  1746. }
  1747. if ( !PV_Boolean ( m_fDisableNewnews ) ) {
  1748. m_fDisableNewnews = !!m_fDisableNewnews;
  1749. }
  1750. if ( !PV_MinMax ( m_dwExpireRunFrequency, MIN_NEWSCRAWLERTIME, MAX_NEWSCRAWLERTIME ) ) {
  1751. m_dwExpireRunFrequency = NNTP_DEF_NEWSCRAWLERTIME;
  1752. }
  1753. if ( !PV_MinMax ( m_dwShutdownLatency, MIN_SHUTDOWNLATENCY, MAX_SHUTDOWNLATENCY ) ) {
  1754. m_dwShutdownLatency = NNTP_DEF_SHUTDOWNLATENCY;
  1755. }
  1756. if ( !PV_Boolean ( m_fAutoStart ) ) {
  1757. m_fAutoStart = !!m_fAutoStart;
  1758. }
  1759. if ( !PV_Boolean ( m_fClusterEnabled ) ) {
  1760. m_fClusterEnabled = !!m_fClusterEnabled;
  1761. }
  1762. _ASSERT ( ValidateProperties ( ) );
  1763. }
  1764. NNTP_SERVER_STATE CNntpVirtualServer::TranslateServerState ( DWORD dwState )
  1765. {
  1766. NNTP_SERVER_STATE result = NNTP_SERVER_STATE_UNKNOWN;
  1767. switch ( dwState ) {
  1768. case MD_SERVER_STATE_STARTING:
  1769. result = NNTP_SERVER_STATE_STARTING;
  1770. break;
  1771. case MD_SERVER_STATE_STARTED:
  1772. result = NNTP_SERVER_STATE_STARTED;
  1773. break;
  1774. case MD_SERVER_STATE_STOPPING:
  1775. result = NNTP_SERVER_STATE_STOPPING;
  1776. break;
  1777. case MD_SERVER_STATE_STOPPED:
  1778. result = NNTP_SERVER_STATE_STOPPED;
  1779. break;
  1780. case MD_SERVER_STATE_PAUSING:
  1781. result = NNTP_SERVER_STATE_PAUSING;
  1782. break;
  1783. case MD_SERVER_STATE_PAUSED:
  1784. result = NNTP_SERVER_STATE_PAUSED;
  1785. break;
  1786. case MD_SERVER_STATE_CONTINUING:
  1787. result = NNTP_SERVER_STATE_CONTINUING;
  1788. break;
  1789. case MD_SERVER_STATE_INVALID:
  1790. result = NNTP_SERVER_STATE_UNKNOWN;
  1791. break;
  1792. default:
  1793. _ASSERT ( FALSE );
  1794. break;
  1795. }
  1796. return result;
  1797. }
  1798. HRESULT AclToAdministrators ( LPCTSTR strServer, PSECURITY_DESCRIPTOR pSDRelative, SAFEARRAY ** ppsaAdmins )
  1799. {
  1800. HRESULT hr = NOERROR;
  1801. SAFEARRAY * psaResult = NULL;
  1802. SAFEARRAYBOUND rgsaBound[1];
  1803. DWORD cbAcl;
  1804. long cValidAdmins;
  1805. long cAdmins;
  1806. long i;
  1807. long iValid;
  1808. PSECURITY_DESCRIPTOR pSD = NULL;
  1809. PACL pAcl;
  1810. BOOL fDaclPresent;
  1811. BOOL fDaclDef;
  1812. pSD = (PSECURITY_DESCRIPTOR)pSDRelative;
  1813. if (pSD == NULL)
  1814. {
  1815. //
  1816. // Empty...
  1817. //
  1818. return ERROR_SUCCESS;
  1819. }
  1820. if (!IsValidSecurityDescriptor(pSD))
  1821. {
  1822. return GetLastError();
  1823. }
  1824. _VERIFY(GetSecurityDescriptorDacl(pSD, &fDaclPresent, &pAcl, &fDaclDef));
  1825. if (!fDaclPresent || pAcl == NULL)
  1826. {
  1827. return ERROR_SUCCESS;
  1828. }
  1829. if (!IsValidAcl(pAcl))
  1830. {
  1831. return GetLastError();
  1832. }
  1833. cAdmins = pAcl->AceCount;
  1834. cbAcl = pAcl->AclSize;
  1835. //
  1836. // Count valid Acls:
  1837. //
  1838. for ( cValidAdmins = 0, i = 0; i < cAdmins; i++ ) {
  1839. PVOID pAce;
  1840. PACE_HEADER pAceHeader;
  1841. if ( GetAce(pAcl, i, &pAce) ) {
  1842. pAceHeader = (PACE_HEADER)pAce;
  1843. if ( pAceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE ) {
  1844. ACCESS_MASK AccessMask;
  1845. AccessMask = ((PACCESS_ALLOWED_ACE)pAce)->Mask;
  1846. if ( AccessMask & FILE_GENERIC_WRITE ) {
  1847. // Only count admins with write access.
  1848. cValidAdmins++;
  1849. }
  1850. }
  1851. }
  1852. }
  1853. rgsaBound[0].lLbound = 0;
  1854. rgsaBound[0].cElements = cValidAdmins;
  1855. psaResult = SafeArrayCreate ( VT_BSTR, 1, rgsaBound );
  1856. if ( !psaResult ) {
  1857. BAIL_WITH_FAILURE ( hr, E_OUTOFMEMORY );
  1858. }
  1859. for ( iValid = 0, i = 0; i < cAdmins; i++ ) {
  1860. PVOID pAce;
  1861. PACE_HEADER pAceHeader;
  1862. PSID pSID;
  1863. if ( GetAce(pAcl, i, &pAce) ) {
  1864. pAceHeader = (PACE_HEADER)pAce;
  1865. if ( pAceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE ) {
  1866. ACCESS_MASK AccessMask;
  1867. AccessMask = ((PACCESS_ALLOWED_ACE)pAce)->Mask;
  1868. if ( AccessMask & FILE_GENERIC_WRITE ) {
  1869. CComBSTR str;
  1870. pSID = (PSID)&((PACCESS_ALLOWED_ACE)pAce)->SidStart;
  1871. hr = SidToString ( strServer, pSID, &str );
  1872. BAIL_ON_FAILURE(hr);
  1873. hr = SafeArrayPutElement ( psaResult, &iValid, (PVOID) str );
  1874. BAIL_ON_FAILURE(hr);
  1875. iValid++;
  1876. }
  1877. }
  1878. }
  1879. }
  1880. if ( *ppsaAdmins ) {
  1881. SafeArrayDestroy ( *ppsaAdmins );
  1882. }
  1883. *ppsaAdmins = psaResult;
  1884. Exit:
  1885. return hr;
  1886. }
  1887. PSID
  1888. GetOwnerSID()
  1889. /*++
  1890. Routine Description:
  1891. Arguments:
  1892. Return Value:
  1893. Owner sid
  1894. --*/
  1895. {
  1896. PSID pSID = NULL;
  1897. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  1898. if (!AllocateAndInitializeSid(
  1899. &NtAuthority,
  1900. 2,
  1901. SECURITY_BUILTIN_DOMAIN_RID,
  1902. DOMAIN_ALIAS_RID_ADMINS,
  1903. 0, 0, 0, 0, 0, 0,
  1904. &pSID))
  1905. {
  1906. _ASSERT( 0 );
  1907. //TRACEEOLID("Unable to get primary SID " << ::GetLastError());
  1908. }
  1909. return pSID;
  1910. }
  1911. HRESULT AdministratorsToAcl (
  1912. LPCTSTR strServer,
  1913. SAFEARRAY * psaAdmins,
  1914. PSECURITY_DESCRIPTOR* ppSD,
  1915. DWORD * pcbSD
  1916. )
  1917. {
  1918. HRESULT hr = NOERROR;
  1919. long lBound;
  1920. long uBound;
  1921. long i;
  1922. BOOL fRet;
  1923. DWORD cbAcl;
  1924. PACL pAclResult = NULL;
  1925. PSID pSID;
  1926. *ppSD = NULL;
  1927. *pcbSD = 0;
  1928. if ( psaAdmins == NULL ) {
  1929. lBound = 0;
  1930. uBound = -1;
  1931. }
  1932. else {
  1933. SafeArrayGetLBound ( psaAdmins, 1, &lBound );
  1934. SafeArrayGetUBound ( psaAdmins, 1, &uBound );
  1935. }
  1936. // Do we have an array of Domain\Usernames?
  1937. if ( lBound > uBound ) {
  1938. // Nothing in the array, so the ACL is NULL.
  1939. goto Exit;
  1940. }
  1941. //
  1942. // Calculate ACL size:
  1943. //
  1944. cbAcl = sizeof (ACL);
  1945. for ( i = lBound; i <= uBound ; i++ ) {
  1946. CComBSTR str;
  1947. pSID = NULL;
  1948. SafeArrayGetElement ( psaAdmins, &i, &str );
  1949. hr = StringToSid ( strServer, str, &pSID );
  1950. if ( SUCCEEDED(hr) && IsValidSid(pSID)) {
  1951. cbAcl += GetLengthSid ( pSID );
  1952. cbAcl += sizeof ( ACCESS_ALLOWED_ACE );
  1953. cbAcl -= sizeof (DWORD);
  1954. }
  1955. hr = NOERROR;
  1956. delete pSID;
  1957. }
  1958. pAclResult = (PACL) new char [ cbAcl ];
  1959. if ( !pAclResult ) {
  1960. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  1961. }
  1962. fRet = InitializeAcl ( pAclResult, cbAcl, ACL_REVISION );
  1963. _ASSERT ( fRet );
  1964. if ( !fRet ) {
  1965. BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT(GetLastError() ) );
  1966. }
  1967. //
  1968. // Create ACL:
  1969. //
  1970. for ( i = lBound; i <= uBound; i++ ) {
  1971. CComBSTR str;
  1972. PSID pSID;
  1973. pSID = NULL;
  1974. SafeArrayGetElement ( psaAdmins, &i, &str );
  1975. hr = StringToSid ( strServer, str, &pSID );
  1976. if ( SUCCEEDED(hr) ) {
  1977. fRet = AddAccessAllowedAce (
  1978. pAclResult,
  1979. ACL_REVISION,
  1980. FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE,
  1981. pSID
  1982. );
  1983. if ( !fRet ) {
  1984. BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT(GetLastError() ) );
  1985. }
  1986. }
  1987. hr = NOERROR;
  1988. delete pSID;
  1989. }
  1990. //
  1991. // Build the security descriptor
  1992. //
  1993. PSECURITY_DESCRIPTOR pSD;
  1994. pSD = new char[SECURITY_DESCRIPTOR_MIN_LENGTH];
  1995. _VERIFY(InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION));
  1996. _VERIFY(SetSecurityDescriptorDacl(pSD, TRUE, pAclResult, FALSE));
  1997. //
  1998. // Set owner and primary group
  1999. //
  2000. pSID = GetOwnerSID();
  2001. _ASSERT(pSID);
  2002. _VERIFY(SetSecurityDescriptorOwner(pSD, pSID, TRUE));
  2003. _VERIFY(SetSecurityDescriptorGroup(pSD, pSID, TRUE));
  2004. //
  2005. // Convert to self-relative
  2006. //
  2007. PSECURITY_DESCRIPTOR pSDSelfRelative;
  2008. pSDSelfRelative = NULL;
  2009. DWORD dwSize;
  2010. dwSize = 0L;
  2011. MakeSelfRelativeSD(pSD, pSDSelfRelative, &dwSize);
  2012. pSDSelfRelative = new char[dwSize];
  2013. MakeSelfRelativeSD(pSD, pSDSelfRelative, &dwSize);
  2014. //
  2015. // Clean up
  2016. //
  2017. delete (char*)pSD;
  2018. FreeSid( pSID );
  2019. _ASSERT ( SUCCEEDED(hr) );
  2020. *ppSD = pSDSelfRelative;
  2021. *pcbSD = dwSize;
  2022. Exit:
  2023. if ( FAILED(hr) ) {
  2024. delete pAclResult;
  2025. }
  2026. return hr;
  2027. }
  2028. HRESULT SidToString ( LPCWSTR strSystemName, PSID pSID, BSTR * pStr )
  2029. {
  2030. HRESULT hr = NOERROR;
  2031. BOOL fLookup;
  2032. SID_NAME_USE SidToNameUse;
  2033. WCHAR wszUsername [ PATHLEN ];
  2034. DWORD cbUsername = sizeof ( wszUsername );
  2035. WCHAR wszDomain [ PATHLEN ];
  2036. DWORD cbDomain = sizeof ( wszDomain );
  2037. WCHAR wszResult [ 2 * PATHLEN + 2 ];
  2038. LPWSTR pwszSid = NULL;
  2039. fLookup = LookupAccountSid (
  2040. strSystemName,
  2041. pSID,
  2042. wszUsername,
  2043. &cbUsername,
  2044. wszDomain,
  2045. &cbDomain,
  2046. &SidToNameUse
  2047. );
  2048. if ( !fLookup && GetLastError() != ERROR_NONE_MAPPED) {
  2049. BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT (GetLastError ()) );
  2050. }
  2051. if (fLookup) {
  2052. wsprintf ( wszResult, _T("%s\\%s"), wszDomain, wszUsername );
  2053. } else {
  2054. // Couldn't get the username. Convert it to a string of the form .\S-1-5-xxx
  2055. if (!ConvertSidToStringSid(pSID, &pwszSid)) {
  2056. BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT (GetLastError ()) );
  2057. }
  2058. wsprintf(wszResult, _T(".\\%s"), pwszSid);
  2059. }
  2060. *pStr = ::SysAllocString ( wszResult );
  2061. if (*pStr == NULL)
  2062. hr = E_OUTOFMEMORY;
  2063. Exit:
  2064. if (pwszSid) {
  2065. LocalFree(pwszSid);
  2066. }
  2067. return hr;
  2068. }
  2069. HRESULT StringToSid ( LPCWSTR strSystemName, LPWSTR str, PSID * ppSID )
  2070. {
  2071. HRESULT hr = NOERROR;
  2072. BOOL fLookup;
  2073. WCHAR wszRefDomain[PATHLEN];
  2074. DWORD cbRefDomain = sizeof ( wszRefDomain );
  2075. DWORD cbSid = 0;
  2076. SID_NAME_USE SidNameUse;
  2077. BOOL fIsSID = FALSE;
  2078. PSID pSID = NULL;
  2079. *ppSID = NULL;
  2080. //
  2081. // If the string starts with .\, then a SID follows rather than a domain\user
  2082. //
  2083. if (str[0] == L'.' && str[1] == L'\\') {
  2084. fIsSID = TRUE;
  2085. str+=2;
  2086. }
  2087. if ( str[0] == '\\' ) {
  2088. //
  2089. // Skip the initial \, this is for BUILTIN usernames:
  2090. //
  2091. str++;
  2092. }
  2093. _ASSERT ( str[0] != '\\' );
  2094. if (fIsSID) {
  2095. if (!ConvertStringSidToSid(str, &pSID))
  2096. BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT(GetLastError()));
  2097. cbSid = GetLengthSid(pSID);
  2098. *ppSID = (LPVOID) new char [ cbSid ];
  2099. if ( !*ppSID ) {
  2100. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  2101. }
  2102. memcpy(*ppSID, pSID, cbSid);
  2103. } else {
  2104. fLookup = LookupAccountName (
  2105. strSystemName,
  2106. str,
  2107. *ppSID,
  2108. &cbSid,
  2109. wszRefDomain,
  2110. &cbRefDomain,
  2111. &SidNameUse
  2112. );
  2113. // First lookup will fail, but the size will be right:
  2114. if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) {
  2115. BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT ( GetLastError () ) );
  2116. }
  2117. *ppSID = (LPVOID) new char [ cbSid ];
  2118. if ( !*ppSID ) {
  2119. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  2120. }
  2121. fLookup = LookupAccountName (
  2122. strSystemName,
  2123. str,
  2124. *ppSID,
  2125. &cbSid,
  2126. wszRefDomain,
  2127. &cbRefDomain,
  2128. &SidNameUse
  2129. );
  2130. }
  2131. if ( !fLookup ) {
  2132. BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT ( GetLastError () ) );
  2133. }
  2134. Exit:
  2135. if (pSID) {
  2136. LocalFree(pSID);
  2137. }
  2138. return hr;
  2139. }