From c34304027a8ad80926fbd2041956fb9fa656a596 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Tue, 16 Sep 2008 18:40:14 +0000 Subject: [PATCH] DHCP module --- lam/lib/modules/range.inc | 478 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 478 insertions(+) create mode 100644 lam/lib/modules/range.inc diff --git a/lam/lib/modules/range.inc b/lam/lib/modules/range.inc new file mode 100644 index 00000000..938f7093 --- /dev/null +++ b/lam/lib/modules/range.inc @@ -0,0 +1,478 @@ + Function attibute_processed already running? + public $processed; + + // Are the ranges ok??? + public $ranges_ok; + + // For check, if IPs overlaped. + public $overlaped; + + public function get_metaData() { + + $return = array(); + // manages dhcp accounts + $return["account_types"] = array("dhcp"); + // alias name + $return["alias"] = "Range"; + // this is a base module + $return["is_base"] = false; + // RDN attribute + $return["RDN"] = array("cn" => "high"); + // LDAP filter + $return["ldap_filter"] = array('or'=>"(objectClass=dhcpSubnet)"); + // module dependencies + $return['dependencies'] = array('depends' => array(), 'conflicts' => array()); + // managed object classes + $return['objectClasses'] = array(); + // managed attributes + $return['attributes'] = array(); + // help Entries + $return['help'] = array( + 'range_from' => array( + "Headline" => _("Range from"), + "Text" => _("The starting IP address of the range.") + ) , 'range_to' => array( + "Headline" => _("Range to"), + "Text" => _("The ending IP address of the range.") + ) , 'drop_range' => array( + "Headline" => _("Delete range"), + "Text" => _("Deletes an IP range.") + ) , 'add_range' => array( + "Headline" => _("New Range"), + "Text" => _("Adds input fields for a new IP range.") + ) ); + + // available PDF fields + $return['PDF_fields'] = array(); + return $return; + } + + public function load_Messages() { + $this->messages['range_errors'][0] = array('ERROR', _('One or more errors occured. All wrong fields are marked.'), ''); + $this->messages['add_range'][0] = array('ERROR', _('New range'), _('Adding the range failed because errors occured.')); + $this->messages['drop_range'][0] = array('ERROR', _('Delete range'), _('It is not possible to delete all ranges.')); + } + + /** + * + * Checked, if it's a valid range + * + * @param first ip + * @param second ip + * + * @return true, if it's a valid Range, else false; + **/ + + public function check_range($first_ip,$second_ip) { + + $ex_first = explode(".", $first_ip); + $ex_second = explode(".", $second_ip); + + if ($ex_first[0]!=$ex_second[0]) + return false; + + if ($ex_first[1]!=$ex_second[1]) + return false; + + if ($ex_first[2]!=$ex_second[2]) + return false; + + if ($ex_first[3]>$ex_second[3]) { + return false; + } + return true; + } + + /** + * + * Check if the range and subnet are valid. + * + * @param IP + * @param Subnet + * + * @return true if the range and subnet valid, else false! + * + **/ + + public function check_subnet_range($ip,$subnet) { + + // Check if the range was valid with the subnet: + $ex = explode(".", $ip); + $ex_subnet = explode(".", $subnet); + + if ($ex[0]==$ex_subnet[0] && $ex[1]==$ex_subnet[1] && $ex[2]==$ex_subnet[2]) { + + return true; + } + else + { + return false; + } + + } + + /** + * + * Checked, if Ranges are overlaped. + * + * @param first ip + * @param second ip + * + * @return false, if overlaped, else true. + * + **/ + function overlaped_range($ip,$ipB) { + $ex = explode(".", $ip); + $exB = explode(".", $ipB); + + if(!is_array($this->overlaped)) { + $this->overlaped = array(); + } + for($n=$ex[3];$n<=$exB[3];$n++) { + if (in_array($n, $this->overlaped)) { + return false; + } + else + { + $this->overlaped[] = $n; + } + } + return true; + } + + /** + * + * Reset the overlaped_range() function + * + **/ + function reset_overlaped_range() { + $this->overlaped = array(); + } + + /** + * Controls if the module button the account page is visible and activated. + * + * @return string status ("enabled", "disabled", "hidden") + */ + public function getButtonStatus() { + if ($_SESSION['account']->getAccountModule('dhcp_settings')->dn!=$_SESSION['config']->get_suffix('dhcp')) { + return "enabled"; + } + else { + return "hidden"; + } + } + + /** + * This function loads all needed LDAP attributes. + * + * @param array $attr list of attributes + */ + function load_attributes($attr) { + parent::load_attributes($attr); + // Load DHCP Options: + if ($_SESSION['account']->getAccountModule('dhcp_settings')->dn!=$_SESSION['config']->get_suffix('dhcp')) { + $this->orig = $attr; + $this->attributes = $attr; + + + // Load DHCP Options: + if (is_array($attr['dhcpRange'])) { + foreach($attr['dhcpRange'] AS $id=>$value) { + $ex = explode(" ", $value); + + // DHCP Range ins Array laden: + $this->ranges[$id] = array('range_start'=>$ex[0],'range_end'=>$ex[1]); + } + } + } + } + + /** + * + * Adapt the Ranges with the subnet. + * + * @return true, if ranges were edit. + * + **/ + public function reload_ranges() { + // Only run it, when ranges already exists: + if(is_array($this->ranges)) { + $ex_subnet = explode(".", $_SESSION['account']->getAccountModule('dhcp_settings')->attributes['cn'][0]); + $range_edit = false; // Range were edit? + foreach ($this->ranges AS $id=>$arr) { + if (!empty($this->ranges[$id]['range_start']) && !$this->check_subnet_range($this->ranges[$id]['range_start'],$_SESSION['account']->getAccountModule('dhcp_settings')->$this->attributes['cn'][0])) { + // Range anpassen: + $ex = explode(".", $this->ranges[$id]['range_start']); + $tmp = $this->ranges[$id]['range_start']; + $this->ranges[$id]['range_start'] = $ex_subnet['0'].".".$ex_subnet['1'].".".$ex_subnet['2'].".".$ex['3']; + if($tmp!=$this->ranges[$id]['range_start']) + $range_edit = true; + } + if (!empty($this->ranges[$id]['range_end']) && !$this->check_subnet_range($this->ranges[$id]['range_start'],$_SESSION['account']->getAccountModule('dhcp_settings')->$this->attributes['cn'][0])) { + // Range anpassen: + $ex = explode(".", $this->ranges[$id]['range_end']); + $tmp = $this->ranges[$id]['range_end']; + $this->ranges[$id]['range_end'] = $ex_subnet['0'].".".$ex_subnet['1'].".".$ex_subnet['2'].".".$ex['3']; + if($tmp!=$this->ranges[$id]['range_end']) + $range_edit = true; + } + } + if ($range_edit) { + // sort the range new, id it was edit. + foreach($this->ranges AS $id=>$arr) { + $this->attributes['dhcpRange'][$id] = $this->ranges[$id]['range_start']." ".$this->ranges[$id]['range_end']; + } + } + } + return $range_edit; + } + + /** + * Processes user input of the primary module page. + * It checks if all input values are correct and updates the associated LDAP attributes. + * + * @return array list of info/error messages + */ + public function process_attributes() { + $errors = array(); + + $droped = false; // Was a Range droped??? + if ($_SESSION['account']->getAccountModule('dhcp_settings')->dn!=$_SESSION['config']->get_suffix('dhcp')) { + if ($_SESSION['account']->getAccountModule('dhcp_settings')->attributes['cn'][0]!="") { + $was_a_error = false; + $this->reset_overlaped_range(); + + foreach($this->ranges AS $id=>$arr) { + + // Check if range is to drop + if (isset($_POST['drop_range_'.$id])) { + // Drop Range: + unset($this->ranges[$id]); + unset($this->attributes['dhcpRange'][$id]); + $droped = true; + continue; + } + + // if the inputs are empty, then do nothing: + if ($_POST['range_start_'.$id]=="" && $_POST['range_end_'.$id]=="") { + unset($this->attributes['dhcpRange'][$id]); + } + else + { + // Check range_start: + $_POST['range_start_'.$id] = trim($_POST['range_start_'.$id]); + if (!check_ip($_POST['range_start_'.$id])) { + $this->ranges[$id]['range_start'] = $_POST['range_start_'.$id]; + $was_a_error = true; + } + else + { + $this->ranges[$id]['range_start'] = $_POST['range_start_'.$id]; + } + + // Check end: + $_POST['range_end_'.$id] = trim($_POST['range_end_'.$id]); + if (!check_ip($_POST['range_end_'.$id])) { + $this->ranges[$id]['range_end'] = $_POST['range_end_'.$id]; + $was_a_error = true; + } + else + { + $this->ranges[$id]['range_end'] = $_POST['range_end_'.$id]; + } + + // Check if ip overlaped: + if(!$this->overlaped_range($_POST['range_start_'.$id],$_POST['range_end_'.$id])) { + $was_a_error = true; + } + + // Check if Subnet and range first are valid: + if (!$this->check_subnet_range($_POST['range_start_'.$id],$_SESSION['account']->getAccountModule('dhcp_settings')->attributes['cn'][0])) { + $was_a_error = true; + } + + // Check if Subnet and range last are valid: + if (!$this->check_subnet_range($_POST['range_last_'.$id],$_SESSION['account']->getAccountModule('dhcp_settings')->$this->attributes['cn'][0])) { + $was_a_error = true; + } + + // Check if Range is valid + if (!$this->check_range($_POST['range_start_'.$id],$_POST['range_end_'.$id])) { + $was_a_error = true; + } + + // Check, if range_start and range_end are ok! + if (!$was_a_error) { + $this->attributes['dhcpRange'][$id] = $_POST['range_start_'.$id]." ".$_POST['range_end_'.$id]; + $this->ranges_ok = true; + } + else + { + unset($this->attributes['dhcpRange'][$id]); + $this->ranges_ok = false; + } + } + } + } + + // Check if there was a error: + if ($was_a_error) { + $errors[] = $this->messages['range_errors'][0]; + } + + // Add new Range + if(isset($_POST['add_range'])) { + // Check, if there where no errors: + if ($was_a_error) { + $errors[] = $this->messages['add_range'][0]; + } + else + { + // Add Range: + $this->ranges[] = array('range_start'=>'','range_end'=>''); + } + } + + + $this->processed = true; + } + return $errors; + } + + /* This function will create the html-page + * to show a page with all attributes. + * It will output a complete html-table + */ + public function display_html_attributes() { + // user name if no posixAccount + $modules = $_SESSION['config']->get_AccountModules($this->get_scope()); + if ($_SESSION['account']->getAccountModule('dhcp_settings')->attributes['cn'][0]=="") { + echo "" . _("Please fill the DHCP settings first.") . ""; + } + else + { + + // If $ranges is not a array, then create an: + if (!is_array($this->ranges)) { + $this->ranges[] = array(); + } + $this->reset_overlaped_range(); + foreach($this->ranges AS $id=>$arr) { + + // Range start + if ($this->processed && !check_ip($this->ranges[$id]['range_start'])) { + $error = "«« " . _("The IP address is invalid."); + } elseif($this->processed && !$this->check_range($this->ranges[$id]['range_start'],$this->ranges[$id]['range_end'])) { + $error = "«« " . _("The range end needs to be greater than the range start."); + } elseif ($this->processed && !$this->check_subnet_range($this->ranges[$id]['range_start'],$_SESSION['account']->getAccountModule('dhcp_settings')->attributes['cn'][0])) { + $error = "«« " . _("The IP does not match the subnet."); + } elseif ($this->processed && !$this->overlaped_range($this->ranges[$id]['range_start'],$this->ranges[$id]['range_end']) ) { + $error = "«« " . _("The range conflicts with another range."); + } else { + $error = ""; + } + $return[] = array(0 => array('kind' => 'text', 'text' => _('Range from') . ":* "), + 1 => array('kind' => 'input', 'name' => 'range_start_'.$id.'', 'value' => $this->ranges[$id]['range_start']), + 2 => array('kind' => 'help', 'value' => 'range_from', 'scope' => 'user'), + 3 => array('kind' => 'text', 'text'=>$error)); + + // Range end + if ($this->processed && !check_ip($this->ranges[$id]['range_end'])) { + $error = "«« " . _("The IP address is invalid."); + } elseif ($this->processed && !$this->check_subnet_range($this->ranges[$id]['range_end'],$_SESSION['account']->getAccountModule('dhcp_settings')->attributes['cn'][0])) { + $error = "«« " . _("The IP does not match the subnet."); + } else { + $error = ""; + } + $return[] = array(0 => array('kind' => 'text', 'text' => _('Range to') . ":* "), + 1 => array('kind' => 'input', 'name' => 'range_end_'.$id.'', 'value' => $this->ranges[$id]['range_end']), + 2 => array('kind' => 'help', 'value' => 'range_to', 'scope' => 'user'), + 3 => array('kind' => 'text', 'text'=>$error)); + + // Drop range: + $return[] = array( + 0 => array('kind' => 'text', 'text' => _('Delete Range') . ':'), + 1 => array('kind' => 'input', 'name' => 'drop_range_'.$id, 'type' => 'submit', 'value' => _('Delete range')), + 2 => array('kind' => 'help', 'value' => 'drop_range')); + + // Space Line + $return[] = array(0 => array('kind' => 'text', 'text' => '
')); + } + + // Range hinzufügen: + $return[] = array( + 0 => array('kind' => 'text', 'text' => _('New range') . ':'), + 1 => array('kind' => 'input', 'name' => 'add_range', 'type' => 'submit', 'value' => _('New range')), + 2 => array('kind' => 'help', 'value' => 'add_range')); + } + + return $return; + } + + /* This function returns an array with 4 entries: + * array( DN1 ('add' => array($attr), 'remove' => array($attr), 'modify' => array($attr), 'lamdaemon' => array(cmds)), DN2 .... ) + * DN is the DN to change. It may be possible to change several DNs, + * e.g. create a new user and add him to some groups via attribute memberUid + * add are attributes which have to be added to ldap entry + * remove are attributes which have to be removed from ldap entry + * lamdaemon are lamdaemon commands to modify homedir, quotas, ... + */ + public function save_attributes() { + $return = array(); + // Get easy attributes + if ($_SESSION['account']->getAccountModule('dhcp_settings')->dn!=$_SESSION['config']->get_suffix('dhcp')) { + $return = $this->getAccountContainer()->save_module_attributes($this->attributes, $this->orig); + } + // Return attributes + return $return; + } + +} +?> \ No newline at end of file