[ Index ] |
|
Code source de Horde 3.1.3 |
1 <?php 2 3 require_once 'Horde/Auth/sql.php'; 4 require_once 'Horde/IMAP/Admin.php'; 5 6 /** 7 * The Auth_cyrsql class provides a SQL implementation of the Horde 8 * authentication system for the Cyrus IMAP server. Most of the functionality 9 * is the same as for the SQL class; only what is different overrides the 10 * parent class implementations. 11 * 12 * Required parameters:<pre> 13 * 'cyradmin' The username of the cyrus administrator. 14 * 'cyrpass' The password for the cyrus administrator. 15 * 'imap_dsn' The full IMAP DSN 16 * (i.e. {localhost:993/imap/ssl/novalidate-cert}). 17 * 'phptype' The database type (ie. 'pgsql', 'mysql', etc.).</pre> 18 * 19 * Optional parameters:<pre> 20 * 'domain_field' If set to anything other than 'none' this is used as 21 * field name where domain is stored. 22 * DEFAULT: 'domain_name' 23 * 'encryption' The encryption to use to store the password in the 24 * table (e.g. plain, crypt, md5-hex, md5-base64, smd5, 25 * sha, ssha). 26 * DEFAULT: 'md5-hex' 27 * 'folders' An array of folders to create under username. 28 * DEFAULT: NONE 29 * 'password_field' The name of the password field in the auth table. 30 * DEFAULT: 'password' 31 * 'quota' The quota (in kilobytes) to grant on the mailbox. 32 * DEFAULT: NONE 33 * 'table' The name of the auth table in 'database'. 34 * DEFAULT: 'accountuser' 35 * 'unixhier' The value of imapd.conf's unixhierarchysep setting. 36 * Set this to true if the value is true in imapd.conf. 37 * 'username_field' The name of the username field in the auth table. 38 * DEFAULT: 'username'</pre> 39 * 40 * Required by some database implementations:<pre> 41 * 'database' The name of the database. 42 * 'hostspec' The hostname of the database server. 43 * 'protocol' The communication protocol ('tcp', 'unix', etc.). 44 * 'username' The username with which to connect to the database. 45 * 'password' The password associated with 'username'. 46 * 'options' Additional options to pass to the database. 47 * 'port' The port on which to connect to the database. 48 * 'tty' The TTY on which to connect to the database.</pre> 49 * 50 * 51 * The table structure for the auth system is as follows: 52 * 53 * <pre> 54 * CREATE TABLE accountuser ( 55 * username VARCHAR(255) BINARY NOT NULL DEFAULT '', 56 * password VARCHAR(32) BINARY NOT NULL DEFAULT '', 57 * prefix VARCHAR(50) NOT NULL DEFAULT '', 58 * domain_name VARCHAR(255) NOT NULL DEFAULT '', 59 * UNIQUE KEY username (username) 60 * ); 61 * 62 * CREATE TABLE adminuser ( 63 * username VARCHAR(50) BINARY NOT NULL DEFAULT '', 64 * password VARCHAR(50) BINARY NOT NULL DEFAULT '', 65 * type INT(11) NOT NULL DEFAULT '0', 66 * SID VARCHAR(255) NOT NULL DEFAULT '', 67 * home VARCHAR(255) NOT NULL DEFAULT '', 68 * PRIMARY KEY (username) 69 * ); 70 * 71 * CREATE TABLE alias ( 72 * alias VARCHAR(255) NOT NULL DEFAULT '', 73 * dest LONGTEXT, 74 * username VARCHAR(50) NOT NULL DEFAULT '', 75 * status INT(11) NOT NULL DEFAULT '1', 76 * PRIMARY KEY (alias) 77 * ); 78 * 79 * CREATE TABLE domain ( 80 * domain_name VARCHAR(255) NOT NULL DEFAULT '', 81 * prefix VARCHAR(50) NOT NULL DEFAULT '', 82 * maxaccounts INT(11) NOT NULL DEFAULT '20', 83 * quota INT(10) NOT NULL DEFAULT '20000', 84 * transport VARCHAR(255) NOT NULL DEFAULT 'cyrus', 85 * freenames ENUM('YES','NO') NOT NULL DEFAULT 'NO', 86 * freeaddress ENUM('YES','NO') NOT NULL DEFAULT 'NO', 87 * PRIMARY KEY (domain_name), 88 * UNIQUE KEY prefix (prefix) 89 * ); 90 * 91 * CREATE TABLE domainadmin ( 92 * domain_name VARCHAR(255) NOT NULL DEFAULT '', 93 * adminuser VARCHAR(255) NOT NULL DEFAULT '' 94 * ); 95 * 96 * CREATE TABLE search ( 97 * search_id VARCHAR(255) NOT NULL DEFAULT '', 98 * search_sql TEXT NOT NULL, 99 * perpage INT(11) NOT NULL DEFAULT '0', 100 * timestamp TIMESTAMP(14) NOT NULL, 101 * PRIMARY KEY (search_id), 102 * KEY search_id (search_id) 103 * ); 104 * 105 * CREATE TABLE virtual ( 106 * alias VARCHAR(255) NOT NULL DEFAULT '', 107 * dest LONGTEXT, 108 * username VARCHAR(50) NOT NULL DEFAULT '', 109 * status INT(11) NOT NULL DEFAULT '1', 110 * KEY alias (alias) 111 * ); 112 * 113 * CREATE TABLE log ( 114 * id INT(11) NOT NULL AUTO_INCREMENT, 115 * msg TEXT NOT NULL, 116 * user VARCHAR(255) NOT NULL DEFAULT '', 117 * host VARCHAR(255) NOT NULL DEFAULT '', 118 * time DATETIME NOT NULL DEFAULT '2000-00-00 00:00:00', 119 * pid VARCHAR(255) NOT NULL DEFAULT '', 120 * PRIMARY KEY (id) 121 * ); 122 * </pre> 123 * 124 * $Horde: framework/Auth/Auth/cyrsql.php,v 1.33.10.14 2006/08/14 02:48:48 chuck Exp $ 125 * 126 * Copyright 2002-2006 Ilya <mail@krel.org> 127 * Copyright 2005-2006 Jan Schneider <jan@horde.org> 128 * 129 * See the enclosed file COPYING for license information (LGPL). If you 130 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. 131 * 132 * @author Ilya <mail@krel.org> 133 * @author Jan Schneider <jan@horde.org> 134 * @since Horde 3.0 135 * @package Horde_Auth 136 */ 137 class Auth_cyrsql extends Auth_sql { 138 139 /** 140 * Handle for the current IMAP connection. 141 * 142 * @var resource 143 */ 144 var $_imapStream; 145 146 /** 147 * Handle for an IMAP_Admin object. 148 * 149 * @var IMAP_Admin 150 */ 151 var $_admin; 152 153 /** 154 * Hierarchy separator to use (e.g., is it user/mailbox or user.mailbox) 155 * 156 * @var string 157 */ 158 var $_separator = '.'; 159 160 /** 161 * Constructor. 162 * 163 * @param array $params A hash containing connection parameters. 164 */ 165 function Auth_cyrsql($params = array()) 166 { 167 if (!Util::extensionExists('imap')) { 168 Horde::fatal(_("Auth_cyrsql: Required imap extension not found."), __FILE__, __LINE__); 169 } 170 parent::Auth_sql($params); 171 172 $admin_params = array('admin_user' => $params['cyradmin'], 173 'admin_password' => $params['cyrpass'], 174 'dsn' => $params['imap_dsn']); 175 if (!empty($this->_params['unixhier'])) { 176 $admin_params['userhierarchy'] = 'user/'; 177 } 178 $this->_admin = &new IMAP_Admin($admin_params); 179 } 180 181 /** 182 * Add a set of authentication credentials. 183 * 184 * @param string $userId The userId to add. 185 * @param array $credentials The credentials to add. 186 * 187 * @return mixed True on success or a PEAR_Error object on failure. 188 */ 189 function addUser($userId, $credentials) 190 { 191 $this->_connect(); 192 193 if (!empty($this->_params['domain_field']) && 194 ($this->_params['domain_field'] != 'none')) { 195 list($name, $domain) = explode('@', $userId); 196 /* Build the SQL query. */ 197 $query = sprintf('INSERT INTO %s (%s, %s, %s) VALUES (?, ?, ?)', 198 $this->_params['table'], 199 $this->_params['username_field'], 200 $this->_params['domain_field'], 201 $this->_params['password_field']); 202 $values = array($name, 203 $domain, 204 $this->getCryptedPassword($credentials['password'], 205 '', 206 $this->_params['encryption'], 207 $this->_params['show_encryption'])); 208 209 Horde::logMessage('SQL Query by Auth_cyrsql::addUser(): ' . $query, __FILE__, __LINE__, PEAR_LOG_DEBUG); 210 211 $dbresult = $this->_db->query($query, $values); 212 $query = 'INSERT INTO virtual (alias, dest, username, status) VALUES (?, ?, ?, 1)'; 213 $values = array($userId, $name, $name); 214 215 Horde::logMessage('SQL Query by Auth_cyrsql::addUser(): ' . $query, __FILE__, __LINE__, PEAR_LOG_DEBUG); 216 217 $dbresult2 = $this->_db->query($query, $values); 218 if (is_a($dbresult2, 'PEAR_Error')) { 219 return $dbresult2; 220 } 221 } else { 222 $dbresult = parent::addUser($userId, $credentials); 223 $name = $userId; 224 } 225 if (is_a($dbresult, 'PEAR_Error')) { 226 return $dbresult; 227 } 228 229 if (!is_a($result = $this->_admin->addMailbox($name), 'PEAR_Error')) { 230 @array_walk($this->_params['folders'], 231 array($this, '_createSubFolders'), $name); 232 } else { 233 Horde::logMessage('IMAP mailbox creation for ' . $name . ' failed: ' . $result->getMessage(), 234 __FILE__, __LINE__, PEAR_LOG_ERR); 235 return PEAR::raiseError(sprintf(_("IMAP mailbox creation failed: %s"), $result->getMessage())); 236 } 237 238 if (isset($this->_params['quota']) && $this->_params['quota'] >= 0) { 239 if (!@imap_set_quota($this->_imapStream, 240 'user' . $this->_separator . $name, 241 $this->_params['quota'])) { 242 return PEAR::raiseError(sprintf(_("IMAP mailbox quota creation failed: %s"), imap_last_error())); 243 } 244 } 245 246 return true; 247 } 248 249 /** 250 * Delete a set of authentication credentials. 251 * 252 * @param string $userId The userId to delete. 253 * 254 * @return boolean Success or failure. 255 */ 256 function removeUser($userId) 257 { 258 $this->_connect(); 259 260 if (!empty($this->_params['domain_field']) && 261 ($this->_params['domain_field'] != 'none')) { 262 list($name, $domain) = explode('@', $userId); 263 /* Build the SQL query. */ 264 $query = sprintf('DELETE FROM %s WHERE %s = ? and %s = ?', 265 $this->_params['table'], 266 $this->_params['username_field'], 267 $this->_params['domain_field']); 268 $values = array($name, $domain); 269 270 Horde::logMessage('SQL Query by Auth_cyrsql::removeUser(): ' . $query, __FILE__, __LINE__, PEAR_LOG_DEBUG); 271 272 $dbresult = $this->_db->query($query, $values); 273 $query = 'DELETE FROM virtual WHERE dest = ?'; 274 $values = array($name); 275 276 Horde::logMessage('SQL Query by Auth_cyrsql::removeUser(): ' . $query, __FILE__, __LINE__, PEAR_LOG_DEBUG); 277 278 $dbresult2 = $this->_db->query($query, $values); 279 if (is_a($dbresult2, 'PEAR_Error')) { 280 return $dbresult2; 281 } 282 } else { 283 $dbresult = parent::removeUser($userId); 284 $name = $userId; 285 } 286 287 if (is_a($dbresult, 'PEAR_Error')) { 288 return $dbresult; 289 } 290 291 /* Delete IMAP mailbox. */ 292 $imapresult = $this->_admin->removeMailbox($name); 293 294 if (is_a($imapresult, 'PEAR_Error')) { 295 return PEAR::raiseError(sprintf(_("IMAP mailbox deletion failed: %s"), $imapresult->getMessage())); 296 } 297 298 return $this->removeUserData($userId); 299 } 300 301 /** 302 * Attempts to open connections to the SQL and IMAP servers. 303 * 304 * @access private 305 * 306 * @return mixed True on success or a PEAR_Error object on failure. 307 */ 308 function _connect() 309 { 310 if (!$this->_connected) { 311 parent::_connect(); 312 313 // Reset the $_connected flag; we haven't yet successfully opened 314 // everything. 315 $this->_connected = false; 316 317 $this->_imapStream = @imap_open($this->_params['imap_dsn'], $this->_params['cyradmin'], $this->_params['cyrpass'], OP_HALFOPEN); 318 if (!$this->_imapStream) { 319 Horde::fatal(sprintf(_("Can't connect to IMAP server: %s"), imap_last_error()), __FILE__, __LINE__); 320 } 321 322 if (!empty($this->_params['unixhier'])) { 323 $this->_separator = '/'; 324 } 325 $this->_connected = true; 326 } 327 328 return true; 329 } 330 331 /** 332 * Disconnect from the SQL and IMAP servers and clean up the connections. 333 * 334 * @access private 335 * 336 * @return boolean True on success, false on failure. 337 */ 338 function _disconnect() 339 { 340 if ($this->_connected) { 341 parent::_disconnect(); 342 @imap_close($this->_imapStream); 343 } 344 345 return true; 346 } 347 348 /** 349 * Creates all mailboxes supplied in configuration 350 * 351 * @access private 352 * 353 * @param string $value 354 * @param string $key Unused by this driver 355 * @param string userName 356 */ 357 function _createSubFolders($value, $key, $userName) 358 { 359 if (!empty($this->_params['domain_field']) && 360 ($this->_params['domain_field'] != 'none')) { 361 list($userName) = explode('@', $userName); 362 } 363 $this->_admin->addMailbox($userName . $this->_separator . $value); 364 } 365 366 /** 367 * List all users in the system. 368 * 369 * @return mixed The array of userIds, or false on failure/unsupported. 370 */ 371 function listUsers() 372 { 373 /* _connect() will die with Horde::fatal() upon failure. */ 374 $this->_connect(); 375 376 if (!empty($this->_params['domain_field']) && 377 ($this->_params['domain_field'] != 'none')) { 378 /* Build the SQL query with domain. */ 379 $query = sprintf('SELECT %s, %s FROM %s ORDER BY %s', 380 $this->_params['username_field'], 381 $this->_params['domain_field'], 382 $this->_params['table'], 383 $this->_params['username_field']); 384 } else { 385 /* Build the SQL query without domain. */ 386 $query = sprintf('SELECT %s FROM %s ORDER BY %s', 387 $this->_params['username_field'], 388 $this->_params['table'], 389 $this->_params['username_field']); 390 } 391 392 Horde::logMessage('SQL Query by Auth_cyrsql::listUsers(): ' . $query, __FILE__, __LINE__, PEAR_LOG_DEBUG); 393 394 $result = $this->_db->getAll($query, null, DB_FETCHMODE_ORDERED); 395 if (is_a($result, 'PEAR_Error')) { 396 return $result; 397 } 398 399 /* Loop through and build return array. */ 400 $users = array(); 401 if (!empty($this->_params['domain_field']) && 402 ($this->_params['domain_field'] != 'none')) { 403 foreach ($result as $ar) { 404 $users[] = $ar[0] . '@' . $ar[1]; 405 } 406 } else { 407 foreach ($result as $ar) { 408 $users[] = $ar[0]; 409 } 410 } 411 412 return $users; 413 } 414 415 /** 416 * Update a set of authentication credentials. 417 * 418 * @param string $oldID The old userId. 419 * @param string $newID The new userId. 420 * @param array $credentials The new credentials 421 * 422 * @return mixed True on success or a PEAR_Error object on failure. 423 */ 424 function updateUser($oldID, $newID, $credentials) 425 { 426 /* _connect() will die with Horde::fatal() upon failure. */ 427 $this->_connect(); 428 429 if (!empty($this->_params['domain_field']) && 430 ($this->_params['domain_field'] != 'none')) { 431 list($name, $domain) = explode('@', $oldID); 432 /* Build the SQL query with domain. */ 433 $query = sprintf('UPDATE %s SET %s = ? WHERE %s = ? and %s = ?', 434 $this->_params['table'], 435 $this->_params['password_field'], 436 $this->_params['username_field'], 437 $this->_params['domain_field']); 438 $values = array($this->getCryptedPassword($credentials['password'], 439 '', 440 $this->_params['encryption'], 441 $this->_params['show_encryption']), 442 $name, $domain); 443 } else { 444 /* Build the SQL query. */ 445 $query = sprintf('UPDATE %s SET %s = ? WHERE %s = ?', 446 $this->_params['table'], 447 $this->_params['password_field'], 448 $this->_params['username_field']); 449 $values = array($this->getCryptedPassword($credentials['password'], 450 '', 451 $this->_params['encryption'], 452 $this->_params['show_encryption']), 453 $oldID); 454 } 455 456 Horde::logMessage('SQL Query by Auth_cyrsql::updateUser(): ' . $query, __FILE__, __LINE__, PEAR_LOG_DEBUG); 457 458 return $this->_db->query($query, $values); 459 } 460 461 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |