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

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 "UsrUtils.h"
  36. #include "POP3GwLink.h"
  37. #define SVR_LINKS_FILE              "pop3links.tab"
  38. #define SVR_LINKS_ENABLE_DIR        "pop3links"
  39. #define SVR_POP3LOCKS_DIR           "pop3linklocks"
  40. #define LINKS_TABLE_LINE_MAX        2048
  41. enum LinksFileds {
  42. lnkDomain = 0,
  43. lnkName,
  44. lnkRmtDomain,
  45. lnkRmtName,
  46. lnkRmtPassword,
  47. lnkAuthType,
  48. lnkMax
  49. };
  50. struct GwLkDBScanData {
  51. char szTmpDBFile[SYS_MAX_PATH];
  52. FILE *pDBFile;
  53. };
  54. static char *GwLkGetTableFilePath(char *pszLnkFilePath, int iMaxPath);
  55. static char *GwLkEnableDir(char *pszEnableDir, int iMaxPath);
  56. static char *GwLkGetLocksDir(char *pszLocksDir, int iMaxPath);
  57. static POP3Link *GwLkGetLinkFromStrings(char **ppszStrings);
  58. static int GwLkWriteLink(FILE * pLnkFile, POP3Link * pPopLnk);
  59. static char *GwLkSanitizeFileName(char const *pszInName, char *pszOutName, int iOutSize);
  60. static char *GwLkGetLockFileName(POP3Link const *pPopLnk, char *pszLockFile);
  61. static int GwLkGetDisableFilePath(POP3Link const *pPopLnk, char *pszEnableFile);
  62. static char *GwLkGetTableFilePath(char *pszLnkFilePath, int iMaxPath)
  63. {
  64. CfgGetRootPath(pszLnkFilePath, iMaxPath);
  65. StrNCat(pszLnkFilePath, SVR_LINKS_FILE, iMaxPath);
  66. return (pszLnkFilePath);
  67. }
  68. static char *GwLkEnableDir(char *pszEnableDir, int iMaxPath)
  69. {
  70. CfgGetRootPath(pszEnableDir, iMaxPath);
  71. StrNCat(pszEnableDir, SVR_LINKS_ENABLE_DIR, iMaxPath);
  72. return (pszEnableDir);
  73. }
  74. static char *GwLkGetLocksDir(char *pszLocksDir, int iMaxPath)
  75. {
  76. CfgGetRootPath(pszLocksDir, iMaxPath);
  77. StrNCat(pszLocksDir, SVR_POP3LOCKS_DIR, iMaxPath);
  78. return (pszLocksDir);
  79. }
  80. static POP3Link *GwLkGetLinkFromStrings(char **ppszStrings)
  81. {
  82. int iFieldsCount = StrStringsCount(ppszStrings);
  83. if (iFieldsCount < lnkMax)
  84. return (NULL);
  85. char szPassword[512] = "";
  86. if (StrDeCrypt(ppszStrings[lnkRmtPassword], szPassword) == NULL)
  87. return (NULL);
  88. POP3Link *pPopLnk = (POP3Link *) SysAlloc(sizeof(POP3Link));
  89. if (pPopLnk == NULL)
  90. return (NULL);
  91. pPopLnk->pszDomain = SysStrDup(ppszStrings[lnkDomain]);
  92. pPopLnk->pszName = SysStrDup(ppszStrings[lnkName]);
  93. pPopLnk->pszRmtDomain = SysStrDup(ppszStrings[lnkRmtDomain]);
  94. pPopLnk->pszRmtName = SysStrDup(ppszStrings[lnkRmtName]);
  95. pPopLnk->pszRmtPassword = SysStrDup(szPassword);
  96. pPopLnk->pszAuthType = SysStrDup(ppszStrings[lnkAuthType]);
  97. return (pPopLnk);
  98. }
  99. POP3Link *GwLkAllocLink(char const *pszDomain, char const *pszName,
  100. char const *pszRmtDomain, char const *pszRmtName,
  101. char const *pszRmtPassword, char const *pszAuthType)
  102. {
  103. POP3Link *pPopLnk = (POP3Link *) SysAlloc(sizeof(POP3Link));
  104. if (pPopLnk == NULL)
  105. return (NULL);
  106. pPopLnk->pszDomain = (pszDomain != NULL) ? SysStrDup(pszDomain) : NULL;
  107. pPopLnk->pszName = (pszName != NULL) ? SysStrDup(pszName) : NULL;
  108. pPopLnk->pszRmtDomain = (pszRmtDomain != NULL) ? SysStrDup(pszRmtDomain) : NULL;
  109. pPopLnk->pszRmtName = (pszRmtName != NULL) ? SysStrDup(pszRmtName) : NULL;
  110. pPopLnk->pszRmtPassword = (pszRmtPassword != NULL) ? SysStrDup(pszRmtPassword) : NULL;
  111. pPopLnk->pszAuthType = (pszAuthType != NULL) ? SysStrDup(pszAuthType) : NULL;
  112. return (pPopLnk);
  113. }
  114. void GwLkFreePOP3Link(POP3Link * pPopLnk)
  115. {
  116. if (pPopLnk->pszDomain != NULL)
  117. SysFree(pPopLnk->pszDomain);
  118. if (pPopLnk->pszName != NULL)
  119. SysFree(pPopLnk->pszName);
  120. if (pPopLnk->pszRmtDomain != NULL)
  121. SysFree(pPopLnk->pszRmtDomain);
  122. if (pPopLnk->pszRmtName != NULL)
  123. SysFree(pPopLnk->pszRmtName);
  124. if (pPopLnk->pszRmtPassword != NULL)
  125. SysFree(pPopLnk->pszRmtPassword);
  126. if (pPopLnk->pszAuthType != NULL)
  127. SysFree(pPopLnk->pszAuthType);
  128. SysFree(pPopLnk);
  129. }
  130. static int GwLkWriteLink(FILE * pLnkFile, POP3Link * pPopLnk)
  131. {
  132. ///////////////////////////////////////////////////////////////////////////////
  133. //  Domain
  134. ///////////////////////////////////////////////////////////////////////////////
  135. char *pszQuoted = StrQuote(pPopLnk->pszDomain, '"');
  136. if (pszQuoted == NULL)
  137. return (ErrGetErrorCode());
  138. fprintf(pLnkFile, "%st", pszQuoted);
  139. SysFree(pszQuoted);
  140. ///////////////////////////////////////////////////////////////////////////////
  141. //  Local user
  142. ///////////////////////////////////////////////////////////////////////////////
  143. pszQuoted = StrQuote(pPopLnk->pszName, '"');
  144. if (pszQuoted == NULL)
  145. return (ErrGetErrorCode());
  146. fprintf(pLnkFile, "%st", pszQuoted);
  147. SysFree(pszQuoted);
  148. ///////////////////////////////////////////////////////////////////////////////
  149. //  Remote domain
  150. ///////////////////////////////////////////////////////////////////////////////
  151. pszQuoted = StrQuote(pPopLnk->pszRmtDomain, '"');
  152. if (pszQuoted == NULL)
  153. return (ErrGetErrorCode());
  154. fprintf(pLnkFile, "%st", pszQuoted);
  155. SysFree(pszQuoted);
  156. ///////////////////////////////////////////////////////////////////////////////
  157. //  Remote user
  158. ///////////////////////////////////////////////////////////////////////////////
  159. pszQuoted = StrQuote(pPopLnk->pszRmtName, '"');
  160. if (pszQuoted == NULL)
  161. return (ErrGetErrorCode());
  162. fprintf(pLnkFile, "%st", pszQuoted);
  163. SysFree(pszQuoted);
  164. ///////////////////////////////////////////////////////////////////////////////
  165. //  Remote password
  166. ///////////////////////////////////////////////////////////////////////////////
  167. char szPassword[512] = "";
  168. StrCrypt(pPopLnk->pszRmtPassword, szPassword);
  169. pszQuoted = StrQuote(szPassword, '"');
  170. if (pszQuoted == NULL)
  171. return (ErrGetErrorCode());
  172. fprintf(pLnkFile, "%st", pszQuoted);
  173. SysFree(pszQuoted);
  174. ///////////////////////////////////////////////////////////////////////////////
  175. //  Authentication type
  176. ///////////////////////////////////////////////////////////////////////////////
  177. pszQuoted = StrQuote(pPopLnk->pszAuthType, '"');
  178. if (pszQuoted == NULL)
  179. return (ErrGetErrorCode());
  180. fprintf(pLnkFile, "%sn", pszQuoted);
  181. SysFree(pszQuoted);
  182. return (0);
  183. }
  184. int GwLkAddLink(POP3Link * pPopLnk)
  185. {
  186. char szLnkFilePath[SYS_MAX_PATH] = "";
  187. GwLkGetTableFilePath(szLnkFilePath, sizeof(szLnkFilePath));
  188. char szResLock[SYS_MAX_PATH] = "";
  189. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szLnkFilePath, szResLock,
  190.   sizeof(szResLock)));
  191. if (hResLock == INVALID_RLCK_HANDLE)
  192. return (ErrGetErrorCode());
  193. FILE *pLnkFile = fopen(szLnkFilePath, "r+t");
  194. if (pLnkFile == NULL) {
  195. RLckUnlockEX(hResLock);
  196. ErrSetErrorCode(ERR_LINKS_FILE_NOT_FOUND);
  197. return (ERR_LINKS_FILE_NOT_FOUND);
  198. }
  199. char szLnkLine[LINKS_TABLE_LINE_MAX] = "";
  200. while (MscGetConfigLine(szLnkLine, sizeof(szLnkLine) - 1, pLnkFile) != NULL) {
  201. char **ppszStrings = StrGetTabLineStrings(szLnkLine);
  202. if (ppszStrings == NULL)
  203. continue;
  204. int iFieldsCount = StrStringsCount(ppszStrings);
  205. if ((iFieldsCount >= lnkMax) &&
  206.     (stricmp(pPopLnk->pszDomain, ppszStrings[lnkDomain]) == 0) &&
  207.     (stricmp(pPopLnk->pszName, ppszStrings[lnkName]) == 0) &&
  208.     (stricmp(pPopLnk->pszRmtDomain, ppszStrings[lnkRmtDomain]) == 0) &&
  209.     (stricmp(pPopLnk->pszRmtName, ppszStrings[lnkRmtName]) == 0)) {
  210. StrFreeStrings(ppszStrings);
  211. fclose(pLnkFile);
  212. RLckUnlockEX(hResLock);
  213. ErrSetErrorCode(ERR_LINK_EXIST);
  214. return (ERR_LINK_EXIST);
  215. }
  216. StrFreeStrings(ppszStrings);
  217. }
  218. fseek(pLnkFile, 0, SEEK_END);
  219. if (GwLkWriteLink(pLnkFile, pPopLnk) < 0) {
  220. fclose(pLnkFile);
  221. RLckUnlockEX(hResLock);
  222. ErrSetErrorCode(ERR_WRITE_LINKS_FILE);
  223. return (ERR_WRITE_LINKS_FILE);
  224. }
  225. fclose(pLnkFile);
  226. RLckUnlockEX(hResLock);
  227. return (0);
  228. }
  229. int GwLkRemoveLink(POP3Link * pPopLnk)
  230. {
  231. char szLnkFilePath[SYS_MAX_PATH] = "";
  232. GwLkGetTableFilePath(szLnkFilePath, sizeof(szLnkFilePath));
  233. char szTmpFile[SYS_MAX_PATH] = "";
  234. SysGetTmpFile(szTmpFile);
  235. char szResLock[SYS_MAX_PATH] = "";
  236. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szLnkFilePath, szResLock,
  237.   sizeof(szResLock)));
  238. if (hResLock == INVALID_RLCK_HANDLE)
  239. return (ErrGetErrorCode());
  240. FILE *pLnkFile = fopen(szLnkFilePath, "rt");
  241. if (pLnkFile == NULL) {
  242. RLckUnlockEX(hResLock);
  243. ErrSetErrorCode(ERR_LINKS_FILE_NOT_FOUND);
  244. return (ERR_LINKS_FILE_NOT_FOUND);
  245. }
  246. FILE *pTmpFile = fopen(szTmpFile, "wt");
  247. if (pTmpFile == NULL) {
  248. fclose(pLnkFile);
  249. RLckUnlockEX(hResLock);
  250. ErrSetErrorCode(ERR_FILE_CREATE);
  251. return (ERR_FILE_CREATE);
  252. }
  253. int iLinksFound = 0;
  254. char szLnkLine[LINKS_TABLE_LINE_MAX] = "";
  255. while (MscGetConfigLine(szLnkLine, sizeof(szLnkLine) - 1, pLnkFile, false) != NULL) {
  256. if (szLnkLine[0] == TAB_COMMENT_CHAR) {
  257. fprintf(pTmpFile, "%sn", szLnkLine);
  258. continue;
  259. }
  260. char **ppszStrings = StrGetTabLineStrings(szLnkLine);
  261. if (ppszStrings == NULL)
  262. continue;
  263. int iFieldsCount = StrStringsCount(ppszStrings);
  264. if ((iFieldsCount >= lnkMax) &&
  265.     (stricmp(pPopLnk->pszDomain, ppszStrings[lnkDomain]) == 0) &&
  266.     (stricmp(pPopLnk->pszName, ppszStrings[lnkName]) == 0) &&
  267.     (stricmp(pPopLnk->pszRmtDomain, ppszStrings[lnkRmtDomain]) == 0) &&
  268.     (stricmp(pPopLnk->pszRmtName, ppszStrings[lnkRmtName]) == 0)) {
  269. ++iLinksFound;
  270. } else
  271. fprintf(pTmpFile, "%sn", szLnkLine);
  272. StrFreeStrings(ppszStrings);
  273. }
  274. fclose(pLnkFile);
  275. fclose(pTmpFile);
  276. if (iLinksFound == 0) {
  277. SysRemove(szTmpFile);
  278. RLckUnlockEX(hResLock);
  279. ErrSetErrorCode(ERR_LINK_NOT_FOUND);
  280. return (ERR_LINK_NOT_FOUND);
  281. }
  282. char szTmpLnkFilePath[SYS_MAX_PATH] = "";
  283. sprintf(szTmpLnkFilePath, "%s.tmp", szLnkFilePath);
  284. if (MscMoveFile(szLnkFilePath, szTmpLnkFilePath) < 0) {
  285. ErrorPush();
  286. RLckUnlockEX(hResLock);
  287. return (ErrorPop());
  288. }
  289. if (MscMoveFile(szTmpFile, szLnkFilePath) < 0) {
  290. ErrorPush();
  291. MscMoveFile(szTmpLnkFilePath, szLnkFilePath);
  292. RLckUnlockEX(hResLock);
  293. return (ErrorPop());
  294. }
  295. SysRemove(szTmpLnkFilePath);
  296. ///////////////////////////////////////////////////////////////////////////////
  297. //  Remove the disable file if exist
  298. ///////////////////////////////////////////////////////////////////////////////
  299. char szEnableFile[SYS_MAX_PATH] = "";
  300. if (GwLkGetDisableFilePath(pPopLnk, szEnableFile) < 0) {
  301. ErrorPush();
  302. RLckUnlockEX(hResLock);
  303. return (ErrorPop());
  304. }
  305. CheckRemoveFile(szEnableFile);
  306. RLckUnlockEX(hResLock);
  307. return (0);
  308. }
  309. int GwLkRemoveUserLinks(const char *pszDomain, const char *pszName)
  310. {
  311. char szLnkFilePath[SYS_MAX_PATH] = "";
  312. GwLkGetTableFilePath(szLnkFilePath, sizeof(szLnkFilePath));
  313. char szTmpFile[SYS_MAX_PATH] = "";
  314. SysGetTmpFile(szTmpFile);
  315. char szResLock[SYS_MAX_PATH] = "";
  316. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szLnkFilePath, szResLock,
  317.   sizeof(szResLock)));
  318. if (hResLock == INVALID_RLCK_HANDLE) {
  319. ErrorPush();
  320. CheckRemoveFile(szTmpFile);
  321. return (ErrorPop());
  322. }
  323. FILE *pLnkFile = fopen(szLnkFilePath, "rt");
  324. if (pLnkFile == NULL) {
  325. RLckUnlockEX(hResLock);
  326. ErrSetErrorCode(ERR_LINKS_FILE_NOT_FOUND);
  327. return (ERR_LINKS_FILE_NOT_FOUND);
  328. }
  329. FILE *pTmpFile = fopen(szTmpFile, "wt");
  330. if (pTmpFile == NULL) {
  331. fclose(pLnkFile);
  332. RLckUnlockEX(hResLock);
  333. ErrSetErrorCode(ERR_FILE_CREATE);
  334. return (ERR_FILE_CREATE);
  335. }
  336. int iLinksFound = 0;
  337. char szLnkLine[LINKS_TABLE_LINE_MAX] = "";
  338. while (MscGetConfigLine(szLnkLine, sizeof(szLnkLine) - 1, pLnkFile, false) != NULL) {
  339. if (szLnkLine[0] == TAB_COMMENT_CHAR) {
  340. fprintf(pTmpFile, "%sn", szLnkLine);
  341. continue;
  342. }
  343. char **ppszStrings = StrGetTabLineStrings(szLnkLine);
  344. if (ppszStrings == NULL)
  345. continue;
  346. int iFieldsCount = StrStringsCount(ppszStrings);
  347. if ((iFieldsCount >= lnkMax) && (stricmp(pszDomain, ppszStrings[lnkDomain]) == 0)
  348.     && (stricmp(pszName, ppszStrings[lnkName]) == 0)) {
  349. ++iLinksFound;
  350. } else
  351. fprintf(pTmpFile, "%sn", szLnkLine);
  352. StrFreeStrings(ppszStrings);
  353. }
  354. fclose(pLnkFile);
  355. fclose(pTmpFile);
  356. if (iLinksFound == 0) {
  357. SysRemove(szTmpFile);
  358. RLckUnlockEX(hResLock);
  359. return (0);
  360. }
  361. char szTmpLnkFilePath[SYS_MAX_PATH] = "";
  362. sprintf(szTmpLnkFilePath, "%s.tmp", szLnkFilePath);
  363. if (MscMoveFile(szLnkFilePath, szTmpLnkFilePath) < 0) {
  364. ErrorPush();
  365. RLckUnlockEX(hResLock);
  366. return (ErrorPop());
  367. }
  368. if (MscMoveFile(szTmpFile, szLnkFilePath) < 0) {
  369. ErrorPush();
  370. MscMoveFile(szTmpLnkFilePath, szLnkFilePath);
  371. RLckUnlockEX(hResLock);
  372. return (ErrorPop());
  373. }
  374. SysRemove(szTmpLnkFilePath);
  375. RLckUnlockEX(hResLock);
  376. return (0);
  377. }
  378. int GwLkRemoveDomainLinks(const char *pszDomain)
  379. {
  380. char szLnkFilePath[SYS_MAX_PATH] = "";
  381. GwLkGetTableFilePath(szLnkFilePath, sizeof(szLnkFilePath));
  382. char szTmpFile[SYS_MAX_PATH] = "";
  383. SysGetTmpFile(szTmpFile);
  384. char szResLock[SYS_MAX_PATH] = "";
  385. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szLnkFilePath, szResLock,
  386.   sizeof(szResLock)));
  387. if (hResLock == INVALID_RLCK_HANDLE) {
  388. ErrorPush();
  389. CheckRemoveFile(szTmpFile);
  390. return (ErrorPop());
  391. }
  392. FILE *pLnkFile = fopen(szLnkFilePath, "rt");
  393. if (pLnkFile == NULL) {
  394. RLckUnlockEX(hResLock);
  395. CheckRemoveFile(szTmpFile);
  396. ErrSetErrorCode(ERR_LINKS_FILE_NOT_FOUND);
  397. return (ERR_LINKS_FILE_NOT_FOUND);
  398. }
  399. FILE *pTmpFile = fopen(szTmpFile, "wt");
  400. if (pTmpFile == NULL) {
  401. fclose(pLnkFile);
  402. RLckUnlockEX(hResLock);
  403. CheckRemoveFile(szTmpFile);
  404. ErrSetErrorCode(ERR_FILE_CREATE);
  405. return (ERR_FILE_CREATE);
  406. }
  407. int iLinksFound = 0;
  408. char szLnkLine[LINKS_TABLE_LINE_MAX] = "";
  409. while (MscGetConfigLine(szLnkLine, sizeof(szLnkLine) - 1, pLnkFile, false) != NULL) {
  410. if (szLnkLine[0] == TAB_COMMENT_CHAR) {
  411. fprintf(pTmpFile, "%sn", szLnkLine);
  412. continue;
  413. }
  414. char **ppszStrings = StrGetTabLineStrings(szLnkLine);
  415. if (ppszStrings == NULL)
  416. continue;
  417. int iFieldsCount = StrStringsCount(ppszStrings);
  418. if ((iFieldsCount >= lnkMax) && (stricmp(pszDomain, ppszStrings[lnkDomain]) == 0)) {
  419. ++iLinksFound;
  420. } else
  421. fprintf(pTmpFile, "%sn", szLnkLine);
  422. StrFreeStrings(ppszStrings);
  423. }
  424. fclose(pLnkFile);
  425. fclose(pTmpFile);
  426. if (iLinksFound == 0) {
  427. SysRemove(szTmpFile);
  428. RLckUnlockEX(hResLock);
  429. return (0);
  430. }
  431. char szTmpLnkFilePath[SYS_MAX_PATH] = "";
  432. sprintf(szTmpLnkFilePath, "%s.tmp", szLnkFilePath);
  433. if (MscMoveFile(szLnkFilePath, szTmpLnkFilePath) < 0) {
  434. ErrorPush();
  435. SysRemove(szTmpFile);
  436. RLckUnlockEX(hResLock);
  437. return (ErrorPop());
  438. }
  439. if (MscMoveFile(szTmpFile, szLnkFilePath) < 0) {
  440. ErrorPush();
  441. MscMoveFile(szTmpLnkFilePath, szLnkFilePath);
  442. SysRemove(szTmpFile);
  443. RLckUnlockEX(hResLock);
  444. return (ErrorPop());
  445. }
  446. SysRemove(szTmpLnkFilePath);
  447. RLckUnlockEX(hResLock);
  448. return (0);
  449. }
  450. int GwLkGetDBFileSnapShot(const char *pszFileName)
  451. {
  452. char szGwLkFilePath[SYS_MAX_PATH] = "";
  453. GwLkGetTableFilePath(szGwLkFilePath, sizeof(szGwLkFilePath));
  454. char szResLock[SYS_MAX_PATH] = "";
  455. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szGwLkFilePath, szResLock,
  456.   sizeof(szResLock)));
  457. if (hResLock == INVALID_RLCK_HANDLE)
  458. return (ErrGetErrorCode());
  459. if (MscCopyFile(pszFileName, szGwLkFilePath) < 0) {
  460. ErrorPush();
  461. RLckUnlockSH(hResLock);
  462. return (ErrorPop());
  463. }
  464. RLckUnlockSH(hResLock);
  465. return (0);
  466. }
  467. GWLKF_HANDLE GwLkOpenDB(void)
  468. {
  469. GwLkDBScanData *pGLSD = (GwLkDBScanData *) SysAlloc(sizeof(GwLkDBScanData));
  470. if (pGLSD == NULL)
  471. return (INVALID_GWLKF_HANDLE);
  472. SysGetTmpFile(pGLSD->szTmpDBFile);
  473. if (GwLkGetDBFileSnapShot(pGLSD->szTmpDBFile) < 0) {
  474. SysFree(pGLSD);
  475. return (INVALID_GWLKF_HANDLE);
  476. }
  477. if ((pGLSD->pDBFile = fopen(pGLSD->szTmpDBFile, "rt")) == NULL) {
  478. SysRemove(pGLSD->szTmpDBFile);
  479. SysFree(pGLSD);
  480. ErrSetErrorCode(ERR_FILE_OPEN);
  481. return (INVALID_GWLKF_HANDLE);
  482. }
  483. return ((GWLKF_HANDLE) pGLSD);
  484. }
  485. void GwLkCloseDB(GWLKF_HANDLE hLinksDB)
  486. {
  487. GwLkDBScanData *pGLSD = (GwLkDBScanData *) hLinksDB;
  488. fclose(pGLSD->pDBFile);
  489. SysRemove(pGLSD->szTmpDBFile);
  490. SysFree(pGLSD);
  491. }
  492. POP3Link *GwLkGetFirstUser(GWLKF_HANDLE hLinksDB)
  493. {
  494. GwLkDBScanData *pGLSD = (GwLkDBScanData *) hLinksDB;
  495. rewind(pGLSD->pDBFile);
  496. POP3Link *pPopLnk = NULL;
  497. char szLnkLine[LINKS_TABLE_LINE_MAX] = "";
  498. while ((pPopLnk == NULL) &&
  499.        (MscGetConfigLine(szLnkLine, sizeof(szLnkLine) - 1, pGLSD->pDBFile) != NULL)) {
  500. char **ppszStrings = StrGetTabLineStrings(szLnkLine);
  501. if (ppszStrings == NULL)
  502. continue;
  503. int iFieldsCount = StrStringsCount(ppszStrings);
  504. if (iFieldsCount >= lnkMax)
  505. pPopLnk = GwLkGetLinkFromStrings(ppszStrings);
  506. StrFreeStrings(ppszStrings);
  507. }
  508. return (pPopLnk);
  509. }
  510. POP3Link *GwLkGetNextUser(GWLKF_HANDLE hLinksDB)
  511. {
  512. GwLkDBScanData *pGLSD = (GwLkDBScanData *) hLinksDB;
  513. POP3Link *pPopLnk = NULL;
  514. char szLnkLine[LINKS_TABLE_LINE_MAX] = "";
  515. while ((pPopLnk == NULL) &&
  516.        (MscGetConfigLine(szLnkLine, sizeof(szLnkLine) - 1, pGLSD->pDBFile) != NULL)) {
  517. char **ppszStrings = StrGetTabLineStrings(szLnkLine);
  518. if (ppszStrings == NULL)
  519. continue;
  520. int iFieldsCount = StrStringsCount(ppszStrings);
  521. if (iFieldsCount >= lnkMax)
  522. pPopLnk = GwLkGetLinkFromStrings(ppszStrings);
  523. StrFreeStrings(ppszStrings);
  524. }
  525. return (pPopLnk);
  526. }
  527. static char *GwLkSanitizeFileName(char const *pszInName, char *pszOutName, int iOutSize)
  528. {
  529. int i;
  530. for (i = 0, iOutSize--; i < iOutSize && *pszInName != ''; i++, pszInName++) {
  531. switch (*pszInName) {
  532. case ':':
  533. case '/':
  534. case '\':
  535. pszOutName[i] = '_';
  536. break;
  537. default:
  538. pszOutName[i] = *pszInName;
  539. }
  540. }
  541. pszOutName[i] = '';
  542. return (pszOutName);
  543. }
  544. static char *GwLkGetLockFileName(POP3Link const *pPopLnk, char *pszLockFile)
  545. {
  546. char szLocksDir[SYS_MAX_PATH] = "";
  547. char szRmtDomain[MAX_HOST_NAME] = "";
  548. char szRmtName[MAX_HOST_NAME] = "";
  549. GwLkGetLocksDir(szLocksDir, sizeof(szLocksDir));
  550. GwLkSanitizeFileName(pPopLnk->pszRmtDomain, szRmtDomain, sizeof(szRmtDomain) - 1);
  551. GwLkSanitizeFileName(pPopLnk->pszRmtName, szRmtName, sizeof(szRmtName) - 1);
  552. sprintf(pszLockFile, "%s%s%s@%s", szLocksDir, SYS_SLASH_STR, szRmtName,
  553. szRmtDomain);
  554. return (pszLockFile);
  555. }
  556. int GwLkLinkLock(POP3Link const *pPopLnk)
  557. {
  558. char szLockFile[SYS_MAX_PATH] = "";
  559. GwLkGetLockFileName(pPopLnk, szLockFile);
  560. return (SysLockFile(szLockFile));
  561. }
  562. void GwLkLinkUnlock(POP3Link const *pPopLnk)
  563. {
  564. char szLockFile[SYS_MAX_PATH] = "";
  565. GwLkGetLockFileName(pPopLnk, szLockFile);
  566. SysUnlockFile(szLockFile);
  567. }
  568. int GwLkClearLinkLocksDir(void)
  569. {
  570. char szLocksDir[SYS_MAX_PATH] = "";
  571. GwLkGetLocksDir(szLocksDir, sizeof(szLocksDir));
  572. return (MscClearDirectory(szLocksDir));
  573. }
  574. int GwLkLocalDomain(POP3Link const *pPopLnk)
  575. {
  576. return (((pPopLnk != NULL) && (pPopLnk->pszDomain[0] != '@') &&
  577.  (pPopLnk->pszDomain[0] != '?') && (pPopLnk->pszDomain[0] != '&')) ? 1 : 0);
  578. }
  579. int GwLkMasqueradeDomain(POP3Link const *pPopLnk)
  580. {
  581. return (((pPopLnk != NULL) &&
  582.  ((pPopLnk->pszDomain[0] == '?') || (pPopLnk->pszDomain[0] == '&'))) ? 1 : 0);
  583. }
  584. static int GwLkGetDisableFilePath(POP3Link const *pPopLnk, char *pszEnableFile)
  585. {
  586. if (GwLkLocalDomain(pPopLnk)) {
  587. UserInfo *pUI = UsrGetUserByName(pPopLnk->pszDomain, pPopLnk->pszName);
  588. if (pUI == NULL)
  589. return (ErrGetErrorCode());
  590. char szUserPath[SYS_MAX_PATH] = "";
  591. if (UsrGetUserPath(pUI, szUserPath, sizeof(szUserPath), 1) == NULL) {
  592. ErrorPush();
  593. UsrFreeUserInfo(pUI);
  594. return (ErrorPop());
  595. }
  596. UsrFreeUserInfo(pUI);
  597. sprintf(pszEnableFile, "%s%s@%s.disabled", szUserPath, pPopLnk->pszRmtName,
  598. pPopLnk->pszRmtDomain);
  599. } else {
  600. char szEnableDir[SYS_MAX_PATH] = "";
  601. GwLkEnableDir(szEnableDir, sizeof(szEnableDir));
  602. sprintf(pszEnableFile, "%s%s%s@%s.disabled", szEnableDir, SYS_SLASH_STR,
  603. pPopLnk->pszRmtName, pPopLnk->pszRmtDomain);
  604. }
  605. return (0);
  606. }
  607. int GwLkCheckEnabled(POP3Link const *pPopLnk)
  608. {
  609. char szEnableFile[SYS_MAX_PATH] = "";
  610. if (GwLkGetDisableFilePath(pPopLnk, szEnableFile) < 0)
  611. return (ErrGetErrorCode());
  612. if (SysExistFile(szEnableFile)) {
  613. ErrSetErrorCode(ERR_POP3_EXTERNAL_LINK_DISABLED);
  614. return (ERR_POP3_EXTERNAL_LINK_DISABLED);
  615. }
  616. return (0);
  617. }
  618. int GwLkEnable(POP3Link const *pPopLnk, bool bEnable)
  619. {
  620. char szEnableFile[SYS_MAX_PATH] = "";
  621. if (GwLkGetDisableFilePath(pPopLnk, szEnableFile) < 0)
  622. return (ErrGetErrorCode());
  623. if (bEnable)
  624. CheckRemoveFile(szEnableFile);
  625. else {
  626. FILE *pFile = fopen(szEnableFile, "wt");
  627. if (pFile == NULL) {
  628. ErrSetErrorCode(ERR_FILE_CREATE);
  629. return (ERR_FILE_CREATE);
  630. }
  631. time_t tCurr;
  632. time(&tCurr);
  633. struct tm tmTime;
  634. char szTime[256] = "";
  635. SysLocalTime(&tCurr, &tmTime);
  636. strftime(szTime, sizeof(szTime), "%d %b %Y %H:%M:%S %Z", &tmTime);
  637. fprintf(pFile, "%sn", szTime);
  638. fclose(pFile);
  639. }
  640. return (0);
  641. }
  642. int GwLkEnable(char const *pszDomain, char const *pszName,
  643.        char const *pszRmtDomain, char const *pszRmtName, bool bEnable)
  644. {
  645. GWLKF_HANDLE hLinksDB = GwLkOpenDB();
  646. if (hLinksDB == INVALID_GWLKF_HANDLE)
  647. return (ErrGetErrorCode());
  648. int iMatchingUsers = 0;
  649. POP3Link *pPopLnk = GwLkGetFirstUser(hLinksDB);
  650. for (; pPopLnk != NULL; pPopLnk = GwLkGetNextUser(hLinksDB)) {
  651. if ((stricmp(pPopLnk->pszDomain, pszDomain) == 0) &&
  652.     (stricmp(pPopLnk->pszName, pszName) == 0) &&
  653.     ((pszRmtDomain == NULL) ||
  654.      (stricmp(pPopLnk->pszRmtDomain, pszRmtDomain) == 0)) && ((pszRmtName == NULL)
  655.       ||
  656.       (stricmp
  657.        (pPopLnk->
  658. pszRmtName,
  659. pszRmtName) ==
  660.        0))) {
  661. GwLkEnable(pPopLnk, bEnable);
  662. ++iMatchingUsers;
  663. }
  664. GwLkFreePOP3Link(pPopLnk);
  665. }
  666. GwLkCloseDB(hLinksDB);
  667. if (iMatchingUsers == 0) {
  668. ErrSetErrorCode(ERR_LINK_NOT_FOUND);
  669. return (ERR_LINK_NOT_FOUND);
  670. }
  671. return (0);
  672. }