[c5c522c] | 1 | diff -ru zarafa-7.1.4/provider/libserver/ZarafaCmd.cpp zarafa-7.1.4.spamhook/provider/libserver/ZarafaCmd.cpp |
---|
| 2 | --- zarafa-7.1.4/provider/libserver/ZarafaCmd.cpp 2013-02-28 17:13:17.000000000 +0100 |
---|
| 3 | +++ zarafa-7.1.4.spamhook/provider/libserver/ZarafaCmd.cpp 2013-04-15 11:34:45.018632455 +0200 |
---|
| 4 | @@ -84,6 +84,7 @@ |
---|
| 5 | #include "StreamUtil.h" |
---|
| 6 | #include "CommonUtil.h" |
---|
| 7 | #include "StorageUtil.h" |
---|
| 8 | +#include "UnixUtil.h" |
---|
| 9 | |
---|
| 10 | #include "ZarafaICS.h" |
---|
| 11 | |
---|
| 12 | @@ -7655,6 +7656,179 @@ |
---|
| 13 | bool bMoved; |
---|
| 14 | }COPYITEM; |
---|
| 15 | |
---|
| 16 | +//SPAM HOOK |
---|
| 17 | +//This function parses an e-mail to the /etc/zarafa/userscripts/junklearn script. With 2 arguments: |
---|
| 18 | +//ham or spam |
---|
| 19 | +//message id |
---|
| 20 | +//and pipes the mail header to the script. |
---|
| 21 | +//This script wil be inhaled by MoveObjects(); |
---|
| 22 | +///////////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 23 | +int SpamHook(ECDatabase *lpDatabase,int ulId, unsigned int ulDestFolderId) |
---|
| 24 | +{ |
---|
| 25 | + |
---|
| 26 | + ALLOC_DBRESULT(); |
---|
| 27 | + ECRESULT er = erSuccess; |
---|
| 28 | + std::string shScriptPath = g_lpSessionManager->GetConfig()->GetSetting("junklearn_script"); |
---|
| 29 | + string shMailStatus; |
---|
| 30 | + entryId* junkFolderEntryId; |
---|
| 31 | + entryId* wasteBucketEntryId; |
---|
| 32 | + int shNumRows; |
---|
| 33 | + |
---|
| 34 | + //dont do anything if the junklearn script doesnt exist: |
---|
| 35 | + int fCheck=open(shScriptPath.c_str(), O_RDONLY); |
---|
| 36 | + if (fCheck==0) { |
---|
| 37 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_INFO,"SpamHook: skipping, script "+shScriptPath+" not found"); |
---|
| 38 | + er=erSuccess; |
---|
| 39 | + goto exit; |
---|
| 40 | + } |
---|
| 41 | + close(fCheck); |
---|
| 42 | + |
---|
| 43 | + //Get store object ID via message object id |
---|
| 44 | + unsigned int storeId; |
---|
| 45 | + er = g_lpSessionManager->GetCacheManager()->GetStore(ulId,&storeId,NULL); |
---|
| 46 | + if(er != erSuccess) |
---|
| 47 | + { |
---|
| 48 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve source folder."); |
---|
| 49 | + goto exit; |
---|
| 50 | + } |
---|
| 51 | + |
---|
| 52 | + //get deleted items folder entry id |
---|
| 53 | + strQuery="SELECT val_binary FROM properties WHERE hierarchyid="+stringify(storeId)+" AND tag="+stringify(PROP_ID(PR_IPM_WASTEBASKET_ENTRYID)); |
---|
| 54 | + er = lpDatabase->DoSelect(strQuery, &lpDBResult); |
---|
| 55 | + if(er != erSuccess) { |
---|
| 56 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve wastebasket entryid from DB."); |
---|
| 57 | + goto exit; |
---|
| 58 | + } |
---|
| 59 | + lpDBRow = lpDatabase->FetchRow(lpDBResult); |
---|
| 60 | + lpDBLen = lpDatabase->FetchRowLengths(lpDBResult); |
---|
| 61 | + shNumRows=lpDatabase->GetNumRows(lpDBResult); |
---|
| 62 | + if(shNumRows<1) |
---|
| 63 | + { |
---|
| 64 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve wastebasket entryid, empty DB result."); |
---|
| 65 | + goto exit; |
---|
| 66 | + } |
---|
| 67 | + |
---|
| 68 | + //Convert 'deleted items' entryid to objectid. |
---|
| 69 | + wasteBucketEntryId = new entryId[0]; |
---|
| 70 | + wasteBucketEntryId->__ptr=(unsigned char*)lpDBRow[0]; |
---|
| 71 | + wasteBucketEntryId->__size=lpDBLen[0]; |
---|
| 72 | + unsigned int wasteBucketFolderId; |
---|
| 73 | + er=g_lpSessionManager->GetCacheManager()->GetObjectFromEntryId(wasteBucketEntryId,&wasteBucketFolderId); |
---|
| 74 | + delete wasteBucketEntryId; |
---|
| 75 | + if(er!=erSuccess) |
---|
| 76 | + { |
---|
| 77 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve wastebasket entryid, converting to objectID."); |
---|
| 78 | + goto exit; |
---|
| 79 | + } |
---|
| 80 | + |
---|
| 81 | + //Get 'junk folder' entryId. |
---|
| 82 | + FREE_DBRESULT(); |
---|
| 83 | + strQuery="SELECT val_binary FROM receivefolder LEFT JOIN mvproperties ON receivefolder.objid=mvproperties.hierarchyid WHERE receivefolder.storeid="+stringify(storeId)+" AND receivefolder.messageclass='IPC' AND mvproperties.tag="+stringify(PROP_ID(PR_ADDITIONAL_REN_ENTRYIDS))+" AND mvproperties.orderid=4"; |
---|
| 84 | + er = lpDatabase->DoSelect(strQuery, &lpDBResult); |
---|
| 85 | + if(er != erSuccess) { |
---|
| 86 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve junkfolder entryids from DB."); |
---|
| 87 | + goto exit; |
---|
| 88 | + } |
---|
| 89 | + lpDBRow = lpDatabase->FetchRow(lpDBResult); |
---|
| 90 | + lpDBLen = lpDatabase->FetchRowLengths(lpDBResult); |
---|
| 91 | + shNumRows=lpDatabase->GetNumRows(lpDBResult); |
---|
| 92 | + if(shNumRows<1) |
---|
| 93 | + { |
---|
| 94 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve junkfolder entryid, empty DB result."); |
---|
| 95 | + goto exit; |
---|
| 96 | + } |
---|
| 97 | + |
---|
| 98 | + //Convert 'junk folder' entryid to objectid. |
---|
| 99 | + junkFolderEntryId = new entryId[0]; |
---|
| 100 | + junkFolderEntryId->__ptr=(unsigned char*)lpDBRow[0]; |
---|
| 101 | + junkFolderEntryId->__size=lpDBLen[0]; |
---|
| 102 | + unsigned int junkFolderId; |
---|
| 103 | + er=g_lpSessionManager->GetCacheManager()->GetObjectFromEntryId(junkFolderEntryId,&junkFolderId); |
---|
| 104 | + delete junkFolderEntryId; |
---|
| 105 | + if(er!=erSuccess) |
---|
| 106 | + { |
---|
| 107 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve junkfolder entryid, converting to objectID."); |
---|
| 108 | + goto exit; |
---|
| 109 | + } |
---|
| 110 | + |
---|
| 111 | + //Get source folder object ID. (Actually we should check if mail came from subfolders in the 'deleted items folder', which I think never happens.) |
---|
| 112 | + unsigned int srcFolderId; |
---|
| 113 | + er=g_lpSessionManager->GetCacheManager()->GetParent(ulId,&srcFolderId); |
---|
| 114 | + if(er!=erSuccess) |
---|
| 115 | + { |
---|
| 116 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve src folder id."); |
---|
| 117 | + goto exit; |
---|
| 118 | + } |
---|
| 119 | + |
---|
| 120 | + //now we can determine if object being moved from or to the junkfolder |
---|
| 121 | + //if destination folder is junk, mark as spam |
---|
| 122 | + if(ulDestFolderId==junkFolderId) |
---|
| 123 | + shMailStatus="spam"; |
---|
| 124 | + else |
---|
| 125 | + { |
---|
| 126 | + //if destination folder is not TRASH and de source folder is JUNK, mark as ham |
---|
| 127 | + if(ulDestFolderId!=wasteBucketFolderId && srcFolderId==junkFolderId) |
---|
| 128 | + shMailStatus="ham"; |
---|
| 129 | + else |
---|
| 130 | + //its just a normal movement, so do nothing. |
---|
| 131 | + goto exit; |
---|
| 132 | + } |
---|
| 133 | + |
---|
| 134 | + //Get the mail from the DB. |
---|
| 135 | + FREE_DBRESULT(); |
---|
| 136 | + strQuery="SELECT val_string FROM properties WHERE tag="+stringify(PROP_ID(PR_TRANSPORT_MESSAGE_HEADERS))+" AND hierarchyid= "+stringify(ulId); |
---|
| 137 | + er = lpDatabase->DoSelect(strQuery, &lpDBResult); |
---|
| 138 | + if(er != erSuccess) { |
---|
| 139 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: db error while retrieve mail header."); |
---|
| 140 | + goto exit; |
---|
| 141 | + } |
---|
| 142 | + |
---|
| 143 | + lpDBRow = lpDatabase->FetchRow(lpDBResult); |
---|
| 144 | + shNumRows=lpDatabase->GetNumRows(lpDBResult); |
---|
| 145 | + |
---|
| 146 | + if(shNumRows<=0) { |
---|
| 147 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: warning mail header empty or this object is no e-mail"); |
---|
| 148 | + goto exit; |
---|
| 149 | + } |
---|
| 150 | + |
---|
| 151 | + { |
---|
| 152 | + //now its time to open the spamhook script and pass the mail to it: |
---|
| 153 | + shScriptPath=shScriptPath+" "+shMailStatus+" "+stringify(ulId); |
---|
| 154 | + int ulFpWrite = -1; |
---|
| 155 | + int ulFpRead = -1; |
---|
| 156 | + int ulCommandRetval; |
---|
| 157 | + |
---|
| 158 | + //we asume failure, unless we make it all the way though the script |
---|
| 159 | + er=ZARAFA_E_UNKNOWN; |
---|
| 160 | + |
---|
| 161 | + pid_t ulCommandPid = unix_popen_rw(g_lpSessionManager->GetLogger(), shScriptPath.c_str(), &ulFpWrite, &ulFpRead, NULL, NULL, true, false); |
---|
| 162 | + if (ulCommandPid <= 0) { |
---|
| 163 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error opening subprocess."); |
---|
| 164 | + goto exit; |
---|
| 165 | + } |
---|
| 166 | + |
---|
| 167 | + //pass the data to the subprocess: |
---|
| 168 | + write(ulFpWrite, lpDBRow[0], strlen(lpDBRow[0])); |
---|
| 169 | + ulCommandRetval=unix_pclose(ulFpRead, ulFpWrite, ulCommandPid); |
---|
| 170 | + |
---|
| 171 | + //subprocess is done, check results |
---|
| 172 | + if (ulCommandRetval<0) { |
---|
| 173 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error "+shScriptPath+" exits with: "+stringify(WEXITSTATUS(ulCommandRetval))); |
---|
| 174 | + goto exit; |
---|
| 175 | + } |
---|
| 176 | + } |
---|
| 177 | + |
---|
| 178 | + g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_INFO,"SpamHook: "+shScriptPath+" successfully executed."); |
---|
| 179 | + er=erSuccess; |
---|
| 180 | + |
---|
| 181 | + exit: |
---|
| 182 | + // Free database results |
---|
| 183 | + FREE_DBRESULT(); |
---|
| 184 | + |
---|
| 185 | + return er; |
---|
| 186 | +} |
---|
| 187 | + |
---|
| 188 | + |
---|
| 189 | // Move one or more messages and/or moved a softdeleted message to a normal message |
---|
| 190 | ECRESULT MoveObjects(ECSession *lpSession, ECDatabase *lpDatabase, ECListInt* lplObjectIds, unsigned int ulDestFolderId, unsigned int ulSyncId) |
---|
| 191 | { |
---|
| 192 | @@ -8641,6 +8815,16 @@ |
---|
| 193 | |
---|
| 194 | // @note The object type checking wille be done in MoveObjects or CopyObject |
---|
| 195 | |
---|
| 196 | +//SPAMHOOK |
---|
| 197 | +///////////////////////////////////// |
---|
| 198 | + //Iterate over all mail ids and initiate spamhook. |
---|
| 199 | + for(iObjectId = lObjectIds.begin(); iObjectId != lObjectIds.end(); iObjectId++) |
---|
| 200 | + { |
---|
| 201 | + SpamHook(lpDatabase,*iObjectId,ulDestFolderId); |
---|
| 202 | + } |
---|
| 203 | +//SPAMHOOK END |
---|
| 204 | +//////////////////////////////////// |
---|
| 205 | + |
---|
| 206 | //check copy or a move |
---|
| 207 | if(ulFlags & FOLDER_MOVE ) { // A move |
---|
| 208 | er = MoveObjects(lpecSession, lpDatabase, &lObjectIds, ulDestFolderId, ulSyncId); |
---|
| 209 | diff -ru zarafa-7.1.4/provider/server/ECServer.cpp zarafa-7.1.4.spamhook/provider/server/ECServer.cpp |
---|
| 210 | --- zarafa-7.1.4/provider/server/ECServer.cpp 2013-02-28 17:13:17.000000000 +0100 |
---|
| 211 | +++ zarafa-7.1.4.spamhook/provider/server/ECServer.cpp 2013-04-15 11:14:40.000000000 +0200 |
---|
| 212 | @@ -963,6 +963,7 @@ |
---|
| 213 | { "deletegroup_script", "/etc/zarafa/userscripts/deletegroup", CONFIGSETTING_RELOADABLE}, |
---|
| 214 | { "createcompany_script", "/etc/zarafa/userscripts/createcompany", CONFIGSETTING_RELOADABLE }, |
---|
| 215 | { "deletecompany_script", "/etc/zarafa/userscripts/deletecompany", CONFIGSETTING_RELOADABLE }, |
---|
| 216 | + { "junklearn_script", "/etc/zarafa/userscripts/junklearn", CONFIGSETTING_RELOADABLE }, |
---|
| 217 | { "user_safe_mode", "no", CONFIGSETTING_RELOADABLE }, |
---|
| 218 | |
---|
| 219 | // Storename format |
---|