-
The Great Git Migration authoredThe Great Git Migration authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
zimbra.module 14.49 KiB
<?php
/**
* @file
* Implements Zimbra e-mail accounts provisioning.
*/
//////////////////////////////////////////////////////////////////////////////
define('ZIMBRA_ENABLED', variable_get('zimbra_enabled', FALSE));
define('ZIMBRA_SOAP_URL', variable_get('zimbra_soap_url', ''));
define('ZIMBRA_DOMAIN', variable_get('zimbra_domain', ''));
define('ZIMBRA_NAME', variable_get('zimbra_name', ''));
define('ZIMBRA_PASS', variable_get('zimbra_pass', ''));
define('ZIMBRA_PASS_CLEAR', variable_get('zimbra_pass_clear', 0));
define('ZIMBRA_TIMEOUT', variable_get('zimbra_timeout', 10));
define('ZIMBRA_USER_PASS', variable_get('zimbra_user_pass', TRUE));
define('ZIMBRA_PROFILE', 'Zimbra e-mail account');
define('ZIMBRA_PROFILE_WEIGHT', 5);
define('ZIMBRA_BATCH_LIMIT', 10);
define('ZIMBRA_SUSPENSION_ENABLED', variable_get('zimbra_suspension_enabled', FALSE));
define('ZIMBRA_STATUS_ACTIVE', 'active');
define('ZIMBRA_STATUS_CLOSED', 'closed');
define('ZIMBRA_STATUS_LOCKED', 'locked');
define('ZIMBRA_STATUS_MAINTENANCE', 'maintenance');
define('ZIMBRA_SUSPENSION_STATUS', variable_get('zimbra_suspension_status', ZIMBRA_STATUS_CLOSED));
define('ZIMBRA_DEFAULT_USER_PASS_STRENGTH', 12);
define('ZIMBRA_CURLOPT_SSL_VERIFYPEER', FALSE);
define('ZIMBRA_CURLOPT_SSL_VERIFYHOST', FALSE);
//////////////////////////////////////////////////////////////////////////////
// Core API hooks
/**
* Implementation of hook_menu().
*/
function zimbra_menu() {
return array(
'admin/settings/zimbra' => array(
'title' => 'Zimbra',
'description' => 'Configure Zimbra Provisioning settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array('zimbra_admin_settings'),
'access arguments' => array('administer site configuration'),
'file' => 'zimbra.admin.inc',
),
'admin/settings/zimbra/configure' => array(
'title' => 'Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
),
'admin/settings/zimbra/create' => array(
'title' => 'Create',
'description' => 'Create Zimbra e-mail accounts for all existing users.',
'type' => MENU_LOCAL_TASK,
'page callback' => 'drupal_get_form',
'page arguments' => array('zimbra_admin'),
'access arguments' => array('administer site configuration'),
'weight' => 1,
),
'zimbra/create/%user' => array(
'title' => 'Create',
'description' => 'Create Zimbra e-mail account.',
'type' => MENU_CALLBACK,
'page callback' => 'zimbra_create_account',
'page arguments' => array(2),
'access arguments' => array('administer users'),
),
);
}
/**
* Implementation of hook_init().
*/
function zimbra_init() {
require_once drupal_get_path('module', 'zimbra') .'/zimbra.inc';
}
/**
* Implementation of hook_user().
*/
function zimbra_user($op, &$edit, &$account, $category = NULL) {
if (ZIMBRA_ENABLED && _zimbra_user_check($account)) {
switch ($op) {
case 'view':
if (user_access('administer users')) {
$zimbra = new ZimbraSoapClient(ZIMBRA_SOAP_URL);
if (zimbra_login($zimbra)) {
$id = zimbra_get_id($zimbra, $account->name);
$account->content[t(LDAPAUTH_PROFILE)] = array(
'#type' => 'user_profile_category',
'#title' => t(ZIMBRA_PROFILE),
'#attributes' => array('class' => 'zimbra-entry'),
'#weight' => ZIMBRA_PROFILE_WEIGHT,
'zimbra_id' => array('#type' => 'user_profile_item', '#title' => t('ID'), '#value' => $id ? $id : l(t('create'), 'zimbra/create/'. $account->uid, array('query' => drupal_get_destination())), '#weight' => 1),
);
}
}
break;
case 'insert':
$zimbra = new ZimbraSoapClient(ZIMBRA_SOAP_URL);
if (zimbra_login($zimbra)) {
_zimbra_create_account($zimbra, $edit['name'], ZIMBRA_USER_PASS ? $edit['pass'] : user_password(ZIMBRA_DEFAULT_USER_PASS_STRENGTH));
}
break;
case 'delete':
$zimbra = new ZimbraSoapClient(ZIMBRA_SOAP_URL);
if (zimbra_login($zimbra) && ($id = zimbra_get_id($zimbra, $account->name)) && ($result = zimbra_delete($zimbra, $id, $account->name))) {
watchdog('zimbra', 'Zimbra account for %name was deleted.', array('%name' => $account->name));
}
else if (!isset($result) || $result === FALSE) {
watchdog('zimbra', 'Zimbra account for %name was not deleted.', array('%name' => $account->name), WATCHDOG_ERROR);
drupal_set_message(t('Zimbra e-mail account for %name was not deleted. Please contact site administrator.', array('%name' => $account->name)), 'error');
}
break;
case 'submit':
if (isset($edit['name']) && $account->name != $edit['name'] && $account->uid > 1) {
$zimbra = new ZimbraSoapClient(ZIMBRA_SOAP_URL);
if (zimbra_login($zimbra) && ($id = zimbra_get_id($zimbra, $account->name)) && ($result = zimbra_rename($zimbra, $id, $account->name, $edit['name']))) {
watchdog('zimbra', 'Zimbra account for %name was renamed to %name_new.', array('%name' => $account->name, '%name_new' => $edit['name']));
}
else if (!isset($result) || $result === FALSE) {
watchdog('zimbra', 'Zimbra account for %name was not renamed to %name_new.', array('%name' => $account->name, '%name_new' => $edit['name']), WATCHDOG_ERROR);
drupal_set_message(t('Zimbra e-mail account for %name was not renamed to %name_new. Please contact site administrator.', array('%name' => $account->name, '%name_new' => $edit['name'])), 'error');
}
}
if (ZIMBRA_USER_PASS && !empty($edit['pass']) && $account->uid > 1) {
$zimbra = new ZimbraSoapClient(ZIMBRA_SOAP_URL);
if (zimbra_login($zimbra) && ($id = zimbra_get_id($zimbra, $account->name)) && ($result = zimbra_set_pass($zimbra, $id, $account->name, $edit['pass']))) {
watchdog('zimbra', 'Zimbra account password for %name was set.', array('%name' => $account->name));
}
else if (!isset($result) || $result === FALSE) {
watchdog('zimbra', 'Zimbra account password for %name was not set.', array('%name' => $account->name), WATCHDOG_ERROR);
drupal_set_message(t('Zimbra e-mail account password for %name was not set. Please contact site administrator.', array('%name' => $account->name)), 'error');
}
}
break;
case 'update':
if (ZIMBRA_SUSPENSION_ENABLED && isset($edit['status']) && $edit['status'] != $account->status) {
$status = $edit['status'] == 1 ? ZIMBRA_STATUS_ACTIVE : ZIMBRA_SUSPENSION_STATUS;
$zimbra = new ZimbraSoapClient(ZIMBRA_SOAP_URL);
if (zimbra_login($zimbra) && ($id = zimbra_get_id($zimbra, $account->name)) && ($result = zimbra_change_status($zimbra, $id, $status))) {
watchdog('zimbra', 'Zimbra account status for %name has been changed to %status.', array('%name' => $account->name, '%status' => $status));
}
else if (!isset($result) || $result === FALSE) {
watchdog('zimbra', 'Zimbra account status for %name has not been changed to %status.', array('%name' => $account->name, '%status' => $status), WATCHDOG_ERROR);
drupal_set_message(t('Zimbra e-mail account status for %name has not been changed to %status. Please contact site administrator.', array('%name' => $account->name, '%status' => $status)), 'error');
}
}
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////
// Menu callback functions
/**
* Zimbra admin form.
*/
function zimbra_admin() {
$form['zimbra'] = array(
'#type' => 'fieldset',
'#title' => t('Create zimbra accounts'),
'#description' => t('Create Zimbra e-mail accounts for all existing users.'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['zimbra']['submit'] = array(
'#type' => 'submit',
'#value' => t('Create'),
);
return $form;
}
/**
* Zimbra admin form submit.
*/
function zimbra_admin_submit($form, &$form_state) {
$batch = array(
'operations' => array(
array('zimbra_account_create_batch_process', array()),
),
'finished' => 'zimbra_account_create_batch_finished',
'title' => t('Processing zimbra account creation'),
'init_message' => t('Zimbra account creation is starting.'),
'progress_message' => t('Processing...'),
'error_message' => t('Zimbra account creation has encountered an error.'),
);
batch_set($batch);
}
/**
* Batch Operation Callback.
*/
function zimbra_account_create_batch_process(&$context) {
if (!isset($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['max'] = db_result(db_query('SELECT COUNT(uid) FROM {users} WHERE uid > 1'));
$context['sandbox']['current_uid'] = 1;
}
$zimbra = new ZimbraSoapClient(ZIMBRA_SOAP_URL);
if (zimbra_login($zimbra)) {
$result = db_query_range("SELECT uid FROM {users} WHERE uid > %d ORDER BY uid ASC", $context['sandbox']['current_uid'], 0, ZIMBRA_BATCH_LIMIT);
while ($row = db_fetch_array($result)) {
$account = user_load($row['uid']);
$context['sandbox']['progress']++;
$context['sandbox']['current_uid'] = $account->uid;
$context['message'] = t('Inspecting %name.', array('%name' => $account->name));
unset($created);
if (_zimbra_user_check($account) && ($created = zimbra_create($zimbra, $account->name, user_password(ZIMBRA_DEFAULT_USER_PASS_STRENGTH)))) {
$context['results'][] = theme('username', $account);
watchdog('zimbra', 'A new zimbra account for %name was created.', array('%name' => $account->name), WATCHDOG_ERROR);
}
else if ($created === FALSE) {
watchdog('zimbra', 'A new zimbra account for %name was not created.', array('%name' => $account->name), WATCHDOG_ERROR);
}
}
}
else {
$context['sandbox']['progress'] = $context['sandbox']['max'];
drupal_set_message(t('Cannot login to the Zimbra server.'), 'error');
}
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
/**
* Batch 'finished' callback.
*/
function zimbra_account_create_batch_finished($success, $results, $operations) {
if ($success) {
if (!empty($results)) {
drupal_set_message(t('Zimbra accounts were created for following users.') . theme('item_list', $results));
}
else {
drupal_set_message(t('No new zimbra accounts were created.'));
}
}
else {
$error_operation = reset($operations);
drupal_set_message(t('An error occurred while processing %error. Please contact site administrator.', array('%error' => $error_operation[0])), 'error');
}
}
/**
* Menu callback.
*/
function zimbra_create_account($account) {
$zimbra = new ZimbraSoapClient(ZIMBRA_SOAP_URL);
if (zimbra_login($zimbra) && _zimbra_create_account($zimbra, $account->name)) {
drupal_set_message(t('A new zimbra e-mail account for %name was created.', array('%name' => $name)));
}
drupal_goto();
}
/**
* Creates Zimbra account.
*/
function _zimbra_create_account(&$zimbra, $name, $pass = NULL) {
$pass = isset($pass) ? $pass : user_password(ZIMBRA_DEFAULT_USER_PASS_STRENGTH);
if ($result = zimbra_create($zimbra, $name, $pass)) {
watchdog('zimbra', 'A new zimbra account was created for %name.', array('%name' => $name));
}
else if ($result === FALSE) {
watchdog('zimbra', 'A new zimbra account for %name was not created.', array('%name' => $name), WATCHDOG_ERROR);
drupal_set_message(t('A new zimbra e-mail account for %name was not created.', array('%name' => $name)), 'error');
}
return $result;
}
//////////////////////////////////////////////////////////////////////////////
// Zimbra API functions
/**
* Login to zimbra.
*/
function zimbra_login(&$zimbra) {
return $zimbra->login(ZIMBRA_NAME, ZIMBRA_PASS);
}
/**
* Creates zimbra account.
*
* Returns TRUE if account was created, FALSE if failed and NULL if the account already existed.
*/
function zimbra_create(&$zimbra, $name, $pass) {
if ($result = $zimbra->execute('CreateAccountRequest', array('name' => array('value' => $name .'@'. ZIMBRA_DOMAIN), 'password' => array('value' => $pass)))) {
return TRUE;
}
else if (($notice_strings = _zimbra_notice_strings()) && preg_match($notice_strings['CreateAccountRequest'], $zimbra->error())) {
return;
}
else {
return FALSE;
}
}
/**
* Get zimbra account id.
*/
function zimbra_get_id(&$zimbra, $name) {
$result = $zimbra->execute('GetAccountInfoRequest', array('account' => array('value' => $name .'@'. ZIMBRA_DOMAIN, 'attr' => array('by' => 'name'))));
if ($result) {
return $result['a'][0];
}
else {
watchdog('zimbra', 'Zimbra account information for %name is not available.', array('%name' => $name), WATCHDOG_ERROR);
return FALSE;
}
}
/**
* Delete zimbra account.
*/
function zimbra_delete(&$zimbra, $id, $name) {
return $zimbra->execute('DeleteAccountRequest', array('id' => array('value' => $id)));
}
/**
* Rename zimbra account.
*/
function zimbra_rename(&$zimbra, $id, $name, $name_new) {
return $zimbra->execute('RenameAccountRequest', array('id' => array('value' => $id), 'newName' => array('value' => $name_new .'@'. ZIMBRA_DOMAIN)));
}
/**
* Set zimbra password.
*/
function zimbra_set_pass(&$zimbra, $id, $name, $pass) {
return $zimbra->execute('SetPasswordRequest', array('id' => array('value' => $id), 'newPassword' => array('value' => $pass)));
}
/**
* Change zimbra status.
*/
function zimbra_change_status(&$zimbra, $id, $status) {
return $zimbra->execute('ModifyAccountRequest', array('id' => array('value' => $id), 'a' => array('value' => $status, 'attr' => array('n' => 'zimbraAccountStatus'))));;
}
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
/**
* This function returns array of zimbra functions and error matching strings.
* If string is matched, notice is logged instead of the error.
*/
function _zimbra_notice_strings() {
return array('CreateAccountRequest' => '/^email address already exists: /');
}
/**
* Checks if a Zimbra account should be created for this user.
*/
function _zimbra_user_check(&$account) {
if (!isset($account->uid))
return FALSE;
$module = db_result(db_query('SELECT module FROM {authmap} WHERE uid = %d', $account->uid));
$module = !empty($module) ? $module : 'local';
return in_array($module, variable_get('zimbra_auth_modules', array('local' => 'local')), TRUE);
}