inc/record.inc.php
changeset 82 c255196bc447
parent 81 c72d6d51f3d3
child 86 0205771bf84c
--- a/inc/record.inc.php	Wed Mar 12 20:45:56 2008 +0000
+++ b/inc/record.inc.php	Tue Mar 25 22:45:31 2008 +0000
@@ -19,86 +19,59 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+function count_zone_records($zone_id) {
+	global $db;
+	$sqlq = "SELECT COUNT(id) FROM records WHERE domain_id = ".$db->quote($zone_id);
+	$record_count = $db->queryOne($sqlq);
+	return $record_count;
+}
+
 function update_soa_serial($domain_id)
 {
-    global $db;
-	/*
-	 * THIS CODE ISNT TESTED THROUGH MUCH YET!
-	 * !!!!!!! BETACODE !!!!!!!!!!
-	 * Code committed by DeViCeD, Thanks a lot!
-	 * Heavily hax0red by Trancer/azurazu
-	 *
-	 * First we have to check, wheather current searial number 
-	 * was already updated on the other nameservers.
-	 * If field 'notified_serial' is NULL, then I guess domain is
-	 * NATIVE and we don't have any secondary nameservers for this domain.
-	 * NOTICE: Serial number *will* be RFC1912 compilant after update 
-	 * NOTICE: This function will allow only 100 DNS zone transfers ;-)
-	 * YYYYMMDDnn
-	 */
+	global $db;
 
 	$sqlq = "SELECT notified_serial FROM domains WHERE id = ".$db->quote($domain_id);
 	$notified_serial = $db->queryOne($sqlq);
 
 	$sqlq = "SELECT content FROM records WHERE type = 'SOA' AND domain_id = ".$db->quote($domain_id);
 	$content = $db->queryOne($sqlq);
-    $need_to_update = false;
-	
+	$need_to_update = false;
+
 	// Getting the serial field.
 	$soa = explode(" ", $content);
-	
-	if(empty($notified_serial))
-    {
-        // Ok native replication, so we have to update.
-        $need_to_update = true;
-    }
-    elseif($notified_serial >= $soa[2])
-    {
-        $need_to_update = true;
-    }
-    elseif(strlen($soa[2]) != 10)
-    {
-        $need_to_update = true;
-    }
-    else
-    {
-        $need_to_update = false;
-    }
-    if($need_to_update)
-    {
-        // Ok so we have to update it seems.
-        $current_serial = $soa[2];
-        
-		/*
-		 * What we need here (for RFC1912) is YEAR, MONTH and DAY
-		 * so let's get it ...
-		 */
+
+	if(empty($notified_serial)) {
+		// Ok native replication, so we have to update.
+		$need_to_update = true;
+	} elseif($notified_serial >= $soa[2]) {
+		$need_to_update = true;
+	} elseif(strlen($soa[2]) != 10) {
+		$need_to_update = true;
+	} else {
+		$need_to_update = false;
+	}
+
+	if($need_to_update) {
+		// Ok so we have to update it seems.
+		$current_serial = $soa[2];
 		$new_serial = date('Ymd'); // we will add revision number later
 
-		if(strncmp($new_serial, $current_serial, 8) === 0)
-		{
-            /*
-             * Ok, so we already made updates tonight
-             * let's just increase the revision number
-             */				
-            $revision_number = (int) substr($current_serial, -2);
-            if ($revision_number == 99) return false; // ok, we cannot update anymore tonight
-            ++$revision_number;
-            // here it is ... same date, new revision
-            $new_serial .= str_pad($revision_number, 2, "0", STR_PAD_LEFT);	
-		}
- 		else
-		{
-            /*
+		if(strncmp($new_serial, $current_serial, 8) === 0) {
+			$revision_number = (int) substr($current_serial, -2);
+			if ($revision_number == 99) return false; // ok, we cannot update anymore tonight
+			++$revision_number;
+			// here it is ... same date, new revision
+			$new_serial .= str_pad($revision_number, 2, "0", STR_PAD_LEFT);	
+		} else {
+			/*
 			 * Current serial is not RFC1912 compilant, so let's make a new one
 			 */
- 			$new_serial .= '00';
+			$new_serial .= '00';
 		}
-        $soa[2] = $new_serial; // change serial in SOA array
+		$soa[2] = $new_serial; // change serial in SOA array
 		$new_soa = "";		
 		// build new soa and update SQL after that
-		for ($i = 0; $i < count($soa); $i++) 
-		{	
+		for ($i = 0; $i < count($soa); $i++) {	
 			$new_soa .= $soa[$i] . " "; 
 		}
 		$sqlq = "UPDATE records SET content = ".$db->quote($new_soa)." WHERE domain_id = ".$db->quote($domain_id)." AND type = 'SOA'";
@@ -112,147 +85,123 @@
  * This function validates it if correct it inserts it into the database.
  * return values: true if succesful.
  */
-function edit_record($recordid, $zoneid, $name, $type, $content, $ttl, $prio)
-{
-	global $db;
-  	if($content == "")
-  	{
-  		error(ERR_RECORD_EMPTY_CONTENT);
-  	}
-  	// Edits the given record (validates specific stuff first)
-	if (!xs(recid_to_domid($recordid)))
-	{
-		error(ERR_RECORD_ACCESS_DENIED);
+function edit_record($record) {
+
+	if (verify_permission(zone_content_edit_others)) { $perm_content_edit = "all" ; }
+	elseif (verify_permission(zone_content_edit_own)) { $perm_content_edit = "own" ; }
+	else { $perm_content_edit = "none" ; }
+
+	$user_is_zone_owner = verify_user_is_owner_zoneid($record['zid']);
+	$zone_type = get_domain_type($record['zid']);
+
+	if ( $zone_type == "SLAVE" || $perm_content_edit == "none" || $perm_content_edit == "own" && $user_is_zone_owner == "0" ) {
+		return _("You are not allowed to edit this record.") ; 
+	} else {
+		if($record['content'] == "") {
+			return _("Error: content field may not be empty.") ; 
+		}
+		global $db;
+		// TODO: no need to check for numeric-ness of zone id if we check with validate_input as well?
+		if (is_numeric($record['zid'])) {
+			validate_input($record['zid'], $record['type'], $record['content'], $record['name'], $record['prio'], $record['ttl']);
+			$query = "UPDATE records 
+					SET name=".$db->quote($record['name']).", 
+					type=".$db->quote($record['type']).", 
+					content=".$db->quote($record['content']).", 
+					ttl=".$db->quote($record['ttl']).", 
+					prio=".$db->quote($record['prio']).", 
+					change_date=".$db->quote(time())." 
+					WHERE id=".$db->quote($record['rid']);
+			$result = $db->Query($query);
+			if (PEAR::isError($result)) {
+				error($result->getMessage());
+				return false;
+			} elseif ($record['type'] != 'SOA') {
+				update_soa_serial($record['zid']);
+			}
+			return true;
+		}
+		else
+		{
+			// TODO change to error style as above (returning directly)
+			error(sprintf(ERR_INV_ARGC, "edit_record", "no zoneid given"));
+		}
 	}
-	if (is_numeric($zoneid))
-	{
-		validate_input($zoneid, $type, $content, $name, $prio, $ttl);
-                $change = time();
-                $db->query("UPDATE records set name=".$db->quote($name).", type=".$db->quote($type).", content=".$db->quote($content).", ttl=".$db->quote($ttl).", prio=".$db->quote($prio).", change_date=".$db->quote($change)." WHERE id=".$db->quote($recordid));
-		
-		/*
-		 * Added by DeViCeD - Update SOA Serial number
-		 * There should be more checks
-		 */
-		if ($type != 'SOA')
-		{
-			update_soa_serial($zoneid);
-		}
-		return true;
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARGC, "edit_record", "no zoneid given"));
-	}
-
+	return true;
 }
 
 
-function add_record_owner($zoneid,$userid,$recordid)
-{
-	global $db;
-	if (!xs($zoneid))
-	{
-		error(ERR_RECORD_ACCESS_DENIED);
-	}
-	if (is_numeric($zoneid) || is_numeric($userid) || is_numeric($recordid))
-	{
-		$db->query("INSERT INTO record_owners (user_id, record_id) VALUES (".$db->quote($userid).", ".$db->quote($recordid).")");
-		return true;
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARGC, "add_record_owner", "at least one of the arguments is not numeric"));
-	}
-}
-
-function delete_record_owner($zoneid,$rowid,$recordid)
-{
-	global $db;
-	if (!xs($zoneid))
-	{
-		error(ERR_RECORD_ACCESS_DENIED);
-	}
-	if (is_numeric($zoneid) || is_numeric($rowid) || is_numeric($recordid))
-	{
-		$db->query("DELETE FROM record_owners WHERE id=".$db->quote($rowid)." AND record_id=".$db->quote($recordid));
-		return true;
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARGC, "delete_record_owner", "at least one of the arguments is not numeric"));
-	}
-}
-
 /*
  * Adds a record.
  * This function validates it if correct it inserts it into the database.
  * return values: true if succesful.
  */
-function add_record($zoneid, $name, $type, $content, $ttl, $prio)
-{
-
+function add_record($zoneid, $name, $type, $content, $ttl, $prio) {
 	global $db;
-	if (!xs($zoneid))
-	{
-		error(ERR_RECORD_ACCESS_DENIED);
-	}
-	if (is_numeric($zoneid))
-	{
-		// Check the user input.
-		validate_input($zoneid, $type, $content, $name, $prio, $ttl);
+
+	if (verify_permission(zone_content_edit_others)) { $perm_content_edit = "all" ; }
+	elseif (verify_permission(zone_content_edit_own)) { $perm_content_edit = "own" ; }
+	else { $perm_content_edit = "none" ; }
+
+	$user_is_zone_owner = verify_user_is_owner_zoneid($zoneid);
+	$zone_type = get_domain_type($zoneid);
 
-		// Generate new timestamp for the daemon
-		$change = time();
-		
-		// Execute query.
-		$db->query("INSERT INTO records (domain_id, name, type, content, ttl, prio, change_date) VALUES (".$db->quote($zoneid).", ".$db->quote($name).", ".$db->quote($type).", ".$db->quote($content).", ".$db->quote($ttl).", ".$db->quote($prio).", ".$db->quote($change).")");
-		if ($type != 'SOA')
-		{
-			update_soa_serial($zoneid);
+        if ( $zone_type == "SLAVE" || $perm_content_edit == "none" || $perm_content_edit == "own" && $user_is_zone_owner == "0" ) {
+		error(ERR_PERM_ADD_RECORD);
+		return false;
+	} else {
+		if (validate_input($zoneid, $type, $content, $name, $prio, $ttl) ) {
+			$change = time();
+			$query = "INSERT INTO records VALUES ('',"
+						. $db->quote($zoneid) . ","
+						. $db->quote($name) . "," 
+						. $db->quote($type) . "," 
+						. $db->quote($content) . ","
+						. $db->quote($ttl) . ","
+						. $db->quote($prio) . ","
+						. $db->quote($change) . ")";
+			$response = $db->query($query);
+			if (PEAR::isError($response)) {
+				error($response->getMessage());
+				return false;
+			} else {
+				if ($type != 'SOA') { update_soa_serial($zoneid); }
+				return true;
+			}
+		} else {
+			return false;
 		}
 		return true;
 	}
-	else
-	{
-		error(sprintf(ERR_INV_ARG, "add_record"));
-	}
 }
 
 
 function add_supermaster($master_ip, $ns_name, $account)
 {
         global $db;
-        if (!is_valid_ip($master_ip) && !is_valid_ip6($master_ip))
-        {
-                error(sprintf(ERR_INV_ARGC, "add_supermaster", "No or no valid ipv4 or ipv6 address given."));
+        if (!is_valid_ip($master_ip) && !is_valid_ip6($master_ip)) {
+                error(ERR_DNS_IP);
+		return false;
         }
-        if (!is_valid_hostname($ns_name))
-        {
+        if (!is_valid_hostname($ns_name)) {
                 error(ERR_DNS_HOSTNAME);
+		return false;
         }
-	if (!validate_account($account))
-	{
+	if (!validate_account($account)) {
 		error(sprintf(ERR_INV_ARGC, "add_supermaster", "given account name is invalid (alpha chars only)"));
+		return false;
 	}
-        if (supermaster_exists($master_ip))
-        {
-                error(sprintf(ERR_INV_ARGC, "add_supermaster", "supermaster already exists"));
-        }
-        else
-        {
+        if (supermaster_exists($master_ip)) {
+                error(ERR_SM_EXISTS);
+		return false;
+        } else {
                 $db->query("INSERT INTO supermasters VALUES (".$db->quote($master_ip).", ".$db->quote($ns_name).", ".$db->quote($account).")");
                 return true;
         }
 }
 
-function delete_supermaster($master_ip)
-{
-        global $db;
-        if (!level(5))
-        {
-                error(ERR_LEVEL_5);
-        }
+function delete_supermaster($master_ip) {
+	global $db;
         if (is_valid_ip($master_ip) || is_valid_ip6($master_ip))
         {
                 $db->query("DELETE FROM supermasters WHERE ip = ".$db->quote($master_ip));
@@ -267,10 +216,6 @@
 function get_supermaster_info_from_ip($master_ip)
 {
 	global $db;
-        if (!level(5))
-        {
-                error(ERR_LEVEL_5);
-        }
         if (is_valid_ip($master_ip) || is_valid_ip6($master_ip))
 	{
 	        $result = $db->queryRow("SELECT ip,nameserver,account FROM supermasters WHERE ip = ".$db->quote($master_ip));
@@ -289,48 +234,57 @@
         }
 }
 
+function get_record_details_from_record_id($rid) {
+
+	global $db;
+
+	$query = "SELECT * FROM records WHERE id = " . $db->quote($rid) ;
+
+	$response = $db->query($query);
+	if (PEAR::isError($response)) { error($response->getMessage()); return false; }
+
+	while ($r = $response->fetchRow()) {
+		$return[] = array(
+			"rid"		=>	$r['id'],
+			"zid"		=>	$r['domain_id'],
+			"name"		=>	$r['name'],
+			"type"		=>	$r['type'],
+			"content"	=>	$r['content'],
+			"ttl"		=>	$r['ttl'],
+			"prio"		=>	$r['prio'],
+			"change_date"	=>	$r['change_date']);
+	}
+	return $return;
+}
 
 /*
  * Delete a record by a given id.
  * return values: true, this function is always succesful.
  */
-function delete_record($id)
+function delete_record($rid)
 {
 	global $db;
 
-	// Check if the user has access.
-	if (!xs(recid_to_domid($id)))
-	{
-		error(ERR_RECORD_ACCESS_DENIED);
-	}
+	if (verify_permission(zone_content_edit_others)) { $perm_content_edit = "all" ; } 
+	elseif (verify_permission(zone_content_edit_own)) { $perm_content_edit = "own" ; } 
+	else { $perm_content_edit = "none" ; }
 
-	// Retrieve the type of record to see if we can actually remove it.
-	$recordtype = get_recordtype_from_id($id);
+	// Determine ID of zone first.
+	$record = get_record_details_from_record_id($rid);
+	$user_is_zone_owner = verify_user_is_owner_zoneid($record['zid']);
 
-	// If the record type is NS and the user tries to delete it while ALLOW_NS_EDIT is set to 0
-	// OR
-	// check if the name of the record isnt the domain name (if so it should delete all records)
-	// OR
-	// check if we are dealing with a SOA field (same story as NS)
-	if (($recordtype == "NS" && $GLOBALS["ALLOW_NS_EDIT"] != 1 && (get_name_from_record_id($id) == get_domain_name_from_id(recid_to_domid($id)))) || ($recordtype == "SOA" && $GLOBALS["ALLOW_SOA_EDIT"] != 1))
-	{
-		error(sprintf(ERR_RECORD_DELETE_TYPE_DENIED, $recordtype));
-
-	}
-	if (is_numeric($id))
-	{
-	    $did = recid_to_domid($id);
-		$db->query('DELETE FROM records WHERE id=' . $db->quote($id) );
-		if ($type != 'SOA')
-		{
-			update_soa_serial($did);
+	if ( $perm_content_edit == "all" || ($perm_content_edit == "own" && $user_is_zone_owner == "0" )) {
+		if ($record['type'] == "SOA") {
+			error(_('You are trying to delete the SOA record. If are not allowed to remove it, unless you remove the entire zone.'));
+		} else {
+			$quote = "DELETE FROM records WHERE id = " . $db->quote($rid);
+			$response = $db->query($query);
+			if (PEAR::isError($response)) { error($response->getMessage()); return false; }
+			return true;
 		}
-        // $id doesnt exist in database anymore so its deleted or just not there which means "true"	
-		return true;
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARG, "delete_record"));
+	} else {
+		error(ERR_PERM_DEL_RECORD);
+		return false;
 	}
 }
 
@@ -348,104 +302,87 @@
  */
 function add_domain($domain, $owner, $webip, $mailip, $empty, $type, $slave_master)
 {
+	if(verify_permission(zone_master_add)) { $zone_master_add = "1" ; } ;
+	if(verify_permission(zone_slave_add)) { $zone_slave_add = "1" ; } ;
 
-	global $db;
+	// TODO: make sure only one is possible if only one is enabled
+	if($zone_master_add == "1" || $zone_master_add == "1") {
 
-	if (!level(5))
-	{
-		error(ERR_LEVEL_5);
-	}
+		global $db;
+		if (($domain && $owner && $webip && $mailip) || 
+				($empty && $owner && $domain) || 
+				(eregi('in-addr.arpa', $domain) && $owner) || 
+				$type=="SLAVE" && $domain && $owner && $slave_master) {
+
+			$response = $db->query("INSERT INTO domains (name, type) VALUES (".$db->quote($domain).", ".$db->quote($type).")");
+			if (PEAR::isError($response)) { error($response->getMessage()); return false; }
 
-	// If domain, owner and mailip are given
-	// OR
-	// empty is given and owner and domain
-	// OR
-	// the domain is an arpa record and owner is given
-	// OR
-	// the type is slave, domain, owner and slave_master are given
-	// THAN
-	// Continue this function
-	if (($domain && $owner && $webip && $mailip) || ($empty && $owner && $domain) || (eregi('in-addr.arpa', $domain) && $owner) || $type=="SLAVE" && $domain && $owner && $slave_master)
-	{
-                // First insert zone into domain table
-                $db->query("INSERT INTO domains (name, type) VALUES (".$db->quote($domain).", ".$db->quote($type).")");
+			$domain_id = $db->lastInsertId('domains', 'id');
+			if (PEAR::isError($domain_id)) { error($id->getMessage()); return false; }
+
+			$response = $db->query("INSERT INTO zones (domain_id, owner) VALUES (".$db->quote($domain_id).", ".$db->quote($owner).")");
+			if (PEAR::isError($response)) { error($response->getMessage()); return false; }
 
-                // Determine id of insert zone (in other words, find domain_id)
-                $iddomain = $db->lastInsertId('domains', 'id');
-                if (PEAR::isError($iddomain)) {
-                        die($id->getMessage());
-                }
-
-                // Second, insert into zones tables
-                $db->query("INSERT INTO zones (domain_id, owner) VALUES (".$db->quote($iddomain).", ".$db->quote($owner).")");
-
-		if ($type == "SLAVE")
-		{
-			$db->query("UPDATE domains SET master = ".$db->quote($slave_master)." WHERE id = ".$db->quote($iddomain));
-			
-			// Done
-			return true;
-		}
-		else
-		{
-			// Generate new timestamp. We need this one anyhow.
-			$now = time();
+			if ($type == "SLAVE") {
+				$response = $db->query("UPDATE domains SET master = ".$db->quote($slave_master)." WHERE id = ".$db->quote($domain_id));
+				if (PEAR::isError($response)) { error($response->getMessage()); return false; }
+				return true;
+			} else {
+				$now = time();
+				if ($empty && $domain_id) {
+					$ns1 = $GLOBALS['NS1'];
+					$hm  = $GLOBALS['HOSTMASTER'];
+					$ttl = $GLOBALS['DEFAULT_TTL'];
 
-			if ($empty && $iddomain)
-			{
-				// If we come into this if statement we dont want to apply templates.
-				// Retrieve configuration settings.
-				$ns1 = $GLOBALS["NS1"];
-				$hm  = $GLOBALS["HOSTMASTER"];
-				$ttl = $GLOBALS["DEFAULT_TTL"];
+					$query = "INSERT INTO records VALUES (''," 
+							. $db->quote($domain_id) . "," 
+							. $db->quote($domain) . "," 
+							. $db->quote($ns1.' '.$hm.' 1') 
+							. ",'SOA',"
+							. $db->quote($ttl) 
+							. ", 0, "
+							. $db->quote($now).")";
+					$response = $db->query($query);
+					if (PEAR::isError($response)) { error($response->getMessage()); return false; }
+				} elseif ($domain_id) {
+					global $template;
 
-				// Build and execute query
-				$sql = "INSERT INTO records (domain_id, name, content, type, ttl, prio, change_date) VALUES (".$db->quote($iddomain).", ".$db->quote($domain).", ".$db->quote($ns1.' '.$hm.' 1').", 'SOA', ".$db->quote($ttl).", 0, ".$db->quote($now).")";
-				$db->query($sql);
-
-				// Done
-				return true;
-			}
-			elseif ($iddomain)
-			{
-				// If we are here we want to apply templates.
-				global $template;
+					foreach ($template as $r) {
+						if ((eregi('in-addr.arpa', $domain) && ($r["type"] == "NS" || $r["type"] == "SOA")) || (!eregi('in-addr.arpa', $domain)))
+						{
+							$name     = parse_template_value($r["name"], $domain, $webip, $mailip);
+							$type     = $r["type"];
+							$content  = parse_template_value($r["content"], $domain, $webip, $mailip);
+							$ttl      = $r["ttl"];
+							$prio     = intval($r["prio"]);
 
-				// Iterate over the template and apply it for each field.
-				foreach ($template as $r)
-				{
-					// Same type of if statement as previous.
-					if ((eregi('in-addr.arpa', $domain) && ($r["type"] == "NS" || $r["type"] == "SOA")) || (!eregi('in-addr.arpa', $domain)))
-					{
-						// Parse the template.
-						$name     = parse_template_value($r["name"], $domain, $webip, $mailip);
-						$type     = $r["type"];
-						$content  = parse_template_value($r["content"], $domain, $webip, $mailip);
-						$ttl      = $r["ttl"];
-						$prio     = intval($r["prio"]);
+							if (!$ttl) {
+								$ttl = $GLOBALS["DEFAULT_TTL"];
+							}
 
-						// If no ttl is given, use the default.
-						if (!$ttl)
-						{
-							$ttl = $GLOBALS["DEFAULT_TTL"];
+							$query = "INSERT INTO records VALUES (''," 
+									. $db->quote($domain_id) . ","
+									. $db->quote($name) . ","
+									. $db->quote($content) . ","
+									. $db->quote($type) . ","
+									. $db->quote($ttl) . ","
+									. $db->quote($prio) . ","
+									. $db->quote($now) . ")";
+							$response = $db->query($query);
+							if (PEAR::isError($response)) { error($response->getMessage()); return false; }
 						}
-
-						$sql = "INSERT INTO records (domain_id, name, content, type, ttl, prio, change_date) VALUES (".$db->quote($iddomain).", ".$db->quote($name).", ".$db->quote($content).", ".$db->quote($type).", ".$db->quote($ttl).", ".$db->quote($prio).", ".$db->quote($now).")";
-						$db->query($sql);
 					}
-				}
-				// All done.
-				return true;
-			 }
-			 else
-			 {
-				error(sprintf(ERR_INV_ARGC, "add_domain", "could not create zone"));
-			 }
+					return true;
+				 } else {
+					error(sprintf(ERR_INV_ARGC, "add_domain", "could not create zone"));
+				 }
+			}
+		} else {
+			error(sprintf(ERR_INV_ARG, "add_domain"));
 		}
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARG, "add_domain"));
+	} else {
+		error(ERR_PERM_ADD_ZONE_MASTER);
+		return false;
 	}
 }
 
@@ -458,24 +395,23 @@
 {
 	global $db;
 
-	if (!level(5))
-	{
-		error(ERR_LEVEL_5);
-	}
+	if (verify_permission(zone_content_edit_others)) { $perm_edit = "all" ; }
+	elseif (verify_permission(zone_content_edit_own)) { $perm_edit = "own" ; }
+	else { $perm_edit = "none" ; }
+	$user_is_zone_owner = verify_user_is_owner_zoneid($id);
 
-	// See if the ID is numeric.
-	if (is_numeric($id))
-	{
-		$db->query("DELETE FROM zones WHERE domain_id=".$db->quote($id));
-		$db->query("DELETE FROM domains WHERE id=".$db->quote($id));
-		$db->query("DELETE FROM records WHERE domain_id=".$db->quote($id));
-		// Nothing in the database. If the delete deleted 0 records it means the id is just not there.
-		// therefore the is no need to check the affectedRows values.
-		return true;
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARGC, "delete_domain", "id must be a number"));
+        if ( $perm_edit == "all" || ( $perm_edit == "own" && $user_is_zone_owner == "1") ) {    
+		if (is_numeric($id)) {
+			$db->query("DELETE FROM zones WHERE domain_id=".$db->quote($id));
+			$db->query("DELETE FROM domains WHERE id=".$db->quote($id));
+			$db->query("DELETE FROM records WHERE domain_id=".$db->quote($id));
+			return true;
+		} else {
+			error(sprintf(ERR_INV_ARGC, "delete_domain", "id must be a number"));
+			return false;
+		}
+	} else {
+		error(ERR_PERM_DEL_ZONE);
 	}
 }
 
@@ -501,93 +437,50 @@
 
 
 /*
- * Sorts a zone by records.
- * return values: the sorted zone.
- */
-function sort_zone($records)
-{
-	$ar_so = array();
-	$ar_ns = array();
-	$ar_mx = array();
-	$ar_mb = array();
-	$ar_ur = array();
-	$ar_ov = array();
-	foreach ($records as $c)
-	{
-		switch(strtoupper($c['type']))
-		{
-			case "SOA":
-				$ar_so[] = $c;
-				break;
-			case "NS":
-				$ar_ns[] = $c;
-				break;
-			case "MX":
-				$ar_mx[] = $c;
-				break;
-			case "MBOXFW":
-				$ar_mb[] = $c;
-				break;
-			case "URL":
-				$ar_ur[] = $c;
-				break;
-			default:
-				$ar_ov[] = $c;
-				break;
-		}
-	}
-
-	$res = array_merge($ar_so, $ar_ns, $ar_mx, $ar_mb, $ar_ur, $ar_ov);
-
-	if (count($records) == count($res))
-	{
-		$records = $res;
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARGC, "sort_zone", "records sorting failed!"));
-	}
-	return $records;
-}
-
-
-/*
  * Change owner of a domain.
- * Function should actually be in users.inc.php. But its more of a record modification than a user modification
  * return values: true when succesful.
  */
-function add_owner($domain, $newowner)
+function add_owner_to_zone($zone_id, $user_id)
 {
 	global $db;
-
-	if (!level(5))
-	{
-		error(ERR_LEVEL_5);
-	}
-
-	if (is_numeric($domain) && is_numeric($newowner) && is_valid_user($newowner))
-	{
-		if($db->queryOne("SELECT COUNT(id) FROM zones WHERE owner=".$db->quote($newowner)." AND domain_id=".$db->quote($domain)) == 0)
+	if ( (verify_permission(zone_meta_edit_others)) || (verify_permission(zone_meta_edit_own)) && verify_user_is_owner_zoneid($_GET["id"])) {
+		// User is allowed to make change to meta data of this zone.
+		if (is_numeric($zone_id) && is_numeric($user_id) && is_valid_user($user_id))
 		{
-			$db->query("INSERT INTO zones (domain_id, owner) VALUES(".$db->quote($domain).", ".$db->quote($newowner).")");
+			if($db->queryOne("SELECT COUNT(id) FROM zones WHERE owner=".$db->quote($user_id)." AND domain_id=".$db->quote($zone_id)) == 0)
+			{
+				$db->query("INSERT INTO zones (domain_id, owner) VALUES(".$db->quote($zone_id).", ".$db->quote($user_id).")");
+			}
+			return true;
+		} else {
+			error(sprintf(ERR_INV_ARGC, "add_owner_to_zone", "$zone_id / $user_id"));
 		}
-		return true;
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARGC, "change_owner", "$domain / $newowner"));
+	} else {
+		return false;
 	}
 }
 
 
-function delete_owner($domain, $owner)
+function delete_owner_from_zone($zone_id, $user_id)
 {
 	global $db;
-	if($db->queryOne("SELECT COUNT(id) FROM zones WHERE owner=".$db->quote($owner)." AND domain_id=".$db->quote($domain)) != 0)
-	{
-		$db->query("DELETE FROM zones WHERE owner=".$db->quote($owner)." AND domain_id=".$db->quote($domain));
+	if ( (verify_permission(zone_meta_edit_others)) || (verify_permission(zone_meta_edit_own)) && verify_user_is_owner_zoneid($_GET["id"])) {
+		// User is allowed to make change to meta data of this zone.
+		if (is_numeric($zone_id) && is_numeric($user_id) && is_valid_user($user_id))
+		{
+			// TODO: Next if() required, why not just execute DELETE query?
+			if($db->queryOne("SELECT COUNT(id) FROM zones WHERE owner=".$db->quote($user_id)." AND domain_id=".$db->quote($zone_id)) != 0)
+			{
+				$db->query("DELETE FROM zones WHERE owner=".$db->quote($user_id)." AND domain_id=".$db->quote($zone_id));
+			}
+			return true;
+		} else {
+			error(sprintf(ERR_INV_ARGC, "delete_owner_from_zone", "$zone_id / $user_id"));
+		}
+	} else {
+		return false;
 	}
-	return true;
+	
 }
 
 /*
@@ -653,130 +546,37 @@
 function get_name_from_record_id($id)
 {
 	global $db;
-	if (is_numeric($id))
-	{
+	if (is_numeric($id)) {
 		$result = $db->query("SELECT name FROM records WHERE id=".$db->quote($id));
 		$r = $result->fetchRow();
 		return $r["name"];
-	}
-	else
-	{
+	} else {
 		error(sprintf(ERR_INV_ARG, "get_name_from_record_id"));
 	}
 }
 
 
 /*
- * Get all the domains from a database of which the user is the owner.
- * return values: an array with the id of the domain and its name.
- */
-function get_domains_from_userid($id)
-{
-	global $db;
-	if (is_numeric($id))
-	{
-		$a_zones = array();
-
-		// Check for zones the user has full access for (the 
-		// user is owner of the zone.
-
-		$res_full = $db->query("SELECT 
-					domains.id AS domain_id, 
-					domains.name AS name 
-					FROM domains 
-					LEFT JOIN zones ON domains.id=zones.domain_id 
-					WHERE owner=".$db->quote($id)); 
-		
-		// Process the output.
-
-		$numrows = $res_full->numRows();
-		$i=1;
-		if ($numrows > 0) 
-		{
-			$andnot=" AND NOT domains.id IN (";
-			while($r = $res_full->fetchRow()) {
-				
-				// Create array of zone id's and name's the owner
-				// has full access to.
-
-				$a_zones[] = array(
-				"id"            =>              $r["domain_id"],
-				"name"          =>              $r["name"],
-				"partial"	=>		"0"
-				);
-
-				// Create AND NOT for query of zones the user has 
-				// only partial access to. In that query we just 
-				// want to see the zones he has not full access to 
-				// as well.
-
-				$andnot.=$db->quote($r["domain_id"]);
-				if ($i < $numrows) {
-					$andnot.=",";
-					$i++;
-				}
-
-			}
-			$andnot.=")";
-		}
-		else
-		{
-			$andnot="";
-		}
-
-		// Check for zones the user has partial access only to.
-
-		$res_partial = $db->query("SELECT DISTINCT 
-					records.domain_id, 
-					domains.name 
-					FROM records, record_owners, domains 
-					WHERE record_owners.user_id = ".$db->quote($id)." 
-					AND records.id = record_owners.record_id 
-					AND domains.id = records.domain_id
-					".$andnot);
-		
-		// Add these zones to the array as well.
-
-		while ($r = $res_partial->fetchRow())
-		{
-			$a_zones[] = array(
-			"id"            =>              $r["domain_id"],
-			"name"          =>              $r["name"],
-			"partial"	=>		"1"
-			);
-		}
-
-		return $a_zones;
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARGC, "get_domains_from_userid", "This is not a valid userid: $id"));
-	}
-}
-
-
-/*
  * Get domain name from a given id
  * return values: the name of the domain associated with the id.
  */
 function get_domain_name_from_id($id)
 {
 	global $db;
-	if (!xs($id))
-	{
-		error(ERR_RECORD_ACCESS_DENIED);
-	}
+
 	if (is_numeric($id))
 	{
 		$result = $db->query("SELECT name FROM domains WHERE id=".$db->quote($id));
-		if ($result->numRows() == 1)
-		{
+		$rows = $result->numRows() ;
+		if ($rows == 1) {
  			$r = $result->fetchRow();
  			return $r["name"];
-		}
-		else
-		{
+		} elseif ($rows == "0") {
+			error(sprintf("Zone does not exist."));
+			return false;
+		} else {
 	 		error(sprintf(ERR_INV_ARGC, "get_domain_name_from_id", "more than one domain found?! whaaa! BAD! BAD! Contact admin!"));
+			return false;
 		}
 	}
 	else
@@ -785,86 +585,34 @@
 	}
 }
 
-
-/*
- * Get information about a domain name from a given domain id.
- * the function looks up the domainname, the owner of the domain and the number of records in it.
- * return values: an array containing the information.
- */
-function get_domain_info_from_id($id)
-{
-	global $db;
-	if (!xs($id))
-	{
-		error(ERR_RECORD_ACCESS_DENIED);
-	}
-	if (is_numeric($id))
-	{
+function get_zone_info_from_id($zone_id) {
 
-	if ($_SESSION[$id."_ispartial"] == 1) {
-	
-	$sqlq = "SELECT 
-	domains.type AS type,
-	domains.name AS name,
-	users.fullname AS owner,
-	count(record_owners.id) AS aantal
-	FROM domains, users, record_owners, records
-	
-        WHERE record_owners.user_id = ".$db->quote($_SESSION["userid"])."
-        AND record_owners.record_id = records.id
-	AND records.domain_id = ".$db->quote($id)."
+	if (verify_permission(zone_content_view_others)) { $perm_view = "all" ; } 
+	elseif (verify_permission(zone_content_view_own)) { $perm_view = "own" ; }
+	else { $perm_view = "none" ;}
 
-	GROUP BY domains.name, owner, users.fullname, domains.type
-	ORDER BY domains.name";
-	
-	$result = $db->queryRow($sqlq);
+	if ($perm_view == "none") { 
+		error(ERR_PERM_VIEW_ZONE);
+	} else {
+		global $db;
 
-	$ret = array(
-	"name"          =>              $result["name"],
-	"ownerid"       =>              $_SESSION["userid"],
-	"owner"         =>              $result["owner"],
-	"type"		=>		$result["type"],
-	"numrec"        =>              $result["aantal"]
-	);
-
-	return $ret;
+		$query = "SELECT 	domains.type AS type, 
+					domains.name AS name, 
+					domains.master AS master_ip,
+					count(records.domain_id) AS record_count
+					FROM domains, records 
+					WHERE domains.id = " . $db->quote($zone_id) . "
+					AND domains.id = records.domain_id 
+					GROUP BY domains.id";
 
-	} else{
-	
-		// Query that retrieves the information we need.
-		$sqlq = "SELECT 
-			domains.type AS type,
-			domains.name AS name,
-			min(zones.owner) AS ownerid,
-			users.fullname AS owner,
-			count(records.domain_id) AS aantal
-			FROM domains
-			LEFT JOIN records ON domains.id=records.domain_id
-			LEFT JOIN zones ON domains.id=zones.domain_id
-			LEFT JOIN users ON zones.owner=users.id
-			WHERE domains.id=$id
-			GROUP BY domains.name, owner, users.fullname, domains.type, zones.id
-			ORDER BY zones.id";
-
-		// Put the first occurence in an array and return it.
-		$result = $db->queryRow($sqlq);
-
-		//$result["ownerid"] = ($result["ownerid"] == NULL) ? $db->queryOne("select min(id) from users where users.level=10") : $result["ownerid"];
-
-		$ret = array(
-		"name"          =>              $result["name"],
-		"ownerid"       =>              $result["ownerid"],
-		"owner"         =>              $result["owner"],
-		"type"          =>              $result["type"],
-		"numrec"        =>              $result["aantal"]
-		);
-		return $ret;
-	}
-
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARGC, "get_domain_num_records_from_id", "This is not a valid domainid: $id"));
+		$response = $db->queryRow($query);
+		if (PEAR::isError($response)) { error($response->getMessage()); return false; }
+		$return = array(
+			"name"		=>	$response['name'],
+			"type"		=>	$response['type'],
+			"master_ip"	=>	$response['master_ip'],
+			"record_count"	=>	$response['record_count']);
+		return $return;
 	}
 }
 
@@ -877,24 +625,14 @@
 {
 	global $db;
 
-	if (!level(5))
-	{
-		error(ERR_LEVEL_5);
-	}
-	if (is_valid_domain($domain))
-	{
+	if (is_valid_domain($domain)) {
 		$result = $db->query("SELECT id FROM domains WHERE name=".$db->quote($domain));
-		if ($result->numRows() == 0)
-		{
+		if ($result->numRows() == 0) {
 			return false;
-		}
-		elseif ($result->numRows() >= 1)
-		{
+		} elseif ($result->numRows() >= 1) {
 			return true;
 		}
-	}
-	else
-	{
+	} else {
 		error(ERR_DOMAIN_INVALID);
 	}
 }
@@ -902,17 +640,16 @@
 function get_supermasters()
 {
         global $db;
-        $result = $db->query("SELECT ip, nameserver, account FROM supermasters");
+        
+	$result = $db->query("SELECT ip, nameserver, account FROM supermasters");
+	if (PEAR::isError($response)) { error($response->getMessage()); return false; }
+
         $ret = array();
 
-        if($result->numRows() == 0)
-        {
+        if($result->numRows() == 0) {
                 return -1;
-        }
-        else
-        {
-                while ($r = $result->fetchRow())
-                {
+        } else {
+                while ($r = $result->fetchRow()) {
                         $ret[] = array(
                         "master_ip"     => $r["ip"],
                         "ns_name"       => $r["nameserver"],
@@ -926,10 +663,6 @@
 function supermaster_exists($master_ip)
 {
         global $db;
-        if (!level(5))
-        {
-                error(ERR_LEVEL_5);
-        }
         if (is_valid_ip($master_ip) || is_valid_ip6($master_ip))
         {
                 $result = $db->query("SELECT ip FROM supermasters WHERE ip = ".$db->quote($master_ip));
@@ -949,206 +682,92 @@
 }
 
 
-/*
- * Get all domains from the database 
- * This function gets all the domains from the database unless a user id is below 5.
- * if a user id is below 5 this function will only retrieve records for that user.
- * return values: the array of domains or -1 if nothing is found.
- */
-function get_domains($userid=true,$letterstart='all',$rowstart=0,$rowamount=999999)
+function get_zones($perm,$userid=0,$letterstart=all,$rowstart=0,$rowamount=999999) 
 {
 	global $db;
 	global $sql_regexp;
-	if((!level(5) || !$userid) && !level(10) && !level(5))
-	{
-		$add = " AND zones.owner=".$db->quote($_SESSION["userid"]);
+	if ($perm != "own" && $perm != "all") {
+		error(ERR_PERM_VIEW_ZONE);
+		return false;
 	}
 	else
 	{
-		$add = "";
+		if ($perm == "own") {
+			$sql_add = " AND zones.domain_id = domains.id
+				AND zones.owner = ".$db->quote($userid);
+		}
+		if ($letterstart!=all && $letterstart!=1) {
+			$sql_add .=" AND domains.name LIKE ".$db->quote($letterstart."%")." ";
+		} elseif ($letterstart==1) {
+			$sql_add .=" AND substring(domains.name,1,1) ".$sql_regexp." '^[[:digit:]]'";
+		}
 	}
-
-	$sqlq = "SELECT domains.id AS domain_id,
-	min(zones.owner) AS owner,
-	count(DISTINCT records.id) AS aantal,
-	domains.name AS domainname
-	FROM domains
-	LEFT JOIN zones ON domains.id=zones.domain_id 
-	LEFT JOIN records ON records.domain_id=domains.id
-	WHERE 1=1 $add ";
-	if ($letterstart!='all' && $letterstart!=1) {
-	   $sqlq.=" AND substring(domains.name,1,1) ".$sql_regexp." ".$db->quote("^".$letterstart);
-	} elseif ($letterstart==1) {
-	   $sqlq.=" AND substring(domains.name,1,1) ".$sql_regexp." '^[[:digit:]]'";
-	}
-	$sqlq.=" GROUP BY domainname, domains.id
-	ORDER BY domainname";
-
+	
+	$sqlq = "SELECT domains.id, 
+			domains.name,
+			domains.type,
+			COUNT(DISTINCT records.id) AS count_records
+			FROM domains
+			LEFT JOIN zones ON domains.id=zones.domain_id 
+			LEFT JOIN records ON records.domain_id=domains.id
+			WHERE 1=1".$sql_add." 
+			GROUP BY domains.name, domains.id
+			ORDER BY domains.name";
+	
 	$db->setLimit($rowamount, $rowstart);
 	$result = $db->query($sqlq);
-	// Set limit needs to be called before each query
-	$db->setLimit($rowamount, $rowstart);
-	$result2 = $db->query($sqlq); 
-	
-	$numrows = $result2->numRows();
-	$i=1;
-	if ($numrows > 0) {
-		$andnot=" AND NOT domains.id IN (";
-		while($r = $result2->fetchRow()) {
-			$andnot.=$db->quote($r["domain_id"]);
-			if ($i < $numrows) {
-				$andnot.=",";
-				$i++;
-			}
-		}
-		$andnot.=")";
-	}
-	else
-	{
-		$andnot="";
-	}
-
-	if ($letterstart!='all' && $letterstart!=1) {
-
-		$sqlq = "SELECT domains.id AS domain_id,
-		count(DISTINCT record_owners.record_id) AS aantal,
-		domains.name AS domainname
-		FROM domains, record_owners,records, zones
-		WHERE record_owners.user_id = ".$db->quote($_SESSION["userid"])."
-		AND (records.id = record_owners.record_id
-		AND domains.id = records.domain_id)
-		$andnot 
-		AND domains.name LIKE ".$db->quote($letterstart."%")." 
-		AND (zones.domain_id != records.domain_id AND zones.owner!=".$db->quote($_SESSION["userid"]).")
-		GROUP BY domainname, domains.id
-		ORDER BY domainname";
-
-		$result_extra = $db->query($sqlq);
-
-	} else {
-
-		$sqlq = "SELECT domains.id AS domain_id,
-		count(DISTINCT record_owners.record_id) AS aantal,
-		domains.name AS domainname
-		FROM domains, record_owners,records, zones
-		WHERE record_owners.user_id = ".$db->quote($_SESSION["userid"])."
-		AND (records.id = record_owners.record_id
-		AND domains.id = records.domain_id)
-		$andnot";
-		if ($letterstart != 'all') { 
-			$sqlq .= " AND substring(domains.name,1,1) ".$sql_regexp." '^[[:digit:]]'";
-		}
-		$sqlq .= "AND (zones.domain_id != records.domain_id AND zones.owner!=".$db->quote($_SESSION["userid"]).")
-		GROUP BY domainname, domains.id
-		ORDER BY domainname";
-
-		$result_extra[$i] = $db->query($sqlq);
-
-	}
 
 	while($r = $result->fetchRow())
 	{
-		$r["owner"] = ($r["owner"] == NULL) ? $db->queryOne("select min(id) from users where users.level=10") : $r["owner"];
-	     	$ret[$r["domainname"]] = array(
-		"name"          =>              $r["domainname"],
-		"id"            =>              $r["domain_id"],
-		"owner"         =>              $r["owner"],
-		"numrec"        =>              $r["aantal"]
-		);
+		$ret[$r["name"]] = array(
+		"id"		=>	$r["id"],
+		"name"		=>	$r["name"],
+		"type"		=>	$r["type"],
+		"count_records"	=>	$r["count_records"]
+		);	
 	}
-
-
-	if ($letterstart!='all' && $letterstart!=1) {
-
-		while($r = $result_extra->fetchRow())
-		{
-		       $ret[$r["domainname"]] = array(
-		       "name"          =>              $r["domainname"]."*",
-		       "id"            =>              $r["domain_id"],
-		       "owner"         =>              $_SESSION["userid"],
-		       "numrec"        =>              $r["aantal"]
-		       );
-		       $_SESSION["partial_".$r["domainname"]] = 1;
-		}
-
-	} else {
-
-		foreach ($result_extra as $result_e) {
-		while($r = $result_e->fetchRow())
-		{
-		       $ret[$r["domainname"]] = array(
-		       "name"          =>              $r["domainname"]."*",
-		       "id"            =>              $r["domain_id"],
-		       "owner"         =>              $_SESSION["userid"],
-		       "numrec"        =>              $r["aantal"]
-		       );
-		       $_SESSION["partial_".$r["domainname"]] = 1;
-		}
-		}
-
-	}
-
-	if (empty($ret)) {
-	   return -1;
-	} else {
-	   sort($ret);
-	   return $ret;
-	}
-
+	return $ret;
 }
 
-
-/*
- * zone_count
- * Does a select query to count how many zones we have in the database
- *
- * @todo: see whether or not it is possible to add the records
- * @param $userid integer The userid of the current user
- * @return integer the number of zones
- */
-
-function zone_count($userid=true, $letterstart='all') {
-        global $db;
+// TODO: letterstart limitation and userid permission limitiation should be applied at the same time?
+function zone_count_ng($perm, $letterstart=all) {
+	global $db;
 	global $sql_regexp;
-        if((!level(5) || !$userid) && !level(10) && !level(5))
-        {
-		// First select the zones for which we have ownership on one or more records.
-		$query = 'SELECT records.domain_id FROM records, record_owners WHERE user_id = '.$db->quote($_SESSION['userid']).' AND records.id = record_owners.record_id';
-		$result = $db->query($query);
-		$zones = array();
-		if (!PEAR::isError($result)) {
-			$zones = $result->fetchCol();
+	if ($perm != "own" && $perm != "all") {
+		$zone_count = "0";
+	} 
+	else 
+	{
+		if ($perm == "own") {
+			$sql_add = " AND zones.domain_id = domains.id
+					AND zones.owner = ".$db->quote($_SESSION['userid']);
+		}
+		if ($letterstart!=all && $letterstart!=1) {
+			$sql_add .=" AND domains.name LIKE ".$db->quote($letterstart."%")." ";
+		} elseif ($letterstart==1) {
+			$sql_add .=" AND substring(domains.name,1,1) ".$sql_regexp." '^[[:digit:]]'";
 		}
-	
-                $add = " AND (zones.owner=".$db->quote($_SESSION["userid"]);
-		if (count($zones) > 0) {
-			$add .= ' OR zones.domain_id IN ('.implode(',', $zones).') '; 
 
-		}
-		$add .= ')';
-        }
-        else
-        {
-                $add = "";
-        }
+		$sqlq = "SELECT COUNT(distinct domains.id) AS count_zones 
+			FROM domains,zones 
+			WHERE 1=1
+			".$sql_add.";";
+
+		$zone_count = $db->queryOne($sqlq);
+	}
+	return $zone_count;
+}
 
-        if ($letterstart!='all' && $letterstart!=1) {
-           $add .=" AND domains.name LIKE ".$db->quote($letterstart."%")." ";
-        } elseif ($letterstart==1) {
-           $add .=" AND substring(domains.name,1,1) ".$sql_regexp." '^[[:digit:]]'";
-        }
+function zone_count_for_uid($uid) {
+	global $db;
+	$query = "SELECT COUNT(domain_id) 
+			FROM zones 
+			WHERE owner = " . $db->quote($uid) . " 
+			ORDER BY domain_id";
+	$zone_count = $db->queryOne($query);
+	return $zone_count;
+}
 
-        if (level(5))
-        {
-                $query = 'SELECT count(distinct domains.id) as zone_count FROM domains WHERE 1=1 '.$add;
-        }
-        else
-        {
-                $query = 'SELECT count(distinct zones.domain_id) as zone_count FROM zones, domains WHERE zones.domain_id = domains.id '.$add;
-        }
-        $numRows = $db->queryOne($query);
-        return $numRows;
-}
 
 /*
  * Get a record from an id.
@@ -1169,15 +788,15 @@
 		{
 			$r = $result->fetchRow();
 			$ret = array(
-			"id"            =>      $r["id"],
-			"domain_id"     =>      $r["domain_id"],
-			"name"          =>      $r["name"],
-			"type"          =>      $r["type"],
-			"content"       =>      $r["content"],
-			"ttl"           =>      $r["ttl"],
-			"prio"          =>      $r["prio"],
-			"change_date"   =>      $r["change_date"]
-			);
+				"id"            =>      $r["id"],
+				"domain_id"     =>      $r["domain_id"],
+				"name"          =>      $r["name"],
+				"type"          =>      $r["type"],
+				"content"       =>      $r["content"],
+				"ttl"           =>      $r["ttl"],
+				"prio"          =>      $r["prio"],
+				"change_date"   =>      $r["change_date"]
+				);
 			return $ret;
 		}
 		else
@@ -1197,58 +816,53 @@
  * Retrieve all fields of the records and send it back to the function caller.
  * return values: the array with information, or -1 is nothing is found.
  */
-function get_records_from_domain_id($id,$rowstart=0,$rowamount=999999)
-{
+function get_records_from_domain_id($id,$rowstart=0,$rowamount=999999) {
 	global $db;
-	if (is_numeric($id))
-	{
+	if (is_numeric($id)) {
 		if ($_SESSION[$id."_ispartial"] == 1) {
-		$db->setLimit($rowamount, $rowstart);
-		$result = $db->query("SELECT record_owners.record_id as id
-		FROM record_owners,domains,records
-		WHERE record_owners.user_id = ".$db->quote($_SESSION["userid"])."
-		AND record_owners.record_id = records.id
-		AND records.domain_id = ".$db->quote($id)."
-		GROUP bY record_owners.record_id");
+			$db->setLimit($rowamount, $rowstart);
+			$result = $db->query("SELECT record_owners.record_id as id
+					FROM record_owners,domains,records
+					WHERE record_owners.user_id = " . $db->quote($_SESSION["userid"]) . "
+					AND record_owners.record_id = records.id
+					AND records.domain_id = " . $db->quote($id) . "
+					GROUP BY record_owners.record_id");
 
-		$ret = array();
-		if($result->numRows() == 0)
-		{
-		return -1;
-		}
-		else
-		{
-		$ret[] = array();
-		$retcount = 0;
-		while($r = $result->fetchRow())
-		{
-		// Call get_record_from_id for each row.
-		$ret[$retcount] = get_record_from_id($r["id"]);
-		$retcount++;
-		}
-		return $ret;
-		}
+			$ret = array();
+			if($result->numRows() == 0) {
+				return -1;
+			} else {
+				$ret[] = array();
+				$retcount = 0;
+				while($r = $result->fetchRow())
+				{
+					// Call get_record_from_id for each row.
+					$ret[$retcount] = get_record_from_id($r["id"]);
+					$retcount++;
+				}
+				return $ret;
+			}
 
 		} else {
-		$db->setLimit($rowamount, $rowstart);
-		$result = $db->query("SELECT id FROM records WHERE domain_id=".$db->quote($id));
-		$ret = array();
-		if($result->numRows() == 0)
-		{
-			return -1;
-		}
-		else
-		{
-			$ret[] = array();
-			$retcount = 0;
-			while($r = $result->fetchRow())
+			$db->setLimit($rowamount, $rowstart);
+			$result = $db->query("SELECT id FROM records WHERE domain_id=".$db->quote($id));
+			$ret = array();
+			if($result->numRows() == 0)
+			{
+				return -1;
+			}
+			else
 			{
-				// Call get_record_from_id for each row.
-				$ret[$retcount] = get_record_from_id($r["id"]);
-				$retcount++;
+				$ret[] = array();
+				$retcount = 0;
+				while($r = $result->fetchRow())
+				{
+					// Call get_record_from_id for each row.
+					$ret[$retcount] = get_record_from_id($r["id"]);
+					$retcount++;
+				}
+				return $ret;
 			}
-			return $ret;
-		}
 
 		}
 	}
@@ -1259,165 +873,164 @@
 }
 
 
-function get_users_from_domain_id($id)
-{
+function get_users_from_domain_id($id) {
 	global $db;
-	$result = $db->queryCol("SELECT owner FROM zones WHERE domain_id=".$db->quote($id));
-	$ret = array();
-	foreach($result as $uid)
-	{
-		$fullname = $db->queryOne("SELECT fullname FROM users WHERE id=".$db->quote($uid));
-		$ret[] = array(
-		"id" 		=> 	$uid,
-		"fullname"	=>	$fullname		
-		);		
+	$sqlq = "SELECT owner FROM zones WHERE domain_id =" .$db->quote($id);
+	$id_owners = $db->query($sqlq);
+	if ($id_owners->numRows() == 0) {
+		return -1;
+	} else {
+		while ($r = $id_owners->fetchRow()) {
+			$fullname = $db->queryOne("SELECT fullname FROM users WHERE id=".$r['owner']);
+			$owners[] = array(
+				"id" 		=> 	$r['owner'],
+				"fullname"	=>	$fullname		
+			);		
+		}
 	}
-	return $ret;	
+	return $owners;	
 }
 
-function search_record($question)
-{
+
+function search_zone_and_record($holy_grail,$perm) {
+	
 	global $db;
-	$question = trim($question);
+
+	$holy_grail = trim($holy_grail);
+
+	if (verify_permission(zone_content_view_others)) { $perm_view = "all" ; }
+	elseif (verify_permission(zone_content_view_own)) { $perm_view = "own" ; }
+	else { $perm_view = "none" ; }
+
+	if (verify_permission(zone_content_edit_others)) { $perm_content_edit = "all" ; }
+	elseif (verify_permission(zone_content_edit_own)) { $perm_content_edit = "own" ; }
+	else { $perm_content_edit = "none" ; }
+
+	// Search for matching domains
 
-	if (is_valid_search($question))
-	{
-		$sqlq = "SELECT * 
-				FROM records 
-				WHERE content LIKE ".$db->quote($question)." 
-				OR name LIKE ".$db->quote($question)."
-				ORDER BY type DESC";
-		$result = $db->query($sqlq);
-		$ret_r = array();
-		while ($r = $result->fetchRow())
-		{
-		    if(xs($r['domain_id']))
-		    {
-			$ret_r[] = array(
-			  'id'			=>	$r['id'],
-			  'domain_id'		=>	$r['domain_id'],
-			  'name'		=>	$r['name'],
-			  'type'		=>	$r['type'],
-			  'content'		=>	$r['content'],
-			  'ttl'			=>	$r['ttl'],
-			  'prio'		=>	$r['prio'],
-			  'change_date'		=>	$r['change_date']
-			);
-			}
-		}
+	if ($perm == "own") {
+		$sql_add_from = ", zones ";
+		$sql_add_where = " AND zones.domain_id = domains.id AND zones.owner = " . $db->quote($userid);
+	}
+	
+	$query = "SELECT 
+			domains.id AS zid,
+			domains.name AS name,
+			domains.type AS type,
+			domains.master AS master
+			FROM domains" . $sql_add_from . "
+			WHERE domains.name LIKE " . $db->quote($holy_grail)
+			. $sql_add_where ;
+	
+	$response = $db->query($query);
+	if (PEAR::isError($response)) { error($response->getMessage()); return false; }
 
-		$sqlq = "SELECT domains.id, domains.name, count(records.id) AS numrec, zones.owner, records.domain_id
-				FROM domains LEFT JOIN records ON domains.id = records.domain_id, zones  
-				WHERE zones.domain_id = domains.id 
-				AND domains.name LIKE ".$db->quote($question)." 
-				GROUP BY domains.id, domains.name, zones.owner, records.domain_id";
-		$result = $db->query($sqlq);
-		$ret_d = array();
-		while ($r = $result->fetchRow())
-		{
-		    if(xs($r['id']))
-		    {
-			    $ret_d[] = array(
-				'id'			=>	$r['id'],
-				'name'		=>	$r['name'],
-				'numrec'		=>	$r['numrec'],
-				'owner'		=>	$r['owner']
-			);
-			}
-		}
-		return array('domains' => $ret_d, 'records' => $ret_r);
-	}
-	else
-	{
-		error(sprintf(ERR_INV_ARGC, "search_record", "Invalid searchstring: $question"));
+	while ($r = $response->fetchRow()) {
+		$return_zones[] = array(
+			"zid"		=>	$r['zid'],
+			"name"		=>	$r['name'],
+			"type"		=>	$r['type'],
+			"master"	=>	$r['master']);
 	}
 
+	// Search for matching records
+
+	if ($perm == "own") {
+		$sql_add_from = ", zones ";
+		$sql_add_where = " AND zones.domain_id = record.id AND zones.owner = " . $db->quote($userid);
+	}
+
+	$query = "SELECT
+			records.id AS rid,
+			records.name AS name,
+			records.type AS type,
+			records.content AS content,
+			records.ttl AS ttl,
+			records.prio AS prio,
+			records.domain_id AS zid
+			FROM records" . $sql_add_from . "
+			WHERE (records.name LIKE " . $db->quote($holy_grail) . " OR records.content LIKE " . $db->quote($holy_grail) . ")"
+			. $sql_add_where ;
+
+	$response = $db->query($query);
+	if (PEAR::isError($response)) { error($response->getMessage()); return false; }
+
+	while ($r = $response->fetchRow()) {
+		$return_records[] = array(
+			"rid"		=>	$r['rid'],
+			"name"		=>	$r['name'],
+			"type"		=>	$r['type'],
+			"content"	=>	$r['content'],
+			"ttl"		=>	$r['ttl'],
+			"zid"		=>	$r['zid'],
+			"prio"		=>	$r['prio']);
+	}
+	return array('zones' => $return_zones, 'records' => $return_records);
 }
 
-function get_domain_type($id)
-{
+function get_domain_type($id) {
 	global $db;
-        if (is_numeric($id))
-	{
+        if (is_numeric($id)) {
 		$type = $db->queryOne("SELECT type FROM domains WHERE id = ".$db->quote($id));
-		if($type == "")
-		{
+		if ($type == "") {
 			$type = "NATIVE";
 		}
 		return $type;
-        }
-        else
-        {
+        } else {
                 error(sprintf(ERR_INV_ARG, "get_record_from_id", "no or no valid zoneid given"));
         }
 }
 
-function get_domain_slave_master($id)
-{
+function get_domain_slave_master($id){
 	global $db;
-        if (is_numeric($id))
-	{
+        if (is_numeric($id)) {
 		$slave_master = $db->queryOne("SELECT master FROM domains WHERE type = 'SLAVE' and id = ".$db->quote($id));
 		return $slave_master;
-        }
-        else
-        {
+        } else {
                 error(sprintf(ERR_INV_ARG, "get_domain_slave_master", "no or no valid zoneid given"));
         }
 }
 
-function change_domain_type($type, $id)
+function change_zone_type($type, $id)
 {
 	global $db;
 	$add = '';
         if (is_numeric($id))
 	{
-		// It is not really neccesary to clear the master field if a 
-		// zone is not of the type "slave" as powerdns will ignore that
-		// fiedl, but it is cleaner anyway.
-		if ($type != "SLAVE")
-		{
+		// It is not really neccesary to clear the field that contains the IP address 
+		// of the master if the type changes from slave to something else. PowerDNS will
+		// ignore the field if the type isn't something else then slave. But then again,
+		// it's much clearer this way.
+		if ($type != "SLAVE") {
 			$add = ", master=''";
 		}
-		$result = $db->query("UPDATE domains SET type = " .$db->quote($type). $add." WHERE id = ".$db->quote($id));
-	}
-        else
-        {
+		$result = $db->query("UPDATE domains SET type = " . $db->quote($type) . $add . " WHERE id = ".$db->quote($id));
+	} else {
                 error(sprintf(ERR_INV_ARG, "change_domain_type", "no or no valid zoneid given"));
         }
 }
 
-function change_domain_slave_master($id, $slave_master)
-{
+function change_zone_slave_master($zone_id, $ip_slave_master) {
 	global $db;
-        if (is_numeric($id))
-	{
-       		if (is_valid_ip($slave_master) || is_valid_ip6($slave_master))
-		{
-			$result = $db->query("UPDATE domains SET master = " .$db->quote($slave_master). " WHERE id = ".$db->quote($id));
+        if (is_numeric($zone_id)) {
+       		if (is_valid_ip($ip_slave_master) || is_valid_ip6($ip_slave_master)) {
+			$result = $db->query("UPDATE domains SET master = " .$db->quote($ip_slave_master). " WHERE id = ".$db->quote($zone_id));
+		} else {
+			error(sprintf(ERR_INV_ARGC, "change_domain_ip_slave_master", "This is not a valid IPv4 or IPv6 address: $ip_slave_master"));
 		}
-		else
-		{
-			error(sprintf(ERR_INV_ARGC, "change_domain_slave_master", "This is not a valid IPv4 or IPv6 address: $slave_master"));
-		}
-	}
-        else
-        {
+	} else {
                 error(sprintf(ERR_INV_ARG, "change_domain_type", "no or no valid zoneid given"));
         }
 }
 
 
-function validate_account($account)
-{
-	
-  	if(preg_match("/^[A-Z0-9._-]+$/i",$account))
-	{
+function validate_account($account) {
+  	if(preg_match("/^[A-Z0-9._-]+$/i",$account)) {
 		return true;
-	}
-	else
-	{
+	} else {
 		return false;
 	}
 }
+
+
 ?>