Dmitriev Roman 3 månader sedan
förälder
incheckning
941beaf815
35 ändrade filer med 1265 tillägg och 743 borttagningar
  1. 2 0
      docs/databases/mysql/en/data.sql
  2. 1 0
      docs/databases/mysql/ru/data.sql
  3. 1 0
      docs/databases/postgres/en/data.sql
  4. 1 0
      docs/databases/postgres/ru/data.sql
  5. 38 32
      html/admin/customers/building.php
  6. 50 29
      html/admin/customers/control-options.php
  7. 53 85
      html/admin/customers/devmodels.php
  8. 40 42
      html/admin/customers/devvendors.php
  9. 81 41
      html/admin/customers/editcustom.php
  10. 87 74
      html/admin/customers/editsubnet.php
  11. 50 25
      html/admin/customers/index-subnets.php
  12. 28 14
      html/admin/customers/index.php
  13. 24 10
      html/admin/customers/ipcam.php
  14. 25 13
      html/admin/devices/edit_gw_instances.php
  15. 1 1
      html/admin/devices/edit_l3int.php
  16. 14 10
      html/admin/filters/editfilter.php
  17. 63 41
      html/admin/filters/editgroup.php
  18. 33 14
      html/admin/filters/groups.php
  19. 34 18
      html/admin/filters/index.php
  20. 66 27
      html/admin/filters/instances.php
  21. 117 50
      html/admin/groups/edit_group.php
  22. 25 17
      html/admin/groups/index.php
  23. 11 5
      html/admin/iplist/auto_rules.php
  24. 26 21
      html/admin/iplist/deleted.php
  25. 26 13
      html/admin/iplist/doubles.php
  26. 1 1
      html/admin/iplist/index.php
  27. 73 29
      html/admin/queues/index.php
  28. 99 60
      html/admin/users/edit_alias.php
  29. 110 50
      html/admin/users/edit_rules.php
  30. 1 1
      html/admin/users/edituser.php
  31. 6 1
      html/admin/users/index.php
  32. 8 2
      html/inc/auth.utils.php
  33. 64 14
      html/inc/common.php
  34. 2 2
      html/inc/snmp.php
  35. 4 1
      scripts/updates/3-0-1/migration.msql

+ 2 - 0
docs/databases/mysql/en/data.sql

@@ -6,6 +6,7 @@ SET time_zone = "+00:00";
 /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
 /*!40101 SET NAMES utf8mb4 */;
 
+INSERT INTO `acl` (`id`, `name`, description_english, description_russian) VALUES(0,'Disabled','User disabled','Пользователь отключен');
 INSERT INTO `acl` (`id`, `name`, description_english, description_russian) VALUES(1, 'Full access', 'Full access', 'Полный доступ');
 INSERT INTO `acl` (`id`, `name`, description_english, description_russian) VALUES(2, 'Operator', 'Editing parameters that are not related to access rights', 'Редактирование параметров, не связанных с правами доступа');
 INSERT INTO `acl` (`id`, `name`, description_english, description_russian) VALUES(3, 'View only', 'View only', 'Только просмотр');
@@ -351,6 +352,7 @@ INSERT INTO `config` VALUES (144,37,'/opt/Eye/scripts/sync_mikrotik.pl');
 INSERT INTO `config` VALUES (145,23,'1');
 INSERT INTO `config` VALUES (148,22,'1');
 
+
 INSERT INTO `version` (`id`, `version`) VALUES(1, '3.0.1');
 
 /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

+ 1 - 0
docs/databases/mysql/ru/data.sql

@@ -6,6 +6,7 @@ SET time_zone = "+00:00";
 /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
 /*!40101 SET NAMES utf8mb4 */;
 
+INSERT INTO `acl` (`id`, `name`, description_english, description_russian) VALUES(0,'Disabled','User disabled','Пользователь отключен');
 INSERT INTO `acl` (`id`, `name`, description_english, description_russian) VALUES(1, 'Full access', 'Full access', 'Полный доступ');
 INSERT INTO `acl` (`id`, `name`, description_english, description_russian) VALUES(2, 'Operator', 'Editing parameters that are not related to access rights', 'Редактирование параметров, не связанных с правами доступа');
 INSERT INTO `acl` (`id`, `name`, description_english, description_russian) VALUES(3, 'View only', 'View only', 'Только просмотр');

+ 1 - 0
docs/databases/postgres/en/data.sql

@@ -3,6 +3,7 @@
 -- ACL (Access Control List)
 INSERT INTO acl (id, name, description_english, description_russian) 
 VALUES 
+(0, 'Disabled','User disabled','Пользователь отключен'),
 (1, 'Full access', 'Full access', 'Полный доступ'),
 (2, 'Operator', 'Editing parameters that are not related to access rights', 'Редактирование параметров, не связанных с правами доступа'),
 (3, 'View only', 'View only', 'Только просмотр')

+ 1 - 0
docs/databases/postgres/ru/data.sql

@@ -3,6 +3,7 @@
 -- ACL (Access Control List)
 INSERT INTO acl (id, name, description_english, description_russian) 
 VALUES 
+(0, 'Disabled','User disabled','Пользователь отключен'),
 (1, 'Full access', 'Full access', 'Полный доступ'),
 (2, 'Operator', 'Editing parameters that are not related to access rights', 'Редактирование параметров, не связанных с правами доступа'),
 (3, 'View only', 'View only', 'Только просмотр')

+ 38 - 32
html/admin/customers/building.php

@@ -2,51 +2,57 @@
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 
-if (isset($_POST["remove"])) {
-    $fid = $_POST["f_id"];
-    foreach ($fid as $key => $val) {
-        if (isset($val) and $val > 1) {
-            LOG_INFO($db_link,'Remove building id: '. $val .' '. dump_record($db_link,'building','id=?', [$val]));
-            delete_record($db_link, "building", "id=?", [$val]);
-        }
+if (getPOST("remove")) {
+    $fid = getPOST("f_id", null, []);
+    $valid_ids = array_filter(array_map('intval', $fid), fn($id) => $id > 1);
+
+    foreach ($valid_ids as $val) {
+        LOG_INFO($db_link, 'Remove building id: ' . $val . ' ' . dump_record($db_link, 'building', 'id=?', [$val]));
+        delete_record($db_link, "building", "id=?", [$val]);
     }
+
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST['save'])) {
-    $len = is_array($_POST['r_id']) ? count($_POST['r_id']) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $save_id = intval($_POST['save'][$i]);
-        if ($save_id == 0) {
-            continue;
-        }
-        $len_all = is_array($_POST['r_id']) ? count($_POST['r_id']) : 0;
-        for ($j = 0; $j < $len_all; $j ++) {
-            if (intval($_POST['r_id'][$j]) != $save_id) {
-                continue;
-            }
-            $value = $_POST['f_building_name'][$j];
-            $value_description = $_POST['f_building_description'][$j];
-            if (isset($value)) {
-                $new['name'] = $value;
-                $new['description'] = $value_description;
-                LOG_INFO($db_link,"Change building id='{$save_id}': name=".$value." description=".$value_description);
-                update_record($db_link, "building", "id=?", $new, [$save_id]);
-            }
+if (getPOST("save")) {
+    $r_id = getPOST("r_id",null, []);
+    $f_building_name = getPOST("f_building_name", null, []);
+    $f_building_description = getPOST("f_building_description", null, []);
+    $save_flags = getPOST("save", null, []);
+
+    $r_id = array_map('intval', $r_id);
+    $save_flags = array_map('intval', $save_flags);
+
+    foreach ($save_flags as $i => $save_id) {
+        if ($save_id <= 0) continue;
+
+        $found_index = array_search($save_id, $r_id, true);
+        if ($found_index === false) continue;
+
+        $name = trim($f_building_name[$found_index] ?? '');
+        $description = trim($f_building_description[$found_index] ?? '');
+
+        if ($name !== '') {
+            $new = ['name' => $name, 'description' => $description];
+            LOG_INFO($db_link, "Change building id='{$save_id}': name=" . $name . " description=" . $description);
+            update_record($db_link, "building", "id=?", $new, [$save_id]);
         }
     }
+
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["create"])) {
-    $building_name = $_POST["new_building"];
-    if (isset($building_name)) {
-        $new['name'] = $building_name;
-        LOG_INFO($db_link,'Add building $building_name');
+if (getPOST("create")) {
+    $building_name = trim(getPOST("new_building", null, ''));
+    
+    if ($building_name !== '') {
+        $new = ['name' => $building_name];
+        LOG_INFO($db_link, "Add building: " . $building_name);
         insert_record($db_link, "building", $new);
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }

+ 50 - 29
html/admin/customers/control-options.php

@@ -3,37 +3,53 @@
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/auth.php");
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/languages/" . HTML_LANG . ".php");
 
-if (isset($_POST["remove"])) {
-    if (!empty($_POST["f_id"])) {
-        $fid = $_POST["f_id"];
+if (getPOST("remove")) {
+    $fid = getPOST("f_id", null, []);
+    if (!empty($fid) && is_array($fid)) {
         foreach ($fid as $option_id => $config_id) {
-            $opt_def = get_record($db_link, "config_options", "id=?" ,[ $option_id ]);
-            LOG_INFO($db_link, WEB_config_remove_option . " id: " . $config_id . " name: " . $opt_def["option_name"]);
-            delete_record($db_link, "config", "id=?" ,[ $config_id ]);
+            $option_id = (int)$option_id;
+            $config_id = (int)$config_id;
+            
+            if ($option_id <= 0 || $config_id <= 0) continue;
+
+            $opt_def = get_record($db_link, "config_options", "id = ?", [$option_id]);
+            if ($opt_def) {
+                LOG_INFO($db_link, WEB_config_remove_option . " id: " . $config_id . " name: " . ($opt_def["option_name"] ?? ''));
+            }
+            delete_record($db_link, "config", "id = ?", [$config_id]);
         }
     }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST['save'])) {
-    if (!empty($_POST["f_id"])) {
-        $fid = $_POST["f_id"];
+if (getPOST("save")) {
+    $fid = getPOST("f_id", null, []);
+    $f_config_value = getPOST("f_config_value", null, []);
+    if (!empty($fid) && is_array($fid)) {
         foreach ($fid as $option_id => $config_id) {
-            $value = $_POST['f_config_value'][$config_id];
-            $option = get_record_sql($db_link, "SELECT * FROM config_options WHERE id=?",[ $option_id ]);
-            if (isset($value)) {
-                $new['value'] = $value;
-            }
-            //crypt password
-            if ($option_id == 29) { 
-                $new['value']=crypt_string($value); 
+            $option_id = (int)$option_id;
+            $config_id = (int)$config_id;
+            
+            if ($option_id <= 0 || $config_id <= 0) continue;
+
+            $value = trim($f_config_value[$config_id] ?? '');
+            $option = get_record($db_link, "config_options", "id = ?", [$option_id]);
+
+            if (!$option) continue;
+
+            $new = [];
+            if ($option_id == 29) {
+                // Пароль — шифруем
+                $new['value'] = crypt_string($value);
             } else {
-            //log event if changed option not password
-                LOG_INFO($db_link, WEB_config_set_option . " id: " . $config_id . " name: " . $option["option_name"] . " = " . $value);
+                // Обычное значение
+                $new['value'] = $value;
+                LOG_INFO($db_link, WEB_config_set_option . " id: " . $config_id . " name: " . ($option["option_name"] ?? '') . " = " . $value);
             }
+
             if (!empty($new)) {
-                update_record($db_link, "config", "id=?" , $new, [$config_id ]);
+                update_record($db_link, "config", "id = ?", $new, [$config_id]);
             }
         }
     }
@@ -41,14 +57,19 @@ if (isset($_POST['save'])) {
     exit;
 }
 
-if (isset($_POST["create"])) {
-    $new_option = $_POST["f_new_option"];
-    if (isset($new_option)) {
-        $new['option_id'] = $new_option;
-        $new['value'] = get_option($db_link, $new_option);
-        $opt_def = get_record($db_link, "config_options", "id=?", [$new_option]);
-        LOG_INFO($db_link, WEB_config_add_option . " id: " . $new_option . " name: " . $opt_def["option_name"] . " = " . $new['value']);
-        insert_record($db_link, "config", $new);
+if (getPOST("create")) {
+    $new_option = (int)getPOST("f_new_option", null, 0);
+    
+    if ($new_option > 0) {
+        $opt_def = get_record($db_link, "config_options", "id = ?", [$new_option]);
+        if ($opt_def) {
+            $new = [
+                'option_id' => $new_option,
+                'value' => get_option($db_link, $new_option)
+            ];
+            LOG_INFO($db_link, WEB_config_add_option . " id: " . $new_option . " name: " . ($opt_def["option_name"] ?? '') . " = " . ($new['value'] ?? ''));
+            insert_record($db_link, "config", $new);
+        }
     }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
@@ -77,7 +98,7 @@ print_control_submenu($page_url);
                     <input type="submit" onclick="return confirm('<?php print WEB_btn_delete; ?>?')" name="remove" value="<?php print WEB_btn_remove; ?>">
                 </td>
                 <td class="up">
-                    <button name='save'><?php print WEB_btn_save; ?></button>
+                    <button name='save' value='save'><?php print WEB_btn_save; ?></button>
                 </td>
             </tr>
 

+ 53 - 85
html/admin/customers/devmodels.php

@@ -5,102 +5,70 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/vendorfilter.php");
 
-if (isset($_POST['save'])) {
-    $saved = array();
-    //button save
-    $len = is_array($_POST['save']) ? count($_POST['save']) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $save_id = intval($_POST['save'][$i]);
-        if ($save_id == 0) { continue;  }
-        array_push($saved,$save_id);
-        }
-    //select box
-    $len = is_array($_POST['f_id']) ? count($_POST['f_id']) : 0;
-    if ($len>0) {
-        for ($i = 0; $i < $len; $i ++) {
-            $save_id = intval($_POST['f_id'][$i]);
-            if ($save_id == 0) { continue; }
-            if (!in_array($save_id, $saved)) { array_push($saved,$save_id); }
-            }
-        }
-    //save changes
-    $len = is_array($saved) ? count($saved) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $save_id = intval($saved[$i]);
-        if ($save_id == 0) { continue;  }
-        $len_all = is_array($_POST['r_id']) ? count($_POST['r_id']) : 0;
-        for ($j = 0; $j < $len_all; $j ++) {
-            if (intval($_POST['r_id'][$j]) != $save_id) { continue; }
-            $new = NULL;
-            if ($save_id>=10000) {
-                $new['vendor_id'] = $_POST['f_vendor'][$j];
-	            $new['model_name'] = $_POST['f_name'][$j];
-	            $new['poe_in'] = $_POST['f_poe_in'][$j];
-	            $new['poe_out'] = $_POST['f_poe_out'][$j];
-	        } else {
-	            $new['poe_in'] = $_POST['f_poe_in'][$j];
-	            $new['poe_out'] = $_POST['f_poe_out'][$j];      
+if (getPOST("save")) {
+    $f_ids = getPOST("f_id", null, []);
+    if (!empty($f_ids) && is_array($f_ids)) {
+        // Преобразуем в целые числа
+        $f_ids = array_map('intval', array_filter($f_ids, fn($id) => $id > 0));
+        // Получаем все данные
+        $r_ids       = array_map('intval', getPOST("r_id",       null, []));
+        $f_vendors   = getPOST("f_vendor",   null, []);
+        $f_names     = getPOST("f_name",     null, []);
+        $f_poe_ins   = getPOST("f_poe_in",   null, []);
+        $f_poe_outs  = getPOST("f_poe_out",  null, []);
+        $f_nagios    = getPOST("f_nagios",   null, []);
+        foreach ($f_ids as $save_id) {
+            $idx = array_search($save_id, $r_ids, true);
+            if ($idx === false) continue;
+            $new = [
+                'poe_in'  => !empty($f_poe_ins[$idx])  ? (int)$f_poe_ins[$idx]  : 0,
+                'poe_out' => !empty($f_poe_outs[$idx]) ? (int)$f_poe_outs[$idx] : 0,
+                'nagios_template' => trim($f_nagios[$idx] ?? '')
+            ];
+            // Для кастомных моделей (ID >= 10000)
+            if ($save_id >= 10000) {
+                $new['vendor_id']  = !empty($f_vendors[$idx]) ? (int)$f_vendors[$idx] : 1;
+                $new['model_name'] = trim($f_names[$idx] ?? '');
             }
-            if (!isset($new['poe_in']) OR empty($new['poe_in'])) { $new['poe_in'] = 0; }
-            if (!isset($new['poe_out']) OR empty($new['poe_out'])) { $new['poe_out'] = 0; }
-            $new['nagios_template'] = $_POST['f_nagios'][$j];
+
             update_record($db_link, "device_models", "id = ?", $new, [$save_id]);
-            }
         }
+    }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
-    }
+}
 
-if (isset($_POST['remove'])) {
-        $saved = array();
-        //button save
-        $len = is_array($_POST['save']) ? count($_POST['save']) : 0;
-        for ($i = 0; $i < $len; $i ++) {
-            $save_id = intval($_POST['save'][$i]);
-            if ($save_id == 0) { continue;  }
-            array_push($saved,$save_id);
-            }
-        //select box
-        $len = is_array($_POST['f_id']) ? count($_POST['f_id']) : 0;
-        if ($len>0) {
-            for ($i = 0; $i < $len; $i ++) {
-                $save_id = intval($_POST['f_id'][$i]);
-                if ($save_id == 0) { continue; }
-                if (!in_array($save_id, $saved)) { array_push($saved,$save_id); }
-                }
-            }
-        //save changes
-        $len = is_array($saved) ? count($saved) : 0;
-        for ($i = 0; $i < $len; $i ++) {
-            $save_id = intval($saved[$i]);
-            if ($save_id == 0) { continue;  }
-            $len_all = is_array($_POST['r_id']) ? count($_POST['r_id']) : 0;
-            for ($j = 0; $j < $len_all; $j ++) {
-                if (intval($_POST['r_id'][$j]) != $save_id) { continue; }
-                if ($save_id>=10000) { 
-                    delete_record($db_link, "device_models", "id= ?", [$save_id]);
-                    update_records($db_link, 'devices', 'device_model_id = ?', ['device_model_id' => null], [$save_id]);
-                    }
-                }
-            }
-        header("Location: " . $_SERVER["REQUEST_URI"]);
-        exit;
+if (getPOST("remove")) {
+    $f_ids = getPOST("f_id", null, []);
+    if (!empty($f_ids) && is_array($f_ids)) {
+        $f_ids = array_map('intval', array_filter($f_ids, fn($id) => $id >= 10000));
+        foreach ($f_ids as $id) {
+            delete_record($db_link, "device_models", "id = ?", [$id]);
+            update_records($db_link, "devices", "device_model_id = ?", ['device_model_id' => null], [$id]);
         }
+    }
+    header("Location: " . $_SERVER["REQUEST_URI"]);
+    exit;
+}
 
-if (isset($_POST["create"])) {
-    $model_name = $_POST["new_model"];
-    if (isset($model_name)) {
-	$max_record = get_record_sql($db_link,"SELECT MAX(id) as max_id FROM device_models");
-	if (!isset($max_record) or $max_record['max_id']<10000) { $next_id = 10000; } else { $next_id = $max_record['max_id'] + 1; }
-        $new['vendor_id']=1;
-        $new['id'] = $next_id;
-        if (isset($f_vendor_select) and $f_vendor_select>1) { $new['vendor_id']=$f_vendor_select; }
-        $new['model_name'] = $model_name;
+if (getPOST("create")) {
+    $model_name = trim(getPOST("new_model", null, ''));
+    if ($model_name !== '') {
+        $max_record = get_record_sql($db_link, "SELECT MAX(id) AS max_id FROM device_models");
+        $next_id = (isset($max_record['max_id']) && $max_record['max_id'] >= 10000)
+            ? (int)$max_record['max_id'] + 1
+            : 10000;
+
+        $new = [
+            'id'         => $next_id,
+            'vendor_id'  => (int)($f_vendor_select ?? 1),
+            'model_name' => $model_name
+        ];
         insert_record($db_link, "device_models", $new);
-        }
+    }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
-    }
+}
 
 unset($_POST);
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");

+ 40 - 42
html/admin/customers/devvendors.php

@@ -4,55 +4,53 @@ $default_displayed=25;
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 
-if (isset($_POST['save'])) {
-    $saved = array();
-    //button save
-    $len = is_array($_POST['save']) ? count($_POST['save']) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $save_id = intval($_POST['save'][$i]);
-        if ($save_id == 0) { continue;  }
-        if ($save_id<10000) { continue; }
-        array_push($saved,$save_id);
-        }
-    //select box
-    $len = is_array($_POST['f_id']) ? count($_POST['f_id']) : 0;
-    if ($len>0) {
-        for ($i = 0; $i < $len; $i ++) {
-            $save_id = intval($_POST['f_id'][$i]);
-            if ($save_id == 0) { continue; }
-            if ($save_id<10000) { continue; }
-            if (!in_array($save_id, $saved)) { array_push($saved,$save_id); }
-            }
-        }
-    //save changes
-    $len = is_array($saved) ? count($saved) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $save_id = intval($saved[$i]);
-        if ($save_id == 0) { continue;  }
-        if ($save_id<10000) { continue; }
-        $len_all = is_array($_POST['r_id']) ? count($_POST['r_id']) : 0;
-        for ($j = 0; $j < $len_all; $j ++) {
-            if (intval($_POST['r_id'][$j]) != $save_id) { continue; }
-            $new['name'] = $_POST['f_name'][$j];
-            update_record($db_link, "vendors", "id= ?", $new, [$save_id]);
+// Сохранение изменений
+if (getPOST("save") !== null) {
+    $selected_ids = getPOST("f_id", null, []);
+    
+    if (!empty($selected_ids) && is_array($selected_ids)) {
+        // Преобразуем в целые числа и оставляем только >= 10000
+        $selected_ids = array_filter(array_map('intval', $selected_ids), fn($id) => $id >= 10000);
+        
+        if (!empty($selected_ids)) {
+            $r_ids   = array_map('intval', getPOST("r_id",   null, []));
+            $f_names = getPOST("f_name", null, []);
+            
+            foreach ($selected_ids as $vendor_id) {
+                $idx = array_search($vendor_id, $r_ids, true);
+                if ($idx === false) continue;
+                
+                $name = trim($f_names[$idx] ?? '');
+                if ($name === '') continue;
+                
+                update_record($db_link, "vendors", "id = ?", ['name' => $name], [$vendor_id]);
             }
         }
+    }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
-    }
+}
 
-if (isset($_POST["create"])) {
-    $vendor_name = $_POST["new_vendor"];
-    if (isset($vendor_name)) {
-	$max_record = get_record_sql($db_link,"SELECT MAX(id) as max_id FROM vendors");
-	if (!isset($max_record) or $max_record['max_id']<10000) { $next_id = 10000; } else { $next_id = $max_record['max_id'] + 1; }
-        $new['id'] = $next_id;
-        $new['name'] = $vendor_name;
-        insert_record($db_link, "vendors", $new);
-        }
+// Создание нового производителя
+if (getPOST("create") !== null) {
+    $vendor_name = trim(getPOST("new_vendor", null, ''));
+    
+    if ($vendor_name !== '') {
+        $max_record = get_record_sql($db_link, "SELECT MAX(id) AS max_id FROM vendors");
+        $next_id = (isset($max_record['max_id']) && $max_record['max_id'] >= 10000)
+            ? (int)$max_record['max_id'] + 1
+            : 10000;
+            
+        insert_record($db_link, "vendors", [
+            'id'   => $next_id,
+            'name' => $vendor_name
+        ]);
+    }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
-    }
+}
 
 unset($_POST);
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");

+ 81 - 41
html/admin/customers/editcustom.php

@@ -5,19 +5,41 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/idfilter.php");
 
 $msg_error = "";
 
-if (isset($_POST["edituser"])) {
+$customer=get_record($db_link,'customers',"id=?", [$id]);
+
+if (getPOST("edituser") !== null) {
     global $salt;
-    $new['login'] = substr(trim($_POST["login"]), 0, 20);
-    $new['description'] = substr(trim($_POST["description"]), 0, 100);
-    if (isset($_POST["pass"]) and (strlen(trim($_POST["pass"])) > 0)) {
-        $new['password'] = password_hash($_POST["pass"], PASSWORD_BCRYPT);
-	}
-    if (isset($_POST["api_key"]) and (strlen(trim($_POST["api_key"])) > 20)) {
-        $new['api_key'] = $_POST["api_key"];
-	}
-    $new['rights'] = $_POST["f_acl"] * 1;
-    update_record($db_link, "customers", "id= ?", $new, [ $id ]);
-    unset($_POST["pass"]);
+
+    $new = [];
+
+    // Логин (макс. 20 символов)
+    $new['login'] = substr(trim(getPOST("login", null, $customer['login'])), 0, 20);
+
+    // Описание (макс. 100 символов)
+    $new['description'] = substr(trim(getPOST("description", null, '')), 0, 100);
+
+    // Пароль (если задан и не пустой)
+    $pass = trim(getPOST("pass", null, ''));
+    if ($pass !== '') {
+        $new['password'] = password_hash($pass, PASSWORD_BCRYPT);
+    }
+
+    // API-ключ (если длина > 20)
+    $api_key = getPOST("api_key", null, randomPassword(20));
+    if (strlen(trim($api_key)) > 20) {
+        $new['api_key'] = substr(trim($api_key),0,20);
+    }
+    if (strlen(trim($api_key)) <20) {
+        $new['api_key'] = $customer['api_key'];
+    }
+    $new['api_key'] = trim($api_key);
+
+    // Права доступа
+    $new['rights'] = (int)getPOST("f_acl", null, 0);
+
+    // Обновление записи
+    update_record($db_link, "customers", "id = ?", $new, [$id]);
+
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
@@ -27,37 +49,55 @@ unset($_POST);
 print_control_submenu($page_url);
 
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");
-$customer=get_record($db_link,'customers',"id=?", [$id]);
+
 ?>
 
 <div id="cont">
 <br><b><?php echo WEB_customer_titles; ?></b><br>
-	<form name="def" action="editcustom.php?id=<?php echo $id; ?>" method="post">
-		<input type="hidden" name="id" value=<?php echo $id; ?>>
-		<table class="data">
-			<tr>
-				<td><?php echo WEB_customer_login; ?></td>
-				<td><input type="text" name="login" value="<?php print $customer['login']; ?>" size=20></td>
-			</tr>
-			<tr>
-				<td><?php echo WEB_cell_description; ?></td>
-				<td><input type="text" name="description" value="<?php print $customer['description']; ?>" size=50></td>
-			</tr>
-			<tr>
-				<td><?php echo WEB_customer_password; ?></td>
-				<td><input type="password" name="pass" value="" size=20></td>
-			</tr>
-			<tr>
-				<td><?php echo WEB_customer_api_key; ?></td>
-				<td><input type="text" name="api_key" value="<?php print $customer['api_key']; ?>" size=50></td>
-			</tr>
-			<tr>
-				<td><?php echo WEB_customer_mode; ?></td>
-				<td><?php print_acl_select($db_link,'f_acl',$customer['rights']); ?></td>
-			</tr>
-                        <tr>
-        			<td colspan=2><input type="submit" name="edituser" value="<?php echo WEB_btn_save; ?>"></td>
-                        </tr>
-		</table>
-	</form>
+<form name="def" action="editcustom.php?id=<?php echo $id; ?>" method="post">
+    <input type="hidden" name="id" value="<?php echo $id; ?>">
+    <table class="data">
+        <tr>
+            <td><?php echo WEB_customer_login; ?></td>
+            <td><input type="text" name="login" value="<?php print htmlspecialchars($customer['login']); ?>" size=20></td>
+        </tr>
+        <tr>
+            <td><?php echo WEB_cell_description; ?></td>
+            <td><input type="text" name="description" value="<?php print htmlspecialchars($customer['description']); ?>" size=50></td>
+        </tr>
+        <tr>
+            <td><?php echo WEB_customer_password; ?></td>
+            <td><input type="password" name="pass" value="" size=20></td>
+        </tr>
+        <tr>
+            <td><?php echo WEB_customer_api_key; ?></td>
+            <td>
+                <input type="text" name="api_key" id="api_key" value="<?php print htmlspecialchars($customer['api_key']); ?>" size=50>
+                <!-- Кнопка перегенерации -->
+                <button type="button" onclick="generateApiKey()">🔄</button>
+            </td>
+        </tr>
+        <tr>
+            <td><?php echo WEB_customer_mode; ?></td>
+            <td><?php print_acl_select($db_link,'f_acl',$customer['rights']); ?></td>
+        </tr>
+        <tr>
+            <td colspan=2>
+                <input type="submit" name="edituser" value="<?php echo WEB_btn_save; ?>">
+            </td>
+        </tr>
+    </table>
+</form>
+
+<script>
+function generateApiKey() {
+    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+    let result = '';
+    for (let i = 0; i < 20; i++) {
+        result += chars.charAt(Math.floor(Math.random() * chars.length));
+    }
+    document.getElementById('api_key').value = result;
+}
+</script>
+
 <?php require_once ($_SERVER['DOCUMENT_ROOT']."/inc/footer.php"); ?>

+ 87 - 74
html/admin/customers/editsubnet.php

@@ -3,104 +3,117 @@ require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/auth.php");
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/languages/" . HTML_LANG . ".php");
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/idfilter.php");
 
-if (isset($_POST['s_save'])) {
-        $new = [];
-
-        // === INPUT CLEANING =====================================================================================
-        $new['subnet'] = trim($_POST['s_subnet']);
-        $new['vlan_tag'] = normalize_vlan($_POST['s_vlan']);
-        $new['office'] = intval_or_zero($_POST['s_office']);
-        $new['hotspot'] = intval_or_zero($_POST['s_hotspot']);
-        $new['vpn'] = intval_or_zero($_POST['s_vpn']);
-        $new['free'] = intval_or_zero($_POST['s_free']);
-        $new['dhcp'] = intval_or_zero($_POST['s_dhcp']);
-        $new['dhcp_lease_time'] = intval_or_zero($_POST['s_lease_time']);
-        $new['static'] = intval_or_zero($_POST['s_static']);
-        $new['discovery'] = intval_or_zero($_POST['s_discovery']);
-        $new['notify'] = intval_or_zero($_POST['s_notify']);
-        $new['dhcp_update_hostname'] = intval_or_zero($_POST['s_dhcp_update']);
-        $new['description'] = trim($_POST['s_description']);
+$sSQL = "SELECT * FROM subnets WHERE id= ?";
+$subnet_info = get_record_sql($db_link, $sSQL, [ $id ]);
 
-        // === CIDR / RANGE PROCESSING =============================================================================
+if (getPOST("s_save") !== null) {
+    $new = [];
 
-        $range = cidrToRange($new['subnet']);
-        $first_ip     = $range[0];
-        $last_ip      = $range[1];
-        $cidr         = $range[2][1] ?? null;
-        $new['subnet'] = ($cidr && $cidr <= 32) ? "$first_ip/$cidr" : '';
-        $new['ip_int_start'] = ip2long($first_ip);
-        $new['ip_int_stop']  = ip2long($last_ip);
+    // === INPUT CLEANING =====================================================================================
+    $new['subnet']              = trim(getPOST("s_subnet", null, $subnet_info['subnet']));
 
-        // === GATEWAY ===============================================================================================
+    // === CIDR / RANGE PROCESSING ============================================================================
+    $range = cidrToRange($new['subnet']);
+    $first_ip = $range[0];
+    $last_ip  = $range[1];
+    $cidr     = $range[2] ?? null;
 
-        $gateway_fallback = ip2long($range[5]);
-        $new['gateway'] = get_dhcp_gateway($_POST['s_gateway'], $gateway_fallback);
+    // Формируем корректный CIDR
+    if ($cidr !== null && $cidr < 32) {
+            $new['subnet'] = "$first_ip/$cidr";
+        } else {
+            $range = cidrToRange($first_ip.'/24');
+            $first_ip = $range[0];
+            $last_ip  = $range[1];
+            $cidr     = $range[2] ?? null;
+            if ($cidr !== null && $cidr < 32) {
+                $new['subnet'] = "$first_ip/$cidr";
+                } else {
+                //abort
+                header("Location: " . $_SERVER["REQUEST_URI"]);
+                exit;
+                }
+        }
 
-        // === GATEWAY VALIDATION ===================================================================================
+    $new['vlan_tag']            = normalize_vlan(getPOST("s_vlan", null, 1));
+    $new['office']              = intval_or_zero(getPOST("s_office", null, 0));
+    $new['hotspot']             = intval_or_zero(getPOST("s_hotspot", null, 0));
+    $new['vpn']                 = intval_or_zero(getPOST("s_vpn", null, 0));
+    $new['free']                = intval_or_zero(getPOST("s_free", null, 0));
+    $new['dhcp']                = intval_or_zero(getPOST("s_dhcp", null, 0));
+    $new['dhcp_lease_time']     = intval_or_zero(getPOST("s_lease_time", null, 0));
+    $new['static']              = intval_or_zero(getPOST("s_static", null, 0));
+    $new['discovery']           = intval_or_zero(getPOST("s_discovery", null, 0));
+    $new['notify']              = intval_or_zero(getPOST("s_notify", null, 0));
+    $new['dhcp_update_hostname']= intval_or_zero(getPOST("s_dhcp_update", null, 0));
+    $new['description']         = trim(getPOST("s_description", null, ''));
 
-        if ( !$new['gateway'] || $new['gateway'] <= $new['ip_int_start'] || $new['gateway'] >= $new['ip_int_stop'] ) {
-              // если введённый gateway не подходит — используем дефолтный
-                $new['gateway'] = $gateway_fallback;
-            }
+    $new['ip_int_start']        = ip2long($first_ip);
+    $new['ip_int_stop']         = ip2long($last_ip);
 
-        // === DHCP RANGE VALIDATION ================================================================================
+    // === GATEWAY ============================================================================================
+    $gateway_fallback = ip2long($range[5]);
+    $new['gateway'] = get_dhcp_gateway(getPOST("s_gateway", null, ''), $gateway_fallback);
 
-        $dhcp_start = ip2long(trim($_POST['s_dhcp_start']));
-        $dhcp_stop  = ip2long(trim($_POST['s_dhcp_stop']));
+    // === GATEWAY VALIDATION =================================================================================
+    if (!$new['gateway'] || $new['gateway'] <= $new['ip_int_start'] || $new['gateway'] >= $new['ip_int_stop']) {
+        $new['gateway'] = $gateway_fallback;
+    }
 
-        if (!validate_dhcp_range(
-            $dhcp_start,
-            $dhcp_stop,
-            $new['ip_int_start'],
-            $new['ip_int_stop']
-        )) {
-            // fallback пул
-            $dhcp_start = ip2long($range[3]);
-            $dhcp_stop  = ip2long($range[4]);
-        }
+    // === DHCP RANGE VALIDATION =============================================================================
+    $dhcp_start = ip2long(trim(getPOST("s_dhcp_start", null, $range[3])));
+    $dhcp_stop  = ip2long(trim(getPOST("s_dhcp_stop", null, $range[4])));
 
-        $new['dhcp_start'] = $dhcp_start;
-        $new['dhcp_stop']  = $dhcp_stop;
+    if (!validate_dhcp_range($dhcp_start, $dhcp_stop, $new['ip_int_start'], $new['ip_int_stop'])) {
+        // fallback пул
+        $dhcp_start = ip2long($range[3]);
+        $dhcp_stop  = ip2long($range[4]);
+    }
 
+    $new['dhcp_start'] = $dhcp_start;
+    $new['dhcp_stop']  = $dhcp_stop;
 
-        // === MODE DEPENDENCY RULES ================================================================================
+    // === MODE DEPENDENCY RULES =============================================================================
 
-        if ($new['hotspot']) {
-            $new['dhcp_update_hostname'] = 0;
-            $new['discovery'] = 0;
-            $new['vpn'] = 0;
+    if ($dhcp_start === $dhcp_stop ) {
+        $new['dhcp'] = 0;
         }
 
-        if ($new['vpn']) {
-            $new['discovery'] = 0;
-            $new['dhcp'] = 0;
-        }
+    if ($new['hotspot']) {
+        $new['dhcp_update_hostname'] = 0;
+        $new['discovery'] = 0;
+        $new['vpn'] = 0;
+    }
 
-        if ($new['office']) {
-            $new['free'] = 0;
-        }
+    if ($new['vpn']) {
+        $new['discovery'] = 0;
+        $new['dhcp'] = 0;
+    }
 
-        if (!$new['office']) {
-            $new['discovery'] = 0;
-            $new['dhcp'] = 0;
-            $new['static'] = 0;
-            $new['dhcp_update_hostname'] = 0;
-            $new['gateway'] = 0;
-            $new['dhcp_start'] = 0;
-            $new['dhcp_stop'] = 0;
-        }
+    if ($new['office']) {
+        $new['free'] = 0;
+    }
+
+    if (!$new['office']) {
+        $new['discovery'] = 0;
+        $new['dhcp'] = 0;
+        $new['static'] = 0;
+        $new['dhcp_update_hostname'] = 0;
+        $new['gateway'] = 0;
+        $new['dhcp_start'] = 0;
+        $new['dhcp_stop'] = 0;
+    }
 
-        update_record($db_link, "subnets", "id= ?", $new, [ $id ]);
-        header("Location: /admin/customers/index-subnets.php");
-        exit;
+    update_record($db_link, "subnets", "id = ?", $new, [$id]);
+
+    header("Location: /admin/customers/index-subnets.php");
+    exit;
 }
 
 unset($_POST);
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/header.php");
 print_control_submenu($page_url);
 
-$sSQL = "SELECT * FROM subnets WHERE id= ?";
-$subnet_info = get_record_sql($db_link, $sSQL, [ $id ]);
 ?>
 
 <div id="cont">

+ 50 - 25
html/admin/customers/index-subnets.php

@@ -3,42 +3,67 @@
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/auth.php");
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/languages/" . HTML_LANG . ".php");
 
-if (isset($_POST["s_remove"])) {
-    if (!empty($_POST["s_id"])) {
-        $s_id = $_POST["s_id"];
-        foreach ($s_id as $key => $net_id) {
-            if (isset($net_id)) {
-                LOG_INFO($db_link, "Remove subnet id: $net_id ". dump_record($db_link,'subnets','id=?', [$val]));
-                delete_record($db_link, "subnets", "id= ?", [ $net_id ]);
-                delete_record($db_link, "gateway_subnets", "subnet_id= ?" , [ $net_id ]);
-            }
+// Удаление подсетей
+if (getPOST("s_remove") !== null) {
+    $s_id = getPOST("s_id", null, []);
+    
+    if (!empty($s_id) && is_array($s_id)) {
+        foreach ($s_id as $net_id) {
+            $net_id = trim($net_id);
+            if ($net_id === '') continue;
+            
+            LOG_INFO($db_link, "Remove subnet id: $net_id " . dump_record($db_link, 'subnets', 'id = ?', [$net_id]));
+            delete_record($db_link, "subnets", "id = ?", [$net_id]);
+            delete_record($db_link, "gateway_subnets", "subnet_id = ?", [$net_id]);
         }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["s_create"])) {
-    $new_subnet = $_POST["s_create_subnet"];
-    if (isset($new_subnet)) {
-        $new['subnet'] = trim($new_subnet);
-        $range = cidrToRange($new['subnet']);
-        $first_user_ip = $range[0];
-        $last_user_ip = $range[1];
-        $cidr = $range[2][1];
-        if (isset($cidr) and $cidr < 32) {
-            $ip = $first_user_ip . '/' . $cidr;
+// Создание новой подсети
+if (getPOST("s_create") !== null) {
+    $new_subnet = trim(getPOST("s_create_subnet", null, ''));
+
+    if ($new_subnet !== '') {
+        $range = cidrToRange($new_subnet);
+        $first_user_ip = $range[0] ?? '';
+        $last_user_ip  = $range[1] ?? '';
+        $cidr          = $range[2] ?? null;
+        // Формируем корректный CIDR
+        if ($cidr !== null && $cidr < 32) {
+            $new_subnet = "$first_user_ip/$cidr";
         } else {
-            $ip = $first_user_ip;
+            $range = cidrToRange($first_user_ip.'/24');
+            $first_user_ip = $range[0] ?? '';
+            $last_user_ip  = $range[1] ?? '';
+            $cidr          = $range[2] ?? null;
+            if ($cidr !== null && $cidr < 32) {
+                $new_subnet = "$first_user_ip/$cidr";
+                } else {
+                //abort
+                header("Location: " . $_SERVER["REQUEST_URI"]);
+                exit;
+                }
         }
-        $new['ip_int_start'] = ip2long($first_user_ip);
-        $new['ip_int_stop'] = ip2long($last_user_ip);
-        $new['dhcp_start'] = ip2long($range[3]);
-        $new['dhcp_stop'] = ip2long($range[4]);
-        $new['gateway'] = ip2long($range[5]);
+
+        $start_ip = ip2long($first_user_ip);
+        $stop_ip = ip2long($last_user_ip);
+
+        $new = [
+            'subnet' => $new_subnet,
+            'ip_int_start' => $start_ip,
+            'ip_int_stop'  => $stop_ip,
+            'dhcp_start'   => ip2long($range[3] ?? $first_user_ip),
+            'dhcp_stop'    => ip2long($range[4] ?? $first_user_ip),
+            'gateway'      => ip2long($range[5] ?? $first_user_ip)
+        ];
+
         LOG_INFO($db_link, "Create new subnet $new_subnet");
         insert_record($db_link, "subnets", $new);
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }

+ 28 - 14
html/admin/customers/index.php

@@ -4,38 +4,52 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 
 $msg_error = "";
 
-if (isset($_POST["create"])) {
-    $login = $_POST["newlogin"];
-    if ($login) {
+// Создание нового пользователя
+if (getPOST("create") !== null) {
+    $login = trim(getPOST("newlogin", null, ''));
+    
+    if ($login !== '') {
         $customer = get_record_sql($db_link, "SELECT * FROM customers WHERE LOWER(login) = LOWER(?)", [$login]);
+        
         if (!empty($customer)) {
             $msg_error = "Login $login already exists!";
             LOG_ERROR($db_link, $msg_error);
-            unset($_POST);
         } else {
-            $new['login'] = $login;
-	    $new['api_key'] = randomPassword(20);
-            $new['rights'] = 3;
+            $new = [
+                'login'    => $login,
+                'api_key'  => randomPassword(20),
+                'rights'   => 3
+            ];
             LOG_INFO($db_link, "Create new login: $login");
             $id = insert_record($db_link, "customers", $new);
-	    if (!empty($id)) { header("Location: editcustom.php?id=$id"); exit; }
+            if (!empty($id)) {
+                header("Location: editcustom.php?id=$id");
+                exit;
+            }
         }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["remove"])) {
-    $fid = $_POST["fid"];
-    foreach ($fid as $key => $val) {
-        if ($val) {
-            LOG_INFO($db_link, "Remove login with id: $val ". dump_record($db_link,'customers','id=?', [ $val]));
-            delete_record($db_link, "customers", "id=?", [ $val ]);
+// Удаление пользователей
+if (getPOST("remove") !== null) {
+    $fid = getPOST("fid", null, []);
+    
+    if (!empty($fid) && is_array($fid)) {
+        foreach ($fid as $val) {
+            $val = trim($val);
+            if ($val === '' or $val == '1') continue;
+            LOG_INFO($db_link, "Remove login with id: $val " . dump_record($db_link, 'customers', 'id = ?', [$val]));
+            delete_record($db_link, "customers", "id = ?", [$val]);
         }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
+
 unset($_POST);
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");
 

+ 24 - 10
html/admin/customers/ipcam.php

@@ -6,22 +6,36 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 
 $f_ou_id = IPCAM_GROUP_ID;
 
-if (isset($_POST['port_on'])) {
-    $len = is_array($_POST['port_on']) ? count($_POST['port_on']) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $building_id = intval($_POST['port_on'][$i]);
-        set_port_for_group($db_link, $f_ou_id, $building_id, 1);
+// Включение портов
+if (getPOST("port_on") !== null) {
+    $port_on = getPOST("port_on", null, []);
+    
+    if (is_array($port_on)) {
+        foreach ($port_on as $building_id) {
+            $building_id = (int)$building_id;
+            if ($building_id > 0) {
+                set_port_for_group($db_link, $f_ou_id, $building_id, 1);
+            }
+        }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST['port_off'])) {
-    $len = is_array($_POST['port_off']) ? count($_POST['port_off']) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $building_id = intval($_POST['port_off'][$i]);
-        set_port_for_group($db_link, $f_ou_id, $building_id, 0);
+// Отключение портов
+if (getPOST("port_off") !== null) {
+    $port_off = getPOST("port_off", null, []);
+    
+    if (is_array($port_off)) {
+        foreach ($port_off as $building_id) {
+            $building_id = (int)$building_id;
+            if ($building_id > 0) {
+                set_port_for_group($db_link, $f_ou_id, $building_id, 0);
+            }
+        }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }

+ 25 - 13
html/admin/devices/edit_gw_instances.php

@@ -4,28 +4,40 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/idfilter.php");
 
-$device=get_record($db_link,'devices',"id=?", [$id]);
-$user_info = get_record_sql($db_link,"SELECT * FROM user_list WHERE id=?", [$device['user_id']]);
+$device = get_record($db_link, 'devices', "id = ?", [$id]);
+$user_info = get_record_sql($db_link, "SELECT * FROM user_list WHERE id = ?", [$device['user_id']]);
 
-if (isset($_POST["s_remove"])) {
-    $s_id = $_POST["gs_id"];
-    foreach ($s_id as $key => $val) {
-        if (isset($val)) {
-            LOG_INFO($db_link, "Remove filter instances from gateway id: $val ". dump_record($db_link,'device_filter_instances','id=?',[$val]));
-            delete_record($db_link, "device_filter_instances", "id=?", [$val]);
+// Удаление фильтров
+if (getPOST("s_remove") !== null) {
+    $s_id = getPOST("gs_id", null, []);
+    
+    if (!empty($s_id) && is_array($s_id)) {
+        foreach ($s_id as $val) {
+            $val = trim($val);
+            if ($val === '') continue;
+            LOG_INFO($db_link, "Remove filter instances from gateway id: $val " . dump_record($db_link, 'device_filter_instances', 'id = ?', [$val]));
+            delete_record($db_link, "device_filter_instances", "id = ?", [$val]);
         }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["s_create"])) {
-    if (!empty($_POST["new_instance"])) {
-        $new['instance_id'] = trim($_POST["new_instance"]);
-        $new['device_id'] = $id;
-        LOG_INFO($db_link, "Add instance id: ".$new['instance_id']." for gateway id: ".$id);
+// Создание нового фильтра
+if (getPOST("s_create") !== null) {
+    $new_instance = trim(getPOST("new_instance", null, ''));
+    
+    if ($new_instance !== '') {
+        $new = [
+            'instance_id' => $new_instance,
+            'device_id'   => $id
+        ];
+        
+        LOG_INFO($db_link, "Add instance id: " . $new['instance_id'] . " for gateway id: " . $id);
         insert_record($db_link, "device_filter_instances", $new);
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }

+ 1 - 1
html/admin/devices/edit_l3int.php

@@ -77,7 +77,7 @@ print_editdevice_submenu($page_url,$id,$device['device_type'],$user_info['login'
 $t_l3_interface = get_records_sql($db_link,"SELECT * FROM device_l3_interfaces WHERE device_id=? ORDER BY name", [ $id ]);
 
 $int_by_name = [];
-foreach ($int_list as $row) { 
+foreach ($int_list as $row) {
     $row['name'] = preg_replace('/\"/','',$row['name']);
     $int_by_name[$row['name']]=$row;
 }

+ 14 - 10
html/admin/filters/editfilter.php

@@ -3,15 +3,20 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/idfilter.php");
 
-if (isset($_POST["editfilter"])) {
-    $new['name'] = $_POST["f_name"];
-    $new['dst'] = $_POST["f_dst"];
-    $new['proto'] = $_POST["f_proto"];
-    $new['dstport'] = str_replace(':', '-', $_POST["f_dstport"]);
-    $new['srcport'] = str_replace(':', '-', $_POST["f_srcport"]);
-    $new['description'] = $_POST["f_description"];
-    update_record($db_link, "filter_list", "id=?", $new, [ $id ]);
-    unset($_POST);
+$filter = get_record($db_link, 'filter_list','id=?', [ $id ]);
+
+if (getPOST("editfilter") !== null) {
+    $new = [
+        'name'        => trim(getPOST("f_name", null, $filter['name'])),
+        'dst'         => trim(getPOST("f_dst", null, '')),
+        'proto'       => trim(getPOST("f_proto", null, '')),
+        'dstport'     => str_replace(':', '-', trim(getPOST("f_dstport", null, ''))),
+        'srcport'     => str_replace(':', '-', trim(getPOST("f_srcport", null, ''))),
+        'description' => trim(getPOST("f_description", null, ''))
+    ];
+
+    update_record($db_link, "filter_list", "id = ?", $new, [$id]);
+
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
@@ -20,7 +25,6 @@ unset($_POST);
 
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");
 
-$filter = get_record($db_link, 'filter_list','id=?', [ $id ]);
 
 print_filters_submenu($page_url);
 

+ 63 - 41
html/admin/filters/editgroup.php

@@ -3,71 +3,93 @@ require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/auth.php");
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/languages/" . HTML_LANG . ".php");
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/idfilter.php");
 
-if (isset($_POST["editgroup"])) {
-    $new['group_name'] = $_POST["f_group_name"];
-    $new['instance_id'] = $_POST["f_instance_id"]*1;
-    $new['description'] = $_POST["f_group_description"];
-    update_record($db_link, "group_list", "id=?", $new, [ $id ]);
+$group = get_record_sql($db_link, "SELECT * FROM group_list WHERE id=?", [ $id ]);
+
+// Редактирование группы
+if (getPOST("editgroup") !== null) {
+    $new = [
+        'group_name'    => trim(getPOST("f_group_name", null, $group['group_name'])),
+        'instance_id'   => (int)getPOST("f_instance_id", null, 1),
+        'description'   => trim(getPOST("f_group_description", null, ''))
+    ];
+    update_record($db_link, "group_list", "id = ?", $new, [$id]);
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["addfilter"])) {
-    $filter_id = $_POST["newfilter"] * 1;
-    $max_record = get_record_sql($db_link, "SELECT MAX(G.rule_order) as morder FROM group_filters as G where G.group_id=?", [ $id ]);
-    if (empty($max_record)) {
-        $forder = 1;
-    } else {
-        $forder = $max_record["morder"] * 1 + 1;
+// Добавление фильтра в группу
+if (getPOST("addfilter") !== null) {
+    $filter_id = (int)getPOST("newfilter", null, 0);
+    
+    if ($filter_id > 0) {
+        $max_record = get_record_sql($db_link, "SELECT MAX(G.rule_order) as morder FROM group_filters AS G WHERE G.group_id = ?", [$id]);
+        $forder = (!empty($max_record) && isset($max_record['morder'])) 
+            ? ((int)$max_record['morder'] + 1) 
+            : 1;
+
+        $new = [
+            'group_id'     => $id,
+            'filter_id'    => $filter_id,
+            'rule_order'   => $forder,
+            'action'       => 1
+        ];
+        insert_record($db_link, "group_filters", $new);
     }
-    $new['group_id'] = $id;
-    $new['filter_id'] = $filter_id;
-    $new['rule_order'] = $forder;
-    $new['action'] = 1;
-    insert_record($db_link, "group_filters", $new);
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["removefilter"])) {
-    $f_group_filter = $_POST["f_group_filter"];
-    foreach ($f_group_filter as $key => $val) {
-        if (!empty($val)) {
-            delete_record($db_link, "group_filters", "id=? ", [ $val ]);
+// Удаление фильтров из группы
+if (getPOST("removefilter") !== null) {
+    $f_group_filter = getPOST("f_group_filter", null, []);
+    
+    if (!empty($f_group_filter) && is_array($f_group_filter)) {
+        foreach ($f_group_filter as $val) {
+            $val = trim($val);
+            if ($val !== '') {
+                delete_record($db_link, "group_filters", "id = ?", [(int)$val]);
+            }
         }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["updateFilters"])) {
-    if (!empty($_POST["f_group_filter"])) {
-        $f_group_filter = $_POST["f_group_filter"];
+// Обновление порядка и действий фильтров
+if (getPOST("updateFilters") !== null) {
+    $f_group_filter = getPOST("f_group_filter", null, []);
+    
+    if (!empty($f_group_filter) && is_array($f_group_filter)) {
+        $f_ord    = getPOST("f_ord",    null, []);
+        $f_action = getPOST("f_action", null, []);
+        
         LOG_DEBUG($db_link, "Update filters for group id: " . $id);
-        for ($i = 0; $i < count($f_group_filter); ++$i) {
-            $group_filter_id = $f_group_filter[$i];
-            if (empty($_POST["f_ord"][$group_filter_id])) {
-                $new['rule_order'] = $i;
-            } else {
-                $new['rule_order'] = $_POST["f_ord"][$group_filter_id] * 1;
-            }
-            if (empty($_POST["f_action"][$group_filter_id])) {
-                $new['action'] = 0;
-            } else {
-                $new['action'] = $_POST["f_action"][$group_filter_id] * 1;
-            }
-            if (!empty($new)) {
-                update_record($db_link, "group_filters", "id=?", $new, [ $group_filter_id ]);
-            }
+        
+        foreach ($f_group_filter as $i => $group_filter_id) {
+            $group_filter_id = (int)$group_filter_id;
+            if ($group_filter_id <= 0) continue;
+            
+            $new = [
+                'rule_order' => isset($f_ord[$group_filter_id]) 
+                    ? (int)$f_ord[$group_filter_id] 
+                    : $i,
+                'action'     => isset($f_action[$group_filter_id]) 
+                    ? (int)$f_action[$group_filter_id] 
+                    : 0
+            ];
+            
+            update_record($db_link, "group_filters", "id = ?", $new, [$group_filter_id]);
         }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
 unset($_POST);
 
-$group = get_record_sql($db_link, "SELECT * FROM group_list WHERE id=?", [ $id ]);
 
 print_filters_submenu($page_url);
 

+ 33 - 14
html/admin/filters/groups.php

@@ -2,27 +2,46 @@
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/auth.php");
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/languages/" . HTML_LANG . ".php");
 
-if (isset($_POST["create"])) {
-    $fname = $_POST["newgroup"];
-    if ($fname) {
-        $new['group_name'] = $fname;
-        $new_id = insert_record($db_link, "group_list", $new);
-        header("location: editgroup.php?id=$new_id");
-        exit;
+// Создание новой группы
+if (getPOST("create") !== null) {
+    $fname = trim(getPOST("newgroup", null, ''));
+    
+    if ($fname !== '') {
+        $new_id = insert_record($db_link, "group_list", ['group_name' => $fname]);
+        if ($new_id) {
+            header("Location: editgroup.php?id=$new_id");
+            exit;
+        }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["remove"])) {
-    $fgid = $_POST["fid"];
-    foreach ($fgid as $key => $val) {
-        if (!empty($val)) {
-            run_sql($db_link, "UPDATE user_auth SET filter_group_id=0, changed = 1 WHERE deleted=0 AND filter_group_id=?", [ $val ]);
-            run_sql($db_link, "DELETE FROM group_filters WHERE group_id=? ", [ $val ]);
-            delete_record($db_link, "group_list", "id=?", [ $val ]);
+// Удаление групп
+if (getPOST("remove") !== null) {
+    $fgid = getPOST("fid", null, []);
+    
+    if (!empty($fgid) && is_array($fgid)) {
+        foreach ($fgid as $val) {
+            $val = trim($val);
+            if ($val === '') continue;
+            
+            // Сброс привязки в user_auth
+            update_records($db_link, "user_auth", 
+                "deleted = 0 AND filter_group_id = ?", 
+                ['filter_group_id' => 0, 'changed' => 1], 
+                [$val]
+            );
+            
+            // Удаление связей
+            delete_records($db_link, "group_filters", "group_id = ?", [$val]);
+            
+            // Удаление самой группы
+            delete_records($db_link, "group_list", "id = ?", [$val]);
         }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }

+ 34 - 18
html/admin/filters/index.php

@@ -2,32 +2,48 @@
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/auth.php");
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/languages/" . HTML_LANG . ".php");
 
-if (isset($_POST["create"])) {
-    $fname = $_POST["newfilter"];
-    $ftype = 0;
-    if (isset($_POST['filter_type'])) {
-        $ftype = $_POST["filter_type"] * 1;
-    }
-    if (isset($fname)) {
-        $new['name'] = $fname;
-        $new['filter_type'] = $ftype;
-        $new_id = insert_record($db_link, "filter_list", $new);
-        header("Location: editfilter.php?id=$new_id");
-        exit;
+// Создание нового фильтра
+if (getPOST("create") !== null) {
+    $fname = trim(getPOST("newfilter", null, ''));
+    $ftype = (int)getPOST("filter_type", null, 0);
+    
+    if ($fname !== '') {
+        $new_id = insert_record($db_link, "filter_list", [
+            'name'         => $fname,
+            'filter_type'  => $ftype
+        ]);
+        
+        if ($new_id) {
+            header("Location: editfilter.php?id=$new_id");
+            exit;
+        }
     }
+    
+    header("Location: " . $_SERVER["REQUEST_URI"]);
+    exit;
 }
 
-if (isset($_POST["remove"])) {
-    $fid = $_POST["fid"];
-    foreach ($fid as $key => $val) {
-        if ($val) {
-            run_sql($db_link, "DELETE FROM group_filters WHERE filter_id=?", [ $val ]);
-            delete_record($db_link, "filter_list", "id=?", [ $val ]);
+// Удаление фильтров
+if (getPOST("remove") !== null) {
+    $fid = getPOST("fid", null, []);
+    
+    if (!empty($fid) && is_array($fid)) {
+        foreach ($fid as $val) {
+            $val = trim($val);
+            if ($val === '') continue;
+            
+            // Удаляем из связей
+            delete_records($db_link, "group_filters", "filter_id = ?", [(int)$val]);
+            
+            // Удаляем сам фильтр
+            delete_record($db_link, "filter_list", "id = ?", [(int)$val]);
         }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
+
 unset($_POST);
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/header.php");
 print_filters_submenu($page_url);

+ 66 - 27
html/admin/filters/instances.php

@@ -2,46 +2,85 @@
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 
-if (isset($_POST['save'])) {
-    $len = is_array($_POST['f_id']) ? count($_POST['f_id']) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $save_id = intval($_POST['f_id'][$i]);
-        $len_all = is_array($_POST['r_id']) ? count($_POST['r_id']) : 0;
-        for ($j = 0; $j < $len_all; $j ++) {
-            if (intval($_POST['r_id'][$j]) != $save_id) { continue; }
-            $id = intval($_POST['r_id'][$j]);
-            $new['name'] = trim($_POST['f_name'][$j]);
-            $new['description'] = trim($_POST['f_description'][$j]);
-            update_record($db_link, "filter_instances", "id=?", $new, [ $id ]);
+// Сохранение изменений
+if (getPOST("save") !== null) {
+    $f_ids = getPOST("f_id", null, []);
+    $r_ids = getPOST("r_id", null, []);
+    $f_names = getPOST("f_name", null, []);
+    $f_descriptions = getPOST("f_description", null, []);
+    if (is_array($f_ids) && is_array($r_ids)) {
+        foreach ($f_ids as $save_id) {
+            $save_id = (int)$save_id;
+            if ($save_id <= 0) continue;
+
+            $idx = array_search($save_id, $r_ids, true);
+            if ($idx === false) continue;
+
+            $new = [
+                'name'        => trim($f_names[$idx] ?? ''),
+                'description' => trim($f_descriptions[$idx] ?? '')
+            ];
+
+            update_record($db_link, "filter_instances", "id = ?", $new, [$save_id]);
         }
     }
+
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["create"])) {
-    $instance_name = trim($_POST["new_instance"]);
-    if (!empty($instance_name)) {
-        $instance['name'] = $instance_name;
-        insert_record($db_link, "filter_instances", $instance);
+// Создание нового экземпляра
+if (getPOST("create") !== null) {
+    $instance_name = trim(getPOST("new_instance", null, ''));
+    
+    if ($instance_name !== '') {
+        insert_record($db_link, "filter_instances", ['name' => $instance_name]);
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["remove"])) {
-    $len = is_array($_POST['r_id']) ? count($_POST['r_id']) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $id = intval($_POST['r_id'][$i]);
-        if (!empty($id) and $id>1) {
-	    $deleted_groups = get_records_sql($db_link,"SELECT * FROM group_list WHERE instance_id>1 AND instance_id=?", [ $id ]);
-	    foreach ($deleted_groups as $d_group) {
-	        run_sql($db_link, "UPDATE user_auth SET filter_group_id=0, changed = 1 WHERE deleted=0 AND filter_group_id=?", [ $d_group['id'] ]);
-		delete_record($db_link, "group_list", "id=?", [ $d_group['id'] ]);
-		}
-            delete_record($db_link, "filter_instances", "id=?", [$id ]);
+// Удаление экземпляров
+if (getPOST("remove") !== null) {
+    $r_ids = getPOST("r_id", null, []);
+    
+    if (is_array($r_ids)) {
+        foreach ($r_ids as $id) {
+            $id = (int)$id;
+            if ($id <= 1) continue; // защищаем ID <= 1
+            
+            // Находим все группы, использующие этот instance_id
+            $deleted_groups = get_records_sql($db_link, 
+                "SELECT id FROM group_list WHERE instance_id > 1 AND instance_id = ?", 
+                [$id]
+            );
+            
+            if (!empty($deleted_groups)) {
+                foreach ($deleted_groups as $d_group) {
+                    $group_id = (int)($d_group['id'] ?? 0);
+                    if ($group_id <= 0) continue;
+                    
+                    // Сбрасываем привязку в user_auth
+                    update_records($db_link, "user_auth", 
+                        "deleted = 0 AND filter_group_id = ?", 
+                        ['filter_group_id' => 0, 'changed' => 1], 
+                        [$group_id]
+                    );
+
+                    // Удаление связей
+                    delete_records($db_link, "group_filters", "group_id = ?", [$group_id]);
+
+                    // Удаляем группу
+                    delete_record($db_link, "group_list", "id = ?", [$group_id]);
+                }
+            }
+            
+            // Удаляем сам экземпляр
+            delete_record($db_link, "filter_instances", "id = ?", [$id]);
         }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }

+ 117 - 50
html/admin/groups/edit_group.php

@@ -3,64 +3,132 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 require_once ($_SERVER["DOCUMENT_ROOT"]."/inc/idfilter.php");
 
-if (isset($_POST['save'])) {
-        $new['ou_name'] = $_POST['f_group_name'];
-        $new['default_users'] = $_POST['f_default']*1;
-        $new['default_hotspot'] = $_POST['f_default_hotspot']*1;
-        $new['nagios_dir'] = $_POST['f_nagios'];
-        $new['nagios_host_use'] = $_POST['f_nagios_host'];
-        $new['nagios_ping'] = $_POST['f_nagios_ping'];
-        $new['nagios_default_service'] = $_POST['f_nagios_service'];
-        $new['queue_id']= $_POST['f_queue_id']*1;
-        $new['filter_group_id']= $_POST['f_filter_group_id']*1;
-        $new['enabled']= $_POST['f_enabled']*1;
-        $new['dynamic']= $_POST['f_dynamic']*1;
-        if ($new['dynamic']) {
-            $tmp_life_duration = str_replace(',', '.',$_POST['f_life_duration']*1);
-            if (!empty($tmp_life_duration) and is_numeric($tmp_life_duration)) { $new['life_duration'] = $tmp_life_duration; }
-            } else { $new['life_duration']=0; }
-        if ($new['default_users'] == TRUE) { run_sql($db_link,"UPDATE ou set default_users=0 WHERE id!=?", [ $id ]); }
-        if ($new['default_hotspot'] == TRUE) { run_sql($db_link,"UPDATE ou set default_hotspot=0 WHERE id!=?", [ $id ]); }
-        update_record($db_link, "ou", "id=?", $new, [ $id ]);
-        header("Location: " . $_SERVER["REQUEST_URI"]);
-	exit;
-	}
+$ou_info = get_record_sql($db_link,'SELECT * FROM ou WHERE id=?', [$id]);
 
-if (isset($_POST["s_remove"])) {
-    $s_id = $_POST["s_id"];
-    foreach ($s_id as $key => $val) {
-        if (isset($val)) {
-            LOG_INFO($db_link, "Remove rule id: $val ".dump_record($db_link,'auth_rules','id=?', [$val]));
-            delete_record($db_link, "auth_rules", "id=?", [ $val ]);
-        }
+// Сохранение настроек OU
+if (getPOST("save") !== null) {
+    $new = [
+        'ou_name'                => trim(getPOST("f_group_name", null, $ou_info['ou_name'])),
+        'default_users'          => (int)getPOST("f_default", null, 0),
+        'default_hotspot'        => (int)getPOST("f_default_hotspot", null, 0),
+        'nagios_dir'             => trim(getPOST("f_nagios", null, '')),
+        'nagios_host_use'        => trim(getPOST("f_nagios_host", null, '')),
+        'nagios_ping'            => trim(getPOST("f_nagios_ping", null, 0)),
+        'nagios_default_service' => trim(getPOST("f_nagios_service", null, '')),
+        'queue_id'               => (int)getPOST("f_queue_id", null, 0),
+        'filter_group_id'        => (int)getPOST("f_filter_group_id", null, 0),
+        'enabled'                => (int)getPOST("f_enabled", null, 0),
+        'dynamic'                => (int)getPOST("f_dynamic", null, 0)
+    ];
+
+    // Обработка life_duration
+    if ($new['dynamic']) {
+        $tmp_life_duration = str_replace(',', '.', getPOST("f_life_duration", null, 0));
+        $new['life_duration'] = (!empty($tmp_life_duration) && is_numeric($tmp_life_duration)) 
+            ? (float)$tmp_life_duration 
+            : 0;
+    } else {
+        $new['life_duration'] = 0;
+    }
+
+    // Сброс флагов по умолчанию
+    if ($new['default_users']) {
+        update_records($db_link, "ou", "id != ?", ['default_users' => 0], [$id]);
+    }
+    if ($new['default_hotspot']) {
+        update_records($db_link, "ou", "id != ?", ['default_hotspot' => 0], [$id]);
     }
+
+    update_record($db_link, "ou", "id = ?", $new, [$id]);
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST['s_save'])) {
-    $len = is_array($_POST['s_id']) ? count($_POST['s_id']) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $save_id = intval($_POST['s_id'][$i]);
-        $len_all = is_array($_POST['n_id']) ? count($_POST['n_id']) : 0;
-        for ($j = 0; $j < $len_all; $j ++) {
-            if (intval($_POST['n_id'][$j]) != $save_id) { continue; }
-            $new['type'] = $_POST['s_type'][$j];
-            $new['rule'] = trim($_POST['s_rule'][$j]);
-            $new['description'] = trim($_POST['s_description'][$j]);
-            update_record($db_link, "auth_rules", "id=?", $new, [ $save_id ]);
+// Удаление правил авторизации
+if (getPOST("s_remove") !== null) {
+    $s_id = getPOST("s_id", null, []);
+    
+    if (!empty($s_id) && is_array($s_id)) {
+        foreach ($s_id as $val) {
+            $val = trim($val);
+            if ($val === '') continue;
+            
+            LOG_INFO($db_link, "Remove rule id: $val " . dump_record($db_link, 'auth_rules', 'id = ?', [$val]));
+            delete_record($db_link, "auth_rules", "id = ?", [(int)$val]);
         }
     }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["s_create"])) {
-    $new_rule = $_POST["s_new_rule"];
-    if (!empty($new_rule)) {
-        $new['type'] = $_POST["s_new_type"];
-        $new['rule'] = $new_rule;
-        $new['ou_id'] = $id;
+// Сохранение изменений в правилах
+if (getPOST("s_save") !== null) {
+    $s_ids = getPOST("s_id", null, []);
+    $n_ids = getPOST("n_id", null, []);
+    $s_types = getPOST("s_type", null, []);
+    $s_rules = getPOST("s_rule", null, []);
+    $s_descriptions = getPOST("s_description", null, []);
+
+    if (is_array($s_ids) && is_array($n_ids)) {
+        // Преобразуем ID в целые числа
+        $n_ids = array_map('intval', $n_ids);
+        $s_ids = array_map('intval', $s_ids);
+        foreach ($s_ids as $save_id) {
+            if ($save_id <= 0) continue;
+            $idx = array_search($save_id, $n_ids, true);
+            if ($idx === false) continue;
+            // Получаем тип правила
+            $rule_type = (int)($s_types[$idx] ?? 3);
+            // Получаем и очищаем правило
+            $raw_rule = trim($s_rules[$idx] ?? '');
+            if ($raw_rule === '') continue;
+            $new_rule = $raw_rule;
+            // Валидация в зависимости от типа
+            if ($rule_type == 1) {
+                // IP-адрес
+                if (!checkValidIp($new_rule)) {
+                    continue; // пропускаем невалидный IP
+                }
+            } elseif ($rule_type == 2) {
+                // MAC-адрес
+                $normalized_mac = MayBeMac($new_rule);
+                if ($normalized_mac === null) {
+                    continue; // пропускаем невалидный MAC
+                }
+                $new_rule = $normalized_mac;
+            }
+            // Для других типов (3 и т.д.) — без валидации
+            $new = [
+                'rule_type'   => $rule_type,
+                'rule'        => $new_rule,
+                'description' => trim($s_descriptions[$idx] ?? '')
+            ];
+            update_record($db_link, "auth_rules", "id = ?", $new, [$save_id]);
+        }
+    }
+    header("Location: " . $_SERVER["REQUEST_URI"]);
+    exit;
+}
+// Создание нового правила
+if (getPOST("s_create") !== null) {
+    $new_rule = trim(getPOST("s_new_rule", null, ''));
+    if ($new_rule !== '') {
+        $rule_type  = (int)getPOST("s_new_type", null, 3);
+        if ($rule_type == 1 and !checkValidIp($new_rule)) {
+                header("Location: " . $_SERVER["REQUEST_URI"]);
+                exit;
+                }
+        if ($rule_type == 2 and MayBeMac($new_rule)==null) {
+                header("Location: " . $_SERVER["REQUEST_URI"]);
+                exit;
+                }
+        if ($rule_type == 2) { $new_rule = MayBeMac($new_rule); }
+        $new = [
+            'rule_type'    => $rule_type,
+            'rule'    => $new_rule,
+            'ou_id'   => $id
+        ];
         LOG_INFO($db_link, "Create new rule $new_rule for ou_id: $id");
         insert_record($db_link, "auth_rules", $new);
     }
@@ -84,7 +152,7 @@ fix_auth_rules($db_link);
 <td><b><?php print WEB_cell_dynamic; ?></b></td>
 </tr>
 <?php
-$ou_info = get_record_sql($db_link,'SELECT * FROM ou WHERE id=?', [$id]);
+
 print "<tr align=center>\n";
 print "<td colspan=2 class=\"data\"><input type=\"text\" name='f_group_name' value='{$ou_info['ou_name']}' style=\"width:95%;\"></td>\n";
 if ($ou_info['default_users']) { $cl = "up"; } else { $cl="data"; }
@@ -132,7 +200,7 @@ if (!$ou_info['dynamic']) { print "disabled"; }; print " style=\"width:35%;\" ><
     <td><b><?php echo WEB_ou_rule; ?></b></td>
     <td><b><?php echo WEB_cell_description; ?></b></td>
     <td><input type="submit" onclick="return confirm('<?php echo WEB_msg_delete; ?>?')" name="s_remove" value="<?php echo WEB_btn_delete; ?>"></td>
-    <?php print "<td><button id='s_save' name='s_save'>".WEB_btn_save."</button></td>"; ?>
+    <?php print "<td><button id='s_save' name='s_save' value='s_save'>".WEB_btn_save."</button></td>"; ?>
 </tr>
 <?php
 $t_auth_rules = get_records_sql($db_link,"SELECT * FROM auth_rules WHERE ou_id=? ORDER BY id", [ $id ]);
@@ -140,7 +208,7 @@ foreach ( $t_auth_rules as $row ) {
     print "<tr align=center>\n";
     print "<td class=\"data\" style='padding:0'><input type=checkbox name=s_id[] value='{$row['id']}'></td>\n";
     print "<td class=\"data\"><input type=\"hidden\" name='n_id[]' value='{$row['id']}'>{$row['id']}</td>\n";
-    print "<td class=\"data\">"; print_qa_rule_select("s_type[]","{$row['type']}"); print "</td>\n";
+    print "<td class=\"data\">"; print_qa_rule_select("s_type[]","{$row['rule_type']}"); print "</td>\n";
     print "<td class=\"data\"><input type=\"text\" name='s_rule[]' value='{$row['rule']}'></td>\n";
     print "<td class=\"data\"><input type=\"text\" name='s_description[]' value='{$row['description']}'></td>\n";
     print "<td colspan=2 class=\"data\"></td>\n";
@@ -172,4 +240,3 @@ document.getElementById('f_dynamic').addEventListener('change', function(event)
 <?php
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/footer.simple.php");
 ?>
-

+ 25 - 17
html/admin/groups/index.php

@@ -2,29 +2,37 @@
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 
-if (isset($_POST["remove"])) {
-    $fid = $_POST["f_id"];
-    foreach ($fid as $key => $val) {
-        if (isset($val) and $val > 0) {
-            run_sql($db_link, "UPDATE user_list SET ou_id=0 WHERE ou_id=?", [ $val ]);
-            run_sql($db_link, "UPDATE user_auth SET ou_id=0 WHERE ou_id=?", [ $val ]);
-            run_sql($db_link, "DELETE FROM auth_rules WHERE ou_id=?", [ $val ]);
-            delete_record($db_link, "ou", "id=?", [$val]);
-            }
+// Удаление OU
+if (getPOST("remove") !== null) {
+    $fid = getPOST("f_id", null, []);
+    
+    if (!empty($fid) && is_array($fid)) {
+        foreach ($fid as $val) {
+            $val = (int)$val;
+            if ($val <= 0) continue;
+            // Обнуляем привязки в user_list
+            update_records($db_link, "user_list", "ou_id = ?", ['ou_id' => 0], [$val]);
+            // Обнуляем привязки в user_auth
+            update_records($db_link, "user_auth", "ou_id = ?", ['ou_id' => 0], [$val]);
+            // Удаляем правила авторизации
+            delete_records($db_link, "auth_rules", "ou_id = ?", [$val]);
+            // Удаляем сам OU
+            delete_record($db_link, "ou", "id = ?", [$val]);
         }
+    }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
-    }
+}
 
-if (isset($_POST["create"])) {
-    $ou_name = $_POST["new_ou"];
-    if (isset($ou_name)) {
-        $new['ou_name'] = $ou_name;
-        insert_record($db_link, "ou", $new);
-        }
+// Создание нового OU
+if (getPOST("create") !== null) {
+    $ou_name = trim(getPOST("new_ou", null, ''));
+    if ($ou_name !== '') {
+        insert_record($db_link, "ou", ['ou_name' => $ou_name]);
+    }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
-    }
+}
 
 unset($_POST);
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");

+ 11 - 5
html/admin/iplist/auto_rules.php

@@ -5,14 +5,20 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/rulesfilter.php");
 
-if (isset($_POST["removeRule"])) {
-    $r_id = $_POST["f_id"];
-    foreach ($r_id as $key => $val) {
-        if ($val) { delete_record($db_link, "auth_rules", "id=?", [$val]); }
+if (getPOST("removeRule") !== null) {
+    $r_id = getPOST("f_id", null, []);
+    if (!empty($r_id) && is_array($r_id)) {
+        foreach ($r_id as $val) {
+            $val = trim($val);
+            if ($val !== '') {
+                delete_record($db_link, "auth_rules", "id = ?", [(int)$val]);
+            }
         }
+    }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
-    }
+}
 
 print_ip_submenu($page_url);
 ?>

+ 26 - 21
html/admin/iplist/deleted.php

@@ -10,37 +10,42 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/sortfilter.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/gatefilter.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/enabledfilter.php");
 
-if (isset($_POST['searchDescription'])) { $f_description = $_POST['searchDescription']; }
-if (isset($_GET['searchDescription'])) { $f_description = $_GET['searchDescription']; }
-if (!isset($f_description) and isset($_SESSION[$page_url]['description'])) { $f_description=$_SESSION[$page_url]['description']; }
-if (!isset($f_description)) { $f_description=''; }
+// Получаем параметр с использованием сессии (page_url задан)
+$f_description = getParam('searchDescription', $page_url, '');
 
-$_SESSION[$page_url]['description']=$f_description;
+// Сохраняем в сессию
+$_SESSION[$page_url]['description'] = $f_description;
 
 $sort_table = 'user_auth';
 $sort_url = "<a href=deleted.php?";
 
-$params=[];
-if ($rsubnet == 0) { $subnet_filter = ''; } else {
-    $subnet_range = get_subnet_range($db_link,$rsubnet);
-    $subnet_filter = " and user_auth.ip_int>=? and user_auth.ip_int<=?";
-    $params[]=$subnet_range['start'];
-    $params[]=$subnet_range['stop'];
-    }
+$params = [];
+if ($rsubnet == 0) {
+    $subnet_filter = '';
+} else {
+    $subnet_range = get_subnet_range($db_link, $rsubnet);
+    $subnet_filter = " AND user_auth.ip_int >= ? AND user_auth.ip_int <= ?";
+    $params[] = $subnet_range['start'];
+    $params[] = $subnet_range['stop'];
+}
 
 $ip_list_filter = $subnet_filter;
-
 $ip_where = '';
+
 if (!empty($f_description)) {
-    if (checkValidIp($f_description)) { $ip_where = " and ip=?"; $params[]=$f_description; }
-    if (checkValidMac($f_description)) { $ip_where = " and mac=?"; $params[]= mac_dotted($f_description); }
-    if (empty($ip_where)) { 
-	$ip_where=" and (user_auth.description LIKE ? OR user_auth.dhcp_hostname LIKE ?)"; 
-	$params[]=$f_description;
-	$params[]=$f_description;
-	}
+    if (checkValidIp($f_description)) {
+        $ip_where = " AND ip = ?";
+        $params[] = $f_description;
+    } elseif (checkValidMac($f_description)) {
+        $ip_where = " AND mac = ?";
+        $params[] = mac_dotted($f_description);
+    } else {
+        $ip_where = " AND (user_auth.description LIKE ? OR user_auth.dhcp_hostname LIKE ?)";
+        $params[] = "%$f_description%";
+        $params[] = "%$f_description%";
+    }
     $ip_list_filter = $ip_where;
-    } 
+    }
 
 print_ip_submenu($page_url);
 

+ 26 - 13
html/admin/iplist/doubles.php

@@ -4,25 +4,38 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/cidrfilter.php");
 
-if (isset($_POST["removeauth"])) {
-    $auth_id = $_POST["f_auth_id"];
-    foreach ($auth_id as $key => $val) {
-        if ($val) { delete_user_auth($db_link,$val); }
+// Удаление записей авторизации
+if (getPOST("removeauth") !== null) {
+    $auth_id = getPOST("f_auth_id", null, []);
+    if (!empty($auth_id) && is_array($auth_id)) {
+        foreach ($auth_id as $val) {
+            $val = trim($val);
+            if ($val !== '') {
+                delete_user_auth($db_link, (int)$val);
+            }
         }
+    }
+    
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
-    }
+}
 
-print_ip_submenu($page_url);
-$params=[];
-if (empty($rcidr)) { $cidr_filter = ''; } else {
+// Фильтрация по CIDR
+$params = [];
+if (!empty($rcidr)) {
     $cidr_range = cidrToRange($rcidr);
-    if (!empty($cidr_range)) { 
-	$cidr_filter = " AND (U.ip_int>=? AND U.ip_int<=?)"; 
-	$params[]=ip2long($cidr_range[0]);
-	$params[]=ip2long($cidr_range[1]);
-	}
+    if (!empty($cidr_range) && isset($cidr_range[0], $cidr_range[1])) {
+        $cidr_filter = " AND (U.ip_int >= ? AND U.ip_int <= ?)";
+        $params[] = ip2long($cidr_range[0]);
+        $params[] = ip2long($cidr_range[1]);
+    } else {
+        $cidr_filter = '';
     }
+} else {
+    $cidr_filter = '';
+}
+
+print_ip_submenu($page_url);
 
 ?>
 <div id="cont">

+ 1 - 1
html/admin/iplist/index.php

@@ -147,7 +147,7 @@ print_ip_submenu($page_url);
         <h2 id="modal1Title"><?php print WEB_selection_title; ?></h2>
         <input type="hidden" name="ApplyForAll" value="MassChange">
         <table class="data" align=center>
-        <tr><td><input type=checkbox class="putField" name="e_new_ou" value='1'></td><td align=left><?php print WEB_cell_ou."</td><td align=right>";print_ou_select($db_link, 'a_new_ou', 0); ?></td></tr>
+        <tr><td><input type=checkbox class="putField" name="e_new_ou" value='1'></td><td align=left><?php print WEB_cell_ou."</td><td align=right>";print_ou_set($db_link, 'a_new_ou', 0); ?></td></tr>
         <tr><td><input type=checkbox class="putField" name="e_enabled" value='1'></td><td align=left><?php print WEB_cell_enabled."</td><td align=right>";print_qa_select('a_enabled', 1);?></td></tr>
         <tr><td><input type=checkbox class="putField" name="e_group_id" value='1'></td><td align=left><?php print WEB_cell_filter."</td><td align=right>";print_filter_group_select($db_link, 'a_group_id', 0);?></td></tr>
         <tr><td><input type=checkbox class="putField" name="e_queue_id" value='1'></td><td align=left><?php print WEB_cell_shaper."</td><td align=right>";print_queue_select($db_link, 'a_queue_id', 0);?></td></tr>

+ 73 - 29
html/admin/queues/index.php

@@ -2,24 +2,57 @@
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.php");
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
 
-if (isset($_POST['save'])) {
-    $len = is_array($_POST['r_id']) ? count($_POST['r_id']) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $id = intval($_POST['r_id'][$i]);
-        $new['queue_name'] = trim($_POST['f_queue_name'][$i]);
-        $new['Download'] = $_POST['f_down'][$i] * 1;
-        $new['Upload'] = $_POST['f_up'][$i] * 1;
-        update_record($db_link, "queue_list", "id=?", $new, [ $id ]);
+// Сохранение ОТМЕЧЕННЫХ записей
+if (getPOST("save") !== null) {
+    $selected_ids = getPOST("f_id", null, []);        // отмеченные чекбоксы
+    $all_ids      = getPOST("r_id", null, []);        // все ID
+    $names        = getPOST("f_queue_name", null, []);
+    $downs        = getPOST("f_down", null, []);
+    $ups          = getPOST("f_up", null, []);
+
+    if (!empty($selected_ids) && is_array($selected_ids)) {
+        $selected_ids = array_map('intval', $selected_ids);
+        $selected_set = array_flip($selected_ids);
+
+        foreach ($all_ids as $i => $id) {
+            $id = (int)$id;
+            if ($id <= 0 || !isset($selected_set[$id])) continue;
+
+            $name = trim($names[$i] ?? '');
+            if ($name === '') continue;
+
+            update_record($db_link, "queue_list", "id = ?", [
+                'queue_name' => $name,
+                'Download'   => (int)($downs[$i] ?? 0),
+                'Upload'     => (int)($ups[$i] ?? 0)
+            ], [$id]);
+        }
+    }
+
+    header("Location: " . $_SERVER["REQUEST_URI"]);
+    exit;
+}
+
+// Удаление отмеченных
+if (getPOST("remove") !== null) {
+    $f_id = getPOST("f_id", null, []);
+    if (!empty($f_id) && is_array($f_id)) {
+        foreach ($f_id as $id) {
+            $id = (int)$id;
+            if ($id > 0) {
+                delete_record($db_link, "queue_list", "id = ?", [$id]);
+            }
+        }
     }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["create"])) {
-    $queue_name = $_POST["new_queue"];
-    if (isset($queue_name)) {
-        $q['queue_name'] = $queue_name;
-        insert_record($db_link, "queue_list", $q);
+// Создание новой очереди
+if (getPOST("create") !== null) {
+    $queue_name = trim(getPOST("new_queue", null, ''));
+    if ($queue_name !== '') {
+        insert_record($db_link, "queue_list", ['queue_name' => $queue_name]);
     }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
@@ -31,33 +64,44 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");
 <div id="cont">
 <b><?php echo WEB_list_queues; ?></b> <br>
 <form name="def" action="index.php" method="post">
+
+<!-- ЕДИНАЯ КНОПКА СОХРАНЕНИЯ -->
+<div style="margin-top: 10px; text-align: right;">
+    <input type="submit" name="save" value="<?php echo WEB_btn_save; ?>">
+    <input type="submit" 
+           onclick="return confirm('<?php echo WEB_msg_delete; ?>?')" 
+           name="remove" 
+           value="<?php echo WEB_btn_delete; ?>">
+</div>
+
 <table class="data">
 <tr align="center">
-	<td><input type="checkbox" onClick="checkAll(this.checked);"></td>
-	<td><b>Id</b></td>
-	<td><b><?php echo WEB_cell_name; ?></b></td>
-	<td><b>Download</b></td>
-	<td><b>Upload</b></td>
-	<td><input type="submit" onclick="return confirm('<?php echo WEB_msg_delete; ?>?')" name="remove" value="<?php echo WEB_btn_delete; ?>"></td>
+    <td><input type="checkbox" onClick="checkAll(this.checked);"></td>
+    <td><b>Id</b></td>
+    <td><b><?php echo WEB_cell_name; ?></b></td>
+    <td><b>Download</b></td>
+    <td><b>Upload</b></td>
 </tr>
 <?php
-$t_queue=get_records_sql($db_link, "SELECT * FROM queue_list ORDER BY id");
+$t_queue = get_records_sql($db_link, "SELECT * FROM queue_list ORDER BY id");
 foreach ($t_queue as $row) {
     print "<tr align=center>\n";
-    print "<td class=\"data\" style='padding:0'><input type=checkbox name=f_id[] value='{$row['id']}'></td>\n";
-    print "<td class=\"data\"><input type=\"hidden\" name='r_id[]' value='{$row['id']}'>{$row['id']}</td>\n";
-    print "<td class=\"data\"><input type=\"text\" name='f_queue_name[]' value='{$row['queue_name']}'></td>\n";
-    print "<td class=\"data\"><input type=\"text\" name='f_down[]' value='{$row['Download']}'></td>\n";
-    print "<td class=\"data\"><input type=\"text\" name='f_up[]' value='{$row['Upload']}'></td>\n";
-    print "<td class=\"data\"><input type=\"submit\" name=\"save\" value='".WEB_btn_save."'></td>\n";
+    print "<td class=\"data\" style='padding:0'><input type=\"checkbox\" name=\"f_id[]\" value=\"{$row['id']}\"></td>\n";
+    print "<td class=\"data\"><input type=\"hidden\" name=\"r_id[]\" value=\"{$row['id']}\">{$row['id']}</td>\n";
+    print "<td class=\"data\"><input type=\"text\" name=\"f_queue_name[]\" value=\"" . htmlspecialchars($row['queue_name']) . "\"></td>\n";
+    print "<td class=\"data\"><input type=\"text\" name=\"f_down[]\" value=\"{$row['download']}\"></td>\n";
+    print "<td class=\"data\"><input type=\"text\" name=\"f_up[]\" value=\"{$row['upload']}\"></td>\n";
     print "</tr>\n";
 }
 ?>
 </table>
-<div>
-<input type=text name=new_queue value="New_queue">
-<input type="submit" name="create" value="<?php echo WEB_btn_add; ?>">
+
+
+<div style="margin-top: 15px;">
+    <input type="text" name="new_queue" value="New_queue">
+    <input type="submit" name="create" value="<?php echo WEB_btn_add; ?>">
 </div>
+
 </form>
 <?php
 require_once ($_SERVER['DOCUMENT_ROOT']."/inc/footer.php");

+ 99 - 60
html/admin/users/edit_alias.php

@@ -6,82 +6,111 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/idfilter.php");
 
 $msg_error = "";
 
-$sSQL = "SELECT * FROM user_auth WHERE id=?";
-$auth_info = get_record_sql($db_link, $sSQL, [ $id ]);
+$sSQL = "SELECT * FROM user_auth WHERE id = ?";
+$auth_info = get_record_sql($db_link, $sSQL, [$id]);
 
-if (empty($auth_info['dns_name']) or $auth_info['deleted']) {
-    header("Location: /admin/users/editauth.php?id=".$id);
+if (empty($auth_info['dns_name']) || $auth_info['deleted']) {
+    header("Location: /admin/users/editauth.php?id=" . $id);
     exit;
-    }
-
-run_sql($db_link,"DELETE FROM user_auth_alias WHERE auth_id in (SELECT id FROM user_auth WHERE deleted=1)");
+}
 
-if (isset($_POST["s_remove"])) {
-    $s_id = $_POST["s_id"];
-    foreach ($s_id as $key => $val) {
-        if (isset($val)) {
-            LOG_INFO($db_link, "Remove alias id: $val ".dump_record($db_link,'user_auth_alias','id=?', [ $val ]));
-            delete_record($db_link, "user_auth_alias", "id=?", [ $val ]);
+// Очистка удалённых алиасов
+delete_records($db_link, "user_auth_alias", "auth_id IN (SELECT id FROM user_auth WHERE deleted = 1)");
+
+// Удаление алиасов
+if (getPOST("s_remove") !== null) {
+    $s_id = getPOST("s_id", null, []);
+    
+    if (!empty($s_id) && is_array($s_id)) {
+        foreach ($s_id as $val) {
+            $val = trim($val);
+            if ($val === '') continue;
+            
+            LOG_INFO($db_link, "Remove alias id: $val " . dump_record($db_link, 'user_auth_alias', 'id = ?', [$val]));
+            delete_record($db_link, "user_auth_alias", "id = ?", [(int)$val]);
         }
     }
+    
     header("Location: " . $page_url);
     exit;
 }
 
-if (isset($_POST['s_save'])) {
-    $len = is_array($_POST['s_save']) ? count($_POST['s_save']) : 0;
-    $domain_zone = get_option($db_link, 33);
-    $domain_zone = ltrim($domain_zone, '.');
-    for ($i = 0; $i < $len; $i ++) {
-        $save_id = intval($_POST['s_save'][$i]);
-        $len_all = is_array($_POST['n_id']) ? count($_POST['n_id']) : 0;
-        for ($j = 0; $j < $len_all; $j ++) {
-            if (intval($_POST['n_id'][$j]) != $save_id) { continue; }
-            $f_dnsname = trim($_POST['s_alias'][$j]);
-            if (!empty($f_dnsname)) {
-                $f_dnsname = preg_replace('/\.' . str_replace('.', '\.', $domain_zone) . '$/', '', $f_dnsname);
-//                $f_dnsname = preg_replace('/\.$/','',$f_dnsname);
-                $f_dnsname = preg_replace('/\s+/','-',$f_dnsname);
-//                $f_dnsname = preg_replace('/\./','-',$f_dnsname);
-                }
-            if (empty($f_dnsname) or !checkValidHostname($f_dnsname) or !checkUniqHostname($db_link,$id,$f_dnsname)) { continue; }
-            $new['alias'] = $f_dnsname;
-            $new['description'] = trim($_POST['s_description'][$j]);
-            update_record($db_link, "user_auth_alias", "id=?", $new, [ $save_id ]);
+// Сохранение изменений в алиасах
+if (getPOST("s_save") !== null) {
+    $selected_ids = getPOST("s_id", null, []);        // отмеченные чекбоксы
+    $all_ids      = getPOST("n_id", null, []);        // все ID
+    $s_aliases    = getPOST("s_alias", null, []);
+    $s_descriptions = getPOST("s_description", null, []);
+
+    if (!empty($selected_ids) && is_array($selected_ids)) {
+        $selected_ids = array_map('intval', $selected_ids);
+        $selected_set = array_flip($selected_ids);
+        $domain_zone = ltrim(get_option($db_link, 33), '.');
+
+        foreach ($all_ids as $i => $id) {
+            $id = (int)$id;
+            if ($id <= 0 || !isset($selected_set[$id])) continue;
+            $f_dnsname = trim($s_aliases[$i] ?? '');
+            if ($f_dnsname !== '') {
+                // Удаляем доменную зону из конца
+                $escaped_zone = preg_quote($domain_zone, '/');
+                $f_dnsname = preg_replace('/\.' . $escaped_zone . '$/i', '', $f_dnsname);
+                $f_dnsname = preg_replace('/\s+/', '-', $f_dnsname);
+            }
+            // Валидация
+            if (
+                $f_dnsname === '' ||
+                !checkValidHostname($f_dnsname) ||
+                !checkUniqHostname($db_link, $id, $f_dnsname)
+            ) {
+                continue;
+            }
+            $new = [
+                'alias'      => $f_dnsname,
+                'description' => trim($s_descriptions[$i] ?? '')
+            ];
+            update_record($db_link, "user_auth_alias", "id = ?", $new, [$id]);
         }
     }
     header("Location: " . $page_url);
     exit;
 }
 
-if (isset($_POST["s_create"])) {
-    $new_alias = $_POST["s_create_alias"];
-    if (isset($new_alias)) {
-        $f_dnsname = trim($new_alias);
-        if (!empty($f_dnsname)) {
-            $domain_zone = get_option($db_link, 33);
-            $domain_zone = ltrim($domain_zone, '.');
-            $f_dnsname = preg_replace('/\.' . str_replace('.', '\.', $domain_zone) . '$/', '', $f_dnsname);
-//            $f_dnsname = preg_replace('/\.$/','',$f_dnsname);
-            $f_dnsname = preg_replace('/\s+/','-',$f_dnsname);
-//            $f_dnsname = preg_replace('/\./','-',$f_dnsname);
-            }
-
-        if (empty($f_dnsname) or !checkValidHostname($f_dnsname) or !checkUniqHostname($db_link,$id,$f_dnsname)) {
-            $msg_error = "DNS $f_dnsname already exists at: ".searchHostname($db_link,$id,$f_dnsname)." Discard changes!";
+// Создание нового алиаса
+if (getPOST("s_create") !== null) {
+    $new_alias = trim(getPOST("s_create_alias", null, ''));
+    
+    if ($new_alias !== '') {
+        $domain_zone = ltrim(get_option($db_link, 33), '.');
+        $f_dnsname = $new_alias;
+        
+        if ($f_dnsname !== '') {
+            $escaped_zone = preg_quote($domain_zone, '/');
+            $f_dnsname = preg_replace('/\.' . $escaped_zone . '$/i', '', $f_dnsname);
+            $f_dnsname = preg_replace('/\s+/', '-', $f_dnsname);
+        }
+        
+        if (
+            $f_dnsname === '' ||
+            !checkValidHostname($f_dnsname) ||
+            !checkUniqHostname($db_link, $id, $f_dnsname)
+        ) {
+            $msg_error = "DNS $f_dnsname already exists at: " . searchHostname($db_link, $id, $f_dnsname) . " Discard changes!";
             $_SESSION[$page_url]['msg'] = $msg_error;
             LOG_ERROR($db_link, $msg_error);
             header("Location: " . $_SERVER["REQUEST_URI"]);
             exit;
         }
-
-        if (empty($f_dnsname)) { $f_dnsname = ''; }
-
-        $new_rec['alias'] = $f_dnsname;
-        $new_rec['auth_id'] = $id;
+        
+        $new_rec = [
+            'alias'    => $f_dnsname,
+            'auth_id'  => $id
+        ];
+        
         LOG_INFO($db_link, "Create new alias $new_alias");
         insert_record($db_link, "user_auth_alias", $new_rec);
     }
+    
     header("Location: " . $page_url);
     exit;
 }
@@ -104,14 +133,24 @@ require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");
 <b><?php print WEB_user_alias_for."&nbsp"; print_url($auth_info['ip'],"/admin/users/editauth.php?id=$id"); ?></b> <br>
 <table class="data">
 <tr align="center">
-	<td></td>
-	<td width=30><b>id</b></td>
-	<td><b><?php echo WEB_cell_name; ?></b></td>
-	<td><b><?php echo WEB_cell_description; ?></b></td>
-	<td><input type="submit" onclick="return confirm('<?php echo WEB_msg_delete; ?>?')" name="s_remove" value="<?php echo WEB_btn_delete; ?>"></td>
+    <td><input type="checkbox" onClick="checkAll(this.checked);"></td>
+    <td width=30><b>id</b></td>
+    <td><b><?php echo WEB_cell_name; ?></b></td>
+    <td><b><?php echo WEB_cell_description; ?></b></td>
+    <td>
+        <!-- Контейнер для кнопок справа -->
+        <div style="text-align: right; white-space: nowrap;">
+            <input type="submit" name="s_save" value="<?php echo WEB_btn_save; ?>">
+            <input type="submit" 
+                   onclick="return confirm('<?php echo WEB_msg_delete; ?>?')" 
+                   name="s_remove" 
+                   value="<?php echo WEB_btn_delete; ?>"
+                   style="margin-left: 8px;">
+        </div>
+    </td>
 </tr>
 <?php
-$t_user_auth_alias = get_records_sql($db_link,"SELECT * FROM user_auth_alias WHERE auth_id=? ORDER BY alias", [ $id ]);
+$t_user_auth_alias = get_records_sql($db_link,"SELECT * FROM user_auth_alias WHERE auth_id=? ORDER BY id", [ $id ]);
 if (!empty($t_user_auth_alias)) {
 foreach ( $t_user_auth_alias as $row ) {
     print "<tr align=center>\n";
@@ -119,7 +158,7 @@ foreach ( $t_user_auth_alias as $row ) {
     print "<td class=\"data\"><input type=\"hidden\" name='n_id[]' value='{$row['id']}'>{$row['id']}</td>\n";
     print "<td class=\"data\"><input type=\"text\" name='s_alias[]' value='{$row['alias']}' pattern=\"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$\"></td>\n";
     print "<td class=\"data\"><input type=\"text\" name='s_description[]' value='{$row['description']}'></td>\n";
-    print "<td class=\"data\"><button name='s_save[]' value='{$row['id']}'>".WEB_btn_save."</button></td>\n";
+    print "<td class=\"data\"></td>\n";
     print "</tr>\n";
 }
 }

+ 110 - 50
html/admin/users/edit_rules.php

@@ -1,98 +1,158 @@
 <?php
-
-require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.php");
-require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
-require_once ($_SERVER['DOCUMENT_ROOT']."/inc/idfilter.php");
+require_once ($_SERVER['DOCUMENT_ROOT'] . "/inc/auth.php");
+require_once ($_SERVER['DOCUMENT_ROOT'] . "/inc/languages/" . HTML_LANG . ".php");
+require_once ($_SERVER['DOCUMENT_ROOT'] . "/inc/idfilter.php");
 
 $msg_error = "";
 
-$sSQL = "SELECT * FROM user_list WHERE id=?";
-$auth_info = get_record_sql($db_link, $sSQL, [ $id ]);
+$sSQL = "SELECT * FROM user_list WHERE id = ?";
+$auth_info = get_record_sql($db_link, $sSQL, [$id]);
 
-if (isset($_POST["s_remove"])) {
-    $s_id = $_POST["s_id"];
-    foreach ($s_id as $key => $val) {
-        if (isset($val)) {
-            LOG_INFO($db_link, "Remove rule id: $val ".dump_record($db_link,'auth_rules','id=?', [ $val ]));
-            delete_record($db_link, "auth_rules", "id=?" , [ $val ]);
+// Удаление правил
+if (getPOST("s_remove") !== null) {
+    $s_id = getPOST("s_id", null, []);
+    if (!empty($s_id) && is_array($s_id)) {
+        foreach ($s_id as $val) {
+            $val = trim($val);
+            if ($val === '') continue;
+            LOG_INFO($db_link, "Remove rule id: $val " . dump_record($db_link, 'auth_rules', 'id = ?', [$val]));
+            delete_record($db_link, "auth_rules", "id = ?", [(int)$val]);
         }
     }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST['s_save'])) {
-    $len = is_array($_POST['s_save']) ? count($_POST['s_save']) : 0;
-    for ($i = 0; $i < $len; $i ++) {
-        $save_id = intval($_POST['s_save'][$i]);
-        $len_all = is_array($_POST['n_id']) ? count($_POST['n_id']) : 0;
-        for ($j = 0; $j < $len_all; $j ++) {
-            if (intval($_POST['n_id'][$j]) != $save_id) { continue; }
-            $new['rule_type'] = $_POST['s_type'][$j]*1;
-            $new['rule'] = trim($_POST['s_rule'][$j]);
-            $new['description'] = trim($_POST['s_description'][$j]);
-            if ($new['rule_type'] ==2) {
-                $new['rule'] = mac_dotted($new['rule']);
+// Сохранение ОТМЕЧЕННЫХ правил
+if (getPOST("s_save") !== null) {
+    $selected_ids = getPOST("s_id", null, []);      // отмеченные чекбоксы
+    $all_ids      = getPOST("n_id", null, []);      // все ID
+    $types        = getPOST("s_type", null, []);
+    $rules        = getPOST("s_rule", null, []);
+    $descriptions = getPOST("s_description", null, []);
+
+    if (!empty($selected_ids) && is_array($selected_ids)) {
+        $selected_ids = array_map('intval', $selected_ids);
+        $selected_set = array_flip($selected_ids);
+
+        foreach ($all_ids as $i => $id) {
+            $id = (int)$id;
+            if ($id <= 0 || !isset($selected_set[$id])) continue;
+
+            // Получаем тип правила
+            $rule_type = (int)($types[$i] ?? 3);
+            $raw_rule  = trim($rules[$i] ?? '');
+            $desc      = trim($descriptions[$i] ?? '');
+
+            if ($raw_rule === '') continue;
+
+            $new_rule = $raw_rule;
+            // Валидация в зависимости от типа
+            if ($rule_type == 1) {
+                // IP-адрес
+                if (!checkValidIp($new_rule)) {
+                    continue; // пропускаем невалидный IP
                 }
-	    update_auth_rule($db_link,$new,$save_id);
+            } elseif ($rule_type == 2) {
+                // MAC-адрес
+                $normalized_mac = MayBeMac($new_rule);
+                if ($normalized_mac === null) {
+                    continue; // пропускаем невалидный MAC
+                }
+                $new_rule = $normalized_mac;
+            }
+
+            $new = [
+                'rule_type'   => $rule_type,
+                'rule'        => $new_rule,
+                'description' => $desc
+            ];
+
+            update_auth_rule($db_link, $new, $id);
         }
     }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
-if (isset($_POST["s_create"])) {
-    $new_rule = $_POST["s_new_rule"];
-    if (isset($new_rule)) {
-	add_auth_rule($db_link,$new_rule,$_POST["s_new_type"],$id);
-	}
+// Создание нового правила
+if (getPOST("s_create") !== null) {
+    $new_rule = trim(getPOST("s_new_rule", null, ''));
+    $rule_type = (int)getPOST("s_new_type", null, 3);
+    if ($new_rule !== '') {
+        if ($rule_type == 1 and !checkValidIp($new_rule)) {
+                header("Location: " . $_SERVER["REQUEST_URI"]);
+                exit;
+                }
+        if ($rule_type == 2 and MayBeMac($new_rule)==null) {
+                header("Location: " . $_SERVER["REQUEST_URI"]);
+                exit;
+                }
+        if ($rule_type == 2) { $new_rule = MayBeMac($new_rule); }
+        add_auth_rule($db_link, $new_rule, $rule_type, $id);
+    }
     header("Location: " . $_SERVER["REQUEST_URI"]);
     exit;
 }
 
 unset($_POST);
-
 fix_auth_rules($db_link);
 
-require_once ($_SERVER['DOCUMENT_ROOT']."/inc/header.php");
-
+require_once ($_SERVER['DOCUMENT_ROOT'] . "/inc/header.php");
 ?>
 <div id="cont">
 <br>
 <form name="def" action="edit_rules.php?id=<?php echo $id; ?>" method="post">
-<b><?php print WEB_ou_rules_for_autoassigning."&nbsp"; print_url($auth_info['login'],"/admin/users/edituser.php?id=$id"); ?></b>
+<b><?php print WEB_ou_rules_for_autoassigning . "&nbsp;"; print_url($auth_info['login'], "/admin/users/edituser.php?id=$id"); ?></b>
 <br>
-<?php echo WEB_ou_rules_order; ?>:  hotspot => subnet => mac => hostname => default user
+<?php echo WEB_ou_rules_order; ?>: hotspot => subnet => mac => hostname => default user
 <br><br>
 <table class="data">
 <tr align="center">
-    <td></td>
+    <td><input type="checkbox" onClick="checkAll(this.checked);"></td>
     <td width=30><b>id</b></td>
     <td><b><?php echo WEB_cell_type; ?></b></td>
     <td><b><?php echo WEB_ou_rule; ?></b></td>
     <td><b><?php echo WEB_cell_description; ?></b></td>
-    <td><input type="submit" onclick="return confirm('<?php echo WEB_msg_delete; ?>?')" name="s_remove" value="<?php echo WEB_btn_delete; ?>"></td>
+    <td>
+        <!-- Кнопки управления справа -->
+        <div style="text-align: right; white-space: nowrap;">
+            <input type="submit" name="s_save" value="<?php echo WEB_btn_save; ?>">
+            <input type="submit" 
+                   onclick="return confirm('<?php echo WEB_msg_delete; ?>?')" 
+                   name="s_remove" 
+                   value="<?php echo WEB_btn_delete; ?>"
+                   style="margin-left: 8px;">
+        </div>
+    </td>
 </tr>
 <?php
-$t_auth_rules = get_records_sql($db_link,"SELECT * FROM auth_rules WHERE user_id=? ORDER BY id", [ $id ]);
-foreach ( $t_auth_rules as $row ) {
+$t_auth_rules = get_records_sql($db_link, "SELECT * FROM auth_rules WHERE user_id = ? ORDER BY id", [$id]);
+foreach ($t_auth_rules as $row) {
     print "<tr align=center>\n";
-    print "<td class=\"data\" style='padding:0'><input type=checkbox name=s_id[] value='{$row['id']}'></td>\n";
-    print "<td class=\"data\"><input type=\"hidden\" name='n_id[]' value='{$row['id']}'>{$row['id']}</td>\n";
-    print "<td class=\"data\">"; print_qa_rule_select("s_type[]","{$row['rule_type']}"); print "</td>\n";
-    print "<td class=\"data\"><input type=\"text\" name='s_rule[]' value='{$row['rule']}'></td>\n";
-    print "<td class=\"data\"><input type=\"text\" name='s_description[]' value='{$row['description']}'></td>\n";
-    print "<td class=\"data\"><button name='s_save[]' value='{$row['id']}'>".WEB_btn_save."</button></td>\n";
+    print "<td class=\"data\" style='padding:0'><input type=\"checkbox\" name=\"s_id[]\" value=\"{$row['id']}\"></td>\n";
+    print "<td class=\"data\"><input type=\"hidden\" name=\"n_id[]\" value=\"{$row['id']}\">{$row['id']}</td>\n";
+    print "<td class=\"data\">";
+    print_qa_rule_select("s_type[]", "{$row['rule_type']}");
+    print "</td>\n";
+    print "<td class=\"data\"><input type=\"text\" name=\"s_rule[]\" value=\"" . htmlspecialchars($row['rule']) . "\"></td>\n";
+    print "<td class=\"data\"><input type=\"text\" name=\"s_description[]\" value=\"" . htmlspecialchars($row['description']) . "\"></td>\n";
+    print "<td class=\"data\"></td>\n";
     print "</tr>\n";
 }
 ?>
 </table>
-<div>
-<?php print WEB_ou_new_rule."&nbsp"; print_qa_rule_select("s_new_type","1");  
-print "<input type=\"text\" name='s_new_rule' value=''>"; ?>
-<input type="submit" name="s_create" value="<?php echo WEB_btn_add; ?>">
+
+<div style="margin-top: 15px;">
+    <?php 
+    print WEB_ou_new_rule . "&nbsp;";
+    print_qa_rule_select("s_new_type", "1");
+    print '<input type="text" name="s_new_rule" value="">'; 
+    ?>
+    <input type="submit" name="s_create" value="<?php echo WEB_btn_add; ?>">
 </div>
+
 </form>
 <?php
-require_once ($_SERVER['DOCUMENT_ROOT']."/inc/footer.php");
+require_once ($_SERVER['DOCUMENT_ROOT'] . "/inc/footer.php");
 ?>

+ 1 - 1
html/admin/users/edituser.php

@@ -17,7 +17,7 @@ if (empty($user_info)) {
 
 if (isset($_POST["edituser"])) {
     unset($new);
-    $new["ou_id"] = $_POST["f_ou"] * 1;
+    if ($_POST["f_ou"] >0) {  $new["ou_id"] = $_POST["f_ou"]; }
     $new["filter_group_id"] = $_POST["f_filter"] * 1;
     $new["queue_id"] = $_POST["f_queue"] * 1;
     $user_name = trim($_POST["f_login"]);

+ 6 - 1
html/admin/users/index.php

@@ -18,7 +18,12 @@ if (isset($_POST["create"])) {
             unset($_POST);
         } else {
             $new['login'] = $login;
-            $new['ou_id'] = $rou;
+            if ($rou>0) { $new['ou_id'] = $rou; } else {
+                $row = 3; //User OU
+                $ou_exists = get_record_sql($db_link,"SELECT id FROM ou WHERE id=?", [ $rou ]);
+                if (empty($ou_exists)) { $row = $default_user_ou_id; }
+                $new['ou_id'] = $row;
+                }
             $ou_info = get_record_sql($db_link,"SELECT * FROM ou WHERE id=?", [ $rou ]);
 	    if (!empty($ou_info)) {
 		if (empty($ou_info['enabled'])) { $ou_info['enabled'] = 0; }

+ 8 - 2
html/inc/auth.utils.php

@@ -258,6 +258,12 @@ function authenticate_by_credentials($db, $login, $password) {
         return false;
     }
 
+    if (!empty($user) and $user['rights']==0) {
+        log_session_debug($db, "User $login disabled");
+        sleep(1);
+        return false;
+    }
+
     log_session_debug($db, "User found", ['user_id' => $user['id']]);
 
     if (!password_verify($password, $user['password'])) {
@@ -416,12 +422,12 @@ function IsSilentAuthenticated($db) {
         return false;
     }
 
-    $stmt = $db->prepare("SELECT id, rights FROM customers WHERE login = ? AND api_key = ? LIMIT 1");
+    $stmt = $db->prepare("SELECT id, rights FROM customers WHERE rights>0 AND login = ? AND api_key = ? LIMIT 1");
     $stmt->execute([$login, $api_key]);
 
     if ($stmt->rowCount() === 0) {
         LOG_DEBUG($db, "API auth failed for: $login");
-        log_session_debug($db, "Silent auth failed - user not found or invalid API key");
+        log_session_debug($db, "Silent auth failed - user not found, disabled  or invalid API key");
         return false;
     }
 

+ 64 - 14
html/inc/common.php

@@ -121,8 +121,9 @@ function getPOST($name, $page_url = null, $default = null, $filter = FILTER_DEFA
     if (isset($_GET[$name]) && is_array($_GET[$name])) {
         return $_GET[$name];
     }
+
     $value = filter_input(INPUT_POST, $name, $filter, $options);
-    if ($value === false || $value === null) {
+    if ($value === false || $value === null || empty($value)) {
         if ($page_url !== null  && isset($page_url) && isset($_SESSION[$page_url][$name])) {
             return $_SESSION[$page_url][$name];
         }
@@ -395,6 +396,52 @@ function checkValidMac($mac)
     return false;
 }
 
+function MayBeMac($mac)
+{
+    if (!is_string($mac)) {
+        return;
+    }
+
+    // Оставляем только hex-символы
+    $hex = preg_replace('/[^0-9a-f]/i', '', trim($mac));
+
+    // Длина: от 2 до 6 октетов (4–12 hex-символов)
+    if (!preg_match('/^[0-9a-f]{4,12}$/i', $hex)) {
+        return;
+    }
+
+    // Чётное количество символов (целые октеты)
+    if (strlen($hex) % 2 !== 0) {
+        return;
+    }
+
+    return mac_dotted2($mac);
+}
+
+function mac_dotted2($mac)
+{
+    if (!is_string($mac)) {
+        return;
+    }
+
+    // оставляем только hex
+    $hex = preg_replace('/[^0-9a-f]/i', '', trim($mac));
+
+    // максимум 6 октетов = 12 hex
+    if ($hex === '' || strlen($hex) > 12) {
+        return;
+    }
+
+    // только целые октеты
+    if (strlen($hex) % 2 !== 0) {
+        return;
+    }
+
+    // разбиваем по 2 символа
+    return implode(':', str_split(strtolower($hex), 2));
+}
+
+
 function checkValidHostname($dnsname)
 {
     if (empty($dnsname)) {
@@ -682,19 +729,24 @@ function cidrToRange($cidr)
 {
     $range = array();
     $cidr = explode('/', $cidr);
-    if (!isset($cidr[1])) {
+    if (!isset($cidr[1]) or empty($cidr[1])) {
+        $cidr[1] = 32;
+    }
+    if (!empty($cidr[1]) and $cidr[1]>32) {
         $cidr[1] = 32;
     }
-    $start = (ip2long($cidr[0])) & ((-1 << (32 - (int) $cidr[1])));
-    $stop = $start + pow(2, (32 - (int) $cidr[1])) - 1;
+    $mask = (int)$cidr[1];
+    $start = (ip2long($cidr[0])) & ((-1 << (32 - $mask)));
+    $stop = $start + pow(2, (32 - $mask)) - 1;
     $range[0] = long2ip($start);
     $range[1] = long2ip($stop);
-    $range[2] = $cidr;
+    $range[2] = $mask;
     //dhcp
     $dhcp_size = round(($stop - $start) / 2, PHP_ROUND_HALF_UP);
     $dhcp_start = $start + round($dhcp_size / 2, PHP_ROUND_HALF_UP);
     $range[3] = long2ip($dhcp_start);
     $range[4] = long2ip($dhcp_start + $dhcp_size);
+    //gateway
     $range[5] = long2ip($start + 1);
     return $range;
 }
@@ -795,14 +847,12 @@ function print_add_dev_interface($db, $device_id, $int_list, $int_name)
         if (!empty($int_exists[$interface['index']])) {
             continue;
         }
+        $display_value = WEB_select_item_lan;
         $value = $interface['name'] . ';' . $interface['index'] . ';' . $interface['interface_type'];
-        if ($interface['type'] == 1) {
-            $interface['type'] = WEB_select_item_wan;
-        }
-        if ($interface['type'] == 0) {
-            $interface['type'] = WEB_select_item_lan;
+        if ($interface['interface_type'] == 1) {
+            $display_value = WEB_select_item_wan;
         }
-        $display_str = $interface['name'] . '&nbsp|' . $interface['ip'] . '|' . $interface['interface_type'];
+        $display_str = $interface['name'] . '&nbsp|' . $interface['ip'] . '|' . $display_value;
         print_select_item($display_str, $value, 0);
     }
     print "</select>\n";
@@ -826,7 +876,7 @@ function print_ou_select_recursive($db, $ou_name, $ou_value, $parent_id = null,
     
     $sql = "SELECT id, parent_id, ou_name FROM ou 
             WHERE $where 
-            ORDER BY ou_name";
+            ORDER BY id";
     
     $items = get_records_sql($db, $sql);
 
@@ -2151,13 +2201,13 @@ function get_port($db, $port_id)
 function print_option_select($db, $option_name)
 {
     print "<select id=\"$option_name\" name=\"$option_name\">\n";
-    $t_option = get_records_sql($db, "SELECT id,option_name FROM config_options WHERE uniq=0 AND draft=0 ORDER BY option_name");
+    $t_option = get_records_sql($db, "SELECT id,option_name FROM config_options WHERE uniq=0 AND draft=0 AND ID<>68 ORDER BY option_name");
     if (!empty($t_option)) {
         foreach ($t_option as $row) {
             print "<option value=".$row['id'].">".$row['option_name']."</option>";
         }
     }
-    $t_option = get_records_sql($db, "SELECT id,option_name FROM config_options WHERE draft=0 AND uniq=1 AND id NOT IN (select option_id FROM config where draft=0) ORDER BY option_name");
+    $t_option = get_records_sql($db, "SELECT id,option_name FROM config_options WHERE draft=0 AND uniq=1 AND ID<>68 AND id NOT IN (select option_id FROM config where draft=0) ORDER BY option_name");
     if (!empty($t_option)) {
         foreach ($t_option as $row) {
             print "<option value=".$row['id'].">".$row['option_name']."</option>";

+ 2 - 2
html/inc/snmp.php

@@ -137,9 +137,9 @@ function getIpAdEntIfIndex($db, $ip, $snmp)
             $result[$interface_index]['index'] = $interface_index;
             $result[$interface_index]['name'] = $interface_name;
             //type: 0 - local, 1 - WAN
-            $result[$interface_index]['type'] = 1;
+            $result[$interface_index]['interface_type'] = 1;
             if (is_our_network($db, $interface_ip)) {
-                $result[$interface_index]['type'] = 0;
+                $result[$interface_index]['interface_type'] = 0;
             }
         }
     }

+ 4 - 1
scripts/updates/3-0-1/migration.msql

@@ -109,10 +109,13 @@ ALTER TABLE `user_stats` ADD COLUMN `step` int(11) NOT NULL DEFAULT 3600;
 ALTER TABLE `user_stats_full` MODIFY COLUMN `pkt_in` int(11) NOT NULL DEFAULT 0;
 ALTER TABLE `user_stats_full` MODIFY COLUMN `pkt_out` int(11) NOT NULL DEFAULT 0;
 
---- set default value for ip to NULL
+-- set default value for ip to NULL
 
 ALTER TABLE `dhcp_log` MODIFY COLUMN `ip` varchar(15) NULL DEFAULT NULL;
 ALTER TABLE `dhcp_queue` MODIFY COLUMN `ip` varchar(15) NULL DEFAULT NULL;
 ALTER TABLE `mac_history` MODIFY COLUMN `ip` varchar(16) NULL DEFAULT NULL;
 ALTER TABLE `remote_syslog` MODIFY COLUMN `ip` varchar(15) NULL DEFAULT NULL;
 ALTER TABLE `user_auth` MODIFY COLUMN `ip` varchar(18) NULL DEFAULT NULL;
+
+-- Add ACL for disable user
+INSERT INTO acl (id,name,description_english,description_russian) VALUES(0,'Disabled','User disabled','Пользователь отключен');