URL: https://github.com/freeipa/freeipa/pull/1265
Author: felipevolpone
 Title: #1265: [Backport][ipa-4-6] Warning the user when using a loopback IP as 
forwarder
Action: opened

PR body:
"""
This PR was opened automatically because PR #903 was pushed to master and 
backport to ipa-4-6 is required.
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/1265/head:pr1265
git checkout pr1265
From 8156209aa97b2060349ee9883cbe7b2e316e36d5 Mon Sep 17 00:00:00 2001
From: Felipe Barreto <fbarr...@redhat.com>
Date: Mon, 23 Oct 2017 09:45:56 -0200
Subject: [PATCH] Warning the user when using a loopback IP as forwarder

Changing the --forwarder option to accept a loopback IP.
Previously, an error would be raised, now we just show a
warning message.

Fixes: https://pagure.io/freeipa/issue/5801
---
 install/tools/ipa-dns-install |  2 +-
 ipapython/config.py           | 17 ++++++++++++-----
 ipapython/install/cli.py      |  5 ++++-
 ipapython/ipautil.py          | 19 +++++++++++++++++++
 ipaserver/install/dns.py      |  2 +-
 5 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install
index 6963cb343e..a7f136b16a 100755
--- a/install/tools/ipa-dns-install
+++ b/install/tools/ipa-dns-install
@@ -54,7 +54,7 @@ def parse_options():
                       help="Master Server IP Address. This option can be used "
                            "multiple times")
     parser.add_option("--forwarder", dest="forwarders", action="append",
-                      type="ip", help="Add a DNS forwarder. This option can be used multiple times")
+                      type="ip_with_loopback", help="Add a DNS forwarder. This option can be used multiple times")
     parser.add_option("--no-forwarders", dest="no_forwarders", action="store_true",
                       default=False, help="Do not add any DNS forwarders, use root servers instead")
     parser.add_option("--auto-forwarders", dest="auto_forwarders",
diff --git a/ipapython/config.py b/ipapython/config.py
index 8393e0d5d5..aa4b3e48fe 100644
--- a/ipapython/config.py
+++ b/ipapython/config.py
@@ -23,6 +23,7 @@
 # pylint: enable=deprecated-module
 from copy import copy
 import socket
+import functools
 
 from dns import resolver, rdatatype
 from dns.exception import DNSException
@@ -33,6 +34,7 @@
 # pylint: enable=import-error
 
 from ipapython.dn import DN
+from ipapython.ipautil import CheckedIPAddress, CheckedIPAddressLoopback
 
 try:
     # pylint: disable=ipa-forbidden-import
@@ -65,13 +67,16 @@ def format_usage(self, usage):
             ret += "%s %s\n" % (spacing, line)
         return ret
 
-def check_ip_option(option, opt, value):
-    from ipapython.ipautil import CheckedIPAddress
 
+def check_ip_option(option, opt, value, allow_loopback=False):
     try:
-        return CheckedIPAddress(value)
+        if allow_loopback:
+            return CheckedIPAddressLoopback(value)
+        else:
+            return CheckedIPAddress(value)
     except Exception as e:
-        raise OptionValueError("option %s: invalid IP address %s: %s" % (opt, value, e))
+        raise OptionValueError("option {}: invalid IP address {}: {}"
+                               .format(opt, value, e))
 
 def check_dn_option(option, opt, value):
     try:
@@ -95,9 +100,11 @@ class IPAOption(Option):
     security-sensitive such as passwords.
     """
     ATTRS = Option.ATTRS + ["sensitive", "constructor"]
-    TYPES = Option.TYPES + ("ip", "dn", "constructor")
+    TYPES = Option.TYPES + ("ip", "dn", "constructor", "ip_with_loopback")
     TYPE_CHECKER = copy(Option.TYPE_CHECKER)
     TYPE_CHECKER["ip"] = check_ip_option
+    TYPE_CHECKER["ip_with_loopback"] = functools.partial(check_ip_option,
+                                                         allow_loopback=True)
     TYPE_CHECKER["dn"] = check_dn_option
     TYPE_CHECKER["constructor"] = check_constructor
 
diff --git a/ipapython/install/cli.py b/ipapython/install/cli.py
index 1cac24d50e..e8f67a3de3 100644
--- a/ipapython/install/cli.py
+++ b/ipapython/install/cli.py
@@ -16,7 +16,8 @@
 
 from ipapython import admintool
 from ipapython.ipa_log_manager import standard_logging_setup
-from ipapython.ipautil import CheckedIPAddress, private_ccache
+from ipapython.ipautil import (CheckedIPAddress, CheckedIPAddressLoopback,
+                               private_ccache)
 
 from . import core, common
 
@@ -166,6 +167,8 @@ def add_options(cls, parser, positional=False):
                 kwargs['type'] = 'int'
             elif knob_scalar_type is long:
                 kwargs['type'] = 'long'
+            elif knob_scalar_type is CheckedIPAddressLoopback:
+                kwargs['type'] = 'ip_with_loopback'
             elif knob_scalar_type is CheckedIPAddress:
                 kwargs['type'] = 'ip'
             elif issubclass(knob_scalar_type, enum.Enum):
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 71ed4a1747..c4149a184d 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -244,6 +244,25 @@ def set_ip_net(self, ifnet):
         self._net = ifnet
 
 
+class CheckedIPAddressLoopback(CheckedIPAddress):
+    """IPv4 or IPv6 address with additional constraints with
+    possibility to use a loopback IP.
+    Reserved or link-local addresses are never accepted.
+    """
+    def __init__(self, addr, parse_netmask=True, allow_multicast=False):
+
+        super(CheckedIPAddressLoopback, self).__init__(
+                addr, parse_netmask=parse_netmask,
+                allow_multicast=allow_multicast,
+                allow_loopback=True)
+
+        if self.is_loopback():
+            # print is being used instead of a logger, because at this
+            # moment, in execution process, there is no logger configured
+            print("WARNING: You are using a loopback IP: {}".format(addr),
+                  file=sys.stderr)
+
+
 def valid_ip(addr):
     return netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
 
diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
index 119aae1369..e14b353e9c 100644
--- a/ipaserver/install/dns.py
+++ b/ipaserver/install/dns.py
@@ -491,7 +491,7 @@ def zonemgr(self, value):
 
     forwarders = knob(
         # pylint: disable=invalid-sequence-index
-        typing.List[ipautil.CheckedIPAddress], None,
+        typing.List[ipautil.CheckedIPAddressLoopback], None,
         description=("Add a DNS forwarder. This option can be used multiple "
                      "times"),
         cli_names='--forwarder',
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org

Reply via email to