MailDomains.cpp
上传用户:woshihumen
上传日期:2013-07-18
资源大小:484k
文件大小:14k
源码类别:

Email服务器

开发平台:

Visual C++

  1. /*
  2.  *  XMail by Davide Libenzi ( Intranet and Internet mail server )
  3.  *  Copyright (C) 1999,..,2004  Davide Libenzi
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  *  Davide Libenzi <davidel@xmailserver.org>
  20.  *
  21.  */
  22. #include "SysInclude.h"
  23. #include "SysDep.h"
  24. #include "SvrDefines.h"
  25. #include "ShBlocks.h"
  26. #include "ResLocks.h"
  27. #include "StrUtils.h"
  28. #include "SList.h"
  29. #include "BuffSock.h"
  30. #include "MailConfig.h"
  31. #include "MessQueue.h"
  32. #include "MailSvr.h"
  33. #include "MiscUtils.h"
  34. #include "SvrUtils.h"
  35. #include "POP3GwLink.h"
  36. #include "ExtAliases.h"
  37. #include "UsrUtils.h"
  38. #include "UsrAuth.h"
  39. #include "TabIndex.h"
  40. #include "AliasDomain.h"
  41. #include "SMAILUtils.h"
  42. #include "MailDomains.h"
  43. #define MAIL_DOMAINS_DIR            "domains"
  44. #define MAIL_DOMAINS_FILE           "domains.tab"
  45. #define MAIL_DOMAINS_LINE_MAX       512
  46. enum PopDomainFileds {
  47. domDomain = 0,
  48. domMax
  49. };
  50. struct DomainsScanData {
  51. char szTmpDBFile[SYS_MAX_PATH];
  52. FILE *pDBFile;
  53. char szCurrDomain[256];
  54. };
  55. static int MDomRebuildDomainsIndexes(char const *pszDomainsFilePath);
  56. static char *MDomGetDomainsFilePath(char *pszDomainsFilePath, int iMaxPath);
  57. static int iIdxDomains_Domain[] = {
  58. domDomain,
  59. INDEX_SEQUENCE_TERMINATOR
  60. };
  61. int MDomCheckDomainsIndexes(void)
  62. {
  63. char szDomainsFilePath[SYS_MAX_PATH] = "";
  64. MDomGetDomainsFilePath(szDomainsFilePath, sizeof(szDomainsFilePath));
  65. ///////////////////////////////////////////////////////////////////////////////
  66. //  Align RmtDomain-RmtName index
  67. ///////////////////////////////////////////////////////////////////////////////
  68. if (TbixCheckIndex(szDomainsFilePath, iIdxDomains_Domain, false) < 0)
  69. return (ErrGetErrorCode());
  70. return (0);
  71. }
  72. static int MDomRebuildDomainsIndexes(char const *pszDomainsFilePath)
  73. {
  74. ///////////////////////////////////////////////////////////////////////////////
  75. //  Rebuild RmtDomain-RmtName index
  76. ///////////////////////////////////////////////////////////////////////////////
  77. if (TbixCreateIndex(pszDomainsFilePath, iIdxDomains_Domain, false) < 0)
  78. return (ErrGetErrorCode());
  79. return (0);
  80. }
  81. char *MDomGetDomainPath(char const *pszDomain, char *pszDomainPath, int iMaxPath, int iFinalSlash)
  82. {
  83. ///////////////////////////////////////////////////////////////////////////////
  84. //  Make the domain lower-case
  85. ///////////////////////////////////////////////////////////////////////////////
  86. char szLoDomain[SYS_MAX_PATH] = "";
  87. StrSNCpy(szLoDomain, pszDomain);
  88. StrLower(szLoDomain);
  89. CfgGetRootPath(pszDomainPath, iMaxPath);
  90. StrNCat(pszDomainPath, MAIL_DOMAINS_DIR, iMaxPath);
  91. AppendSlash(pszDomainPath);
  92. StrNCat(pszDomainPath, szLoDomain, iMaxPath);
  93. if (iFinalSlash)
  94. AppendSlash(pszDomainPath);
  95. return (pszDomainPath);
  96. }
  97. static char *MDomGetDomainsFilePath(char *pszDomainsFilePath, int iMaxPath)
  98. {
  99. CfgGetRootPath(pszDomainsFilePath, iMaxPath);
  100. StrNCat(pszDomainsFilePath, MAIL_DOMAINS_FILE, iMaxPath);
  101. return (pszDomainsFilePath);
  102. }
  103. int MDomLookupDomain(char const *pszDomain)
  104. {
  105. char szDomainsFilePath[SYS_MAX_PATH] = "";
  106. MDomGetDomainsFilePath(szDomainsFilePath, sizeof(szDomainsFilePath));
  107. char szResLock[SYS_MAX_PATH] = "";
  108. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szDomainsFilePath, szResLock,
  109.   sizeof(szResLock)));
  110. if (hResLock == INVALID_RLCK_HANDLE)
  111. return (ErrGetErrorCode());
  112. ///////////////////////////////////////////////////////////////////////////////
  113. //  Lookup record using the specified index
  114. ///////////////////////////////////////////////////////////////////////////////
  115. char **ppszTabTokens = TbixLookup(szDomainsFilePath, iIdxDomains_Domain, false,
  116.   pszDomain,
  117.   NULL);
  118. if (ppszTabTokens == NULL) {
  119. RLckUnlockSH(hResLock);
  120. ErrSetErrorCode(ERR_DOMAIN_NOT_HANDLED, pszDomain);
  121. return (ERR_DOMAIN_NOT_HANDLED);
  122. }
  123. StrFreeStrings(ppszTabTokens);
  124. RLckUnlockSH(hResLock);
  125. return (0);
  126. }
  127. int MDomAddDomain(char const *pszDomain)
  128. {
  129. char szDomainsFilePath[SYS_MAX_PATH] = "";
  130. MDomGetDomainsFilePath(szDomainsFilePath, sizeof(szDomainsFilePath));
  131. char szResLock[SYS_MAX_PATH] = "";
  132. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szDomainsFilePath, szResLock,
  133.   sizeof(szResLock)));
  134. if (hResLock == INVALID_RLCK_HANDLE)
  135. return (ErrGetErrorCode());
  136. FILE *pDomainsFile = fopen(szDomainsFilePath, "r+t");
  137. if (pDomainsFile == NULL) {
  138. RLckUnlockEX(hResLock);
  139. ErrSetErrorCode(ERR_ALIAS_FILE_NOT_FOUND);
  140. return (ERR_ALIAS_FILE_NOT_FOUND);
  141. }
  142. char szDomainsLine[MAIL_DOMAINS_LINE_MAX] = "";
  143. while (MscFGets(szDomainsLine, sizeof(szDomainsLine) - 1, pDomainsFile) != NULL) {
  144. char **ppszStrings = StrGetTabLineStrings(szDomainsLine);
  145. if (ppszStrings == NULL)
  146. continue;
  147. int iFieldsCount = StrStringsCount(ppszStrings);
  148. if ((iFieldsCount >= domMax) && (stricmp(pszDomain, ppszStrings[domDomain]) == 0)) {
  149. StrFreeStrings(ppszStrings);
  150. fclose(pDomainsFile);
  151. RLckUnlockEX(hResLock);
  152. ErrSetErrorCode(ERR_DOMAIN_ALREADY_HANDLED);
  153. return (ERR_DOMAIN_ALREADY_HANDLED);
  154. }
  155. StrFreeStrings(ppszStrings);
  156. }
  157. fseek(pDomainsFile, 0, SEEK_END);
  158. fprintf(pDomainsFile, ""%s"n", pszDomain);
  159. fclose(pDomainsFile);
  160. ///////////////////////////////////////////////////////////////////////////////
  161. //  Rebuild indexes
  162. ///////////////////////////////////////////////////////////////////////////////
  163. if (MDomRebuildDomainsIndexes(szDomainsFilePath) < 0) {
  164. ErrorPush();
  165. RLckUnlockEX(hResLock);
  166. return (ErrorPop());
  167. }
  168. ///////////////////////////////////////////////////////////////////////////////
  169. //  Create domain directory
  170. ///////////////////////////////////////////////////////////////////////////////
  171. char szDomainPath[SYS_MAX_PATH] = "";
  172. MDomGetDomainPath(pszDomain, szDomainPath, sizeof(szDomainPath), 0);
  173. if (SysMakeDir(szDomainPath) < 0) {
  174. ErrorPush();
  175. RLckUnlockEX(hResLock);
  176. return (ErrorPop());
  177. }
  178. ///////////////////////////////////////////////////////////////////////////////
  179. //  Create cmd alias directory
  180. ///////////////////////////////////////////////////////////////////////////////
  181. if (USmlCreateCmdAliasDomainDir(pszDomain) < 0) {
  182. ErrorPush();
  183. RLckUnlockEX(hResLock);
  184. return (ErrorPop());
  185. }
  186. RLckUnlockEX(hResLock);
  187. return (0);
  188. }
  189. int MDomRemoveDomain(char const *pszDomain)
  190. {
  191. char szDomainsFilePath[SYS_MAX_PATH] = "";
  192. MDomGetDomainsFilePath(szDomainsFilePath, sizeof(szDomainsFilePath));
  193. char szTmpFile[SYS_MAX_PATH] = "";
  194. SysGetTmpFile(szTmpFile);
  195. char szResLock[SYS_MAX_PATH] = "";
  196. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szDomainsFilePath, szResLock,
  197.   sizeof(szResLock)));
  198. if (hResLock == INVALID_RLCK_HANDLE) {
  199. ErrorPush();
  200. CheckRemoveFile(szTmpFile);
  201. return (ErrorPop());
  202. }
  203. FILE *pDomainsFile = fopen(szDomainsFilePath, "rt");
  204. if (pDomainsFile == NULL) {
  205. RLckUnlockEX(hResLock);
  206. CheckRemoveFile(szTmpFile);
  207. ErrSetErrorCode(ERR_DOMAINS_FILE_NOT_FOUND);
  208. return (ERR_DOMAINS_FILE_NOT_FOUND);
  209. }
  210. FILE *pTmpFile = fopen(szTmpFile, "wt");
  211. if (pTmpFile == NULL) {
  212. fclose(pDomainsFile);
  213. RLckUnlockEX(hResLock);
  214. CheckRemoveFile(szTmpFile);
  215. ErrSetErrorCode(ERR_FILE_CREATE);
  216. return (ERR_FILE_CREATE);
  217. }
  218. int iDomainsFound = 0;
  219. char szDomainsLine[MAIL_DOMAINS_LINE_MAX] = "";
  220. while (MscFGets(szDomainsLine, sizeof(szDomainsLine) - 1, pDomainsFile) != NULL) {
  221. char **ppszStrings = StrGetTabLineStrings(szDomainsLine);
  222. if (ppszStrings == NULL)
  223. continue;
  224. int iFieldsCount = StrStringsCount(ppszStrings);
  225. if ((iFieldsCount >= domMax) && (stricmp(pszDomain, ppszStrings[domDomain]) == 0)) {
  226. ++iDomainsFound;
  227. } else
  228. fprintf(pTmpFile, "%sn", szDomainsLine);
  229. StrFreeStrings(ppszStrings);
  230. }
  231. fclose(pDomainsFile);
  232. fclose(pTmpFile);
  233. if (iDomainsFound == 0) {
  234. SysRemove(szTmpFile);
  235. RLckUnlockEX(hResLock);
  236. ErrSetErrorCode(ERR_DOMAIN_NOT_HANDLED);
  237. return (ERR_DOMAIN_NOT_HANDLED);
  238. }
  239. char szTmpAliasFilePath[SYS_MAX_PATH] = "";
  240. sprintf(szTmpAliasFilePath, "%s.tmp", szDomainsFilePath);
  241. if (MscMoveFile(szDomainsFilePath, szTmpAliasFilePath) < 0) {
  242. ErrorPush();
  243. RLckUnlockEX(hResLock);
  244. return (ErrorPop());
  245. }
  246. if (MscMoveFile(szTmpFile, szDomainsFilePath) < 0) {
  247. ErrorPush();
  248. MscMoveFile(szTmpAliasFilePath, szDomainsFilePath);
  249. RLckUnlockEX(hResLock);
  250. return (ErrorPop());
  251. }
  252. SysRemove(szTmpAliasFilePath);
  253. ///////////////////////////////////////////////////////////////////////////////
  254. //  Rebuild indexes
  255. ///////////////////////////////////////////////////////////////////////////////
  256. if (MDomRebuildDomainsIndexes(szDomainsFilePath) < 0) {
  257. ErrorPush();
  258. RLckUnlockEX(hResLock);
  259. return (ErrorPop());
  260. }
  261. RLckUnlockEX(hResLock);
  262. ///////////////////////////////////////////////////////////////////////////////
  263. //  Domain cleanup
  264. ///////////////////////////////////////////////////////////////////////////////
  265. if (UsrRemoveDomainUsers(pszDomain) < 0)
  266. return (ErrGetErrorCode());
  267. if (UsrRemoveDomainAliases(pszDomain) < 0)
  268. return (ErrGetErrorCode());
  269. if (ExAlRemoveDomainAliases(pszDomain) < 0)
  270. return (ErrGetErrorCode());
  271. if (GwLkRemoveDomainLinks(pszDomain) < 0)
  272. return (ErrGetErrorCode());
  273. if (ADomRemoveLinkedDomains(pszDomain) < 0)
  274. return (ErrGetErrorCode());
  275. ///////////////////////////////////////////////////////////////////////////////
  276. //  Try ( if defined ) to drop external auth domain
  277. ///////////////////////////////////////////////////////////////////////////////
  278. UAthDropDomain(AUTH_SERVICE_POP3, pszDomain);
  279. ///////////////////////////////////////////////////////////////////////////////
  280. //  Directory cleanup
  281. ///////////////////////////////////////////////////////////////////////////////
  282. char szDomainPath[SYS_MAX_PATH] = "";
  283. MDomGetDomainPath(pszDomain, szDomainPath, sizeof(szDomainPath), 0);
  284. if (MscClearDirectory(szDomainPath) < 0)
  285. return (ErrGetErrorCode());
  286. if (SysRemoveDir(szDomainPath) < 0)
  287. return (ErrGetErrorCode());
  288. ///////////////////////////////////////////////////////////////////////////////
  289. //  Remove the cmd alias directory
  290. ///////////////////////////////////////////////////////////////////////////////
  291. if (USmlDeleteCmdAliasDomainDir(pszDomain) < 0)
  292. return (ErrGetErrorCode());
  293. return (0);
  294. }
  295. int MDomGetDomainsFileSnapShot(const char *pszFileName)
  296. {
  297. char szDomainsFilePath[SYS_MAX_PATH] = "";
  298. MDomGetDomainsFilePath(szDomainsFilePath, sizeof(szDomainsFilePath));
  299. char szResLock[SYS_MAX_PATH] = "";
  300. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szDomainsFilePath, szResLock,
  301.   sizeof(szResLock)));
  302. if (hResLock == INVALID_RLCK_HANDLE)
  303. return (ErrGetErrorCode());
  304. if (MscCopyFile(pszFileName, szDomainsFilePath) < 0) {
  305. ErrorPush();
  306. RLckUnlockSH(hResLock);
  307. return (ErrorPop());
  308. }
  309. RLckUnlockSH(hResLock);
  310. return (0);
  311. }
  312. DOMLS_HANDLE MDomOpenDB(void)
  313. {
  314. DomainsScanData *pDSD = (DomainsScanData *) SysAlloc(sizeof(DomainsScanData));
  315. if (pDSD == NULL)
  316. return (INVALID_DOMLS_HANDLE);
  317. SysGetTmpFile(pDSD->szTmpDBFile);
  318. if (MDomGetDomainsFileSnapShot(pDSD->szTmpDBFile) < 0) {
  319. CheckRemoveFile(pDSD->szTmpDBFile);
  320. SysFree(pDSD);
  321. return (INVALID_DOMLS_HANDLE);
  322. }
  323. if ((pDSD->pDBFile = fopen(pDSD->szTmpDBFile, "rt")) == NULL) {
  324. SysRemove(pDSD->szTmpDBFile);
  325. SysFree(pDSD);
  326. return (INVALID_DOMLS_HANDLE);
  327. }
  328. return ((DOMLS_HANDLE) pDSD);
  329. }
  330. void MDomCloseDB(DOMLS_HANDLE hDomainsDB)
  331. {
  332. DomainsScanData *pDSD = (DomainsScanData *) hDomainsDB;
  333. fclose(pDSD->pDBFile);
  334. SysRemove(pDSD->szTmpDBFile);
  335. SysFree(pDSD);
  336. }
  337. char const *MDomGetFirstDomain(DOMLS_HANDLE hDomainsDB)
  338. {
  339. DomainsScanData *pDSD = (DomainsScanData *) hDomainsDB;
  340. rewind(pDSD->pDBFile);
  341. const char *pszDomain = NULL;
  342. char szDomainsLine[MAIL_DOMAINS_LINE_MAX] = "";
  343. while ((pszDomain == NULL) &&
  344.        (MscFGets(szDomainsLine, sizeof(szDomainsLine) - 1, pDSD->pDBFile) != NULL)) {
  345. char **ppszStrings = StrGetTabLineStrings(szDomainsLine);
  346. if (ppszStrings == NULL)
  347. continue;
  348. int iFieldsCount = StrStringsCount(ppszStrings);
  349. if (iFieldsCount >= domMax) {
  350. StrSNCpy(pDSD->szCurrDomain, ppszStrings[0]);
  351. pszDomain = pDSD->szCurrDomain;
  352. }
  353. StrFreeStrings(ppszStrings);
  354. }
  355. return (pszDomain);
  356. }
  357. char const *MDomGetNextDomain(DOMLS_HANDLE hDomainsDB)
  358. {
  359. DomainsScanData *pDSD = (DomainsScanData *) hDomainsDB;
  360. const char *pszDomain = NULL;
  361. char szDomainsLine[MAIL_DOMAINS_LINE_MAX] = "";
  362. while ((pszDomain == NULL) &&
  363.        (MscFGets(szDomainsLine, sizeof(szDomainsLine) - 1, pDSD->pDBFile) != NULL)) {
  364. char **ppszStrings = StrGetTabLineStrings(szDomainsLine);
  365. if (ppszStrings == NULL)
  366. continue;
  367. int iFieldsCount = StrStringsCount(ppszStrings);
  368. if (iFieldsCount >= domMax) {
  369. StrSNCpy(pDSD->szCurrDomain, ppszStrings[0]);
  370. pszDomain = pDSD->szCurrDomain;
  371. }
  372. StrFreeStrings(ppszStrings);
  373. }
  374. return (pszDomain);
  375. }
  376. int MDomGetClientDomain(char const *pszFQDN, char *pszClientDomain, int iMaxDomain)
  377. {
  378. for (; pszFQDN != NULL;) {
  379. if (MDomIsHandledDomain(pszFQDN) == 0) {
  380. StrNCpy(pszClientDomain, pszFQDN, iMaxDomain);
  381. return (0);
  382. }
  383. if ((pszFQDN = strchr(pszFQDN, '.')) != NULL)
  384. ++pszFQDN;
  385. }
  386. ErrSetErrorCode(ERR_NO_HANDLED_DOMAIN);
  387. return (ERR_NO_HANDLED_DOMAIN);
  388. }
  389. int MDomIsHandledDomain(char const *pszDomain)
  390. {
  391. ///////////////////////////////////////////////////////////////////////////////
  392. //  Check for alias domain
  393. ///////////////////////////////////////////////////////////////////////////////
  394. char szADomain[MAX_HOST_NAME] = "";
  395. if (ADomLookupDomain(pszDomain, szADomain, true))
  396. pszDomain = szADomain;
  397. return (MDomLookupDomain(pszDomain));
  398. }