I used dspam on a Linux server in front of a Microsoft Exchange server and was fighting with a good integration of user relay lists since I have multiple domains and users on my Exchange server. I wrote a little PHP script to help synchronize my LDAP to dspam MySQL information. I also set Postfix to use the dspam database for relay_recipients and it works like a charm. I'm not a PHP programmer by far so it's probably rather clunky, but it seems to work for me.
You do need to use the virtual user database setup where the uid is not auto_increment and is not unique. Please excuse and formatting issues. Improvements are welcome. Here's the script if anybody is interested: <?php $ldap_server = "ldap://yourserver.yourdomain.com"; $auth_user = "[EMAIL PROTECTED]"; $auth_pass = "password"; $mysql_user = "mysql_user"; $mysql_pass = "mysql_pass"; $dspam_database = "dspam"; // Set the base dn to search the entire directory. $base_dn = "DC=yourdomain, DC=com"; // Show only user persons $filter = "(&(objectClass=user)(objectCategory=person)(cn=*))"; // connect to server if (!([EMAIL PROTECTED]($ldap_server))) { die("Could not connect to ldap server"); } ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($connect, LDAP_OPT_REFERRALS, 0); // bind to server if (!([EMAIL PROTECTED]($connect, $auth_user, $auth_pass))) { die("Unable to bind to server"); } // search active directory if (!([EMAIL PROTECTED]($connect, $base_dn, $filter))) { die("Unable to search ldap server"); } $number_returned = ldap_count_entries($connect,$search); $info = ldap_get_entries($connect, $search); // Create an array of users and their e-mails for ($i=0; $i<$info["count"]; $i++) { $current_user = $info[$i]['samaccountname'][0]; if ( $info[$i]['mail'][0] ) { $emails[$i]['user'] = $current_user; $emails[$i]['emails'][] = strtolower($info[$i]['mail'][0]); for ($e=0; $e<$info[$i]['proxyaddresses']['count']; $e++) { $current_address = strtolower( $info[$i]['proxyaddresses'][$e]) ; if ( strstr( $current_address, 'smtp:') ) { $emails[$i]['emails'][] = str_replace( 'smtp:', '', $current_address) ; } } } } // Disconnect LDAP ldap_close($connect); // Open MySQL database $db = mysql_connect( 'localhost', $mysql_user, $mysql_pass' ) or die('Could not connect: ' . mysql_error()); mysql_select_db( $dspam_database ) or die('Could not select database'); // Get UID of each user, add UID and user if not exists. foreach ( $emails as $key => $value ) { $emails[$key]['uid'] = getUID( $value ); updateLocalStore( $emails[$key]['uid'] ); } echo 'UIDs up to date.<br/>'; // Have the users, now update the email addresses foreach ( $emails as $value ) { addEmails( $value ); } echo 'E-mails syncronized with LDAP.<br/>'; // Clean out deleted users and/or e-mail addresses cleanDatabase( $emails ); echo 'Database cleaned.<br/>'; function getUID($user) { global $db; $query = 'SELECT * FROM dspam_virtual_uids WHERE username = "' . $user['user'] . '"'; $res = mysql_query( $query ); if ( mysql_num_rows( $res ) > 0 ) { $user_id = mysql_fetch_assoc( $res ); return $user_id['uid']; } else { $email_res = mysql_query( 'SELECT * FROM dspam_virtual_uids WHERE username = "' . $user['emails'][0] . '"') ; if ( mysql_num_rows($email_res) > 0 ) { $uid = mysql_fetch_row( $email_res ); } else { $id_res = mysql_query( 'SELECT MAX(uid) + 1 FROM dspam_virtual_uids' ); $uid = mysql_fetch_row( $id_res ); if ( createUser( $uid[0], $user['user'] ) != $uid[0] ) die(mysql_error()) ; } return $uid[0]; } } function updateLocalStore( $uid ) { global $db; $preference_res = mysql_query( 'SELECT * FROM dspam_preferences WHERE preference = "localStore" AND uid = ' . $uid ) or die( mysql_error() ); if ( mysql_num_rows( $preference_res ) > 0 ) { $row = mysql_fetch_assoc( $preference_res ); if ( $row['value'] != $uid ) { $replace_preference = 'REPLACE INTO dspam_preferences VALUES ( ' . $uid . ', "localStore", ' . $uid . ')'; if ( !mysql_query( $replace_preference ) ) die(mysql_error()); } } else { $update_preference = 'INSERT INTO dspam_preferences VALUES ( ' . $uid . ', "localStore", ' . $uid . ' )'; if ( !mysql_query( $update_preference ) ) die (mysql_error()); } } function createUser( $uid, $username ) { global $db; $query = 'INSERT INTO dspam_virtual_uids VALUES ( ' . $uid . ', "' . addslashes($username) . '" )'; if ( mysql_query( $query ) ) { echo 'Created user ' . $username . ' with a uid of ' . $uid . '.<br/>'; return $uid; } else { return false; } } function addEmails( $user ) { global $db; foreach ( $user['emails'] as $value ) { $query_res = mysql_query( 'SELECT uid FROM dspam_virtual_uids WHERE username = "' . $value . '"' ) or die(mysql_error()); if ( mysql_num_rows($query_res) > 0 ) { // A user exists, check if it's accurate $row = mysql_fetch_row( $query_res ); if ( $row[0] != $user['uid'] ) { $update = 'REPLACE INTO dspam_virtual_uids VALUES ( ' . $user['uid'] . ', "' . $value . '" )'; if ( !mysql_query( $update ) ) die(mysql_error()); echo 'User ' . $value . ' was updated.<br/>'; } } else { $insert = 'INSERT INTO dspam_virtual_uids VALUES ( ' . $user['uid'] . ', "' . $value . '" )'; if ( !mysql_query( $insert ) ) die( mysql_error() ); echo 'User ' . $value . ' was added.<br/>'; } } } function cleanDatabase( $users ) { global $db; $query = 'SELECT * FROM dspam_virtual_uids'; $res = mysql_query( $query ); if ( mysql_num_rows( $res ) > 0 ) { while ( $row = mysql_fetch_assoc( $res ) ) { if ( !in_arrayr( $row['username'], $users ) && $row['username'] != 'root') { // Something is in the database but not in LDAP. $delete_query = 'DELETE from dspam_virtual_uids WHERE uid = ' . $row['uid'] . ' AND username = "' . $row['username'] . '"'; if ( !mysql_query( $delete_query ) ) die(mysql_error()) ; echo 'User ' . $row['username'] . ' not in LDAP. Deleted.<br/>'; } } } $root_res = mysql_query( 'REPLACE INTO dspam_virtual_uids VALUES ( 0, "root" )' ) or die(mysql_error()) ; } function in_arrayr($needle, $haystack) { foreach ($haystack as $v) { if ($needle == $v) return true; elseif (is_array($v)) { if (in_arrayr($needle, $v) === true) return true; } } return false; } ?>
