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

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 "UsrUtils.h"
  32. #include "SvrUtils.h"
  33. #include "MessQueue.h"
  34. #include "SMAILUtils.h"
  35. #include "QueueUtils.h"
  36. #include "MailSvr.h"
  37. #include "MiscUtils.h"
  38. #include "MailDomains.h"
  39. #include "POP3GwLink.h"
  40. #include "ExtAliases.h"
  41. #include "Maildir.h"
  42. #include "TabIndex.h"
  43. #include "SMTPUtils.h"
  44. #include "AliasDomain.h"
  45. #include "UsrAuth.h"
  46. #define SVR_TABLE_FILE              "mailusers.tab"
  47. #define SVR_ALIAS_FILE              "aliases.tab"
  48. #define WILD_ALIASES_HASH           0
  49. #define USR_TABLE_LINE_MAX          2048
  50. #define USR_ALIAS_LINE_MAX          512
  51. #define USER_PROFILE_FILE           "user.tab"
  52. #define DEFAULT_USER_PROFILE_FILE   "userdef.tab"
  53. #define MAILBOX_DIRECTORY           "mailbox"
  54. #define POP3_LOCKS_DIR              "pop3locks"
  55. #define MLUSERS_TABLE_FILE          "mlusers.tab"
  56. #define MAILPROCESS_FILE            "mailproc.tab"
  57. enum UsrFileds {
  58. usrDomain = 0,
  59. usrName,
  60. usrPassword,
  61. usrID,
  62. usrPath,
  63. usrType,
  64. usrMax
  65. };
  66. struct UserInfoVar {
  67. LISTLINK LL;
  68. char *pszName;
  69. char *pszValue;
  70. };
  71. enum AliasFileds {
  72. alsDomain = 0,
  73. alsAlias,
  74. alsName,
  75. alsMax
  76. };
  77. struct UsersDBScanData {
  78. char szTmpDBFile[SYS_MAX_PATH];
  79. FILE *pDBFile;
  80. };
  81. struct AliasDBScanData {
  82. char szTmpDBFile[SYS_MAX_PATH];
  83. FILE *pDBFile;
  84. };
  85. static int UsrCalcAliasHash(char const *const *ppszTabTokens, int const *piFieldsIdx,
  86.     SYS_UINT32 * puHashVal, bool bCaseSens);
  87. static int UsrRebuildUsersIndexes(char const *pszUsrFilePath);
  88. static int UsrRebuildAliasesIndexes(char const *pszAlsFilePath);
  89. static char *UsrGetTableFilePath(char *pszUsrFilePath, int iMaxPath);
  90. static char *UsrGetAliasFilePath(char *pszAlsFilePath, int iMaxPath);
  91. static UserInfo *UsrGetUserFromStrings(char **ppszStrings);
  92. static UserInfoVar *UsrAllocVar(const char *pszName, const char *pszValue);
  93. static void UsrFreeVar(UserInfoVar * pUIV);
  94. static void UsrFreeInfoList(HSLIST & InfoList);
  95. static UserInfoVar *UsrGetUserVar(HSLIST & InfoList, const char *pszName);
  96. static int UsrWriteInfoList(HSLIST & InfoList, FILE * pProfileFile);
  97. static int UsrLoadUserInfo(HSLIST & InfoList, unsigned int uUserID, const char *pszFilePath);
  98. static int UsrGetDefaultInfoFile(char const *pszDomain, char *pszInfoFile, int iMaxPath);
  99. static int UsrLoadUserDefaultInfo(HSLIST & InfoList, char const *pszDomain = NULL);
  100. static int UsrAliasLookupNameLK(const char *pszAlsFilePath, const char *pszDomain,
  101. const char *pszAlias, char *pszName = NULL, bool bWildMatch =
  102. true);
  103. static int UsrWriteAlias(FILE * pAlsFile, AliasInfo * pAI);
  104. static bool UsrIsWildAlias(char const *pszAlias);
  105. static int UsrRemoveUserAlias(char const *pszDomain, char const *pszName);
  106. static UserInfo *UsrGetUserByNameLK(const char *pszUsrFilePath, const char *pszDomain,
  107.     const char *pszName);
  108. static UserInfo *UsrGetUserByNameOrAliasNDA(const char *pszDomain, const char *pszName,
  109.     char *pszRealAddr);
  110. static int UsrDropUserEnv(UserInfo * pUI);
  111. static int UsrWriteUser(UserInfo * pUI, FILE * pUsrFile);
  112. static char const *UsrGetMailboxDir(void);
  113. static int UsrCreateMailbox(char const *pszUsrUserPath);
  114. static int UsrPrepareUserEnv(UserInfo * pUI);
  115. static char *UsrGetPop3LocksPath(UserInfo * pUI, char *pszPop3LockPath, int iMaxPath);
  116. static int iIdxUser_Domain_Name[] = {
  117. usrDomain,
  118. usrName,
  119. INDEX_SEQUENCE_TERMINATOR
  120. };
  121. static int iIdxAlias_Domain_Alias[] = {
  122. alsDomain,
  123. alsAlias,
  124. INDEX_SEQUENCE_TERMINATOR
  125. };
  126. static int UsrCalcAliasHash(char const *const *ppszTabTokens, int const *piFieldsIdx,
  127.     SYS_UINT32 * puHashVal, bool bCaseSens)
  128. {
  129. ///////////////////////////////////////////////////////////////////////////////
  130. //  This will group wild alias ( * ? )
  131. ///////////////////////////////////////////////////////////////////////////////
  132. int iFieldsCount = StrStringsCount(ppszTabTokens);
  133. if ((iFieldsCount > alsAlias) &&
  134.     (UsrIsWildAlias(ppszTabTokens[alsAlias]) || UsrIsWildAlias(ppszTabTokens[alsDomain])))
  135. {
  136. *puHashVal = WILD_ALIASES_HASH;
  137. return (0);
  138. }
  139. return (TbixCalculateHash(ppszTabTokens, piFieldsIdx, puHashVal, bCaseSens));
  140. }
  141. int UsrCheckUsersIndexes(void)
  142. {
  143. char szUsrFilePath[SYS_MAX_PATH] = "";
  144. UsrGetTableFilePath(szUsrFilePath, sizeof(szUsrFilePath));
  145. ///////////////////////////////////////////////////////////////////////////////
  146. //  Align Domain-Name index
  147. ///////////////////////////////////////////////////////////////////////////////
  148. if (TbixCheckIndex(szUsrFilePath, iIdxUser_Domain_Name, false) < 0)
  149. return (ErrGetErrorCode());
  150. return (0);
  151. }
  152. int UsrCheckAliasesIndexes(void)
  153. {
  154. char szAlsFilePath[SYS_MAX_PATH] = "";
  155. UsrGetAliasFilePath(szAlsFilePath, sizeof(szAlsFilePath));
  156. ///////////////////////////////////////////////////////////////////////////////
  157. //  Align Domain-Alias index
  158. ///////////////////////////////////////////////////////////////////////////////
  159. if (TbixCheckIndex(szAlsFilePath, iIdxAlias_Domain_Alias, false, UsrCalcAliasHash) < 0)
  160. return (ErrGetErrorCode());
  161. return (0);
  162. }
  163. static int UsrRebuildUsersIndexes(char const *pszUsrFilePath)
  164. {
  165. ///////////////////////////////////////////////////////////////////////////////
  166. //  Rebuild Domain-Name index
  167. ///////////////////////////////////////////////////////////////////////////////
  168. if (TbixCreateIndex(pszUsrFilePath, iIdxUser_Domain_Name, false) < 0)
  169. return (ErrGetErrorCode());
  170. return (0);
  171. }
  172. static int UsrRebuildAliasesIndexes(char const *pszAlsFilePath)
  173. {
  174. ///////////////////////////////////////////////////////////////////////////////
  175. //  Rebuild Domain-Alias index
  176. ///////////////////////////////////////////////////////////////////////////////
  177. if (TbixCreateIndex(pszAlsFilePath, iIdxAlias_Domain_Alias, false, UsrCalcAliasHash) < 0)
  178. return (ErrGetErrorCode());
  179. return (0);
  180. }
  181. static char *UsrGetTableFilePath(char *pszUsrFilePath, int iMaxPath)
  182. {
  183. CfgGetRootPath(pszUsrFilePath, iMaxPath);
  184. StrNCat(pszUsrFilePath, SVR_TABLE_FILE, iMaxPath);
  185. return (pszUsrFilePath);
  186. }
  187. static char *UsrGetAliasFilePath(char *pszAlsFilePath, int iMaxPath)
  188. {
  189. CfgGetRootPath(pszAlsFilePath, iMaxPath);
  190. StrNCat(pszAlsFilePath, SVR_ALIAS_FILE, iMaxPath);
  191. return (pszAlsFilePath);
  192. }
  193. char *UsrGetMLTableFilePath(UserInfo * pUI, char *pszMLTablePath, int iMaxPath)
  194. {
  195. UsrGetUserPath(pUI, pszMLTablePath, iMaxPath, 1);
  196. StrNCat(pszMLTablePath, MLUSERS_TABLE_FILE, iMaxPath);
  197. return (pszMLTablePath);
  198. }
  199. UserType UsrGetUserType(UserInfo * pUI)
  200. {
  201. if (pUI->pszType == NULL)
  202. return (usrTypeError);
  203. switch (ToUpper(pUI->pszType[0])) {
  204. case ('U'):
  205. return (usrTypeUser);
  206. case ('M'):
  207. return (usrTypeML);
  208. }
  209. return (usrTypeError);
  210. }
  211. UserInfo *UsrCreateDefaultUser(char const *pszDomain, char const *pszName,
  212.        char const *pszPassword, UserType TypeUser)
  213. {
  214. UserInfo *pUI = (UserInfo *) SysAlloc(sizeof(UserInfo));
  215. if (pUI == NULL)
  216. return (NULL);
  217. pUI->pszDomain = SysStrDup(pszDomain);
  218. pUI->uUserID = 0;
  219. pUI->pszName = SysStrDup(pszName);
  220. pUI->pszPassword = SysStrDup(pszPassword);
  221. pUI->pszPath = SysStrDup(pszName);
  222. pUI->pszType = SysStrDup((TypeUser == usrTypeUser) ? "U" : "M");
  223. ///////////////////////////////////////////////////////////////////////////////
  224. //  Load user profile
  225. ///////////////////////////////////////////////////////////////////////////////
  226. ListInit(pUI->InfoList);
  227. UsrLoadUserDefaultInfo(pUI->InfoList, pszDomain);
  228. return (pUI);
  229. }
  230. static UserInfo *UsrGetUserFromStrings(char **ppszStrings)
  231. {
  232. int iFieldsCount = StrStringsCount(ppszStrings);
  233. if (iFieldsCount < usrMax)
  234. return (NULL);
  235. char szPassword[512] = "";
  236. if (StrDeCrypt(ppszStrings[usrPassword], szPassword) == NULL)
  237. return (NULL);
  238. UserInfo *pUI = (UserInfo *) SysAlloc(sizeof(UserInfo));
  239. if (pUI == NULL)
  240. return (NULL);
  241. pUI->pszDomain = SysStrDup(ppszStrings[usrDomain]);
  242. pUI->uUserID = (unsigned int) atol(ppszStrings[usrID]);
  243. pUI->pszName = SysStrDup(ppszStrings[usrName]);
  244. pUI->pszPassword = SysStrDup(szPassword);
  245. pUI->pszPath = SysStrDup(ppszStrings[usrPath]);
  246. pUI->pszType = SysStrDup(ppszStrings[usrType]);
  247. ///////////////////////////////////////////////////////////////////////////////
  248. //  Load user profile
  249. ///////////////////////////////////////////////////////////////////////////////
  250. ListInit(pUI->InfoList);
  251. char szUsrFilePath[SYS_MAX_PATH] = "";
  252. UsrGetUserPath(pUI, szUsrFilePath, sizeof(szUsrFilePath), 1);
  253. StrNCat(szUsrFilePath, USER_PROFILE_FILE, sizeof(szUsrFilePath));
  254. UsrLoadUserInfo(pUI->InfoList, pUI->uUserID, szUsrFilePath);
  255. return (pUI);
  256. }
  257. void UsrFreeUserInfo(UserInfo * pUI)
  258. {
  259. UsrFreeInfoList(pUI->InfoList);
  260. if (pUI->pszDomain != NULL)
  261. SysFree(pUI->pszDomain);
  262. if (pUI->pszPassword != NULL)
  263. SysFree(pUI->pszPassword);
  264. if (pUI->pszName != NULL)
  265. SysFree(pUI->pszName);
  266. if (pUI->pszPath != NULL)
  267. SysFree(pUI->pszPath);
  268. if (pUI->pszType != NULL)
  269. SysFree(pUI->pszType);
  270. SysFree(pUI);
  271. }
  272. char *UsrGetUserInfoVar(UserInfo * pUI, const char *pszName, const char *pszDefault)
  273. {
  274. UserInfoVar *pUIV = UsrGetUserVar(pUI->InfoList, pszName);
  275. if (pUIV != NULL)
  276. return (SysStrDup(pUIV->pszValue));
  277. return ((pszDefault != NULL) ? SysStrDup(pszDefault) : NULL);
  278. }
  279. int UsrGetUserInfoVarInt(UserInfo * pUI, const char *pszName, int iDefault)
  280. {
  281. UserInfoVar *pUIV = UsrGetUserVar(pUI->InfoList, pszName);
  282. return ((pUIV != NULL) ? atoi(pUIV->pszValue) : iDefault);
  283. }
  284. int UsrDelUserInfoVar(UserInfo * pUI, const char *pszName)
  285. {
  286. UserInfoVar *pUIV = UsrGetUserVar(pUI->InfoList, pszName);
  287. if (pUIV == NULL) {
  288. ErrSetErrorCode(ERR_USER_VAR_NOT_FOUND);
  289. return (ERR_USER_VAR_NOT_FOUND);
  290. }
  291. ListRemovePtr(pUI->InfoList, (PLISTLINK) pUIV);
  292. UsrFreeVar(pUIV);
  293. return (0);
  294. }
  295. int UsrSetUserInfoVar(UserInfo * pUI, const char *pszName, const char *pszValue)
  296. {
  297. UserInfoVar *pUIV = UsrGetUserVar(pUI->InfoList, pszName);
  298. if (pUIV != NULL) {
  299. SysFree(pUIV->pszValue);
  300. pUIV->pszValue = SysStrDup(pszValue);
  301. } else {
  302. UserInfoVar *pUIV = UsrAllocVar(pszName, pszValue);
  303. if (pUIV == NULL)
  304. return (ErrGetErrorCode());
  305. ListAddTail(pUI->InfoList, (PLISTLINK) pUIV);
  306. }
  307. return (0);
  308. }
  309. char **UsrGetProfileVars(UserInfo * pUI)
  310. {
  311. int iVarsCount = ListGetCount(pUI->InfoList);
  312. char **ppszVars = (char **) SysAlloc((iVarsCount + 1) * sizeof(char *));
  313. if (ppszVars == NULL)
  314. return (NULL);
  315. int iCurrVar = 0;
  316. UserInfoVar *pUIV = (UserInfoVar *) ListFirst(pUI->InfoList);
  317. for (; pUIV != INVALID_SLIST_PTR; pUIV = (UserInfoVar *)
  318.      ListNext(pUI->InfoList, (PLISTLINK) pUIV))
  319. ppszVars[iCurrVar++] = SysStrDup(pUIV->pszName);
  320. ppszVars[iCurrVar] = NULL;
  321. return (ppszVars);
  322. }
  323. static UserInfoVar *UsrAllocVar(const char *pszName, const char *pszValue)
  324. {
  325. UserInfoVar *pUIV = (UserInfoVar *) SysAlloc(sizeof(UserInfoVar));
  326. if (pUIV == NULL)
  327. return (NULL);
  328. ListLinkInit(pUIV);
  329. pUIV->pszName = SysStrDup(pszName);
  330. pUIV->pszValue = SysStrDup(pszValue);
  331. return (pUIV);
  332. }
  333. static void UsrFreeVar(UserInfoVar * pUIV)
  334. {
  335. SysFree(pUIV->pszName);
  336. SysFree(pUIV->pszValue);
  337. SysFree(pUIV);
  338. }
  339. static void UsrFreeInfoList(HSLIST & InfoList)
  340. {
  341. UserInfoVar *pUIV;
  342. while ((pUIV = (UserInfoVar *) ListRemove(InfoList)) != INVALID_SLIST_PTR)
  343. UsrFreeVar(pUIV);
  344. }
  345. static UserInfoVar *UsrGetUserVar(HSLIST & InfoList, const char *pszName)
  346. {
  347. UserInfoVar *pUIV = (UserInfoVar *) ListFirst(InfoList);
  348. for (; pUIV != INVALID_SLIST_PTR; pUIV = (UserInfoVar *)
  349.      ListNext(InfoList, (PLISTLINK) pUIV))
  350. if (strcmp(pUIV->pszName, pszName) == 0)
  351. return (pUIV);
  352. return (NULL);
  353. }
  354. static int UsrWriteInfoList(HSLIST & InfoList, FILE * pProfileFile)
  355. {
  356. UserInfoVar *pUIV = (UserInfoVar *) ListFirst(InfoList);
  357. for (; pUIV != INVALID_SLIST_PTR; pUIV = (UserInfoVar *)
  358.      ListNext(InfoList, (PLISTLINK) pUIV)) {
  359. ///////////////////////////////////////////////////////////////////////////////
  360. //  Write variabile name
  361. ///////////////////////////////////////////////////////////////////////////////
  362. char *pszQuoted = StrQuote(pUIV->pszName, '"');
  363. if (pszQuoted == NULL)
  364. return (ErrGetErrorCode());
  365. fprintf(pProfileFile, "%st", pszQuoted);
  366. SysFree(pszQuoted);
  367. ///////////////////////////////////////////////////////////////////////////////
  368. //  Write variabile value
  369. ///////////////////////////////////////////////////////////////////////////////
  370. pszQuoted = StrQuote(pUIV->pszValue, '"');
  371. if (pszQuoted == NULL)
  372. return (ErrGetErrorCode());
  373. fprintf(pProfileFile, "%sn", pszQuoted);
  374. SysFree(pszQuoted);
  375. }
  376. return (0);
  377. }
  378. static int UsrLoadUserInfo(HSLIST & InfoList, unsigned int uUserID, const char *pszFilePath)
  379. {
  380. char szResLock[SYS_MAX_PATH] = "";
  381. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(pszFilePath, szResLock,
  382.   sizeof(szResLock)));
  383. if (hResLock == INVALID_RLCK_HANDLE)
  384. return (ErrGetErrorCode());
  385. FILE *pProfileFile = fopen(pszFilePath, "rt");
  386. if (pProfileFile == NULL) {
  387. RLckUnlockSH(hResLock);
  388. ErrSetErrorCode(ERR_NO_USER_PRFILE);
  389. return (ERR_NO_USER_PRFILE);
  390. }
  391. char szProfileLine[USR_TABLE_LINE_MAX] = "";
  392. while (MscFGets(szProfileLine, sizeof(szProfileLine) - 1, pProfileFile) != NULL) {
  393. if (szProfileLine[0] == TAB_COMMENT_CHAR)
  394. continue;
  395. char **ppszStrings = StrGetTabLineStrings(szProfileLine);
  396. if (ppszStrings == NULL)
  397. continue;
  398. int iFieldsCount = StrStringsCount(ppszStrings);
  399. if (iFieldsCount == 2) {
  400. UserInfoVar *pUIV = UsrAllocVar(ppszStrings[0], ppszStrings[1]);
  401. if (pUIV != NULL)
  402. ListAddTail(InfoList, (PLISTLINK) pUIV);
  403. }
  404. StrFreeStrings(ppszStrings);
  405. }
  406. fclose(pProfileFile);
  407. RLckUnlockSH(hResLock);
  408. return (0);
  409. }
  410. static int UsrGetDefaultInfoFile(char const *pszDomain, char *pszInfoFile, int iMaxPath)
  411. {
  412. if (pszDomain != NULL) {
  413. ///////////////////////////////////////////////////////////////////////////////
  414. //  Try to lookup domain specific configuration
  415. ///////////////////////////////////////////////////////////////////////////////
  416. MDomGetDomainPath(pszDomain, pszInfoFile, iMaxPath, 1);
  417. StrNCat(pszInfoFile, DEFAULT_USER_PROFILE_FILE, iMaxPath);
  418. if (SysExistFile(pszInfoFile))
  419. return (0);
  420. }
  421. ///////////////////////////////////////////////////////////////////////////////
  422. //  Try to lookup global configuration
  423. ///////////////////////////////////////////////////////////////////////////////
  424. CfgGetRootPath(pszInfoFile, iMaxPath);
  425. StrNCat(pszInfoFile, DEFAULT_USER_PROFILE_FILE, iMaxPath);
  426. if (!SysExistFile(pszInfoFile)) {
  427. ErrSetErrorCode(ERR_NO_USER_DEFAULT_PRFILE);
  428. return (ERR_NO_USER_DEFAULT_PRFILE);
  429. }
  430. return (0);
  431. }
  432. static int UsrLoadUserDefaultInfo(HSLIST & InfoList, char const *pszDomain)
  433. {
  434. char szUserDefFilePath[SYS_MAX_PATH] = "";
  435. if (UsrGetDefaultInfoFile(pszDomain, szUserDefFilePath, sizeof(szUserDefFilePath)) < 0)
  436. return (ErrGetErrorCode());
  437. char szResLock[SYS_MAX_PATH] = "";
  438. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szUserDefFilePath, szResLock,
  439.   sizeof(szResLock)));
  440. if (hResLock == INVALID_RLCK_HANDLE)
  441. return (ErrGetErrorCode());
  442. FILE *pProfileFile = fopen(szUserDefFilePath, "rt");
  443. if (pProfileFile == NULL) {
  444. ErrSetErrorCode(ERR_NO_USER_DEFAULT_PRFILE);
  445. RLckUnlockSH(hResLock);
  446. return (ERR_NO_USER_DEFAULT_PRFILE);
  447. }
  448. char szProfileLine[USR_TABLE_LINE_MAX] = "";
  449. while (MscFGets(szProfileLine, sizeof(szProfileLine) - 1, pProfileFile) != NULL) {
  450. if (szProfileLine[0] == TAB_COMMENT_CHAR)
  451. continue;
  452. char **ppszStrings = StrGetTabLineStrings(szProfileLine);
  453. if (ppszStrings == NULL)
  454. continue;
  455. int iFieldsCount = StrStringsCount(ppszStrings);
  456. if (iFieldsCount == 2) {
  457. UserInfoVar *pUIV = UsrAllocVar(ppszStrings[0], ppszStrings[1]);
  458. if (pUIV != NULL)
  459. ListAddTail(InfoList, (PLISTLINK) pUIV);
  460. }
  461. StrFreeStrings(ppszStrings);
  462. }
  463. fclose(pProfileFile);
  464. RLckUnlockSH(hResLock);
  465. return (0);
  466. }
  467. static int UsrAliasLookupNameLK(const char *pszAlsFilePath, const char *pszDomain,
  468. const char *pszAlias, char *pszName, bool bWildMatch)
  469. {
  470. ///////////////////////////////////////////////////////////////////////////////
  471. //  Lookup record using the specified index ( lookup precise aliases )
  472. ///////////////////////////////////////////////////////////////////////////////
  473. char **ppszTabTokens = TbixLookup(pszAlsFilePath, iIdxAlias_Domain_Alias, false,
  474.   pszDomain,
  475.   pszAlias,
  476.   NULL);
  477. if (ppszTabTokens != NULL) {
  478. if (pszName != NULL)
  479. strcpy(pszName, ppszTabTokens[alsName]);
  480. StrFreeStrings(ppszTabTokens);
  481. return (1);
  482. }
  483. ///////////////////////////////////////////////////////////////////////////////
  484. //  We can stop here if wild alias matching is not required
  485. ///////////////////////////////////////////////////////////////////////////////
  486. if (!bWildMatch)
  487. return (0);
  488. ///////////////////////////////////////////////////////////////////////////////
  489. //  Lookup record using the specified index ( lookup wild aliases grouped
  490. //  under WILD_ALIASES_HASH hash key )
  491. ///////////////////////////////////////////////////////////////////////////////
  492. INDEX_HANDLE hIndexLookup = TbixOpenHandle(pszAlsFilePath, iIdxAlias_Domain_Alias,
  493.    WILD_ALIASES_HASH);
  494. if (hIndexLookup != INVALID_INDEX_HANDLE) {
  495. int iNumRecords = TbixLookedUpRecords(hIndexLookup);
  496. int iMaxLength = -1;
  497. for (int ii = 0; ii < iNumRecords; ii++) {
  498. char **ppszTabTokens = TbixGetRecord(hIndexLookup, ii);
  499. if (ppszTabTokens == NULL)
  500. continue;
  501. int iFieldsCount = StrStringsCount(ppszTabTokens);
  502. if ((iFieldsCount >= alsMax) &&
  503.     StrIWildMatch(pszDomain, ppszTabTokens[alsDomain]) &&
  504.     StrIWildMatch(pszAlias, ppszTabTokens[alsAlias])) {
  505. int iLength = strlen(ppszTabTokens[alsDomain]) +
  506.     strlen(ppszTabTokens[alsAlias]);
  507. if (iLength > iMaxLength) {
  508. iMaxLength = iLength;
  509. if (pszName != NULL)
  510. strcpy(pszName, ppszTabTokens[alsName]);
  511. }
  512. }
  513. StrFreeStrings(ppszTabTokens);
  514. }
  515. TbixCloseHandle(hIndexLookup);
  516. if (iMaxLength > 0)
  517. return (1);
  518. }
  519. return (0);
  520. }
  521. int UsrAliasLookupName(const char *pszDomain, const char *pszAlias,
  522.        char *pszName, bool bWildMatch)
  523. {
  524. char szAlsFilePath[SYS_MAX_PATH] = "";
  525. UsrGetAliasFilePath(szAlsFilePath, sizeof(szAlsFilePath));
  526. char szResLock[SYS_MAX_PATH] = "";
  527. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szAlsFilePath, szResLock,
  528.   sizeof(szResLock)));
  529. if (hResLock == INVALID_RLCK_HANDLE)
  530. return (0);
  531. int iLookupResult = UsrAliasLookupNameLK(szAlsFilePath, pszDomain,
  532.  pszAlias, pszName, bWildMatch);
  533. RLckUnlockSH(hResLock);
  534. return (iLookupResult);
  535. }
  536. static int UsrWriteAlias(FILE * pAlsFile, AliasInfo * pAI)
  537. {
  538. ///////////////////////////////////////////////////////////////////////////////
  539. //  Domain
  540. ///////////////////////////////////////////////////////////////////////////////
  541. char *pszQuoted = StrQuote(pAI->pszDomain, '"');
  542. if (pszQuoted == NULL)
  543. return (ErrGetErrorCode());
  544. fprintf(pAlsFile, "%st", pszQuoted);
  545. SysFree(pszQuoted);
  546. ///////////////////////////////////////////////////////////////////////////////
  547. //  Alias
  548. ///////////////////////////////////////////////////////////////////////////////
  549. pszQuoted = StrQuote(pAI->pszAlias, '"');
  550. if (pszQuoted == NULL)
  551. return (ErrGetErrorCode());
  552. fprintf(pAlsFile, "%st", pszQuoted);
  553. SysFree(pszQuoted);
  554. ///////////////////////////////////////////////////////////////////////////////
  555. //  Account name
  556. ///////////////////////////////////////////////////////////////////////////////
  557. pszQuoted = StrQuote(pAI->pszName, '"');
  558. if (pszQuoted == NULL)
  559. return (ErrGetErrorCode());
  560. fprintf(pAlsFile, "%sn", pszQuoted);
  561. SysFree(pszQuoted);
  562. return (0);
  563. }
  564. AliasInfo *UsrAllocAlias(const char *pszDomain, const char *pszAlias, const char *pszName)
  565. {
  566. AliasInfo *pAI = (AliasInfo *) SysAlloc(sizeof(AliasInfo));
  567. if (pAI == NULL)
  568. return (NULL);
  569. pAI->pszDomain = (pszDomain != NULL) ? SysStrDup(pszDomain) : NULL;
  570. pAI->pszAlias = (pszAlias != NULL) ? SysStrDup(pszAlias) : NULL;
  571. pAI->pszName = (pszName != NULL) ? SysStrDup(pszName) : NULL;
  572. return (pAI);
  573. }
  574. void UsrFreeAlias(AliasInfo * pAI)
  575. {
  576. SysFreeCheck(pAI->pszDomain);
  577. SysFreeCheck(pAI->pszAlias);
  578. SysFreeCheck(pAI->pszName);
  579. SysFree(pAI);
  580. }
  581. static bool UsrIsWildAlias(char const *pszAlias)
  582. {
  583. return ((strchr(pszAlias, '*') != NULL) || (strchr(pszAlias, '?') != NULL));
  584. }
  585. int UsrAddAlias(AliasInfo * pAI)
  586. {
  587. char szAlsFilePath[SYS_MAX_PATH] = "";
  588. UsrGetAliasFilePath(szAlsFilePath, sizeof(szAlsFilePath));
  589. char szResLock[SYS_MAX_PATH] = "";
  590. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szAlsFilePath, szResLock,
  591.   sizeof(szResLock)));
  592. if (hResLock == INVALID_RLCK_HANDLE)
  593. return (ErrGetErrorCode());
  594. FILE *pAlsFile = fopen(szAlsFilePath, "r+t");
  595. if (pAlsFile == NULL) {
  596. ErrSetErrorCode(ERR_ALIAS_FILE_NOT_FOUND);
  597. RLckUnlockEX(hResLock);
  598. return (ERR_ALIAS_FILE_NOT_FOUND);
  599. }
  600. char szAlsLine[USR_ALIAS_LINE_MAX] = "";
  601. while (MscFGets(szAlsLine, sizeof(szAlsLine) - 1, pAlsFile) != NULL) {
  602. char **ppszStrings = StrGetTabLineStrings(szAlsLine);
  603. if (ppszStrings == NULL)
  604. continue;
  605. int iFieldsCount = StrStringsCount(ppszStrings);
  606. if ((iFieldsCount >= alsMax) &&
  607.     (stricmp(pAI->pszDomain, ppszStrings[alsDomain]) == 0) &&
  608.     (stricmp(pAI->pszAlias, ppszStrings[alsAlias]) == 0)) {
  609. StrFreeStrings(ppszStrings);
  610. fclose(pAlsFile);
  611. RLckUnlockEX(hResLock);
  612. ErrSetErrorCode(ERR_ALIAS_EXIST);
  613. return (ERR_ALIAS_EXIST);
  614. }
  615. StrFreeStrings(ppszStrings);
  616. }
  617. fseek(pAlsFile, 0, SEEK_END);
  618. if (UsrWriteAlias(pAlsFile, pAI) < 0) {
  619. fclose(pAlsFile);
  620. RLckUnlockEX(hResLock);
  621. ErrSetErrorCode(ERR_WRITE_ALIAS_FILE);
  622. return (ERR_WRITE_ALIAS_FILE);
  623. }
  624. fclose(pAlsFile);
  625. ///////////////////////////////////////////////////////////////////////////////
  626. //  Rebuild indexes
  627. ///////////////////////////////////////////////////////////////////////////////
  628. if (UsrRebuildAliasesIndexes(szAlsFilePath) < 0) {
  629. ErrorPush();
  630. RLckUnlockEX(hResLock);
  631. return (ErrorPop());
  632. }
  633. RLckUnlockEX(hResLock);
  634. return (0);
  635. }
  636. int UsrRemoveAlias(const char *pszDomain, const char *pszAlias)
  637. {
  638. char szAlsFilePath[SYS_MAX_PATH] = "";
  639. UsrGetAliasFilePath(szAlsFilePath, sizeof(szAlsFilePath));
  640. char szTmpFile[SYS_MAX_PATH] = "";
  641. SysGetTmpFile(szTmpFile);
  642. char szResLock[SYS_MAX_PATH] = "";
  643. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szAlsFilePath, szResLock,
  644.   sizeof(szResLock)));
  645. if (hResLock == INVALID_RLCK_HANDLE) {
  646. ErrorPush();
  647. CheckRemoveFile(szTmpFile);
  648. return (ErrorPop());
  649. }
  650. FILE *pAlsFile = fopen(szAlsFilePath, "rt");
  651. if (pAlsFile == NULL) {
  652. RLckUnlockEX(hResLock);
  653. CheckRemoveFile(szTmpFile);
  654. ErrSetErrorCode(ERR_ALIAS_FILE_NOT_FOUND);
  655. return (ERR_ALIAS_FILE_NOT_FOUND);
  656. }
  657. FILE *pTmpFile = fopen(szTmpFile, "wt");
  658. if (pTmpFile == NULL) {
  659. fclose(pAlsFile);
  660. RLckUnlockEX(hResLock);
  661. CheckRemoveFile(szTmpFile);
  662. ErrSetErrorCode(ERR_FILE_CREATE);
  663. return (ERR_FILE_CREATE);
  664. }
  665. int iAliasFound = 0;
  666. char szAlsLine[USR_ALIAS_LINE_MAX] = "";
  667. while (MscFGets(szAlsLine, sizeof(szAlsLine) - 1, pAlsFile) != NULL) {
  668. char **ppszStrings = StrGetTabLineStrings(szAlsLine);
  669. if (ppszStrings == NULL)
  670. continue;
  671. int iFieldsCount = StrStringsCount(ppszStrings);
  672. if ((iFieldsCount >= alsMax) && (stricmp(pszDomain, ppszStrings[alsDomain]) == 0)
  673.     && (stricmp(pszAlias, ppszStrings[alsAlias]) == 0)) {
  674. ++iAliasFound;
  675. } else
  676. fprintf(pTmpFile, "%sn", szAlsLine);
  677. StrFreeStrings(ppszStrings);
  678. }
  679. fclose(pAlsFile);
  680. fclose(pTmpFile);
  681. if (iAliasFound == 0) {
  682. SysRemove(szTmpFile);
  683. RLckUnlockEX(hResLock);
  684. ErrSetErrorCode(ERR_ALIAS_NOT_FOUND);
  685. return (ERR_ALIAS_NOT_FOUND);
  686. }
  687. char szTmpAlsFilePath[SYS_MAX_PATH] = "";
  688. sprintf(szTmpAlsFilePath, "%s.tmp", szAlsFilePath);
  689. if (MscMoveFile(szAlsFilePath, szTmpAlsFilePath) < 0) {
  690. RLckUnlockEX(hResLock);
  691. return (ErrGetErrorCode());
  692. }
  693. if (MscMoveFile(szTmpFile, szAlsFilePath) < 0) {
  694. MscMoveFile(szTmpAlsFilePath, szAlsFilePath);
  695. RLckUnlockEX(hResLock);
  696. return (ErrGetErrorCode());
  697. }
  698. SysRemove(szTmpAlsFilePath);
  699. ///////////////////////////////////////////////////////////////////////////////
  700. //  Rebuild indexes
  701. ///////////////////////////////////////////////////////////////////////////////
  702. if (UsrRebuildAliasesIndexes(szAlsFilePath) < 0) {
  703. ErrorPush();
  704. RLckUnlockEX(hResLock);
  705. return (ErrorPop());
  706. }
  707. RLckUnlockEX(hResLock);
  708. return (0);
  709. }
  710. int UsrRemoveDomainAliases(const char *pszDomain)
  711. {
  712. char szAlsFilePath[SYS_MAX_PATH] = "";
  713. UsrGetAliasFilePath(szAlsFilePath, sizeof(szAlsFilePath));
  714. char szTmpFile[SYS_MAX_PATH] = "";
  715. SysGetTmpFile(szTmpFile);
  716. char szResLock[SYS_MAX_PATH] = "";
  717. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szAlsFilePath, szResLock,
  718.   sizeof(szResLock)));
  719. if (hResLock == INVALID_RLCK_HANDLE) {
  720. ErrorPush();
  721. CheckRemoveFile(szTmpFile);
  722. return (ErrorPop());
  723. }
  724. FILE *pAlsFile = fopen(szAlsFilePath, "rt");
  725. if (pAlsFile == NULL) {
  726. RLckUnlockEX(hResLock);
  727. CheckRemoveFile(szTmpFile);
  728. ErrSetErrorCode(ERR_ALIAS_FILE_NOT_FOUND);
  729. return (ERR_ALIAS_FILE_NOT_FOUND);
  730. }
  731. FILE *pTmpFile = fopen(szTmpFile, "wt");
  732. if (pTmpFile == NULL) {
  733. fclose(pAlsFile);
  734. RLckUnlockEX(hResLock);
  735. CheckRemoveFile(szTmpFile);
  736. ErrSetErrorCode(ERR_FILE_CREATE);
  737. return (ERR_FILE_CREATE);
  738. }
  739. int iAliasFound = 0;
  740. char szAlsLine[USR_ALIAS_LINE_MAX] = "";
  741. while (MscFGets(szAlsLine, sizeof(szAlsLine) - 1, pAlsFile) != NULL) {
  742. char **ppszStrings = StrGetTabLineStrings(szAlsLine);
  743. if (ppszStrings == NULL)
  744. continue;
  745. int iFieldsCount = StrStringsCount(ppszStrings);
  746. if ((iFieldsCount >= alsMax) && (stricmp(pszDomain, ppszStrings[alsDomain]) == 0)) {
  747. ++iAliasFound;
  748. } else
  749. fprintf(pTmpFile, "%sn", szAlsLine);
  750. StrFreeStrings(ppszStrings);
  751. }
  752. fclose(pAlsFile);
  753. fclose(pTmpFile);
  754. if (iAliasFound == 0) {
  755. SysRemove(szTmpFile);
  756. RLckUnlockEX(hResLock);
  757. return (0);
  758. }
  759. char szTmpAlsFilePath[SYS_MAX_PATH] = "";
  760. sprintf(szTmpAlsFilePath, "%s.tmp", szAlsFilePath);
  761. if (MscMoveFile(szAlsFilePath, szTmpAlsFilePath) < 0) {
  762. ErrorPush();
  763. SysRemove(szTmpFile);
  764. RLckUnlockEX(hResLock);
  765. return (ErrorPop());
  766. }
  767. if (MscMoveFile(szTmpFile, szAlsFilePath) < 0) {
  768. ErrorPush();
  769. MscMoveFile(szTmpAlsFilePath, szAlsFilePath);
  770. SysRemove(szTmpFile);
  771. RLckUnlockEX(hResLock);
  772. return (ErrorPop());
  773. }
  774. SysRemove(szTmpAlsFilePath);
  775. ///////////////////////////////////////////////////////////////////////////////
  776. //  Rebuild indexes
  777. ///////////////////////////////////////////////////////////////////////////////
  778. if (UsrRebuildAliasesIndexes(szAlsFilePath) < 0) {
  779. ErrorPush();
  780. RLckUnlockEX(hResLock);
  781. return (ErrorPop());
  782. }
  783. RLckUnlockEX(hResLock);
  784. return (0);
  785. }
  786. static int UsrRemoveUserAlias(char const *pszDomain, char const *pszName)
  787. {
  788. char szAlsFilePath[SYS_MAX_PATH] = "";
  789. UsrGetAliasFilePath(szAlsFilePath, sizeof(szAlsFilePath));
  790. char szTmpFile[SYS_MAX_PATH] = "";
  791. SysGetTmpFile(szTmpFile);
  792. char szResLock[SYS_MAX_PATH] = "";
  793. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szAlsFilePath, szResLock,
  794.   sizeof(szResLock)));
  795. if (hResLock == INVALID_RLCK_HANDLE)
  796. return (ErrGetErrorCode());
  797. FILE *pAlsFile = fopen(szAlsFilePath, "rt");
  798. if (pAlsFile == NULL) {
  799. RLckUnlockEX(hResLock);
  800. ErrSetErrorCode(ERR_ALIAS_FILE_NOT_FOUND);
  801. return (ERR_ALIAS_FILE_NOT_FOUND);
  802. }
  803. FILE *pTmpFile = fopen(szTmpFile, "wt");
  804. if (pTmpFile == NULL) {
  805. fclose(pAlsFile);
  806. RLckUnlockEX(hResLock);
  807. ErrSetErrorCode(ERR_FILE_CREATE);
  808. return (ERR_FILE_CREATE);
  809. }
  810. char szUserAddress[MAX_ADDR_NAME] = "";
  811. sprintf(szUserAddress, "%s@%s", pszName, pszDomain);
  812. int iAliasFound = 0;
  813. char szAlsLine[USR_ALIAS_LINE_MAX] = "";
  814. while (MscFGets(szAlsLine, sizeof(szAlsLine) - 1, pAlsFile) != NULL) {
  815. char **ppszStrings = StrGetTabLineStrings(szAlsLine);
  816. if (ppszStrings == NULL)
  817. continue;
  818. int iFieldsCount = StrStringsCount(ppszStrings);
  819. if ((iFieldsCount >= alsMax) &&
  820.     (((stricmp(pszName, ppszStrings[alsName]) == 0) &&
  821.       (stricmp(pszDomain, ppszStrings[alsDomain]) == 0)) ||
  822.      (stricmp(szUserAddress, ppszStrings[alsName]) == 0))) {
  823. ++iAliasFound;
  824. } else
  825. fprintf(pTmpFile, "%sn", szAlsLine);
  826. StrFreeStrings(ppszStrings);
  827. }
  828. fclose(pAlsFile);
  829. fclose(pTmpFile);
  830. if (iAliasFound == 0) {
  831. SysRemove(szTmpFile);
  832. RLckUnlockEX(hResLock);
  833. return (0);
  834. }
  835. char szTmpAlsFilePath[SYS_MAX_PATH] = "";
  836. sprintf(szTmpAlsFilePath, "%s.tmp", szAlsFilePath);
  837. if (MscMoveFile(szAlsFilePath, szTmpAlsFilePath) < 0) {
  838. RLckUnlockEX(hResLock);
  839. return (ErrGetErrorCode());
  840. }
  841. if (MscMoveFile(szTmpFile, szAlsFilePath) < 0) {
  842. MscMoveFile(szTmpAlsFilePath, szAlsFilePath);
  843. RLckUnlockEX(hResLock);
  844. return (ErrGetErrorCode());
  845. }
  846. SysRemove(szTmpAlsFilePath);
  847. ///////////////////////////////////////////////////////////////////////////////
  848. //  Rebuild indexes
  849. ///////////////////////////////////////////////////////////////////////////////
  850. if (UsrRebuildAliasesIndexes(szAlsFilePath) < 0) {
  851. ErrorPush();
  852. RLckUnlockEX(hResLock);
  853. return (ErrorPop());
  854. }
  855. RLckUnlockEX(hResLock);
  856. return (0);
  857. }
  858. static UserInfo *UsrGetUserByNameLK(const char *pszUsrFilePath, const char *pszDomain,
  859.     const char *pszName)
  860. {
  861. ///////////////////////////////////////////////////////////////////////////////
  862. //  Lookup record using the specified index
  863. ///////////////////////////////////////////////////////////////////////////////
  864. char **ppszTabTokens = TbixLookup(pszUsrFilePath, iIdxUser_Domain_Name, false,
  865.   pszDomain,
  866.   pszName,
  867.   NULL);
  868. if (ppszTabTokens == NULL) {
  869. ErrSetErrorCode(ERR_USER_NOT_FOUND);
  870. return (NULL);
  871. }
  872. UserInfo *pUI = UsrGetUserFromStrings(ppszTabTokens);
  873. StrFreeStrings(ppszTabTokens);
  874. return (pUI);
  875. }
  876. UserInfo *UsrLookupUser(const char *pszDomain, const char *pszName)
  877. {
  878. char szUsrFilePath[SYS_MAX_PATH] = "";
  879. UsrGetTableFilePath(szUsrFilePath, sizeof(szUsrFilePath));
  880. char szResLock[SYS_MAX_PATH] = "";
  881. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szUsrFilePath, szResLock,
  882.   sizeof(szResLock)));
  883. if (hResLock == INVALID_RLCK_HANDLE)
  884. return (NULL);
  885. UserInfo *pUI = UsrGetUserByNameLK(szUsrFilePath, pszDomain, pszName);
  886. RLckUnlockSH(hResLock);
  887. return (pUI);
  888. }
  889. UserInfo *UsrGetUserByName(const char *pszDomain, const char *pszName)
  890. {
  891. ///////////////////////////////////////////////////////////////////////////////
  892. //  Check for alias domain
  893. ///////////////////////////////////////////////////////////////////////////////
  894. UserInfo *pUI = UsrLookupUser(pszDomain, pszName);
  895. char szADomain[MAX_HOST_NAME] = "";
  896. ///////////////////////////////////////////////////////////////////////////////
  897. //  Check for alias domain if first lookup failed
  898. ///////////////////////////////////////////////////////////////////////////////
  899. if ((pUI == NULL) && ADomLookupDomain(pszDomain, szADomain, true))
  900. pUI = UsrLookupUser(szADomain, pszName);
  901. return (pUI);
  902. }
  903. static UserInfo *UsrGetUserByNameOrAliasNDA(const char *pszDomain, const char *pszName,
  904.     char *pszRealAddr)
  905. {
  906. char const *pszAliasedUser = NULL;
  907. char const *pszAliasedDomain = NULL;
  908. char szAliasedAccount[MAX_ADDR_NAME] = "";
  909. char szAliasedName[MAX_ADDR_NAME] = "";
  910. char szAliasedDomain[MAX_ADDR_NAME] = "";
  911. if (UsrAliasLookupName(pszDomain, pszName, szAliasedAccount)) {
  912. if (USmtpSplitEmailAddr(szAliasedAccount, szAliasedName, szAliasedDomain) < 0) {
  913. pszAliasedUser = szAliasedAccount;
  914. pszAliasedDomain = pszDomain;
  915. } else {
  916. pszAliasedUser = szAliasedName;
  917. pszAliasedDomain = szAliasedDomain;
  918. }
  919. }
  920. char szUsrFilePath[SYS_MAX_PATH] = "";
  921. UsrGetTableFilePath(szUsrFilePath, sizeof(szUsrFilePath));
  922. char szResLock[SYS_MAX_PATH] = "";
  923. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szUsrFilePath, szResLock,
  924.   sizeof(szResLock)));
  925. if (hResLock == INVALID_RLCK_HANDLE)
  926. return (NULL);
  927. UserInfo *pUI = UsrGetUserByNameLK(szUsrFilePath, pszDomain, pszName);
  928. if ((pUI == NULL) && (pszAliasedUser != NULL))
  929. pUI = UsrGetUserByNameLK(szUsrFilePath, pszAliasedDomain, pszAliasedUser);
  930. if ((pUI != NULL) && (pszRealAddr != NULL))
  931. UsrGetAddress(pUI, pszRealAddr);
  932. RLckUnlockSH(hResLock);
  933. return (pUI);
  934. }
  935. UserInfo *UsrGetUserByNameOrAlias(const char *pszDomain, const char *pszName, char *pszRealAddr)
  936. {
  937. UserInfo *pUI = UsrGetUserByNameOrAliasNDA(pszDomain, pszName, pszRealAddr);
  938. char szADomain[MAX_HOST_NAME] = "";
  939. ///////////////////////////////////////////////////////////////////////////////
  940. //  Check for alias domain if first lookup failed
  941. ///////////////////////////////////////////////////////////////////////////////
  942. if ((pUI == NULL) && ADomLookupDomain(pszDomain, szADomain, true))
  943. pUI = UsrGetUserByNameOrAliasNDA(szADomain, pszName, pszRealAddr);
  944. return (pUI);
  945. }
  946. int UsrRemoveUser(const char *pszDomain, const char *pszName, unsigned int uUserID)
  947. {
  948. char szUsrFilePath[SYS_MAX_PATH] = "";
  949. UsrGetTableFilePath(szUsrFilePath, sizeof(szUsrFilePath));
  950. char szTmpFile[SYS_MAX_PATH] = "";
  951. SysGetTmpFile(szTmpFile);
  952. char szResLock[SYS_MAX_PATH] = "";
  953. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szUsrFilePath, szResLock,
  954.   sizeof(szResLock)));
  955. if (hResLock == INVALID_RLCK_HANDLE) {
  956. ErrorPush();
  957. CheckRemoveFile(szTmpFile);
  958. return (ErrorPop());
  959. }
  960. FILE *pUsrFile = fopen(szUsrFilePath, "rt");
  961. if (pUsrFile == NULL) {
  962. RLckUnlockEX(hResLock);
  963. CheckRemoveFile(szTmpFile);
  964. ErrSetErrorCode(ERR_USERS_FILE_NOT_FOUND);
  965. return (ERR_USERS_FILE_NOT_FOUND);
  966. }
  967. FILE *pTmpFile = fopen(szTmpFile, "wt");
  968. if (pTmpFile == NULL) {
  969. fclose(pUsrFile);
  970. RLckUnlockEX(hResLock);
  971. CheckRemoveFile(szTmpFile);
  972. ErrSetErrorCode(ERR_FILE_CREATE);
  973. return (ERR_FILE_CREATE);
  974. }
  975. UserInfo *pUI = NULL;
  976. char szUsrLine[USR_TABLE_LINE_MAX] = "";
  977. while (MscFGets(szUsrLine, sizeof(szUsrLine) - 1, pUsrFile) != NULL) {
  978. char **ppszStrings = StrGetTabLineStrings(szUsrLine);
  979. if (ppszStrings == NULL)
  980. continue;
  981. int iFieldsCount = StrStringsCount(ppszStrings);
  982. if ((iFieldsCount >= usrMax) && (stricmp(pszDomain, ppszStrings[usrDomain]) == 0)
  983.     && (((uUserID != 0) && (uUserID == (unsigned int) atol(ppszStrings[usrID])))
  984. || ((pszName != NULL) &&
  985.     (stricmp(pszName, ppszStrings[usrName]) == 0)))) {
  986. if (pUI != NULL)
  987. UsrFreeUserInfo(pUI);
  988. pUI = UsrGetUserFromStrings(ppszStrings);
  989. } else
  990. fprintf(pTmpFile, "%sn", szUsrLine);
  991. StrFreeStrings(ppszStrings);
  992. }
  993. fclose(pUsrFile);
  994. fclose(pTmpFile);
  995. if (pUI == NULL) {
  996. SysRemove(szTmpFile);
  997. RLckUnlockEX(hResLock);
  998. ErrSetErrorCode(ERR_USER_NOT_FOUND);
  999. return (ERR_USER_NOT_FOUND);
  1000. }
  1001. char szTmpUsrFilePath[SYS_MAX_PATH] = "";
  1002. sprintf(szTmpUsrFilePath, "%s.tmp", szUsrFilePath);
  1003. if (MscMoveFile(szUsrFilePath, szTmpUsrFilePath) < 0) {
  1004. ErrorPush();
  1005. UsrFreeUserInfo(pUI);
  1006. RLckUnlockEX(hResLock);
  1007. return (ErrorPop());
  1008. }
  1009. if (MscMoveFile(szTmpFile, szUsrFilePath) < 0) {
  1010. ErrorPush();
  1011. MscMoveFile(szTmpUsrFilePath, szUsrFilePath);
  1012. UsrFreeUserInfo(pUI);
  1013. RLckUnlockEX(hResLock);
  1014. return (ErrorPop());
  1015. }
  1016. SysRemove(szTmpUsrFilePath);
  1017. ///////////////////////////////////////////////////////////////////////////////
  1018. //  Rebuild indexes
  1019. ///////////////////////////////////////////////////////////////////////////////
  1020. if (UsrRebuildUsersIndexes(szUsrFilePath) < 0) {
  1021. ErrorPush();
  1022. UsrFreeUserInfo(pUI);
  1023. RLckUnlockEX(hResLock);
  1024. return (ErrorPop());
  1025. }
  1026. RLckUnlockEX(hResLock);
  1027. GwLkRemoveUserLinks(pUI->pszDomain, pUI->pszName);
  1028. ExAlRemoveUserAliases(pUI->pszDomain, pUI->pszName);
  1029. UsrRemoveUserAlias(pUI->pszDomain, pUI->pszName);
  1030. ///////////////////////////////////////////////////////////////////////////////
  1031. //  Try ( if defined ) to remove external auth user
  1032. ///////////////////////////////////////////////////////////////////////////////
  1033. UAthDelUser(AUTH_SERVICE_POP3, pUI);
  1034. UsrDropUserEnv(pUI);
  1035. UsrFreeUserInfo(pUI);
  1036. return (0);
  1037. }
  1038. int UsrModifyUser(UserInfo * pUI)
  1039. {
  1040. char szUsrFilePath[SYS_MAX_PATH] = "";
  1041. UsrGetTableFilePath(szUsrFilePath, sizeof(szUsrFilePath));
  1042. char szTmpFile[SYS_MAX_PATH] = "";
  1043. SysGetTmpFile(szTmpFile);
  1044. char szResLock[SYS_MAX_PATH] = "";
  1045. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szUsrFilePath, szResLock,
  1046.   sizeof(szResLock)));
  1047. if (hResLock == INVALID_RLCK_HANDLE) {
  1048. ErrorPush();
  1049. CheckRemoveFile(szTmpFile);
  1050. return (ErrorPop());
  1051. }
  1052. FILE *pUsrFile = fopen(szUsrFilePath, "rt");
  1053. if (pUsrFile == NULL) {
  1054. RLckUnlockEX(hResLock);
  1055. CheckRemoveFile(szTmpFile);
  1056. ErrSetErrorCode(ERR_USERS_FILE_NOT_FOUND);
  1057. return (ERR_USERS_FILE_NOT_FOUND);
  1058. }
  1059. FILE *pTmpFile = fopen(szTmpFile, "wt");
  1060. if (pTmpFile == NULL) {
  1061. fclose(pUsrFile);
  1062. RLckUnlockEX(hResLock);
  1063. CheckRemoveFile(szTmpFile);
  1064. ErrSetErrorCode(ERR_FILE_CREATE);
  1065. return (ERR_FILE_CREATE);
  1066. }
  1067. UserInfo *pFoundUI = NULL;
  1068. char szUsrLine[USR_TABLE_LINE_MAX] = "";
  1069. while (MscFGets(szUsrLine, sizeof(szUsrLine) - 1, pUsrFile) != NULL) {
  1070. char **ppszStrings = StrGetTabLineStrings(szUsrLine);
  1071. if (ppszStrings == NULL)
  1072. continue;
  1073. int iFieldsCount = StrStringsCount(ppszStrings);
  1074. if ((iFieldsCount >= usrMax) && (pFoundUI == NULL) &&
  1075.     (pUI->uUserID == (unsigned int) atol(ppszStrings[usrID])) &&
  1076.     (stricmp(pUI->pszDomain, ppszStrings[usrDomain]) == 0) &&
  1077.     (stricmp(pUI->pszName, ppszStrings[usrName]) == 0)) {
  1078. if ((UsrWriteUser(pUI, pTmpFile) < 0) ||
  1079.     ((pFoundUI = UsrGetUserFromStrings(ppszStrings)) == NULL)) {
  1080. ErrorPush();
  1081. fclose(pUsrFile);
  1082. fclose(pTmpFile);
  1083. SysRemove(szTmpFile);
  1084. RLckUnlockEX(hResLock);
  1085. return (ErrorPop());
  1086. }
  1087. } else
  1088. fprintf(pTmpFile, "%sn", szUsrLine);
  1089. StrFreeStrings(ppszStrings);
  1090. }
  1091. fclose(pUsrFile);
  1092. fclose(pTmpFile);
  1093. if (pFoundUI == NULL) {
  1094. SysRemove(szTmpFile);
  1095. RLckUnlockEX(hResLock);
  1096. ErrSetErrorCode(ERR_USER_NOT_FOUND);
  1097. return (ERR_USER_NOT_FOUND);
  1098. }
  1099. ///////////////////////////////////////////////////////////////////////////////
  1100. //
  1101. //  Adjust for fields changes
  1102. //
  1103. ///////////////////////////////////////////////////////////////////////////////
  1104. ///////////////////////////////////////////////////////////////////////////////
  1105. //  Try ( if defined ) to modify external auth user
  1106. ///////////////////////////////////////////////////////////////////////////////
  1107. UAthModifyUser(AUTH_SERVICE_POP3, pUI);
  1108. UsrFreeUserInfo(pFoundUI);
  1109. char szTmpUsrFilePath[SYS_MAX_PATH] = "";
  1110. sprintf(szTmpUsrFilePath, "%s.tmp", szUsrFilePath);
  1111. if (MscMoveFile(szUsrFilePath, szTmpUsrFilePath) < 0) {
  1112. ErrorPush();
  1113. SysRemove(szTmpFile);
  1114. RLckUnlockEX(hResLock);
  1115. return (ErrorPop());
  1116. }
  1117. if (MscMoveFile(szTmpFile, szUsrFilePath) < 0) {
  1118. ErrorPush();
  1119. MscMoveFile(szTmpUsrFilePath, szUsrFilePath);
  1120. SysRemove(szTmpFile);
  1121. RLckUnlockEX(hResLock);
  1122. return (ErrorPop());
  1123. }
  1124. SysRemove(szTmpUsrFilePath);
  1125. ///////////////////////////////////////////////////////////////////////////////
  1126. //  Rebuild indexes
  1127. ///////////////////////////////////////////////////////////////////////////////
  1128. if (UsrRebuildUsersIndexes(szUsrFilePath) < 0) {
  1129. ErrorPush();
  1130. RLckUnlockEX(hResLock);
  1131. return (ErrorPop());
  1132. }
  1133. RLckUnlockEX(hResLock);
  1134. return (0);
  1135. }
  1136. int UsrRemoveDomainUsers(const char *pszDomain)
  1137. {
  1138. char szUsrFilePath[SYS_MAX_PATH] = "";
  1139. UsrGetTableFilePath(szUsrFilePath, sizeof(szUsrFilePath));
  1140. char szTmpFile[SYS_MAX_PATH] = "";
  1141. SysGetTmpFile(szTmpFile);
  1142. char szResLock[SYS_MAX_PATH] = "";
  1143. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szUsrFilePath, szResLock,
  1144.   sizeof(szResLock)));
  1145. if (hResLock == INVALID_RLCK_HANDLE) {
  1146. ErrorPush();
  1147. CheckRemoveFile(szTmpFile);
  1148. return (ErrorPop());
  1149. }
  1150. FILE *pUsrFile = fopen(szUsrFilePath, "rt");
  1151. if (pUsrFile == NULL) {
  1152. RLckUnlockEX(hResLock);
  1153. CheckRemoveFile(szTmpFile);
  1154. ErrSetErrorCode(ERR_USERS_FILE_NOT_FOUND);
  1155. return (ERR_USERS_FILE_NOT_FOUND);
  1156. }
  1157. FILE *pTmpFile = fopen(szTmpFile, "wt");
  1158. if (pTmpFile == NULL) {
  1159. fclose(pUsrFile);
  1160. RLckUnlockEX(hResLock);
  1161. CheckRemoveFile(szTmpFile);
  1162. ErrSetErrorCode(ERR_FILE_CREATE);
  1163. return (ERR_FILE_CREATE);
  1164. }
  1165. int iUsersFound = 0;
  1166. char szUsrLine[USR_TABLE_LINE_MAX] = "";
  1167. while (MscFGets(szUsrLine, sizeof(szUsrLine) - 1, pUsrFile) != NULL) {
  1168. char **ppszStrings = StrGetTabLineStrings(szUsrLine);
  1169. if (ppszStrings == NULL)
  1170. continue;
  1171. int iFieldsCount = StrStringsCount(ppszStrings);
  1172. if ((iFieldsCount >= usrMax) && (stricmp(pszDomain, ppszStrings[usrDomain]) == 0)) {
  1173. ++iUsersFound;
  1174. } else
  1175. fprintf(pTmpFile, "%sn", szUsrLine);
  1176. StrFreeStrings(ppszStrings);
  1177. }
  1178. fclose(pUsrFile);
  1179. fclose(pTmpFile);
  1180. if (iUsersFound == 0) {
  1181. SysRemove(szTmpFile);
  1182. RLckUnlockEX(hResLock);
  1183. return (0);
  1184. }
  1185. char szTmpUsrFilePath[SYS_MAX_PATH] = "";
  1186. sprintf(szTmpUsrFilePath, "%s.tmp", szUsrFilePath);
  1187. if (MscMoveFile(szUsrFilePath, szTmpUsrFilePath) < 0) {
  1188. ErrorPush();
  1189. SysRemove(szTmpFile);
  1190. RLckUnlockEX(hResLock);
  1191. return (ErrorPop());
  1192. }
  1193. if (MscMoveFile(szTmpFile, szUsrFilePath) < 0) {
  1194. ErrorPush();
  1195. MscMoveFile(szTmpUsrFilePath, szUsrFilePath);
  1196. SysRemove(szTmpFile);
  1197. RLckUnlockEX(hResLock);
  1198. return (ErrorPop());
  1199. }
  1200. SysRemove(szTmpUsrFilePath);
  1201. ///////////////////////////////////////////////////////////////////////////////
  1202. //  Rebuild indexes
  1203. ///////////////////////////////////////////////////////////////////////////////
  1204. if (UsrRebuildUsersIndexes(szUsrFilePath) < 0) {
  1205. ErrorPush();
  1206. RLckUnlockEX(hResLock);
  1207. return (ErrorPop());
  1208. }
  1209. RLckUnlockEX(hResLock);
  1210. return (0);
  1211. }
  1212. static int UsrDropUserEnv(UserInfo * pUI)
  1213. {
  1214. ///////////////////////////////////////////////////////////////////////////////
  1215. //  User directory cleaning
  1216. ///////////////////////////////////////////////////////////////////////////////
  1217. char szUsrUserPath[SYS_MAX_PATH] = "";
  1218. UsrGetUserPath(pUI, szUsrUserPath, sizeof(szUsrUserPath), 0);
  1219. if (MscClearDirectory(szUsrUserPath) < 0)
  1220. return (ErrGetErrorCode());
  1221. ///////////////////////////////////////////////////////////////////////////////
  1222. //  User directory removing
  1223. ///////////////////////////////////////////////////////////////////////////////
  1224. if (SysRemoveDir(szUsrUserPath) < 0)
  1225. return (ErrGetErrorCode());
  1226. return (0);
  1227. }
  1228. static int UsrWriteUser(UserInfo * pUI, FILE * pUsrFile)
  1229. {
  1230. ///////////////////////////////////////////////////////////////////////////////
  1231. //  Domain
  1232. ///////////////////////////////////////////////////////////////////////////////
  1233. char *pszQuoted = StrQuote(pUI->pszDomain, '"');
  1234. if (pszQuoted == NULL)
  1235. return (ErrGetErrorCode());
  1236. fprintf(pUsrFile, "%st", pszQuoted);
  1237. SysFree(pszQuoted);
  1238. ///////////////////////////////////////////////////////////////////////////////
  1239. //  Name
  1240. ///////////////////////////////////////////////////////////////////////////////
  1241. pszQuoted = StrQuote(pUI->pszName, '"');
  1242. if (pszQuoted == NULL)
  1243. return (ErrGetErrorCode());
  1244. fprintf(pUsrFile, "%st", pszQuoted);
  1245. SysFree(pszQuoted);
  1246. ///////////////////////////////////////////////////////////////////////////////
  1247. //  Password
  1248. ///////////////////////////////////////////////////////////////////////////////
  1249. char szPassword[512] = "";
  1250. StrCrypt(pUI->pszPassword, szPassword);
  1251. pszQuoted = StrQuote(szPassword, '"');
  1252. if (pszQuoted == NULL)
  1253. return (ErrGetErrorCode());
  1254. fprintf(pUsrFile, "%st", pszQuoted);
  1255. SysFree(pszQuoted);
  1256. ///////////////////////////////////////////////////////////////////////////////
  1257. //  UserID
  1258. ///////////////////////////////////////////////////////////////////////////////
  1259. fprintf(pUsrFile, "%ut", pUI->uUserID);
  1260. ///////////////////////////////////////////////////////////////////////////////
  1261. //  Directory
  1262. ///////////////////////////////////////////////////////////////////////////////
  1263. pszQuoted = StrQuote(pUI->pszPath, '"');
  1264. if (pszQuoted == NULL)
  1265. return (ErrGetErrorCode());
  1266. fprintf(pUsrFile, "%st", pszQuoted);
  1267. SysFree(pszQuoted);
  1268. ///////////////////////////////////////////////////////////////////////////////
  1269. //  User type
  1270. ///////////////////////////////////////////////////////////////////////////////
  1271. pszQuoted = StrQuote(pUI->pszType, '"');
  1272. if (pszQuoted == NULL)
  1273. return (ErrGetErrorCode());
  1274. fprintf(pUsrFile, "%sn", pszQuoted);
  1275. SysFree(pszQuoted);
  1276. return (0);
  1277. }
  1278. int UsrAddUser(UserInfo * pUI)
  1279. {
  1280. ///////////////////////////////////////////////////////////////////////////////
  1281. //  Search for overlapping alias ( wildcard alias not checked here )
  1282. ///////////////////////////////////////////////////////////////////////////////
  1283. if (UsrAliasLookupName(pUI->pszDomain, pUI->pszName, NULL, false)) {
  1284. ErrSetErrorCode(ERR_ALIAS_EXIST);
  1285. return (ERR_ALIAS_EXIST);
  1286. }
  1287. char szUsrFilePath[SYS_MAX_PATH] = "";
  1288. UsrGetTableFilePath(szUsrFilePath, sizeof(szUsrFilePath));
  1289. char szResLock[SYS_MAX_PATH] = "";
  1290. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szUsrFilePath, szResLock,
  1291.   sizeof(szResLock)));
  1292. if (hResLock == INVALID_RLCK_HANDLE)
  1293. return (ErrGetErrorCode());
  1294. FILE *pUsrFile = fopen(szUsrFilePath, "r+t");
  1295. if (pUsrFile == NULL) {
  1296. RLckUnlockEX(hResLock);
  1297. ErrSetErrorCode(ERR_USERS_FILE_NOT_FOUND);
  1298. return (ERR_USERS_FILE_NOT_FOUND);
  1299. }
  1300. unsigned int uMaxUserID = 0;
  1301. char szUsrLine[USR_TABLE_LINE_MAX] = "";
  1302. while (MscFGets(szUsrLine, sizeof(szUsrLine) - 1, pUsrFile) != NULL) {
  1303. char **ppszStrings = StrGetTabLineStrings(szUsrLine);
  1304. if (ppszStrings == NULL)
  1305. continue;
  1306. int iFieldsCount = StrStringsCount(ppszStrings);
  1307. if (iFieldsCount >= usrMax) {
  1308. if ((stricmp(pUI->pszDomain, ppszStrings[usrDomain]) == 0) &&
  1309.     (stricmp(pUI->pszName, ppszStrings[usrName]) == 0)) {
  1310. StrFreeStrings(ppszStrings);
  1311. fclose(pUsrFile);
  1312. RLckUnlockEX(hResLock);
  1313. ErrSetErrorCode(ERR_USER_EXIST);
  1314. return (ERR_USER_EXIST);
  1315. }
  1316. unsigned int uUserID = (unsigned int) atol(ppszStrings[usrID]);
  1317. if (uUserID > uMaxUserID)
  1318. uMaxUserID = uUserID;
  1319. }
  1320. StrFreeStrings(ppszStrings);
  1321. }
  1322. pUI->uUserID = uMaxUserID + 1;
  1323. if (UsrPrepareUserEnv(pUI) < 0) {
  1324. fclose(pUsrFile);
  1325. RLckUnlockEX(hResLock);
  1326. return (ErrGetErrorCode());
  1327. }
  1328. fseek(pUsrFile, 0, SEEK_END);
  1329. if (UsrWriteUser(pUI, pUsrFile) < 0) {
  1330. fclose(pUsrFile);
  1331. RLckUnlockEX(hResLock);
  1332. ErrSetErrorCode(ERR_WRITE_USERS_FILE);
  1333. return (ERR_WRITE_USERS_FILE);
  1334. }
  1335. fclose(pUsrFile);
  1336. ///////////////////////////////////////////////////////////////////////////////
  1337. //  Rebuild indexes
  1338. ///////////////////////////////////////////////////////////////////////////////
  1339. if (UsrRebuildUsersIndexes(szUsrFilePath) < 0) {
  1340. ErrorPush();
  1341. RLckUnlockEX(hResLock);
  1342. return (ErrorPop());
  1343. }
  1344. RLckUnlockEX(hResLock);
  1345. ///////////////////////////////////////////////////////////////////////////////
  1346. //  Try ( if defined ) to add external auth user
  1347. ///////////////////////////////////////////////////////////////////////////////
  1348. UAthAddUser(AUTH_SERVICE_POP3, pUI);
  1349. return (0);
  1350. }
  1351. static char const *UsrGetMailboxDir(void)
  1352. {
  1353. return ((iMailboxType == XMAIL_MAILBOX) ? MAILBOX_DIRECTORY : MAILDIR_DIRECTORY);
  1354. }
  1355. static int UsrCreateMailbox(char const *pszUsrUserPath)
  1356. {
  1357. if (iMailboxType == XMAIL_MAILBOX) {
  1358. ///////////////////////////////////////////////////////////////////////////////
  1359. //  Create mailbox directory
  1360. ///////////////////////////////////////////////////////////////////////////////
  1361. char szUsrMailboxPath[SYS_MAX_PATH] = "";
  1362. StrSNCpy(szUsrMailboxPath, pszUsrUserPath);
  1363. AppendSlash(szUsrMailboxPath);
  1364. StrSNCat(szUsrMailboxPath, MAILBOX_DIRECTORY);
  1365. if (SysMakeDir(szUsrMailboxPath) < 0)
  1366. return (ErrGetErrorCode());
  1367. return (0);
  1368. }
  1369. return (MdirCreateStructure(pszUsrUserPath));
  1370. }
  1371. static int UsrPrepareUserEnv(UserInfo * pUI)
  1372. {
  1373. char szUsrUserPath[SYS_MAX_PATH] = "";
  1374. UsrGetUserPath(pUI, szUsrUserPath, sizeof(szUsrUserPath), 0);
  1375. ///////////////////////////////////////////////////////////////////////////////
  1376. //  Create main directory
  1377. ///////////////////////////////////////////////////////////////////////////////
  1378. if (SysMakeDir(szUsrUserPath) < 0)
  1379. return (ErrGetErrorCode());
  1380. if (UsrGetUserType(pUI) == usrTypeUser) {
  1381. ///////////////////////////////////////////////////////////////////////////////
  1382. //  Create mailbox directory
  1383. ///////////////////////////////////////////////////////////////////////////////
  1384. if (UsrCreateMailbox(szUsrUserPath) < 0) {
  1385. ErrorPush();
  1386. MscClearDirectory(szUsrUserPath);
  1387. SysRemoveDir(szUsrUserPath);
  1388. return (ErrorPop());
  1389. }
  1390. } else {
  1391. ///////////////////////////////////////////////////////////////////////////////
  1392. //  Create mailing list users file
  1393. ///////////////////////////////////////////////////////////////////////////////
  1394. char szMLUsersFilePath[SYS_MAX_PATH] = "";
  1395. StrSNCpy(szMLUsersFilePath, szUsrUserPath);
  1396. AppendSlash(szMLUsersFilePath);
  1397. StrSNCat(szMLUsersFilePath, MLUSERS_TABLE_FILE);
  1398. if (MscCreateEmptyFile(szMLUsersFilePath) < 0) {
  1399. ErrorPush();
  1400. MscClearDirectory(szUsrUserPath);
  1401. SysRemoveDir(szUsrUserPath);
  1402. return (ErrorPop());
  1403. }
  1404. }
  1405. ///////////////////////////////////////////////////////////////////////////////
  1406. //  Create profile file
  1407. ///////////////////////////////////////////////////////////////////////////////
  1408. char szUsrProfileFilePath[SYS_MAX_PATH] = "";
  1409. StrSNCpy(szUsrProfileFilePath, szUsrUserPath);
  1410. AppendSlash(szUsrProfileFilePath);
  1411. StrSNCat(szUsrProfileFilePath, USER_PROFILE_FILE);
  1412. FILE *pProfileFile = fopen(szUsrProfileFilePath, "wt");
  1413. if (pProfileFile == NULL) {
  1414. MscClearDirectory(szUsrUserPath);
  1415. SysRemoveDir(szUsrUserPath);
  1416. ErrSetErrorCode(ERR_FILE_CREATE);
  1417. return (ERR_FILE_CREATE);
  1418. }
  1419. UsrWriteInfoList(pUI->InfoList, pProfileFile);
  1420. fclose(pProfileFile);
  1421. return (0);
  1422. }
  1423. int UsrFlushUserVars(UserInfo * pUI)
  1424. {
  1425. char szUsrUserPath[SYS_MAX_PATH] = "";
  1426. UsrGetUserPath(pUI, szUsrUserPath, sizeof(szUsrUserPath), 0);
  1427. ///////////////////////////////////////////////////////////////////////////////
  1428. //  Build profile file path
  1429. ///////////////////////////////////////////////////////////////////////////////
  1430. char szUsrProfileFilePath[SYS_MAX_PATH] = "";
  1431. StrSNCpy(szUsrProfileFilePath, szUsrUserPath);
  1432. AppendSlash(szUsrProfileFilePath);
  1433. StrSNCat(szUsrProfileFilePath, USER_PROFILE_FILE);
  1434. char szResLock[SYS_MAX_PATH] = "";
  1435. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szUsrProfileFilePath, szResLock,
  1436.   sizeof(szResLock)));
  1437. if (hResLock == INVALID_RLCK_HANDLE)
  1438. return (ErrGetErrorCode());
  1439. FILE *pProfileFile = fopen(szUsrProfileFilePath, "wt");
  1440. if (pProfileFile == NULL) {
  1441. RLckUnlockEX(hResLock);
  1442. ErrSetErrorCode(ERR_FILE_CREATE);
  1443. return (ERR_FILE_CREATE);
  1444. }
  1445. UsrWriteInfoList(pUI->InfoList, pProfileFile);
  1446. fclose(pProfileFile);
  1447. RLckUnlockEX(hResLock);
  1448. return (0);
  1449. }
  1450. int UsrGetDBFileSnapShot(const char *pszFileName)
  1451. {
  1452. char szUsrFilePath[SYS_MAX_PATH] = "";
  1453. UsrGetTableFilePath(szUsrFilePath, sizeof(szUsrFilePath));
  1454. char szResLock[SYS_MAX_PATH] = "";
  1455. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szUsrFilePath, szResLock,
  1456.   sizeof(szResLock)));
  1457. if (hResLock == INVALID_RLCK_HANDLE)
  1458. return (ErrGetErrorCode());
  1459. if (MscCopyFile(pszFileName, szUsrFilePath) < 0) {
  1460. RLckUnlockSH(hResLock);
  1461. return (ErrGetErrorCode());
  1462. }
  1463. RLckUnlockSH(hResLock);
  1464. return (0);
  1465. }
  1466. USRF_HANDLE UsrOpenDB(void)
  1467. {
  1468. UsersDBScanData *pUDBSD = (UsersDBScanData *) SysAlloc(sizeof(UsersDBScanData));
  1469. if (pUDBSD == NULL)
  1470. return (INVALID_USRF_HANDLE);
  1471. SysGetTmpFile(pUDBSD->szTmpDBFile);
  1472. if (UsrGetDBFileSnapShot(pUDBSD->szTmpDBFile) < 0) {
  1473. SysFree(pUDBSD);
  1474. return (INVALID_USRF_HANDLE);
  1475. }
  1476. if ((pUDBSD->pDBFile = fopen(pUDBSD->szTmpDBFile, "rt")) == NULL) {
  1477. SysRemove(pUDBSD->szTmpDBFile);
  1478. SysFree(pUDBSD);
  1479. return (INVALID_USRF_HANDLE);
  1480. }
  1481. return ((USRF_HANDLE) pUDBSD);
  1482. }
  1483. void UsrCloseDB(USRF_HANDLE hUsersDB)
  1484. {
  1485. UsersDBScanData *pUDBSD = (UsersDBScanData *) hUsersDB;
  1486. fclose(pUDBSD->pDBFile);
  1487. SysRemove(pUDBSD->szTmpDBFile);
  1488. SysFree(pUDBSD);
  1489. }
  1490. UserInfo *UsrGetFirstUser(USRF_HANDLE hUsersDB)
  1491. {
  1492. UsersDBScanData *pUDBSD = (UsersDBScanData *) hUsersDB;
  1493. rewind(pUDBSD->pDBFile);
  1494. UserInfo *pUI = NULL;
  1495. char szUsrLine[USR_TABLE_LINE_MAX] = "";
  1496. while ((pUI == NULL) &&
  1497.        (MscFGets(szUsrLine, sizeof(szUsrLine) - 1, pUDBSD->pDBFile) != NULL)) {
  1498. char **ppszStrings = StrGetTabLineStrings(szUsrLine);
  1499. if (ppszStrings == NULL)
  1500. continue;
  1501. int iFieldsCount = StrStringsCount(ppszStrings);
  1502. if (iFieldsCount >= usrMax)
  1503. pUI = UsrGetUserFromStrings(ppszStrings);
  1504. StrFreeStrings(ppszStrings);
  1505. }
  1506. return (pUI);
  1507. }
  1508. UserInfo *UsrGetNextUser(USRF_HANDLE hUsersDB)
  1509. {
  1510. UsersDBScanData *pUDBSD = (UsersDBScanData *) hUsersDB;
  1511. UserInfo *pUI = NULL;
  1512. char szUsrLine[USR_TABLE_LINE_MAX] = "";
  1513. while ((pUI == NULL) &&
  1514.        (MscFGets(szUsrLine, sizeof(szUsrLine) - 1, pUDBSD->pDBFile) != NULL)) {
  1515. char **ppszStrings = StrGetTabLineStrings(szUsrLine);
  1516. if (ppszStrings == NULL)
  1517. continue;
  1518. int iFieldsCount = StrStringsCount(ppszStrings);
  1519. if (iFieldsCount >= usrMax)
  1520. pUI = UsrGetUserFromStrings(ppszStrings);
  1521. StrFreeStrings(ppszStrings);
  1522. }
  1523. return (pUI);
  1524. }
  1525. static char *UsrGetPop3LocksPath(UserInfo * pUI, char *pszPop3LockPath, int iMaxPath)
  1526. {
  1527. CfgGetRootPath(pszPop3LockPath, iMaxPath);
  1528. StrNCat(pszPop3LockPath, POP3_LOCKS_DIR, iMaxPath);
  1529. AppendSlash(pszPop3LockPath);
  1530. char szUserAddress[MAX_ADDR_NAME] = "";
  1531. UsrGetAddress(pUI, szUserAddress);
  1532. StrNCat(pszPop3LockPath, szUserAddress, iMaxPath);
  1533. return (pszPop3LockPath);
  1534. }
  1535. int UsrPOP3Lock(UserInfo * pUI)
  1536. {
  1537. char szLockPath[SYS_MAX_PATH] = "";
  1538. UsrGetPop3LocksPath(pUI, szLockPath, sizeof(szLockPath));
  1539. if (SysLockFile(szLockPath) < 0)
  1540. return (ErrGetErrorCode());
  1541. return (0);
  1542. }
  1543. void UsrPOP3Unlock(UserInfo * pUI)
  1544. {
  1545. char szLockPath[SYS_MAX_PATH] = "";
  1546. UsrGetPop3LocksPath(pUI, szLockPath, sizeof(szLockPath));
  1547. SysUnlockFile(szLockPath);
  1548. }
  1549. int UsrClearPop3LocksDir(void)
  1550. {
  1551. char szLocksDir[SYS_MAX_PATH] = "";
  1552. CfgGetRootPath(szLocksDir, sizeof(szLocksDir));
  1553. StrNCat(szLocksDir, POP3_LOCKS_DIR, sizeof(szLocksDir));
  1554. return (MscClearDirectory(szLocksDir));
  1555. }
  1556. char *UsrGetUserPath(UserInfo * pUI, char *pszUserPath, int iMaxPath, int iFinalSlash)
  1557. {
  1558. MDomGetDomainPath(pUI->pszDomain, pszUserPath, iMaxPath, 1);
  1559. StrNCat(pszUserPath, pUI->pszPath, iMaxPath);
  1560. if (iFinalSlash)
  1561. AppendSlash(pszUserPath);
  1562. return (pszUserPath);
  1563. }
  1564. char *UsrGetMailboxPath(UserInfo * pUI, char *pszMBPath, int iMaxPath, int iFinalSlash)
  1565. {
  1566. UsrGetUserPath(pUI, pszMBPath, iMaxPath, 1);
  1567. StrNCat(pszMBPath, UsrGetMailboxDir(), iMaxPath);
  1568. if (iFinalSlash)
  1569. AppendSlash(pszMBPath);
  1570. return (pszMBPath);
  1571. }
  1572. int UsrMoveToMailBox(UserInfo * pUI, char const *pszFileName, char const *pszMessageID)
  1573. {
  1574. if (iMailboxType == XMAIL_MAILBOX) {
  1575. ///////////////////////////////////////////////////////////////////////////////
  1576. //  Setup full mailbox file path
  1577. ///////////////////////////////////////////////////////////////////////////////
  1578. char szMBPath[SYS_MAX_PATH] = "";
  1579. char szMBFile[SYS_MAX_PATH] = "";
  1580. UsrGetMailboxPath(pUI, szMBPath, sizeof(szMBPath), 0);
  1581. sprintf(szMBFile, "%s" SYS_SLASH_STR "%s", szMBPath, pszMessageID);
  1582. char szResLock[SYS_MAX_PATH] = "";
  1583. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szMBPath, szResLock,
  1584.   sizeof(szResLock)));
  1585. if (hResLock == INVALID_RLCK_HANDLE)
  1586. return (ErrGetErrorCode());
  1587. if (MscMoveFile(pszFileName, szMBFile) < 0) {
  1588. ErrorPush();
  1589. RLckUnlockEX(hResLock);
  1590. return (ErrorPop());
  1591. }
  1592. RLckUnlockEX(hResLock);
  1593. } else {
  1594. ///////////////////////////////////////////////////////////////////////////////
  1595. //  Get user Maildir path
  1596. ///////////////////////////////////////////////////////////////////////////////
  1597. char szMBPath[SYS_MAX_PATH] = "";
  1598. UsrGetMailboxPath(pUI, szMBPath, sizeof(szMBPath), 0);
  1599. char szResLock[SYS_MAX_PATH] = "";
  1600. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szMBPath, szResLock,
  1601.   sizeof(szResLock)));
  1602. if (hResLock == INVALID_RLCK_HANDLE)
  1603. return (ErrGetErrorCode());
  1604. if (MdirMoveMessage(szMBPath, pszFileName, pszMessageID) < 0) {
  1605. ErrorPush();
  1606. RLckUnlockEX(hResLock);
  1607. return (ErrorPop());
  1608. }
  1609. RLckUnlockEX(hResLock);
  1610. }
  1611. return (0);
  1612. }
  1613. int UsrGetMailProcessFile(UserInfo * pUI, char const *pszMPPath)
  1614. {
  1615. int iAppendFiles = 0;
  1616. char szMPFilePath[SYS_MAX_PATH] = "";
  1617. if (MDomGetDomainPath(pUI->pszDomain, szMPFilePath, sizeof(szMPFilePath) - 1,
  1618.       1) == NULL)
  1619. return (ErrGetErrorCode());
  1620. StrNCat(szMPFilePath, MAILPROCESS_FILE, sizeof(szMPFilePath) - 1);
  1621. if (SysExistFile(szMPFilePath)) {
  1622. char szResLock[SYS_MAX_PATH] = "";
  1623. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szMPFilePath, szResLock,
  1624.   sizeof(szResLock)));
  1625. if (hResLock == INVALID_RLCK_HANDLE)
  1626. return (ErrGetErrorCode());
  1627. if (MscAppendFile(pszMPPath, szMPFilePath) < 0) {
  1628. ErrorPush();
  1629. CheckRemoveFile(pszMPPath);
  1630. RLckUnlockSH(hResLock);
  1631. return (ErrorPop());
  1632. }
  1633. RLckUnlockSH(hResLock);
  1634. iAppendFiles++;
  1635. }
  1636. if (UsrGetUserPath(pUI, szMPFilePath, sizeof(szMPFilePath), 1) == NULL)
  1637. return (ErrGetErrorCode());
  1638. StrNCat(szMPFilePath, MAILPROCESS_FILE, sizeof(szMPFilePath));
  1639. if (SysExistFile(szMPFilePath)) {
  1640. char szResLock[SYS_MAX_PATH] = "";
  1641. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szMPFilePath, szResLock,
  1642.   sizeof(szResLock)));
  1643. if (hResLock == INVALID_RLCK_HANDLE)
  1644. return (ErrGetErrorCode());
  1645. if (MscAppendFile(pszMPPath, szMPFilePath) < 0) {
  1646. ErrorPush();
  1647. CheckRemoveFile(pszMPPath);
  1648. RLckUnlockSH(hResLock);
  1649. return (ErrorPop());
  1650. }
  1651. RLckUnlockSH(hResLock);
  1652. iAppendFiles++;
  1653. }
  1654. if (!iAppendFiles) {
  1655. ErrSetErrorCode(ERR_NO_MAILPROC_FILE);
  1656. return (ERR_NO_MAILPROC_FILE);
  1657. }
  1658. return (0);
  1659. }
  1660. int UsrSetMailProcessFile(UserInfo * pUI, char const *pszMPPath)
  1661. {
  1662. char szMPFilePath[SYS_MAX_PATH] = "";
  1663. if (UsrGetUserPath(pUI, szMPFilePath, sizeof(szMPFilePath), 1) == NULL)
  1664. return (ErrGetErrorCode());
  1665. StrNCat(szMPFilePath, MAILPROCESS_FILE, sizeof(szMPFilePath));
  1666. char szResLock[SYS_MAX_PATH] = "";
  1667. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szMPFilePath, szResLock,
  1668.   sizeof(szResLock)));
  1669. if (hResLock == INVALID_RLCK_HANDLE)
  1670. return (ErrGetErrorCode());
  1671. if (pszMPPath != NULL) {
  1672. if (MscCopyFile(szMPFilePath, pszMPPath) < 0) {
  1673. ErrorPush();
  1674. RLckUnlockEX(hResLock);
  1675. return (ErrorPop());
  1676. }
  1677. } else
  1678. SysRemove(szMPFilePath);
  1679. RLckUnlockEX(hResLock);
  1680. return (0);
  1681. }
  1682. char *UsrGetAddress(UserInfo * pUI, char *pszAddress)
  1683. {
  1684. sprintf(pszAddress, "%s@%s", pUI->pszName, pUI->pszDomain);
  1685. return (pszAddress);
  1686. }
  1687. int UsrGetAliasDBFileSnapShot(char const *pszFileName)
  1688. {
  1689. char szAlsFilePath[SYS_MAX_PATH] = "";
  1690. UsrGetAliasFilePath(szAlsFilePath, sizeof(szAlsFilePath));
  1691. char szResLock[SYS_MAX_PATH] = "";
  1692. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szAlsFilePath, szResLock,
  1693.   sizeof(szResLock)));
  1694. if (hResLock == INVALID_RLCK_HANDLE)
  1695. return (ErrGetErrorCode());
  1696. if (MscCopyFile(pszFileName, szAlsFilePath) < 0) {
  1697. RLckUnlockSH(hResLock);
  1698. return (ErrGetErrorCode());
  1699. }
  1700. RLckUnlockSH(hResLock);
  1701. return (0);
  1702. }
  1703. ALSF_HANDLE UsrAliasOpenDB(void)
  1704. {
  1705. AliasDBScanData *pADBSD = (AliasDBScanData *) SysAlloc(sizeof(AliasDBScanData));
  1706. if (pADBSD == NULL)
  1707. return (INVALID_ALSF_HANDLE);
  1708. SysGetTmpFile(pADBSD->szTmpDBFile);
  1709. if (UsrGetAliasDBFileSnapShot(pADBSD->szTmpDBFile) < 0) {
  1710. SysFree(pADBSD);
  1711. return (INVALID_ALSF_HANDLE);
  1712. }
  1713. if ((pADBSD->pDBFile = fopen(pADBSD->szTmpDBFile, "rt")) == NULL) {
  1714. SysRemove(pADBSD->szTmpDBFile);
  1715. SysFree(pADBSD);
  1716. return (INVALID_ALSF_HANDLE);
  1717. }
  1718. return ((ALSF_HANDLE) pADBSD);
  1719. }
  1720. void UsrAliasCloseDB(ALSF_HANDLE hAliasDB)
  1721. {
  1722. AliasDBScanData *pADBSD = (AliasDBScanData *) hAliasDB;
  1723. fclose(pADBSD->pDBFile);
  1724. SysRemove(pADBSD->szTmpDBFile);
  1725. SysFree(pADBSD);
  1726. }
  1727. AliasInfo *UsrAliasGetFirst(ALSF_HANDLE hAliasDB)
  1728. {
  1729. AliasDBScanData *pADBSD = (AliasDBScanData *) hAliasDB;
  1730. rewind(pADBSD->pDBFile);
  1731. AliasInfo *pAI = NULL;
  1732. char szUsrLine[USR_ALIAS_LINE_MAX] = "";
  1733. while ((pAI == NULL) &&
  1734.        (MscFGets(szUsrLine, sizeof(szUsrLine) - 1, pADBSD->pDBFile) != NULL)) {
  1735. char **ppszStrings = StrGetTabLineStrings(szUsrLine);
  1736. if (ppszStrings == NULL)
  1737. continue;
  1738. int iFieldsCount = StrStringsCount(ppszStrings);
  1739. if (iFieldsCount >= alsMax)
  1740. pAI =
  1741.     UsrAllocAlias(ppszStrings[alsDomain], ppszStrings[alsAlias],
  1742.   ppszStrings[alsName]);
  1743. StrFreeStrings(ppszStrings);
  1744. }
  1745. return (pAI);
  1746. }
  1747. AliasInfo *UsrAliasGetNext(ALSF_HANDLE hAliasDB)
  1748. {
  1749. AliasDBScanData *pADBSD = (AliasDBScanData *) hAliasDB;
  1750. AliasInfo *pAI = NULL;
  1751. char szUsrLine[USR_ALIAS_LINE_MAX] = "";
  1752. while ((pAI == NULL) &&
  1753.        (MscFGets(szUsrLine, sizeof(szUsrLine) - 1, pADBSD->pDBFile) != NULL)) {
  1754. char **ppszStrings = StrGetTabLineStrings(szUsrLine);
  1755. if (ppszStrings == NULL)
  1756. continue;
  1757. int iFieldsCount = StrStringsCount(ppszStrings);
  1758. if (iFieldsCount >= alsMax)
  1759. pAI =
  1760.     UsrAllocAlias(ppszStrings[alsDomain], ppszStrings[alsAlias],
  1761.   ppszStrings[alsName]);
  1762. StrFreeStrings(ppszStrings);
  1763. }
  1764. return (pAI);
  1765. }