Blame SOURCES/firewalld-0.4.3.2-ALREADY_ENABLED_rhbz#1366654.patch

dddd59
commit 0f6b0b3342ab9125d0768e4f57b80414c28c7f70
dddd59
Author: Thomas Woerner <twoerner@redhat.com>
dddd59
Date:   Fri Aug 12 16:42:43 2016 +0200
dddd59
dddd59
    firewall.command: ALREADY_ENABLED, NOT_ENABLED, ZONE_ALREADY_SET are warnings
dddd59
    
dddd59
    Refixes: RHBZ#845257
dddd59
dddd59
diff --git a/src/firewall/command.py b/src/firewall/command.py
dddd59
index 7964fab..c907cd3 100644
dddd59
--- a/src/firewall/command.py
dddd59
+++ b/src/firewall/command.py
dddd59
@@ -121,12 +121,18 @@ class FirewallCommand(object):
dddd59
             try:
dddd59
                 action_method(*call_item)
dddd59
             except DBusException as msg:
dddd59
-                code = FirewallError.get_code(msg.get_dbus_message())
dddd59
                 if len(option) > 1:
dddd59
                     self.print_warning("Warning: %s" % msg.get_dbus_message())
dddd59
                 else:
dddd59
-                    self.print_and_exit("Error: %s" % msg.get_dbus_message(),
dddd59
-                                        code)
dddd59
+                    code = FirewallError.get_code(msg.get_dbus_message())
dddd59
+                    if code in [ errors.ALREADY_ENABLED, errors.NOT_ENABLED,
dddd59
+                                 errors.ZONE_ALREADY_SET ]:
dddd59
+                        self.print_warning("Warning: %s" % \
dddd59
+                                           msg.get_dbus_message())
dddd59
+                        sys.exit(0)
dddd59
+                    else:
dddd59
+                        self.print_and_exit("Error: %s" % \
dddd59
+                                            msg.get_dbus_message(), code)
dddd59
                 _errors += 1
dddd59
             except Exception as msg:
dddd59
                 if len(option) > 1:
dddd59
@@ -135,7 +141,12 @@ class FirewallCommand(object):
dddd59
                     continue
dddd59
                 else:
dddd59
                     code = FirewallError.get_code(str(msg))
dddd59
-                    self.print_and_exit("Error: %s" % msg, code)
dddd59
+                    if code in [ errors.ALREADY_ENABLED, errors.NOT_ENABLED,
dddd59
+                                 errors.ZONE_ALREADY_SET ]:
dddd59
+                        self.print_warning("Warning: %s" % msg)
dddd59
+                        sys.exit(0)
dddd59
+                    else:
dddd59
+                        self.print_and_exit("Error: %s" % msg, code)
dddd59
                     _errors += 1
dddd59
             self.activate_exception_handler()
dddd59
 
dddd59
dddd59
commit e9e3ae8a6ac6fe121ed8a2c875bac355a2c7d102
dddd59
Author: Thomas Woerner <twoerner@redhat.com>
dddd59
Date:   Fri Aug 12 17:12:08 2016 +0200
dddd59
dddd59
    test-suite: Do not fail on ALREADY_ENABLED --add-destination tests
dddd59
    
dddd59
    Related to 0f6b0b3
dddd59
dddd59
diff --git a/src/tests/firewall-cmd_test.sh b/src/tests/firewall-cmd_test.sh
dddd59
index dd7c4f8..59ea81a 100755
dddd59
--- a/src/tests/firewall-cmd_test.sh
dddd59
+++ b/src/tests/firewall-cmd_test.sh
dddd59
@@ -577,7 +577,7 @@ assert_bad "--permanent --service=${myservice} --query-destination=ipv6:fd00:dea
dddd59
 
dddd59
 # test icmptype options, ipv4 and ipv6 destinations are default
dddd59
 assert_bad  "--permanent --icmptype=${myicmp} --add-destination=ipv5"
dddd59
-assert_bad "--permanent --icmptype=${myicmp} --add-destination=ipv4"
dddd59
+assert_good "--permanent --icmptype=${myicmp} --add-destination=ipv4"
dddd59
 assert_good "--permanent --icmptype=${myicmp} --remove-destination=ipv4"
dddd59
 assert_good "--permanent --icmptype=${myicmp} --add-destination=ipv4"
dddd59
 assert_good "--permanent --icmptype=${myicmp} --query-destination=ipv4"
dddd59
diff --git a/src/tests/firewall-offline-cmd_test.sh b/src/tests/firewall-offline-cmd_test.sh
dddd59
index 344b825..00f9a01 100755
dddd59
--- a/src/tests/firewall-offline-cmd_test.sh
dddd59
+++ b/src/tests/firewall-offline-cmd_test.sh
dddd59
@@ -474,7 +474,7 @@ assert_bad "--service=${myservice} --query-destination=ipv6:fd00:dead:beef:ff0::
dddd59
 
dddd59
 # test icmptype options, ipv4 and ipv6 destinations are default
dddd59
 assert_bad  "--icmptype=${myicmp} --add-destination=ipv5"
dddd59
-assert_bad "--icmptype=${myicmp} --add-destination=ipv4"
dddd59
+assert_good "--icmptype=${myicmp} --add-destination=ipv4"
dddd59
 assert_good "--icmptype=${myicmp} --remove-destination=ipv4"
dddd59
 assert_good "--icmptype=${myicmp} --add-destination=ipv4"
dddd59
 assert_good "--icmptype=${myicmp} --query-destination=ipv4"
dddd59
dddd59
commit 84f54680c14ab1aa149cebe65e25eef16f8ba621
dddd59
Author: Thomas Woerner <twoerner@redhat.com>
dddd59
Date:   Thu Aug 18 16:37:20 2016 +0200
dddd59
dddd59
    firewall.command: Do not use error code 254 for {ALREADY,NOT}_ENABLED sequences
dddd59
    
dddd59
    if there is one error code, then it will be directly used. If there are two and
dddd59
    one is 0, then the other will be used. If there are two or more different than
dddd59
    254 will be used.
dddd59
    
dddd59
    This is an addition for RHBZ#1366654
dddd59
dddd59
diff --git a/src/firewall/command.py b/src/firewall/command.py
dddd59
index c907cd3..a587d56 100644
dddd59
--- a/src/firewall/command.py
dddd59
+++ b/src/firewall/command.py
dddd59
@@ -91,19 +91,21 @@ class FirewallCommand(object):
dddd59
             self.fw.authorizeAll()
dddd59
         items = [ ]
dddd59
         _errors = 0
dddd59
+        _error_codes = [ ]
dddd59
         for item in option:
dddd59
             if parse_method is not None:
dddd59
                 try:
dddd59
                     item = parse_method(item)
dddd59
                 except Exception as msg:
dddd59
+                    code = FirewallError.get_code(str(msg))
dddd59
                     if len(option) > 1:
dddd59
                         self.print_warning("Warning: %s" % msg)
dddd59
-                        _errors += 1
dddd59
-                        continue
dddd59
                     else:
dddd59
-                        code = FirewallError.get_code(msg)
dddd59
                         self.print_and_exit("Error: %s" % msg, code)
dddd59
-                        _errors += 1
dddd59
+                    if code not in _error_codes:
dddd59
+                        _error_codes.append(code)
dddd59
+                    _errors += 1
dddd59
+                    continue
dddd59
 
dddd59
             items.append(item)
dddd59
 
dddd59
@@ -120,37 +122,32 @@ class FirewallCommand(object):
dddd59
             self.deactivate_exception_handler()
dddd59
             try:
dddd59
                 action_method(*call_item)
dddd59
-            except DBusException as msg:
dddd59
-                if len(option) > 1:
dddd59
-                    self.print_warning("Warning: %s" % msg.get_dbus_message())
dddd59
+            except (DBusException, Exception) as msg:
dddd59
+                if isinstance(msg, DBusException):
dddd59
+                    msg = msg.get_dbus_message()
dddd59
                 else:
dddd59
-                    code = FirewallError.get_code(msg.get_dbus_message())
dddd59
-                    if code in [ errors.ALREADY_ENABLED, errors.NOT_ENABLED,
dddd59
-                                 errors.ZONE_ALREADY_SET ]:
dddd59
-                        self.print_warning("Warning: %s" % \
dddd59
-                                           msg.get_dbus_message())
dddd59
-                        sys.exit(0)
dddd59
-                    else:
dddd59
-                        self.print_and_exit("Error: %s" % \
dddd59
-                                            msg.get_dbus_message(), code)
dddd59
-                _errors += 1
dddd59
-            except Exception as msg:
dddd59
+                    msg = str(msg)
dddd59
+                code = FirewallError.get_code(msg)
dddd59
+                if code in [ errors.ALREADY_ENABLED, errors.NOT_ENABLED,
dddd59
+                             errors.ZONE_ALREADY_SET ]:
dddd59
+                    code = 0
dddd59
                 if len(option) > 1:
dddd59
                     self.print_warning("Warning: %s" % msg)
dddd59
-                    _errors += 1
dddd59
-                    continue
dddd59
+                elif code == 0:
dddd59
+                    self.print_warning("Warning: %s" % msg)
dddd59
+                    sys.exit(0)
dddd59
                 else:
dddd59
-                    code = FirewallError.get_code(str(msg))
dddd59
-                    if code in [ errors.ALREADY_ENABLED, errors.NOT_ENABLED,
dddd59
-                                 errors.ZONE_ALREADY_SET ]:
dddd59
-                        self.print_warning("Warning: %s" % msg)
dddd59
-                        sys.exit(0)
dddd59
-                    else:
dddd59
-                        self.print_and_exit("Error: %s" % msg, code)
dddd59
-                    _errors += 1
dddd59
+                    self.print_and_exit("Error: %s" % msg, code)
dddd59
+                if code not in _error_codes:
dddd59
+                    _error_codes.append(code)
dddd59
+                _errors += 1
dddd59
             self.activate_exception_handler()
dddd59
 
dddd59
         if _errors == len(option) and not no_exit:
dddd59
+            if len(_error_codes) == 1:
dddd59
+                sys.exit(_error_codes[0])
dddd59
+            elif len(_error_codes) == 2 and 0 in _error_codes:
dddd59
+                sys.exit(list(set(_error_codes) - set([0]))[0])
dddd59
             sys.exit(errors.UNKNOWN_ERROR)
dddd59
 
dddd59
     def add_sequence(self, option, action_method, query_method, parse_method,
dddd59
diff --git a/src/tests/firewall-cmd_test.sh b/src/tests/firewall-cmd_test.sh
dddd59
index bc06ce0..c30c759 100755
dddd59
--- a/src/tests/firewall-cmd_test.sh
dddd59
+++ b/src/tests/firewall-cmd_test.sh
dddd59
@@ -148,6 +148,20 @@ assert_rich_bad() {
dddd59
   fi
dddd59
 }
dddd59
 
dddd59
+assert_exit_code() {
dddd59
+  local args="${1}"
dddd59
+  local ret="${2}"
dddd59
+
dddd59
+  ${path}firewall-cmd ${args} > /dev/null 2>&1
dddd59
+  got=$?
dddd59
+  if [[ "$got" -eq "$ret" ]]; then
dddd59
+    echo "${args} ... OK"
dddd59
+  else
dddd59
+    ((failures++))
dddd59
+    echo -e "${args} ... ${RED}${failures}. FAILED (bad exit status ${got} != ${ret})${RESTORE}"
dddd59
+  fi
dddd59
+}
dddd59
+
dddd59
 if ! ${path}firewall-cmd --state --quiet; then
dddd59
   echo "FirewallD is not running"
dddd59
   exit 1
dddd59
@@ -620,6 +634,14 @@ assert_good "--zone=${zone} --remove-source=${source}"
dddd59
 assert_good "--permanent --delete-ipset=${ipset}"
dddd59
 assert_good "--reload"
dddd59
 
dddd59
+# exit return value tests
dddd59
+assert_exit_code "--add-port 122/udpp" 103
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp" 103
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp" 103
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp --add-port 8745897/foo" 254
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp --add-port 8745897/foo --add-port bar" 254
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udp" 0
dddd59
+
dddd59
 # ... --direct ...
dddd59
 modprobe dummy
dddd59
 assert_good          "--direct --passthrough ipv4 --table mangle --append POSTROUTING --out-interface dummy0 --protocol udp --destination-port 68 --jump CHECKSUM --checksum-fill"
dddd59
dddd59
commit f70190d20448f52556745e88d50de7c7a8a774b8
dddd59
Author: Thomas Woerner <twoerner@redhat.com>
dddd59
Date:   Tue Aug 23 15:50:53 2016 +0200
dddd59
dddd59
    firewall.command: Fix sequence exit code with at least one succeeded item
dddd59
    
dddd59
    For sequences with errors but at least one succeeded item, the exit code should
dddd59
    be 0 as there has been a change. The errors will be printed as warnings.
dddd59
    
dddd59
    Without any succeeded item, the exit code will depend on the error codes. If
dddd59
    there is exactly one error code, then this is used. If there are more than one
dddd59
    then UNKNOWN_ERROR (254) will be used.
dddd59
    
dddd59
    This is an additional fix for 84f5468 and RHBZ#1366654
dddd59
dddd59
diff --git a/src/firewall/command.py b/src/firewall/command.py
dddd59
index a587d56..6e26c46 100644
dddd59
--- a/src/firewall/command.py
dddd59
+++ b/src/firewall/command.py
dddd59
@@ -135,7 +135,7 @@ class FirewallCommand(object):
dddd59
                     self.print_warning("Warning: %s" % msg)
dddd59
                 elif code == 0:
dddd59
                     self.print_warning("Warning: %s" % msg)
dddd59
-                    sys.exit(0)
dddd59
+                    return
dddd59
                 else:
dddd59
                     self.print_and_exit("Error: %s" % msg, code)
dddd59
                 if code not in _error_codes:
dddd59
@@ -143,12 +143,20 @@ class FirewallCommand(object):
dddd59
                 _errors += 1
dddd59
             self.activate_exception_handler()
dddd59
 
dddd59
-        if _errors == len(option) and not no_exit:
dddd59
-            if len(_error_codes) == 1:
dddd59
+        if not no_exit:
dddd59
+            if len(option) > _errors or 0 in _error_codes:
dddd59
+                # There have been more options than errors or there
dddd59
+                # was at least one error code 0, return.
dddd59
+                return
dddd59
+            elif len(_error_codes) == 1:
dddd59
+                # Exactly one error code, use it.
dddd59
                 sys.exit(_error_codes[0])
dddd59
-            elif len(_error_codes) == 2 and 0 in _error_codes:
dddd59
-                sys.exit(list(set(_error_codes) - set([0]))[0])
dddd59
-            sys.exit(errors.UNKNOWN_ERROR)
dddd59
+            elif len(_error_codes) > 1:
dddd59
+                # There is more than error, exit using
dddd59
+                # UNKNOWN_ERROR. This could happen within sequences
dddd59
+                # where parsing failed with different errors like
dddd59
+                # INVALID_PORT and INVALID_PROTOCOL.
dddd59
+                sys.exit(errors.UNKNOWN_ERROR)
dddd59
 
dddd59
     def add_sequence(self, option, action_method, query_method, parse_method,
dddd59
                      message, no_exit=False):
dddd59
diff --git a/src/tests/firewall-cmd_test.sh b/src/tests/firewall-cmd_test.sh
dddd59
index c30c759..f521840 100755
dddd59
--- a/src/tests/firewall-cmd_test.sh
dddd59
+++ b/src/tests/firewall-cmd_test.sh
dddd59
@@ -635,12 +635,18 @@ assert_good "--permanent --delete-ipset=${ipset}"
dddd59
 assert_good "--reload"
dddd59
 
dddd59
 # exit return value tests
dddd59
+assert_exit_code "--remove-port 122/udp" 0
dddd59
 assert_exit_code "--add-port 122/udpp" 103
dddd59
-assert_exit_code "--add-port 122/udp --add-port 122/udpp" 103
dddd59
-assert_exit_code "--add-port 122/udp --add-port 122/udpp" 103
dddd59
-assert_exit_code "--add-port 122/udp --add-port 122/udpp --add-port 8745897/foo" 254
dddd59
-assert_exit_code "--add-port 122/udp --add-port 122/udpp --add-port 8745897/foo --add-port bar" 254
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp" 0
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp" 0
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp --add-port 8745897/foo" 0
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp --add-port 8745897/foo --add-port bar" 0
dddd59
+assert_exit_code "--add-port 122/udpa --add-port 122/udpp" 103
dddd59
+assert_exit_code "--add-port 122/udpa --add-port 122/udpp" 103
dddd59
+assert_exit_code "--add-port 122/udpa --add-port 122/udpp --add-port 8745897/foo" 254
dddd59
+assert_exit_code "--add-port 122/udpa --add-port 122/udpp --add-port 8745897/foo --add-port bar" 254
dddd59
 assert_exit_code "--add-port 122/udp --add-port 122/udp" 0
dddd59
+assert_exit_code "--remove-port 122/udp" 0
dddd59
 
dddd59
 # ... --direct ...
dddd59
 modprobe dummy
dddd59
diff --git a/src/tests/firewall-offline-cmd_test.sh b/src/tests/firewall-offline-cmd_test.sh
dddd59
index ebbdfad..fb15300 100755
dddd59
--- a/src/tests/firewall-offline-cmd_test.sh
dddd59
+++ b/src/tests/firewall-offline-cmd_test.sh
dddd59
@@ -156,6 +156,20 @@ assert_rich_bad() {
dddd59
   fi
dddd59
 }
dddd59
 
dddd59
+assert_exit_code() {
dddd59
+  local args="${1}"
dddd59
+  local ret="${2}"
dddd59
+
dddd59
+  ${path}firewall-cmd ${args} > /dev/null 2>&1
dddd59
+  got=$?
dddd59
+  if [[ "$got" -eq "$ret" ]]; then
dddd59
+    echo "${args} ... OK"
dddd59
+  else
dddd59
+    ((failures++))
dddd59
+    echo -e "${args} ... ${RED}${failures}. FAILED (bad exit status ${got} != ${ret})${RESTORE}"
dddd59
+  fi
dddd59
+}
dddd59
+
dddd59
 test_lokkit_opts() {
dddd59
 rm -f /etc/firewalld/zones/*
dddd59
 assert_good "${lokkit_opts}"
dddd59
@@ -515,6 +529,20 @@ assert_good "--zone=${zone} --remove-source=${source}"
dddd59
 
dddd59
 assert_good "--delete-ipset=${ipset}"
dddd59
 
dddd59
+# exit return value tests
dddd59
+assert_exit_code "--remove-port 122/udp" 0
dddd59
+assert_exit_code "--add-port 122/udpp" 103
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp" 0
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp" 0
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp --add-port 8745897/foo" 0
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udpp --add-port 8745897/foo --add-port bar" 0
dddd59
+assert_exit_code "--add-port 122/udpa --add-port 122/udpp" 103
dddd59
+assert_exit_code "--add-port 122/udpa --add-port 122/udpp" 103
dddd59
+assert_exit_code "--add-port 122/udpa --add-port 122/udpp --add-port 8745897/foo" 254
dddd59
+assert_exit_code "--add-port 122/udpa --add-port 122/udpp --add-port 8745897/foo --add-port bar" 254
dddd59
+assert_exit_code "--add-port 122/udp --add-port 122/udp" 0
dddd59
+assert_exit_code "--remove-port 122/udp" 0
dddd59
+
dddd59
 # ... --direct ...
dddd59
 assert_bad           "--direct --add-passthrough ipv7 --table filter -A INPUT --in-interface dummy0 --protocol tcp --destination-port 67 --jump ACCEPT" # bad ipv
dddd59
 assert_good          "--direct --add-passthrough ipv4 --table filter --append INPUT --in-interface dummy0 --protocol tcp --destination-port 67 --jump ACCEPT"
dddd59
dddd59
commit e28dac9c52d1f661e1203ad5128ced95a1bef072
dddd59
Author: Thomas Woerner <twoerner@redhat.com>
dddd59
Date:   Tue Aug 30 16:36:36 2016 +0200
dddd59
dddd59
    Command line tools man pages: New section about sequence options and exit codes
dddd59
    
dddd59
    This has been added to the firewall-[offline-]cmd and firewallctl man pages.
dddd59
dddd59
diff --git a/doc/xml/firewall-cmd.xml b/doc/xml/firewall-cmd.xml
dddd59
index d441198..d77115a 100644
dddd59
--- a/doc/xml/firewall-cmd.xml
dddd59
+++ b/doc/xml/firewall-cmd.xml
dddd59
@@ -67,6 +67,12 @@
dddd59
   <refsect1 id="options">
dddd59
     <title>Options</title>
dddd59
     <para>
dddd59
+      For sequence options, this are the options that can be specified multiple times, the exit code is 0 if there is at least one item that succeded. The <literal>ALREADY_ENABLED</literal> (11), <literal>NOT_ENABLED</literal> (12) and also <literal>ZONE_ALREADY_SET</literal> (16) errors are treated as succeeded.
dddd59
+      If there are issues while parsing the items, then these are treated as warnings and will not change the result as long as there is a succeeded one.
dddd59
+      Without any succeeded item, the exit code will depend on the error codes. If there is exactly one error code, then this is used. If there are more than one then <literal>UNKNOWN_ERROR</literal> (254) will be used.
dddd59
+    </para>
dddd59
+
dddd59
+    <para>
dddd59
       The following options are supported:
dddd59
     </para>
dddd59
 
dddd59
diff --git a/doc/xml/firewall-offline-cmd.xml b/doc/xml/firewall-offline-cmd.xml
dddd59
index c4e5b80..0c45921 100644
dddd59
--- a/doc/xml/firewall-offline-cmd.xml
dddd59
+++ b/doc/xml/firewall-offline-cmd.xml
dddd59
@@ -70,6 +70,13 @@
dddd59
     <para>
dddd59
       If no options are given, configuration from <command>/etc/sysconfig/system-config-firewall</command> will be migrated.
dddd59
     </para>
dddd59
+
dddd59
+    <para>
dddd59
+      For sequence options, this are the options that can be specified multiple times, the exit code is 0 if there is at least one item that succeded. The <literal>ALREADY_ENABLED</literal> (11), <literal>NOT_ENABLED</literal> (12) and also <literal>ZONE_ALREADY_SET</literal> (16) errors are treated as succeeded.
dddd59
+      If there are issues while parsing the items, then these are treated as warnings and will not change the result as long as there is a succeeded one.
dddd59
+      Without any succeeded item, the exit code will depend on the error codes. If there is exactly one error code, then this is used. If there are more than one then <literal>UNKNOWN_ERROR</literal> (254) will be used.
dddd59
+    </para>
dddd59
+
dddd59
     <para>
dddd59
       The following options are supported:
dddd59
     </para>
dddd59
diff --git a/doc/xml/firewallctl.xml b/doc/xml/firewallctl.xml
dddd59
index ff99e5d..30c51ec 100644
dddd59
--- a/doc/xml/firewallctl.xml
dddd59
+++ b/doc/xml/firewallctl.xml
dddd59
@@ -67,6 +67,12 @@
dddd59
   <refsect1 id="options">
dddd59
     <title>Options</title>
dddd59
     <para>
dddd59
+      For sequence options, this are the options that can be specified multiple times, the exit code is 0 if there is at least one item that succeded. The <literal>ALREADY_ENABLED</literal> (11), <literal>NOT_ENABLED</literal> (12) and also <literal>ZONE_ALREADY_SET</literal> (16) errors are treated as succeeded.
dddd59
+      If there are issues while parsing the items, then these are treated as warnings and will not change the result as long as there is a succeeded one.
dddd59
+      Without any succeeded item, the exit code will depend on the error codes. If there is exactly one error code, then this is used. If there are more than one then <literal>UNKNOWN_ERROR</literal> (254) will be used.
dddd59
+    </para>
dddd59
+
dddd59
+    <para>
dddd59
       The following options are supported:
dddd59
     </para>
dddd59