edit.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <?php
  2. if (processForm() AND isset($_POST['zone-content'])) { // Update zone
  3. nsCheckZonePossession($_POST['zone']);
  4. // Get current SOA record
  5. $current_zone_content = file_get_contents(CONF['ns']['knot_zones_path'] . '/' . $_POST['zone'] . 'zone');
  6. if ($current_zone_content === false)
  7. output(500, 'Unable to read zone file.');
  8. if (preg_match('/^(?<soa>' . preg_quote($_POST['zone']) . '[\t ]+[0-9]{1,16}[\t ]+SOA[\t ]+.+)$/m', $current_zone_content, $matches) !== 1)
  9. output(500, 'Unable to get current serial from zone file.');
  10. // Generate new zone content
  11. $new_zone_content = $matches['soa'] . LF;
  12. if (strlen($_POST['zone-content']) > ZONE_MAX_CHARACTERS)
  13. output(403, 'La zone n\'est pas autorisée à dépasser ' . ZONE_MAX_CHARACTERS . ' caractères.');
  14. foreach (explode("\r\n", $_POST['zone-content']) as $line) {
  15. if ($line === '') continue;
  16. if (preg_match('/^(?<domain>[a-z0-9@._-]+)(?:[\t ]+(?<ttl>[0-9]{1,16}))?(?:[\t ]+IN)?[\t ]+(?<type>[A-Z]{1,16})[\t ]+(?<value>.+)$/', $line, $matches) !== 1)
  17. output(403, 'La zone est mal formatée (selon Niver).');
  18. if (in_array($matches['type'], ALLOWED_TYPES, true) !== true)
  19. output(403, 'Le type <code>' . $matches['type'] . '</code> n\'est pas autorisé.');
  20. if ($matches['ttl'] !== '' AND $matches['ttl'] < MIN_TTL)
  21. output(403, 'Les TTLs inférieurs à ' . MIN_TTL . ' secondes ne sont pas autorisés.');
  22. if ($matches['ttl'] !== '' AND $matches['ttl'] > MAX_TTL)
  23. output(403, 'Les TTLs supérieurs à ' . MAX_TTL . ' secondes ne sont pas autorisés.');
  24. $new_zone_content .= $matches['domain'] . ' ' . (($matches['ttl'] === '') ? DEFAULT_TTL : $matches['ttl']) . ' ' . $matches['type'] . ' ' . $matches['value'] . LF;
  25. }
  26. // Send the zone content to kzonecheck's stdin
  27. $process = proc_open(CONF['ns']['kzonecheck_path'] . ' --origin ' . $_POST['zone'] . ' --dnssec off -', [0 => ['pipe', 'r']], $pipes);
  28. if (is_resource($process) !== true)
  29. output(500, 'Can\'t spawn kzonecheck.');
  30. fwrite($pipes[0], $new_zone_content);
  31. fclose($pipes[0]);
  32. if (proc_close($process) !== 0)
  33. output(403, 'Le contenu de zone envoyé n\'est pas valide (selon <code>kzonecheck</code>).');
  34. ratelimit();
  35. exec(CONF['dns']['knotc_path'] . ' --blocking --timeout 10 zone-freeze ' . $_POST['zone'], $output, $return_code);
  36. if ($return_code !== 0)
  37. output(500, 'Failed to freeze zone file.', $output);
  38. exec(CONF['dns']['knotc_path'] . ' --blocking --timeout 10 zone-flush ' . $_POST['zone'], $output, $return_code);
  39. if ($return_code !== 0)
  40. output(500, 'Failed to flush zone file.', $output);
  41. if (file_put_contents(CONF['ns']['knot_zones_path'] . '/' . $_POST['zone'] . 'zone', $new_zone_content) === false)
  42. output(500, 'Failed to write zone file.');
  43. exec(CONF['dns']['knotc_path'] . ' --blocking --timeout 10 zone-reload ' . $_POST['zone'], $output, $return_code);
  44. if ($return_code !== 0)
  45. output(500, 'Failed to reload zone file.', $output);
  46. exec(CONF['dns']['knotc_path'] . ' --blocking --timeout 10 zone-thaw ' . $_POST['zone'], $output, $return_code);
  47. if ($return_code !== 0)
  48. output(500, 'Failed to thaw zone file.', $output);
  49. usleep(1000000);
  50. output(200, 'La zone a été mise à jour.');
  51. }
  52. ?>
  53. <form method="post">
  54. <label for="zone">Zone à modifier</label>
  55. <br>
  56. <select required="" name="zone" id="zone">
  57. <option value="" disabled="" selected="">-</option>
  58. <?php
  59. if (isset($_SESSION['username']))
  60. foreach (nsListUserZones($_SESSION['username']) as $zone)
  61. echo ' <option value="' . $zone . '">' . $zone . '</option>' . LF;
  62. ?>
  63. </select>
  64. <br>
  65. <input type="submit" value="Afficher">
  66. </form>
  67. <?php
  68. if (processForm()) { // Display zone
  69. nsCheckZonePossession($_POST['zone']);
  70. $zone_content = file_get_contents(CONF['ns']['knot_zones_path'] . '/' . $_POST['zone'] . 'zone');
  71. if ($zone_content === false)
  72. output(500, 'Unable to read zone file.');
  73. $displayed_zone_content = '';
  74. foreach(explode(LF, $zone_content) as $zone_line) {
  75. if (empty($zone_line) OR str_starts_with($zone_line, ';'))
  76. continue;
  77. if (preg_match('/^(?:(?:[a-z0-9_-]{1,63}\.){1,127})?' . preg_quote($_POST['zone'], '/') . '[\t ]+[0-9]{1,8}[\t ]+(?<type>[A-Z]{1,16})[\t ]+.+$/', $zone_line, $matches)) {
  78. if (in_array($matches['type'], ALLOWED_TYPES, true) !== true)
  79. continue;
  80. $displayed_zone_content .= $zone_line . LF;
  81. }
  82. }
  83. $displayed_zone_content .= LF;
  84. ?>
  85. <form method="post">
  86. <input type="hidden" name="zone" value="<?= $_POST['zone'] ?>">
  87. <label for="zone-content">Nouveau contenu de la zone <code><strong><?= $_POST['zone'] ?></strong></code></label>
  88. <textarea id="zone-content" name="zone-content" wrap="off" rows="<?= substr_count($displayed_zone_content, LF) + 1 ?>"><?= htmlspecialchars($displayed_zone_content) ?></textarea>
  89. <br>
  90. <input type="submit" value="Remplacer">
  91. </form>
  92. <?php
  93. }
  94. global $final_message;
  95. displayFinalMessage();
  96. ?>
  97. <h2>Valeurs par défaut</h2>
  98. <p>Si le TTL est omis, il sera définit à <code><?= DEFAULT_TTL ?></code> secondes.</p>
  99. <p>La précision de la classe (<code>IN</code>) est facultative.</p>
  100. <h2>Valeurs autorisées</h2>
  101. <p>La zone n'est pas autorisée à dépasser <?= ZONE_MAX_CHARACTERS ?> caractères.</p>
  102. <p>Les TTLs ne sont autorisés qu'entre <code><?= MIN_TTL ?></code> et <code><?= MAX_TTL ?></code> secondes.</p>
  103. <p>Les seuls types dont l'édition est autorisée sont :</p>
  104. <ul>
  105. <?php
  106. foreach (ALLOWED_TYPES as $allowed_type)
  107. echo ' <li><code>' . $allowed_type . '</code></li>';
  108. ?>
  109. </ul>