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.

2329 lines
63 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. admin.cxx
  5. Abstract:
  6. This module contains code for doing admin rpcs
  7. Author:
  8. Todd Christensen (ToddCh) 28-Apr-1996
  9. Revision History:
  10. Rohan Phillips (Rohanp) - enabled virtual server support 4-Feb-1997
  11. --*/
  12. #define INCL_INETSRV_INCS
  13. #include "smtpinc.h"
  14. #include "smtpsvc.h"
  15. #include "smtpcli.hxx"
  16. #include "admin.hxx"
  17. // Address validation lib (KeithLau 7/28/96)
  18. #include "address.hxx"
  19. #include "findiis.hxx"
  20. #include <stdio.h>
  21. #include <malloc.h>
  22. //
  23. // Quick and dirty string validation
  24. //
  25. static inline BOOL pValidateStringPtr(LPWSTR lpwszString, DWORD dwMaxLength)
  26. {
  27. if (IsBadStringPtr((LPCTSTR)lpwszString, dwMaxLength))
  28. return(FALSE);
  29. while (dwMaxLength--)
  30. if (*lpwszString++ == 0)
  31. return(TRUE);
  32. return(FALSE);
  33. }
  34. //
  35. // Quick and dirty range check using inlines
  36. //
  37. static inline BOOL pValidateRange(DWORD dwValue, DWORD dwLower, DWORD dwUpper)
  38. {
  39. // Inclusive
  40. if ((dwValue >= dwLower) && (dwValue <= dwUpper))
  41. return(TRUE);
  42. SetLastError(ERROR_INVALID_PARAMETER);
  43. return(FALSE);
  44. }
  45. NET_API_STATUS
  46. NET_API_FUNCTION
  47. SmtprGetAdminInformation(
  48. IN LPWSTR pszServer OPTIONAL,
  49. OUT LPSMTP_CONFIG_INFO * ppConfig,
  50. IN DWORD dwInstance
  51. )
  52. /*++
  53. Description
  54. Retrieves the admin information
  55. Arguments:
  56. pszServer - unused
  57. ppConfig - Receives pointer to admin information
  58. Note:
  59. --*/
  60. {
  61. SMTP_CONFIG_INFO * pConfig;
  62. PSMTP_SERVER_INSTANCE pInstance;
  63. DWORD err = NO_ERROR;
  64. if(g_IsShuttingDown)
  65. {
  66. return ERROR_SHUTDOWN_IN_PROGRESS;
  67. }
  68. if (IsBadWritePtr((LPVOID)ppConfig, sizeof(LPSMTP_CONFIG_INFO)))
  69. return(ERROR_INVALID_PARAMETER);
  70. // In case we exit on an error...
  71. *ppConfig = NULL;
  72. if ( err = TsApiAccessCheck( TCP_QUERY_ADMIN_INFORMATION ))
  73. return err;
  74. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  75. if(pInstance == NULL)
  76. {
  77. return(ERROR_INVALID_PARAMETER);
  78. }
  79. if (!ConvertSmtpConfigToRpc(&pConfig, pInstance))
  80. {
  81. err = GetLastError();
  82. goto exit;
  83. }
  84. if (!ConvertSmtpRoutingListToRpc(&(pConfig->RoutingList), pInstance))
  85. {
  86. FreeRpcSmtpConfig(pConfig);
  87. err = GetLastError();
  88. goto exit;
  89. }
  90. *ppConfig = pConfig;
  91. exit:
  92. pInstance->Dereference();
  93. return err;
  94. }
  95. NET_API_STATUS
  96. NET_API_FUNCTION
  97. SmtprSetAdminInformation(
  98. IN LPWSTR pszServer OPTIONAL,
  99. IN SMTP_CONFIG_INFO * pConfig,
  100. IN DWORD dwInstance
  101. )
  102. /*++
  103. Description
  104. Sets the common service admin information for the servers specified
  105. in dwServerMask.
  106. Arguments:
  107. pszServer - unused
  108. pConfig - Admin information to set
  109. Note:
  110. --*/
  111. {
  112. PSMTP_SERVER_INSTANCE pInstance;
  113. if (IsBadReadPtr((LPVOID)pConfig, sizeof(SMTP_CONFIG_INFO)))
  114. return(ERROR_INVALID_PARAMETER);
  115. if(g_IsShuttingDown)
  116. {
  117. return ERROR_SHUTDOWN_IN_PROGRESS;
  118. }
  119. DWORD err;
  120. if ( err = TsApiAccessCheck( TCP_SET_ADMIN_INFORMATION ))
  121. return err;
  122. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  123. if(pInstance != NULL)
  124. {
  125. // raid 129712 - we treat this case the same as before.
  126. if ( !(pInstance->WriteRegParams(pConfig)) ||
  127. !(pInstance->ReadRegParams(pConfig->FieldControl, TRUE)))
  128. {
  129. pInstance->Dereference();
  130. return GetLastError();
  131. }
  132. pInstance->Dereference();
  133. return NO_ERROR;
  134. }
  135. return ERROR_INVALID_DATA;
  136. }
  137. //+---------------------------------------------------------------
  138. //
  139. // Function: ConvertSmtpConfigToRpc
  140. //
  141. // Synopsis: Moves config values into the RPC structure
  142. //
  143. // Arguments: LPSMTP_CONFIG_INFO *: structure to be filled with
  144. // configuration data.
  145. //
  146. // Returns: BOOL - TRUE on SUCCESS, FALSE on FAIL
  147. //
  148. //----------------------------------------------------------------
  149. BOOL ConvertSmtpConfigToRpc(LPSMTP_CONFIG_INFO *ppConfig, PSMTP_SERVER_INSTANCE pInstance)
  150. {
  151. SetLastError(ERROR_INVALID_PARAMETER);
  152. return FALSE;
  153. }
  154. void FreeRpcSmtpConfig(LPSMTP_CONFIG_INFO pConfig)
  155. {
  156. if (pConfig)
  157. {
  158. if (pConfig->lpszSmartHostName)
  159. FreeRpcString(pConfig->lpszSmartHostName);
  160. if (pConfig->lpszConnectResp)
  161. FreeRpcString(pConfig->lpszConnectResp);
  162. if (pConfig->lpszBadMailDir)
  163. FreeRpcString(pConfig->lpszBadMailDir);
  164. if (pConfig->RoutingList)
  165. FreeRpcSmtpRoutingList(pConfig->RoutingList);
  166. MIDL_user_free(pConfig);
  167. }
  168. }
  169. BOOL ConvertSmtpRoutingListToRpc(LPSMTP_CONFIG_ROUTING_LIST *ppRoutingList, PSMTP_SERVER_INSTANCE pInstance)
  170. {
  171. #if 0
  172. LPSMTP_CONFIG_ROUTING_LIST pRoutingList;
  173. DWORD dwErr;
  174. DWORD iSource;
  175. DWORD cSources = 0;
  176. DWORD cbAlloc;
  177. PLIST_ENTRY pEntry;
  178. PLIST_ENTRY pHead;
  179. cSources = pInstance->GetRoutingSourceCount();
  180. cbAlloc = sizeof(SMTP_CONFIG_ROUTING_LIST) + cSources * sizeof(SMTP_CONFIG_ROUTING_ENTRY);
  181. pRoutingList = (LPSMTP_CONFIG_ROUTING_LIST) MIDL_user_allocate(cbAlloc);
  182. if (!pRoutingList)
  183. {
  184. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  185. return FALSE;
  186. }
  187. ZeroMemory(pRoutingList, cbAlloc);
  188. pRoutingList->cEntries = cSources;
  189. pHead = pInstance->GetRoutingSourceList();
  190. for (pEntry = pHead->Flink, iSource = 0 ; pEntry != pHead ; pEntry = pEntry->Flink, iSource++)
  191. {
  192. if (!ConvertStringToRpc(&(pRoutingList->aRoutingEntry[iSource].lpszSource),
  193. CONTAINING_RECORD(pEntry, ABSOURCE, list)->szConfig))
  194. {
  195. dwErr = GetLastError();
  196. for (iSource = 0 ; iSource < cSources ; iSource++)
  197. {
  198. if (pRoutingList->aRoutingEntry[iSource].lpszSource)
  199. FreeRpcString(pRoutingList->aRoutingEntry[iSource].lpszSource);
  200. }
  201. MIDL_user_free(pRoutingList);
  202. SetLastError(dwErr);
  203. return FALSE;
  204. }
  205. }
  206. *ppRoutingList = pRoutingList;
  207. #endif
  208. return FALSE;
  209. }
  210. void FreeRpcSmtpRoutingList(LPSMTP_CONFIG_ROUTING_LIST pRoutingList)
  211. {
  212. DWORD iSource;
  213. if (pRoutingList)
  214. {
  215. for (iSource = 0 ; iSource < pRoutingList->cEntries ; iSource++)
  216. {
  217. if (pRoutingList->aRoutingEntry[iSource].lpszSource)
  218. FreeRpcString(pRoutingList->aRoutingEntry[iSource].lpszSource);
  219. }
  220. MIDL_user_free(pRoutingList);
  221. }
  222. }
  223. NET_API_STATUS
  224. NET_API_FUNCTION
  225. SmtprGetConnectedUserList(
  226. IN LPWSTR pszServer OPTIONAL,
  227. OUT LPSMTP_CONN_USER_LIST *ppConnUserList,
  228. IN DWORD dwInstance
  229. )
  230. /*++
  231. Description
  232. Retrieves the connected user list
  233. Arguments:
  234. pszServer - unused
  235. ppConnUserList - Receives pointer to admin information
  236. Note:
  237. --*/
  238. {
  239. SMTP_CONN_USER_LIST *pConnUserList;
  240. SMTP_CONN_USER_ENTRY *pConnEntry;
  241. DWORD dwErr;
  242. PLIST_ENTRY pleHead;
  243. PLIST_ENTRY pleT;
  244. SMTP_CONNECTION *pConn;
  245. DWORD iEntry;
  246. DWORD NumUsers = 0;
  247. PSMTP_SERVER_INSTANCE pInstance;
  248. // In case we exit on an error...
  249. *ppConnUserList = NULL;
  250. if(g_IsShuttingDown)
  251. {
  252. return ERROR_SHUTDOWN_IN_PROGRESS;
  253. }
  254. if (IsBadWritePtr((LPVOID)ppConnUserList, sizeof(LPSMTP_CONN_USER_LIST)))
  255. return(ERROR_INVALID_PARAMETER);
  256. if (dwErr = TsApiAccessCheck( TCP_QUERY_ADMIN_INFORMATION))
  257. return dwErr;
  258. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  259. if(pInstance == NULL)
  260. {
  261. return(ERROR_INVALID_PARAMETER);
  262. }
  263. pInstance->LockConfig();
  264. //loop through the list to get the count of all connected users.
  265. //These are users whose sockets are not equal to INVALID_SOCKET
  266. pleHead = pInstance->GetConnectionList();
  267. for (pleT = pleHead->Flink ; pleT != pleHead ; pleT = pleT->Flink)
  268. {
  269. pConn = CONTAINING_RECORD(pleT, SMTP_CONNECTION, m_listEntry);
  270. if(pConn->QueryClientSocket() != INVALID_SOCKET)
  271. {
  272. NumUsers++;
  273. }
  274. }
  275. pConnUserList = (SMTP_CONN_USER_LIST *)MIDL_user_allocate(sizeof(SMTP_CONN_USER_LIST) +
  276. sizeof(SMTP_CONN_USER_ENTRY) * NumUsers);
  277. if (!pConnUserList)
  278. {
  279. pInstance->UnLockConfig();
  280. pInstance->Dereference();
  281. return ERROR_NOT_ENOUGH_MEMORY;
  282. }
  283. pConnUserList->cEntries = NumUsers;
  284. pConnEntry = pConnUserList->aConnUserEntry;
  285. ZeroMemory(pConnEntry, sizeof(SMTP_CONN_USER_ENTRY) * pConnUserList->cEntries);
  286. pleHead = pInstance->GetConnectionList();
  287. for (pleT = pleHead->Flink ; pleT != pleHead ; pleT = pleT->Flink)
  288. {
  289. pConn = CONTAINING_RECORD(pleT, SMTP_CONNECTION, m_listEntry);
  290. //disregard anyone whose socket is invalid
  291. if(pConn->QueryClientSocket() == INVALID_SOCKET)
  292. continue;
  293. pConnEntry->dwUserId = pConn->QueryClientId();
  294. pConnEntry->dwConnectTime = pConn->QuerySessionTime();
  295. if (pConn->QueryClientUserName())
  296. {
  297. if (!ConvertStringToRpc(&(pConnEntry->lpszName), pConn->QueryClientUserName()))
  298. {
  299. pInstance->UnLockConfig();
  300. pConnEntry = pConnUserList->aConnUserEntry;
  301. for (iEntry = 0 ; iEntry < pConnUserList->cEntries ; iEntry++, pConnEntry++)
  302. {
  303. if (pConnEntry->lpszName)
  304. FreeRpcString(pConnEntry->lpszName);
  305. if (pConnEntry->lpszHost)
  306. FreeRpcString(pConnEntry->lpszHost);
  307. }
  308. MIDL_user_free(pConnUserList);
  309. pInstance->Dereference();
  310. return ERROR_NOT_ENOUGH_MEMORY;
  311. }
  312. }
  313. if (pConn->QueryClientHostName())
  314. {
  315. if (!ConvertStringToRpc(&(pConnEntry->lpszHost), pConn->QueryClientHostName()))
  316. {
  317. pInstance->UnLockConfig();
  318. pConnEntry = pConnUserList->aConnUserEntry;
  319. for (iEntry = 0 ; iEntry < pConnUserList->cEntries ; iEntry++, pConnEntry++)
  320. {
  321. if (pConnEntry->lpszName)
  322. FreeRpcString(pConnEntry->lpszName);
  323. if (pConnEntry->lpszHost)
  324. FreeRpcString(pConnEntry->lpszHost);
  325. }
  326. MIDL_user_free(pConnUserList);
  327. pInstance->Dereference();
  328. return ERROR_NOT_ENOUGH_MEMORY;
  329. }
  330. }
  331. pConnEntry++;
  332. }
  333. pInstance->UnLockConfig();
  334. *ppConnUserList = pConnUserList;
  335. pInstance->Dereference();
  336. return NO_ERROR;
  337. }
  338. NET_API_STATUS
  339. NET_API_FUNCTION
  340. SmtprDisconnectUser(
  341. IN LPWSTR pszServer OPTIONAL,
  342. IN DWORD dwUserId,
  343. IN DWORD dwInstance
  344. )
  345. /*++
  346. Description
  347. Disconnects the specified user
  348. Arguments:
  349. pszServer - unused
  350. dwUserId - user to disconnect
  351. Note:
  352. --*/
  353. {
  354. DWORD dwErr;
  355. PLIST_ENTRY pleHead;
  356. PLIST_ENTRY pleT;
  357. SMTP_CONNECTION *pConn;
  358. PSMTP_SERVER_INSTANCE pInstance;
  359. if(g_IsShuttingDown)
  360. {
  361. return ERROR_SHUTDOWN_IN_PROGRESS;
  362. }
  363. if (dwErr = TsApiAccessCheck( TCP_QUERY_ADMIN_INFORMATION))
  364. return dwErr;
  365. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  366. if(pInstance == NULL)
  367. {
  368. return(ERROR_INVALID_PARAMETER);
  369. }
  370. pInstance->LockConfig();
  371. pleHead = pInstance->GetConnectionList();
  372. for (pleT = pleHead->Flink ; pleT != pleHead ; pleT = pleT->Flink)
  373. {
  374. pConn = CONTAINING_RECORD(pleT, SMTP_CONNECTION, m_listEntry);
  375. if (pConn->QueryClientId() == dwUserId)
  376. {
  377. pConn->DisconnectClient();
  378. pInstance->UnLockConfig();
  379. pInstance->Dereference();
  380. return NO_ERROR;
  381. }
  382. }
  383. pInstance->UnLockConfig();
  384. pInstance->Dereference();
  385. return ERROR_NO_SUCH_USER;
  386. }
  387. /*++
  388. Description:
  389. Adds a user
  390. Note:
  391. --*/
  392. NET_API_STATUS
  393. NET_API_FUNCTION
  394. SmtprCreateUser(
  395. IN LPWSTR wszServer,
  396. IN LPWSTR wszEmail,
  397. IN LPWSTR wszForwardEmail,
  398. IN DWORD dwLocal,
  399. IN DWORD dwMailboxSize,
  400. IN DWORD dwMailboxMessageSize,
  401. IN LPWSTR wszVRoot,
  402. IN DWORD dwInstance
  403. )
  404. {
  405. DWORD dwErr;
  406. LPSTR szEmail;
  407. LPSTR szForward = NULL;
  408. LPSTR szVRoot = NULL;
  409. HANDLE hToken;
  410. DWORD cbRoot;
  411. char szRoot[MAX_PATH + 1];
  412. PSMTP_SERVER_INSTANCE pInstance;
  413. TraceFunctEnter("SmtprCreateUser");
  414. if(g_IsShuttingDown)
  415. {
  416. TraceFunctLeave();
  417. return ERROR_SHUTDOWN_IN_PROGRESS;
  418. }
  419. if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  420. return(ERROR_INVALID_PARAMETER);
  421. if (wszForwardEmail &&
  422. !pValidateStringPtr(wszForwardEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  423. return(ERROR_INVALID_PARAMETER);
  424. if (wszVRoot &&
  425. !pValidateStringPtr(wszVRoot, AB_MAX_VROOT))
  426. return(ERROR_INVALID_PARAMETER);
  427. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  428. if(pInstance == NULL)
  429. {
  430. TraceFunctLeave();
  431. return(ERROR_INVALID_PARAMETER);
  432. }
  433. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  434. if (dwErr != NO_ERROR)
  435. {
  436. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  437. pInstance->Dereference();
  438. TraceFunctLeave();
  439. return dwErr;
  440. }
  441. DebugTrace(NULL, "Email name: %ls", wszEmail);
  442. szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
  443. if (!szEmail)
  444. {
  445. dwErr = GetLastError();
  446. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %u", wszEmail, dwErr);
  447. pInstance->Dereference();
  448. TraceFunctLeave();
  449. return dwErr;
  450. }
  451. DebugTrace(NULL, "Forward: %ls", wszForwardEmail ? wszForwardEmail : L"<NULL>");
  452. if (wszForwardEmail)
  453. {
  454. szForward = ConvertUnicodeToAnsi(wszForwardEmail, NULL, 0);
  455. if (!szForward)
  456. {
  457. dwErr = GetLastError();
  458. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %u", wszForwardEmail, dwErr);
  459. TCP_FREE(szEmail);
  460. pInstance->Dereference();
  461. TraceFunctLeave();
  462. return dwErr;
  463. }
  464. }
  465. // Parameter checking
  466. if (!CAddr::ValidateEmailName(szEmail)) // Note: ANSI version
  467. {
  468. ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
  469. (wszEmail)?wszEmail:L"NULL");
  470. if (szForward)
  471. TCP_FREE(szForward);
  472. TCP_FREE(szEmail);
  473. pInstance->Dereference();
  474. TraceFunctLeave();
  475. return(ERROR_INVALID_PARAMETER);
  476. }
  477. if (wszForwardEmail)
  478. if (!CAddr::ValidateEmailName(szForward)) // Note: ANSI version
  479. {
  480. ErrorTrace(NULL, "Invalid parameter: wszForwardEmail (%ls)\n",
  481. (wszForwardEmail)?wszForwardEmail:L"NULL");
  482. if (szForward)
  483. TCP_FREE(szForward);
  484. TCP_FREE(szEmail);
  485. pInstance->Dereference();
  486. TraceFunctLeave();
  487. return(ERROR_INVALID_PARAMETER);
  488. }
  489. if (!pValidateRange(dwLocal, 0, 1))
  490. {
  491. ErrorTrace(NULL, "Invalid parameter: dwLocal (%u)\n",
  492. dwLocal);
  493. if (szForward)
  494. TCP_FREE(szForward);
  495. TCP_FREE(szEmail);
  496. pInstance->Dereference();
  497. TraceFunctLeave();
  498. return(ERROR_INVALID_PARAMETER);
  499. }
  500. // VRoot is checked downstream
  501. DebugTrace(NULL, "Create mailbox: %s", dwLocal ? "TRUE" : "FALSE");
  502. if (dwLocal)
  503. {
  504. DebugTrace(NULL, "VRoot: %ls", wszVRoot ? wszVRoot : L"<NULL>");
  505. if (wszVRoot)
  506. {
  507. szVRoot = ConvertUnicodeToAnsi(wszVRoot, NULL, 0);
  508. if (!szVRoot)
  509. {
  510. dwErr = GetLastError();
  511. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %u", wszVRoot, dwErr);
  512. if (szForward)
  513. TCP_FREE(szForward);
  514. TCP_FREE(szEmail);
  515. pInstance->Dereference();
  516. TraceFunctLeave();
  517. return dwErr;
  518. }
  519. DWORD dwAccessMask = 0;
  520. // Parameter checking for valid vroot
  521. cbRoot = sizeof(szRoot);
  522. if(!pInstance->QueryVrootTable()->LookupVirtualRoot(
  523. szVRoot, szRoot, &cbRoot, &dwAccessMask, NULL, NULL,
  524. &hToken, NULL))
  525. {
  526. dwErr = GetLastError();
  527. ErrorTrace(NULL, "Unable to resolve virtual root(%ls): %u", wszVRoot, dwErr);
  528. if (szForward)
  529. TCP_FREE(szForward);
  530. TCP_FREE(szEmail);
  531. TCP_FREE(szVRoot);
  532. pInstance->Dereference();
  533. TraceFunctLeave();
  534. return dwErr;
  535. }
  536. }
  537. else
  538. {
  539. szVRoot = (LPSTR)TCP_ALLOC(MAX_PATH);
  540. if (!szVRoot)
  541. {
  542. ErrorTrace(NULL, "Allocation failed");
  543. if (szForward)
  544. TCP_FREE(szForward);
  545. TCP_FREE(szEmail);
  546. pInstance->Dereference();
  547. TraceFunctLeave();
  548. return ERROR_NOT_ENOUGH_MEMORY;
  549. }
  550. if (!pInstance->FindBestVRoot(szVRoot))
  551. {
  552. dwErr = GetLastError();
  553. ErrorTrace(NULL, "Unable to FindBestVRoot: %u", dwErr);
  554. if (szForward)
  555. TCP_FREE(szForward);
  556. TCP_FREE(szEmail);
  557. pInstance->Dereference();
  558. TraceFunctLeave();
  559. return dwErr;
  560. }
  561. }
  562. }
  563. /*
  564. if (!pInstance->PRtx()->CreateUser(szEmail, szForward, dwLocal, szVRoot, dwMailboxSize, dwMailboxMessageSize))
  565. {
  566. dwErr = GetLastError();
  567. ErrorTrace(NULL, "Unable to create user %s: %u", szEmail, dwErr);
  568. if (szVRoot)
  569. TCP_FREE(szVRoot);
  570. if (szForward)
  571. TCP_FREE(szForward);
  572. TCP_FREE(szEmail);
  573. pInstance->Dereference();
  574. TraceFunctLeave();
  575. return dwErr;
  576. }
  577. */
  578. if (szVRoot)
  579. TCP_FREE(szVRoot);
  580. if (szForward)
  581. TCP_FREE(szForward);
  582. TCP_FREE(szEmail);
  583. pInstance->Dereference();
  584. TraceFunctLeave();
  585. return NO_ERROR;
  586. }
  587. /*++
  588. Description:
  589. Deletes a user
  590. Note:
  591. --*/
  592. NET_API_STATUS
  593. NET_API_FUNCTION
  594. SmtprDeleteUser(
  595. IN LPWSTR wszServer,
  596. IN LPWSTR wszEmail,
  597. IN DWORD dwInstance
  598. )
  599. {
  600. DWORD dwErr;
  601. LPSTR szEmail;
  602. PSMTP_SERVER_INSTANCE pInstance;
  603. TraceFunctEnter("SmtprDeleteUser");
  604. if(g_IsShuttingDown)
  605. {
  606. TraceFunctLeave();
  607. return ERROR_SHUTDOWN_IN_PROGRESS;
  608. }
  609. if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  610. {
  611. TraceFunctLeave();
  612. return(ERROR_INVALID_PARAMETER);
  613. }
  614. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  615. if(pInstance == NULL)
  616. {
  617. TraceFunctLeave();
  618. return(ERROR_INVALID_PARAMETER);
  619. }
  620. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  621. if (dwErr != NO_ERROR)
  622. {
  623. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  624. pInstance->Dereference();
  625. TraceFunctLeave();
  626. return dwErr;
  627. }
  628. DebugTrace(NULL, "Email name: %ls", wszEmail);
  629. szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
  630. if (!szEmail)
  631. {
  632. dwErr = GetLastError();
  633. TCP_FREE(szEmail);
  634. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
  635. pInstance->Dereference();
  636. TraceFunctLeave();
  637. return dwErr;
  638. }
  639. // Parameter checking
  640. if (!CAddr::ValidateEmailName(szEmail))
  641. {
  642. ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
  643. (wszEmail)?wszEmail:L"NULL");
  644. TCP_FREE(szEmail);
  645. pInstance->Dereference();
  646. TraceFunctLeave();
  647. return(ERROR_INVALID_PARAMETER);
  648. }
  649. /*
  650. if (!pInstance->PRtx()->DeleteUser(szEmail))
  651. {
  652. dwErr = GetLastError();
  653. ErrorTrace(NULL, "Unable to delete user %s: %d", szEmail, dwErr);
  654. TCP_FREE(szEmail);
  655. pInstance->Dereference();
  656. TraceFunctLeave();
  657. return dwErr;
  658. }
  659. */
  660. TCP_FREE(szEmail);
  661. pInstance->Dereference();
  662. TraceFunctLeave();
  663. return NO_ERROR;
  664. }
  665. /*++
  666. Description:
  667. Gets user properties
  668. Note:
  669. --*/
  670. NET_API_STATUS
  671. NET_API_FUNCTION
  672. SmtprGetUserProps(
  673. IN LPWSTR wszServer,
  674. IN LPWSTR wszEmail,
  675. OUT LPSMTP_USER_PROPS *ppUserProps,
  676. IN DWORD dwInstance
  677. )
  678. {
  679. #if 0
  680. LPSTR szEmail;
  681. DWORD dwErr;
  682. LPSMTP_USER_PROPS pUserProps;
  683. RTX_USER_PROPS rtxuserprops;
  684. PSMTP_SERVER_INSTANCE pInstance;
  685. TraceFunctEnter("SmtprGetUserProps");
  686. if(g_IsShuttingDown)
  687. {
  688. return ERROR_SHUTDOWN_IN_PROGRESS;
  689. }
  690. if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  691. return(ERROR_INVALID_PARAMETER);
  692. if (IsBadWritePtr((LPVOID)ppUserProps, sizeof(LPSMTP_USER_PROPS)))
  693. return(ERROR_INVALID_PARAMETER);
  694. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  695. if(pInstance == NULL)
  696. {
  697. return(ERROR_INVALID_PARAMETER);
  698. }
  699. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  700. if (dwErr != NO_ERROR)
  701. {
  702. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  703. pInstance->Dereference();
  704. return dwErr;
  705. }
  706. szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
  707. if (!szEmail)
  708. {
  709. dwErr = GetLastError();
  710. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
  711. pInstance->Dereference();
  712. TraceFunctLeave();
  713. return dwErr;
  714. }
  715. // Parameter checking
  716. if (!CAddr::ValidateEmailName(szEmail))
  717. {
  718. ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
  719. (wszEmail)?wszEmail:L"NULL");
  720. TCP_FREE(szEmail);
  721. pInstance->Dereference();
  722. TraceFunctLeave();
  723. return(ERROR_INVALID_PARAMETER);
  724. }
  725. if (!pInstance->PRtx()->GetUserProps(szEmail, &rtxuserprops))
  726. {
  727. ErrorTrace(NULL, "GetUserProps call failed: %u", GetLastError());
  728. TCP_FREE(szEmail);
  729. pInstance->Dereference();
  730. return GetLastError();
  731. }
  732. TCP_FREE(szEmail);
  733. pUserProps = (LPSMTP_USER_PROPS) MIDL_user_allocate(sizeof(SMTP_USER_PROPS));
  734. if (!ConvertStringToRpc(&(pUserProps->wszForward), rtxuserprops.szForward))
  735. {
  736. ErrorTrace(NULL, "Unable to convert forward to rpc string: %u", GetLastError());
  737. MIDL_user_free(pUserProps);
  738. pInstance->Dereference();
  739. return GetLastError();
  740. }
  741. if (!ConvertStringToRpc(&(pUserProps->wszVRoot), rtxuserprops.szVRoot))
  742. {
  743. ErrorTrace(NULL, "Unable to convert vroot to rpc string: %u", GetLastError());
  744. FreeRpcString(pUserProps->wszForward);
  745. MIDL_user_free(pUserProps);
  746. pInstance->Dereference();
  747. return GetLastError();
  748. }
  749. pUserProps->dwMailboxMax = rtxuserprops.cbMailBoxSize;
  750. pUserProps->dwMailboxMessageMax = rtxuserprops.cbMailboxMessageSize;
  751. pUserProps->dwLocal = rtxuserprops.fLocal;
  752. pUserProps->fc = FC_SMTP_USER_PROPS_ALL;
  753. *ppUserProps = pUserProps;
  754. pInstance->Dereference();
  755. TraceFunctLeave();
  756. return NO_ERROR;
  757. #endif
  758. return ERROR_INVALID_PARAMETER;
  759. }
  760. /*++
  761. Description:
  762. Sets a users properties
  763. Note:
  764. --*/
  765. NET_API_STATUS
  766. NET_API_FUNCTION
  767. SmtprSetUserProps(
  768. IN LPWSTR wszServer,
  769. IN LPWSTR wszEmail,
  770. IN LPSMTP_USER_PROPS pUserProps,
  771. IN DWORD dwInstance
  772. )
  773. {
  774. #if 0
  775. DWORD dwErr;
  776. DWORD dwErrKeep = NO_ERROR;
  777. LPSTR szEmail = NULL;
  778. LPSTR szForward = NULL;
  779. LPSTR szVRoot = NULL;
  780. HANDLE hToken;
  781. DWORD cbRoot;
  782. char szRoot[MAX_PATH + 1];
  783. BOOL fSet;
  784. PSMTP_SERVER_INSTANCE pInstance;
  785. TraceFunctEnter("SmtprSetUserProps");
  786. if(g_IsShuttingDown)
  787. {
  788. return ERROR_SHUTDOWN_IN_PROGRESS;
  789. }
  790. if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  791. return(ERROR_INVALID_PARAMETER);
  792. if (IsBadReadPtr((LPVOID)pUserProps, sizeof(SMTP_USER_PROPS)))
  793. return(ERROR_INVALID_PARAMETER);
  794. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  795. if(pInstance == NULL)
  796. {
  797. return(ERROR_INVALID_PARAMETER);
  798. }
  799. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  800. if (dwErr != NO_ERROR)
  801. {
  802. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  803. pInstance->Dereference();
  804. return dwErr;
  805. }
  806. if (!pUserProps->fc)
  807. {
  808. // Nothing to do...
  809. pInstance->Dereference();
  810. return NO_ERROR;
  811. }
  812. DebugTrace(NULL, "Email name: %ls", wszEmail);
  813. szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
  814. if (!szEmail)
  815. {
  816. dwErr = GetLastError();
  817. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
  818. pInstance->Dereference();
  819. TraceFunctLeave();
  820. return dwErr;
  821. }
  822. // Parameter checking
  823. if (!CAddr::ValidateEmailName(szEmail))
  824. {
  825. ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
  826. (wszEmail)?wszEmail:L"NULL");
  827. TCP_FREE(szEmail);
  828. pInstance->Dereference();
  829. TraceFunctLeave();
  830. return(ERROR_INVALID_PARAMETER);
  831. }
  832. if (!pUserProps)
  833. {
  834. ErrorTrace(NULL, "Invalid parameter: pUserProps (NULL)\n");
  835. TCP_FREE(szEmail);
  836. pInstance->Dereference();
  837. TraceFunctLeave();
  838. return(ERROR_INVALID_PARAMETER);
  839. }
  840. // More checking downstream ...
  841. if (IsFieldSet(pUserProps->fc, FC_SMTP_USER_PROPS_FORWARD))
  842. {
  843. fSet = TRUE;
  844. if (pUserProps->wszForward)
  845. {
  846. szForward = ConvertUnicodeToAnsi(pUserProps->wszForward, NULL, 0);
  847. if (!szForward)
  848. {
  849. dwErr = GetLastError();
  850. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", pUserProps->wszForward, dwErr);
  851. if (dwErrKeep == NO_ERROR)
  852. dwErrKeep = dwErr;
  853. fSet = FALSE;
  854. }
  855. }
  856. else
  857. {
  858. szForward = NULL;
  859. }
  860. // Parameter check for forward
  861. if (szForward &&
  862. !CAddr::ValidateEmailName(szForward))
  863. {
  864. ErrorTrace(NULL, "Invalid parameter: pconfig->pUserProps->wszForward (%s)\n",
  865. (pUserProps->wszForward)?pUserProps->wszForward:L"NULL");
  866. if (dwErrKeep == NO_ERROR)
  867. dwErrKeep = ERROR_INVALID_PARAMETER;
  868. fSet = FALSE;
  869. }
  870. if (fSet)
  871. {
  872. if (!pInstance->PRtx()->SetForward(szEmail, szForward))
  873. {
  874. dwErr = GetLastError();
  875. ErrorTrace(NULL, "Unable to set forward for %s: %d", szEmail, dwErr);
  876. if (dwErrKeep == NO_ERROR)
  877. dwErrKeep = dwErr;
  878. }
  879. }
  880. }
  881. if (IsFieldSet(pUserProps->fc, FC_SMTP_USER_PROPS_MAILBOX_SIZE))
  882. {
  883. if (!pInstance->PRtx()->SetMailboxSize(szEmail, pUserProps->dwMailboxMax))
  884. {
  885. dwErr = GetLastError();
  886. ErrorTrace(NULL, "Unable to set mailbox size for %s: %d", szEmail, dwErr);
  887. if (dwErrKeep == NO_ERROR)
  888. dwErrKeep = dwErr;
  889. }
  890. }
  891. if (IsFieldSet(pUserProps->fc, FC_SMTP_USER_PROPS_MAILBOX_MESSAGE_SIZE))
  892. {
  893. if (!pInstance->PRtx()->SetMailboxMessageSize(szEmail, pUserProps->dwMailboxMessageMax))
  894. {
  895. dwErr = GetLastError();
  896. ErrorTrace(NULL, "Unable to set mailbox size for %s: %d", szEmail, dwErr);
  897. if (dwErrKeep == NO_ERROR)
  898. dwErrKeep = dwErr;
  899. }
  900. }
  901. if (IsFieldSet(pUserProps->fc, FC_SMTP_USER_PROPS_VROOT))
  902. {
  903. fSet = TRUE;
  904. szVRoot = ConvertUnicodeToAnsi(pUserProps->wszVRoot, NULL, 0);
  905. if (!szVRoot)
  906. {
  907. dwErr = GetLastError();
  908. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", pUserProps->wszVRoot, dwErr);
  909. if (dwErrKeep == NO_ERROR)
  910. dwErrKeep = dwErr;
  911. fSet = FALSE;
  912. }
  913. DWORD dwAccessMask = 0;
  914. // Parameter checking for VRoot
  915. cbRoot = sizeof(szRoot);
  916. if(!pInstance->QueryVrootTable()->LookupVirtualRoot(
  917. szVRoot, szRoot, &cbRoot, &dwAccessMask, NULL, NULL,
  918. &hToken, NULL))
  919. {
  920. dwErr = GetLastError();
  921. ErrorTrace(NULL, "Unable to resolve virtual root(%ls): %u", pUserProps->wszVRoot, dwErr);
  922. if (dwErrKeep == NO_ERROR)
  923. dwErrKeep = dwErr;
  924. fSet = FALSE;
  925. }
  926. if (fSet)
  927. {
  928. if (!pInstance->PRtx()->SetVRoot(szEmail, szVRoot))
  929. {
  930. dwErr = GetLastError();
  931. ErrorTrace(NULL, "Unable to set vroot for %s: %d", szEmail, dwErr);
  932. if (dwErrKeep == NO_ERROR)
  933. dwErrKeep = dwErr;
  934. }
  935. }
  936. }
  937. if (szVRoot)
  938. TCP_FREE(szVRoot);
  939. if (szForward)
  940. TCP_FREE(szForward);
  941. TCP_FREE(szEmail);
  942. pInstance->Dereference();
  943. TraceFunctLeave();
  944. return dwErrKeep;
  945. #endif
  946. return ERROR_INVALID_PARAMETER;
  947. }
  948. /*++
  949. Description:
  950. Creates a DL
  951. Note:
  952. --*/
  953. NET_API_STATUS
  954. NET_API_FUNCTION
  955. SmtprCreateDistList(
  956. IN LPWSTR wszServer,
  957. IN LPWSTR wszEmail,
  958. IN DWORD dwType,
  959. IN DWORD dwInstance
  960. )
  961. {
  962. #if 0
  963. DWORD dwErr;
  964. LPSTR szEmail;
  965. DWORD dwRtxType;
  966. PSMTP_SERVER_INSTANCE pInstance;
  967. TraceFunctEnter("SmtprCreateDistList");
  968. if(g_IsShuttingDown)
  969. {
  970. TraceFunctLeave();
  971. return ERROR_SHUTDOWN_IN_PROGRESS;
  972. }
  973. if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  974. {
  975. TraceFunctLeave();
  976. return(ERROR_INVALID_PARAMETER);
  977. }
  978. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  979. if(pInstance == NULL)
  980. {
  981. TraceFunctLeave();
  982. return(ERROR_INVALID_PARAMETER);
  983. }
  984. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  985. if (dwErr != NO_ERROR)
  986. {
  987. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  988. pInstance->Dereference();
  989. TraceFunctLeave();
  990. return dwErr;
  991. }
  992. if (dwType == NAME_TYPE_LIST_NORMAL)
  993. dwRtxType = rtxnameDistListNormal;
  994. else if (dwType == NAME_TYPE_LIST_SITE)
  995. dwRtxType = rtxnameDistListSite;
  996. else if (dwType == NAME_TYPE_LIST_DOMAIN)
  997. dwRtxType = rtxnameDistListDomain;
  998. else
  999. {
  1000. ErrorTrace(NULL, "TYPE is not NAME_TYPE_LIST_NORMAL or NAME_TYPE_LIST_SITE");
  1001. pInstance->Dereference();
  1002. TraceFunctLeave();
  1003. return ERROR_INVALID_PARAMETER;
  1004. }
  1005. DebugTrace(NULL, "Email name: %ls", wszEmail);
  1006. szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
  1007. if (!szEmail)
  1008. {
  1009. dwErr = GetLastError();
  1010. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
  1011. pInstance->Dereference();
  1012. TraceFunctLeave();
  1013. return dwErr;
  1014. }
  1015. // Parameter check
  1016. if (!CAddr::ValidateEmailName(szEmail))
  1017. {
  1018. ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
  1019. (wszEmail)?wszEmail:L"NULL");
  1020. TCP_FREE(szEmail);
  1021. pInstance->Dereference();
  1022. TraceFunctLeave();
  1023. return(ERROR_INVALID_PARAMETER);
  1024. }
  1025. if (!pInstance->PRtx()->CreateDistList(szEmail, dwRtxType))
  1026. {
  1027. dwErr = GetLastError();
  1028. ErrorTrace(NULL, "Unable to create list %s: %d", szEmail, dwErr);
  1029. TCP_FREE(szEmail);
  1030. pInstance->Dereference();
  1031. TraceFunctLeave();
  1032. return dwErr;
  1033. }
  1034. TCP_FREE(szEmail);
  1035. pInstance->Dereference();
  1036. TraceFunctLeave();
  1037. return NO_ERROR;
  1038. #endif
  1039. return ERROR_INVALID_PARAMETER;
  1040. }
  1041. /*++
  1042. Description:
  1043. Deletes a DL
  1044. Note:
  1045. --*/
  1046. NET_API_STATUS
  1047. NET_API_FUNCTION
  1048. SmtprDeleteDistList(
  1049. IN LPWSTR wszServer,
  1050. IN LPWSTR wszEmail,
  1051. IN DWORD dwInstance
  1052. )
  1053. {
  1054. DWORD dwErr;
  1055. LPSTR szEmail;
  1056. PSMTP_SERVER_INSTANCE pInstance;
  1057. TraceFunctEnter("SmtprDeleteDistList");
  1058. if(g_IsShuttingDown)
  1059. {
  1060. return ERROR_SHUTDOWN_IN_PROGRESS;
  1061. }
  1062. if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  1063. return(ERROR_INVALID_PARAMETER);
  1064. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  1065. if(pInstance == NULL)
  1066. {
  1067. return(ERROR_INVALID_PARAMETER);
  1068. }
  1069. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  1070. if (dwErr != NO_ERROR)
  1071. {
  1072. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  1073. pInstance->Dereference();
  1074. return dwErr;
  1075. }
  1076. DebugTrace(NULL, "Email name: %ls", wszEmail);
  1077. szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
  1078. if (!szEmail)
  1079. {
  1080. dwErr = GetLastError();
  1081. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
  1082. pInstance->Dereference();
  1083. TraceFunctLeave();
  1084. return dwErr;
  1085. }
  1086. // Parameter check
  1087. if (!CAddr::ValidateEmailName(szEmail))
  1088. {
  1089. ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
  1090. (wszEmail)?wszEmail:L"NULL");
  1091. TCP_FREE(szEmail);
  1092. pInstance->Dereference();
  1093. TraceFunctLeave();
  1094. return(ERROR_INVALID_PARAMETER);
  1095. }
  1096. #if 0
  1097. if (!pInstance->PRtx()->DeleteDistList(szEmail))
  1098. {
  1099. dwErr = GetLastError();
  1100. ErrorTrace(NULL, "Unable to delete list %s: %d", szEmail, dwErr);
  1101. TCP_FREE(szEmail);
  1102. pInstance->Dereference();
  1103. TraceFunctLeave();
  1104. return dwErr;
  1105. }
  1106. #endif
  1107. TCP_FREE(szEmail);
  1108. pInstance->Dereference();
  1109. TraceFunctLeave();
  1110. return NO_ERROR;
  1111. }
  1112. /*++
  1113. Description:
  1114. Adds a member to the DL
  1115. Note:
  1116. --*/
  1117. NET_API_STATUS
  1118. NET_API_FUNCTION
  1119. SmtprCreateDistListMember(
  1120. IN LPWSTR wszServer,
  1121. IN LPWSTR wszEmail,
  1122. IN LPWSTR wszEmailMember,
  1123. IN DWORD dwInstance
  1124. )
  1125. {
  1126. DWORD dwErr;
  1127. LPSTR szEmail;
  1128. LPSTR szMember;
  1129. PSMTP_SERVER_INSTANCE pInstance;
  1130. TraceFunctEnter("SmtprCreateDistListMember");
  1131. if(g_IsShuttingDown)
  1132. {
  1133. return ERROR_SHUTDOWN_IN_PROGRESS;
  1134. }
  1135. if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  1136. return(ERROR_INVALID_PARAMETER);
  1137. if (!pValidateStringPtr(wszEmailMember, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  1138. return(ERROR_INVALID_PARAMETER);
  1139. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  1140. if(pInstance == NULL)
  1141. {
  1142. return(ERROR_INVALID_PARAMETER);
  1143. }
  1144. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  1145. if (dwErr != NO_ERROR)
  1146. {
  1147. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  1148. pInstance->Dereference();
  1149. return dwErr;
  1150. }
  1151. DebugTrace(NULL, "Email name: %ls", wszEmail);
  1152. szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
  1153. if (!szEmail)
  1154. {
  1155. dwErr = GetLastError();
  1156. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
  1157. pInstance->Dereference();
  1158. TraceFunctLeave();
  1159. return dwErr;
  1160. }
  1161. szMember = ConvertUnicodeToAnsi(wszEmailMember, NULL, 0);
  1162. if (!szMember)
  1163. {
  1164. dwErr = GetLastError();
  1165. TCP_FREE(szEmail);
  1166. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmailMember, dwErr);
  1167. pInstance->Dereference();
  1168. TraceFunctLeave();
  1169. return dwErr;
  1170. }
  1171. // Parameter check
  1172. if (!CAddr::ValidateEmailName(szEmail))
  1173. {
  1174. ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
  1175. (wszEmail)?wszEmail:L"NULL");
  1176. TCP_FREE(szMember);
  1177. TCP_FREE(szEmail);
  1178. pInstance->Dereference();
  1179. TraceFunctLeave();
  1180. return(ERROR_INVALID_PARAMETER);
  1181. }
  1182. if (!CAddr::ValidateEmailName(szMember))
  1183. {
  1184. ErrorTrace(NULL, "Invalid parameter: wszEmailMember (%ls)\n",
  1185. (wszEmailMember)?wszEmailMember:L"NULL");
  1186. TCP_FREE(szMember);
  1187. TCP_FREE(szEmail);
  1188. pInstance->Dereference();
  1189. TraceFunctLeave();
  1190. return(ERROR_INVALID_PARAMETER);
  1191. }
  1192. #if 0
  1193. if (!pInstance->PRtx()->CreateDistListMember(szEmail, szMember))
  1194. {
  1195. dwErr = GetLastError();
  1196. ErrorTrace(NULL, "Unable to add member %s to %s: %d", szMember, szEmail, dwErr);
  1197. TCP_FREE(szMember);
  1198. TCP_FREE(szEmail);
  1199. pInstance->Dereference();
  1200. TraceFunctLeave();
  1201. return dwErr;
  1202. }
  1203. #endif
  1204. TCP_FREE(szMember);
  1205. TCP_FREE(szEmail);
  1206. pInstance->Dereference();
  1207. TraceFunctLeave();
  1208. return NO_ERROR;
  1209. }
  1210. /*++
  1211. Description:
  1212. Deletes a member from the DL
  1213. Note:
  1214. --*/
  1215. NET_API_STATUS
  1216. NET_API_FUNCTION
  1217. SmtprDeleteDistListMember(
  1218. IN LPWSTR wszServer,
  1219. IN LPWSTR wszEmail,
  1220. IN LPWSTR wszEmailMember,
  1221. IN DWORD dwInstance
  1222. )
  1223. {
  1224. DWORD dwErr;
  1225. LPSTR szEmail;
  1226. LPSTR szMember;
  1227. PSMTP_SERVER_INSTANCE pInstance;
  1228. TraceFunctEnter("SmtprDeleteDistListMember");
  1229. if(g_IsShuttingDown)
  1230. {
  1231. return ERROR_SHUTDOWN_IN_PROGRESS;
  1232. }
  1233. if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  1234. return(ERROR_INVALID_PARAMETER);
  1235. if (!pValidateStringPtr(wszEmailMember, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  1236. return(ERROR_INVALID_PARAMETER);
  1237. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  1238. if(pInstance == NULL)
  1239. {
  1240. return(ERROR_INVALID_PARAMETER);
  1241. }
  1242. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  1243. if (dwErr != NO_ERROR)
  1244. {
  1245. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  1246. pInstance->Dereference();
  1247. return dwErr;
  1248. }
  1249. DebugTrace(NULL, "Email name: %ls", wszEmail);
  1250. szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
  1251. if (!szEmail)
  1252. {
  1253. dwErr = GetLastError();
  1254. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
  1255. pInstance->Dereference();
  1256. TraceFunctLeave();
  1257. return dwErr;
  1258. }
  1259. szMember = ConvertUnicodeToAnsi(wszEmailMember, NULL, 0);
  1260. if (!szMember)
  1261. {
  1262. dwErr = GetLastError();
  1263. TCP_FREE(szEmail);
  1264. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmailMember, dwErr);
  1265. pInstance->Dereference();
  1266. TraceFunctLeave();
  1267. return dwErr;
  1268. }
  1269. // Parameter check
  1270. if (!CAddr::ValidateEmailName(szEmail))
  1271. {
  1272. ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
  1273. (wszEmail)?wszEmail:L"NULL");
  1274. TCP_FREE(szMember);
  1275. TCP_FREE(szEmail);
  1276. pInstance->Dereference();
  1277. TraceFunctLeave();
  1278. return(ERROR_INVALID_PARAMETER);
  1279. }
  1280. if (!CAddr::ValidateEmailName(szMember))
  1281. {
  1282. ErrorTrace(NULL, "Invalid parameter: wszEmailMember (%ls)\n",
  1283. (wszEmailMember)?wszEmailMember:L"NULL");
  1284. TCP_FREE(szMember);
  1285. TCP_FREE(szEmail);
  1286. pInstance->Dereference();
  1287. TraceFunctLeave();
  1288. return(ERROR_INVALID_PARAMETER);
  1289. }
  1290. #if 0
  1291. if (!pInstance->PRtx()->DeleteDistListMember(szEmail, szMember))
  1292. {
  1293. dwErr = GetLastError();
  1294. ErrorTrace(NULL, "Unable to delete member %s from %s: %d", szMember, szEmail, dwErr);
  1295. TCP_FREE(szMember);
  1296. TCP_FREE(szEmail);
  1297. pInstance->Dereference();
  1298. TraceFunctLeave();
  1299. return dwErr;
  1300. }
  1301. #endif
  1302. TCP_FREE(szMember);
  1303. TCP_FREE(szEmail);
  1304. pInstance->Dereference();
  1305. TraceFunctLeave();
  1306. return NO_ERROR;
  1307. }
  1308. /*++
  1309. Description:
  1310. Sets DL properties
  1311. Note:
  1312. --*/
  1313. NET_API_STATUS
  1314. NET_API_FUNCTION
  1315. SmtprGetNameList(
  1316. IN LPWSTR wszServer,
  1317. IN LPWSTR wszEmail,
  1318. IN DWORD dwType,
  1319. IN DWORD dwRowsReq,
  1320. IN BOOL fForward,
  1321. OUT LPSMTP_NAME_LIST *ppNameList,
  1322. IN DWORD dwInstance
  1323. )
  1324. {
  1325. #if 0
  1326. DWORD dwErr;
  1327. HRTXENUM hrtxenum;
  1328. LPSTR szEmail;
  1329. DWORD crowsReturned;
  1330. DWORD cbAlloc;
  1331. DWORD irows;
  1332. LPSMTP_NAME_LIST pNameList;
  1333. DWORD dwFlags;
  1334. DWORD cbNameEntry;
  1335. char szName[cbEmailNameMax];
  1336. PSMTP_SERVER_INSTANCE pInstance;
  1337. TraceFunctEnter("SmtprGetNameList");
  1338. if(g_IsShuttingDown)
  1339. {
  1340. return ERROR_SHUTDOWN_IN_PROGRESS;
  1341. }
  1342. if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  1343. return(ERROR_INVALID_PARAMETER);
  1344. if (IsBadWritePtr((LPVOID)ppNameList, sizeof(LPSMTP_NAME_LIST)))
  1345. return(ERROR_INVALID_PARAMETER);
  1346. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  1347. if(pInstance == NULL)
  1348. {
  1349. return(ERROR_INVALID_PARAMETER);
  1350. }
  1351. *ppNameList = NULL;
  1352. // Up front parameter check
  1353. if (!pValidateRange(dwType, 1,15))
  1354. {
  1355. ErrorTrace(NULL, "Invalid parameter: dwType (%u)\n",
  1356. dwType);
  1357. pInstance->Dereference();
  1358. TraceFunctLeave();
  1359. return(ERROR_INVALID_PARAMETER);
  1360. }
  1361. if (!pValidateRange(dwRowsReq, 1, 100))
  1362. {
  1363. ErrorTrace(NULL, "Invalid parameter: dwRowsReq (%u)\n",
  1364. dwRowsReq);
  1365. pInstance->Dereference();
  1366. TraceFunctLeave();
  1367. return(ERROR_INVALID_PARAMETER);
  1368. }
  1369. if (!pValidateRange(fForward, 0, 1))
  1370. {
  1371. ErrorTrace(NULL, "Invalid parameter: fForward (%u)\n",
  1372. fForward);
  1373. pInstance->Dereference();
  1374. TraceFunctLeave();
  1375. return(ERROR_INVALID_PARAMETER);
  1376. }
  1377. if (!ppNameList)
  1378. {
  1379. ErrorTrace(NULL, "Invalid parameter: ppNameList (NULL)\n");
  1380. pInstance->Dereference();
  1381. TraceFunctLeave();
  1382. return(ERROR_INVALID_PARAMETER);
  1383. }
  1384. // More checks downstream
  1385. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  1386. if (dwErr != NO_ERROR)
  1387. {
  1388. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  1389. pInstance->Dereference();
  1390. return dwErr;
  1391. }
  1392. DebugTrace(NULL, "Email name: %ls", wszEmail);
  1393. szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
  1394. if (!szEmail)
  1395. {
  1396. dwErr = GetLastError();
  1397. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
  1398. pInstance->Dereference();
  1399. TraceFunctLeave();
  1400. return dwErr;
  1401. }
  1402. // Parameter change
  1403. if (szEmail[0] != 0 &&
  1404. szEmail[0] != '@' &&
  1405. !CAddr::ValidateEmailName(szEmail, TRUE))
  1406. {
  1407. ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
  1408. (wszEmail)?wszEmail:L"NULL");
  1409. TCP_FREE(szEmail);
  1410. pInstance->Dereference();
  1411. TraceFunctLeave();
  1412. return(ERROR_INVALID_PARAMETER);
  1413. }
  1414. dwFlags = 0;
  1415. if (dwType & NAME_TYPE_USER)
  1416. dwFlags |= rtxnameUser;
  1417. if (dwType & NAME_TYPE_LIST_NORMAL)
  1418. dwFlags |= rtxnameDistListNormal;
  1419. if (dwType & NAME_TYPE_LIST_SITE)
  1420. dwFlags |= rtxnameDistListSite;
  1421. if (dwType & NAME_TYPE_LIST_DOMAIN)
  1422. dwFlags |= rtxnameDistListDomain;
  1423. if (!pInstance->PRtx()->EnumNameList(szEmail, fForward, dwRowsReq, dwFlags, &hrtxenum))
  1424. {
  1425. dwErr = GetLastError();
  1426. ErrorTrace(NULL, "Unable to enum name list: %d", dwErr);
  1427. TCP_FREE(szEmail);
  1428. pInstance->Dereference();
  1429. TraceFunctLeave();
  1430. return dwErr;
  1431. }
  1432. TCP_FREE(szEmail);
  1433. crowsReturned = pInstance->PRtx()->EnumRowsReturned(hrtxenum);
  1434. cbAlloc = sizeof(SMTP_NAME_LIST) + crowsReturned * sizeof(SMTP_NAME_ENTRY);
  1435. pNameList = (LPSMTP_NAME_LIST)MIDL_user_allocate(cbAlloc);
  1436. ZeroMemory(pNameList, cbAlloc);
  1437. pNameList->cEntries = crowsReturned;
  1438. for (irows = 0 ; irows < crowsReturned ; irows++)
  1439. {
  1440. cbNameEntry = cbEmailNameMax;
  1441. if (!pInstance->PRtx()->GetNextEmail(hrtxenum, &(dwFlags),
  1442. szName))
  1443. {
  1444. dwErr = GetLastError();
  1445. _VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
  1446. _VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
  1447. for (irows = 0 ; irows < crowsReturned ; irows++)
  1448. {
  1449. if (pNameList->aNameEntry[irows].lpszName)
  1450. FreeRpcString(pNameList->aNameEntry[irows].lpszName);
  1451. }
  1452. MIDL_user_free(pNameList);
  1453. ErrorTrace(NULL, "GetNext failed on row %u: %u", irows, dwErr);
  1454. pInstance->Dereference();
  1455. return dwErr;
  1456. }
  1457. if (dwFlags & rtxnameUser)
  1458. pNameList->aNameEntry[irows].dwType = NAME_TYPE_USER;
  1459. if (dwFlags & rtxnameDistListNormal)
  1460. pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_NORMAL;
  1461. if (dwFlags & rtxnameDistListSite)
  1462. pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_SITE;
  1463. if (dwFlags & rtxnameDistListDomain)
  1464. pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_DOMAIN;
  1465. if (!ConvertStringToRpc(&(pNameList->aNameEntry[irows].lpszName), szName))
  1466. {
  1467. dwErr = GetLastError();
  1468. _VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
  1469. _VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
  1470. for (irows = 0 ; irows < crowsReturned ; irows++)
  1471. {
  1472. if (pNameList->aNameEntry[irows].lpszName)
  1473. FreeRpcString(pNameList->aNameEntry[irows].lpszName);
  1474. }
  1475. MIDL_user_free(pNameList);
  1476. ErrorTrace(NULL, "Unable to convert %s to RPC string: %u", szName, dwErr);
  1477. pInstance->Dereference();
  1478. return dwErr;
  1479. }
  1480. }
  1481. _VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
  1482. _VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
  1483. *ppNameList = pNameList;
  1484. pInstance->Dereference();
  1485. TraceFunctLeave();
  1486. return NO_ERROR;
  1487. #endif
  1488. return ERROR_INVALID_PARAMETER;
  1489. }
  1490. NET_API_STATUS
  1491. NET_API_FUNCTION
  1492. SmtprGetNameListFromList(
  1493. IN SMTP_HANDLE wszServerName,
  1494. IN LPWSTR wszEmailList,
  1495. IN LPWSTR wszEmail,
  1496. IN DWORD dwType,
  1497. IN DWORD dwRowsRequested,
  1498. IN BOOL fForward,
  1499. OUT LPSMTP_NAME_LIST *ppNameList,
  1500. IN DWORD dwInstance
  1501. )
  1502. /*++
  1503. Description
  1504. Performs a search within a list
  1505. Arguments:
  1506. wszServer - unused
  1507. wszEmailList - Email list to search from
  1508. wszEmail - Email name to search for
  1509. dwType - Type of the Email name supplied
  1510. dwRowsRequested - Number of rows requested
  1511. fForward -
  1512. ppNameList - pointer to pointer to name list to return
  1513. Note:
  1514. This RPC is added by Keith Lau (keithlau) on 7/5/96
  1515. --*/
  1516. {
  1517. #if 0
  1518. DWORD dwErr;
  1519. HRTXENUM hrtxenum;
  1520. LPSTR szEmail;
  1521. LPSTR szEmailList;
  1522. DWORD crowsReturned;
  1523. DWORD cbAlloc;
  1524. DWORD irows;
  1525. LPSMTP_NAME_LIST pNameList;
  1526. DWORD dwFlags;
  1527. DWORD cbNameEntry;
  1528. char szName[cbEmailNameMax];
  1529. PSMTP_SERVER_INSTANCE pInstance;
  1530. TraceFunctEnter("SmtprGetNameListFromList");
  1531. if(g_IsShuttingDown)
  1532. {
  1533. return ERROR_SHUTDOWN_IN_PROGRESS;
  1534. }
  1535. if (!pValidateStringPtr(wszEmailList, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  1536. return(ERROR_INVALID_PARAMETER);
  1537. if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
  1538. return(ERROR_INVALID_PARAMETER);
  1539. if (IsBadWritePtr((LPVOID)ppNameList, sizeof(LPSMTP_NAME_LIST)))
  1540. return(ERROR_INVALID_PARAMETER);
  1541. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  1542. if(pInstance == NULL)
  1543. {
  1544. return(ERROR_INVALID_PARAMETER);
  1545. }
  1546. *ppNameList = NULL;
  1547. if (!pValidateRange(dwType, 1, 15))
  1548. {
  1549. ErrorTrace(NULL, "Invalid parameter: dwType (%u)\n",
  1550. dwType);
  1551. pInstance->Dereference();
  1552. TraceFunctLeave();
  1553. return(ERROR_INVALID_PARAMETER);
  1554. }
  1555. if (!pValidateRange(dwRowsRequested, 1, 100))
  1556. {
  1557. ErrorTrace(NULL, "Invalid parameter: dwRowsRequested (%u)\n",
  1558. dwRowsRequested);
  1559. pInstance->Dereference();
  1560. TraceFunctLeave();
  1561. return(ERROR_INVALID_PARAMETER);
  1562. }
  1563. if (!pValidateRange(fForward, 0, 1))
  1564. {
  1565. ErrorTrace(NULL, "Invalid parameter: fForward (%u)\n",
  1566. fForward);
  1567. pInstance->Dereference();
  1568. TraceFunctLeave();
  1569. return(ERROR_INVALID_PARAMETER);
  1570. }
  1571. if (!ppNameList)
  1572. {
  1573. ErrorTrace(NULL, "Invalid parameter: ppNameList (NULL)\n");
  1574. pInstance->Dereference();
  1575. TraceFunctLeave();
  1576. return(ERROR_INVALID_PARAMETER);
  1577. }
  1578. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  1579. if (dwErr != NO_ERROR)
  1580. {
  1581. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  1582. pInstance->Dereference();
  1583. return dwErr;
  1584. }
  1585. DebugTrace(NULL, "Email list name: %ls", wszEmailList);
  1586. szEmailList = ConvertUnicodeToAnsi(wszEmailList, NULL, 0);
  1587. if (!szEmailList)
  1588. {
  1589. dwErr = GetLastError();
  1590. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d",
  1591. wszEmailList, dwErr);
  1592. pInstance->Dereference();
  1593. TraceFunctLeave();
  1594. return dwErr;
  1595. }
  1596. if (!CAddr::ValidateEmailName(szEmailList))
  1597. {
  1598. ErrorTrace(NULL, "Invalid parameter: wszEmailList (%ls)\n",
  1599. (wszEmailList)?wszEmailList:L"NULL");
  1600. TCP_FREE(szEmailList);
  1601. pInstance->Dereference();
  1602. TraceFunctLeave();
  1603. return(ERROR_INVALID_PARAMETER);
  1604. }
  1605. DebugTrace(NULL, "Email name: %ls", wszEmail);
  1606. szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
  1607. if (!szEmail)
  1608. {
  1609. dwErr = GetLastError();
  1610. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d",
  1611. wszEmail, dwErr);
  1612. TCP_FREE(szEmailList);
  1613. pInstance->Dereference();
  1614. TraceFunctLeave();
  1615. return dwErr;
  1616. }
  1617. if (szEmail[0] != 0 &&
  1618. szEmail[0] != '@' &&
  1619. !CAddr::ValidateEmailName(szEmail, TRUE))
  1620. {
  1621. ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
  1622. (wszEmail)?wszEmail:L"NULL");
  1623. TCP_FREE(szEmail);
  1624. TCP_FREE(szEmailList);
  1625. pInstance->Dereference();
  1626. TraceFunctLeave();
  1627. return(ERROR_INVALID_PARAMETER);
  1628. }
  1629. dwFlags = 0;
  1630. if (dwType & NAME_TYPE_USER)
  1631. dwFlags |= rtxnameUser;
  1632. if (dwType & NAME_TYPE_LIST_NORMAL)
  1633. dwFlags |= rtxnameDistListNormal;
  1634. if (dwType & NAME_TYPE_LIST_SITE)
  1635. dwFlags |= rtxnameDistListSite;
  1636. if (dwType & NAME_TYPE_LIST_DOMAIN)
  1637. dwFlags |= rtxnameDistListDomain;
  1638. if (!pInstance->PRtx()->EnumNameListFromDL(szEmailList,
  1639. szEmail,
  1640. fForward,
  1641. dwRowsRequested,
  1642. dwFlags,
  1643. &hrtxenum))
  1644. {
  1645. dwErr = GetLastError();
  1646. ErrorTrace(NULL, "Unable to enum name list: %d", dwErr);
  1647. TCP_FREE(szEmailList);
  1648. TCP_FREE(szEmail);
  1649. pInstance->Dereference();
  1650. TraceFunctLeave();
  1651. return dwErr;
  1652. }
  1653. TCP_FREE(szEmailList);
  1654. TCP_FREE(szEmail);
  1655. crowsReturned = pInstance->PRtx()->EnumRowsReturned(hrtxenum);
  1656. cbAlloc = sizeof(SMTP_NAME_LIST) + crowsReturned * sizeof(SMTP_NAME_ENTRY);
  1657. pNameList = (LPSMTP_NAME_LIST)MIDL_user_allocate(cbAlloc);
  1658. ZeroMemory(pNameList, cbAlloc);
  1659. pNameList->cEntries = crowsReturned;
  1660. for (irows = 0 ; irows < crowsReturned ; irows++)
  1661. {
  1662. cbNameEntry = cbEmailNameMax;
  1663. if (!pInstance->PRtx()->GetNextEmail(hrtxenum, &(dwFlags), szName))
  1664. {
  1665. dwErr = GetLastError();
  1666. _VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
  1667. _VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
  1668. for (irows = 0 ; irows < crowsReturned ; irows++)
  1669. {
  1670. if (pNameList->aNameEntry[irows].lpszName)
  1671. FreeRpcString(pNameList->aNameEntry[irows].lpszName);
  1672. }
  1673. MIDL_user_free(pNameList);
  1674. ErrorTrace(NULL, "GetNext failed on row %u: %u", irows, dwErr);
  1675. pInstance->Dereference();
  1676. return dwErr;
  1677. }
  1678. if (dwFlags & rtxnameUser)
  1679. pNameList->aNameEntry[irows].dwType = NAME_TYPE_USER;
  1680. if (dwFlags & rtxnameDistListNormal)
  1681. pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_NORMAL;
  1682. if (dwFlags & rtxnameDistListSite)
  1683. pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_SITE;
  1684. if (dwFlags & rtxnameDistListDomain)
  1685. pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_DOMAIN;
  1686. if (!ConvertStringToRpc(&(pNameList->aNameEntry[irows].lpszName), szName))
  1687. {
  1688. dwErr = GetLastError();
  1689. _VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
  1690. _VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
  1691. for (irows = 0 ; irows < crowsReturned ; irows++)
  1692. {
  1693. if (pNameList->aNameEntry[irows].lpszName)
  1694. FreeRpcString(pNameList->aNameEntry[irows].lpszName);
  1695. }
  1696. MIDL_user_free(pNameList);
  1697. ErrorTrace(NULL, "Unable to convert %s to RPC string: %u", szName, dwErr);
  1698. pInstance->Dereference();
  1699. return dwErr;
  1700. }
  1701. }
  1702. _VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
  1703. _VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
  1704. *ppNameList = pNameList;
  1705. pInstance->Dereference();
  1706. TraceFunctLeave();
  1707. return NO_ERROR;
  1708. #endif
  1709. return ERROR_INVALID_PARAMETER;
  1710. }
  1711. NET_API_STATUS
  1712. NET_API_FUNCTION
  1713. SmtprGetVRootSize(
  1714. IN SMTP_HANDLE wszServerName,
  1715. IN LPWSTR wszVRoot,
  1716. OUT LPDWORD pdwBytes,
  1717. IN DWORD dwInstance
  1718. )
  1719. /*++
  1720. Description
  1721. Obtains the size of the specified VRoot
  1722. Arguments:
  1723. wszServer - unused
  1724. wszVRoot - VRoot whose size to return
  1725. pdwBytes - Pointer to a DWORD to contain the VRoot size on return
  1726. Return Value:
  1727. This call returns NO_ERROR on success. ERROR_INVALID_NAME is returned
  1728. if ResolveVirtualRoot returns an invalid directory name. A Win32
  1729. error code is returned for other error conditions.
  1730. Note:
  1731. This RPC is added by Keith Lau (keithlau) on 7/5/96
  1732. --*/
  1733. {
  1734. HANDLE hToken;
  1735. DWORD cbRoot;
  1736. LPSTR szVRoot;
  1737. char szRoot[MAX_PATH + 1];
  1738. DWORD dwErr;
  1739. ULARGE_INTEGER uliBytesAvail;
  1740. ULARGE_INTEGER uliBytesTotal;
  1741. ULARGE_INTEGER uliBytesFree;
  1742. DWORD dwAccessMask = 0;
  1743. PSMTP_SERVER_INSTANCE pInstance;
  1744. TraceFunctEnter("SmtprGetVRootSize");
  1745. if(g_IsShuttingDown)
  1746. {
  1747. return ERROR_SHUTDOWN_IN_PROGRESS;
  1748. }
  1749. if (!pValidateStringPtr(wszVRoot, AB_MAX_VROOT))
  1750. {
  1751. ErrorTrace(NULL, "Invalid parameter: wszVRoot\n");
  1752. TraceFunctLeave();
  1753. return(ERROR_INVALID_PARAMETER);
  1754. }
  1755. if (IsBadWritePtr((LPVOID)pdwBytes, sizeof(DWORD)))
  1756. {
  1757. ErrorTrace(NULL, "Invalid parameter: pdwBytes\n");
  1758. TraceFunctLeave();
  1759. return(ERROR_INVALID_PARAMETER);
  1760. }
  1761. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  1762. if(pInstance == NULL)
  1763. {
  1764. return(ERROR_INVALID_PARAMETER);
  1765. }
  1766. // Default the size to 0 bytes free
  1767. *pdwBytes = 0;
  1768. dwErr = NO_ERROR;
  1769. // Access check
  1770. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  1771. if (dwErr != NO_ERROR)
  1772. {
  1773. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  1774. pInstance->Dereference();
  1775. return dwErr;
  1776. }
  1777. // Resolve the Virtual Root, need Unicode - ANSI conversion
  1778. cbRoot = sizeof(szRoot);
  1779. DebugTrace(NULL, "VRoot name: %ls", wszVRoot);
  1780. if (!(szVRoot = ConvertUnicodeToAnsi(wszVRoot, NULL, 0)))
  1781. {
  1782. dwErr = GetLastError();
  1783. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d",
  1784. wszVRoot, dwErr);
  1785. pInstance->Dereference();
  1786. TraceFunctLeave();
  1787. return dwErr;
  1788. }
  1789. if(!pInstance->QueryVrootTable()->LookupVirtualRoot(
  1790. szVRoot, szRoot, &cbRoot, &dwAccessMask, NULL, NULL,
  1791. &hToken, NULL))
  1792. {
  1793. dwErr = GetLastError();
  1794. ErrorTrace(NULL, "ResolveVirtualRoot failed for %s, %u", wszVRoot, dwErr);
  1795. TCP_FREE(szVRoot);
  1796. }
  1797. else
  1798. {
  1799. // Free it right away lest we forget
  1800. TCP_FREE(szVRoot);
  1801. DebugTrace(NULL, "Getting free disk ratio on %s", szRoot);
  1802. if (hToken == 0 || ImpersonateLoggedOnUser(hToken))
  1803. {
  1804. if (GetDiskFreeSpaceEx(szRoot,
  1805. &uliBytesAvail,
  1806. &uliBytesTotal,
  1807. &uliBytesFree))
  1808. {
  1809. // Make sure we are not overflowing 4Gig, which is easy
  1810. _ASSERT(uliBytesAvail.HighPart == 0);
  1811. *pdwBytes = uliBytesAvail.LowPart;
  1812. }
  1813. else
  1814. {
  1815. dwErr = GetLastError();
  1816. ErrorTrace(NULL, "GetDiskFreeSpaceEx failed on %s: %u", szRoot, dwErr);
  1817. }
  1818. if (hToken != 0)
  1819. _VERIFY(RevertToSelf());
  1820. }
  1821. else
  1822. {
  1823. ErrorTrace(NULL, "Impersonation failed");
  1824. dwErr = GetLastError();
  1825. }
  1826. }
  1827. pInstance->Dereference();
  1828. TraceFunctLeave();
  1829. return dwErr;
  1830. }
  1831. NET_API_STATUS
  1832. NET_API_FUNCTION
  1833. SmtprBackupRoutingTable(
  1834. IN SMTP_HANDLE wszServerName,
  1835. IN LPWSTR wszPath,
  1836. IN DWORD dwInstance
  1837. )
  1838. /*++
  1839. Description
  1840. Tells routing table to backup itself to the given path
  1841. Arguments:
  1842. wszServer - unused
  1843. wszVRoot - Path to put backup file
  1844. Return Value:
  1845. This call returns NO_ERROR on success. Routing table error
  1846. if routing table cannot create the backup
  1847. --*/
  1848. {
  1849. #if 0
  1850. DWORD dwErr;
  1851. LPSTR szBackupDir = NULL;
  1852. PSMTP_SERVER_INSTANCE pInstance;
  1853. TraceFunctEnter("SmtprBackupRoutingTable");
  1854. if(g_IsShuttingDown)
  1855. {
  1856. return ERROR_SHUTDOWN_IN_PROGRESS;
  1857. }
  1858. if (!pValidateStringPtr(wszPath, MAX_PATH))
  1859. {
  1860. ErrorTrace(NULL, "Invalid parameter: wszPath\n");
  1861. TraceFunctLeave();
  1862. return(ERROR_INVALID_PARAMETER);
  1863. }
  1864. pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
  1865. if(pInstance == NULL)
  1866. {
  1867. return(ERROR_INVALID_PARAMETER);
  1868. }
  1869. dwErr = NO_ERROR;
  1870. // Access check
  1871. dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
  1872. if (dwErr != NO_ERROR)
  1873. {
  1874. ErrorTrace(NULL, "Access check failed: %u", dwErr);
  1875. pInstance->Dereference();
  1876. return dwErr;
  1877. }
  1878. if (pInstance->PRtx()->GetRtType() != rttypeFF)
  1879. {
  1880. ErrorTrace(NULL, "Backup for non-FF routing table isn't allowed!");
  1881. pInstance->Dereference();
  1882. return ERROR_NOT_SUPPORTED;
  1883. }
  1884. if (!(szBackupDir = ConvertUnicodeToAnsi(wszPath, NULL, 0)))
  1885. {
  1886. dwErr = GetLastError();
  1887. ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d",
  1888. wszPath, dwErr);
  1889. pInstance->Dereference();
  1890. TraceFunctLeave();
  1891. return dwErr;
  1892. }
  1893. if (!pInstance->PRtx()->MakeBackup(szBackupDir))
  1894. {
  1895. dwErr = GetLastError();
  1896. ErrorTrace(NULL, "Unable to complete backup to %s: %d", szBackupDir, dwErr);
  1897. TCP_FREE(szBackupDir);
  1898. pInstance->Dereference();
  1899. TraceFunctLeave();
  1900. return dwErr;
  1901. }
  1902. TCP_FREE(szBackupDir);
  1903. pInstance->Dereference();
  1904. TraceFunctLeave();
  1905. return dwErr;
  1906. #endif
  1907. return ERROR_INVALID_PARAMETER;
  1908. }