#!/usr/local/bin/php -c/usr/local/directadmin/scripts/php_clean.ini 1: an error worthy or reporting has occured. Message on stderr. 1: an error, most likely due to not actually having RoundCube installed or no restore data, has occured. */ /*********************** * Environmental variables */ $domain = getenv("domain"); //for security reasons, it must match the XML values. $system_username = getenv("username"); //only this account is allowed to be restored. $xml_file = getenv("xml_file"); //Name of the file to restore. /*********************** * Enabling debug lets you see which Email is seen, * and what values are being restored, and shows you their respective IDs (found or set) * Keep this set to FALSE if the dataksq is calling it, so as to not fill the stdin buffer (dataskq only reads from stderr for this script) */ $is_debug = FALSE; /*********************** * this restores as da_admin instead of da_roundube. It is less secure, avoid using it if possible. */ $high_access_connection = FALSE; /*********************** * is the host value set within the da_roundcube.users table. */ $rc_mail_host = 'localhost'; /*********************** * If $high_access_restore is false, this is used for the mysql credentials. */ $rc_config = "/var/www/html/roundcube/config/config.inc.php"; //**************************************************************** //**************************************************************** if (!isset($xml_file) || $xml_file == "") show_help(); if (!isset($domain) || $domain == "") show_help(); if (!file_exists($xml_file)) { echo_stderr("Cannot find path: $xml_file. Skipping RoundCube restore.\n"); exit(1); } if (filesize($xml_file) == 0) { echo_stderr("Size of $xml_file is 0. Skipping RoundCube restore.\n"); exit(1); } //**************************************************************** //**************************************************************** if ($high_access_connection) { if (version_compare(PHP_VERSION, '5.3.0', '<')) { $mysql_conf = @parse_ini_file("/usr/local/directadmin/conf/mysql.conf", false); } else { $mysql_conf = @parse_ini_file("/usr/local/directadmin/conf/mysql.conf", false, INI_SCANNER_RAW); } } if ($high_access_connection && $mysql_conf && strlen($mysql_conf['passwd']) > 4) { $mysql_conf = parse_ini_file("/usr/local/directadmin/conf/mysql.conf"); $mysql_user = $mysql_conf['user']; $mysql_pass = $mysql_conf['passwd']; $mysql_host = 'localhost'; $mysql_db = 'da_roundcube'; if (isset($mysql_conf['host']) && $mysql_conf['host'] != "") $mysql_host = $mysql_conf['host']; } else { if (!file_exists($rc_config)) { echo_stderr("Cannot find RoundCube config at $rc_config. Is RC installed and up to date?\n"); exit(5); } include_once($rc_config); if (!isset($config) || !isset($config['db_dsnw']) || $config['db_dsnw'] == '') { echo_stderr("Cannot find \$config['db_dsnw'] variable in $rc_config\n"); exit(6); } //$config['db_dsnw'] = 'mysql://da_roundcube:password@localhost/da_roundcube'; $values = explode('/', $config['db_dsnw']); $connect = explode('@', $values[2]); $auth = explode(':', $connect[0]); $mysql_user = $auth[0]; $mysql_pass = $auth[1]; $mysql_host = $connect[1]; $mysql_db = $values[3]; } $mysqli = new mysqli($mysql_host, $mysql_user, $mysql_pass); if ($mysqli->connect_errno) { echo_stderr("Failed to connect to MySQL: (".$mysqli->connect_errno.") ".$mysqli->connect_error."\n"); exit(3); } $mysqli->set_charset('utf8'); if (!$mysqli->select_db($mysql_db)) { echo_stderr("There is no $mysql_db database. Skipping RoundCube restore.\n"); exit(1); } //**************************************************************** //**************************************************************** $xml = simplexml_load_file($xml_file); if ($xml === FALSE) { echo_stderr("Error reading in XML file with with simplexml_load_file('$xml_file')\n"); exit(4); } foreach($xml->children() as $email) { $username = urldecode($email->USERNAME); if ($username != $system_username) { $data = explode('@', $username); if ($data[1] != $domain) { echo_stderr($username. " is not part of domain '".$domain."': Skipping.\n"); continue; } } $user_id = ensure_user($email); if ($user_id == -1) continue; echo_debug("username $username : $user_id\n"); foreach($email->INDENTITIES->children() as $identity) { $id_id = ensure_identity($user_id, $identity); if ($id_id == -1) continue; $id_email = urldecode($identity->EMAIL); echo_debug(" identity $id_email : $id_id\n"); } $groups = Array(); foreach($email->CONTACTS->children() as $contact) { //first, ensure all groups exisrt for this user_id. foreach($contact->GROUPS->children() as $group) { $group_id = ensure_group($user_id, $group); $group_name = urldecode($group->NAME); //save it for later. $groups[$group_name] = $group_id; } //next, ensure the contact exists, and add to contactgroupsmembers. $contact_id = ensure_contact($user_id, $contact); $contact_email = urldecode($contact->EMAIL); echo_debug(" contact $contact_email : $contact_id\n"); //link contact to their groups. link_contact_to_group($contact, $contact_id, $groups); } } $mysqli->close(); exit(0); //********************************************************************** //********************************************************************** /********************************************************************** * ensure that the contact has been assigned to their groups. */ function link_contact_to_group($contact, $contact_id, $groups) { global $mysqli; foreach($contact->GROUPS->children() as $group) { $group_name = urldecode($group->NAME); $group_created = mes(urldecode($group->CREATED)); $query = "REPLACE INTO `contactgroupmembers` (contactgroup_id, contact_id, created) VALUES (".mes($groups[$group_name]).", $contact_id, '$group_created')"; if (!$mysqli->query($query)) { echo_stderr("Query error:\n".$query."\n".$mysqli->error."\n"); return -1; } echo_debug(" group $group_name : ".$groups[$group_name]."\n"); } return 1; } /********************************************************************** * ensure that the Group exists for this user_id. */ function ensure_group($user_id, $group) { global $mysqli; $group_name = mes(urldecode($group->NAME)); $query = "SELECT contactgroup_id FROM `contactgroups` WHERE user_id=$user_id AND name='$group_name'"; if (!$group_ids = $mysqli->query($query)) { echo_stderr("Query error:\n".$query."\n".$mysqli->error."\n"); return -1; } if ($group_ids->num_rows > 0) { $data = $group_ids->fetch_array(); return $data['contactgroup_id']; } //No group, must add it. $group_changed = mes(urldecode($group->CHANGED)); $query = "INSERT INTO `contactgroups` (user_id, changed, name) VALUES ($user_id, '$group_changed', '$group_name')"; if (!$groups = $mysqli->query($query)) { echo_stderr("Query error:\n".$query."\n".$mysqli->error."\n"); return -1; } return $mysqli->insert_id; } /********************************************************************** * ensure that the Contact exists for this user_id. */ function ensure_contact($user_id, $contact) { global $mysqli; $contact_email = mes(urldecode($contact->EMAIL)); $contact_name = mes(urldecode($contact->NAME)); $query = "SELECT contact_id FROM `contacts` WHERE user_id=$user_id AND name='$contact_name' AND email='$contact_email' LIMIT 1"; if (!$contact_ids = $mysqli->query($query)) { echo_stderr("Query error:\n".$query."\n".$mysqli->error."\n"); return -1; } if ($contact_ids->num_rows > 0) { $data = $contact_ids->fetch_array(); return $data['contact_id']; } //No contact, must add it. $contact_changed = mes(urldecode($contact->CHANGED)); $contact_firstname = mes(urldecode($contact->FIRSTNAME)); $contact_surname = mes(urldecode($contact->SURNAME)); $contact_vcard = mes(urldecode($contact->VCARD)); $contact_words = mes(urldecode($contact->WORDS)); $query = "INSERT INTO `contacts` (changed, name, email, firstname, surname, vcard, words, user_id) VALUES ('$contact_changed', '$contact_name', '$contact_email', '$contact_firstname', '$contact_surname', '$contact_vcard', '$contact_words', $user_id)"; if (!$contact_ids = $mysqli->query($query)) { echo_stderr("Query error:\n".$query."\n".$mysqli->error."\n"); return -1; } return $mysqli->insert_id; } /********************************************************************** * ensure that the Identity exists for this user_id. * no need to worry about the return value */ function ensure_identity($user_id, $identity) { global $mysqli; $id_email = mes(urldecode($identity->EMAIL)); $id_name = mes(urldecode($identity->NAME)); $query = "SELECT identity_id FROM `identities` WHERE user_id=$user_id AND name='$id_name' AND email='$id_email' LIMIT 1"; if (!$ids = $mysqli->query($query)) { echo_stderr("Query error:\n".$query."\n".$mysqli->error."\n"); return -1; } if ($ids->num_rows > 0) { $data = $ids->fetch_array(); return $data['identity_id']; } //No identity, must add it. $id_changed = mes(urldecode($identity->CHANGED)); $id_standard = mes(urldecode($identity->STANDARD)); $id_organization = mes(urldecode($identity->ORGANIZATION)); $id_reply_to = mes(urldecode($identity['REPLY-TO'])); $id_bcc = mes(urldecode($identity->BCC)); $id_signature = mes(urldecode($identity->SIGNATURE)); $id_html_signature =mes(urldecode($identity->HTML_SIGNATURE)); $query = "INSERT INTO `identities` (user_id, changed, standard, name, organization, email, `reply-to`, bcc, signature, html_signature) VALUES ($user_id, '$id_changed', $id_standard, '$id_name', '$id_organization', '$id_email', '$id_reply_to', '$id_bcc', '$id_signature', $id_html_signature)"; if (!$ids = $mysqli->query($query)) { echo_stderr("Query error:\n".$query."\n".$mysqli->error."\n"); return -1; } return $mysqli->insert_id; } /********************************************************************** * ensure that the User exists * yes: return user_id * no: add user, set data, resturn user_id */ function ensure_user($email) { global $mysqli, $rc_mail_host; $username = mes(urldecode($email->USERNAME)); $query = "SELECT user_id FROM `users` WHERE username='$username' LIMIT 1"; if (!$users = $mysqli->query($query)) { echo_stderr("Query error:\n".$query."\n".$mysqli->error."\n"); return -1; } if ($users->num_rows > 0) { $data = $users->fetch_array(); return $data['user_id']; } //No User, must add it. $created=mes(urldecode($email->CREATED)); $last_login=mes(urldecode($email->LAST_LOGIN)); $language=mes(urldecode($email->LANGUAGE)); $preferences=mes(urldecode($email->PREFERENCES)); $query = "INSERT INTO `users` (username, mail_host, created, last_login, language, preferences) VALUES ('$username', '$rc_mail_host', '$created', '$last_login', '$language', '$preferences')"; if (!$users = $mysqli->query($query)) { echo_stderr("Query error:\n".$query."\n".$mysqli->error."\n"); return -1; } return $mysqli->insert_id; } //********************************************************************** function show_help() { global $mysql_db, $version; echo_stderr("Roundcube $version restore script to restore Users.\n\n"); echo_stderr("Usage:\n"); echo_stderr(" username=username domain=domain.com xml_file=/path/to/rc.xml ".__FILE__."\n\n"); echo_stderr("The script will read in the XML specified by xml_file.\n"); echo_stderr("It will insert the data into the $mysql_db database.\n"); exit(2); } function die_stderr($str) { echo_stderr($str); die(); } function echo_stderr($str) { $fd = fopen('php://stderr', 'w'); fwrite($fd, $str); fclose($fd); } function echo_debug($str) { global $is_debug; if ($is_debug) echo $str; } function mes($str) { global $mysqli; return $mysqli->real_escape_string($str); } ?>