sam + ldap patch
Neil Sequeira <[email protected]> Wed, 17 Sep 2003 22:54:37 -0400
| Newsgroups | gmane.comp.horde.sam |
|---|---|
| Organization | NCS Consulting Inc. |
| Message-ID | <[email protected]> |
Here's a start at an LDAP backend for sam. It needs the spamassassin ldap patch at http://bugzilla.spamassassin.org/show_bug.cgi?id=2205 to be of any use. Right now the user needs to be able to modify the spamassassin attribute of their ldap record (there's no 'rootdn' setting) and defaults are configured inside the backend parameters. It's more-or-less a hack of spamd_sql but so far it seems get the job done. -neil -- sam mailing list Frequently Asked Questions: http://horde.org/faq/ To unsubscribe, mail: [email protected]
sam.ldap.patch
(text/x-diff, 8.6 KB)
diff -ru -N sam/config/backends.php.dist sam.new/config/backends.php.dist
--- sam/config/backends.php.dist 2003-09-06 13:53:24.000000000 -0400
+++ sam.new/config/backends.php.dist 2003-09-17 22:37:48.000000000 -0400
@@ -121,3 +121,49 @@
),
),
);
+
+/* SpamAssassin LDAP storage example. */
+$backends['spamd_ldap'] = array(
+ 'preferred' => '',
+ 'hordeauth' => true,
+ 'driver' => 'spamd_ldap',
+ 'params' => array(
+ 'ldapserver' => 'localhost',
+ 'basedn' => 'ou=users,dc=example,dc=com',
+ 'attribute' => 'spamassassinConfig',
+ 'uid' => 'uid',
+ 'option_map' => array(
+ 'hit_level' => 'required_hits',
+ 'subject_tag' => 'subject_tag',
+ 'rewrite_sub' => 'rewrite_subject',
+ 'level_stars' => 'spam_level_stars',
+ 'report_header' => 'report_header',
+ 'terse_report' => 'use_terse_report',
+ 'defang_mime' => 'defang_mime',
+ 'skip_rbl' => 'skip_rbl_checks',
+ ),
+ 'defaults' => array(
+ 'hit_level' => '5',
+ 'subject_tag' => '***SPAM***',
+ 'rewrite_sub' => 1,
+ 'level_stars' => 1,
+ 'report_header' => 0,
+ 'terse_report' => 1,
+ 'defang_mime' => 1,
+ 'skip_rbl' => 1,
+ ),
+ 'capabilities' => array(
+ 'hit_level',
+ 'report_header',
+ 'rewrite_sub',
+ 'subject_tag',
+ 'level_stars',
+ 'defang_mime',
+ 'whitelist_to',
+ 'whitelist_from',
+ 'blacklist_to',
+ 'blacklist_from',
+ 'skip_rbl'
+ ),
+ ),
+);
diff -ru -N sam/lib/Driver/spamd_ldap.php sam.new/lib/Driver/spamd_ldap.php
--- sam/lib/Driver/spamd_ldap.php 1969-12-31 19:00:00.000000000 -0500
+++ sam.new/lib/Driver/spamd_ldap.php 2003-09-17 22:35:56.000000000 -0400
@@ -0,0 +1,221 @@
+<?php
+/**
+ * SAM storage implementation for LDAP backend - based on spamd_sql.php.
+ * Requires SpamAssassin patch found at: http://bugzilla.spamassassin.org/show_bug.cgi?id=2205
+ *
+ * Required parameters:
+ * ====================
+ * 'ldapserver' -- The hostname of the ldap server.
+ * 'basedn' -- The password associated with 'username'.
+ * 'attribute' -- The database type (ie. 'pgsql', 'mysql, etc.).
+ * 'uid' -- The communication protocol ('tcp', 'unix', etc.).
+ *
+ */
+
+class SAM_Driver_spamd_ldap extends SAM_Driver {
+
+ /**
+ * Handle for the current database connection.
+ *
+ * @var object DB $_db
+ */
+ var $_linkid;
+
+ /**
+ * Boolean indicating whether or not we're connected to the SQL server.
+ *
+ * @var boolean $_connected
+ */
+ var $_connected = false;
+
+ /**
+ * List of the capabilities supported by this driver.
+ *
+ * @var array $_capabilities
+ */
+/*
+ var $_capabilities = array('hit_level',
+ 'report_header',
+ 'rewrite_sub',
+ 'subject_tag',
+ 'level_stars',
+ 'defang_mime',
+ 'whitelist_to',
+ 'whitelist_from',
+ 'blacklist_to',
+ 'blacklist_from',
+ 'skip_rbl');
+*/
+ /**
+ * Constructs a new SQL storage object.
+ *
+ * @access public
+ *
+ * @param string $user The user who owns these SPAM options.
+ * @param optional array $params A hash containing connection
+ * parameters.
+ */
+ function SAM_Driver_spamd_ldap($user, $params = array())
+ {
+ $this->_user = $user;
+ $this->_params = $params;
+ $this->_capabilities = $params['capabilities'];
+ }
+
+ /**
+ * Converts a SAM attribute to an option that SpamAssassin will use.
+ *
+ * @access private
+ *
+ * @param string $attribute The SAM attribute to convert.
+ *
+ * @return string The converted SpamAssassin option or the original
+ * attribute if no match is found.
+ */
+ function _mapAttributeToOption($attribute)
+ {
+ return isset($this->_params['option_map'][$attribute])
+ ? $this->_params['option_map'][$attribute] : $attribute;
+ }
+
+ /**
+ * Converts a SpamAssassin option to a SAM attribute.
+ *
+ * @access private
+ *
+ * @param string $option The SpamAssassin option to convert.
+ *
+ * @return string The converted SAM attribute or the original option if
+ * no match is found.
+ */
+ function _mapOptionToAttribute($option)
+ {
+ $attribute_map = array();
+ if (isset($this->_params['option_map'])) {
+ $attribute_map = array_flip($this->_params['option_map']);
+ }
+
+ return isset($attribute_map[$option])
+ ? $attribute_map[$option] : $option;
+ }
+
+ /**
+ * Retrieve an option set from the storage backend.
+ *
+ * @access private
+ *
+ * @return mixed Array of option-value pairs or a PEAR_Error object
+ * on failure.
+ */
+ function retrieve()
+ {
+ /* Make sure we have a valid database connection. */
+ $this->_connect();
+ /* set default values */
+ $this->_setDefaults();
+ $eres=false;
+ $user=$this->_user;
+ $attrib=strtolower($this->_params['attribute']);
+ $filter="(".$this->_params['uid']."=$user)";
+ $res=ldap_search($this->_linkid, $this->_params['basedn'], $filter, array($attrib));
+ if ($res) $eres=ldap_get_entries($this->_linkid, $res);
+ if ($eres && isset($eres[0][$attrib])) {
+ for ($i=0;$i<$eres[0][$attrib]['count'];$i++) {
+ list($a,$v)=explode(" ", $eres[0][$attrib][$i]);
+ $ra=$this->_mapOptionToAttribute($a);
+ if (is_numeric($v))
+ $this->_options[$ra]=(int) $v;
+ else
+ $this->_options[$ra]=$v;
+ }
+ }
+ }
+
+ /**
+ * Set default values
+ *
+ * @access private
+ *
+ */
+ function _setDefaults()
+ {
+ $defaults=$this->_params['defaults'];
+ foreach($defaults as $a => $v) {
+ $this->_options[$a]=$v;
+ }
+ }
+
+
+ /**
+ * Store an option set in the storage backend.
+ *
+ * @access private
+ *
+ * @return boolean True on success or false on failure.
+ */
+ function store()
+ {
+ /* Make sure we have a valid database connection. */
+ if (!$this->_connect()) return false;
+ $user=$this->_user;
+ $attrib=$this->_params['attribute'];
+ $userdn=$this->_params['uid']."=$user,".$this->_params['basedn'];
+ $store=$this->_options;
+ foreach($store as $a => $v) {
+ $sa=$this->_mapAttributeToOption($a);
+ if (is_array($v)) {
+ foreach($v as $av)
+ $entry[$attrib][]="$sa $av";
+ } else
+ $entry[$attrib][]="$sa $v";
+ }
+ return (ldap_modify($this->_linkid, $userdn, $entry));
+ }
+
+ /**
+ * Attempts to open a connection to the LDAP server.
+ *
+ * @access private
+ *
+ * @return boolean True on success or false on failure.
+ */
+ function _connect()
+ {
+ if ($this->_connected) return true;
+ $bindpass=Auth::getCredential('password');
+ $user=$this->_user;
+ $binddn=$this->_params['uid']."=$user,".$this->_params['basedn'];
+ Horde::assertDriverConfig($this->_params, 'spamd_ldap',
+ array('ldapserver', 'basedn', 'attribute', 'uid'),
+ 'SAM backend', 'backends.php', '$backends');
+ for ($tries=3;$tries > 0;$tries--) { /* try three times */
+ $lc = ldap_connect($this->_params['ldapserver']);
+ if ($lc) {
+ $lb = ldap_bind($lc, $binddn, $bindpass);
+ if ($lb) {
+ $this->_linkid=$lc;
+ $this->connected=true;
+ return true;
+ } else {
+ ldap_unbind($lc);
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Disconnect from the LDAP server and clean up the connection.
+ *
+ * @return boolean True on success, false on failure.
+ */
+ function _disconnect()
+ {
+ if ($this->_connected) {
+ $this->_connected = false;
+ return ldap_unbind($this->_linkid);
+ }
+ return true;
+ }
+
+}