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.

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