1: <?php
2: /**
3: * Sam storage implementation for LDAP backend.
4:
5: * Requires SpamAssassin patch found at:
6: * http://bugzilla.spamassassin.org/show_bug.cgi?id=2205
7: *
8: * Copyright 2003-2012 Horde LLC (http://www.horde.org/)
9: *
10: * See the enclosed file COPYING for license information (GPL). If you
11: * did not receive this file, see http://www.horde.org/licenses/gpl.
12: *
13: * @author Chris Bowlby <cbowlby@tenthpowertech.com>
14: * @author Max Kalika <max@horde.org>
15: * @author Neil Sequeira <neil@ncsconsulting.com>
16: * @author Jan Schneider <jan@horde.org>
17: * @package Sam
18: */
19: class Sam_Driver_Spamd_Ldap extends Sam_Driver_Spamd_Base
20: {
21: /**
22: * Handle for the current LDAP connection.
23: *
24: * @var Horde_Ldap
25: */
26: protected $_ldap;
27:
28: /**
29: * Constructor.
30: *
31: * @param string $user A user name.
32: * @param array $params Class parameters:
33: * - ldap: (Horde_Ldap) An LDAP handle pointing to
34: * the directory server.
35: * - uid: (string) The user ID attribute name.
36: * - basedn: (string) The base DN.
37: * - attribute: (string) The storage attribute.
38: */
39: public function __construct($user, $params = array())
40: {
41: foreach (array('ldap', 'uid', 'basedn', 'attribute', 'defaults') as $param) {
42: if (!isset($params[$param])) {
43: throw new InvalidArgumentException(
44: sprintf('"%s" parameter is missing', $param));
45: }
46: }
47:
48: $this->_ldap = $params['ldap'];
49: $this->_options = $params['defaults'];
50: unset($params['ldap'], $params['defaults']);
51:
52: parent::__construct($user, $params);
53: }
54:
55: /**
56: * Retrieves user preferences from the backend.
57: *
58: * @throws Sam_Exception
59: */
60: public function retrieve()
61: {
62: $attrib = Horde_String::lower($this->_params['attribute']);
63:
64: try {
65: $search = $this->_ldap->search(
66: $this->_params['basedn'],
67: Horde_Ldap_Filter::create($this->_params['uid'], 'equals', $this->_user),
68: array('attributes' => array($attrib)));
69:
70: $entry = $search->shiftEntry();
71: if (!$entry) {
72: throw new Sam_Exception(sprintf('LDAP user "%s" not found.', $this->_user));
73: }
74:
75: foreach ($entry->getValue($attrib, 'all') as $attribute) {
76: list($a, $v) = explode(' ', $attribute);
77: $ra = $this->_mapOptionToAttribute($a);
78: if (is_numeric($v)) {
79: if (strstr($v, '.')) {
80: $newoptions[$ra][] = (float)$v;
81: } else {
82: $newoptions[$ra][] = (int)$v;
83: }
84: } else {
85: $newoptions[$ra][] = $v;
86: }
87: }
88: } catch (Horde_Ldap_Exception $e) {
89: throw new Sam_Exception($e);
90: }
91:
92: /* Go through new options and pull single values out of their
93: * arrays. */
94: foreach ($newoptions as $k => $v) {
95: if (count($v) > 1) {
96: $this->_options[$k] = $v;
97: } else {
98: $this->_options[$k] = $v[0];
99: }
100: }
101: }
102:
103: /**
104: * Stores user preferences in the backend.
105: *
106: * @param boolean $defaults Whether to store the global defaults instead
107: * of user options. Unused.
108: *
109: * @throws Sam_Exception
110: */
111: public function store($defaults = false)
112: {
113: $entry = array();
114: foreach ($this->_options as $a => $v) {
115: $sa = $this->_mapAttributeToOption($a);
116: if (is_array($v)) {
117: foreach ($v as $av) {
118: $entry[] = $sa . ' ' . $av;
119: }
120: } else {
121: $entry[] = $sa . ' ' . $v;
122: }
123: }
124:
125: $userdn = sprintf('%s=%s,%s',
126: $this->_params['uid'],
127: $this->_user,
128: $this->_params['basedn']);
129: try {
130: $this->_ldap->modify(
131: $userdn,
132: array('replace' => array($this->_params['attribute'] => $entry)));
133: } catch (Horde_Ldap_Exception $e) {
134: throw new Sam_Exception($e);
135: }
136: }
137: }
138: