DNS zones in customer panel

Discussion in 'General' started by pyte, Dec 16, 2022.

  1. pyte

    pyte Well-Known Member HowtoForge Supporter

    I've already limited the ability for customers to create new DNS zones as i don't want them to be able to do so. If a new domain get's bought or transfered i need to create the zone myself anyways. However is there a way to limit the following two things?

    -> Customers should not be able to delete Zones; As our NS server is responsible for the domain, i don't want customers to have control over this.
    -> Customers should not be able to edit the Zonesettings; I don't see the need for a customer to change the defaults that i set.

    I couldn't figure out if this is possible or not. Any help is appriciated.
     
  2. till

    till Super Moderator Staff Member ISPConfig Developer

    Why don't you disable the DNS module for customers?
     
  3. pyte

    pyte Well-Known Member HowtoForge Supporter

    I still want them to be able to create, edit and remove DNS entries.
     
  4. till

    till Super Moderator Staff Member ISPConfig Developer

    Do you have client protection enabled under System > Interface > main config? it might be that it does this, but of course has an effect especially on websites as well. Alternatively, one could write a small interface plugin that hooks to the on_before_delete and on_before_update events to show a message and stop saving / deleting the DNS zone.
     
    ahrasis likes this.
  5. pyte

    pyte Well-Known Member HowtoForge Supporter

    I indeed have "Client protection" enabled. What does this do in the first place?
     
  6. pyte

    pyte Well-Known Member HowtoForge Supporter

    Is there any guidelines or help somewhere about writing a interface plugin?
     
  7. till

    till Super Moderator Staff Member ISPConfig Developer

    It works like this: If you add a website as admin (and not the client himself or the admin via 'login as client' function, then the client can not delete the website, and he also can not change website settings. It might be that we implemented this for DNS as well, not sure, though. You might want to test it.
     
    pyte likes this.
  8. till

    till Super Moderator Staff Member ISPConfig Developer

    I fear we don't have any docs for that. Take a look at the existing plugins in /usr/local/ispconfig/interface/lib/plugins/, especially the dns_dns_soa_plugin plugin.

    The events that you will have to bind your function to would be:

    Code:
    dns:dns_soa:on_before_update
    dns:dns_soa:on_before_delete
    the on_before_delete would be trivial, you just run in this case something like $app->error(''Don't delete me ....."); in conjunction with a check that its not the admin if(!$app->auth->is_admin())) .....

    for the on_before update, it's a bit more complicated, you would want to show an error only in case its not admin but also not when it#s a client that did not change anything, so you would have to compare the array $page_form->dataRecord with $page_form->oldDataRecord, if all records in the two arrays are the same, then the user did not changed any data and you don't have to issue a error message.

    and one important thing to note, plugin bindings get cached in the session, so after creating your plugin with the two bindings, logout and login again once.
     
    ahrasis and pyte like this.
  9. pyte

    pyte Well-Known Member HowtoForge Supporter

    Thank you so much for the detailed explanation, i'll have a look into this next week!
     
  10. pyte

    pyte Well-Known Member HowtoForge Supporter

    I'll tried my luck with the on_before_delete first but i'm not sure how to debug within ISPConfig. Never worked with a big PHP project in the first place tho. Here's what i've done so far:
    PHP:
    <?php
    /**
     * dns_dns_zone_disable_user_plugin
     */

    class dns_dns_zone_disable_user_plugin {

      var 
    $plugin_name 'dns_dns_zone_disable_user_plugin';
      var 
    $class_name 'dns_dns_zone_disable_user_plugin';

      function 
    onLoad() {
        global 
    $app;
        
    // Register Events
        
    $app->plugin->registerEvent('dns:dns_soa:on_before_delete''dns_dns_zone_disable_user_plugin''dns_dns_soa_delete');
      }

      function 
    dns_dns_soa_delete($event_name$page_form) {
        global 
    $app$conf;

        if(
    $event_name == 'dns:dns_soa:on_before_delete' && !$app->auth->is_admin()) {
          
    // User is not admin and event is dns_soa:on_bedore delete
          
    $app->error("You are not allowed to delete DNS Zones.");
        }
      }
    }
    I've named the script "dns_dns_zone_disable_user.inc.php, placed it within the plugins directory and modified the owner to match the other plugins. (Really should consider renaming the script :D)... However there is nothing happening if i delete a zone, it still works and there are no errors.

    Is there anything else that i have to do, instead of just placing the script in the directory and modify the access rights? Or did i just f'd up with my insane PHP coding skills? :p
     
  11. till

    till Super Moderator Staff Member ISPConfig Developer

    Log out and then log in again to activate the plugin in your session.
     
  12. pyte

    pyte Well-Known Member HowtoForge Supporter

    Already did that :) One strange thing that happend after i added the plugin is that when i first login as admin, the site stays white, no content is loaded until i reload the page. But if i login as a customer, i'm still able to delete zones without anything happening.

    Is there a good way to debug plugins?
     
  13. till

    till Super Moderator Staff Member ISPConfig Developer

    First, check global error.log of the web server; there should be no white page, so a code error might appear in the log. Then edit the file interface/lib/classes/plugin.inc.php. It has a private variable named debug. Set that to true. Then you can e.g. add onLoad() and in the dns_dns_soa_delete($event_name, $page_form) some echo or die(....) code to see if they get called.
     
    pyte likes this.
  14. pyte

    pyte Well-Known Member HowtoForge Supporter

    That just did the trick, thank you so much for your help again! :)
    The plugin works, but there is an issue i didn't think about in the first place... The deletion does not only trigger a deletion of the zone itself, but of all the records in that zone.
    upload_2022-12-19_9-47-31.png

    As you can see in the screenshot, the error message gets displayed, and the zone is not deleted, but the job queue has jobs, which are the deletion of the DNS entries.

    What is the correct way to stop the app from doing this? Is there a function that i can call after my error message to stop processing the deletion?
     
  15. till

    till Super Moderator Staff Member ISPConfig Developer

    The processing is already stopped, but deleting records has happened before. Change your code so that your function subscribes to "on_check_delete" event instead of "on_before_delete". And then, re-login to refresh the plugin cache in your session.
     
    pyte likes this.
  16. pyte

    pyte Well-Known Member HowtoForge Supporter

    Sure it's a bit messy :) But... It works just as intended. Is there a place in the git where i makes sense to push this code?

    PHP:
    <?php
    /**
     * dns_dns_zone_disable_user_plugin
     *
     * @author pyte_c
     */

    class dns_dns_zone_disable_user_plugin {

      var 
    $plugin_name 'dns_dns_zone_disable_user_plugin';
      var 
    $class_name 'dns_dns_zone_disable_user_plugin';

      function 
    onLoad() {
        global 
    $app;
        
    // Register Events
        
    $app->plugin->registerEvent('dns:dns_soa:on_before_update''dns_dns_zone_disable_user_plugin''dns_dns_soa_edit');
        
    $app->plugin->registerEvent('dns:dns_soa:on_check_delete''dns_dns_zone_disable_user_plugin''dns_dns_soa_delete');
      }

      function 
    dns_dns_soa_edit($event_name$page_form) {
        global 
    $app$conf;
        
    $tmp $app->db->diffrec($page_form->oldDataRecord$app->tform->getDataRecord($page_form->id));

        if(
    $tmp['diff_num'] > && !$app->auth->is_admin()) {
          
    $app->error("You are not allowed to change DNS Zonesettings.");
        }
      }

      function 
    dns_dns_soa_delete($event_name) {
        global 
    $app$conf;

        
    // If user is not admin and event is check_delete -> show error
        
    if($event_name == 'dns:dns_soa:on_check_delete' && !$app->auth->is_admin()) {
          
    $app->error("You are not allowed to delete DNS Zones.");
        }

      }
    }
     
    till likes this.
  17. till

    till Super Moderator Staff Member ISPConfig Developer

    Thanks, this would be great! This repo might be a good place:

    https://git.ispconfig.org/ispconfig/Modules

    Just make a new folder for the plugin and it would be nice if you might add a small readme file so users know what the plugin is used for. If you reached your project fork limit, then please let me know so I can increase that.
     
    pyte likes this.
  18. pyte

    pyte Well-Known Member HowtoForge Supporter

    I did it :) Let me know if there is something wrong. Still new to contributing code to FOSS projects.
     
    Last edited: Dec 19, 2022
  19. till

    till Super Moderator Staff Member ISPConfig Developer

    Thanks. Looks fine, and I've merged it already.

    Just a s short excursion on the event system for plugins as we don't have any useful documentation on that. The event name is splitter by : and you can also use parts of an event like:

    Code:
    dns:dns_soa
    or even

    Code:
    dns
    to bind a function to all events of the dns_soa form or in the second case even to all events that occur in the dns module.
     
    pyte likes this.
  20. till

    till Super Moderator Staff Member ISPConfig Developer

    And to get an overview of which events get called in which order, check out the interface/lib/classes/tform_actions.inc.php file.
     

Share This Page