Added EPP domain update

This commit is contained in:
Pinga 2023-08-24 11:01:12 +03:00
parent 07d46d9f12
commit c74da6c030
2 changed files with 824 additions and 0 deletions

View file

@ -927,4 +927,816 @@ function processHostUpdate($conn, $db, $xml, $clid, $database_type) {
$epp = new EPP\EppWriter();
$xml = $epp->epp_writer($response);
sendEppResponse($conn, $xml);
}
function processDomainUpdate($conn, $db, $xml, $clid, $database_type) {
$domainName = (string) $xml->command->update->children('urn:ietf:params:xml:ns:domain-1.0')->update->name;
$clTRID = (string) $xml->command->clTRID;
$domainRem = $xml->xpath('//domain:rem')[0] ?? null;
$domainAdd = $xml->xpath('//domain:add')[0] ?? null;
$domainChg = $xml->xpath('//domain:chg')[0] ?? null;
$extensionNode = $xml->xpath('//extension')[0] ?? null;
if ($domainRem === null && $domainAdd === null && $domainChg === null && $extensionNode === null) {
sendEppError($conn, 2003, 'At least one domain:rem || domain:add || domain:chg', $clTRID);
return;
}
if (!$domainName) {
sendEppError($conn, 2003, 'Domain name is not provided', $clTRID);
return;
}
$stmt = $db->prepare("SELECT `id`,`tldid`,`exdate`,`clid` FROM `domain` WHERE `name` = ? LIMIT 1");
$stmt->execute([$domainName]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) {
sendEppError($conn, 2303, 'Domain name does not exist', $clTRID);
return;
}
$stmt = $db->prepare("SELECT id FROM registrar WHERE clid = :clid LIMIT 1");
$stmt->bindParam(':clid', $clid, PDO::PARAM_STR);
$stmt->execute();
$clid = $stmt->fetch(PDO::FETCH_ASSOC);
$clid = $clid['id'];
if ($clid != $row['clid']) {
sendEppError($conn, 2201, 'You do not have privileges to modify a domain name that belongs to another registrar', $clTRID);
return;
}
$domain_id = $row['id'];
$stmt = $db->prepare("SELECT `status` FROM `domain_status` WHERE `domain_id` = ?");
$stmt->execute([$row['id']]);
while ($status = $stmt->fetchColumn()) {
if (strpos($status, 'serverUpdateProhibited') !== false || strpos($status, 'pendingTransfer') !== false) {
sendEppError($conn, 2304, 'It has a serverUpdateProhibited or pendingUpdate status that does not allow modification, first change the status and then update', $clTRID);
return;
}
}
$clientUpdateProhibited = 0;
$stmt = $db->prepare("SELECT `id` FROM `domain_status` WHERE `domain_id` = ? AND `status` = 'clientUpdateProhibited' LIMIT 1");
$stmt->execute([$row['id']]);
$clientUpdateProhibited = $stmt->fetchColumn();
if (isset($domainRem)) {
$ns = $xml->xpath('//domain:rem/domain:ns') ?? [];
$contact_list = $xml->xpath('//domain:rem/domain:contact') ?? [];
$statusList = $xml->xpath('//domain:rem/domain:status/@s') ?? [];
if (!$ns && count($contact_list) == 0 && count($statusList) == 0) {
sendEppError($conn, 2005, 'At least one element MUST be present', $clTRID);
return;
}
foreach ($statusList as $status) {
$status = (string)$status;
if ($status === 'clientUpdateProhibited') {
$clientUpdateProhibited = 0;
}
if (!in_array($status, ['clientDeleteProhibited', 'clientTransferProhibited', 'clientUpdateProhibited', 'clientRenewProhibited'])) {
sendEppError($conn, 2005, 'Only these clientDeleteProhibited|clientTransferProhibited|clientUpdateProhibited|clientRenewProhibited statuses are accepted', $clTRID);
return;
}
}
}
if ($clientUpdateProhibited) {
sendEppError($conn, 2304, 'It has clientUpdateProhibited status, but you did not indicate this status when deleting', $clTRID);
return;
}
$domainAddNodes = $xml->xpath('//domain:add');
if (!empty($domainAddNodes)) {
$domainAddNode = $domainAddNodes[0];
} else {
$domainAddNode = null;
}
if ($domainAddNode !== null) {
$ns = $xml->xpath('//domain:add/domain:ns');
$hostObjList = $xml->xpath('//domain:add/domain:hostObj');
$hostAttrList = $xml->xpath('//domain:add/domain:hostAttr');
$contact_list = $xml->xpath('//domain:add/domain:contact');
$statusList = $xml->xpath('//domain:add/domain:status/@s');
if (!$ns && !count($contact_list) && !count($statusList) && !count($hostObjList) && !count($hostAttrList)) {
sendEppError($conn, 2005, 'At least one element MUST be present', $clTRID);
return;
}
foreach ($statusList as $node) {
$status = (string) $node;
if (!preg_match('/^(clientDeleteProhibited|clientHold|clientRenewProhibited|clientTransferProhibited|clientUpdateProhibited)$/', $status)) {
sendEppError($conn, 2005, 'Only these clientDeleteProhibited|clientTransferProhibited|clientUpdateProhibited statuses are accepted', $clTRID);
return;
}
$matchingNodes = $xml->xpath('domain:status[@s="' . $status . '"]');
if (!$matchingNodes || count($matchingNodes) == 0) {
$stmt = $db->prepare("SELECT `id` FROM `domain_status` WHERE `domain_id` = ? AND `status` = ? LIMIT 1");
$stmt->execute([$row['id'], $status]);
$domainStatusId = $stmt->fetchColumn();
if ($domainStatusId) {
sendEppError($conn, 2306, 'This status '.$status.' already exists for this domain', $clTRID);
return;
}
}
}
if (count($hostObjList) > 0 && count($hostAttrList) > 0) {
sendEppError($conn, 2001, 'It cannot be hostObj and hostAttr at the same time, either one or the other', $clTRID);
return;
}
if (count($hostObjList) > 13) {
sendEppError($conn, 2306, 'No more than 13 domain:hostObj are allowed', $clTRID);
return;
}
if (count($hostAttrList) > 13) {
sendEppError($conn, 2306, 'No more than 13 domain:hostObj are allowed', $clTRID);
return;
}
}
$hostObjList = $xml->xpath('domain:ns/domain:hostObj');
$hostAttrList = $xml->xpath('domain:ns/domain:hostAttr/domain:hostName');
// Compare for duplicates in hostObj list
if (count($hostObjList) > 0) {
$nsArr = [];
foreach ($hostObjList as $node) {
$hostObj = (string)$node;
if (isset($nsArr[$hostObj])) {
sendEppError($conn, 2306, "Duplicate NAMESERVER ($hostObj)", $clTRID);
return;
}
$nsArr[$hostObj] = 1;
}
}
// Compare for duplicates in hostAttr list
if (count($hostAttrList) > 0) {
$nsArr = [];
foreach ($hostAttrList as $node) {
$hostName = (string)$node;
if (isset($nsArr[$hostName])) {
sendEppError($conn, 2306, "Duplicate NAMESERVER ($hostName)", $clTRID);
return;
}
$nsArr[$hostName] = 1;
}
}
// More validation for hostObj
if (count($hostObjList) > 0) {
foreach ($hostObjList as $node) {
$hostObj = strtoupper((string)$node);
if (preg_match('/[^A-Z0-9\.\-]/', $hostObj) || preg_match('/^-|^\.-|-\.-|^-|-$/', $hostObj)) {
sendEppError($conn, 2005, 'Invalid domain:hostObj', $clTRID);
return;
}
// Additional checks related to domain TLDs and existing records
if (preg_match('/^([A-Z0-9]([A-Z0-9-]{0,61}[A-Z0-9]){0,1}\.){1,125}[A-Z0-9]([A-Z0-9-]{0,61}[A-Z0-9])$/i', $hostObj) && strlen($hostObj) < 254) {
$stmt = $db->prepare("SELECT `tld` FROM `domain_tld`");
$stmt->execute();
$tlds = $stmt->fetchAll(PDO::FETCH_COLUMN);
$host_from_this_registry = 0;
foreach ($tlds as $tld) {
$tld = preg_quote(strtoupper($tld), '/');
if (preg_match("/$tld$/i", $hostObj)) {
$host_from_this_registry = 1;
break;
}
}
if ($host_from_this_registry) {
if (preg_match("/\.$domainName$/i", $hostObj)) {
$superordinate_domain = 1;
} else {
$stmt = $db->prepare("SELECT `id` FROM `host` WHERE `name` = :hostObj LIMIT 1");
$stmt->bindParam(':hostObj', $hostObj);
$stmt->execute();
$host_id_already_exist = $stmt->fetchColumn();
if (!$host_id_already_exist) {
sendEppError($conn, 2303, 'Invalid domain:hostObj '.$hostObj, $clTRID);
return;
}
}
}
} else {
sendEppError($conn, 2005, 'Invalid domain:hostObj', $clTRID);
return;
}
}
}
if (count($hostAttrList) > 0) {
foreach ($hostAttrList as $node) {
$hostName = (string)$node->xpath('domain:hostName[1]')[0];
$hostName = strtoupper($hostName);
if (preg_match('/[^A-Z0-9\.\-]/', $hostName) || preg_match('/^-|^\.-|-\.-|\.\.-|$-|\.$/', $hostName)) {
sendEppError($conn, 2005, 'Invalid domain:hostName', $clTRID);
return;
}
if (strpos($hostName, $domainName) !== false) {
$hostAddrList = $node->xpath('domain:hostAddr');
if (count($hostAddrList) > 13) {
sendEppError($conn, 2306, 'No more than 13 domain:hostObj are allowed', $clTRID);
return;
}
$nsArr = [];
foreach ($hostAddrList as $addrNode) {
$hostAddr = (string)$addrNode;
if (isset($nsArr[$hostAddr])) {
sendEppError($conn, 2306, "Duplicate IP ($hostAddr)", $clTRID);
return;
}
$nsArr[$hostAddr] = 1;
}
foreach ($hostAddrList as $addrNode) {
$hostAddr = (string)$addrNode;
$addrType = $addrNode->attributes()['ip'] ?? 'v4';
$addrType = (string)$addrType;
if ($addrType === 'v6') {
if (!filter_var($hostAddr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
sendEppError($conn, 2005, 'Invalid domain:hostAddr v6', $clTRID);
return;
}
} else {
if (!filter_var($hostAddr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) || $hostAddr == '127.0.0.1') {
sendEppError($conn, 2005, 'Invalid domain:hostAddr v4', $clTRID);
return;
}
}
}
} else {
sendEppError($conn, 2005, "Invalid domain:hostName $hostName", $clTRID);
return;
}
}
}
if (isset($contact_list)) {
foreach ($contact_list as $node) {
$contact = (string)$node;
$contactAttributes = $node->attributes();
$contact_type = (string)$contactAttributes['type'];
$contact = strtoupper($contact);
$stmt = $db->prepare("SELECT `id` FROM `contact` WHERE `identifier` = ? LIMIT 1");
$stmt->execute([$contact]);
$contact_id = $stmt->fetchColumn();
if (!$contact_id) {
sendEppError($conn, 2303, 'This contact '.$contact.' does not exist', $clTRID);
return;
}
$stmt2 = $db->prepare("SELECT `id` FROM `domain_contact_map` WHERE `domain_id` = ? AND `contact_id` = ? AND `type` = ? LIMIT 1");
$stmt2->execute([$row['id'], $contact_id, $contact_type]);
$domain_contact_map_id = $stmt2->fetchColumn();
if ($domain_contact_map_id) {
sendEppError($conn, 2306, 'This contact '.$contact.' already exists for type '.$contact_type, $clTRID);
return;
}
}
}
if (isset($domainChg)) {
$registrantNodes = $domainChg->xpath('domain:registrant[1]');
if (!empty($registrantNodes)) {
$registrant = strtoupper((string)$domainChg->xpath('domain:registrant[1]')[0]);
}
if (isset($registrant)) {
$stmt3 = $db->prepare("SELECT `id` FROM `contact` WHERE `identifier` = ? LIMIT 1");
$stmt3->execute([$registrant]);
$registrant_id = $stmt3->fetchColumn();
if (!$registrant_id) {
sendEppError($conn, 2303, 'Registrant does not exist', $clTRID);
return;
}
}
$stmt4 = $db->prepare("SELECT `status` FROM `domain_status` WHERE `domain_id` = ?");
$stmt4->execute([$row['id']]);
while ($status = $stmt4->fetchColumn()) {
if (preg_match('/.*(serverUpdateProhibited)$/', $status) || preg_match('/^pendingTransfer/', $status)) {
sendEppError($conn, 2304, 'It has a status that does not allow modification, first change the status then update', $clTRID);
return;
}
}
$authInfo_pw = (string)$domainChg->xpath('//domain:authInfo/domain:pw[1]')[0];
if ($authInfo_pw) {
if (strlen($authInfo_pw) < 6 || strlen($authInfo_pw) > 16) {
sendEppError($conn, 2005, 'Password needs to be at least 6 and up to 16 characters long', $clTRID);
return;
}
if (!preg_match('/[A-Z]/', $authInfo_pw)) {
sendEppError($conn, 2005, 'Password should have both upper and lower case characters', $clTRID);
return;
}
if (!preg_match('/\d/', $authInfo_pw)) {
sendEppError($conn, 2005, 'Password should contain one or more numbers', $clTRID);
return;
}
}
}
if (isset($rgp_update) && $rgp_update) {
$op_attribute = $xml->xpath('rgp:restore/@op[1]')[0]->__toString();
if ($op_attribute === 'request') {
$stmt = $db->prepare("SELECT COUNT(`id`) AS `ids` FROM `domain` WHERE `rgpstatus` = 'redemptionPeriod' AND `id` = :domain_id LIMIT 1");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->execute();
$temp_id_rgpstatus = $stmt->fetchColumn();
if ($temp_id_rgpstatus == 0) {
sendEppError($conn, 2304, 'pendingRestore can only be done if the domain is now in redemptionPeriod rgpStatus', $clTRID);
return;
}
$stmt = $db->prepare("SELECT COUNT(`id`) AS `ids` FROM `domain_status` WHERE `status` = 'pendingDelete' AND `domain_id` = :domain_id LIMIT 1");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->execute();
$temp_id_status = $stmt->fetchColumn();
if ($temp_id_status == 0) {
sendEppError($conn, 2304, 'pendingRestore can only be done if the domain is now in pendingDelete status', $clTRID);
return;
}
} elseif ($op_attribute === 'report') {
$stmt = $db->prepare("SELECT COUNT(`id`) AS `ids` FROM `domain` WHERE `rgpstatus` = 'pendingRestore' AND `id` = :domain_id LIMIT 1");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->execute();
$temp_id = $stmt->fetchColumn();
if ($temp_id == 0) {
sendEppError($conn, 2304, 'report can only be sent if the domain is in pendingRestore status', $clTRID);
return;
}
}
}
if (isset($domainRem)) {
$nsNodes = $xml->xpath('//domain:rem/domain:ns');
$ns = !empty($nsNodes) ? $nsNodes[0] : null;
$contact_list = $xml->xpath('//domain:rem/domain:contact');
$status_list = $xml->xpath('//domain:rem/domain:status/@s');
$hostObj_list = $xml->xpath('//domain:rem/domain:hostObj');
$hostAttr_list = $xml->xpath('//domain:rem/domain:hostAttr');
foreach ($hostObj_list as $node) {
$hostObj = (string) $node;
$stmt = $db->prepare("SELECT `id` FROM `host` WHERE `name` = :hostObj LIMIT 1");
$stmt->bindParam(':hostObj', $hostObj, PDO::PARAM_STR);
$stmt->execute();
$host_id = $stmt->fetchColumn();
if ($host_id) {
$stmt = $db->prepare("DELETE FROM `domain_host_map` WHERE `domain_id` = :domain_id AND `host_id` = :host_id");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->bindParam(':host_id', $host_id, PDO::PARAM_INT);
$stmt->execute();
}
}
foreach ($hostAttr_list as $node) {
$hostNameNodes = $node->xpath('domain:hostName[1]');
if ($hostNameNodes && isset($hostNameNodes[0])) {
$hostName = (string) $hostNameNodes[0];
$stmt = $db->prepare("SELECT `id` FROM `host` WHERE `name` = :hostName LIMIT 1");
$stmt->bindParam(':hostName', $hostName, PDO::PARAM_STR);
$stmt->execute();
$host_id = $stmt->fetchColumn();
if ($host_id) {
$stmt = $db->prepare("DELETE FROM `domain_host_map` WHERE `domain_id` = :domain_id AND `host_id` = :host_id");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->bindParam(':host_id', $host_id, PDO::PARAM_INT);
$stmt->execute();
$stmt = $db->prepare("DELETE FROM `host_addr` WHERE `host_id` = :host_id");
$stmt->bindParam(':host_id', $host_id, PDO::PARAM_INT);
$stmt->execute();
$stmt = $db->prepare("DELETE FROM `host` WHERE `id` = :host_id");
$stmt->bindParam(':host_id', $host_id, PDO::PARAM_INT);
$stmt->execute();
}
}
}
foreach ($contact_list as $node) {
$contact = (string) $node;
$contact_type = (string) $node->attributes()->type;
$stmt = $db->prepare("SELECT `id` FROM `contact` WHERE `identifier` = :contact LIMIT 1");
$stmt->bindParam(':contact', $contact, PDO::PARAM_STR);
$stmt->execute();
$contact_id = $stmt->fetchColumn();
if ($contact_id) {
$stmt = $db->prepare("DELETE FROM `domain_contact_map` WHERE `domain_id` = :domain_id AND `contact_id` = :contact_id AND `type` = :contact_type");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->bindParam(':contact_id', $contact_id, PDO::PARAM_INT);
$stmt->bindParam(':contact_type', $contact_type, PDO::PARAM_STR);
$stmt->execute();
}
}
foreach ($status_list as $node) {
$status = $node->__toString();
$stmt = $db->prepare("DELETE FROM `domain_status` WHERE `domain_id` = :domain_id AND `status` = :status");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->bindParam(':status', $status, PDO::PARAM_STR);
$stmt->execute();
}
}
if (isset($domainAdd)) {
$ns = $xml->xpath('//domain:add/domain:ns')[0] ?? null;
$hostObj_list = $xml->xpath('//domain:add//domain:hostObj');
$hostAttr_list = $xml->xpath('//domain:add//domain:hostAttr');
$contact_list = $xml->xpath('//domain:add//domain:contact');
$status_list = $xml->xpath('//domain:add//domain:status/@s');
foreach ($hostObj_list as $node) {
$hostObj = (string) $node;
// Check if hostObj exists in the database
$stmt = $db->prepare("SELECT `id` FROM `host` WHERE `name` = :hostObj LIMIT 1");
$stmt->bindParam(':hostObj', $hostObj, PDO::PARAM_STR);
$stmt->execute();
$hostObj_already_exist = $stmt->fetchColumn();
if ($hostObj_already_exist) {
$stmt = $db->prepare("SELECT `domain_id` FROM `domain_host_map` WHERE `domain_id` = :domain_id AND `host_id` = :hostObj_already_exist LIMIT 1");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->bindParam(':hostObj_already_exist', $hostObj_already_exist, PDO::PARAM_INT);
$stmt->execute();
$domain_host_map_id = $stmt->fetchColumn();
if (!$domain_host_map_id) {
$stmt = $db->prepare("INSERT INTO `domain_host_map` (`domain_id`,`host_id`) VALUES(:domain_id, :hostObj_already_exist)");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->bindParam(':hostObj_already_exist', $hostObj_already_exist, PDO::PARAM_INT);
$stmt->execute();
} else {
$stmt = $db->prepare("INSERT INTO `error_log` (`registrar_id`,`log`,`date`) VALUES(:registrar_id, :log, CURRENT_TIMESTAMP)");
$log = "Domain : $domainName ; hostObj : $hostObj - se dubleaza";
$stmt->bindParam(':registrar_id', $clid, PDO::PARAM_INT);
$stmt->bindParam(':log', $log, PDO::PARAM_STR);
$stmt->execute();
}
} else {
$host_from_this_registry = 0;
$sth = $db->prepare("SELECT `tld` FROM `domain_tld`");
if (!$sth->execute()) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
$tld = strtoupper($row['tld']);
$tld = str_replace('.', '\\.', $tld);
if (preg_match("/{$tld}$/i", $hostObj)) {
$host_from_this_registry = 1;
break;
}
}
if ($host_from_this_registry) {
if (preg_match("/\.$domainName$/i", $hostObj)) {
$sth = $db->prepare("INSERT INTO `host` (`name`,`domain_id`,`clid`,`crid`,`crdate`) VALUES(?, ?, ?, ?, CURRENT_TIMESTAMP)");
if (!$sth->execute([$hostObj, $domain_id, $clid, $clid])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
$host_id = $db->lastInsertId();
$sth = $db->prepare("INSERT INTO `domain_host_map` (`domain_id`,`host_id`) VALUES(?, ?)");
if (!$sth->execute([$domain_id, $host_id])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
}
} else {
$sth = $db->prepare("INSERT INTO `host` (`name`,`clid`,`crid`,`crdate`) VALUES(?, ?, ?, CURRENT_TIMESTAMP)");
if (!$sth->execute([$hostObj, $clid, $clid])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
$host_id = $db->lastInsertId();
$sth = $db->prepare("INSERT INTO `domain_host_map` (`domain_id`,`host_id`) VALUES(?, ?)");
if (!$sth->execute([$domain_id, $host_id])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
}
}
}
foreach ($hostAttr_list as $node) {
$hostNames = $xml->xpath('domain:hostName[1]', $node);
$hostName = isset($hostNames[0]) ? (string)$hostNames[0] : null;
if ($hostName) {
$stmt = $db->prepare("SELECT `id` FROM `host` WHERE `name` = :hostName LIMIT 1");
$stmt->bindParam(':hostName', $hostName, PDO::PARAM_STR);
$stmt->execute();
$hostName_already_exist = $stmt->fetchColumn();
if ($hostName_already_exist) {
$sth = $db->prepare("SELECT `domain_id` FROM `domain_host_map` WHERE `domain_id` = ? AND `host_id` = ? LIMIT 1");
$sth->execute([$domain_id, $hostName_already_exist]);
$domain_host_map_id = $sth->fetchColumn();
if (!$domain_host_map_id) {
$sth = $db->prepare("INSERT INTO `domain_host_map` (`domain_id`,`host_id`) VALUES(?, ?)");
if (!$sth->execute([$domain_id, $hostName_already_exist])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
} else {
$logMessage = "Domain : $domainName ; hostName : $hostName - se dubleaza";
$sth = $db->prepare("INSERT INTO `error_log` (`registrar_id`,`log`,`date`) VALUES(?, ?, CURRENT_TIMESTAMP)");
if (!$sth->execute([$clid, $logMessage])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
}
} else {
// Insert into the host table
$sth = $db->prepare("INSERT INTO `host` (`name`,`domain_id`,`clid`,`crid`,`crdate`) VALUES(?, ?, ?, ?, CURRENT_TIMESTAMP)");
$sth->execute([$hostName, $domain_id, $clid, $clid]) or die($sth->errorInfo()[2]);
$host_id = $db->lastInsertId();
// Insert into the domain_host_map table
$sth = $db->prepare("INSERT INTO `domain_host_map` (`domain_id`,`host_id`) VALUES(?, ?)");
$sth->execute([$domain_id, $host_id]) or die($sth->errorInfo()[2]);
// Iterate over the hostAddr_list
$hostAddr_list = $xml->xpath('domain:hostAddr', $node);
foreach ($hostAddr_list as $node) {
$hostAddr = (string)$node;
$addr_type = isset($node['ip']) ? (string)$node['ip'] : 'v4';
// Normalize
if ($addr_type == 'v6') {
$hostAddr = _normalise_v6_address($hostAddr); // PHP function to normalize IPv6
} else {
$hostAddr = _normalise_v4_address($hostAddr); // PHP function to normalize IPv4
}
// Insert into the host_addr table
$sth = $db->prepare("INSERT INTO `host_addr` (`host_id`,`addr`,`ip`) VALUES(?, ?, ?)");
$sth->execute([$host_id, $hostAddr, $addr_type]) or die($sth->errorInfo()[2]);
}
}
}
}
foreach ($contact_list as $node) {
$contact = (string) $node;
$contact_type = (string) $node->attributes()->type;
$stmt = $db->prepare("SELECT `id` FROM `contact` WHERE `identifier` = :contact LIMIT 1");
$stmt->bindParam(':contact', $contact, PDO::PARAM_STR);
$stmt->execute();
$contact_id = $stmt->fetchColumn();
try {
$stmt = $db->prepare("INSERT INTO `domain_contact_map` (`domain_id`,`contact_id`,`type`) VALUES(:domain_id, :contact_id, :contact_type)");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->bindParam(':contact_id', $contact_id, PDO::PARAM_INT);
$stmt->bindParam(':contact_type', $contact_type, PDO::PARAM_STR);
$stmt->execute();
} catch (PDOException $e) {
$codesToIgnore = ['23000', '23505'];
if (!in_array($e->getCode(), $codesToIgnore)) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
}
}
foreach ($status_list as $node) {
$status = $node->__toString();
try {
$stmt = $db->prepare("INSERT INTO `domain_status` (`domain_id`,`status`) VALUES(:domain_id, :status)");
$stmt->bindParam(':domain_id', $domain_id, PDO::PARAM_INT);
$stmt->bindParam(':status', $status, PDO::PARAM_STR);
$stmt->execute();
} catch (PDOException $e) {
$codesToIgnore = ['23000', '23505'];
if (!in_array($e->getCode(), $codesToIgnore)) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
}
}
}
if (isset($domainChg)) {
$registrant_nodes = $xml->xpath('//domain:registrant');
if (count($registrant_nodes) > 0) {
$registrant = strtoupper((string)$registrant_nodes[0]);
if ($registrant) {
$sth = $db->prepare("SELECT `id` FROM `contact` WHERE `identifier` = ? LIMIT 1");
$sth->execute([$registrant]);
$registrant_id = $sth->fetchColumn();
$sth = $db->prepare("UPDATE `domain` SET `registrant` = ?, `update` = CURRENT_TIMESTAMP WHERE `id` = ?");
if (!$sth->execute([$registrant_id, $domain_id])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
} else {
$sth = $db->prepare("UPDATE `domain` SET `registrant` = NULL, `update` = CURRENT_TIMESTAMP WHERE `id` = ?");
if (!$sth->execute([$domain_id])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
}
}
$authInfo = $xml->xpath('//domain:authInfo')[0];
$authInfo_pw = (string)$xml->xpath('//domain:pw[1]')[0];
if ($authInfo_pw) {
$sth = $db->prepare("UPDATE `domain_authInfo` SET `authinfo` = ? WHERE `domain_id` = ? AND `authtype` = ?");
if (!$sth->execute([$authInfo_pw, $domain_id, 'pw'])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
}
$authInfoExtNodes = $xml->xpath('//domain:ext[1]');
if (!empty($authInfoExtNodes)) {
$authInfo_ext = !empty($authInfoExtNodes) ? (string)$authInfoExtNodes[0] : null;
}
if (isset($authInfo_ext)) {
$sth = $db->prepare("UPDATE `domain_authInfo` SET `authinfo` = ? WHERE `domain_id` = ? AND `authtype` = ?");
if (!$sth->execute([$authInfo_ext, $domain_id, 'ext'])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
}
$authInfoNullNodes = $xml->xpath('//domain:null[1]');
if (!empty($authInfoExtNodes)) {
$authInfo_null = !empty($authInfoNullNodes) ? (string)$authInfoNullNodes[0] : null;
}
if (isset($authInfo_null)) {
$sth = $db->prepare("DELETE FROM `domain_authInfo` WHERE `domain_id` = ?");
if (!$sth->execute([$domain_id])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
}
}
if (isset($rgp_update) && $rgp_update) {
$op_attribute = (string)$xml->xpath('//rgp:restore/@op[1]')[0];
if ($op_attribute == 'request') {
$sth = $db->prepare("SELECT COUNT(`id`) AS `ids` FROM `domain` WHERE `rgpstatus` = 'redemptionPeriod' AND `id` = ?");
$sth->execute([$domain_id]);
$temp_id = $sth->fetchColumn();
if ($temp_id == 1) {
$sth = $db->prepare("UPDATE `domain` SET `rgpstatus` = 'pendingRestore', `resTime` = CURRENT_TIMESTAMP, `update` = CURRENT_TIMESTAMP WHERE `id` = ?");
if (!$sth->execute([$domain_id])) {
sendEppError($conn, 2400, 'Database error', $clTRID);
return;
}
} else {
sendEppError($conn, 2304, 'pendingRestore can only be done if the domain is now in redemptionPeriod', $clTRID);
return;
}
} elseif ($op_attribute == 'report') {
$sth = $db->prepare("SELECT COUNT(`id`) AS `ids` FROM `domain` WHERE `rgpstatus` = 'pendingRestore' AND `id` = ?");
$sth->execute([$domain_id]);
$temp_id = $sth->fetchColumn();
if ($temp_id == 1) {
$sth = $db->prepare("SELECT `accountBalance`,`creditLimit` FROM `registrar` WHERE `id` = ?");
$sth->execute([$clid]);
list($registrar_balance, $creditLimit) = $sth->fetch();
$sth = $db->prepare("SELECT `m12` FROM `domain_price` WHERE `tldid` = ? AND `command` = 'renew' LIMIT 1");
$sth->execute([$tldid]);
$renew_price = $sth->fetchColumn();
$sth = $db->prepare("SELECT `price` FROM `domain_restore_price` WHERE `tldid` = ? LIMIT 1");
$sth->execute([$tldid]);
$restore_price = $sth->fetchColumn();
if (($registrar_balance + $creditLimit) < ($renew_price + $restore_price)) {
sendEppError($conn, 2104, 'There is no money on the account for restore and renew', $clTRID);
return;
}
$sth = $db->prepare("SELECT `exdate` FROM `domain` WHERE `id` = ?");
$sth->execute([$domain_id]);
$from = $sth->fetchColumn();
$sth = $db->prepare("UPDATE `domain` SET `exdate` = DATE_ADD(`exdate`, INTERVAL 12 MONTH), `rgpstatus` = NULL, `rgpresTime` = CURRENT_TIMESTAMP, `update` = CURRENT_TIMESTAMP WHERE `id` = ?");
if (!$sth->execute([$domain_id])) {
sendEppError($conn, 2400, 'It was not renewed successfully, something is wrong', $clTRID);
return;
} else {
$sth = $db->prepare("DELETE FROM `domain_status` WHERE `domain_id` = ? AND `status` = ?");
$sth->execute([$domain_id, 'pendingDelete']);
$db->prepare("UPDATE `registrar` SET `accountBalance` = (`accountBalance` - ? - ?) WHERE `id` = ?")
->execute([$renew_price, $restore_price, $clid]);
$db->prepare("INSERT INTO `payment_history` (`registrar_id`,`date`,`description`,`amount`) VALUES(?,CURRENT_TIMESTAMP,'restore domain $domainName',?)")
->execute([$clid, -$restore_price]);
$db->prepare("INSERT INTO `payment_history` (`registrar_id`,`date`,`description`,`amount`) VALUES(?,CURRENT_TIMESTAMP,'renew domain $domainName for period 12 MONTH',?)")
->execute([$clid, -$renew_price]);
$stmt = $db->prepare("SELECT `exdate` FROM `domain` WHERE `id` = ?");
$stmt->execute([$domain_id]);
$to = $stmt->fetchColumn();
$sth = $db->prepare("INSERT INTO `statement` (`registrar_id`,`date`,`command`,`domain_name`,`length_in_months`,`from`,`to`,`amount`) VALUES(?,CURRENT_TIMESTAMP,?,?,?,?,?,?)");
$sth->execute([$clid, 'restore', $domainName, 0, $from, $from, $restore_price]);
$sth->execute([$clid, 'renew', $domainName, 12, $from, $to, $renew_price]);
$stmt = $db->prepare("SELECT `id` FROM `statistics` WHERE `date` = CURDATE()");
$stmt->execute();
$curdate_id = $stmt->fetchColumn();
if (!$curdate_id) {
$db->prepare("INSERT IGNORE INTO `statistics` (`date`) VALUES(CURDATE())")
->execute();
}
$db->prepare("UPDATE `statistics` SET `restored_domains` = `restored_domains` + 1 WHERE `date` = CURDATE()")
->execute();
$db->prepare("UPDATE `statistics` SET `renewed_domains` = `renewed_domains` + 1 WHERE `date` = CURDATE()")
->execute();
}
} else {
sendEppError($conn, 2304, 'report can only be sent if the domain is in pendingRestore status', $clTRID);
return;
}
}
}
$response = [
'command' => 'update_domain',
'resultCode' => 1000,
'lang' => 'en-US',
'message' => 'Command completed successfully',
'clTRID' => $clTRID,
'svTRID' => generateSvTRID(),
];
$epp = new EPP\EppWriter();
$xml = $epp->epp_writer($response);
sendEppResponse($conn, $xml);
}