// // DESCRIPTION: PHP class to automate use of Server Beach's DNS Tool. // This class emulates 100% of the DNS Tool functionality. // Although this class works well, the hope is that this // class will be made obsolete by SB eventually developing // an API to the DNS Tool. // // USAGE: See documentation at http://www.troywolf.com/articles/php/class_sbdns // // NOTES: The class attempts to validate the values you pass to the methods. // If any problems are found, $sbdns->status_msg is set with a // description of the problem and the method returns FALSE. // The class tries to be smart about everything, but please don't // go blindly executing commands against the Server Beach DNS // servers! If you have problems with the code, echo // $sbdns->status_msg to get an indication of the failure. // You may also find $sbdns->dump() handy for debugging. // If you need support, feel free to email the author. // sbdns requires Troy's class_http. http://www.troywolf.com/articles // Alter the path according to your environment. require_once("class_http.php"); // PHP Class to automate Server Beach DNS Tool methods. class sbdns { // Class constructor. Edit with your email and password. // Optionally, you can pass in a delay factor, but you probably do not need // to. See below for more details regarding delay_factor. function sbdns($delay_factor=1) { // Change the next 2 lines to reflect your SB login credentials. $this->auth_email = "me@mydomain.com"; $this->auth_pass = "mypassword"; // You can optionally pass in a delay_factor of 1 or greater. // This will increase the time the class waits between page hits. // Currently most hits are set to wait 1/2 second. So passing in a // value of 2 will make most hits wait 1 full second. If you are having // timing-related problems, increasing this value could solve them. $this->delay_factor = $delay_factor / 1; $this->status_msg = "OK"; $this->phpsessid = ""; } // Emulate the My Server Beach login process and setup to use the // DNS Tool. function login() { // Instantiate the http object used to make the web requests. // More info about this object at www.troywolf.com/articles if (!$this->http = new http()) { $this->status_msg = "Failed to create http object."; return false; } // Step 1: Hit SB login page to initialize phpsessid and cookie. $this->url = "https://secure.serverbeach.com:443/catalog/mysblogin.php"; $this->http->headers['Referer'] = "http://www.serverbeach.com/catalog/"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Login step 1 https request failed."; return false; } // Find phpsessid cookie in headers. $ary_headers = split("\n", $this->http->header); foreach($ary_headers as $hdr) { if (eregi("^Set-Cookie\:", $hdr)) { $hdr = str_replace("Set-Cookie: ", "", $hdr); $ary_cookies = split(";", $hdr); $this->phpsessid = trim($ary_cookies[0]); break; } } // Did we fail to find the phpsessionid cookie? if (!$this->phpsessid) { $this->status_msg = "Login step 1 failed to set PHPSESSID cookie."; return false; } // Step 2. Authenticate by posting the login form along with the phpsessid. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/catalog/mysblogin.php?action=process&".$this->phpsessid; $this->http->headers['Referer'] = "https://secure.serverbeach.com/catalog/mysblogin.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['email_address'] = $this->auth_email; $this->http->postvars['password'] = $this->auth_pass; $this->http->postvars['user'] = "returning"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Login step 2 https request failed."; return false; } // Did login fail? $ary_headers = split("\n", $this->http->header); foreach($ary_headers as $hdr) { if (eregi("^Location\:", $hdr)) { if (strpos($hdr, "login=fail") > 0) { $this->status_msg = "SB login failed. Mostly likely because of incorrect email or password."; return false; } } } // Step 3. Hit the My SB home page. Apparently, this sets some necessary // server-side session variables. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/index.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/index.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Login step 3 https request failed."; return false; } // Step 4. Hit the DNS Tool home page. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/index.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/index.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Login step 4 https request failed."; return false; } return true; } // Add a new domain to the DNS setting SB as either Master or Slave. // $domain = domain name to add // $ip = IP where domain is hosted -or- IP of master DNS server. // $master = true/false, passing false means setup SB as slave. // NOTE: If you had previously set a domain, you'll need to reset it // after executing this method if you plan to execute more methods against // the previously set domain. function add_domain($domain, $ip, $master=true) { if (strlen($domain) == 0) { $this->status_msg = "Domain add failed because no domain passed in."; return false; } $domain = strtolower($domain); if (!ereg("^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$", $ip)) { $this->status_msg = "Domain add failed because invalid IP passed in."; return false; } // First check if domain already exists. If so, stop. // This adds a small time overhead, but is worthwhile to prevent stupid // mistakes. if ($this->set_domain($domain)) { $this->status_msg = "Domain add failed because domain '".$domain."' already exists."; return false; } // Step 1. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/choose_master_slave.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/index.php"; $this->http->headers['Cookie'] = $this->phpsessid; // PLEASE do not change any of these values unless you really know what // you are doing and have permission from Server Beach. $this->http->postvars['info[command]'] = "add_zone"; $this->http->postvars['info[class]'] = "IN"; $this->http->postvars['info[ttl]'] = "86400"; $this->http->postvars['info[source_dname]'] = "ns1.geodns.net"; $this->http->postvars['info[owner_email]'] = "hostmaster@geodns.net"; $this->http->postvars['info[serial]'] = "1"; $this->http->postvars['info[refresh_time]'] = "10800"; $this->http->postvars['info[transfer]'] = "3600"; $this->http->postvars['info[expire_time]'] = "604800"; $this->http->postvars['info[default_ttl]'] = "86400"; $this->http->postvars['info[nameserver]'] = "ns1.geodns.net"; $this->http->postvars['info[new_domain]'] = $domain; if (!$this->http->fetch($this->url)) { $this->status_msg = "Domain add step 1 https request failed."; return false; } if ($master) { // Use Server Beach as Master & Slave DNS. // Step 2. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/add_zone_ip.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/choose_master_slave.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['command'] = "CHOOSE_DNS_TYPE"; $this->http->postvars['info[dns_type]'] = "master"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Domain add master step 2 https request failed."; return false; } // Step 3. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/add_zone_processor.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/choose_master_slave.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['info[address]'] = $ip; $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Domain add master step 3 https request failed."; return false; } } else { // Use Server Beach as Slave DNS only. // Step 2. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/add_master_ip.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/choose_master_slave.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['command'] = "CHOOSE_DNS_TYPE"; $this->http->postvars['info[dns_type]'] = "slave"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Domain add slave step 2 https request failed."; return false; } // Step 3. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/add_master_processor.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/choose_master_slave.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['info[address]'] = $ip; $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Domain add slave step 3 https request failed."; return false; } } return true; } // Delete an entire domain zone from the DNS. // This method, like most of the methods, requires you to first set the // target domain with set_domain(). function delete_domain() { if (!$this->domain) { $this->status_msg = "Delete domain failed because domain is not set."; return false; } $this->http->clean(); usleep(500000 * $this->delay_factor); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_del_domain.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/wizard_del_domain.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Delete domain https request failed."; return false; } return true; } // Set the current domain to issue commands against. // Most of the other methods require that you first set the domain with // this method. Same as clicking the "go" button next to a domain in the // DNS Tool. function set_domain($domain) { if (strlen($domain) == 0) { $this->status_msg = "Set domain failed because no domain passed in."; return false; } $this->zone = ""; $this->records = array(); $this->domain = $domain; usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/zone_list_processor.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/index.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['info[zone]'] = $this->domain."."; $this->http->postvars['action'] = "view_records"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Set domain https request failed."; return false; } if ($this->http->status == "302") { return true; } else { $this->status_msg = "Set domain could not find the domain."; return false; } } // Change the zone's hostmaster email address. function change_hostmaster_email($email_address) { if (!$this->domain) { $this->status_msg = "Change hostmaster email failed because domain is not set."; return false; } if(!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email_address)) { $this->status_msg = "Change hostmaster email failed because email address is invalid."; return false; } $email_address = strtolower($email_address); // Step 1. $this->http->clean(); usleep(500000 * $this->delay_factor); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_change_email.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Change hostmaster email step 1 https request failed."; return false; } // Step 2. $this->http->clean(); usleep(500000 * $this->delay_factor); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_confirm_email.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/wizard_change_email.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['info[email_address]'] = $email_address; $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Change hostmaster email step 2 https request failed."; return false; } return true; } // Add an A or CNAME record to the domain zone. // If $target is missing, create CNAME for main domain. // If $target contains any alpha characters, create a CNAME for the target. // Else assume $target is an IP address and create an A record. function add_record($rec_name, $target="") { if (!$this->domain) { $this->status_msg = "Add record failed because domain is not set."; return false; } $rec_name = strtolower($rec_name); $target = strtolower($target); if (!$target) { $type_val = "current_domain"; } elseif (ereg("[a-z]", $target)) { $type_val = "new_domain"; } else { $type_val = "ip_addr"; }; // Step 1. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_sub_sub.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Add mail exchanger step 1 https request failed."; return false; } // Step 2. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_sub_processor.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/wizard_sub_sub.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['info[subdomain]'] = $rec_name; $this->http->postvars['info[sub_type]'] = $type_val; switch($type_val) { case "new_domain": $this->http->postvars['info[new_canonical_dname]'] = $target; break; case "ip_addr": $this->http->postvars['info[new_a_ip_address]'] = $target; break; } $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Add record step 2 https request failed."; return false; } return true; } // Change a record's target. // If you instead want to change a subdomain name, don't use this method. // Instead, delete the record you don't want and add the one you do want. function update_record($rec_name, $target="") { if (!$this->domain) { $this->status_msg = "Update record failed because domain is not set."; return false; } if (!$this->records) { if (!$this->get_record_ids()) { $this->status_msg = "Update record failed because get_record_ids failed."; return false; } } $rec_name = strtolower($rec_name); $target = strtolower($target); // Find record type and ID. $id = false; foreach($this->records['CNAME'] as $record) { if ($record['name'] == $rec_name) { $id = $record['id']; $rec_type = 'cname'; break; } } if (!$id) { foreach($this->records['A'] as $record) { if (($record['name'] == $rec_name) || ($record['name'] == ($rec_name."."))) { $id = $record['id']; $rec_type = 'a'; break; } } } if (!$id) { $this->status_msg = "Update record failed because '".$rec_name ."' not found in your zone's A or CNAME records."; return false; } // Determine the target type based on $target param. if (!$target) { $type_val = "current_domain"; } elseif (ereg("[a-z]", $target)) { $type_val = "new_domain"; } else { $type_val = "ip_addr"; }; // Check for attempt to convert A to CNAME -- no can do. if (($rec_type == "a") && ($type_val != "ip_addr")) { $this->status_msg = "Update record failed because you cannot convert" ." an A record to a CNAME. You must delete the A record, then" ." create a new CNAME record."; return false; } // Step 1. Set the record id to modify. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/record_list_processor.php?type=".$rec_type."&id=".$id."&action=edit_sub"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Update record step 1 https request failed."; return false; } // Step 2. Step 1 returns a redirect to this step -- does not work // without this step. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_edsub_data.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Update record step 2 https request failed."; return false; } // If converting a CNAME to an A, we have to do something a little different. if (($rec_type == "cname") && ($type_val == "ip_addr")) { // Step 3. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_edsub_type.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/wizard_edsub_ip.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['sub_type'] = $type_val; if (!$this->http->fetch($this->url)) { $this->status_msg = "Update record step 3 https request failed."; return false; } // Step 4. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_edsub_c_to_a_processor.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/wizard_edsub_ip.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['info[new_a_ip_address]'] = $target; $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Update record step 4 https request failed."; return false; } } else { // Step 3. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_edsub_processor.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/wizard_edsub_new.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['sub_type'] = $type_val; switch($type_val) { case "new_domain": $this->http->postvars['info[new_canonical_dname]'] = $target; break; case "ip_addr": $this->http->postvars['info[new_a_ip_address]'] = $target; break; } $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Update record step 3 https request failed."; return false; } } return true; } // Delete a subdomain record. Only pass the sub name. That is, do not append // the domain name. function delete_record($rec_name) { if (!$this->domain) { $this->status_msg = "Delete record failed because domain is not set."; return false; } $rec_name = strtolower($rec_name); // Make sure rec_name is not the root domain record. if ($rec_name == $this->domain) { $this->status_msg = "Delete record failed because you cannot delete" ." the root domain for this zone."; return false; } if (!$this->records) { if (!$this->get_record_ids()) { $this->status_msg = "Delete record failed because get_record_ids failed."; return false; } } // Find record type and ID. $id = false; foreach($this->records['CNAME'] as $record) { if ($record['name'] == $rec_name) { $id = $record['id']; $rec_type = 'cname'; break; } } if (!$id) { foreach($this->records['A'] as $record) { if ($record['name'] == $rec_name) { $id = $record['id']; $rec_type = 'a'; break; } } } if (!$id) { $this->status_msg = "Delete record failed because '".$rec_name."' not found in your zone's A or CNAME records."; return false; } // Step 1. $this->http->clean(); usleep(500000 * $this->delay_factor); $this->url = "https://secure.serverbeach.com/mysb/dns/record_list_processor.php?type=".$rec_type."&id=".$id."&action=del_sub"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Delete record step 1 https request failed."; return false; } // Step 2. $this->http->clean(); usleep(500000 * $this->delay_factor); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_delsub_processor.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Delete record step 2 https request failed."; return false; } return true; } // Add a mail exchanger to the zone. // Note, if the owner is the root domain, then pass the domain name. // If the owner is a subdomain (must be an A record), only pass the sub. // For example, these are both correct: // $sbdns->add_mail_exchanger("troywolf.com", 10, "mail.someserver.com"); // $sbdns->add_mail_exchanger("mail", 10, "mail.someserver.com"); // This is NOT correct: // $sbdns->add_mail_exchanger("mail.troywolf.com", 10, "mail.someserver.com"); // Preference parameter is optional--will default to 10. function add_mail_exchanger($owner, $exchanger, $preference=10) { if (!$this->domain) { $this->status_msg = "Add mail exchanger failed because domain is not set."; return false; } $owner = strtolower($owner); $exchanger = strtolower($exchanger); // Make sure $owner is one of the A records for this domain. if (!$this->get_zone_records()) { $this->status_msg = "Add mail exchanger failed because get_records() failed."; return false; } $OK = false; foreach($this->records['A'] as $record) { if ((in_array($owner, $record)) || (in_array($owner.".", $record))) { $OK = true; break; } } if (!$OK) { $this->status_msg = "Add mail exchanger failed because owner must be" ." an existing A record."; return false; } // Make sure $preference is between 10 and 100. if ((!ereg("^[0-9]{2,3}$", $preference)) || ($preference < 10) || ($preference > 100)) { $this->status_msg = "Add mail exchanger failed because of invalid preference. 10 - 100"; return false; } // Make sure $exchanger is not empty or an IP address. if (!ereg("[a-z]", $exchanger)) { $this->status_msg = "Add mail exchanger failed because of invalid exchanger."; return false; } // Step 1. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_mx_host.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Add mail exchanger step 1 https request failed."; return false; } // Step 2. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_mx_pref.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/wizard_mx_host.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['info[new_domain]'] = $owner; $this->http->postvars['info[preference]'] = $preference; if (!$this->http->fetch($this->url)) { $this->status_msg = "Add mail exchanger step 2 https request failed."; return false; } // Step 3. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_mx_processor.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/wizard_mx_exchange.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['info[new_exchange_dname]'] = $exchanger; $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Add mail exchanger step 4 https request failed."; return false; } return true; } // Change an existing mail exchanger (mx) record. // If you want to change the owner, then don't use this method. Instead, // delete the one you don't want and add the one you do want. function update_mail_exchanger($owner, $exchanger, $preference=10) { if (!$this->domain) { $this->status_msg = "Update mail exchanger failed because domain is not set."; return false; } $owner = trim(strtolower($owner)); $exchanger = trim(strtolower($exchanger)); if (!$this->records) { if (!$this->get_record_ids()) { $this->status_msg = "Delete mail exchanger because get_record_ids failed."; return false; } } // Make sure $owner is one of the MX records for this domain, and get the ID. if (!$this->get_zone_records()) { $this->status_msg = "Update mail exchanger failed because get_records() failed."; return false; } $OK = false; foreach($this->records['MX'] as $record) { if (($record['name'] == $owner) || ($record['name'] == ($owner."."))) { $id = $record['id']; $OK = true; break; } } if (!$OK) { $this->status_msg = "Update mail exchanger failed because '".$owner."' must be" ." an existing MX record."; return false; } // Make sure $preference is between 10 and 100. if ((!ereg("^[0-9]{2,3}$", $preference)) || ($preference < 10) || ($preference > 100)) { $this->status_msg = "Update mail exchanger failed because of invalid preference. 10 - 100"; return false; } // Make sure $exchanger is not empty or an IP address. if (!ereg("[a-z]", $exchanger)) { $this->status_msg = "Update mail exchanger failed because of invalid exchanger."; return false; } // Step 1. Set the record id to modify. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/record_list_processor.php?type=mx&id=".$id."&action=edit_mx"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Update mail exchanger step 1 https request failed."; return false; } // Step 2. Step 1 returns a redirect to this step -- does not work // without this step. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_edmx_data.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Update mail exchanger step 2 https request failed."; return false; } // Step 3. usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_edmx_processor.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['info[new_owner]'] = $owner; $this->http->postvars['info[new_preference]'] = $preference; $this->http->postvars['info[new_exchange_dname]'] = $exchanger; $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Update mail exchanger step 3 https request failed."; return false; } return true; } // Delete a mail exchanger from the domain. // NOTE: If the owner is the root A record, then pass the whole domain name. // If the owner is a sub, then pass only the sub name. That is, do not // append the domain name to the sub. // Examples: // $sbdns->delete_mail_exchanger("troywolf.com"); // $sbdns->delete_mail_exchanger("mail"); function delete_mail_exchanger($owner) { if (!$this->domain) { $this->status_msg = "Delete mail exchanger failed because domain is not set."; return false; } $owner = strtolower($owner); if (!$this->records) { if (!$this->get_record_ids()) { $this->status_msg = "Delete mail exchanger because get_record_ids failed."; return false; } } // Find ID. $id = false; foreach($this->records['MX'] as $record) { if (($record['name'] == $owner) || ($record['name'] == ($owner."."))) { $id = $record['id']; break; } } if (!$id) { $this->status_msg = "Delete mail exchanger failed because '".$owner."' not found in your zone's MX records."; return false; } // Step 1. $this->http->clean(); usleep(500000 * $this->delay_factor); $this->url = "https://secure.serverbeach.com/mysb/dns/record_list_processor.php?type=mx&id=".$id."&action=del_mx"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Delete mail exchanger step 1 https request failed."; return false; } // Step 2. $this->http->clean(); usleep(500000 * $this->delay_factor); $this->url = "https://secure.serverbeach.com/mysb/dns/wizard_delmx_processor.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Cookie'] = $this->phpsessid; $this->http->postvars['confirmed'] = "true"; if (!$this->http->fetch($this->url)) { $this->status_msg = "Delete mail exchanger step 2 https request failed."; return false; } return true; } // Retreive the zone file text. Also used by get_zone_records(). function get_zone_file() { if (!$this->domain) { $this->status_msg = "Get zone file failed because domain is not set."; return false; } $this->http->clean(); usleep(500000 * $this->delay_factor); $this->url = "https://secure.serverbeach.com/mysb/dns/zone_file.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/index.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Get zone file https request failed."; return false; } $posA = strpos($this->http->body, '$ttl'); $posB = strpos($this->http->body, ' $posB)) { $this->status_msg = "Get zone file failed to find zone data in returned body."; return false; } $this->zone = substr($this->http->body, $posA, $posB - $posA); return $this->zone; } // Parse the zone file to find all the NS, A, CNAME, and MX records. // Creates a $this->records array. You should print out the array to // see what it looks like and how to work with it. Used by get_record_ids(). function get_zone_records() { if (!$this->zone) { if (!$this->get_zone_file()) { $this->status_msg = "Get zone records failed because get_zone_file failed."; return false; } } $lines = split("\n",$this->zone); #echo "
"; print_r($lines); echo "
"; foreach($lines as $idx=>$line) { if (($idx > 2) && (strpos($line, "IN"))) { while(strpos($line, " ") !== false) { $line = str_replace(" ", " ", $line); } $parts = split(" ", $line); if ($parts[2] == "MX") { $this->records[trim($parts[2])][] = array("id"=>null, "name"=>trim($parts[0]),"target"=>trim($parts[4]), "preference"=>trim($parts[3])); } else { $this->records[trim($parts[2])][] = array("id"=>null, "name"=>trim($parts[0]), "target"=>trim($parts[3])); } } } #echo "
"; print_r($this->records); echo "
"; return true; } // The ability of this class to update and delete A,CNAME, and MX records // depends on this method in order to know the SB ID of the record. // This is the most likely method to break because screen-scraping is a // brittle activity that can be broken simply by SB changing the page layout. // If this method stops working for you, check for an updated class at // www.troywolf.com. function get_record_ids() { // We need to make sure set_domain() has been called. // We also need to have records, so the record check will indirectly // ensure that the domain has been set. However, since it could be a // common mistake to forget to set the domain first, go ahead and make // this check here. if (!$this->domain) { $this->status_msg = "Get record ids failed because domain is not set."; return false; } if (count($this->records) == 0) { if (!$this->get_zone_records()) { $this->status_msg = "Get zone record ids failed because get_zone_records failed."; return false; } } // Get the record list HTML so we can parse out the ids. This will be fun. ;) usleep(500000 * $this->delay_factor); $this->http->clean(); $this->url = "https://secure.serverbeach.com/mysb/dns/record_list.php"; $this->http->headers['Referer'] = "https://secure.serverbeach.com/mysb/dns/index.php"; $this->http->headers['Cookie'] = $this->phpsessid; if (!$this->http->fetch($this->url)) { $this->status_msg = "Get record list ids https request failed."; return false; } // This will get the SB ids for the A and CNAME records. $scraped_table = http::table_into_array($this->http->body, "edit_sub", 1, ""); for($idx = 2; $idx < count($scraped_table); $idx++) { $links = $scraped_table[$idx][2]; $posA = strpos($links, "?type=")+6; $posB = strpos($links, "&id", $posA); $rectype = strtoupper(substr($links, $posA, $posB-$posA)); $posA = strpos($links, "&id=")+4; $posB = strpos($links, "&action", $posA); $id = substr($links, $posA, $posB-$posA); foreach($this->records[$rectype] as $key=>$record) { $x = trim($scraped_table[$idx][0]); if (($x == $record['name'].".".$this->domain) || ($x."." == $record['name'])) { $this->records[$rectype][$key]['id'] = $id; break; } } } // This will get the SB ids for the MX records. $scraped_table = http::table_into_array($this->http->body, "?type=mx", 1, ""); for($idx = 2; $idx < count($scraped_table); $idx++) { $links = $scraped_table[$idx][3]; $posA = strpos($links, "&id=")+4; $posB = strpos($links, "&action", $posA); $id = substr($links, $posA, $posB-$posA); foreach($this->records['MX'] as $key=>$record) { $x = trim($scraped_table[$idx][0]); if (($x == $record['name'].".".$this->domain) || ($x."." == $record['name'])) { $this->records['MX'][$key]['id'] = $id; break; } } } return true; } // Useful function for debugging. Add whatever you want to this. function dump() { echo "

Status

".$this->http->status; echo "

HTTP Header returned

".$this->http->header."
"; echo "

HTTP Body returned

".$this->http->body; echo "

http object log

".$this->http->log; } } ?>