Subject: check for rcvar can fail incorrectly
To: None <tech-userlevel@netbsd.org>
From: Pavel Cahyna <pcah8322@artax.karlin.mff.cuni.cz>
List: tech-userlevel
Date: 03/17/2003 13:59:27
[ please Cc: me on replies, I'm not subscribed to tech-userlevel ]

Hello,

I had a problem with ipfilter/ipnat on boot which showed up to be a
problem of rc scripts.

In /etc/rc.d/ipnat, a check for ipfilter variable is performed:
	if ! checkyesno ipfilter || [ ! -f /etc/ipf.conf ]; then
                logger -s -p daemon.warning -t ipnat \
                        "Enabling ipfilter for NAT."
                /sbin/ipf -E -Fa
        fi


I have ipfilter turned on, as I use both ipfilter and ipnat. So
checkyesno should succeed and the code between if and fi should not be
executed.

But, the ipfilter variable is not set in /etc/rc.conf , but in
/etc/rc.conf.d/ipfilter . (I believe this is perfectly legal, according
to rc.conf(5).) 

As the ipnat script doesn't take the variables from
/etc/rc.conf.d/ipfilter , but only from /etc/rc.conf and
/etc/rc.conf.d/ipnat . So the script will incorrectly think that the
variable is not set, and the ipfilter rules are flushed.

Similar problem affects e.g. /etc/rc.d/nfsd, because it checks for
mountd and rpcbind, but will ignore them if they are set in
/etc/rc.conf.d/{mountd,rpcbind} and not in /etc/rc.conf .

IMHO the rc system should not break in this way when variables are set
in /etc/rc.conf.d/. If it does, the whole /etc/rc.conf.d/ becomes
useless, if not harmful.

I believe the fix is simple. Add the line 
load_rc_config ipfilter

to /etc/rc.d/ipnat . And the same should be done for all the rc scripts
which check "foreign" rc variables.

For example:
nfslocking checks for nfs_server, which can be set in /etc/rc.conf.d/nfsd

network checks for dhclient, which can be set in .../dhclient.

amd, yppasswd, ypserv, nfsd checks for rpcbind, which can be set in
.../rpcbind.

nfsd checks for mountd, which can be set in .../mountd.

yppasswd checks for ypserv, which can be set in .../ypserv.

(those examples were found by running "grep required_vars *" and "grep
checkyesno *" in /etc/rc.d .)

Bye	Pavel