Courier LDAP authentication with qmail.schema

Need to include qmail.schema into your slapd.conf, and add object class qmailUser with mail attribute to user object. phpldapadmin can assist most of this setup.

For login from external MUA, e.g. Thunderbird:

  • username: postmaster (NOTE: not postmaster@example.com, we have no virtual domain support right now)
  • password: your_password

Some code snippet for Courier LDAP authentication with qmail.schema.
/etc/courier/authldaprc:

LDAP_URI ldap://127.0.0.1
LDAP_PROTOCOL_VERSION 3
LDAP_BASEDN dc=example,dc=com
LDAP_TIMEOUT 15
LDAP_AUTHBIND 1
LDAP_MAIL uid
LDAP_HOMEDIR homeDirectory
LDAP_MAILDIR mailMessageStore
LDAP_DEFAULTDELIVERY defaultDelivery
LDAP_MAILDIRQUOTA mailQuotaSize
LDAP_FULLNAME cn
LDAP_CRYPTPW userPassword
LDAP_UID uidNumber
LDAP_GID gidNumber
LDAP_DEREF never
LDAP_TLS 0

P.S. Courier LDAP authenticate seems support mailmap with extra lookup and attributes. I will need to study more if virtual domain support is required.


LDAP for Rocket Scientists

Still reading...
http://www.zytrax.com/books/ldap/

P.S. Already able to authenticate Courier and Exim4 with LDAP, but now thinging about multiple virtual domain implementation. Need to consider both Samba, Exim4, Courier and eGroupWare (WOW!) requirement... E.g. Multiple DN is not allowed in Courier ldapauth... May be clone eGroupWare design? From egroupware/addressbook/doc/README:

LDAP layout used for the eGroupWare addressbook
-----------------------------------------------

dc=domain,dc=com    base DN of your LDAP server
|
+-o=default         base DN for the addressbook of eGroupWare domain / DB instance "default"
| |                 (specified in Admin >> Addressbook >> Site config)
| |
| +-ou=accounts     base DN for accounts (specified in Setup >> Configuration)
| | +-uid=ralf      entry for user ralf
| | +-uid=lars      entry for user lars
| | +-uid=...       other users
| |
| +-ou=groups       base DN for groups (specified in Setup >> Configuration)
| | +-cn=Default    entry for the group Default
| | +-cn=...        other groups
| |
| +ou=contacts
|   |
|   +-ou=shared     shared addressbooks of the groups
|   | +-cn=default  addressbook of group Default
|   | +-cn=...
|   |
|   +-ou=personal   personal addressbooks of the users
|     +-cn=ralf     addressbook of user ralf
|     +-cn=lars     addressbook of user lars
|     +-cn=...
|
+-o=other           other eGroupWare domain / DB instance
  +-...


Temperary Exim4 SASL AUTH solution with LDAP-Samba-PAM/NSS + Courier authpam module

Recall to my previous Exim4 + Courier + SSL on Debian etch mini-HOWTO, Exim4 authentication should work fine without enable plain_courier_authdaemon and login_courier_authdaemon support. But case will become a bit more complicated when using LDAP-Samba-PAM/NSS setup: LDAP user will now not able to be authenticated. Why and what's up!?

Why not functioning?

By default Debian's Exim4 already coming with AUTH PLAIN and AUTH LOGIN setup with direct query on /etc/passwd or /etc/shadow as follow (Beware! This is completely not equal as authenticate with PAM!):

plain:
  driver = plaintext
  public_name = PLAIN
.ifndef AUTH_CLIENT_ALLOW_NOTLS_PASSWORDS
  client_send = "<; ${if !eq{$tls_cipher}{}\
                    {^${extract{1}{:}{PASSWDLINE}}\
                     ^${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}\
                   }fail}"
.else
  client_send = "<; ^${extract{1}{:}{PASSWDLINE}}\
                    ^${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}"
.endif

login:
  driver = plaintext
  public_name = LOGIN
.ifndef AUTH_CLIENT_ALLOW_NOTLS_PASSWORDS
  # Return empty string if not non-TLS AND looking up $host in passwd-file
  # yields a non-empty string; fail otherwise.
  client_send = "<; ${if and{\
                          {!eq{$tls_cipher}{}}\
                          {!eq{PASSWDLINE}{}}\
                         }\
                      {}fail}\
                 ; ${extract{1}{::}{PASSWDLINE}}\
                 ; ${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}"
.else
  # Return empty string if looking up $host in passwd-file yields a
  # non-empty string; fail otherwise.
  client_send = "<; ${if !eq{PASSWDLINE}{}\
                      {}fail}\
                 ; ${extract{1}{::}{PASSWDLINE}}\
                 ; ${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}"
.endif

As LDAP users information are now NOT stored within /etc/passwd and /etc/shadow, for sure that above setup will not function (because the PASSWDLINE don't contain such information).

Possible solutions

exim4-auth-001.pngexim4-auth-001.png

Some possible solutions:

  1. Direct authenticate with LDAP backend (reference: http://www.wlug.org.nz/EximSmtpAuth)
  2. Manual setup Exim4 with PAM authentication, as LDAP + PAM/NSS function correctly (reference: http://www.wlug.org.nz/EximSmtpAuth)
  3. Enable Exim4's plain_courier_authdaemon and login_courier_authdaemon support, as Courier's authpam module function correctly (which also means LDAP + PAM/NSS function correctly)

Each setup come with different PROS/CONS:

  1. Direct LDAP authentication: We can even store more information within LDAP, e.g. quota, vocation message, redirect, alias and so on, therefore enrich Exim4 functionality; BTW, this method is the most ideal but complicated in setup.
  2. Manual PAM authentication: A bit simple than above but only able to query authenticate information, and nothing else. There is no default Debian's reference setup, too.
  3. Authenticate though Courier: Most simple as Debian already handle most reference setup, what we only need to do is enable it.

Quick-and-dirty solution

Well... Long story short, as a quick and dirty solution, just enable Exim4's Courier authenticate section as below:

# Authenticate against courier authdaemon

# This is now the (working!) example from
# http://www.exim.org/eximwiki/FAQ/Policy_controls/Q0730
#
Possible pitfall: access rights on /var/run/courier/authdaemon/socket.
plain_courier_authdaemon:
  driver = plaintext
  public_name = PLAIN
  server_condition = \
    ${extract {ADDRESS} \
              {${readsocket{/var/run/courier/authdaemon/socket} \
              {AUTH ${strlen:exim\nlogin\n$auth2\n$auth3\n}\nexim\nlogin\n$auth2\n$auth3\n} }} \
              {yes} \
              fail}
  server_set_id = $auth2
  .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS
  server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}}
  .endif

login_courier_authdaemon:
  driver = plaintext
  public_name = LOGIN
  server_prompts = Username:: : Password::
  server_condition = \
    ${extract {ADDRESS} \
              {${readsocket{/var/run/courier/authdaemon/socket} \
              {AUTH ${strlen:exim\nlogin\n$auth1\n$auth2\n}\nexim\nlogin\n$auth1\n$auth2\n} }} \
              {yes} \
              fail}
  server_set_id = $auth1
  .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS
  server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}}
  .endif

And then ensure Courier is now authenticate with authpam:

authmodulelist="authpam"

Finally give access to Exim4 in order to query Courier authdaemon socket:

chmod 755 /var/run/courier/authdaemon

That's all :D


非人工作間

現在的工作已做了快10個月,但仍然是非人工作間... 看看我的桌面 (左邊是 2008/08/18, 右邊是上週)...

DSC00053.JPGDSC00053.JPG20090604(003).jpg20090604(003).jpg
DSC00054.JPGDSC00054.JPG20090604(004).jpg20090604(004).jpg
DSC00055.JPGDSC00055.JPG20090604(005).jpg20090604(005).jpg
DSC00057.JPGDSC00057.JPG20090604(007).jpg20090604(007).jpg

再看看我上司的桌面和其他地方 (左邊是 2008/08/18, 右邊是上週)... 不要上當,認真玩找不同你便輸了...

DSC00056.JPGDSC00056.JPG20090604(006).jpg20090604(006).jpg
DSC00058.JPGDSC00058.JPG20090604(008).jpg20090604(008).jpg
DSC00059.JPGDSC00059.JPG20090604(009).jpg20090604(009).jpg

以下圖片可能引起觀眾情緒不安...

20090601.jpg20090601.jpg20090601(001).jpg20090601(001).jpg20090601(002).jpg20090601(002).jpg20090601(003).jpg20090601(003).jpg20090601(004).jpg20090601(004).jpg20090601(005).jpg20090601(005).jpg20090601(006).jpg20090601(006).jpg20090601(007).jpg20090601(007).jpg20090530.jpg20090530.jpg20090530(001).jpg20090530(001).jpg20090530(002).jpg20090530(002).jpg20090530(003).jpg20090530(003).jpg20090608(006).jpg20090608(006).jpg20090608(007).jpg20090608(007).jpg

Install Windows XP SP3 from local harddisk with USB flash drive and BartPE

Usually we install Windows XP SP3 from CDROM, but sometime you would like to keep the installation file within local harddisk and start with it because of:

  1. Faster installation. Install from local harddisk can greatly increase the installation process from around 40min to 20min.
  2. Install new Windows component without insert installation CD.
  3. Install new hardware without insert installation CD.

Long story short, if you have enough disk space, just free feel and try with this solution. If you are as lazy as me, this will be your cpu of tea :D

Prepare Windows XP SP3 setup files in USB flash drive

Nothing special for this part: 1. Insert both Windows XP SP3 installation CD and your USB flash drive to the PC, 2. Copy and paste all content from CD to somewhere else in your USB flash drive (or just simply copy the I386 folder, you only need it). That's all.

Well... Some more tips: You should use a valid CD key with your valid installation CD, and should verify if they are able to working together. Remember that Microsoft issue license in at least 3 difference version: OEM (e.g. CD coming from Dell, HP, IBM, etc), VL/VOL (Volume License, usually for enterprise or large organization) and Retail (that you are able to buy from retailer directly). Don't mix them up.

Prepare BartPE

Again nothing special: 1. Download BartPE installation file from official site, 2. Install BartPE master program into your PC, and 3. Insert your Windows XP SP3 installation CD and follow the guideline. It is quite simple if you are not requesting extra features.

Once everything are ready, we can now process with next step.

Process pre-installation with BartPE

The following screenshots are taken from a VirtualBox client, but the procedures are verified as valide with real PC:

  1. Insert both BartPE bootable CD and USB flash drive BEFORE system boot. Remember that BartPE don't support USB pnp.
  2. Boot your system with BartPE CD.
  3. Format the local harddisk into NTFS with "A43 File Management Utility"
  4. Copy the prepared I386 folder from USB flash drive to C:
    xpsp3_hda_setup-000.jpgxpsp3_hda_setup-000.jpg
  5. Run the following command and start the pre-installation procedure:
    C:\i386\winnt32.exe /syspart:C: /tempdrive:C: /makelocalsource
  6. Follow the guideline and complete the required steps:
    xpsp3_hda_setup-001.jpgxpsp3_hda_setup-001.jpgxpsp3_hda_setup-002.jpgxpsp3_hda_setup-002.jpgxpsp3_hda_setup-003.jpgxpsp3_hda_setup-003.jpgxpsp3_hda_setup-004.jpgxpsp3_hda_setup-004.jpgxpsp3_hda_setup-005.jpgxpsp3_hda_setup-005.jpgxpsp3_hda_setup-006.jpgxpsp3_hda_setup-006.jpg
  7. Once it complete you can now shutdown the PC.

Remember to unplug both BartPE and USB flash drive BEFORE next system reboot for installation. You don't need them from now.

Process real installation from local harddisk

You should now boot your PC with local harddisk. The Windows XP SP3 installer should start as usual with some trim-down:

xpsp3_hda_setup-007.jpgxpsp3_hda_setup-007.jpgxpsp3_hda_setup-008.jpgxpsp3_hda_setup-008.jpgxpsp3_hda_setup-009.jpgxpsp3_hda_setup-009.jpg

Nothing special during the rest of installation procedure, but you will able to FEEL the speed difference. Enjoy :D

References

http://www.vandomburg.net/installing-windows-xp-from-usb/


Exim4 SMTP relay though smarthost without TLS support on Debian Lenny

Similar as my previous approach with GMail SMTP smarthost relay, now I try to use my own ISP's SMTP as relay server. BTW, as HGC Broadband's SMTP server only allow port 25 with plain text authentication, with default Debian setup I get the following error message:

2009-04-02 13:39:56 1LpFee-00055Y-1N ** someotherelse@gmail.com R=smarthost T=remote_smtp_smarthost: SMTP error from remote mail server after MAIL FROM:<someone@example.com> SIZE=45837: host mail02.hgcbroadband.com [210.0.255.175]: 530 Authentication required

This is happened even setup correctly with dpkg-reconfigure exim4-config and /etc/exim4/passwd.client. Some important note from Debian configuration file /etc/exim4/conf.d/auth/30_exim4-config_examples:

# Because AUTH PLAIN and AUTH LOGIN send the password in clear, we
# only allow these mechanisms over encrypted connections by default.
# You can set AUTH_CLIENT_ALLOW_NOTLS_PASSWORDS to allow unencrypted
# clear text password authentication on all connections.

So edit /etc/exim4/conf.d/main/03_exim4-config_tlsoptions and add this line to the top of file:

AUTH_CLIENT_ALLOW_NOTLS_PASSWORDS = true

Run dpkg-reconfigure exim4-config again and try to send email though HGC Broadband's SMTP server, all done :D


Using Exim4 to send Messages through GMail on Debian Lenny

NOTE: For complete and latest version please refer to http://wiki.debian.org/GmailAndExim4

Background

My email server seems a bit crazy on these day: both GMail and Yahoo! Mail block a direct send from my server because of following reason:

  hswong3i@gmail.com
    SMTP error from remote mail server after end of data:
    host gmail-smtp-in.l.google.com [209.85.143.114]:
    550-5.7.1 [x.x.x.x] The IP you're using to send mail is not authorized to
    550-5.7.1 send email directly to our servers. Please use the SMTP relay at your
    550-5.7.1 service provider instead. Learn more at            http://mail.google
    550 5.7.1 .com/support/bin/answer.py?answer=10336 d4si2957764tib.28

When checking http://mail.google.com/support/bin/answer.py?answer=10336 it give me the following reason:

In order to prevent spam, Gmail refuses mail when the sending IP address does not match the sending domain. To send mail from your server to Gmail, we suggest using the SMTP relay provided by your ISP. Please note that we are unable to whitelist IP addresses or otherwise make exceptions at this time.

First of all I guess this is due to the use of dynamic IP, with only forward DNS record (A/MX/CNAME) but no reserve record (PTR). But even update my own DNS server with reserve record, no one else are able to discover it though internet. So I have no way to prove my IP is under my control, and so can't prove myself as not spammer.

Secondly, I try to use SMTP relay from my own ISP. BTW, as I am using HGC broadband my username and password is required for the connection. Ok, this is another issue and not my cup of tea :S

Finally, I try to configure my Exim4 to send email though my own Gmail account. This should be most simple because it will no longer depend on my internet connection, and so I can change my ISP whenever and whatever. Here are some procedure for Debian Lenny.

Procedure for Debian Lenny

Run dpkg-reconfigure exim4-config with following options:

  1. General type of mail configuration: mail sent by smarthost; received via SMTP or fetchmail
  2. System mail name: Your SMTP FNDQ, e.g. smtp.example.com
  3. IP-addresses to listen on for incoming SMTP connections: left as empty
  4. Other destinations for which mail is accepted: Some FNDQ of your domain, e.g. example.com, *.example.com
  5. Domains to relay mail for: Other server of your domain, e.g. *.example.com
  6. Machines to relay mail for: Your local subnet, e.g. 192.168.0.0/24
  7. IP address or host name of the outgoing smarthost: smtp.gmail.com::587
  8. Hide local mail name in outgoing mail? No
  9. Keep number of DNS-queries minimal (Dial-on-Demand)? No
  10. Delivery method for local mail: Maildir format in home directory
  11. Split configuration into small files? Yes

Next, edit /etc/exim4/passwd.client and add the following lines (Note: change information accordingly):

gmail-smtp.l.google.com:yourAccountName@gmail.com:y0uRpaSsw0RD
*.google.com:yourAccountName@gmail.com:y0uRpaSsw0RD
smtp.gmail.com:yourAccountName@gmail.com:y0uRpaSsw0RD

Finally, run update-exim4.conf and everything should work fine (You may also run dpkg-reconfigure exim4-config again and double check every setup). Try to send an email to somewhere else and check your log from /var/log/exim/mainlog.

Restriction

Well... GMail SMTP server will rewrite my mail sender (e.g. someone@example.com) into my GMail account (e.g. someotherelse@gmail.com)... This is not what I am really asking for... Well... So I will fallback to use ISP SMTP relay solution... Most likely they are working in same idea :D

Some other tips

Remember that Gmail is using port 587 + TLS for SMTP relay. Always remember to check if TLS support enabled if you face any error.


Some suggested default setup for new Mailman list

All default setup for new Mailman list are located in /usr/lib/mailman/Mailman/Defaults.py, BUT please NEVER touch it and override by using /etc/mailman/mm_cfg.py. Here are some suggested setup for internal usage, just copy and append at the end of /etc/mailman/mm_cfg.py:

DEFAULT_ARCHIVE_PRIVATE = 1
DEFAULT_GENERIC_NONMEMBER_ACTION = 3
DEFAULT_LIST_ADVERTISED = No
DEFAULT_MAX_MESSAGE_SIZE = 0
DEFAULT_MSG_FOOTER = ""
DEFAULT_MSG_HEADER = ""
DEFAULT_REQUIRE_EXPLICIT_DESTINATION = No
DEFAULT_SUBJECT_PREFIX = ""

P.S. Someone like to have subject prefix but someone not. If most of your client are using desktop MUA, e.g. Thunderbird or Outlook, having subject prefix can simplify their filtering rules setup. Always remove header/footer message if some of your client are using legacy MUA.


IT-School HTML mail + mailman

As IT-School will send out email as encoded HTML, I need to remove the footer message (text/plain) from mailman, in order to keep overall message as HTML only (text/html).

Non-digest options / Digest options
-> Footer added to mail sent to regular list members
-> (remove all footer message)

UPDATE (20090306): After more indeed study of this problem I get this page (http://wiki.list.org/pages/viewpage.action?pageId=4030707):

4.39. HELP! Mailman is munging HTML & MIME-formatted messages before they are sent out? (problems with Mailman 2.1.x footers)
...
So, what Mailman does instead is to take the entire HTML message as sent, put that into a MIME bodypart, add another MIME bodypart for the footer, and then wrap all that up and send it out as a message that is formatted as a different kind of MIME message. Some MUAs will display the result in a fashion reasonably close to the format in which the message was submitted, and some won't. Those that have problems may result in the footer being displayed as an attachment, or worse. The same issue applies to msg_header, if any, although in this case, some MUA's may display the header as the message and the body as an attachment.
...
To solve this problem, your options are:

1. Configure Mailman to remove the msg_header/msg_footer
2. Configure Mailman to strip all HTML and MIME formatting and send out all
messages as text-only (text/plain)
3. Get everyone to change the MUA they use to one that is more HTML/MIME-aware
4. Live with the problem
...
Remember - this is not an HTML problem. This is a MIME and MIME/HTML problem. All MIME-formatted messages may have the same problem.

Ok fine... Again the problem of the legacy IT-School MUA engine... As it can't display multipart message correctly, I need to remove all footer message from mailman lists.


Mail sync hack for IT-School intranet mail with normal mail server

IT-School (http://myit-school.net/) is a school management system in Hong Kong, which target for intranet mail, calender, account management, and so on. BTW, for the old version (around 2004) of IT-School, its mail system is split into 3 parts:

  • Intranet mail: Mail from and to account will fetch from MySQL DB directly, mail will NEVER deliver though normal email server router BUT save into MySQL DB as HTML format DIRECTLY. Support individual user and group of users.
  • Outgoing internet mail: Mail will send though sendmail.
  • Incoming internet mail: Mail will first received by sendmail as normal email format. User will not able to browse external mail UNLESS they press a "Check email" link from the GUI. Once they press this link, a small window will pop-up, inform user that IT-School will fetch and convert the real email as its own format, and save into its MySQL DB as intranet mail.

The send out email action preform 2 part (/usr/local/it-school/www/php/intra/savemail.php3):

  1. Handle all intranet email transaction.
                    //        send to other user
                    intramail($mail_id);
  2. Send internet email though MTA.
                    //              send e_mail
                    //        check privilege
                    if ($support_sending_email && checkprivilege($userid, 'send_email')) {
                            send_email($mail_id);
                    }

How complicated it is! In order to migrate the old system to normal MTA + eGroupWare, I did some trick in IT-School's source code for:

  1. Hack the send_email() function (/usr/local/it-school/www/php/intra/imapfunction.php3), search out all internal users and groups, generate a public email for them (if user's ~/.forward exists and contain valid forward address), and send out another copy though normal MTA:
    diff -urpN intra.20090216/imapfunction.php3 intra/imapfunction.php3
    --- intra.20090216/imapfunction.php3 2009-02-13 10:00:42.000000000 +0800
    +++ intra/imapfunction.php3 2009-02-16 09:52:34.000000000 +0800
    @@ -174,6 +174,93 @@ function send_email($mail_id) {
       get_email_list($unprocess_bpgroupid, $bcc_puser, $bcc_pemail);
       $pemail_source = array();

    +  // XXX: Check and forward intra email as internet email to mail2.
    +
    +  global $db_database;
    +  global $db_host;
    +  global $db_user;
    +  global $db_password;
    +  $db = new Mysql_DB_Sql($db_database, $db_host, $db_user, $db_password);
    +
    +  // Fetch loginid from userid, generate mail2. address, and append to internet_* as public mail.
    +  foreach (array('recipient', 'cc', 'bcc') as $target) {
    +    $_loginids = array();
    +    $_email_address_array = array();
    +    foreach (explode(',', $sourcemail['internet_' . $target]) as $address) {
    +      $_email_address_array[$address] = $address;
    +    }
    +
    +    // Grep all indiviual user IDs.
    +    if (count($sourcemail[$target]['user']) > 0) {
    +      $sql = "SELECT loginid FROM ituser WHERE userid IN (" . implode(', ', $sourcemail[$target]['user']) . ")";
    +      $db->query($sql);
    +      while ($db->next_record()) {
    +        $_loginids[] = $db->f('loginid');
    +      }
    +    }
    +
    +    // Grep all userid from group, then replace as loginid.
    +    if (count($sourcemail[$target]['group']) > 0) {
    +      $sql = "SELECT userid FROM user_usergroup WHERE groupid IN ('" . implode("', '", $sourcemail[$target]['group']) . "')";
    +      $db->query($sql);
    +      $_userid = array();
    +      while ($db->next_record()) {
    +        $_userid[] = $db->f('userid');
    +      }
    +
    +      $sql = "SELECT loginid FROM ituser WHERE userid IN (" . implode(', ', $_userid) . ")";
    +      $db->query($sql);
    +      while ($db->next_record()) {
    +        $_loginids[] = $db->f('loginid');
    +      }
    +    }
    +
    +    $_user = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\']+';
    +    $_domain = '(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.?)+';
    +    $_ipv4 = '[0-9]{1,3}(\.[0-9]{1,3}){3}';
    +    $_ipv6 = '[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7}';
    +
    +    // If convert required, do so.
    +    if (count($_loginids) > 0) {
    +      foreach ($_loginids as $_loginid) {
    +        $path = '/home/' . $_loginid . '/.forward';
    +        if ($handle = @fopen($path, 'r')) {
    +          while (!feof($handle)) {
    +            $buffer = fgets($handle, 4096);
    +            $buffer = trim($buffer);
    +            if (preg_match("/^$_user@($_domain|(\[($_ipv4|$_ipv6)\]))$/", $buffer)) {
    +              $_email_address_array[$buffer] = $buffer;
    +            }
    +          }
    +          fclose($handle);
    +        }
    +      }
    +      $sourcemail['internet_' . $target] = implode(',', $_email_address_array);
    +    }
    +  }
    +
    +  // Print debug message within header.
    +  $array = array(
    +    'internet_recipient_orig' => $internet_recipient_orig,
    +    'internet_recipient_new' => $internet_recipient_new,
    +    'loginids' => $loginids,
    +    'sourcemail' => $sourcemail,
    +    'recipient_puser' => $recipient_puser,
    +    'recipient_pemail' => $recipient_pemail,
    +    'cc_puser' => $cc_puser,
    +    'cc_pemail' => $cc_pemail,
    +    'bcc_puser' => $bcc_puser,
    +    'bcc_pemail' => $bcc_pemail,
    +    'pemail_source' => $pemail_source,
    +  );
    +  ob_start();
    +  var_dump($array);
    +  $contents = ob_get_contents();
    +  ob_end_clean();
    +  print "\n\n<!-- $contents -->\n\n";
    +
    +  // XXX: Check and forward intra email as internet email to mail2.
    +
    //  join them
       $email_address_array = $process_userid;
    //  $email_address_array = array_merge($process_userid, $recipient_pemail, $cc_pemail, $bcc_pemail);
  2. Trigger "Check email" action though JS periodically (/usr/local/it-school/www/php/intra/index.php3):
    diff -urpN intra.20090216/index.php3 intra/index.php3
    --- intra.20090216/index.php3 2009-02-15 19:02:37.000000000 +0800
    +++ intra/index.php3 2009-02-16 09:49:22.000000000 +0800
    @@ -254,6 +254,13 @@ if ($can_check_email) {
       echo 'email = window.open("check_email.php?"+Math.random(), "CheckEmail","status=1,width=200,height=150");';
         echo 'email.focus();';
       echo '}';
    +
    +  // XXX: Auto open "Check email" window for every 5mins.
    +  echo 'var fm_timerFolderStatus;';
    +  // refresh after 5min.
    +  echo 'var refreshTimeOut = 300000;';
    +  echo 'fm_timerFolderStatus = window.setInterval("check_email()", refreshTimeOut);';
    +  // XXX: Auto open "Check email" window for every 5mins.
    }
    ?>
    </SCRIPT>
  3. Close the pop-up window though JS automatically (/usr/local/it-school/www/php/intra/check_email.php):
    diff -urpN intra.20090216/check_email.php intra/check_email.php
    --- intra.20090216/check_email.php 2009-02-15 20:43:03.000000000 +0800
    +++ intra/check_email.php 2009-02-16 09:49:36.000000000 +0800
    @@ -57,6 +57,11 @@ function refresh_parent() {
    function goBack() {
       window.close();
    }
    +
    +// XXX: Auto close confirm window after 1s.
    +fm_goBack = window.setInterval("goBack()", 1000);
    +// XXX: end Auto close confirm window after 1s.
    +
    //-->
    </SCRIPT>
    <BODY>

Now any IT-School email transaction will be cloned to the new system :D

P.S. Thanks for the experience of hacking Drupal, this hack become much simple: it only cost for 2 working days. Some checking are cloned from Drupal driectly, e.g. email address validation, pipe console output as plain text, and even the skill for patching source. Well, skills will always become weapon, and become useful whenever you need for it :D


Syndicate content