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

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 "SList.h"
  27. #include "BuffSock.h"
  28. #include "ResLocks.h"
  29. #include "MiscUtils.h"
  30. #include "MD5.h"
  31. #include "MailConfig.h"
  32. #include "SvrUtils.h"
  33. #include "UsrUtils.h"
  34. #include "StrUtils.h"
  35. #include "POP3Utils.h"
  36. #include "MessQueue.h"
  37. #include "SMAILUtils.h"
  38. #include "QueueUtils.h"
  39. #include "UsrMailList.h"
  40. #include "POP3GwLink.h"
  41. #include "MailDomains.h"
  42. #include "AliasDomain.h"
  43. #include "ExtAliases.h"
  44. #include "SMTPUtils.h"
  45. #include "MailConfig.h"
  46. #include "AppDefines.h"
  47. #include "MailSvr.h"
  48. #include "CTRLSvr.h"
  49. #define CTRL_ACCOUNTS_FILE      "ctrlaccounts.tab"
  50. #define CTRL_ACCOUNTS_LINE_MAX  512
  51. #define CTRLSRV_ACCEPT_TIMEOUT  4
  52. #define CTRL_LISTEN_SIZE        8
  53. #define CTRL_WAIT_SLEEP         2
  54. #define MAX_CLIENTS_WAIT        300
  55. #define STD_CTRL_TIMEOUT        45
  56. #define CTRL_IPMAP_FILE         "ctrl.ipmap.tab"
  57. #define CTRL_LOG_FILE           "ctrl"
  58. #define CTRL_MAX_LINE_SIZE      4096
  59. #define CTRL_QUIT_CMD_EXIT      1
  60. #define CTRL_LISTFOLLOW_RESULT  100
  61. #define CTRL_WAITDATA_RESULT    101
  62. #define CTRL_VAR_DROP_VALUE     ".|rm"
  63. #define CTRL_SERVER_NAME        "[" APP_NAME_VERSION_STR " CTRL Server]"
  64. enum CtrlAccountsFileds {
  65. accUsername = 0,
  66. accPassword,
  67. accMax
  68. };
  69. static CTRLConfig *CTRLGetConfigCopy(SHB_HANDLE hShbCTRL);
  70. static int CTRLLogEnabled(SHB_HANDLE hShbCTRL, CTRLConfig * pCTRLCfg = NULL);
  71. static int CTRLCheckPeerIP(SYS_SOCKET SockFD);
  72. static int CTRLLogSession(char const *pszUsername, char const *pszPassword,
  73.   SYS_INET_ADDR const &PeerInfo, int iStatus);
  74. static int CTRLThreadCountAdd(long lCount, SHB_HANDLE hShbCTRL, CTRLConfig * pCTRLCfg = NULL);
  75. static unsigned int CTRLClientThread(void *pThreadData);
  76. static int CTRLSendCmdResult(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock, int iErrorCode);
  77. static int CTRLSendCmdResult(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock, int iErrorCode,
  78.      char const *pszMessage);
  79. static int CTRLVSendCmdResult(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock, int iErrorCode,
  80.       char const *pszFormat, ...);
  81. static int CTRLSendCmdResult(BSOCK_HANDLE hBSock, int iErrorCode, char const *pszMessage,
  82.      int iTimeout);
  83. static char *CTRLGetAccountsFilePath(char *pszAccFilePath, int iMaxPath);
  84. static int CTRLAccountCheck(CTRLConfig * pCTRLCfg, char const *pszUsername,
  85.     char const *pszPassword, char const *pszTimeStamp);
  86. static int CTRLLogin(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  87.      char const *pszTimeStamp, SYS_INET_ADDR const &PeerInfo);
  88. static int CTRLHandleSession(SHB_HANDLE hShbCTRL, BSOCK_HANDLE hBSock,
  89.      SYS_INET_ADDR const &PeerInfo);
  90. static int CTRLProcessCommand(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock, char const *pszCommand);
  91. static int CTRLDo_useradd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  92.   char const *const *ppszTokens, int iTokensCount);
  93. static int CTRLDo_userdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  94.   char const *const *ppszTokens, int iTokensCount);
  95. static int CTRLDo_userpasswd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  96.      char const *const *ppszTokens, int iTokensCount);
  97. static int CTRLDo_aliasadd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  98.    char const *const *ppszTokens, int iTokensCount);
  99. static int CTRLDo_aliasdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  100.    char const *const *ppszTokens, int iTokensCount);
  101. static int CTRLDo_aliaslist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  102.     char const *const *ppszTokens, int iTokensCount);
  103. static int CTRLDo_exaliasadd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  104.      char const *const *ppszTokens, int iTokensCount);
  105. static int CTRLDo_exaliasdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  106.      char const *const *ppszTokens, int iTokensCount);
  107. static int CTRLDo_exaliaslist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  108.       char const *const *ppszTokens, int iTokensCount);
  109. static int CTRLDo_uservars(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  110.    char const *const *ppszTokens, int iTokensCount);
  111. static int CTRLDo_uservarsset(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  112.       char const *const *ppszTokens, int iTokensCount);
  113. static int CTRLDo_userlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  114.    char const *const *ppszTokens, int iTokensCount);
  115. static int CTRLDo_usergetmproc(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  116.        char const *const *ppszTokens, int iTokensCount);
  117. static int CTRLDo_usersetmproc(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  118.        char const *const *ppszTokens, int iTokensCount);
  119. static int CTRLDo_userauth(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  120.    char const *const *ppszTokens, int iTokensCount);
  121. static int CTRLDo_userstat(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  122.    char const *const *ppszTokens, int iTokensCount);
  123. static int CTRLDo_mluseradd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  124.     char const *const *ppszTokens, int iTokensCount);
  125. static int CTRLDo_mluserdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  126.     char const *const *ppszTokens, int iTokensCount);
  127. static int CTRLDo_mluserlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  128.      char const *const *ppszTokens, int iTokensCount);
  129. static int CTRLDo_domainadd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  130.     char const *const *ppszTokens, int iTokensCount);
  131. static int CTRLDo_domaindel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  132.     char const *const *ppszTokens, int iTokensCount);
  133. static int CTRLDo_domainlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  134.      char const *const *ppszTokens, int iTokensCount);
  135. static int CTRLDo_custdomget(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  136.      char const *const *ppszTokens, int iTokensCount);
  137. static int CTRLDo_custdomset(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  138.      char const *const *ppszTokens, int iTokensCount);
  139. static int CTRLDo_custdomlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  140.       char const *const *ppszTokens, int iTokensCount);
  141. static int CTRLDo_noop(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  142.        char const *const *ppszTokens, int iTokensCount);
  143. static int CTRLDo_quit(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  144.        char const *const *ppszTokens, int iTokensCount);
  145. static int CTRLDo_poplnkadd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  146.     char const *const *ppszTokens, int iTokensCount);
  147. static int CTRLDo_poplnkdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  148.     char const *const *ppszTokens, int iTokensCount);
  149. static int CTRLDo_poplnklist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  150.      char const *const *ppszTokens, int iTokensCount);
  151. static int CTRLDo_poplnkenable(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  152.        char const *const *ppszTokens, int iTokensCount);
  153. static int CTRLCheckRelativePath(char const *pszPath);
  154. static int CTRLDo_filelist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  155.    char const *const *ppszTokens, int iTokensCount);
  156. static int CTRLDo_cfgfileget(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  157.      char const *const *ppszTokens, int iTokensCount);
  158. static int CTRLDo_cfgfileset(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  159.      char const *const *ppszTokens, int iTokensCount);
  160. static int CTRLDo_frozlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  161.    char const *const *ppszTokens, int iTokensCount);
  162. static int CTRLDo_frozsubmit(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  163.      char const *const *ppszTokens, int iTokensCount);
  164. static int CTRLDo_frozdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  165.   char const *const *ppszTokens, int iTokensCount);
  166. static int CTRLDo_frozgetlog(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  167.      char const *const *ppszTokens, int iTokensCount);
  168. static int CTRLDo_frozgetmsg(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  169.      char const *const *ppszTokens, int iTokensCount);
  170. static int CTRLDo_etrn(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  171.        char const *const *ppszTokens, int iTokensCount);
  172. static int CTRLDo_aliasdomainadd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  173.  char const *const *ppszTokens, int iTokensCount);
  174. static int CTRLDo_aliasdomaindel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  175.  char const *const *ppszTokens, int iTokensCount);
  176. static int CTRLDo_aliasdomainlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  177.   char const *const *ppszTokens, int iTokensCount);
  178. static CTRLConfig *CTRLGetConfigCopy(SHB_HANDLE hShbCTRL)
  179. {
  180. CTRLConfig *pCTRLCfg = (CTRLConfig *) ShbLock(hShbCTRL);
  181. if (pCTRLCfg == NULL)
  182. return (NULL);
  183. CTRLConfig *pCTRLCfgCopy = (CTRLConfig *) SysAlloc(sizeof(CTRLConfig));
  184. if (pCTRLCfgCopy != NULL)
  185. memcpy(pCTRLCfgCopy, pCTRLCfg, sizeof(CTRLConfig));
  186. ShbUnlock(hShbCTRL);
  187. return (pCTRLCfgCopy);
  188. }
  189. static int CTRLLogEnabled(SHB_HANDLE hShbCTRL, CTRLConfig * pCTRLCfg)
  190. {
  191. int iDoUnlock = 0;
  192. if (pCTRLCfg == NULL) {
  193. if ((pCTRLCfg = (CTRLConfig *) ShbLock(hShbCTRL)) == NULL)
  194. return (ErrGetErrorCode());
  195. ++iDoUnlock;
  196. }
  197. unsigned long ulFlags = pCTRLCfg->ulFlags;
  198. if (iDoUnlock)
  199. ShbUnlock(hShbCTRL);
  200. return ((ulFlags & CTRLF_LOG_ENABLED) ? 1 : 0);
  201. }
  202. static int CTRLCheckPeerIP(SYS_SOCKET SockFD)
  203. {
  204. char szIPMapFile[SYS_MAX_PATH] = "";
  205. CfgGetRootPath(szIPMapFile, sizeof(szIPMapFile));
  206. StrSNCat(szIPMapFile, CTRL_IPMAP_FILE);
  207. if (SysExistFile(szIPMapFile)) {
  208. SYS_INET_ADDR PeerInfo;
  209. if (SysGetPeerInfo(SockFD, PeerInfo) < 0)
  210. return (ErrGetErrorCode());
  211. if (MscCheckAllowedIP(szIPMapFile, PeerInfo, true) < 0)
  212. return (ErrGetErrorCode());
  213. }
  214. return (0);
  215. }
  216. static int CTRLLogSession(char const *pszUsername, char const *pszPassword,
  217.   SYS_INET_ADDR const &PeerInfo, int iStatus)
  218. {
  219. char szTime[256] = "";
  220. MscGetTimeNbrString(szTime, sizeof(szTime) - 1);
  221. RLCK_HANDLE hResLock = RLckLockEX(SVR_LOGS_DIR SYS_SLASH_STR CTRL_LOG_FILE);
  222. if (hResLock == INVALID_RLCK_HANDLE)
  223. return (ErrGetErrorCode());
  224. char szIP[128] = "???.???.???.???";
  225. MscFileLog(CTRL_LOG_FILE, ""%s""
  226.    "t"%s""
  227.    "t"%s""
  228.    "t"%s""
  229.    "t"%s""
  230.    "n", SysInetNToA(PeerInfo, szIP), pszUsername, pszPassword, szTime,
  231.    (iStatus == 0) ? "REQ" : ((iStatus > 0) ? "AUTH" : "FAIL"));
  232. RLckUnlockEX(hResLock);
  233. return (0);
  234. }
  235. static int CTRLThreadCountAdd(long lCount, SHB_HANDLE hShbCTRL, CTRLConfig * pCTRLCfg)
  236. {
  237. int iDoUnlock = 0;
  238. if (pCTRLCfg == NULL) {
  239. if ((pCTRLCfg = (CTRLConfig *) ShbLock(hShbCTRL)) == NULL)
  240. return (ErrGetErrorCode());
  241. ++iDoUnlock;
  242. }
  243. if ((pCTRLCfg->lThreadCount + lCount) > pCTRLCfg->lMaxThreads) {
  244. if (iDoUnlock)
  245. ShbUnlock(hShbCTRL);
  246. ErrSetErrorCode(ERR_SERVER_BUSY);
  247. return (ERR_SERVER_BUSY);
  248. }
  249. pCTRLCfg->lThreadCount += lCount;
  250. if (iDoUnlock)
  251. ShbUnlock(hShbCTRL);
  252. return (0);
  253. }
  254. unsigned int CTRLThreadProc(void *pThreadData)
  255. {
  256. CTRLConfig *pCTRLCfg = (CTRLConfig *) ShbLock(hShbCTRL);
  257. if (pCTRLCfg == NULL)
  258. return (ErrGetErrorCode());
  259. int iNumSockFDs = 0;
  260. SYS_SOCKET SockFDs[MAX_CTRL_ACCEPT_ADDRESSES];
  261. if (MscCreateServerSockets(pCTRLCfg->iNumAddr, pCTRLCfg->SvrAddr, pCTRLCfg->iPort,
  262.    CTRL_LISTEN_SIZE, SockFDs, iNumSockFDs) < 0) {
  263. ErrorPush();
  264. SysLogMessage(LOG_LEV_ERROR, "%sn", ErrGetErrorString());
  265. ShbUnlock(hShbCTRL);
  266. return (ErrorPop());
  267. }
  268. ShbUnlock(hShbCTRL);
  269. SysLogMessage(LOG_LEV_MESSAGE, "%s startedn", CTRL_SERVER_NAME);
  270. for (;;) {
  271. int iNumConnSockFD = 0;
  272. SYS_SOCKET ConnSockFD[MAX_CTRL_ACCEPT_ADDRESSES];
  273. if (MscAcceptServerConnection(SockFDs, iNumSockFDs, ConnSockFD,
  274.       iNumConnSockFD, CTRLSRV_ACCEPT_TIMEOUT) < 0) {
  275. unsigned long ulFlags = CTRLF_STOP_SERVER;
  276. pCTRLCfg = (CTRLConfig *) ShbLock(hShbCTRL);
  277. if (pCTRLCfg != NULL)
  278. ulFlags = pCTRLCfg->ulFlags;
  279. ShbUnlock(hShbCTRL);
  280. if (ulFlags & CTRLF_STOP_SERVER)
  281. break;
  282. else
  283. continue;
  284. }
  285. for (int ss = 0; ss < iNumConnSockFD; ss++) {
  286. SYS_THREAD hClientThread =
  287.     SysCreateServiceThread(CTRLClientThread, ConnSockFD[ss]);
  288. if (hClientThread != SYS_INVALID_THREAD)
  289. SysCloseThread(hClientThread, 0);
  290. else
  291. SysCloseSocket(ConnSockFD[ss]);
  292. }
  293. }
  294. for (int ss = 0; ss < iNumSockFDs; ss++)
  295. SysCloseSocket(SockFDs[ss]);
  296. ///////////////////////////////////////////////////////////////////////////////
  297. //  Wait for client completion
  298. ///////////////////////////////////////////////////////////////////////////////
  299. for (int iTotalWait = 0; (iTotalWait < MAX_CLIENTS_WAIT); iTotalWait += CTRL_WAIT_SLEEP) {
  300. pCTRLCfg = (CTRLConfig *) ShbLock(hShbCTRL);
  301. if (pCTRLCfg == NULL)
  302. break;
  303. long lThreadCount = pCTRLCfg->lThreadCount;
  304. ShbUnlock(hShbCTRL);
  305. if (lThreadCount == 0)
  306. break;
  307. SysSleep(CTRL_WAIT_SLEEP);
  308. }
  309. SysLogMessage(LOG_LEV_MESSAGE, "%s stoppedn", CTRL_SERVER_NAME);
  310. return (0);
  311. }
  312. static unsigned int CTRLClientThread(void *pThreadData)
  313. {
  314. SYS_SOCKET SockFD = (SYS_SOCKET) (unsigned long) pThreadData;
  315. ///////////////////////////////////////////////////////////////////////////////
  316. //  Link socket to the bufferer
  317. ///////////////////////////////////////////////////////////////////////////////
  318. BSOCK_HANDLE hBSock = BSckAttach(SockFD);
  319. if (hBSock == INVALID_BSOCK_HANDLE) {
  320. ErrorPush();
  321. SysLogMessage(LOG_LEV_ERROR, "%sn", ErrGetErrorString());
  322. SysCloseSocket(SockFD);
  323. return (ErrorPop());
  324. }
  325. ///////////////////////////////////////////////////////////////////////////////
  326. //  Check IP permission
  327. ///////////////////////////////////////////////////////////////////////////////
  328. if (CTRLCheckPeerIP(SockFD) < 0) {
  329. ErrorPush();
  330. CTRLSendCmdResult(hBSock, ErrorFetch(), ErrGetErrorString(), STD_CTRL_TIMEOUT);
  331. BSckDetach(hBSock, 1);
  332. return (ErrorPop());
  333. }
  334. ///////////////////////////////////////////////////////////////////////////////
  335. //  Increase threads count
  336. ///////////////////////////////////////////////////////////////////////////////
  337. if (CTRLThreadCountAdd(+1, hShbCTRL) < 0) {
  338. ErrorPush();
  339. CTRLSendCmdResult(hBSock, ErrorFetch(), ErrGetErrorString(), STD_CTRL_TIMEOUT);
  340. SysLogMessage(LOG_LEV_ERROR, "%sn", ErrGetErrorString(ErrorFetch()));
  341. BSckDetach(hBSock, 1);
  342. return (ErrorPop());
  343. }
  344. ///////////////////////////////////////////////////////////////////////////////
  345. //  Get client socket information
  346. ///////////////////////////////////////////////////////////////////////////////
  347. SYS_INET_ADDR PeerInfo;
  348. if (SysGetPeerInfo(SockFD, PeerInfo) < 0) {
  349. ErrorPush();
  350. SysLogMessage(LOG_LEV_ERROR, "%sn", ErrGetErrorString());
  351. BSckDetach(hBSock, 1);
  352. CTRLThreadCountAdd(-1, hShbCTRL);
  353. return (ErrorPop());
  354. }
  355. char szIP[128] = "???.???.???.???";
  356. SysLogMessage(LOG_LEV_MESSAGE, "CTRL client connection from [%s]n",
  357.       SysInetNToA(PeerInfo, szIP));
  358. ///////////////////////////////////////////////////////////////////////////////
  359. //  Handle client session
  360. ///////////////////////////////////////////////////////////////////////////////
  361. CTRLHandleSession(hShbCTRL, hBSock, PeerInfo);
  362. SysLogMessage(LOG_LEV_MESSAGE, "CTRL client exit [%s]n", SysInetNToA(PeerInfo, szIP));
  363. ///////////////////////////////////////////////////////////////////////////////
  364. //  Unlink socket from the bufferer and close it
  365. ///////////////////////////////////////////////////////////////////////////////
  366. BSckDetach(hBSock, 1);
  367. ///////////////////////////////////////////////////////////////////////////////
  368. //  Decrease thread count
  369. ///////////////////////////////////////////////////////////////////////////////
  370. CTRLThreadCountAdd(-1, hShbCTRL);
  371. return (0);
  372. }
  373. static int CTRLSendCmdResult(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock, int iErrorCode)
  374. {
  375. return (CTRLSendCmdResult(pCTRLCfg, hBSock, iErrorCode,
  376.   (iErrorCode >= 0) ? "OK" : ErrGetErrorString(iErrorCode)));
  377. }
  378. static int CTRLSendCmdResult(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock, int iErrorCode,
  379.      char const *pszMessage)
  380. {
  381. return (CTRLSendCmdResult(hBSock, iErrorCode, pszMessage, pCTRLCfg->iTimeout));
  382. }
  383. static int CTRLVSendCmdResult(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock, int iErrorCode,
  384.       char const *pszFormat, ...)
  385. {
  386. char *pszMessage = NULL;
  387. STRSPRINTF(pszMessage, pszFormat, pszFormat);
  388. if (pszMessage == NULL)
  389. return (ErrGetErrorCode());
  390. int iSendResult = CTRLSendCmdResult(hBSock, iErrorCode, pszMessage, pCTRLCfg->iTimeout);
  391. SysFree(pszMessage);
  392. return (iSendResult);
  393. }
  394. static int CTRLSendCmdResult(BSOCK_HANDLE hBSock, int iErrorCode, char const *pszMessage,
  395.      int iTimeout)
  396. {
  397. int iSendResult;
  398. if (iErrorCode >= 0)
  399. iSendResult =
  400.     BSckVSendString(hBSock, iTimeout, "+%05d %s", iErrorCode, pszMessage);
  401. else
  402. iSendResult =
  403.     BSckVSendString(hBSock, iTimeout, "-%05d %s", -iErrorCode, pszMessage);
  404. return (iSendResult);
  405. }
  406. static char *CTRLGetAccountsFilePath(char *pszAccFilePath, int iMaxPath)
  407. {
  408. CfgGetRootPath(pszAccFilePath, iMaxPath);
  409. StrNCat(pszAccFilePath, CTRL_ACCOUNTS_FILE, iMaxPath);
  410. return (pszAccFilePath);
  411. }
  412. static int CTRLAccountCheck(CTRLConfig * pCTRLCfg, char const *pszUsername,
  413.     char const *pszPassword, char const *pszTimeStamp)
  414. {
  415. char szAccFilePath[SYS_MAX_PATH] = "";
  416. CTRLGetAccountsFilePath(szAccFilePath, sizeof(szAccFilePath));
  417. char szResLock[SYS_MAX_PATH] = "";
  418. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szAccFilePath, szResLock,
  419.   sizeof(szResLock)));
  420. if (hResLock == INVALID_RLCK_HANDLE)
  421. return (ErrGetErrorCode());
  422. FILE *pAccountsFile = fopen(szAccFilePath, "rt");
  423. if (pAccountsFile == NULL) {
  424. RLckUnlockSH(hResLock);
  425. ErrSetErrorCode(ERR_CTRL_ACCOUNTS_FILE_NOT_FOUND);
  426. return (ERR_CTRL_ACCOUNTS_FILE_NOT_FOUND);
  427. }
  428. char szAccountsLine[CTRL_ACCOUNTS_LINE_MAX] = "";
  429. while (MscFGets(szAccountsLine, sizeof(szAccountsLine) - 1, pAccountsFile) != NULL) {
  430. char **ppszStrings = StrGetTabLineStrings(szAccountsLine);
  431. if (ppszStrings == NULL)
  432. continue;
  433. int iFieldsCount = StrStringsCount(ppszStrings);
  434. if ((iFieldsCount >= accMax) &&
  435.     (stricmp(pszUsername, ppszStrings[accUsername]) == 0)) {
  436. char szClearPassword[256] = "";
  437. StrDeCrypt(ppszStrings[accPassword], szClearPassword);
  438. StrFreeStrings(ppszStrings);
  439. fclose(pAccountsFile);
  440. RLckUnlockSH(hResLock);
  441. ///////////////////////////////////////////////////////////////////////////////
  442. //  Check for MD5 authentication ( # as first char of password )
  443. ///////////////////////////////////////////////////////////////////////////////
  444. if (*pszPassword == '#') {
  445. if (MscMD5Authenticate
  446.     (szClearPassword, pszTimeStamp, pszPassword + 1) < 0) {
  447. ErrSetErrorCode(ERR_BAD_CTRL_LOGIN);
  448. return (ERR_BAD_CTRL_LOGIN);
  449. }
  450. } else if (strcmp(szClearPassword, pszPassword) != 0) {
  451. ErrSetErrorCode(ERR_BAD_CTRL_LOGIN);
  452. return (ERR_BAD_CTRL_LOGIN);
  453. }
  454. return (0);
  455. }
  456. StrFreeStrings(ppszStrings);
  457. }
  458. fclose(pAccountsFile);
  459. RLckUnlockSH(hResLock);
  460. ErrSetErrorCode(ERR_BAD_CTRL_LOGIN);
  461. return (ERR_BAD_CTRL_LOGIN);
  462. }
  463. static int CTRLLogin(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  464.      char const *pszTimeStamp, SYS_INET_ADDR const &PeerInfo)
  465. {
  466. char szLogin[256] = "";
  467. if ((BSckGetString(hBSock, szLogin, sizeof(szLogin) - 1, pCTRLCfg->iTimeout) == NULL) ||
  468.     (MscCmdStringCheck(szLogin) < 0))
  469. return (ErrGetErrorCode());
  470. char **ppszTokens = StrGetTabLineStrings(szLogin);
  471. if (ppszTokens == NULL) {
  472. ErrorPush();
  473. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  474. return (ErrorPop());
  475. }
  476. int iTokensCount = StrStringsCount(ppszTokens);
  477. if (iTokensCount != 2) {
  478. StrFreeStrings(ppszTokens);
  479. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_LOGIN);
  480. ErrSetErrorCode(ERR_BAD_CTRL_LOGIN);
  481. return (ERR_BAD_CTRL_LOGIN);
  482. }
  483. ///////////////////////////////////////////////////////////////////////////////
  484. //  Log CTRL login request
  485. ///////////////////////////////////////////////////////////////////////////////
  486. if (CTRLLogEnabled(SHB_INVALID_HANDLE, pCTRLCfg))
  487. CTRLLogSession(ppszTokens[0], ppszTokens[1], PeerInfo, 0);
  488. ///////////////////////////////////////////////////////////////////////////////
  489. //  Check user and password
  490. ///////////////////////////////////////////////////////////////////////////////
  491. if (CTRLAccountCheck(pCTRLCfg, ppszTokens[0], ppszTokens[1], pszTimeStamp) < 0) {
  492. ErrorPush();
  493. ///////////////////////////////////////////////////////////////////////////////
  494. //  Log CTRL login failure
  495. ///////////////////////////////////////////////////////////////////////////////
  496. if (CTRLLogEnabled(SHB_INVALID_HANDLE, pCTRLCfg))
  497. CTRLLogSession(ppszTokens[0], ppszTokens[1], PeerInfo, -1);
  498. StrFreeStrings(ppszTokens);
  499. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  500. return (ErrorPop());
  501. }
  502. ///////////////////////////////////////////////////////////////////////////////
  503. //  Log CTRL login authentication
  504. ///////////////////////////////////////////////////////////////////////////////
  505. if (CTRLLogEnabled(SHB_INVALID_HANDLE, pCTRLCfg))
  506. CTRLLogSession(ppszTokens[0], ppszTokens[1], PeerInfo, +1);
  507. StrFreeStrings(ppszTokens);
  508. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  509. return (0);
  510. }
  511. static int CTRLHandleSession(SHB_HANDLE hShbCTRL, BSOCK_HANDLE hBSock,
  512.      SYS_INET_ADDR const &PeerInfo)
  513. {
  514. CTRLConfig *pCTRLCfg = CTRLGetConfigCopy(hShbCTRL);
  515. if (pCTRLCfg == NULL)
  516. return (ErrGetErrorCode());
  517. int iSessionTimeout = pCTRLCfg->iSessionTimeout, iTimeout = pCTRLCfg->iTimeout;
  518. ///////////////////////////////////////////////////////////////////////////////
  519. //  Build TimeStamp string
  520. ///////////////////////////////////////////////////////////////////////////////
  521. SYS_INET_ADDR SockInfo;
  522. char szTimeStamp[256] = "";
  523. SysGetSockInfo(BSckGetAttachedSocket(hBSock), SockInfo);
  524. char szIP[128] = "???.???.???.???";
  525. sprintf(szTimeStamp, "<%lu.%lu@%s>",
  526. (unsigned long) time(NULL), SysGetCurrentThreadId(), SysInetNToA(SockInfo, szIP));
  527. ///////////////////////////////////////////////////////////////////////////////
  528. //  Welcome
  529. ///////////////////////////////////////////////////////////////////////////////
  530. char szTime[256] = "";
  531. MscGetTimeStr(szTime, sizeof(szTime) - 1);
  532. CTRLVSendCmdResult(pCTRLCfg, hBSock, 0, "%s %s CTRL Server; %s",
  533.    szTimeStamp, APP_NAME_VERSION_STR, szTime);
  534. ///////////////////////////////////////////////////////////////////////////////
  535. //  User login
  536. ///////////////////////////////////////////////////////////////////////////////
  537. if (CTRLLogin(pCTRLCfg, hBSock, szTimeStamp, PeerInfo) < 0) {
  538. ErrorPush();
  539. SysFree(pCTRLCfg);
  540. return (ErrorPop());
  541. }
  542. SysFree(pCTRLCfg);
  543. ///////////////////////////////////////////////////////////////////////////////
  544. //  Command loop
  545. ///////////////////////////////////////////////////////////////////////////////
  546. char szCommand[CTRL_MAX_LINE_SIZE] = "";
  547. while (!SvrInShutdown() &&
  548.        (BSckGetString(hBSock, szCommand, sizeof(szCommand) - 1, iSessionTimeout) != NULL)
  549.        && (MscCmdStringCheck(szCommand) == 0)) {
  550. ///////////////////////////////////////////////////////////////////////////////
  551. //  Check for exit flag
  552. ///////////////////////////////////////////////////////////////////////////////
  553. pCTRLCfg = CTRLGetConfigCopy(hShbCTRL);
  554. if ((pCTRLCfg == NULL) || (pCTRLCfg->ulFlags & CTRLF_STOP_SERVER)) {
  555. if (pCTRLCfg != NULL)
  556. SysFree(pCTRLCfg);
  557. break;
  558. }
  559. ///////////////////////////////////////////////////////////////////////////////
  560. //  Process client command
  561. ///////////////////////////////////////////////////////////////////////////////
  562. int iCmdResult = CTRLProcessCommand(pCTRLCfg, hBSock, szCommand);
  563. SysFree(pCTRLCfg);
  564. if (iCmdResult == CTRL_QUIT_CMD_EXIT)
  565. break;
  566. }
  567. return (0);
  568. }
  569. static int CTRLProcessCommand(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock, char const *pszCommand)
  570. {
  571. char **ppszTokens = StrGetTabLineStrings(pszCommand);
  572. if (ppszTokens == NULL) {
  573. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  574. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  575. return (ERR_BAD_CTRL_COMMAND);
  576. }
  577. int iTokensCount = StrStringsCount(ppszTokens);
  578. if (iTokensCount < 1) {
  579. StrFreeStrings(ppszTokens);
  580. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  581. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  582. return (ERR_BAD_CTRL_COMMAND);
  583. }
  584. int iCmdResult = -1;
  585. if (stricmp(ppszTokens[0], "useradd") == 0)
  586. iCmdResult = CTRLDo_useradd(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  587. else if (stricmp(ppszTokens[0], "userdel") == 0)
  588. iCmdResult = CTRLDo_userdel(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  589. else if (stricmp(ppszTokens[0], "userpasswd") == 0)
  590. iCmdResult = CTRLDo_userpasswd(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  591. else if (stricmp(ppszTokens[0], "uservars") == 0)
  592. iCmdResult = CTRLDo_uservars(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  593. else if (stricmp(ppszTokens[0], "uservarsset") == 0)
  594. iCmdResult = CTRLDo_uservarsset(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  595. else if (stricmp(ppszTokens[0], "userlist") == 0)
  596. iCmdResult = CTRLDo_userlist(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  597. else if (stricmp(ppszTokens[0], "usergetmproc") == 0)
  598. iCmdResult = CTRLDo_usergetmproc(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  599. else if (stricmp(ppszTokens[0], "usersetmproc") == 0)
  600. iCmdResult = CTRLDo_usersetmproc(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  601. else if (stricmp(ppszTokens[0], "userauth") == 0)
  602. iCmdResult = CTRLDo_userauth(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  603. else if (stricmp(ppszTokens[0], "userstat") == 0)
  604. iCmdResult = CTRLDo_userstat(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  605. else if (stricmp(ppszTokens[0], "aliasadd") == 0)
  606. iCmdResult = CTRLDo_aliasadd(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  607. else if (stricmp(ppszTokens[0], "aliasdel") == 0)
  608. iCmdResult = CTRLDo_aliasdel(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  609. else if (stricmp(ppszTokens[0], "aliaslist") == 0)
  610. iCmdResult = CTRLDo_aliaslist(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  611. else if (stricmp(ppszTokens[0], "exaliasadd") == 0)
  612. iCmdResult = CTRLDo_exaliasadd(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  613. else if (stricmp(ppszTokens[0], "exaliasdel") == 0)
  614. iCmdResult = CTRLDo_exaliasdel(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  615. else if (stricmp(ppszTokens[0], "exaliaslist") == 0)
  616. iCmdResult = CTRLDo_exaliaslist(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  617. else if (stricmp(ppszTokens[0], "mluseradd") == 0)
  618. iCmdResult = CTRLDo_mluseradd(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  619. else if (stricmp(ppszTokens[0], "mluserdel") == 0)
  620. iCmdResult = CTRLDo_mluserdel(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  621. else if (stricmp(ppszTokens[0], "mluserlist") == 0)
  622. iCmdResult = CTRLDo_mluserlist(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  623. else if (stricmp(ppszTokens[0], "domainadd") == 0)
  624. iCmdResult = CTRLDo_domainadd(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  625. else if (stricmp(ppszTokens[0], "domaindel") == 0)
  626. iCmdResult = CTRLDo_domaindel(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  627. else if (stricmp(ppszTokens[0], "domainlist") == 0)
  628. iCmdResult = CTRLDo_domainlist(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  629. else if (stricmp(ppszTokens[0], "custdomget") == 0)
  630. iCmdResult = CTRLDo_custdomget(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  631. else if (stricmp(ppszTokens[0], "custdomset") == 0)
  632. iCmdResult = CTRLDo_custdomset(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  633. else if (stricmp(ppszTokens[0], "custdomlist") == 0)
  634. iCmdResult = CTRLDo_custdomlist(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  635. else if (stricmp(ppszTokens[0], "poplnkadd") == 0)
  636. iCmdResult = CTRLDo_poplnkadd(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  637. else if (stricmp(ppszTokens[0], "poplnkdel") == 0)
  638. iCmdResult = CTRLDo_poplnkdel(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  639. else if (stricmp(ppszTokens[0], "poplnklist") == 0)
  640. iCmdResult = CTRLDo_poplnklist(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  641. else if (stricmp(ppszTokens[0], "poplnkenable") == 0)
  642. iCmdResult = CTRLDo_poplnkenable(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  643. else if (stricmp(ppszTokens[0], "filelist") == 0)
  644. iCmdResult = CTRLDo_filelist(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  645. else if (stricmp(ppszTokens[0], "cfgfileget") == 0)
  646. iCmdResult = CTRLDo_cfgfileget(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  647. else if (stricmp(ppszTokens[0], "cfgfileset") == 0)
  648. iCmdResult = CTRLDo_cfgfileset(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  649. else if (stricmp(ppszTokens[0], "frozlist") == 0)
  650. iCmdResult = CTRLDo_frozlist(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  651. else if (stricmp(ppszTokens[0], "frozsubmit") == 0)
  652. iCmdResult = CTRLDo_frozsubmit(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  653. else if (stricmp(ppszTokens[0], "frozdel") == 0)
  654. iCmdResult = CTRLDo_frozdel(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  655. else if (stricmp(ppszTokens[0], "frozgetlog") == 0)
  656. iCmdResult = CTRLDo_frozgetlog(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  657. else if (stricmp(ppszTokens[0], "frozgetmsg") == 0)
  658. iCmdResult = CTRLDo_frozgetmsg(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  659. else if (stricmp(ppszTokens[0], "aliasdomainadd") == 0)
  660. iCmdResult = CTRLDo_aliasdomainadd(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  661. else if (stricmp(ppszTokens[0], "aliasdomaindel") == 0)
  662. iCmdResult = CTRLDo_aliasdomaindel(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  663. else if (stricmp(ppszTokens[0], "aliasdomainlist") == 0)
  664. iCmdResult = CTRLDo_aliasdomainlist(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  665. else if (stricmp(ppszTokens[0], "etrn") == 0)
  666. iCmdResult = CTRLDo_etrn(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  667. else if (stricmp(ppszTokens[0], "noop") == 0)
  668. iCmdResult = CTRLDo_noop(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  669. else if (stricmp(ppszTokens[0], "quit") == 0)
  670. iCmdResult = CTRLDo_quit(pCTRLCfg, hBSock, ppszTokens, iTokensCount);
  671. else {
  672. StrFreeStrings(ppszTokens);
  673. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  674. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  675. return (ERR_BAD_CTRL_COMMAND);
  676. }
  677. StrFreeStrings(ppszTokens);
  678. return (iCmdResult);
  679. }
  680. static int CTRLDo_useradd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  681.   char const *const *ppszTokens, int iTokensCount)
  682. {
  683. if (iTokensCount != 5) {
  684. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  685. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  686. return (ERR_BAD_CTRL_COMMAND);
  687. }
  688. if (MDomIsHandledDomain(ppszTokens[1]) < 0) {
  689. ErrorPush();
  690. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  691. return (ErrorPop());
  692. }
  693. if ((USmtpCheckAddressPart(ppszTokens[1]) < 0) ||
  694.     (USmtpCheckAddressPart(ppszTokens[2]) < 0)) {
  695. ErrorPush();
  696. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  697. return (ErrorPop());
  698. }
  699. UserInfo *pUI = UsrCreateDefaultUser(ppszTokens[1], ppszTokens[2], ppszTokens[3],
  700.      (ppszTokens[4][0] == 'M') ? usrTypeML : usrTypeUser);
  701. if (pUI == NULL) {
  702. ErrorPush();
  703. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  704. return (ErrorPop());
  705. }
  706. if (UsrAddUser(pUI) < 0) {
  707. ErrorPush();
  708. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  709. UsrFreeUserInfo(pUI);
  710. return (ErrorPop());
  711. }
  712. UsrFreeUserInfo(pUI);
  713. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  714. return (0);
  715. }
  716. static int CTRLDo_userdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  717.   char const *const *ppszTokens, int iTokensCount)
  718. {
  719. if (iTokensCount != 3) {
  720. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  721. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  722. return (ERR_BAD_CTRL_COMMAND);
  723. }
  724. if (MDomIsHandledDomain(ppszTokens[1]) < 0) {
  725. ErrorPush();
  726. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  727. return (ErrorPop());
  728. }
  729. if (UsrRemoveUser(ppszTokens[1], ppszTokens[2], 0) < 0) {
  730. ErrorPush();
  731. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  732. return (ErrorPop());
  733. }
  734. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  735. return (0);
  736. }
  737. static int CTRLDo_userpasswd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  738.      char const *const *ppszTokens, int iTokensCount)
  739. {
  740. if (iTokensCount != 4) {
  741. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  742. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  743. return (ERR_BAD_CTRL_COMMAND);
  744. }
  745. if (MDomIsHandledDomain(ppszTokens[1]) < 0) {
  746. ErrorPush();
  747. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  748. return (ErrorPop());
  749. }
  750. ///////////////////////////////////////////////////////////////////////////////
  751. //  Check real user account existence
  752. ///////////////////////////////////////////////////////////////////////////////
  753. UserInfo *pUI = UsrGetUserByName(ppszTokens[1], ppszTokens[2]);
  754. if (pUI == NULL) {
  755. ErrorPush();
  756. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  757. return (ErrorPop());
  758. }
  759. ///////////////////////////////////////////////////////////////////////////////
  760. //  Set account password and do modify
  761. ///////////////////////////////////////////////////////////////////////////////
  762. if (pUI->pszPassword != NULL)
  763. SysFree(pUI->pszPassword);
  764. pUI->pszPassword = SysStrDup(ppszTokens[3]);
  765. if (UsrModifyUser(pUI) < 0) {
  766. ErrorPush();
  767. UsrFreeUserInfo(pUI);
  768. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  769. return (ErrorPop());
  770. }
  771. UsrFreeUserInfo(pUI);
  772. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  773. return (0);
  774. }
  775. static int CTRLDo_aliasadd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  776.    char const *const *ppszTokens, int iTokensCount)
  777. {
  778. if (iTokensCount != 4) {
  779. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  780. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  781. return (ERR_BAD_CTRL_COMMAND);
  782. }
  783. ///////////////////////////////////////////////////////////////////////////////
  784. //  Check real user account existence
  785. ///////////////////////////////////////////////////////////////////////////////
  786. char szAccountName[MAX_ADDR_NAME] = "";
  787. char szAccountDomain[MAX_ADDR_NAME] = "";
  788. if (USmtpSplitEmailAddr(ppszTokens[3], szAccountName, szAccountDomain) < 0) {
  789. StrSNCpy(szAccountName, ppszTokens[3]);
  790. StrSNCpy(szAccountDomain, ppszTokens[1]);
  791. }
  792. UserInfo *pUI = UsrGetUserByName(szAccountDomain, szAccountName);
  793. if (pUI == NULL) {
  794. ErrorPush();
  795. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  796. return (ErrorPop());
  797. }
  798. UsrFreeUserInfo(pUI);
  799. ///////////////////////////////////////////////////////////////////////////////
  800. //  Check if we're overlapping an existing users with the new alias
  801. ///////////////////////////////////////////////////////////////////////////////
  802. if ((pUI = UsrGetUserByName(ppszTokens[1], ppszTokens[2])) != NULL) {
  803. UsrFreeUserInfo(pUI);
  804. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_USER_EXIST);
  805. ErrSetErrorCode(ERR_USER_EXIST);
  806. return (ERR_USER_EXIST);
  807. }
  808. AliasInfo *pAI = UsrAllocAlias(ppszTokens[1], ppszTokens[2], ppszTokens[3]);
  809. if (pAI == NULL) {
  810. ErrorPush();
  811. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  812. return (ErrorPop());
  813. }
  814. if (UsrAddAlias(pAI) < 0) {
  815. ErrorPush();
  816. UsrFreeAlias(pAI);
  817. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  818. return (ErrorPop());
  819. }
  820. UsrFreeAlias(pAI);
  821. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  822. return (0);
  823. }
  824. static int CTRLDo_aliasdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  825.    char const *const *ppszTokens, int iTokensCount)
  826. {
  827. if (iTokensCount != 3) {
  828. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  829. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  830. return (ERR_BAD_CTRL_COMMAND);
  831. }
  832. if (UsrRemoveAlias(ppszTokens[1], ppszTokens[2]) < 0) {
  833. ErrorPush();
  834. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  835. return (ErrorPop());
  836. }
  837. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  838. return (0);
  839. }
  840. static int CTRLDo_aliaslist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  841.     char const *const *ppszTokens, int iTokensCount)
  842. {
  843. if (iTokensCount > 4) {
  844. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  845. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  846. return (ERR_BAD_CTRL_COMMAND);
  847. }
  848. char const *pszDomain = (iTokensCount > 1) ? ppszTokens[1] : NULL;
  849. char const *pszAlias = (iTokensCount > 2) ? ppszTokens[2] : NULL;
  850. char const *pszName = (iTokensCount > 3) ? ppszTokens[3] : NULL;
  851. ALSF_HANDLE hAliasDB = UsrAliasOpenDB();
  852. if (hAliasDB == INVALID_ALSF_HANDLE) {
  853. ErrorPush();
  854. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  855. return (ErrorPop());
  856. }
  857. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  858. AliasInfo *pAI = UsrAliasGetFirst(hAliasDB);
  859. if (pAI != NULL) {
  860. do {
  861. if (((pszDomain == NULL) || StrIWildMatch(pAI->pszDomain, pszDomain)) &&
  862.     ((pszAlias == NULL) || StrIWildMatch(pAI->pszAlias, pszAlias)) &&
  863.     ((pszName == NULL) || StrIWildMatch(pAI->pszName, pszName))) {
  864. char szAliasLine[1024] = "";
  865. sprintf(szAliasLine,
  866. ""%s"t"
  867. ""%s"t"
  868. ""%s"", pAI->pszDomain, pAI->pszAlias, pAI->pszName);
  869. if (BSckSendString(hBSock, szAliasLine, pCTRLCfg->iTimeout) < 0) {
  870. ErrorPush();
  871. UsrFreeAlias(pAI);
  872. UsrAliasCloseDB(hAliasDB);
  873. return (ErrorPop());
  874. }
  875. }
  876. UsrFreeAlias(pAI);
  877. } while ((pAI = UsrAliasGetNext(hAliasDB)) != NULL);
  878. }
  879. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  880. UsrAliasCloseDB(hAliasDB);
  881. return (0);
  882. }
  883. static int CTRLDo_exaliasadd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  884.      char const *const *ppszTokens, int iTokensCount)
  885. {
  886. if (iTokensCount != 3) {
  887. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  888. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  889. return (ERR_BAD_CTRL_COMMAND);
  890. }
  891. ///////////////////////////////////////////////////////////////////////////////
  892. //  Split local and remote accounts addresses
  893. ///////////////////////////////////////////////////////////////////////////////
  894. char szLocName[MAX_ADDR_NAME] = "";
  895. char szLocDomain[MAX_ADDR_NAME] = "";
  896. char szRmtName[MAX_ADDR_NAME] = "";
  897. char szRmtDomain[MAX_ADDR_NAME] = "";
  898. if ((USmtpSplitEmailAddr(ppszTokens[1], szLocName, szLocDomain) < 0) ||
  899.     (USmtpSplitEmailAddr(ppszTokens[2], szRmtName, szRmtDomain) < 0)) {
  900. ErrorPush();
  901. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  902. return (ErrorPop());
  903. }
  904. ///////////////////////////////////////////////////////////////////////////////
  905. //  Build the external alias structure
  906. ///////////////////////////////////////////////////////////////////////////////
  907. ExtAlias *pEA = ExAlAllocAlias();
  908. if (pEA == NULL) {
  909. ErrorPush();
  910. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  911. return (ErrorPop());
  912. }
  913. pEA->pszRmtDomain = SysStrDup(szRmtDomain);
  914. pEA->pszRmtName = SysStrDup(szRmtName);
  915. pEA->pszDomain = SysStrDup(szLocDomain);
  916. pEA->pszName = SysStrDup(szLocName);
  917. if (ExAlAddAlias(pEA) < 0) {
  918. ErrorPush();
  919. ExAlFreeAlias(pEA);
  920. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  921. return (ErrorPop());
  922. }
  923. ExAlFreeAlias(pEA);
  924. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  925. return (0);
  926. }
  927. static int CTRLDo_exaliasdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  928.      char const *const *ppszTokens, int iTokensCount)
  929. {
  930. if (iTokensCount != 2) {
  931. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  932. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  933. return (ERR_BAD_CTRL_COMMAND);
  934. }
  935. ///////////////////////////////////////////////////////////////////////////////
  936. //  Split local and remote accounts addresses
  937. ///////////////////////////////////////////////////////////////////////////////
  938. char szRmtName[MAX_ADDR_NAME] = "";
  939. char szRmtDomain[MAX_ADDR_NAME] = "";
  940. if (USmtpSplitEmailAddr(ppszTokens[1], szRmtName, szRmtDomain) < 0) {
  941. ErrorPush();
  942. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  943. return (ErrorPop());
  944. }
  945. ///////////////////////////////////////////////////////////////////////////////
  946. //  Build the external alias structure
  947. ///////////////////////////////////////////////////////////////////////////////
  948. ExtAlias *pEA = ExAlAllocAlias();
  949. if (pEA == NULL) {
  950. ErrorPush();
  951. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  952. return (ErrorPop());
  953. }
  954. pEA->pszRmtDomain = SysStrDup(szRmtDomain);
  955. pEA->pszRmtName = SysStrDup(szRmtName);
  956. if (ExAlRemoveAlias(pEA) < 0) {
  957. ErrorPush();
  958. ExAlFreeAlias(pEA);
  959. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  960. return (ErrorPop());
  961. }
  962. ExAlFreeAlias(pEA);
  963. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  964. return (0);
  965. }
  966. static int CTRLDo_exaliaslist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  967.       char const *const *ppszTokens, int iTokensCount)
  968. {
  969. if (iTokensCount > 3) {
  970. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  971. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  972. return (ERR_BAD_CTRL_COMMAND);
  973. }
  974. ///////////////////////////////////////////////////////////////////////////////
  975. //  Split local and remote accounts addresses
  976. ///////////////////////////////////////////////////////////////////////////////
  977. char const *pszLocNameMatch = "*";
  978. char const *pszLocDomainMatch = "*";
  979. char const *pszRmtNameMatch = "*";
  980. char const *pszRmtDomainMatch = "*";
  981. char szLocName[MAX_ADDR_NAME] = "";
  982. char szLocDomain[MAX_ADDR_NAME] = "";
  983. char szRmtName[MAX_ADDR_NAME] = "";
  984. char szRmtDomain[MAX_ADDR_NAME] = "";
  985. if (iTokensCount > 1) {
  986. if (USmtpSplitEmailAddr(ppszTokens[1], szLocName, szLocDomain) < 0) {
  987. ErrorPush();
  988. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  989. return (ErrorPop());
  990. }
  991. pszLocNameMatch = szLocName;
  992. pszLocDomainMatch = szLocDomain;
  993. if (iTokensCount > 2) {
  994. if (USmtpSplitEmailAddr(ppszTokens[2], szRmtName, szRmtDomain) < 0) {
  995. ErrorPush();
  996. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  997. return (ErrorPop());
  998. }
  999. pszRmtNameMatch = szRmtName;
  1000. pszRmtDomainMatch = szRmtDomain;
  1001. }
  1002. }
  1003. EXAL_HANDLE hLinksDB = ExAlOpenDB();
  1004. if (hLinksDB == INVALID_EXAL_HANDLE) {
  1005. ErrorPush();
  1006. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1007. return (ErrorPop());
  1008. }
  1009. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1010. ExtAlias *pEA;
  1011. for (pEA = ExAlGetFirstAlias(hLinksDB); pEA != NULL;
  1012.      pEA = ExAlGetNextAlias(hLinksDB)) {
  1013. if (StrIWildMatch(pEA->pszRmtDomain, pszRmtDomainMatch) &&
  1014.     StrIWildMatch(pEA->pszRmtName, pszRmtNameMatch) &&
  1015.     StrIWildMatch(pEA->pszDomain, pszLocDomainMatch) &&
  1016.     StrIWildMatch(pEA->pszName, pszLocNameMatch)) {
  1017. char szAliasLine[1024] = "";
  1018. sprintf(szAliasLine,
  1019. ""%s"t"
  1020. ""%s"t"
  1021. ""%s"t"
  1022. ""%s"", pEA->pszRmtDomain, pEA->pszRmtName,
  1023. pEA->pszDomain, pEA->pszName);
  1024. if (BSckSendString(hBSock, szAliasLine, pCTRLCfg->iTimeout) < 0) {
  1025. ErrorPush();
  1026. ExAlFreeAlias(pEA);
  1027. ExAlCloseDB(hLinksDB);
  1028. return (ErrorPop());
  1029. }
  1030. }
  1031. ExAlFreeAlias(pEA);
  1032. }
  1033. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  1034. ExAlCloseDB(hLinksDB);
  1035. return (0);
  1036. }
  1037. static int CTRLDo_uservars(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1038.    char const *const *ppszTokens, int iTokensCount)
  1039. {
  1040. if (iTokensCount != 3) {
  1041. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1042. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1043. return (ERR_BAD_CTRL_COMMAND);
  1044. }
  1045. char const *pszDomain = ppszTokens[1];
  1046. char const *pszName = ppszTokens[2];
  1047. if (MDomIsHandledDomain(pszDomain) < 0) {
  1048. ErrorPush();
  1049. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1050. return (ErrorPop());
  1051. }
  1052. UserInfo *pUI = UsrGetUserByName(pszDomain, pszName);
  1053. if (pUI == NULL) {
  1054. ErrorPush();
  1055. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1056. return (ErrorPop());
  1057. }
  1058. char **ppszVars = UsrGetProfileVars(pUI);
  1059. if (ppszVars == NULL) {
  1060. ErrorPush();
  1061. UsrFreeUserInfo(pUI);
  1062. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1063. return (ErrorPop());
  1064. }
  1065. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1066. for (int ii = 0; ppszVars[ii] != NULL; ii++) {
  1067. char *pszVar = UsrGetUserInfoVar(pUI, ppszVars[ii]);
  1068. if (pszVar != NULL) {
  1069. if (BSckVSendString(hBSock, pCTRLCfg->iTimeout, ""%s"t"%s"",
  1070.     ppszVars[ii], pszVar) < 0) {
  1071. ErrorPush();
  1072. SysFree(pszVar);
  1073. StrFreeStrings(ppszVars);
  1074. UsrFreeUserInfo(pUI);
  1075. return (ErrorPop());
  1076. }
  1077. SysFree(pszVar);
  1078. }
  1079. }
  1080. StrFreeStrings(ppszVars);
  1081. UsrFreeUserInfo(pUI);
  1082. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  1083. return (0);
  1084. }
  1085. static int CTRLDo_uservarsset(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1086.       char const *const *ppszTokens, int iTokensCount)
  1087. {
  1088. if ((iTokensCount < 5) || (((iTokensCount - 3) % 2) != 0)) {
  1089. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1090. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1091. return (ERR_BAD_CTRL_COMMAND);
  1092. }
  1093. char const *pszDomain = ppszTokens[1];
  1094. char const *pszName = ppszTokens[2];
  1095. if (MDomIsHandledDomain(pszDomain) < 0) {
  1096. ErrorPush();
  1097. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1098. return (ErrorPop());
  1099. }
  1100. UserInfo *pUI = UsrGetUserByName(pszDomain, pszName);
  1101. if (pUI == NULL) {
  1102. ErrorPush();
  1103. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1104. return (ErrorPop());
  1105. }
  1106. for (int ii = 3; ii < (iTokensCount - 1); ii += 2) {
  1107. ///////////////////////////////////////////////////////////////////////////////
  1108. //  Check if the variable deletion is requested
  1109. ///////////////////////////////////////////////////////////////////////////////
  1110. if (strcmp(ppszTokens[ii + 1], CTRL_VAR_DROP_VALUE) == 0)
  1111. UsrDelUserInfoVar(pUI, ppszTokens[ii]);
  1112. else {
  1113. ///////////////////////////////////////////////////////////////////////////////
  1114. //  Set user variable
  1115. ///////////////////////////////////////////////////////////////////////////////
  1116. if (UsrSetUserInfoVar(pUI, ppszTokens[ii], ppszTokens[ii + 1]) < 0) {
  1117. ErrorPush();
  1118. UsrFreeUserInfo(pUI);
  1119. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1120. return (ErrorPop());
  1121. }
  1122. }
  1123. }
  1124. UsrFlushUserVars(pUI);
  1125. UsrFreeUserInfo(pUI);
  1126. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1127. return (0);
  1128. }
  1129. static int CTRLDo_userlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1130.    char const *const *ppszTokens, int iTokensCount)
  1131. {
  1132. if (iTokensCount > 3) {
  1133. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1134. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1135. return (ERR_BAD_CTRL_COMMAND);
  1136. }
  1137. char const *pszDomain = (iTokensCount > 1) ? ppszTokens[1] : NULL;
  1138. char const *pszName = (iTokensCount > 2) ? ppszTokens[2] : NULL;
  1139. USRF_HANDLE hUsersDB = UsrOpenDB();
  1140. if (hUsersDB == INVALID_USRF_HANDLE) {
  1141. ErrorPush();
  1142. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1143. return (ErrorPop());
  1144. }
  1145. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1146. UserInfo *pUI = UsrGetFirstUser(hUsersDB);
  1147. if (pUI != NULL) {
  1148. do {
  1149. if (((pszDomain == NULL) || StrIWildMatch(pUI->pszDomain, pszDomain)) &&
  1150.     ((pszName == NULL) || StrIWildMatch(pUI->pszName, pszName))) {
  1151. char szUserLine[1024] = "";
  1152. sprintf(szUserLine,
  1153. ""%s"t"
  1154. ""%s"t"
  1155. ""%s"t"
  1156. ""%s"",
  1157. pUI->pszDomain, pUI->pszName, pUI->pszPassword,
  1158. pUI->pszType);
  1159. if (BSckSendString(hBSock, szUserLine, pCTRLCfg->iTimeout) < 0) {
  1160. ErrorPush();
  1161. UsrFreeUserInfo(pUI);
  1162. UsrCloseDB(hUsersDB);
  1163. return (ErrorPop());
  1164. }
  1165. }
  1166. UsrFreeUserInfo(pUI);
  1167. } while ((pUI = UsrGetNextUser(hUsersDB)) != NULL);
  1168. }
  1169. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  1170. UsrCloseDB(hUsersDB);
  1171. return (0);
  1172. }
  1173. static int CTRLDo_usergetmproc(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1174.        char const *const *ppszTokens, int iTokensCount)
  1175. {
  1176. if (iTokensCount != 3) {
  1177. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1178. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1179. return (ERR_BAD_CTRL_COMMAND);
  1180. }
  1181. if (MDomIsHandledDomain(ppszTokens[1]) < 0) {
  1182. ErrorPush();
  1183. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1184. return (ErrorPop());
  1185. }
  1186. ///////////////////////////////////////////////////////////////////////////////
  1187. //  Check real user account existence
  1188. ///////////////////////////////////////////////////////////////////////////////
  1189. UserInfo *pUI = UsrGetUserByName(ppszTokens[1], ppszTokens[2]);
  1190. if (pUI == NULL) {
  1191. ErrorPush();
  1192. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1193. return (ErrorPop());
  1194. }
  1195. ///////////////////////////////////////////////////////////////////////////////
  1196. //  Exist user custom message processing ?
  1197. ///////////////////////////////////////////////////////////////////////////////
  1198. char szMPFile[SYS_MAX_PATH] = "";
  1199. SysGetTmpFile(szMPFile);
  1200. if (UsrGetMailProcessFile(pUI, szMPFile) < 0) {
  1201. ErrorPush();
  1202. UsrFreeUserInfo(pUI);
  1203. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1204. return (ErrorPop());
  1205. }
  1206. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1207. ///////////////////////////////////////////////////////////////////////////////
  1208. //  Send mailproc file
  1209. ///////////////////////////////////////////////////////////////////////////////
  1210. if (MscSendTextFile(szMPFile, hBSock, pCTRLCfg->iTimeout) < 0) {
  1211. ErrorPush();
  1212. SysRemove(szMPFile);
  1213. UsrFreeUserInfo(pUI);
  1214. return (ErrorPop());
  1215. }
  1216. SysRemove(szMPFile);
  1217. UsrFreeUserInfo(pUI);
  1218. return (0);
  1219. }
  1220. static int CTRLDo_usersetmproc(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1221.        char const *const *ppszTokens, int iTokensCount)
  1222. {
  1223. if (iTokensCount != 3) {
  1224. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1225. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1226. return (ERR_BAD_CTRL_COMMAND);
  1227. }
  1228. if (MDomIsHandledDomain(ppszTokens[1]) < 0) {
  1229. ErrorPush();
  1230. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1231. return (ErrorPop());
  1232. }
  1233. ///////////////////////////////////////////////////////////////////////////////
  1234. //  Check real user account existence
  1235. ///////////////////////////////////////////////////////////////////////////////
  1236. UserInfo *pUI = UsrGetUserByName(ppszTokens[1], ppszTokens[2]);
  1237. if (pUI == NULL) {
  1238. ErrorPush();
  1239. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1240. return (ErrorPop());
  1241. }
  1242. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_WAITDATA_RESULT);
  1243. ///////////////////////////////////////////////////////////////////////////////
  1244. //  Read user data in file
  1245. ///////////////////////////////////////////////////////////////////////////////
  1246. char szMPFile[SYS_MAX_PATH] = "";
  1247. SysGetTmpFile(szMPFile);
  1248. if (MscRecvTextFile(szMPFile, hBSock, pCTRLCfg->iTimeout) < 0) {
  1249. ErrorPush();
  1250. CheckRemoveFile(szMPFile);
  1251. UsrFreeUserInfo(pUI);
  1252. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1253. return (ErrorPop());
  1254. }
  1255. ///////////////////////////////////////////////////////////////////////////////
  1256. //  Get file info for size checking
  1257. ///////////////////////////////////////////////////////////////////////////////
  1258. SYS_FILE_INFO FI;
  1259. if (SysGetFileInfo(szMPFile, FI) < 0) {
  1260. ErrorPush();
  1261. CheckRemoveFile(szMPFile);
  1262. UsrFreeUserInfo(pUI);
  1263. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1264. return (ErrorPop());
  1265. }
  1266. ///////////////////////////////////////////////////////////////////////////////
  1267. //  Set mailproc file ( or delete it if size == 0 )
  1268. ///////////////////////////////////////////////////////////////////////////////
  1269. if (UsrSetMailProcessFile(pUI, (FI.ulSize != 0) ? szMPFile : NULL) < 0) {
  1270. ErrorPush();
  1271. SysRemove(szMPFile);
  1272. UsrFreeUserInfo(pUI);
  1273. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1274. return (ErrorPop());
  1275. }
  1276. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1277. SysRemove(szMPFile);
  1278. UsrFreeUserInfo(pUI);
  1279. return (0);
  1280. }
  1281. static int CTRLDo_userauth(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1282.    char const *const *ppszTokens, int iTokensCount)
  1283. {
  1284. if (iTokensCount != 4) {
  1285. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1286. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1287. return (ERR_BAD_CTRL_COMMAND);
  1288. }
  1289. ///////////////////////////////////////////////////////////////////////////////
  1290. //  Check real user account existence
  1291. ///////////////////////////////////////////////////////////////////////////////
  1292. UserInfo *pUI = UsrGetUserByName(ppszTokens[1], ppszTokens[2]);
  1293. if (pUI == NULL) {
  1294. ErrorPush();
  1295. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1296. return (ErrorPop());
  1297. }
  1298. ///////////////////////////////////////////////////////////////////////////////
  1299. //  Check password
  1300. ///////////////////////////////////////////////////////////////////////////////
  1301. if (strcmp(pUI->pszPassword, ppszTokens[3]) != 0) {
  1302. UsrFreeUserInfo(pUI);
  1303. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_INVALID_PASSWORD);
  1304. ErrSetErrorCode(ERR_INVALID_PASSWORD);
  1305. return (ERR_INVALID_PASSWORD);
  1306. }
  1307. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1308. UsrFreeUserInfo(pUI);
  1309. return (0);
  1310. }
  1311. static int CTRLDo_userstat(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1312.    char const *const *ppszTokens, int iTokensCount)
  1313. {
  1314. if (iTokensCount != 3) {
  1315. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1316. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1317. return (ERR_BAD_CTRL_COMMAND);
  1318. }
  1319. ///////////////////////////////////////////////////////////////////////////////
  1320. //  Check real user account existence
  1321. ///////////////////////////////////////////////////////////////////////////////
  1322. char szRealAddress[MAX_ADDR_NAME] = "";
  1323. UserInfo *pUI = UsrGetUserByNameOrAlias(ppszTokens[1], ppszTokens[2],
  1324. szRealAddress);
  1325. if (pUI == NULL) {
  1326. ErrorPush();
  1327. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1328. return (ErrorPop());
  1329. }
  1330. ///////////////////////////////////////////////////////////////////////////////
  1331. //  Get mailbox infos
  1332. ///////////////////////////////////////////////////////////////////////////////
  1333. unsigned long ulMBSize = 0;
  1334. unsigned long ulNumMessages = 0;
  1335. if (UPopGetMailboxSize(pUI, ulMBSize, ulNumMessages) < 0) {
  1336. ErrorPush();
  1337. UsrFreeUserInfo(pUI);
  1338. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1339. return (ErrorPop());
  1340. }
  1341. time_t LTime = time(NULL);
  1342. PopLastLoginInfo LoginInfo;
  1343. char szIPAddr[128] = "0.0.0.0";
  1344. char szLoginTime[128] = "";
  1345. if (UPopGetLastLoginInfo(pUI, &LoginInfo) == 0) {
  1346. SysInetNToA(LoginInfo.Address, szIPAddr);
  1347. LTime = LoginInfo.LTime;
  1348. }
  1349. MscGetTimeStr(szLoginTime, sizeof(szLoginTime) - 1, LTime);
  1350. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1351. if ((BSckVSendString(hBSock, pCTRLCfg->iTimeout, ""RealAddress"t"%s"",
  1352.      szRealAddress) < 0) ||
  1353.     (BSckVSendString(hBSock, pCTRLCfg->iTimeout, ""MailboxSize"t"%lu"",
  1354.      ulMBSize) < 0) ||
  1355.     (BSckVSendString(hBSock, pCTRLCfg->iTimeout, ""MailboxMessages"t"%lu"",
  1356.      ulNumMessages) < 0) ||
  1357.     (BSckVSendString(hBSock, pCTRLCfg->iTimeout, ""LastLoginTimeDate"t"%s"",
  1358.      szLoginTime) < 0) ||
  1359.     (BSckVSendString(hBSock, pCTRLCfg->iTimeout, ""LastLoginIP"t"%s"",
  1360.      szIPAddr) < 0)) {
  1361. ErrorPush();
  1362. UsrFreeUserInfo(pUI);
  1363. return (ErrorPop());
  1364. }
  1365. UsrFreeUserInfo(pUI);
  1366. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  1367. return (0);
  1368. }
  1369. static int CTRLDo_mluseradd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1370.     char const *const *ppszTokens, int iTokensCount)
  1371. {
  1372. if (iTokensCount < 4) {
  1373. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1374. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1375. return (ERR_BAD_CTRL_COMMAND);
  1376. }
  1377. if (MDomIsHandledDomain(ppszTokens[1]) < 0) {
  1378. ErrorPush();
  1379. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1380. return (ErrorPop());
  1381. }
  1382. if (USmtpCheckAddress(ppszTokens[3]) < 0) {
  1383. ErrorPush();
  1384. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1385. return (ErrorPop());
  1386. }
  1387. UserInfo *pUI = UsrGetUserByName(ppszTokens[1], ppszTokens[2]);
  1388. if (pUI == NULL) {
  1389. ErrorPush();
  1390. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1391. return (ErrorPop());
  1392. }
  1393. if (UsrGetUserType(pUI) != usrTypeML) {
  1394. UsrFreeUserInfo(pUI);
  1395. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_USER_NOT_MAILINGLIST);
  1396. ErrSetErrorCode(ERR_USER_NOT_MAILINGLIST);
  1397. return (ERR_USER_NOT_MAILINGLIST);
  1398. }
  1399. char const *pszPerms = (iTokensCount > 4) ? ppszTokens[4] : DEFAULT_MLUSER_PERMS;
  1400. MLUserInfo *pMLUI = UsrMLAllocDefault(ppszTokens[3], pszPerms);
  1401. if (pMLUI == NULL) {
  1402. ErrorPush();
  1403. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1404. UsrFreeUserInfo(pUI);
  1405. return (ErrorPop());
  1406. }
  1407. if (UsrMLAddUser(pUI, pMLUI) < 0) {
  1408. ErrorPush();
  1409. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1410. UsrMLFreeUser(pMLUI);
  1411. UsrFreeUserInfo(pUI);
  1412. return (ErrorPop());
  1413. }
  1414. UsrMLFreeUser(pMLUI);
  1415. UsrFreeUserInfo(pUI);
  1416. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1417. return (0);
  1418. }
  1419. static int CTRLDo_mluserdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1420.     char const *const *ppszTokens, int iTokensCount)
  1421. {
  1422. if (iTokensCount != 4) {
  1423. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1424. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1425. return (ERR_BAD_CTRL_COMMAND);
  1426. }
  1427. if (MDomIsHandledDomain(ppszTokens[1]) < 0) {
  1428. ErrorPush();
  1429. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1430. return (ErrorPop());
  1431. }
  1432. UserInfo *pUI = UsrGetUserByName(ppszTokens[1], ppszTokens[2]);
  1433. if (pUI == NULL) {
  1434. ErrorPush();
  1435. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1436. return (ErrorPop());
  1437. }
  1438. if (UsrGetUserType(pUI) != usrTypeML) {
  1439. UsrFreeUserInfo(pUI);
  1440. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_USER_NOT_MAILINGLIST);
  1441. ErrSetErrorCode(ERR_USER_NOT_MAILINGLIST);
  1442. return (ERR_USER_NOT_MAILINGLIST);
  1443. }
  1444. if (UsrMLRemoveUser(pUI, ppszTokens[3]) < 0) {
  1445. ErrorPush();
  1446. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1447. UsrFreeUserInfo(pUI);
  1448. return (ErrorPop());
  1449. }
  1450. UsrFreeUserInfo(pUI);
  1451. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1452. return (0);
  1453. }
  1454. static int CTRLDo_mluserlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1455.      char const *const *ppszTokens, int iTokensCount)
  1456. {
  1457. if (iTokensCount != 3) {
  1458. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1459. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1460. return (ERR_BAD_CTRL_COMMAND);
  1461. }
  1462. if (MDomIsHandledDomain(ppszTokens[1]) < 0) {
  1463. ErrorPush();
  1464. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1465. return (ErrorPop());
  1466. }
  1467. UserInfo *pUI = UsrGetUserByName(ppszTokens[1], ppszTokens[2]);
  1468. if (pUI == NULL) {
  1469. ErrorPush();
  1470. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1471. return (ErrorPop());
  1472. }
  1473. if (UsrGetUserType(pUI) != usrTypeML) {
  1474. UsrFreeUserInfo(pUI);
  1475. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_USER_NOT_MAILINGLIST);
  1476. ErrSetErrorCode(ERR_USER_NOT_MAILINGLIST);
  1477. return (ERR_USER_NOT_MAILINGLIST);
  1478. }
  1479. USRML_HANDLE hUsersDB = UsrMLOpenDB(pUI);
  1480. if (hUsersDB == INVALID_USRML_HANDLE) {
  1481. ErrorPush();
  1482. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1483. UsrFreeUserInfo(pUI);
  1484. return (ErrorPop());
  1485. }
  1486. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1487. ///////////////////////////////////////////////////////////////////////////////
  1488. //  Mailing list scan
  1489. ///////////////////////////////////////////////////////////////////////////////
  1490. MLUserInfo *pMLUI = UsrMLGetFirstUser(hUsersDB);
  1491. for (; pMLUI != NULL; pMLUI = UsrMLGetNextUser(hUsersDB)) {
  1492. char szUserLine[512] = "";
  1493. sprintf(szUserLine, ""%s"t"%s"", pMLUI->pszAddress, pMLUI->pszPerms);
  1494. if (BSckSendString(hBSock, szUserLine, pCTRLCfg->iTimeout) < 0) {
  1495. ErrorPush();
  1496. UsrMLFreeUser(pMLUI);
  1497. UsrFreeUserInfo(pUI);
  1498. UsrMLCloseDB(hUsersDB);
  1499. return (ErrorPop());
  1500. }
  1501. UsrMLFreeUser(pMLUI);
  1502. }
  1503. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  1504. UsrFreeUserInfo(pUI);
  1505. UsrMLCloseDB(hUsersDB);
  1506. return (0);
  1507. }
  1508. static int CTRLDo_domainadd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1509.     char const *const *ppszTokens, int iTokensCount)
  1510. {
  1511. if (iTokensCount != 2) {
  1512. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1513. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1514. return (ERR_BAD_CTRL_COMMAND);
  1515. }
  1516. if (USmtpCheckAddressPart(ppszTokens[1]) < 0) {
  1517. ErrorPush();
  1518. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1519. return (ErrorPop());
  1520. }
  1521. char szDomain[MAX_HOST_NAME] = "";
  1522. StrSNCpy(szDomain, ppszTokens[1]);
  1523. StrLower(szDomain);
  1524. if (MDomAddDomain(szDomain) < 0) {
  1525. ErrorPush();
  1526. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1527. return (ErrorPop());
  1528. }
  1529. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1530. return (0);
  1531. }
  1532. static int CTRLDo_domaindel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1533.     char const *const *ppszTokens, int iTokensCount)
  1534. {
  1535. if (iTokensCount != 2) {
  1536. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1537. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1538. return (ERR_BAD_CTRL_COMMAND);
  1539. }
  1540. char szDomain[MAX_HOST_NAME] = "";
  1541. StrSNCpy(szDomain, ppszTokens[1]);
  1542. StrLower(szDomain);
  1543. if (MDomRemoveDomain(szDomain) < 0) {
  1544. ErrorPush();
  1545. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1546. return (ErrorPop());
  1547. }
  1548. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1549. return (0);
  1550. }
  1551. static int CTRLDo_domainlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1552.      char const *const *ppszTokens, int iTokensCount)
  1553. {
  1554. DOMLS_HANDLE hDomainsDB = MDomOpenDB();
  1555. if (hDomainsDB == INVALID_DOMLS_HANDLE) {
  1556. ErrorPush();
  1557. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1558. return (ErrorPop());
  1559. }
  1560. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1561. char const *pszDomain = MDomGetFirstDomain(hDomainsDB);
  1562. if (pszDomain != NULL) {
  1563. do {
  1564. if ((iTokensCount < 2) || StrStringsRIWMatch(&ppszTokens[1], pszDomain)) {
  1565. char szDomainLine[512] = "";
  1566. sprintf(szDomainLine, ""%s"", pszDomain);
  1567. if (BSckSendString(hBSock, szDomainLine, pCTRLCfg->iTimeout) < 0) {
  1568. ErrorPush();
  1569. MDomCloseDB(hDomainsDB);
  1570. return (ErrorPop());
  1571. }
  1572. }
  1573. } while ((pszDomain = MDomGetNextDomain(hDomainsDB)) != NULL);
  1574. }
  1575. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  1576. MDomCloseDB(hDomainsDB);
  1577. return (0);
  1578. }
  1579. static int CTRLDo_custdomget(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1580.      char const *const *ppszTokens, int iTokensCount)
  1581. {
  1582. if (iTokensCount != 2) {
  1583. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1584. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1585. return (ERR_BAD_CTRL_COMMAND);
  1586. }
  1587. ///////////////////////////////////////////////////////////////////////////////
  1588. //  Try to get custom domain file ( if exist )
  1589. ///////////////////////////////////////////////////////////////////////////////
  1590. char szCustDomainFile[SYS_MAX_PATH] = "";
  1591. SysGetTmpFile(szCustDomainFile);
  1592. if (USmlGetCustomDomainFile(ppszTokens[1], szCustDomainFile) < 0) {
  1593. ErrorPush();
  1594. CheckRemoveFile(szCustDomainFile);
  1595. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1596. return (ErrorPop());
  1597. }
  1598. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1599. ///////////////////////////////////////////////////////////////////////////////
  1600. //  Send custom domain file
  1601. ///////////////////////////////////////////////////////////////////////////////
  1602. if (MscSendTextFile(szCustDomainFile, hBSock, pCTRLCfg->iTimeout) < 0) {
  1603. ErrorPush();
  1604. SysRemove(szCustDomainFile);
  1605. return (ErrorPop());
  1606. }
  1607. SysRemove(szCustDomainFile);
  1608. return (0);
  1609. }
  1610. static int CTRLDo_custdomset(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1611.      char const *const *ppszTokens, int iTokensCount)
  1612. {
  1613. if (iTokensCount != 2) {
  1614. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1615. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1616. return (ERR_BAD_CTRL_COMMAND);
  1617. }
  1618. if (USmtpCheckAddressPart(ppszTokens[1]) < 0) {
  1619. ErrorPush();
  1620. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1621. return (ErrorPop());
  1622. }
  1623. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_WAITDATA_RESULT);
  1624. ///////////////////////////////////////////////////////////////////////////////
  1625. //  Read user data in file
  1626. ///////////////////////////////////////////////////////////////////////////////
  1627. char szCustDomainFile[SYS_MAX_PATH] = "";
  1628. SysGetTmpFile(szCustDomainFile);
  1629. if (MscRecvTextFile(szCustDomainFile, hBSock, pCTRLCfg->iTimeout) < 0) {
  1630. ErrorPush();
  1631. CheckRemoveFile(szCustDomainFile);
  1632. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1633. return (ErrorPop());
  1634. }
  1635. ///////////////////////////////////////////////////////////////////////////////
  1636. //  Get file info for size checking
  1637. ///////////////////////////////////////////////////////////////////////////////
  1638. SYS_FILE_INFO FI;
  1639. if (SysGetFileInfo(szCustDomainFile, FI) < 0) {
  1640. ErrorPush();
  1641. CheckRemoveFile(szCustDomainFile);
  1642. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1643. return (ErrorPop());
  1644. }
  1645. ///////////////////////////////////////////////////////////////////////////////
  1646. //  Set custom domain file ( or delete it if size == 0 )
  1647. ///////////////////////////////////////////////////////////////////////////////
  1648. if (USmlSetCustomDomainFile(ppszTokens[1],
  1649.     (FI.ulSize != 0) ? szCustDomainFile : NULL) < 0) {
  1650. ErrorPush();
  1651. SysRemove(szCustDomainFile);
  1652. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1653. return (ErrorPop());
  1654. }
  1655. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1656. SysRemove(szCustDomainFile);
  1657. return (0);
  1658. }
  1659. static int CTRLDo_custdomlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1660.       char const *const *ppszTokens, int iTokensCount)
  1661. {
  1662. if (iTokensCount != 1) {
  1663. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1664. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1665. return (ERR_BAD_CTRL_COMMAND);
  1666. }
  1667. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1668. char szCustomPath[SYS_MAX_PATH] = "";
  1669. USmlGetDomainCustomDir(szCustomPath, sizeof(szCustomPath), 0);
  1670. char szCustFileName[SYS_MAX_PATH] = "";
  1671. FSCAN_HANDLE hFileScan = MscFirstFile(szCustomPath, 0, szCustFileName);
  1672. if (hFileScan != INVALID_FSCAN_HANDLE) {
  1673. do {
  1674. char szCustDomain[SYS_MAX_PATH] = "";
  1675. MscSplitPath(szCustFileName, NULL, szCustDomain, NULL);
  1676. if (BSckVSendString(hBSock, pCTRLCfg->iTimeout, ""%s"", szCustDomain) <
  1677.     0) {
  1678. ErrorPush();
  1679. MscCloseFindFile(hFileScan);
  1680. return (ErrorPop());
  1681. }
  1682. } while (MscNextFile(hFileScan, szCustFileName));
  1683. MscCloseFindFile(hFileScan);
  1684. }
  1685. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  1686. return (0);
  1687. }
  1688. static int CTRLDo_noop(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1689.        char const *const *ppszTokens, int iTokensCount)
  1690. {
  1691. if (iTokensCount != 1) {
  1692. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1693. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1694. return (ERR_BAD_CTRL_COMMAND);
  1695. }
  1696. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1697. return (0);
  1698. }
  1699. static int CTRLDo_quit(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1700.        char const *const *ppszTokens, int iTokensCount)
  1701. {
  1702. if (iTokensCount != 1) {
  1703. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1704. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1705. return (ERR_BAD_CTRL_COMMAND);
  1706. }
  1707. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1708. return (CTRL_QUIT_CMD_EXIT);
  1709. }
  1710. static int CTRLDo_poplnkadd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1711.     char const *const *ppszTokens, int iTokensCount)
  1712. {
  1713. if (iTokensCount != 7) {
  1714. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1715. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1716. return (ERR_BAD_CTRL_COMMAND);
  1717. }
  1718. if (MDomIsHandledDomain(ppszTokens[1]) < 0) {
  1719. ErrorPush();
  1720. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1721. return (ErrorPop());
  1722. }
  1723. UserInfo *pUI = UsrGetUserByName(ppszTokens[1], ppszTokens[2]);
  1724. if (pUI == NULL) {
  1725. ErrorPush();
  1726. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1727. return (ErrorPop());
  1728. }
  1729. UsrFreeUserInfo(pUI);
  1730. POP3Link *pPopLnk = GwLkAllocLink(ppszTokens[1], ppszTokens[2],
  1731.   ppszTokens[3], ppszTokens[4], ppszTokens[5],
  1732.   ppszTokens[6]);
  1733. if (pPopLnk == NULL) {
  1734. ErrorPush();
  1735. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1736. return (ErrorPop());
  1737. }
  1738. if (GwLkAddLink(pPopLnk) < 0) {
  1739. ErrorPush();
  1740. GwLkFreePOP3Link(pPopLnk);
  1741. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1742. return (ErrorPop());
  1743. }
  1744. GwLkFreePOP3Link(pPopLnk);
  1745. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1746. return (0);
  1747. }
  1748. static int CTRLDo_poplnkdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1749.     char const *const *ppszTokens, int iTokensCount)
  1750. {
  1751. if (iTokensCount != 5) {
  1752. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1753. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1754. return (ERR_BAD_CTRL_COMMAND);
  1755. }
  1756. if (MDomIsHandledDomain(ppszTokens[1]) < 0) {
  1757. ErrorPush();
  1758. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1759. return (ErrorPop());
  1760. }
  1761. UserInfo *pUI = UsrGetUserByName(ppszTokens[1], ppszTokens[2]);
  1762. if (pUI == NULL) {
  1763. ErrorPush();
  1764. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1765. return (ErrorPop());
  1766. }
  1767. UsrFreeUserInfo(pUI);
  1768. POP3Link *pPopLnk = GwLkAllocLink(ppszTokens[1], ppszTokens[2],
  1769.   ppszTokens[3], ppszTokens[4], NULL, NULL);
  1770. if (pPopLnk == NULL) {
  1771. ErrorPush();
  1772. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1773. return (ErrorPop());
  1774. }
  1775. if (GwLkRemoveLink(pPopLnk) < 0) {
  1776. ErrorPush();
  1777. GwLkFreePOP3Link(pPopLnk);
  1778. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1779. return (ErrorPop());
  1780. }
  1781. GwLkFreePOP3Link(pPopLnk);
  1782. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1783. return (0);
  1784. }
  1785. static int CTRLDo_poplnklist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1786.      char const *const *ppszTokens, int iTokensCount)
  1787. {
  1788. if (iTokensCount > 3) {
  1789. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1790. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1791. return (ERR_BAD_CTRL_COMMAND);
  1792. }
  1793. char const *pszDomain = (iTokensCount > 1) ? ppszTokens[1] : NULL;
  1794. char const *pszName = (iTokensCount > 2) ? ppszTokens[2] : NULL;
  1795. GWLKF_HANDLE hLinksDB = GwLkOpenDB();
  1796. if (hLinksDB == INVALID_GWLKF_HANDLE) {
  1797. ErrorPush();
  1798. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1799. return (ErrorPop());
  1800. }
  1801. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1802. POP3Link *pPopLnk = GwLkGetFirstUser(hLinksDB);
  1803. if (pPopLnk != NULL) {
  1804. do {
  1805. if (((pszDomain == NULL) || (stricmp(pPopLnk->pszDomain, pszDomain) == 0))
  1806.     && ((pszName == NULL) || (stricmp(pPopLnk->pszName, pszName) == 0))) {
  1807. char const *pszEnable =
  1808.     (GwLkCheckEnabled(pPopLnk) == 0) ? "ON" : "OFF";
  1809. char szLinkLine[2048] = "";
  1810. sprintf(szLinkLine,
  1811. ""%s"t"
  1812. ""%s"t"
  1813. ""%s"t"
  1814. ""%s"t"
  1815. ""%s"t"
  1816. ""%s"t"
  1817. ""%s"",
  1818. pPopLnk->pszDomain, pPopLnk->pszName,
  1819. pPopLnk->pszRmtDomain, pPopLnk->pszRmtName,
  1820. pPopLnk->pszRmtPassword, pPopLnk->pszAuthType, pszEnable);
  1821. if (BSckSendString(hBSock, szLinkLine, pCTRLCfg->iTimeout) < 0) {
  1822. ErrorPush();
  1823. GwLkFreePOP3Link(pPopLnk);
  1824. GwLkCloseDB(hLinksDB);
  1825. return (ErrorPop());
  1826. }
  1827. }
  1828. GwLkFreePOP3Link(pPopLnk);
  1829. } while ((pPopLnk = GwLkGetNextUser(hLinksDB)) != NULL);
  1830. }
  1831. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  1832. GwLkCloseDB(hLinksDB);
  1833. return (0);
  1834. }
  1835. static int CTRLDo_poplnkenable(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1836.        char const *const *ppszTokens, int iTokensCount)
  1837. {
  1838. if (iTokensCount < 4) {
  1839. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1840. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1841. return (ERR_BAD_CTRL_COMMAND);
  1842. }
  1843. bool bEnable = (atoi(ppszTokens[1])) ? true : false;
  1844. char const *pszDomain = ppszTokens[2];
  1845. char const *pszName = ppszTokens[3];
  1846. char const *pszRmtDomain = (iTokensCount > 4) ? ppszTokens[4] : NULL;
  1847. char const *pszRmtName = (iTokensCount > 5) ? ppszTokens[5] : NULL;
  1848. if (GwLkEnable(pszDomain, pszName, pszRmtDomain, pszRmtName, bEnable) < 0) {
  1849. ErrorPush();
  1850. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1851. return (ErrorPop());
  1852. }
  1853. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  1854. return (0);
  1855. }
  1856. static int CTRLCheckRelativePath(char const *pszPath)
  1857. {
  1858. ///////////////////////////////////////////////////////////////////////////////
  1859. //  Check 101 tricky path
  1860. ///////////////////////////////////////////////////////////////////////////////
  1861. if (strstr(pszPath, "..") != NULL) {
  1862. ErrSetErrorCode(ERR_BAD_RELATIVE_PATH);
  1863. return (ERR_BAD_RELATIVE_PATH);
  1864. }
  1865. return (0);
  1866. }
  1867. static int CTRLDo_filelist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1868.    char const *const *ppszTokens, int iTokensCount)
  1869. {
  1870. if (iTokensCount != 3) {
  1871. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1872. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1873. return (ERR_BAD_CTRL_COMMAND);
  1874. }
  1875. ///////////////////////////////////////////////////////////////////////////////
  1876. //  Check relative path syntax
  1877. ///////////////////////////////////////////////////////////////////////////////
  1878. if (CTRLCheckRelativePath(ppszTokens[1]) < 0) {
  1879. ErrorPush();
  1880. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1881. return (ErrorPop());
  1882. }
  1883. ///////////////////////////////////////////////////////////////////////////////
  1884. //  Setup listing file path
  1885. ///////////////////////////////////////////////////////////////////////////////
  1886. char szRelativePath[SYS_MAX_PATH] = "";
  1887. char szFullPath[SYS_MAX_PATH] = "";
  1888. StrSNCpy(szRelativePath, ppszTokens[1]);
  1889. MscTranslatePath(szRelativePath);
  1890. CfgGetFullPath(szRelativePath, szFullPath, sizeof(szFullPath));
  1891. DelFinalSlash(szFullPath);
  1892. ///////////////////////////////////////////////////////////////////////////////
  1893. //  Check directory existance
  1894. ///////////////////////////////////////////////////////////////////////////////
  1895. if (!SysExistDir(szFullPath)) {
  1896. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_LISTDIR_NOT_FOUND);
  1897. ErrSetErrorCode(ERR_LISTDIR_NOT_FOUND);
  1898. return (ERR_LISTDIR_NOT_FOUND);
  1899. }
  1900. ///////////////////////////////////////////////////////////////////////////////
  1901. //  Send command continue response
  1902. ///////////////////////////////////////////////////////////////////////////////
  1903. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1904. ///////////////////////////////////////////////////////////////////////////////
  1905. //  List files
  1906. ///////////////////////////////////////////////////////////////////////////////
  1907. char szFileName[SYS_MAX_PATH] = "";
  1908. FSCAN_HANDLE hFileScan = MscFirstFile(szFullPath, 0, szFileName);
  1909. if (hFileScan != INVALID_FSCAN_HANDLE) {
  1910. do {
  1911. if (!SYS_IS_VALID_FILENAME(szFileName) ||
  1912.     !StrWildMatch(szFileName, ppszTokens[2]))
  1913. continue;
  1914. SYS_FILE_INFO FI;
  1915. char szFilePath[SYS_MAX_PATH] = "";
  1916. SysSNPrintf(szFilePath, sizeof(szFilePath) - 1, "%s%s%s",
  1917.     szFullPath, SYS_SLASH_STR, szFileName);
  1918. if (SysGetFileInfo(szFilePath, FI) == 0) {
  1919. if (BSckVSendString(hBSock, pCTRLCfg->iTimeout, ""%s"t"%lu"",
  1920.     szFileName, FI.ulSize) < 0) {
  1921. ErrorPush();
  1922. MscCloseFindFile(hFileScan);
  1923. return (ErrorPop());
  1924. }
  1925. }
  1926. } while (MscNextFile(hFileScan, szFileName));
  1927. MscCloseFindFile(hFileScan);
  1928. }
  1929. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  1930. return (0);
  1931. }
  1932. static int CTRLDo_cfgfileget(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1933.      char const *const *ppszTokens, int iTokensCount)
  1934. {
  1935. if (iTokensCount != 2) {
  1936. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1937. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1938. return (ERR_BAD_CTRL_COMMAND);
  1939. }
  1940. ///////////////////////////////////////////////////////////////////////////////
  1941. //  Check relative path syntax
  1942. ///////////////////////////////////////////////////////////////////////////////
  1943. if (CTRLCheckRelativePath(ppszTokens[1]) < 0) {
  1944. ErrorPush();
  1945. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  1946. return (ErrorPop());
  1947. }
  1948. ///////////////////////////////////////////////////////////////////////////////
  1949. //  Setup client target file path
  1950. ///////////////////////////////////////////////////////////////////////////////
  1951. char szRelativePath[SYS_MAX_PATH] = "";
  1952. char szFullPath[SYS_MAX_PATH] = "";
  1953. StrSNCpy(szRelativePath, ppszTokens[1]);
  1954. MscTranslatePath(szRelativePath);
  1955. CfgGetFullPath(szRelativePath, szFullPath, sizeof(szFullPath));
  1956. DelFinalSlash(szFullPath);
  1957. ///////////////////////////////////////////////////////////////////////////////
  1958. //  Share lock client target file
  1959. ///////////////////////////////////////////////////////////////////////////////
  1960. char szResLock[SYS_MAX_PATH] = "";
  1961. RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szFullPath, szResLock,
  1962.   sizeof(szResLock)));
  1963. if (hResLock == INVALID_RLCK_HANDLE) {
  1964. ErrorPush();
  1965. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1966. return (ErrorPop());
  1967. }
  1968. ///////////////////////////////////////////////////////////////////////////////
  1969. //  Get a file snapshot
  1970. ///////////////////////////////////////////////////////////////////////////////
  1971. char szRequestedFile[SYS_MAX_PATH] = "";
  1972. SysGetTmpFile(szRequestedFile);
  1973. if (MscCopyFile(szRequestedFile, szFullPath) < 0) {
  1974. ErrorPush();
  1975. CheckRemoveFile(szRequestedFile);
  1976. RLckUnlockSH(hResLock);
  1977. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  1978. return (ErrorPop());
  1979. }
  1980. RLckUnlockSH(hResLock);
  1981. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  1982. ///////////////////////////////////////////////////////////////////////////////
  1983. //  Send client target file
  1984. ///////////////////////////////////////////////////////////////////////////////
  1985. if (MscSendTextFile(szRequestedFile, hBSock, pCTRLCfg->iTimeout) < 0) {
  1986. ErrorPush();
  1987. SysRemove(szRequestedFile);
  1988. return (ErrorPop());
  1989. }
  1990. SysRemove(szRequestedFile);
  1991. return (0);
  1992. }
  1993. static int CTRLDo_cfgfileset(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  1994.      char const *const *ppszTokens, int iTokensCount)
  1995. {
  1996. if (iTokensCount != 2) {
  1997. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  1998. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  1999. return (ERR_BAD_CTRL_COMMAND);
  2000. }
  2001. ///////////////////////////////////////////////////////////////////////////////
  2002. //  Check relative path syntax
  2003. ///////////////////////////////////////////////////////////////////////////////
  2004. if (CTRLCheckRelativePath(ppszTokens[1]) < 0) {
  2005. ErrorPush();
  2006. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  2007. return (ErrorPop());
  2008. }
  2009. ///////////////////////////////////////////////////////////////////////////////
  2010. //  Setup client target file path
  2011. ///////////////////////////////////////////////////////////////////////////////
  2012. char szRelativePath[SYS_MAX_PATH] = "";
  2013. char szFullPath[SYS_MAX_PATH] = "";
  2014. StrSNCpy(szRelativePath, ppszTokens[1]);
  2015. MscTranslatePath(szRelativePath);
  2016. CfgGetFullPath(szRelativePath, szFullPath, sizeof(szFullPath));
  2017. DelFinalSlash(szFullPath);
  2018. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_WAITDATA_RESULT);
  2019. ///////////////////////////////////////////////////////////////////////////////
  2020. //  Read user data in file
  2021. ///////////////////////////////////////////////////////////////////////////////
  2022. char szClientFile[SYS_MAX_PATH] = "";
  2023. SysGetTmpFile(szClientFile);
  2024. if (MscRecvTextFile(szClientFile, hBSock, pCTRLCfg->iTimeout) < 0) {
  2025. ErrorPush();
  2026. CheckRemoveFile(szClientFile);
  2027. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2028. return (ErrorPop());
  2029. }
  2030. ///////////////////////////////////////////////////////////////////////////////
  2031. //  Get file info for size checking
  2032. ///////////////////////////////////////////////////////////////////////////////
  2033. SYS_FILE_INFO FI;
  2034. if (SysGetFileInfo(szClientFile, FI) < 0) {
  2035. ErrorPush();
  2036. CheckRemoveFile(szClientFile);
  2037. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2038. return (ErrorPop());
  2039. }
  2040. ///////////////////////////////////////////////////////////////////////////////
  2041. //  Exclusive lock client target file
  2042. ///////////////////////////////////////////////////////////////////////////////
  2043. char szResLock[SYS_MAX_PATH] = "";
  2044. RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szFullPath, szResLock,
  2045.   sizeof(szResLock)));
  2046. if (hResLock == INVALID_RLCK_HANDLE) {
  2047. ErrorPush();
  2048. SysRemove(szClientFile);
  2049. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2050. return (ErrorPop());
  2051. }
  2052. if (FI.ulSize != 0) {
  2053. if (MscCopyFile(szFullPath, szClientFile) < 0) {
  2054. ErrorPush();
  2055. RLckUnlockEX(hResLock);
  2056. SysRemove(szClientFile);
  2057. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2058. return (ErrorPop());
  2059. }
  2060. } else
  2061. SysRemove(szFullPath);
  2062. RLckUnlockEX(hResLock);
  2063. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  2064. SysRemove(szClientFile);
  2065. return (0);
  2066. }
  2067. static int CTRLDo_frozlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  2068.    char const *const *ppszTokens, int iTokensCount)
  2069. {
  2070. if (iTokensCount < 1) {
  2071. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  2072. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  2073. return (ERR_BAD_CTRL_COMMAND);
  2074. }
  2075. ///////////////////////////////////////////////////////////////////////////////
  2076. //  Build frozen list file
  2077. ///////////////////////////////////////////////////////////////////////////////
  2078. char szListFile[SYS_MAX_PATH] = "";
  2079. SysGetTmpFile(szListFile);
  2080. if (QueUtGetFrozenList(hSpoolQueue, szListFile) < 0) {
  2081. ErrorPush();
  2082. CheckRemoveFile(szListFile);
  2083. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2084. return (ErrorPop());
  2085. }
  2086. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  2087. ///////////////////////////////////////////////////////////////////////////////
  2088. //  Send client target file
  2089. ///////////////////////////////////////////////////////////////////////////////
  2090. if (MscSendTextFile(szListFile, hBSock, pCTRLCfg->iTimeout) < 0) {
  2091. ErrorPush();
  2092. SysRemove(szListFile);
  2093. return (ErrorPop());
  2094. }
  2095. SysRemove(szListFile);
  2096. return (0);
  2097. }
  2098. static int CTRLDo_frozsubmit(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  2099.      char const *const *ppszTokens, int iTokensCount)
  2100. {
  2101. if (iTokensCount < 4) {
  2102. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  2103. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  2104. return (ERR_BAD_CTRL_COMMAND);
  2105. }
  2106. ///////////////////////////////////////////////////////////////////////////////
  2107. //  Try to defroze frozen message
  2108. ///////////////////////////////////////////////////////////////////////////////
  2109. int iLevel1 = atoi(ppszTokens[1]);
  2110. int iLevel2 = atoi(ppszTokens[2]);
  2111. char szMessageFile[SYS_MAX_PATH] = "";
  2112. StrSNCpy(szMessageFile, ppszTokens[3]);
  2113. if (QueUtUnFreezeMessage(hSpoolQueue, iLevel1, iLevel2, szMessageFile) < 0) {
  2114. ErrorPush();
  2115. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2116. return (ErrorPop());
  2117. }
  2118. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  2119. return (0);
  2120. }
  2121. static int CTRLDo_frozdel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  2122.   char const *const *ppszTokens, int iTokensCount)
  2123. {
  2124. if (iTokensCount < 4) {
  2125. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  2126. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  2127. return (ERR_BAD_CTRL_COMMAND);
  2128. }
  2129. ///////////////////////////////////////////////////////////////////////////////
  2130. //  Try to delete frozen message
  2131. ///////////////////////////////////////////////////////////////////////////////
  2132. int iLevel1 = atoi(ppszTokens[1]);
  2133. int iLevel2 = atoi(ppszTokens[2]);
  2134. char szMessageFile[SYS_MAX_PATH] = "";
  2135. StrSNCpy(szMessageFile, ppszTokens[3]);
  2136. if (QueUtDeleteFrozenMessage(hSpoolQueue, iLevel1, iLevel2, szMessageFile) < 0) {
  2137. ErrorPush();
  2138. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2139. return (ErrorPop());
  2140. }
  2141. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  2142. return (0);
  2143. }
  2144. static int CTRLDo_frozgetlog(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  2145.      char const *const *ppszTokens, int iTokensCount)
  2146. {
  2147. if (iTokensCount < 4) {
  2148. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  2149. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  2150. return (ERR_BAD_CTRL_COMMAND);
  2151. }
  2152. ///////////////////////////////////////////////////////////////////////////////
  2153. //  Try to delete frozen message
  2154. ///////////////////////////////////////////////////////////////////////////////
  2155. int iLevel1 = atoi(ppszTokens[1]);
  2156. int iLevel2 = atoi(ppszTokens[2]);
  2157. char szMessageFile[SYS_MAX_PATH] = "";
  2158. StrSNCpy(szMessageFile, ppszTokens[3]);
  2159. ///////////////////////////////////////////////////////////////////////////////
  2160. //  Get log file snapshot
  2161. ///////////////////////////////////////////////////////////////////////////////
  2162. char szFileSS[SYS_MAX_PATH] = "";
  2163. SysGetTmpFile(szFileSS);
  2164. if (QueUtGetFrozenLogFile(hSpoolQueue, iLevel1, iLevel2, szMessageFile, szFileSS) < 0) {
  2165. ErrorPush();
  2166. CheckRemoveFile(szFileSS);
  2167. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2168. return (ErrorPop());
  2169. }
  2170. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  2171. ///////////////////////////////////////////////////////////////////////////////
  2172. //  Send client target file
  2173. ///////////////////////////////////////////////////////////////////////////////
  2174. if (MscSendTextFile(szFileSS, hBSock, pCTRLCfg->iTimeout) < 0) {
  2175. ErrorPush();
  2176. SysRemove(szFileSS);
  2177. return (ErrorPop());
  2178. }
  2179. SysRemove(szFileSS);
  2180. return (0);
  2181. }
  2182. static int CTRLDo_frozgetmsg(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  2183.      char const *const *ppszTokens, int iTokensCount)
  2184. {
  2185. if (iTokensCount < 4) {
  2186. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  2187. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  2188. return (ERR_BAD_CTRL_COMMAND);
  2189. }
  2190. ///////////////////////////////////////////////////////////////////////////////
  2191. //  Try to delete frozen message
  2192. ///////////////////////////////////////////////////////////////////////////////
  2193. int iLevel1 = atoi(ppszTokens[1]);
  2194. int iLevel2 = atoi(ppszTokens[2]);
  2195. char szMessageFile[SYS_MAX_PATH] = "";
  2196. StrSNCpy(szMessageFile, ppszTokens[3]);
  2197. ///////////////////////////////////////////////////////////////////////////////
  2198. //  Get log file snapshot
  2199. ///////////////////////////////////////////////////////////////////////////////
  2200. char szFileSS[SYS_MAX_PATH] = "";
  2201. SysGetTmpFile(szFileSS);
  2202. if (QueUtGetFrozenMsgFile(hSpoolQueue, iLevel1, iLevel2, szMessageFile, szFileSS) < 0) {
  2203. ErrorPush();
  2204. CheckRemoveFile(szFileSS);
  2205. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2206. return (ErrorPop());
  2207. }
  2208. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  2209. ///////////////////////////////////////////////////////////////////////////////
  2210. //  Send client target file
  2211. ///////////////////////////////////////////////////////////////////////////////
  2212. if (MscSendTextFile(szFileSS, hBSock, pCTRLCfg->iTimeout) < 0) {
  2213. ErrorPush();
  2214. SysRemove(szFileSS);
  2215. return (ErrorPop());
  2216. }
  2217. SysRemove(szFileSS);
  2218. return (0);
  2219. }
  2220. static int CTRLDo_etrn(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  2221.        char const *const *ppszTokens, int iTokensCount)
  2222. {
  2223. if (iTokensCount < 2) {
  2224. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  2225. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  2226. return (ERR_BAD_CTRL_COMMAND);
  2227. }
  2228. ///////////////////////////////////////////////////////////////////////////////
  2229. //  Do a matched flush of the rsnd arena
  2230. ///////////////////////////////////////////////////////////////////////////////
  2231. for (int ii = 1; ii < iTokensCount; ii++) {
  2232. if (QueFlushRsndArena(hSpoolQueue, ppszTokens[ii]) < 0) {
  2233. ErrorPush();
  2234. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2235. return (ErrorPop());
  2236. }
  2237. }
  2238. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  2239. return (0);
  2240. }
  2241. static int CTRLDo_aliasdomainadd(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  2242.  char const *const *ppszTokens, int iTokensCount)
  2243. {
  2244. if (iTokensCount != 3) {
  2245. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  2246. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  2247. return (ERR_BAD_CTRL_COMMAND);
  2248. }
  2249. ///////////////////////////////////////////////////////////////////////////////
  2250. //  Filter params
  2251. ///////////////////////////////////////////////////////////////////////////////
  2252. char szDomain[MAX_HOST_NAME] = "";
  2253. char szADomain[MAX_HOST_NAME] = "";
  2254. StrSNCpy(szDomain, ppszTokens[1]);
  2255. StrLower(szDomain);
  2256. StrSNCpy(szADomain, ppszTokens[2]);
  2257. StrLower(szADomain);
  2258. ///////////////////////////////////////////////////////////////////////////////
  2259. //  Target domain MUST exit ( alias of aliases are not permitted )
  2260. ///////////////////////////////////////////////////////////////////////////////
  2261. if (MDomLookupDomain(szDomain) < 0) {
  2262. ErrorPush();
  2263. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  2264. return (ErrorPop());
  2265. }
  2266. ///////////////////////////////////////////////////////////////////////////////
  2267. //  Alias domain MUST NOT exit
  2268. ///////////////////////////////////////////////////////////////////////////////
  2269. if ((MDomLookupDomain(szADomain) == 0) ||
  2270.     ADomLookupDomain(szADomain, NULL, false)) {
  2271. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_ADOMAIN_EXIST);
  2272. ErrSetErrorCode(ERR_ADOMAIN_EXIST);
  2273. return (ERR_ADOMAIN_EXIST);
  2274. }
  2275. ///////////////////////////////////////////////////////////////////////////////
  2276. //  Add alias domain
  2277. ///////////////////////////////////////////////////////////////////////////////
  2278. if (ADomAddADomain(szADomain, szDomain) < 0) {
  2279. ErrorPush();
  2280. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2281. return (ErrorPop());
  2282. }
  2283. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  2284. return (0);
  2285. }
  2286. static int CTRLDo_aliasdomaindel(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  2287.  char const *const *ppszTokens, int iTokensCount)
  2288. {
  2289. if (iTokensCount != 2) {
  2290. CTRLSendCmdResult(pCTRLCfg, hBSock, ERR_BAD_CTRL_COMMAND);
  2291. ErrSetErrorCode(ERR_BAD_CTRL_COMMAND);
  2292. return (ERR_BAD_CTRL_COMMAND);
  2293. }
  2294. ///////////////////////////////////////////////////////////////////////////////
  2295. //  Filter params
  2296. ///////////////////////////////////////////////////////////////////////////////
  2297. char szADomain[MAX_HOST_NAME] = "";
  2298. StrSNCpy(szADomain, ppszTokens[1]);
  2299. StrLower(szADomain);
  2300. ///////////////////////////////////////////////////////////////////////////////
  2301. //  Remove alias domain
  2302. ///////////////////////////////////////////////////////////////////////////////
  2303. if (ADomRemoveADomain(szADomain) < 0) {
  2304. ErrorPush();
  2305. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrorFetch());
  2306. return (ErrorPop());
  2307. }
  2308. CTRLSendCmdResult(pCTRLCfg, hBSock, 0);
  2309. return (0);
  2310. }
  2311. static int CTRLDo_aliasdomainlist(CTRLConfig * pCTRLCfg, BSOCK_HANDLE hBSock,
  2312.   char const *const *ppszTokens, int iTokensCount)
  2313. {
  2314. ADOMAIN_HANDLE hADomainDB = ADomOpenDB();
  2315. if (hADomainDB == INVALID_ADOMAIN_HANDLE) {
  2316. ErrorPush();
  2317. CTRLSendCmdResult(pCTRLCfg, hBSock, ErrGetErrorCode());
  2318. return (ErrorPop());
  2319. }
  2320. CTRLSendCmdResult(pCTRLCfg, hBSock, CTRL_LISTFOLLOW_RESULT);
  2321. char const *const *ppszStrings = ADomGetFirstDomain(hADomainDB);
  2322. for (; ppszStrings != NULL; ppszStrings = ADomGetNextDomain(hADomainDB)) {
  2323. if ((iTokensCount < 2) ||
  2324.     ((iTokensCount == 2) && StrStringsRIWMatch(&ppszTokens[1], ppszStrings[adomDomain])) ||
  2325.     ((iTokensCount == 3) && StrStringsRIWMatch(&ppszTokens[1], ppszStrings[adomDomain]) &&
  2326.      StrStringsRIWMatch(&ppszTokens[2], ppszStrings[adomADomain]))) {
  2327. if (BSckVSendString
  2328.     (hBSock, pCTRLCfg->iTimeout, ""%s"t"%s"",
  2329.      ppszStrings[adomDomain], ppszStrings[adomADomain]) < 0) {
  2330. ErrorPush();
  2331. ADomCloseDB(hADomainDB);
  2332. return (ErrorPop());
  2333. }
  2334. }
  2335. }
  2336. ADomCloseDB(hADomainDB);
  2337. BSckSendString(hBSock, ".", pCTRLCfg->iTimeout);
  2338. return (0);
  2339. }