Ezzel a cikkel két éve tartozom magamnak. A cikket akkoriban meg is írtam, de sosem publikáltam, mert elsodort az élet. Most publikálom, de azóta sok minden változott. Azok a részleteket, amik az eredeti cikkből származnak, itt dőlt betűvel írom.
Az előzmények:
Van egy kedves baráti társaságunk (InetPub). Ez a baráti társaság üzemeltet egy levelezőlistát. Ezt végtelenül egyszerűen oldottuk meg. Az egyik kolléga Exchange szerverén felvettünk egy disztribúciós listát és a külsős tagokat felvettük az ő Active Directory-ába contact-ként.
Ezzel a dologgal csak egy gond van. Miután az egész levelező listaként működik, jó lenne megoldani, hogy a kimenő levelekben a Reply-To cím a lista címe legyen. Mi sem egyszerűbb ennél, a csapat egyik tagja írt egy SMTP Sink-et ami alig pár sor és a rajta áthaladó leveleken beállítja a Reply-To mezőt. Ez a Sink-et pedig egy RCPT TO=<listacíme> rule-al regisztrálta. Ez a megoldás szép és jó, mindaddig, amíg a levelek külső feladótól érkeznek. A külső feladóknál szépen végrehajtódik a Sink, de a belső feladónál nem hajtódik végre, hiszen az eredeti listás címzettel rendelkező levél el sem jut az SMTP szerverig, hiszen hamarabb feloldja a rendszer a lista címét az egyenkénti címzettek címére.
Valamikor 2006 decemberében nekiláttam, hogy a fenti állapotot megszüntessem. Elkészült (akkor még Exchange 2003-hoz) egy sink, ami képes a belső címekkel is megcsinálni a fenti trükköt. Tehát folytatva:
Ez a megközelítésem, mint későbbiekben rájöttem, alapvetően hibás. Az Exchange-ben azok a levelek amik belső feladótól MAPI kliens-el küldve belső feladóhoz tartanak is átmennek az SMTP szerver transport részein és végrehajtódnak rájuk az OnTransportSubmission (OnArrival), PreCategorize, PostCategorize események. Ha ezek az események végrehajtódnak, akkor mégis miért nem találkozunk ezekkel a levelekkel az OnArrival Sink-re írt scriptekben? Ennek egyszerű oka van. Amikor regisztrálunk egy Sink-et akkor megadunk egy szabályt (Rule) ami alapján kiválogatja a rendszer azokat a leveleket amiket a Sink-űnk megkap. Ezzel egy gond van. Ez a szabály egy protokoll szabály, azaz az SMTP protokoll kommunikációban lévő elemekre (MAIL FROM, RCPT TO) lehet szűrni. A MAPI levelek viszont nem haladnak keresztül az SMTP szerver protokoll részén így protokoll szabályokat sem lehet rájuk érvényesíteni. A képlet egyszerű: Ha van szabály, akkor nem látjuk a MAPI leveleket. Ezt sajnos a Microsoftnál sem gondolta végig senki így a Sink regisztrációra írt smtpreg.vbs egyetlen verziója sem képes szabály nélkül Sink-et regisztrálni (sajnos az üres szabály is szabály).
Ezen felfedezéseim alapján arra gondoltam, hogy írok egy olyan SMTP Sink-et ami megoldja, hogy a belső felhasználók által küldött leveleken is jó Reply-To cím szerepeljen.
Elképzelések:
Nincs semmi különös teendőm, mindösszesen a fenti eredeti Sink-et kiegészítem egy belső a címzettre vonatkozó szűrővel és már kész is vagyok. Ez alapvetően bukott meg. A MAPI levelek nem MIME formátumban utaznak az SMTP szerveren hanem TNEF formátumban. Bármit módosítok a levélen azt a rendszer eldobja és az eredetivel dolgozik tovább (http://support.microsoft.com/?id=273233)
Ez az a pillanat amikor el kellett vetnem, hogy ezt az egészet script-ben meg tudom írni. Elővettem a Microsoft menedzselt kódban való Sink írásról készült cikkét és a benne található Interop és Wrapper osztályokat. Rengeteget kísérleteztem, sajnos az eredeti Wrapper-t is ki kellett egészíteni (nem képes kezelni a MAPI címzést, csak az SMTP-t). Itt kell megemlítenem, hogy Dean Harding cikke (http://codeka.com/blogs/index.php/dean/2005/06/06/managed_iis_smtp_sink_wrapper_message_co) alapján a CopyContentToStream funkciót is módosítottam (miután kénytelen voltam az eredeti wrapperbe több helyen belenyúlni, így nem követtem az ő kívülről módosítgató módszerét itt sem, hanem beleírtam az eredeti kódba). A dolog igencsak nyakatekert lett. Megpróbálom felvázolni nagy vonalakban, hogyan is működik:
1. Az OnTransportSubmission Sink-en végignézem a bejövő levél címzettjeit és a Global Catalog alapján megnézem, hogy van-e köztük disztribúciós lista. Ha találok ilyet, akkor ezt a címet lecserélem egy olyan dummy címre ami három szabálynak felel meg.
a. Egy későbbi Sink felismeri, hogy ezt a címet az én Sink-em csinálta.
b. Tartalmazza a disztribúciós lista objectGUID azonosítóját
c. Olyan e-mail domain-be tart, ami mindenképp az Exchange hatókörén kívül van. Erre azért van szükség, mert ha belső cím lenne, akkor az SMTP szerver a későbbiekben nem konvertálná a TNEF levelet MIME-ra és így nem tudnánk feldolgozni.
2. Az OnMessagePostCategorize Sink-en megkeresem azt a levelet, ami a korábbi Sink által berakott E-Mail címmel rendelkezik. A Global Catalog alapján visszacserélem az eredeti lista címre, belerakom a Reply-To mezőt, és a levelet leteszem az SMTP szerver pickup könyvtárába.
3. A szerver felveszi a levelet és újra végigmegy a folyamaton (a levélbe közben tettem egy olyan fejléc mezőt is, amit észrevéve az első Sink nem módosítja újra). Ekkor a categorizer már kibontja az eredeti disztribúciós listát a végső címzettekre.
Ennyit az eredeti cikkből. Itt most az következne, hogyan kell telepíteni és használni az egészet. Ez azóta változott. Hogy miért, arról később.
Szóval valamikor 2007. január elején el is készült egy verzió, amit használatba is vettünk. Nem telt el egy hónap, amikor a kolléga (BB), akinél a rendszer volt tudata velem, hogy átállás lesz, és a lista költözik Exchange 2007-re. Ő akkor azt gondolta, hogy semmi gáz, biztos megy a régi sink az új szoftveren. Tévedett. Kemény küzdések árán ekkor tanultam megy Exchange 2007 Transport Agent-et írni.
Az új verzióra szánt szerkezet is működött. Időm továbbra sem volt publikálni.
Valamikor 2008-ban megszültetett egy MVP levelező lista, Exchange 2003 alapon, amit az első verzióval oldottak meg a kitalálói.
2008 nyarán volt egy Rendszergazdák napja című esemény, ami után született több levelező lista a fenti Exchange 2003 szerveren.
Az üzemeltető (GT) ezt a szervert most a napokban állította át 2007-re, így esedékessé vált a sink cseréje is. Ezen felbuzdulva nekiláttam, hogy
1. Egy kicsit kipofozzam mind a 2003-as, mind a 2007-es verziót.
2. Írjak hozzá némi dokumentációt (ez egyelőre még angol, mert máshol is publikálni akarom)
Az elkészült darabok itt érhetőek el:
DistList (Exchange 2003-as verzió)
DistList 2007 (Exchange 2007-es verzió)
Forráskód
Dokumentáció
Ha valakinek kérdése, megjegyzése, továbbfejlesztési ötlete van, azt szívesen fogadom.
Recent Comments