diff --git a/db_scripts/diff/15711.down b/db_scripts/diff/15711.down
new file mode 100644
index 00000000..e20498f5
--- /dev/null
+++ b/db_scripts/diff/15711.down
@@ -0,0 +1,104 @@
+USE provisioning;
+
+DELIMITER ;;
+
+DROP FUNCTION IF EXISTS ip_is_allowed;;
+CREATE DEFINER='root'@'localhost'
+FUNCTION ip_is_allowed(
+  _uuid VARCHAR(36),
+  _ip VARCHAR(46)
+) RETURNS BOOLEAN
+DETERMINISTIC READS SQL DATA
+SQL SECURITY INVOKER
+BEGIN
+
+  DECLARE _network_bytes VARBINARY(16);
+  DECLARE _is_valid_ip, _is_ipv6 BOOLEAN DEFAULT 0;
+  DECLARE _aig_id, _aig_ids_done INT DEFAULT 0;
+  DECLARE _is_allowed BOOLEAN DEFAULT NULL;
+  
+  DECLARE usr_aig_id_cursor CURSOR FOR SELECT
+      v.value
+    FROM provisioning.voip_usr_preferences v
+    JOIN provisioning.voip_subscribers s on v.subscriber_id = s.id
+    JOIN provisioning.voip_preferences a ON v.attribute_id = a.id
+    WHERE
+      s.uuid = _uuid
+      AND a.attribute IN ("man_allowed_ips_grp","allowed_ips_grp");
+
+  DECLARE dom_aig_id_cursor CURSOR FOR SELECT
+      v.value
+    FROM provisioning.voip_dom_preferences v
+    JOIN provisioning.voip_subscribers s on v.domain_id = s.domain_id
+    JOIN provisioning.voip_preferences a ON v.attribute_id = a.id
+    WHERE
+      s.uuid = _uuid
+      AND a.attribute IN ("man_allowed_ips_grp","allowed_ips_grp");
+
+  DECLARE CONTINUE HANDLER FOR NOT FOUND SET _aig_ids_done = _aig_ids_done + 1;
+
+  IF IF(EXISTS(SELECT 1 FROM provisioning.voip_subscribers WHERE uuid = _uuid),0,1) THEN
+    #reject invalid subscribers:
+    RETURN 0;
+  END IF;
+
+  SET _network_bytes = INET6_ATON(_ip);
+  SET _is_valid_ip = IF(_network_bytes IS NULL OR HEX(_network_bytes) = "00000000",0,1);
+  SET _is_ipv6 = IF(_is_valid_ip,ip_is_ipv6(_ip),0);
+
+  OPEN usr_aig_id_cursor;
+  aig_ids_loop: LOOP
+    IF _aig_ids_done = 0 THEN
+      FETCH usr_aig_id_cursor INTO _aig_id;
+    ELSEIF _aig_ids_done = 1 THEN
+      CLOSE usr_aig_id_cursor;
+      IF _is_allowed IS NOT NULL THEN
+        RETURN _is_allowed;
+      ELSE
+        SET _is_allowed = NULL;
+        OPEN dom_aig_id_cursor;
+        FETCH dom_aig_id_cursor INTO _aig_id;
+      END IF;
+    ELSE
+      CLOSE dom_aig_id_cursor;
+      IF _is_allowed IS NOT NULL THEN
+        RETURN _is_allowed;
+      ELSE
+        LEAVE aig_ids_loop;
+      END IF;
+    END IF;
+    IF _aig_id IS NOT NULL THEN
+      IF _is_allowed IS NULL THEN
+        SET _is_allowed = 0;
+      END IF;
+      IF _is_valid_ip THEN
+        IF _is_ipv6 THEN
+          SET _is_allowed = IF(_is_allowed,1,COALESCE((SELECT 1
+            FROM provisioning.voip_allowed_ip_groups aig
+            WHERE
+              aig.group_id = _aig_id 
+              AND aig._ipv6_net_from <= _network_bytes
+              AND aig._ipv6_net_to >= _network_bytes
+          LIMIT 1),0));
+        ELSE
+          SET _is_allowed = IF(_is_allowed,1,COALESCE((SELECT 1
+            FROM provisioning.voip_allowed_ip_groups aig
+            WHERE
+              aig.group_id = _aig_id 
+              AND aig._ipv4_net_from <= _network_bytes
+              AND aig._ipv4_net_to >= _network_bytes
+          LIMIT 1),0));
+        END IF;
+      ELSE
+        #reject invalid IP addresses only if an allowed_ip is configured:
+        RETURN 0;
+      END IF;
+    END IF;
+  END LOOP aig_ids_loop;
+  
+  #accept if there are no allowed_ips set:
+  RETURN 1;
+
+END;;
+
+DELIMITER ;
\ No newline at end of file
diff --git a/db_scripts/diff/15711.up b/db_scripts/diff/15711.up
new file mode 100644
index 00000000..82e18cc8
--- /dev/null
+++ b/db_scripts/diff/15711.up
@@ -0,0 +1,106 @@
+USE provisioning;
+
+DELIMITER ;;
+
+DROP FUNCTION IF EXISTS ip_is_allowed;;
+CREATE DEFINER='root'@'localhost'
+FUNCTION ip_is_allowed(
+  _uuid VARCHAR(36),
+  _ip VARCHAR(46)
+) RETURNS BOOLEAN
+DETERMINISTIC READS SQL DATA
+SQL SECURITY INVOKER
+BEGIN
+
+  DECLARE _network_bytes VARBINARY(16);
+  DECLARE _is_valid_ip, _is_ipv6 BOOLEAN DEFAULT 0;
+  DECLARE _aig_id, _aig_ids_done INT DEFAULT 0;
+  DECLARE _is_allowed BOOLEAN DEFAULT NULL;
+  
+  DECLARE usr_aig_id_cursor CURSOR FOR SELECT
+      v.value
+    FROM provisioning.voip_usr_preferences v
+    JOIN provisioning.voip_subscribers s on v.subscriber_id = s.id
+    JOIN provisioning.voip_preferences a ON v.attribute_id = a.id
+    WHERE
+      s.uuid = _uuid
+      AND a.attribute IN ("man_allowed_ips_grp","allowed_ips_grp");
+
+  DECLARE dom_aig_id_cursor CURSOR FOR SELECT
+      v.value
+    FROM provisioning.voip_dom_preferences v
+    JOIN provisioning.voip_subscribers s on v.domain_id = s.domain_id
+    JOIN provisioning.voip_preferences a ON v.attribute_id = a.id
+    WHERE
+      s.uuid = _uuid
+      AND a.attribute IN ("man_allowed_ips_grp","allowed_ips_grp");
+
+  DECLARE CONTINUE HANDLER FOR NOT FOUND SET _aig_ids_done = _aig_ids_done + 1;
+
+  IF IF(EXISTS(SELECT 1 FROM provisioning.voip_subscribers WHERE uuid = _uuid),0,1) THEN
+    #reject invalid subscribers:
+    RETURN 0;
+  END IF;
+
+  SET _network_bytes = INET6_ATON(_ip);
+  SET _is_valid_ip = IF(_network_bytes IS NULL OR HEX(_network_bytes) = "00000000",0,1);
+  SET _is_ipv6 = IF(_is_valid_ip,ip_is_ipv6(_ip),0);
+
+  OPEN usr_aig_id_cursor;
+  aig_ids_loop: LOOP
+    IF _aig_ids_done = 0 THEN
+      FETCH usr_aig_id_cursor INTO _aig_id;
+      IF _aig_ids_done = 1 THEN
+        CLOSE usr_aig_id_cursor;
+        IF _is_allowed IS NOT NULL THEN
+          RETURN _is_allowed;
+        ELSE
+          SET _is_allowed = NULL;
+          OPEN dom_aig_id_cursor;
+        END IF;
+      END IF;
+    END IF;
+    IF _aig_ids_done = 1 THEN
+      FETCH dom_aig_id_cursor INTO _aig_id;
+      IF _aig_ids_done = 2 THEN
+        CLOSE dom_aig_id_cursor;
+        IF _is_allowed IS NOT NULL THEN
+          RETURN _is_allowed;
+        ELSE
+          LEAVE aig_ids_loop;
+        END IF;
+      END IF;
+    END IF;
+    IF _is_allowed IS NULL THEN
+      SET _is_allowed = 0;
+    END IF;
+    IF _is_valid_ip THEN
+      IF _is_ipv6 THEN
+        SET _is_allowed = IF(_is_allowed,1,COALESCE((SELECT 1
+          FROM provisioning.voip_allowed_ip_groups aig
+          WHERE
+            aig.group_id = _aig_id 
+            AND aig._ipv6_net_from <= _network_bytes
+            AND aig._ipv6_net_to >= _network_bytes
+        LIMIT 1),0));
+      ELSE
+        SET _is_allowed = IF(_is_allowed,1,COALESCE((SELECT 1
+          FROM provisioning.voip_allowed_ip_groups aig
+          WHERE
+            aig.group_id = _aig_id 
+            AND aig._ipv4_net_from <= _network_bytes
+            AND aig._ipv4_net_to >= _network_bytes
+        LIMIT 1),0));
+      END IF;
+    ELSE
+      #reject invalid IP addresses only if an allowed_ip is configured:
+      RETURN 0;
+    END IF;
+  END LOOP aig_ids_loop;
+  
+  #accept if there are no allowed_ips set:
+  RETURN 1;
+
+END;;
+
+DELIMITER ;
\ No newline at end of file