ACC SHELL

Path : /etc/sysconfig/network/scripts/
File Upload :
Current File : //etc/sysconfig/network/scripts/convert_to_netconfig_dns

#!/bin/bash
#
# Exit codes:
# - 0 success
# - 1 on failure
###

unset POSIXLY_CORRECT ; set +o posix # we're using non-posix bash features

test "${DEBUG}" = yes && set -x

# helper functions
failure()
{
	test -n "$*" && echo 1>&2 "FAILURE: $*"
}
warning()
{
	test -n "$*" && echo 1>&2 "WARNING: $*"
}
message()
{
	test -n "$*" && echo 1>&2 "$*"
}
verbose()
{
	test "${VERBOSE}" = yes -a -n "$*" && echo 1>&2 "$*"
}

add_to_wordlist() {
	local v="${1}"
	local l=(${!v}) ; shift
	local a w
	for a in ${@} ; do
		for w in ${l[@]} ; do
			[ "x$w" = "x$a" ] && \
			continue 2
		done
		l=(${l[@]} $a)
	done
	eval "$v='${l[@]}'"
}

try_to_find_original()
{
	local filename="$1"
	local root_dir="$2"

	local original="$filename"
	local backups=()
	local backup=""

	# we use direct/valid backups only
	while test -n "$original" -a -r "${root_dir}${original}" ; do
		backup=`sed -ne '/^### BEGIN INFO/,/^### END INFO/{
			s/^[[:space:]]*[#][[:space:]]*Backup:[[:space:]]*//p
			}' "${root_dir}${original}" | \
			sed -ne 's/[[:space:]]*$//p' 2>/dev/null`
		test -n "$backup" || break
		for f in "$original" "$filename" "${backups[@]}" ; do
			test "$f" = "$backup" && { original=""; break 2; }
		done
		if test -r "${root_dir}${backup}" ; then
			backups=("${backups[@]}" "$backup")
			original="$backup"
		else
			original=""
		fi
	done

	echo "$original"
	test -n "$original"
}

has_networkmanager_info()
{
	test -n "$1" -a -f "$1" && grep -qs '^# generated by NetworkManager' "$1" 2>/dev/null
}

has_netconfig_info()
{
	test -n "$1" -a -f "$1" && grep -qs '^### .* netconfig' "$1" 2>/dev/null
}

fake_netconfig_md5()
{
	src=$1
	dir=$2
	pfx=$3
	md5="${pfx}${dir}${src}"
	test -n "$dir" -a -n "$src" -a -r "${pfx}${src}" || return 1
	mkdir -p "${md5%/*}" 2>/dev/null                 || return 2
	rm -f "${md5}"       2>/dev/null                 || return 3
	grep -Ev '^#|^[[:space:]]*$' "${pfx}${src}" | md5sum > "${md5}" 2>/dev/null
}

contains_old_variables()
{
	test -n "$1" && \
	grep -qs "^[[:space:]]*\(\
MODIFY_NAMED_CONF_DYNAMICALLY\|\
MODIFY_RESOLV_CONF_DYNAMICALLY\|\
MODIFY_RESOLV_CONF_STATIC_DNS\|\
DHCLIENT_MODIFY_RESOLV_CONF\|\
DHCLIENT_KEEP_SEARCHLIST\)=" "${1}" 2>/dev/null
}

has_modify_resolvconf_info()
{
	test -n "$1" -a -f "$1" && grep -qs '^### BEGIN INFO' "$1" 2>/dev/null
}

remove_modify_resolvconf_info()
{
	has_modify_resolvconf_info "$1" && \
	sed -e '/^### BEGIN INFO/,/^### END INFO/d;/^[[:space:]]*$/d' -i "$1"
}

delete_modify_resolvconf_backups()
{
	local filename=$1

	# remove all modify_resolvconf backup files
	out=`LC_ALL=POSIX rm -vf "${filename}.saved.by"*`
	if test "x$out" != x ; then
		message "Deleted following modify_resolvconf backup files:"
		message "$out"
	fi
}

create_backup()
{
	filename=$1
	b_suffix=$2
	root_dir=$3

	test -s "${root_dir}${filename}" && \
	cp -p --backup=t "${root_dir}${filename}" "${root_dir}${filename}${b_suffix}" && \
	message "Created ${filename}${b_suffix}"
}
create_backup_once()
{
	test -f "${3}${1}${2}" || create_backup "$1" "$2" "$3"
}

is_localhost_ip()
{
	case $1 in
	(127\.*\.*\.*|::1) return 0 ;;
	(*)                return 1 ;;
	esac
}

################################################################################
SCRIPTNAME=${0##*/}

# act bellow of this "root" directory
test "${ROOT}" = "/" && unset ROOT
r=${ROOT}

# source sysconfig_remove_and_set()
test -f "$ROOT/etc/sysconfig/network/scripts/functions.rpm-utils" && \
      . "$ROOT/etc/sysconfig/network/scripts/functions.rpm-utils" || exit 1

# the files modified by modify_resolvconf
network_config="/etc/sysconfig/network/config"
network_ifcfgs="/etc/sysconfig/network/ifcfg"
network_dhcp="/etc/sysconfig/network/dhcp"
resolver_conf="/etc/resolv.conf"
forwarder_dir="/etc/named.d"
forwarder_conf="${forwarder_dir}/forwarders.conf"
forwarder_script="/etc/init.d/named"

# backup files we create
backup_suffix=".backup.by.convert_to_netconfig"
netconfig_md5="/var/adm/netconfig/md5"

# internal flags
update_netconfig_settings=yes
resolver_conf_localhost_ns=no
resolver_conf_otherhost_ns=no

# set netconfig defaults
NETCONFIG_DNS_POLICY='auto'
NETCONFIG_DNS_FORWARDER='resolver'
NETCONFIG_DNS_STATIC_SERVERS=''
NETCONFIG_DNS_STATIC_SEARCHLIST=''

# modify_resolvconf variables
MODIFY_NAMED_CONF_DYNAMICALLY='no'
MODIFY_RESOLV_CONF_DYNAMICALLY='no'
MODIFY_RESOLV_CONF_STATIC_DNS=''

#
# check if there is netconfig and its variables
#
test -x "${r}/sbin/netconfig" -a \
$((`grep -c "^[[:space:]]*\(\
NETCONFIG_DNS_POLICY\|\
NETCONFIG_DNS_FORWARDER\|\
NETCONFIG_DNS_STATIC_SERVERS\|\
NETCONFIG_DNS_STATIC_SEARCHLIST\)=" \
"${r}${network_config}" 2>/dev/null`)) -eq 4 || {
	failure "Unable to find netconfig and its sysconfig variables"
	exit 1
}
#
# check if there are conversion backups
#
test -f "${r}${resolver_conf}${backup_suffix}"  -o \
     -f "${r}${forwarder_conf}${backup_suffix}" && {
	verbose "$SCRIPTNAME backup files exists - done"
	exit 0
}

#
# check if there are modify_resolvconf variables
#
contains_old_variables "${r}${network_config}" || \
contains_old_variables "${r}${network_dhcp}"   || {
	verbose "Unable to find modify_resolvconf or its sysconfig variables"
	verbose "Disabled conversion to netconfig (cleanup backups only)"
	update_netconfig_settings=no
}

#
# OK, read current settings
#
eval `grep "^[[:space:]]*\(\
NETWORKMANAGER\|\
NETCONFIG_DNS_POLICY\|\
NETCONFIG_DNS_FORWARDER\|\
NETCONFIG_DNS_STATIC_SERVERS\|\
NETCONFIG_DNS_STATIC_SEARCHLIST\|\
MODIFY_NAMED_CONF_DYNAMICALLY\|\
MODIFY_RESOLV_CONF_DYNAMICALLY\|\
MODIFY_RESOLV_CONF_STATIC_DNS\
\)=" "${r}${network_config}" 2>/dev/null`
_MODIFY_NAMED_CONF_DYNAMICALLY=$MODIFY_NAMED_CONF_DYNAMICALLY
_MODIFY_RESOLV_CONF_DYNAMICALLY=$MODIFY_RESOLV_CONF_DYNAMICALLY

#
# check if have netconfig default settings
#
test "x$NETCONFIG_DNS_POLICY" = xauto        -a \
     "x$NETCONFIG_DNS_FORWARDER" = xresolver -a \
     "x$NETCONFIG_DNS_STATIC_SERVERS" = x    -a \
     "x$NETCONFIG_DNS_STATIC_SEARCHLIST" = x || {
	verbose "Modified netconfig DNS settings found - disabled conversion"
	update_netconfig_settings=no
}

if test "$update_netconfig_settings" = yes ; then
	# just use the old static servers except of localhost ip's ...
	for ns in $MODIFY_RESOLV_CONF_STATIC_DNS ; do
		is_localhost_ip $ns && continue
	 	add_to_wordlist NETCONFIG_DNS_STATIC_SERVERS $ns
	done

	# disable netconfig dns updates when modify was disabled
	if test "$_MODIFY_NAMED_CONF_DYNAMICALLY"  != yes -a \
	        "$_MODIFY_RESOLV_CONF_DYNAMICALLY" != yes -a \
		"$NETWORKMANAGER"                  != yes ;
	then
		# disable netconfig dns updates
		NETCONFIG_DNS_POLICY=''
	fi
	# make sure, only one of the modify variables is set
	if test "$_MODIFY_NAMED_CONF_DYNAMICALLY" = yes ; then
		# modify_resolvconf prefers to use named...
		_MODIFY_RESOLV_CONF_DYNAMICALLY=no
	fi
fi


#
# === resolv.conf ===
#
dns_domains=()
dns_servers=()

original=`try_to_find_original "${resolver_conf}" "${r}"`
# when "original" (that is valid backup or the file itself) exists,
# remove the info block, import the settings from the original and
# fake the current file as a netconfig generated one...
# don't remove the file, because it may be in a running system...
if test -n "$original" -a -r "${r}$original" ; then

	if has_networkmanager_info "${r}${resolver_conf}" ; then

		# just enable for netconfig when created by NM
		create_backup_once "$resolver_conf" "$backup_suffix" "$r" && \
		fake_netconfig_md5 "$resolver_conf" "$netconfig_md5" "$r" && {
			message "Enabled $resolver_conf for use with netconfig"
		}

	elif ! has_netconfig_info "${r}${resolver_conf}" && \
	     test "$update_netconfig_settings" = yes ;
	then

		remove_modify_resolvconf_info "${r}${resolver_conf}"

		# we need the search list in forwarder mode too...
		if test -r "${r}$original" ; then
			while read -rs key val rest ; do
				case $key in
				(domain|search)
					# take the last one defined
					dns_domains=($val)
				;;
				(nameserver)
					# collect all except localhost
					if is_localhost_ip $val ; then
						resolver_conf_localhost_ns=yes
					else
						resolver_conf_otherhost_ns=yes
						dns_servers=(${dns_servers[@]} $val)
					fi
				;;
				esac
			done < <(grep -Ev '^[[:space:]]*(#.*)?$' "${r}$original")
		fi

		# OK, apply to netconfig variables & remove
		if test "$_MODIFY_RESOLV_CONF_DYNAMICALLY" = yes ; then

			add_to_wordlist NETCONFIG_DNS_STATIC_SERVERS    \
					${dns_servers[@]}
			add_to_wordlist NETCONFIG_DNS_STATIC_SEARCHLIST \
					${dns_domains[@]}

			# create backup and fake as a netconfig file
			create_backup_once "$resolver_conf" "$backup_suffix" "$r" && \
			fake_netconfig_md5 "$resolver_conf" "$netconfig_md5" "$r" && {
				message "Enabled $resolver_conf for use with netconfig"
			}
		fi
	fi
else
	# remove info block also if it does not point to valid backup
	remove_modify_resolvconf_info "${r}${resolver_conf}"
fi
# finally, delete the modify_resolvconf backups
delete_modify_resolvconf_backups "${r}${resolver_conf}"

# (re)create empty resolv.conf if missed
test -e "${r}$resolver_conf" || \
touch      "${r}$resolver_conf"
chmod 0644 "${r}$resolver_conf"


#
# === forwarders.conf ===
#
original=`try_to_find_original "$forwarder_conf" "${r}"`
# when "original" (that is valid backup or the file itself) exists,
# remove the info block, import the settings from the original and
# fake the current file as a netconfig generated one...
# don't remove the file, because it may be in a running system...
if test -n "$original" -a -r "$original" ; then

	if ! has_netconfig_info "${r}${forwarder_conf}" && \
	   test "$update_netconfig_settings" = yes ; then

		remove_modify_resolvconf_info "${r}${forwarder_conf}"

		if test "$NETWORKMANAGER" != yes -a \
		        "$_MODIFY_NAMED_CONF_DYNAMICALLY" = yes ;
		then
			# first, read the forwarders
			dns_servers=(`
				test -f "${r}${original}" && \
				sed -e '/^### BEGIN INFO/,/^### END INFO/d' \
				    -e 's/[[:space:]]*#.*$//g;/^[[:space:]]*$/d' \
				    -e '/^[[:space:]]*forwarders/{
					h
					:a
					s-/\*.*\*/--g
					s-#.*$--
					s-//.*$--
					s-[[:space:]\n]\+- -g
					/} *; *$/bb
					N
					ba
					:b
					x
					s-for.*$--
					G
					s-\n --
					s- ;-;-g
					}' \
				   -ne '/^[[:space:]]*forwarders/{
					s-[^0-9:. ]*--g
					p
					}' \
				    "${r}${original}"
			`)

			# modify_resolvconf didn't touched the resolv.conf in "bind" mode.
			#
			# netconfig writes the domain search list without nameserver to the
			# resolv.conf and the static nameservers as forwarder, that is it
			# configures the local dns server as forwarder for the system
			# (glibc makes use of a local ns when no ns in resolv.conf set).
			# Other scenarios need custom netconfig setup (e.g. -dns-resolver
			# in the netconfig module list).

			# apply forwarders & search list to netconfig
			for ns in ${dns_servers[@]} ; do
				is_localhost_ip "$ns" && continue
				add_to_wordlist NETCONFIG_DNS_STATIC_SERVERS $ns
			done
			add_to_wordlist NETCONFIG_DNS_STATIC_SEARCHLIST \
					${dns_domains[@]}

			# enable bind as forwarder only when it is installed
			if test ! -x "${r}${forwarder_script}" ; then
				warning "The bind ($forwarder_script) nameserver seems to be not installed"
				warning "Skipped to enable it as forwarder in netconfig. To enable it:"
				warning "Install bind package, set NETCONFIG_DNS_FORWARDER='bind' variable"
				warning "manually, verify other netconfig dns settings, remove the current"
				warning "$forwarder_conf file and call 'netconfig update -v'"
			else
				# we need either no ns in resolv.conf or localhost IP
				if test "$resolver_conf_localhost_ns" = no -a \
					"$resolver_conf_otherhost_ns" = no ; then
					resolver_conf_localhost_ns=yes
				fi
				if test "$resolver_conf_localhost_ns" = yes ; then
					NETCONFIG_DNS_FORWARDER='bind'
					message "Enabled bind as dns forwarder in netconfig"

					if test "$resolver_conf_otherhost_ns" != yes ; then
						has_netconfig_info "${r}${resolver_conf}" || {
							# reset resolv.conf -- it contains no or local ns only
							create_backup_once "$resolver_conf" "$backup_suffix" "$r" && {
								remove_modify_resolvconf_info "${r}${resolver_conf}"
								fake_netconfig_md5 "$resolver_conf" "$netconfig_md5" "$r" && {
									message "Enabled $resolver_conf for use with netconfig"
								}
							}
						}
						touch      "${r}${resolver_conf}"
						chmod 0644 "${r}${resolver_conf}"
					fi
				fi

				# here, just to write them in a nice order...
				if test "$resolver_conf_otherhost_ns" = yes ; then
					warning "Please verify $resolver_conf and netconfig settings"'!'
					warning "Your resolv.conf seems to require disabling of the dns-resolver module"
				fi
				if test "$resolver_conf_localhost_ns" != yes ; then
					warning "See the NETCONFIG_MODULES_ORDER variable and netconfig(8) manual page"
					warning "and set NETCONFIG_DNS_FORWARDER='bind' manually to enable as forwarder"
				fi

				# create backup and reset the forwarders.conf
				create_backup_once "$forwarder_conf" "$backup_suffix" "$r" && {
					fake_netconfig_md5 "$forwarder_conf" "$netconfig_md5" "$r" && {
						message "Enabling $forwarder_conf for use with netconfig"
					}
				}
				touch      "${r}$forwarder_conf"
				chmod 0644 "${r}$forwarder_conf"
			fi
		fi
	fi
else
	# remove info block also if it does not point to valid backup
	remove_modify_resolvconf_info "${r}${forwarder_conf}"
fi
delete_modify_resolvconf_backups "${r}${forwarder_conf}"


if test "$update_netconfig_settings" = yes ; then
	# ok, test if we have some changes, create backup and change it
	if test "x$NETCONFIG_DNS_POLICY"            = xauto     -a \
	        "x$NETCONFIG_DNS_FORWARDER"         = xresolver -a \
	        "x$NETCONFIG_DNS_STATIC_SERVERS"    = x         -a \
	        "x$NETCONFIG_DNS_STATIC_SEARCHLIST" = x ;
	then
		verbose "No changes to netconfig settings necessary"
	else
		create_backup_once "$network_config" "$backup_suffix" "$r" && {
			verbose "Converting DNS settings to netconfig:"
			for v in NETCONFIG_DNS_POLICY \
				 NETCONFIG_DNS_FORWARDER \
				 NETCONFIG_DNS_STATIC_SERVERS \
				 NETCONFIG_DNS_STATIC_SEARCHLIST ;
			do
				verbose "${v}='${!v}'"
			 	sed -e "s/^[[:space:]]*\(${v}\)=.*/\1='${!v}'/g" \
				    -i "${r}${network_config}" || break
			done
			message "DNS settings to netconfig conversion... done"
		}
	fi
fi

# collect a list of interface with old variables
clear_ifaces=()
for ifcfg in "${r}${network_ifcfgs}-"* ; do
	ifname="${ifcfg##*\/ifcfg-}"
	case $ifname in
	(lo|""|*" "*|*~|*.old|*.rpmnew|*.rpmsave|*.scpmbackup) continue ;;
	esac
	# remember where to remove the variables later...
	contains_old_variables "${r}${network_ifcfgs}-${ifname}" && \
	clear_ifaces=("${clear_ifaces[@]}" "${ifname}")
done

msg="Removing obsolete DNS variables (config, dhcp, ifcfg-<${clear_ifaces[@]}> files)"
contains_old_variables "${r}${network_config}" && {
	test -n "$msg" && message "$msg" ; msg=""
	create_backup_once "$network_config" "$backup_suffix" "$r" && {
		# remove also misrouted dhcp variables from config
		sysconfig_remove_and_set -b ""	\
		"${r}${network_config}"		\
		MODIFY_NAMED_CONF_DYNAMICALLY	\
		MODIFY_RESOLV_CONF_DYNAMICALLY	\
		MODIFY_RESOLV_CONF_STATIC_DNS	\
		DHCLIENT_MODIFY_RESOLV_CONF     \
		DHCLIENT_KEEP_SEARCHLIST
	}
}
contains_old_variables "${r}${network_dhcp}"   && {
	test -n "$msg" && message "$msg" ; msg=""
	create_backup_once "$network_dhcp" "$backup_suffix" "$r" && {
		# remove also misrouted config variables from dhcp
		sysconfig_remove_and_set -b ""	\
		"${r}${network_dhcp}"		\
		MODIFY_NAMED_CONF_DYNAMICALLY	\
		MODIFY_RESOLV_CONF_DYNAMICALLY	\
		MODIFY_RESOLV_CONF_STATIC_DNS	\
		DHCLIENT_MODIFY_RESOLV_CONF     \
		DHCLIENT_KEEP_SEARCHLIST
	}
}
for ifname in "${clear_ifaces[@]}" ; do
	test -n "$msg" && message "$msg" ; msg=""
	if test -f "${r}${network_ifcfgs}-${ifname}" ; then
		test -f "${r}${network_ifcfgs}.${ifname}${backup_suffix}" || {
			cp -p --backup=t "${r}${network_ifcfgs}-${ifname}" \
			"${r}${network_ifcfgs}.${ifname}${backup_suffix}" || continue
		}
		sed -e '/^[[:space:]]*MODIFY_NAMED_CONF_DYNAMICALLY=/d'	\
		    -e '/^[[:space:]]*MODIFY_RESOLV_CONF_DYNAMICALLY=/d'\
		    -e '/^[[:space:]]*MODIFY_RESOLV_CONF_STATIC_DNS=/d'	\
		    -e '/^[[:space:]]*DHCLIENT_MODIFY_RESOLV_CONF=/d'	\
		    -e '/^[[:space:]]*DHCLIENT_KEEP_SEARCHLIST=/d'	\
		    -i "${r}${network_ifcfgs}-${ifname}"
	fi
done

exit 0


ACC SHELL 2018