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

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 "MailDomains.h"
  41. #include "AliasDomain.h"
  42. #define ADOMAIN_FILE                "aliasdomain.tab"
  43. #define WILD_ADOMAIN_HASH           0
  44. #define ADOMAIN_LINE_MAX            512
  45. struct ADomainScanData {
  46. char szTmpDBFile[SYS_MAX_PATH];
  47. FILE *pDBFile;
  48. char **ppszStrings;
  49. };
  50. static bool ADomIsWildAlias(char const *pszAlias);
  51. static int ADomCalcAliasHash(char const *const *ppszTabTokens, int const *piFieldsIdx,
  52.      SYS_UINT32 * puHashVal, bool bCaseSens);
  53. static int ADomRebuildADomainIndexes(char const *pszADomainFilePath);
  54. static char *ADomGetADomainFilePath(char *pszADomainFilePath, int iMaxPath);
  55. static int ADomLookupDomainLK(const char *pszADomainFilePath, const char *pszADomain,
  56.       char *pszDomain, bool bWildMatch);
  57. static int iIdxADomain_Alias[] = {
  58. adomADomain,
  59. INDEX_SEQUENCE_TERMINATOR
  60. };
  61. static bool ADomIsWildAlias(char const *pszAlias)
  62. {
  63. return ((strchr(pszAlias, '*') != NULL) || (strchr(pszAlias, '?') != NULL));
  64. }
  65. static int ADomCalcAliasHash(char const *const *ppszTabTokens, int const *piFieldsIdx,
  66.      SYS_UINT32 * puHashVal, bool bCaseSens)
  67. {
  68. ///////////////////////////////////////////////////////////////////////////////
  69. //  This will group wild alias ( * ? )
  70. ///////////////////////////////////////////////////////////////////////////////
  71. int iFieldsCount = StrStringsCount(ppszTabTokens);
  72. if ((iFieldsCount > adomADomain) && ADomIsWildAlias(ppszTabTokens[adomADomain])) {
  73. *puHashVal = WILD_ADOMAIN_HASH;
  74. return (0);
  75. }
  76. return (TbixCalculateHash(ppszTabTokens, piFieldsIdx, puHashVal, bCaseSens));
  77. }
  78. int ADomCheckDomainsIndexes(void)
  79. {
  80. char szADomainFilePath[SYS_MAX_PATH] = "";
  81. ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath));
  82. ///////////////////////////////////////////////////////////////////////////////
  83. //  Align RmtDomain-RmtName index
  84. ///////////////////////////////////////////////////////////////////////////////
  85. if (TbixCheckIndex(szADomainFilePath, iIdxADomain_Alias, false, ADomCalcAliasHash) < 0)
  86. return (ErrGetErrorCode());
  87. return (0);
  88. }
  89. static int ADomRebuildADomainIndexes(char const *pszADomainFilePath)
  90. {
  91. ///////////////////////////////////////////////////////////////////////////////
  92. //  Rebuild RmtDomain-RmtName index
  93. ///////////////////////////////////////////////////////////////////////////////
  94. if (TbixCreateIndex(pszADomainFilePath, iIdxADomain_Alias, false, ADomCalcAliasHash) < 0)
  95. return (ErrGetErrorCode());
  96. return (0);
  97. }
  98. static char *ADomGetADomainFilePath(char *pszADomainFilePath, int iMaxPath)
  99. {
  100. CfgGetRootPath(pszADomainFilePath, iMaxPath);
  101. StrNCat(pszADomainFilePath, ADOMAIN_FILE, iMaxPath);
  102. return (pszADomainFilePath);
  103. }
  104. static int ADomLookupDomainLK(const char *pszADomainFilePath, const char *pszADomain,
  105.       char *pszDomain, bool bWildMatch)
  106. {
  107. ///////////////////////////////////////////////////////////////////////////////
  108. //  Lookup record using the specified index ( lookup precise aliases )
  109. ///////////////////////////////////////////////////////////////////////////////
  110. char **ppszTabTokens = TbixLookup(pszADomainFilePath, iIdxADomain_Alias, false,
  111.   pszADomain,
  112.   NULL);
  113. if (ppszTabTokens != NULL) {
  114. if (pszDomain != NULL)
  115. StrNCpy(pszDomain, ppszTabTokens[adomDomain], MAX_HOST_NAME);
  116. StrFreeStrings(ppszTabTokens);
  117. return (1);
  118. }
  119. ///////////////////////////////////////////////////////////////////////////////
  120. //  We can stop here if wild alias matching is not required
  121. ///////////////////////////////////////////////////////////////////////////////
  122. if (!bWildMatch)
  123. return (0);
  124. ///////////////////////////////////////////////////////////////////////////////
  125. //  Lookup record using the specified index ( lookup wild aliases grouped
  126. //  under WILD_ADOMAIN_HASH hash key )
  127. ///////////////////////////////////////////////////////////////////////////////
  128. INDEX_HANDLE hIndexLookup = TbixOpenHandle(pszADomainFilePath, iIdxADomain_Alias,
  129.    WILD_ADOMAIN_HASH);
  130. if (hIndexLookup != INVALID_INDEX_HANDLE) {
  131. int iNumRecords = TbixLookedUpRecords(hIndexLookup);
  132. for (int ii = 0; ii < iNumRecords; ii++) {
  133. char **ppszTabTokens = TbixGetRecord(hIndexLookup, ii);
  134. if (ppszTabTokens == NULL)
  135. continue;
  136. int iFieldsCount = StrStringsCount(ppszTabTokens);
  137. if ((iFieldsCount >= adomMax) &&
  138.     StrIWildMatch(pszADomain, ppszTabTokens[adomADomain])) {
  139. if (pszDomain != NULL)
  140. StrNCpy(pszDomain, ppszTabTokens[adomDomain],
  141. MAX_HOST_NAME);
  142. StrFreeStrings(ppszTabTokens);
  143. TbixCloseHandle(hIndexLookup);
  144. return (1);
  145. }
  146. StrFreeStrings(ppszTabTokens);
  147. }
  148. TbixCloseHandle(hIndexLookup);
  149. }
  150. return (0);
  151. }
  152. int ADomLookupDomain(const char *pszADomain, char *pszDomain, bool bWildMatch)
  153. {
  154. char szADomainFilePath[SYS_MAX_PATH] = "";
  155. ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath));
  156. char szResLock[SYS_MAX_PATH] = "";
  157. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szADomainFilePath, szResLock,
  158.   sizeof(szResLock)));
  159. if (hResLock == INVALID_RLCK_HANDLE)
  160. return (0);
  161. int iLookupResult = ADomLookupDomainLK(szADomainFilePath, pszADomain,
  162.        pszDomain, bWildMatch);
  163. RLckUnlockSH(hResLock);
  164. return (iLookupResult);
  165. }
  166. int ADomAddADomain(char const *pszADomain, char const *pszDomain)
  167. {
  168. char szADomainFilePath[SYS_MAX_PATH] = "";
  169. ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath));
  170. char szResLock[SYS_MAX_PATH] = "";
  171. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szADomainFilePath, szResLock,
  172.   sizeof(szResLock)));
  173. if (hResLock == INVALID_RLCK_HANDLE)
  174. return (ErrGetErrorCode());
  175. FILE *pDomainsFile = fopen(szADomainFilePath, "r+t");
  176. if (pDomainsFile == NULL) {
  177. RLckUnlockEX(hResLock);
  178. ErrSetErrorCode(ERR_ADOMAIN_FILE_NOT_FOUND);
  179. return (ERR_ADOMAIN_FILE_NOT_FOUND);
  180. }
  181. char szADomainLine[ADOMAIN_LINE_MAX] = "";
  182. while (MscFGets(szADomainLine, sizeof(szADomainLine) - 1, pDomainsFile) != NULL) {
  183. char **ppszStrings = StrGetTabLineStrings(szADomainLine);
  184. if (ppszStrings == NULL)
  185. continue;
  186. int iFieldsCount = StrStringsCount(ppszStrings);
  187. if ((iFieldsCount >= adomMax) &&
  188.     (stricmp(pszADomain, ppszStrings[adomADomain]) == 0)) {
  189. StrFreeStrings(ppszStrings);
  190. fclose(pDomainsFile);
  191. RLckUnlockEX(hResLock);
  192. ErrSetErrorCode(ERR_ADOMAIN_EXIST);
  193. return (ERR_ADOMAIN_EXIST);
  194. }
  195. StrFreeStrings(ppszStrings);
  196. }
  197. fseek(pDomainsFile, 0, SEEK_END);
  198. fprintf(pDomainsFile, ""%s"t"%s"n", pszADomain, pszDomain);
  199. fclose(pDomainsFile);
  200. ///////////////////////////////////////////////////////////////////////////////
  201. //  Rebuild indexes
  202. ///////////////////////////////////////////////////////////////////////////////
  203. if (ADomRebuildADomainIndexes(szADomainFilePath) < 0) {
  204. ErrorPush();
  205. RLckUnlockEX(hResLock);
  206. return (ErrorPop());
  207. }
  208. RLckUnlockEX(hResLock);
  209. return (0);
  210. }
  211. int ADomRemoveADomain(char const *pszADomain)
  212. {
  213. char szADomainFilePath[SYS_MAX_PATH] = "";
  214. ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath));
  215. char szTmpFile[SYS_MAX_PATH] = "";
  216. SysGetTmpFile(szTmpFile);
  217. char szResLock[SYS_MAX_PATH] = "";
  218. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szADomainFilePath, szResLock,
  219.   sizeof(szResLock)));
  220. if (hResLock == INVALID_RLCK_HANDLE) {
  221. ErrorPush();
  222. CheckRemoveFile(szTmpFile);
  223. return (ErrorPop());
  224. }
  225. FILE *pDomainsFile = fopen(szADomainFilePath, "rt");
  226. if (pDomainsFile == NULL) {
  227. RLckUnlockEX(hResLock);
  228. CheckRemoveFile(szTmpFile);
  229. ErrSetErrorCode(ERR_ADOMAIN_FILE_NOT_FOUND);
  230. return (ERR_ADOMAIN_FILE_NOT_FOUND);
  231. }
  232. FILE *pTmpFile = fopen(szTmpFile, "wt");
  233. if (pTmpFile == NULL) {
  234. fclose(pDomainsFile);
  235. RLckUnlockEX(hResLock);
  236. CheckRemoveFile(szTmpFile);
  237. ErrSetErrorCode(ERR_FILE_CREATE, szTmpFile);
  238. return (ERR_FILE_CREATE);
  239. }
  240. int iADomainFound = 0;
  241. char szADomainLine[ADOMAIN_LINE_MAX] = "";
  242. while (MscFGets(szADomainLine, sizeof(szADomainLine) - 1, pDomainsFile) != NULL) {
  243. char **ppszStrings = StrGetTabLineStrings(szADomainLine);
  244. if (ppszStrings == NULL)
  245. continue;
  246. int iFieldsCount = StrStringsCount(ppszStrings);
  247. if ((iFieldsCount >= adomMax) &&
  248.     (stricmp(pszADomain, ppszStrings[adomADomain]) == 0)) {
  249. ++iADomainFound;
  250. } else
  251. fprintf(pTmpFile, "%sn", szADomainLine);
  252. StrFreeStrings(ppszStrings);
  253. }
  254. fclose(pDomainsFile);
  255. fclose(pTmpFile);
  256. if (iADomainFound == 0) {
  257. SysRemove(szTmpFile);
  258. RLckUnlockEX(hResLock);
  259. ErrSetErrorCode(ERR_ADOMAIN_NOT_FOUND);
  260. return (ERR_ADOMAIN_NOT_FOUND);
  261. }
  262. char szTmpADomainFilePath[SYS_MAX_PATH] = "";
  263. sprintf(szTmpADomainFilePath, "%s.tmp", szADomainFilePath);
  264. if (MscMoveFile(szADomainFilePath, szTmpADomainFilePath) < 0) {
  265. ErrorPush();
  266. RLckUnlockEX(hResLock);
  267. return (ErrorPop());
  268. }
  269. if (MscMoveFile(szTmpFile, szADomainFilePath) < 0) {
  270. ErrorPush();
  271. MscMoveFile(szTmpADomainFilePath, szADomainFilePath);
  272. RLckUnlockEX(hResLock);
  273. return (ErrorPop());
  274. }
  275. SysRemove(szTmpADomainFilePath);
  276. ///////////////////////////////////////////////////////////////////////////////
  277. //  Rebuild indexes
  278. ///////////////////////////////////////////////////////////////////////////////
  279. if (ADomRebuildADomainIndexes(szADomainFilePath) < 0) {
  280. ErrorPush();
  281. RLckUnlockEX(hResLock);
  282. return (ErrorPop());
  283. }
  284. RLckUnlockEX(hResLock);
  285. return (0);
  286. }
  287. int ADomRemoveLinkedDomains(char const *pszDomain)
  288. {
  289. char szADomainFilePath[SYS_MAX_PATH] = "";
  290. ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath));
  291. char szTmpFile[SYS_MAX_PATH] = "";
  292. SysGetTmpFile(szTmpFile);
  293. char szResLock[SYS_MAX_PATH] = "";
  294. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szADomainFilePath, szResLock,
  295.   sizeof(szResLock)));
  296. if (hResLock == INVALID_RLCK_HANDLE) {
  297. ErrorPush();
  298. CheckRemoveFile(szTmpFile);
  299. return (ErrorPop());
  300. }
  301. FILE *pDomainsFile = fopen(szADomainFilePath, "rt");
  302. if (pDomainsFile == NULL) {
  303. RLckUnlockEX(hResLock);
  304. CheckRemoveFile(szTmpFile);
  305. ErrSetErrorCode(ERR_ADOMAIN_FILE_NOT_FOUND);
  306. return (ERR_ADOMAIN_FILE_NOT_FOUND);
  307. }
  308. FILE *pTmpFile = fopen(szTmpFile, "wt");
  309. if (pTmpFile == NULL) {
  310. fclose(pDomainsFile);
  311. RLckUnlockEX(hResLock);
  312. CheckRemoveFile(szTmpFile);
  313. ErrSetErrorCode(ERR_FILE_CREATE, szTmpFile);
  314. return (ERR_FILE_CREATE);
  315. }
  316. int iDomainFound = 0;
  317. char szADomainLine[ADOMAIN_LINE_MAX] = "";
  318. while (MscFGets(szADomainLine, sizeof(szADomainLine) - 1, pDomainsFile) != NULL) {
  319. char **ppszStrings = StrGetTabLineStrings(szADomainLine);
  320. if (ppszStrings == NULL)
  321. continue;
  322. int iFieldsCount = StrStringsCount(ppszStrings);
  323. if ((iFieldsCount >= adomMax) &&
  324.     (stricmp(pszDomain, ppszStrings[adomDomain]) == 0)) {
  325. ++iDomainFound;
  326. } else
  327. fprintf(pTmpFile, "%sn", szADomainLine);
  328. StrFreeStrings(ppszStrings);
  329. }
  330. fclose(pDomainsFile);
  331. fclose(pTmpFile);
  332. if (iDomainFound == 0) {
  333. SysRemove(szTmpFile);
  334. RLckUnlockEX(hResLock);
  335. return (0);
  336. }
  337. char szTmpADomainFilePath[SYS_MAX_PATH] = "";
  338. sprintf(szTmpADomainFilePath, "%s.tmp", szADomainFilePath);
  339. if (MscMoveFile(szADomainFilePath, szTmpADomainFilePath) < 0) {
  340. ErrorPush();
  341. RLckUnlockEX(hResLock);
  342. return (ErrorPop());
  343. }
  344. if (MscMoveFile(szTmpFile, szADomainFilePath) < 0) {
  345. ErrorPush();
  346. MscMoveFile(szTmpADomainFilePath, szADomainFilePath);
  347. RLckUnlockEX(hResLock);
  348. return (ErrorPop());
  349. }
  350. SysRemove(szTmpADomainFilePath);
  351. ///////////////////////////////////////////////////////////////////////////////
  352. //  Rebuild indexes
  353. ///////////////////////////////////////////////////////////////////////////////
  354. if (ADomRebuildADomainIndexes(szADomainFilePath) < 0) {
  355. ErrorPush();
  356. RLckUnlockEX(hResLock);
  357. return (ErrorPop());
  358. }
  359. RLckUnlockEX(hResLock);
  360. return (0);
  361. }
  362. int ADomGetADomainFileSnapShot(const char *pszFileName)
  363. {
  364. char szADomainFilePath[SYS_MAX_PATH] = "";
  365. ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath));
  366. char szResLock[SYS_MAX_PATH] = "";
  367. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szADomainFilePath, szResLock,
  368.   sizeof(szResLock)));
  369. if (hResLock == INVALID_RLCK_HANDLE)
  370. return (ErrGetErrorCode());
  371. if (MscCopyFile(pszFileName, szADomainFilePath) < 0) {
  372. ErrorPush();
  373. RLckUnlockSH(hResLock);
  374. return (ErrorPop());
  375. }
  376. RLckUnlockSH(hResLock);
  377. return (0);
  378. }
  379. ADOMAIN_HANDLE ADomOpenDB(void)
  380. {
  381. ADomainScanData *pDSD = (ADomainScanData *) SysAlloc(sizeof(ADomainScanData));
  382. if (pDSD == NULL)
  383. return (INVALID_ADOMAIN_HANDLE);
  384. SysGetTmpFile(pDSD->szTmpDBFile);
  385. if (ADomGetADomainFileSnapShot(pDSD->szTmpDBFile) < 0) {
  386. CheckRemoveFile(pDSD->szTmpDBFile);
  387. SysFree(pDSD);
  388. return (INVALID_ADOMAIN_HANDLE);
  389. }
  390. if ((pDSD->pDBFile = fopen(pDSD->szTmpDBFile, "rt")) == NULL) {
  391. SysRemove(pDSD->szTmpDBFile);
  392. SysFree(pDSD);
  393. return (INVALID_ADOMAIN_HANDLE);
  394. }
  395. pDSD->ppszStrings = NULL;
  396. return ((ADOMAIN_HANDLE) pDSD);
  397. }
  398. void ADomCloseDB(ADOMAIN_HANDLE hDomainsDB)
  399. {
  400. ADomainScanData *pDSD = (ADomainScanData *) hDomainsDB;
  401. fclose(pDSD->pDBFile);
  402. SysRemove(pDSD->szTmpDBFile);
  403. if (pDSD->ppszStrings != NULL)
  404. StrFreeStrings(pDSD->ppszStrings);
  405. SysFree(pDSD);
  406. }
  407. char const *const *ADomGetFirstDomain(ADOMAIN_HANDLE hDomainsDB)
  408. {
  409. ADomainScanData *pDSD = (ADomainScanData *) hDomainsDB;
  410. rewind(pDSD->pDBFile);
  411. if (pDSD->ppszStrings != NULL)
  412. StrFreeStrings(pDSD->ppszStrings), pDSD->ppszStrings = NULL;
  413. char szADomainLine[ADOMAIN_LINE_MAX] = "";
  414. while (MscFGets(szADomainLine, sizeof(szADomainLine) - 1, pDSD->pDBFile) != NULL) {
  415. char **ppszStrings = StrGetTabLineStrings(szADomainLine);
  416. if (ppszStrings == NULL)
  417. continue;
  418. int iFieldsCount = StrStringsCount(ppszStrings);
  419. if (iFieldsCount >= adomMax)
  420. return (pDSD->ppszStrings = ppszStrings);
  421. StrFreeStrings(ppszStrings);
  422. }
  423. return (NULL);
  424. }
  425. char const *const *ADomGetNextDomain(ADOMAIN_HANDLE hDomainsDB)
  426. {
  427. ADomainScanData *pDSD = (ADomainScanData *) hDomainsDB;
  428. if (pDSD->ppszStrings != NULL)
  429. StrFreeStrings(pDSD->ppszStrings), pDSD->ppszStrings = NULL;
  430. char szADomainLine[ADOMAIN_LINE_MAX] = "";
  431. while (MscFGets(szADomainLine, sizeof(szADomainLine) - 1, pDSD->pDBFile) != NULL) {
  432. char **ppszStrings = StrGetTabLineStrings(szADomainLine);
  433. if (ppszStrings == NULL)
  434. continue;
  435. int iFieldsCount = StrStringsCount(ppszStrings);
  436. if (iFieldsCount >= adomMax)
  437. return (pDSD->ppszStrings = ppszStrings);
  438. StrFreeStrings(ppszStrings);
  439. }
  440. return (NULL);
  441. }