1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
12: class Ingo_Transport_Ldap extends Ingo_Transport
13: {
14: 15: 16: 17: 18:
19: public function __construct($params = array())
20: {
21: if (!Horde_Util::extensionExists('ldap')) {
22: throw new Ingo_Exception(_("LDAP support is required but the LDAP module is not available or not loaded."));
23: }
24:
25: $default_params = array(
26: 'hostspec' => 'localhost',
27: 'port' => 389,
28: 'script_attribute' => 'mailSieveRuleSource'
29: );
30:
31: parent::__construct(array_merge($default_params, $params));
32: }
33:
34: 35: 36: 37: 38: 39: 40: 41: 42:
43: protected function _substUser($templ)
44: {
45: $domain = '';
46: $username = $this->_params['username'];
47:
48: if (strpos($username, '@') !== false) {
49: list($username, $domain) = explode('@', $username);
50: }
51: $domain = implode(', dc=', explode('.', $domain));
52: if (!empty($domain)) {
53: $domain = 'dc=' . $domain;
54: }
55:
56: if (preg_match('/^\s|\s$|\s\s|[,+="\r\n<>#;]/', $username)) {
57: $username = '"' . str_replace('"', '\\"', $username) . '"';
58: }
59:
60: return str_replace(array('%u', '%d'),
61: array($username, $domain),
62: $templ);
63: }
64:
65: 66: 67: 68: 69:
70: protected function _connect()
71: {
72: if (!($ldapcn = @ldap_connect($this->_params['hostspec'],
73: $this->_params['port']))) {
74: throw new Ingo_Exception(_("Connection failure"));
75: }
76:
77:
78: if (!empty($this->_params['version'])) {
79: @ldap_set_option($ldapcn,
80: LDAP_OPT_PROTOCOL_VERSION,
81: $this->_params['version']);
82: }
83:
84:
85: if (!empty($this->_params['tls']) &&
86: !@ldap_start_tls($ldapcn)) {
87: throw new Ingo_Exception(sprintf(_("STARTTLS failed: (%s) %s"),
88: ldap_errno($ldapcn),
89: ldap_error($ldapcn)));
90: }
91:
92:
93: if (isset($this->_params['bind_dn'])) {
94: $bind_dn = $this->_substUser($this->_params['bind_dn']);
95:
96: $password = isset($this->_params['bind_password'])
97: ? $this->_params['bind_password']
98: : $this->_params['password'];
99:
100: $bind_success = @ldap_bind($ldapcn, $bind_dn, $password);
101: } else {
102: $bind_success = @ldap_bind($ldapcn);
103: }
104:
105: if ($bind_success) {
106: return $ldapcn;
107: }
108:
109:
110: throw new Ingo_Exception(sprintf(_("Bind failed: (%s) %s"),
111: ldap_errno($ldapcn),
112: ldap_error($ldapcn)));
113: }
114:
115: 116: 117: 118: 119: 120: 121: 122: 123:
124: protected function _getScripts($ldapcn, &$userDN)
125: {
126: $attrs = array($this->_params['script_attribute'], 'dn');
127: $filter = $this->_substUser($this->_params['script_filter']);
128:
129:
130: $sr = @ldap_search($ldapcn, $this->_params['script_base'], $filter,
131: $attrs);
132: if ($sr === false) {
133: throw new Ingo_Exception(sprintf(_("Error retrieving current script: (%d) %s"),
134: ldap_errno($ldapcn),
135: ldap_error($ldapcn)));
136: }
137:
138: if (@ldap_count_entries($ldapcn, $sr) != 1) {
139: throw new Ingo_Exception(sprintf(_("Expected 1 object, got %d."),
140: ldap_count_entries($ldapcn, $sr)));
141: }
142:
143: $ent = @ldap_first_entry($ldapcn, $sr);
144: if ($ent === false) {
145: throw new Ingo_Exception(sprintf(_("Error retrieving current script: (%d) %s"),
146: ldap_errno($ldapcn),
147: ldap_error($ldapcn)));
148: }
149:
150:
151: $v = @ldap_get_dn($ldapcn, $ent);
152: if ($v === false) {
153: @ldap_free_result($sr);
154: throw new Ingo_Exception(sprintf(_("Error retrieving current script: (%d) %s"),
155: ldap_errno($ldapcn),
156: ldap_error($ldapcn)));
157: }
158: $userDN = $v;
159:
160:
161: $attrs = @ldap_get_attributes($ldapcn, $ent);
162: @ldap_free_result($sr);
163: if ($attrs === false) {
164: throw new Ingo_Exception(sprintf(_("Error retrieving current script: (%d) %s"),
165: ldap_errno($ldapcn),
166: ldap_error($ldapcn)));
167: }
168:
169: 170:
171: $regexp = '/^' . preg_quote($this->_params['script_attribute'], '/') .
172: '(?:;.*)?$/i';
173: unset($attrs['count']);
174: foreach ($attrs as $name => $values) {
175: if (preg_match($regexp, $name)) {
176: unset($values['count']);
177: return array_values($values);
178: }
179: }
180:
181: return array();
182: }
183:
184: 185: 186: 187: 188: 189: 190: 191: 192: 193:
194: protected function setScriptActive($script, $additional = array())
195: {
196: $ldapcn = $this->_connect();
197: $values = $this->_getScripts($ldapcn, $userDN);
198:
199: $found = false;
200: foreach ($values as $i => $value) {
201: if (strpos($value, "# Sieve Filter\n") !== false) {
202: if (empty($script)) {
203: unset($values[$i]);
204: } else {
205: $values[$i] = $script;
206: }
207: $found = true;
208: break;
209: }
210: }
211:
212: if (!$found && !empty($script)) {
213: $values[] = $script;
214: }
215:
216: $replace = array(Horde_String::lower($this->_params['script_attribute']) => $values);
217: $r = empty($values)
218: ? @ldap_mod_del($ldapcn, $userDN, $replace)
219: : @ldap_mod_replace($ldapcn, $userDN, $replace);
220:
221: if (!$r) {
222: throw new Ingo_Exception(sprintf(_("Activating the script for \"%s\" failed: (%d) %s"),
223: $userDN,
224: ldap_errno($ldapcn),
225: ldap_error($ldapcn)));
226: }
227:
228: @ldap_close($ldapcn);
229: }
230:
231: 232: 233: 234: 235: 236: 237:
238: public function getScript()
239: {
240: $ldapcn = $this->_connect();
241: $values = $this->_getScripts($ldapcn, $userDN);
242:
243: $script = '';
244: foreach ($values as $value) {
245: if (strpos($value, "# Sieve Filter\n") !== false) {
246: $script = $value;
247: break;
248: }
249: }
250:
251: @ldap_close($ldapcn);
252: return $script;
253: }
254:
255: }
256: