PageRenderTime 76ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/UPGRADE-RC2/c/zones.php

https://github.com/voldern/wmbind
PHP | 312 lines | 234 code | 47 blank | 31 comment | 70 complexity | 7c7413071efe3666a54388b1541f43f7 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. class Controller_Zones extends Controller_Application
  3. {
  4. public $models = array('Zone', 'User', 'Record', 'Option');
  5. function beforeCall()
  6. {
  7. $this->checkLogin();
  8. if ($this->action == 'register')
  9. $this->requireAdmin();
  10. }
  11. function index()
  12. {
  13. if ($_SESSION['admin'])
  14. $this->template->zones = $this->Zone->findAll('1 = 1');
  15. else
  16. $this->template->zones = $this->Zone->findAll('owner = ?',
  17. array($_SESSION['userid']));
  18. }
  19. function register()
  20. {
  21. // Get users from the database and format it so
  22. // that it can be used inside the owner <select></select>
  23. $this->template->users = $this->User->options();
  24. // Get the default primary and secondary NS
  25. $dns = $this->Option->findAll("prefkey = 'prins' OR prefkey = 'secns' ".
  26. "OR prefkey = 'transfer'",
  27. NULL, array('prefval'), '1 DESC');
  28. $this->template->prins = $dns[0]['prefval'];
  29. $this->template->secns = $dns[1]['prefval'];
  30. $this->template->transfer = $dns[2]['prefval'];
  31. if ($this->request == 'POST')
  32. {
  33. // Validates the input
  34. if ($this->Zone->validate()) {
  35. if ($this->Zone->saveReg())
  36. $this->redirect('/zones/');
  37. } else {
  38. }
  39. }
  40. }
  41. function edit($args)
  42. {
  43. if (empty($args[0]) || !is_numeric($args[0]))
  44. $this->redirect('/zones/');
  45. // Check if user has permission to edit the zone
  46. $owner = $this->Zone->findValue($args[0], NULL, 'owner');
  47. if (!$_SESSION['admin'] && $owner != $_SESSION['userid'])
  48. $this->redirect('/zones/');
  49. // Save any changes
  50. // Validates the zone related input
  51. if ($this->request == "POST" && $this->Zone->validate(false)) {
  52. if ($this->Zone->update($args[0])) {
  53. if (!$this->Record->saveEdit($args[0]))
  54. $this->template->error = "Could not update/save ".
  55. "the records, please try again. <br />\n";
  56. } else
  57. $this->template->error = "Could not update/save the zone, ".
  58. "please try again. <br />\n";
  59. }
  60. // Get data to populate the view with
  61. $this->template->zone = $this->Zone->find($args[0]);
  62. if (empty($this->template->zone))
  63. $this->redirect('/zones/');
  64. $this->template->records = $this->Record->findAll("zone = ?", array($args[0]),
  65. NULL,
  66. 'host, type, pri, destination');
  67. // Create a list of available type options
  68. $types = $this->Option->findAll('preftype = ? AND prefval = ?',
  69. array('record', 'on'), array('prefkey'));
  70. foreach ($types as $type)
  71. $options[$type['prefkey']] = $type['prefkey'];
  72. $this->template->options = $options;
  73. $this->template->users = $this->User->options();
  74. }
  75. function delete($args)
  76. {
  77. if (!is_numeric($args[0]))
  78. $this->redirect('/zones/');
  79. // Get zone
  80. $this->template->zone = $this->Zone->find($args[0], NULL,
  81. array('id', 'name', 'owner'));
  82. // Redirect back if no zone where found
  83. if (empty($this->template->zone))
  84. $this->redirect('/zones/');
  85. // Checks if user has permission to delete the zone
  86. if (!$_SESSION['admin'] && $this->template->zone['owner'] != $_SESSION['userid'])
  87. $this->redirect('/zones');
  88. if (isset($args[1]) && $args[1] == 'yes') {
  89. // Delete zone and all records
  90. $this->Record->delete('zone = ?', array($args[0]));
  91. // TODO
  92. // Remove dirty hack
  93. if ($this->Zone->delete($args[0]))
  94. $this->Zone->query("UPDATE zones SET updated = 'yes' LIMIT 1");
  95. // Redirect back
  96. $this->redirect('/zones/');
  97. }
  98. }
  99. function commit()
  100. {
  101. $hostmaster = $this->Option->find('prefkey = ?', array('hostmaster'),
  102. array('prefval'));
  103. $hostmaster = $hostmaster['prefval'];
  104. $badZones = array();
  105. $zones = $this->Zone->findAll("updated = 'yes'");
  106. /*if (empty($zones))
  107. $this->redirect('/');*/
  108. foreach ($zones as $zone) {
  109. $records = $this->Record->findAll("zone = ? AND valid != 'no'",
  110. array($zone['id']), NULL,
  111. 'host, type, pri, destination');
  112. // Add options
  113. $out = <<<EOF
  114. \$TTL {$zone['ttl']}
  115. @ IN SOA {$zone['pri_dns']}. $hostmaster. (
  116. {$zone['serial']} \t; Serial
  117. {$zone['refresh']} \t\t; Refresh
  118. {$zone['retry']} \t\t; Retry
  119. {$zone['expire']} \t; Expire
  120. {$zone['ttl']}) \t; Negative Cache TTL
  121. ;
  122. EOF;
  123. // Add the primary and secondary DNS
  124. if (!empty($zone['pri_dns']))
  125. $out .= "@ IN NS " . $zone['pri_dns'] . ".\n";
  126. if (!empty($zone['sec_dns']))
  127. $out .= "@ IN NS " . $zone['sec_dns'] . ".\n";
  128. // Write the zone file
  129. $fd = fopen($this->registry->zones_path .
  130. preg_replace('/\//', '-', $zone['name']), 'w');
  131. if (!$fd)
  132. die('Cannot open: ' . $this->registry->zones_path .
  133. preg_replace('/\//', '-', $zone['name']));
  134. fwrite($fd, $out);
  135. fclose($fd);
  136. // Check if the zone file is valid
  137. $cmd = $this->registry->namedcheckzone . " " . $zone['name'] . " " .
  138. $this->registry->zones_path . preg_replace('/\//', '-', $zone['name']) .
  139. ' > /dev/null';
  140. system($cmd, $exit);
  141. if ($exit == 0) {
  142. if (!$this->Zone->save(array('id' => $zone['id'], 'updated' => 'no',
  143. 'valid' => 'yes'))) {
  144. die('Could not update zone');
  145. }
  146. $rebuild = true;
  147. } else {
  148. if (!$this->Zone->save(array('id' => $zone['id'], 'updated' => 'yes',
  149. 'valid' => 'no'))) {
  150. die('Could not update zone');
  151. }
  152. // Add zone to list of broken zones if the user has
  153. // permission to edit that zone
  154. if ($_SESSION['admin'] || $zone['owner'] == $_SESSION['userid'])
  155. $badZones[] = array('id' => $zone['id'], 'name' => $zone['name']);
  156. }
  157. // Get records associated with zone
  158. $records = $this->Record->findAll("zone = ? AND valid != 'no'",
  159. array($zone['id']), NULL,
  160. 'host, type, pri, destination');
  161. if (empty($badZones)) {
  162. foreach ($records as $record) {
  163. // Only add priority if the record is of type 'MX'
  164. if ($record['type'] == 'MX')
  165. $pri = $record['pri'];
  166. else
  167. $pri = '';
  168. // Get the right destination depending on record type
  169. if (($record['type'] == 'NS' || $record['type'] == 'PTR' ||
  170. $record['type'] == 'CNAME' || $record['type'] == 'MX' ||
  171. $record['type'] == 'SRV') && $record['destination'] != '@') {
  172. $destination = $record['destination'] . ".";
  173. } elseif ($record['type'] == 'TXT') {
  174. $destination = '"' . $record['destination'] . '"';
  175. } else {
  176. $destination = $record['destination'];
  177. }
  178. $out = $record['host'] . "\tIN\t" . $record['type'] .
  179. "\t" . $pri . "\t" . $destination . "\n";
  180. // Write record to end of file
  181. $fd = fopen($this->registry->zones_path .
  182. preg_replace('/\//', '-', $zone['name']), 'a');
  183. if (!$fd) {
  184. die('Cannot open: ' . $this->registry->zones_path .
  185. preg_replace('/\//', '-', $zone['name']));
  186. }
  187. fwrite($fd, $out);
  188. fclose($fd);
  189. // Validate the new record
  190. $cmd = $this->registry->namedcheckzone . " " . $zone['name'] .
  191. " " . $this->registry->zones_path .
  192. preg_replace('/\//', '-', $zone['name']) . ' > /dev/null';
  193. system($cmd, $exit);
  194. if ($exit == 0) {
  195. if (!$this->Record->save(array('id' => $record['id'],
  196. 'valid' => 'yes'))) {
  197. die('Could not update zone');
  198. }
  199. } else {
  200. // Remove the last record from the zone file that caused the error
  201. $fd = fopen($this->registry->zones_path .
  202. preg_replace('/\//', '-', $zone['name']), 'r+');
  203. if (!$fd) {
  204. die('Cannot open: ' . $this->registry->zones_path .
  205. preg_replace('/\//', '-', $zone['name']));
  206. }
  207. for ($i = 0; fgets($fd); $i++)
  208. $addr[$i] = ftell($fd);
  209. ftruncate($fd, $addr[$i - 2]);
  210. fclose($fd);
  211. if (!$this->Record->save(array('id' => $record['id'],
  212. 'valid' => 'no'))) {
  213. die('Could not update zone');
  214. }
  215. }
  216. }
  217. }
  218. }
  219. // Create a new config file
  220. if (isset($rebuild) && $rebuild == true) {
  221. if (!$zones = $this->Zone->findAll('1 = 1', NULL, array('name', 'transfer'),
  222. 'name')) {
  223. die('Could not find any zones');
  224. }
  225. $cout = '';
  226. foreach ($zones as $zone) {
  227. if (!empty($zone['transfer']))
  228. $transfer = 'allow-transfer { ' . $zone['transfer'] . ' };';
  229. else
  230. $transfer = '';
  231. $cout .= 'zone "' . $zone['name'] . '" {
  232. type master;
  233. file "' . $this->registry->zones_path . preg_replace('/\//', '-', $zone['name']) . "\";
  234. $transfer
  235. };\n\n";
  236. }
  237. $fd = fopen($this->registry->conf_path, 'w')
  238. or die('Cannot open: ' . $this->registry->conf_path);
  239. fwrite($fd, $cout);
  240. fclose($fd);
  241. // Check if conf file is valid
  242. $cmd = $this->registry->namedcheckconf . ' ' .
  243. $this->registry->conf_path . ' > /dev/null';
  244. system($cmd, $exit);
  245. if ($exit != 0)
  246. die ($this->registry->namedcheckconf . ' exit status ' . $exit);
  247. // Reload bind
  248. $cmd = $this->registry->rndc . ' reload > /dev/null';
  249. system($cmd, $exit);
  250. if ($exit != 0)
  251. die($this->registry->rndc . ' exit status ' . $exit);
  252. }
  253. // Assing view variables
  254. if (!empty($badZones))
  255. $this->template->badZones = $badZones;
  256. $this->template->badRecords = $this->Record->badRecords(1);
  257. }
  258. }
  259. ?>