# Copyright (C) 1999, 2000, 2003 Jay Beale
# Copyright (C) 2001, 2002 Hewlett Packard
# Licensed under the GNU General Public License

package Bastille::MiscellaneousDaemons;
use lib "/usr/lib";

use Bastille::API;
use Bastille::TestAPI;

@ENV="";
$ENV{PATH}="";
$ENV{CDPATH}=".";
$ENV{BASH_ENV}="";



#######################################################################
##                          Miscellaneous Daemons                    ##
#######################################################################

# Deactivate ?standard? services chosen at install, at admin's option.
# Explain why they might want to turn this stuff off.  Remember, most
# newbies will take the, "I don't want to break anything -- turn it all on!"
# approach.  Let's deactivate apmd, portmap, pcmcia, nfs, netfs, smb, 
# dhcpd, amd, gpm, innd, linuxconf, if possible.

&DeactivateAPMD;
&DeactivateRemoteFS;
&DeactivatePCMCIA;
&DeactivateDHCP;
&DeactivateGPM;
&DeactivateINND;
&DeactivateAllChkconfig;
&DeactivatePTY;
&DeactivatePwgrd;
&DeactivateRbootd;
&DeactivateKudzu;
&DeactivateHPOJ;
&DeactivateISDN;
&DeactivateBluetooth;


&RestrictRendezvous;
&RestrictAutoDiskMount;
&RestrictNTPD;

# Restricting access for the dtlogin, diagmond, and syslog daemons to the local machine.
&RestrictXaccess;
&RestrictDiagnostics;
&RestrictSyslog;


# If we are running SuSE7.x, we also write to rc.config so that changes are unaltered
# upon reboot of the system. Otherwise, rc.config would overwrite these changes.

#
# Disable non-standard services, which may have been badly chosen at install:
#
# Possibly disable arpwatch, autofs, bootparamd, gated, mars-nwe, mcserv,
# postgresql, routed, rstatd, rusersd, rwalld, rwhod, snmpd, squid, xntpd, 
# ypbind, yppasswdd, ypserv

#
#### WHICH ONES SHOULD WE DISABLE?
#

&DeactivateRoutingDaemons;
&DeactivateNIS;
&DeactivateSNMPD;


sub DeactivateAPMD {

    if (&getGlobalConfig("MiscellaneousDaemons","apmd") eq "Y") {
        &B_log("DEBUG","# sub DeactivateAPMD\n");

	# Deactivate both apmd and its newer ACPI counterpart acpid. 
        &B_chkconfig_off ("apmd");
	&B_chkconfig_off ("acpid");

	if (&GetDistro =~ "^SE" and -e &getGlobal('FILE',"rc.config")) {
	    &B_replace_line(&getGlobal('FILE',"rc.config"),'^START_APMD=','START_APMD="no"\n');
	}
}
}

sub DeactivateRemoteFS {

    if (&getGlobalConfig("MiscellaneousDaemons","remotefs") eq "Y") {
	&B_log("DEBUG","# sub DeactivateRemoteFS\n");

        # For now, we break NFS/SAMBA.  Does someone want to make a "secure?" NFS
        # configuration?  Should we allow samba? Can we use samba without the 
        # automounter? Are they safe when we don't know if the admin has a firewall?
	# question: should we remove the symbolic links for netfs, which
	# mounts external net-based drives?

	# Turn off the portmapper -- it's only used by NIS and NFS on Linux. 
        &B_chkconfig_off ("portmap");
	# Turn off NFS server daemon
        &B_chkconfig_off ("nfs");
	# Deactivate server-and-client-side NFSv4 idmapd on Linux
        &B_chkconfig_off ("rpcidmapd");
	# Deactivate client-side NFSv4 script
	&B_chkconfig_off ("rpcgssd");
	# Deactivate client-side NFS script
	&B_chkconfig_off ("nfslock");
        &B_chkconfig_off ("smb");
	# Deactivate the remote-filesystem (client-side) mounting script
	&B_chkconfig_off ("netfs");
	# Disable the NFS automounter
        &B_chkconfig_off ("amd");

	# Deactivate the network automounting without deactivating local CD-ROM mounting
	# in recent Linux distributions (RHFC4).
	if ( -e '/etc/auto.master') {
	    &B_hash_comment_line('/etc/auto.master','^\\s*\/net\\s+\/etc\/auto\.net');
	}
    
	if (&GetDistro =~ "^SE7" and -e &getGlobal('FILE',"rc.config")) {
	    &B_replace_line(&getGlobal('FILE',"rc.config"),'^START_PORTMAP','START_PORTMAP="no"\n');
	    &B_replace_line(&getGlobal('FILE',"rc.config"),'^NFS_SERVER','NFS_SERVER="no"\n');
	    &B_replace_line(&getGlobal('FILE',"rc.config"),'^START_SMB','START_SMB="no"\n');
	}

	if ( defined(&getGlobal('FILE', "inetd.conf") ) ) {
	   my $inetd_conf = &getGlobal('FILE', "inetd.conf");
	   if ( -e $inetd_conf ) { 	
	      &B_hash_comment_line($inetd_conf,"nfs");
	   }
	}

    }

    if (&getGlobalConfig("MiscellaneousDaemons","nfs_server") eq "Y") {
	&B_log("DEBUG","# sub DeactivateRemoteFS\n");

	if (&GetDistro =~ "^HP-UX") {
            # Kill off process and change permanant start-up behavior
            &B_ch_rc ("NFS_SERVER", &getGlobal('FILE', 'chkconfig_nfs_server'));
	}
	elsif (&GetDistro =~ '^OSX') {
	    # NFS is deactivated on OSX simply by making sure there are no exported
	    # filesystems.
	    &B_hash_comment_line('/etc/exports','^\s*[^\#]+');
	}

    }


    if (&getGlobalConfig("MiscellaneousDaemons","nfs_client") eq "Y") {
	&B_log("DEBUG","# sub DeactivateRemoteFS\n");

	if ( &GetDistro =~ "^HP-UX") {
            # Kill off process and change permanent start-up behavior
            &B_ch_rc ('NFS_CLIENT',&getGlobal('FILE', 'chkconfig_nfs_client'));
	}
	elsif (&GetDistro =~ '^OSX') {
	    # You can't deactivate NFS client daemon (nfsiod) separately without 
	    # deactivating the network, unless you're willing to modify the NFS
	    # script.  Right!

	    &B_hash_comment_line(&getGlobal('FILE','NFS'),'^\s*nfsiod\b');

	    # We also deactivate the automounter here, which is done via /etc/hostconfig.
	    
	    # JJB: Replace the line below with an abstraction, after talking with
	    #      Keith Buck.
	    &B_replace_line(&getGlobal('FILE','hostconfig'),'^AUTOMOUNT\=\-YES\-',"AUTOMOUNT=-NO-\n");
	}
    }


}


sub DeactivatePCMCIA {
 
    # If this isn't a notebook, strongly recommend disabling PCMCIA.
    if (&getGlobalConfig("MiscellaneousDaemons","pcmcia") eq "Y") {
    &B_log("DEBUG","# sub DeactivatePCMCI\n");
 
        &B_chkconfig_off ("pcmcia");
    if (&GetDistro =~ "^SE" and -e &getGlobal('FILE',"rc.config")) { 
	&B_replace_line(&getGlobal('FILE',"rc.config"),'^START_PCMCIA','START_PCMCIA="no"\n');
   }
}
}

sub DeactivateDHCP {
 
    # If this is # If this is not a DHCP server, we deactivate dhcpd.
 
    if (&getGlobalConfig("MiscellaneousDaemons","dhcpd") eq "Y") {
        &B_log("DEBUG","# sub DeactivateDHCP\n");
 
        &B_chkconfig_off ("dhcpd");
    if (&GetDistro =~ "^SE" and -e &getGlobal('FILE',"rc.config")) {
        &B_replace_line(&getGlobal('FILE',"rc.config"),'^IFCONFIG_0="dhcpclient"','IFCONFIG_0=""\n');
    }
}
}

sub DeactivateGPM {
 
    if (&getGlobalConfig("MiscellaneousDaemons","gpm") eq "Y") {
        &B_log("DEBUG","# sub DeactivateGPM\n");
 
        &B_chkconfig_off ("gpm");
    if (&GetDistro =~ "^SE" and -e &getGlobal('FILE',"rc.config")) {
        &B_replace_line(&getGlobal('FILE',"rc.config"),'^START_GPM="yes"','START_GPM="no"\n');
	&B_log("DEBUG","# this is where GPM should be edited in rc.config\n");
    }
}
}

sub DeactivateINND {

    # Deactivate innd unless they really need a new server.
	
    if (&getGlobalConfig("MiscellaneousDaemons","innd") eq "Y" ) {
	&B_log("DEBUG","# sub DeactivateINND\n");
	
	&B_chkconfig_off ("innd");
   }
    
}


sub DeactivateRoutingDaemons {

    # Disable gated if they're not running a router...  Otherwise, disable 
    # either gated or routed.
    
    &B_log("DEBUG","# sub DeactivateRoutingDaemons\n");

    if (&getGlobalConfig("MiscellaneousDaemons","disable_routed") eq "Y") {
	&B_chkconfig_off ("routed");
    }
    if (&getGlobalConfig("MiscellaneousDaemons","disable_gated") eq "Y") {
	&B_chkconfig_off ("gated");
    }

}


sub DeactivateNIS {

    &B_log("DEBUG","# sub DeactivateNIS\n");

    # NIS Server section
    if (&getGlobalConfig("MiscellaneousDaemons","nis_server") eq "Y") {
	&B_log("DEBUG","# deactivating NIS server\n");
	if ( &GetDistro =~ "^HP-UX") {
	    &B_ch_rc ('NIS_MASTER_SERVER',&getGlobal('FILE', 'chkconfig_nis_server'));
	    &B_ch_rc ('NIS_SLAVE_SERVER',&getGlobal('FILE', 'chkconfig_nis_server'));
	}
	else {
	    &B_chkconfig_off ("ypserv");
	    &B_chkconfig_off ("yppasswdd");
	}

    }


    # NIS Client Section
    if (&getGlobalConfig("MiscellaneousDaemons","nis_client") eq "Y") {
	&B_log("DEBUG","# deactivating NIS client\n");
	if ( &GetDistro =~ "^HP-UX") {
            &B_set_rc('NIS_DOMAIN',"");
	    &B_ch_rc ('NIS_CLIENT',&getGlobal('FILE', 'chkconfig_nis_client'));

	    # nsswitch.conf is used by several programs to determine how to resolve
	    # system unknowns.  e.g. the hosts entry of this file is used by nslookup
	    # to resolve network host names.
	    my $nsswitch = &getGlobal('FILE',"nsswitch.conf");

	    # The system defaults may use nis, in this case Bastille will
	    # create a reasonable default that depends on the system files and dns
	    if( ! -f $nsswitch ) {
		&B_create_file($nsswitch);
                # we don't need to revert the permissions change because we just
                # created the file
                chmod(0444, $nsswitch);
	    }


	    &B_append_line($nsswitch,'\s*passwd:', "passwd:       files\n");
	    &B_append_line($nsswitch,'\s*group:', "group:        files\n");
	    &B_append_line($nsswitch,'\s*hosts:', "hosts:        files dns\n");
	    &B_append_line($nsswitch,'\s*networks:', "networks:     files\n");
	    &B_append_line($nsswitch,'\s*protocols:', "protocols:    files\n");
	    &B_append_line($nsswitch,'\s*rpc:', "rpc:          files\n");
	    &B_append_line($nsswitch,'\s*publickey:', "publickey:    files\n"); 
	    &B_append_line($nsswitch,'\s*netgroup:', "netgroup:     files\n");
	    &B_append_line($nsswitch,'\s*automount:', "automount:    files\n");
	    &B_append_line($nsswitch,'\s*aliases:', "aliases:      files\n");
	    &B_append_line($nsswitch,'\s*services:', "services:     files\n");
	    
	    # if an nsswitch.conf file was using nis to resolve unknowns then
	    # changes need to be made to this file in order to ensure that
	    # the new system configuration is acknowledged by the nsswitch.conf file.
	    if( &B_match_line($nsswitch,'.+:\s+.*nis|.+:\s+.*compat') ) {
		&B_TODO("\n" .
			"------------------------------------\n" .
			"Deactivating NIS client programs:\n" .
			"------------------------------------\n" .
			"Bastille has detected nis entries in the following file:\n" .
			"$nsswitch\n" . 
			"To remain internally consistent please remove all references\n" .
                        "to 'nis' or 'compat' from the file.\n");
	    }
	    
	    
	}
	else {
	    &B_chkconfig_off ("ypbind");
	}

	if (&GetDistro =~ "^SE" and -e &getGlobal('FILE',"rc.config")) {
	    &B_replace_line(&getGlobal('FILE',"rc.config"),'^START_YPBIND=','START_YPBIND="no"\n');
	}
    }


}

sub DeactivateSNMPD {

    # SNMP is rather insecure.  If you need proof, go read the Phrack
    # article or read a bit about the protocol...
    
    if (&getGlobalConfig("MiscellaneousDaemons","snmpd") eq "Y") {
	&B_log("DEBUG","# sub DeactivateSNMPD\n");
	unless ( &GetDistro =~ "^HP-UX") {
	    &B_chkconfig_off ("snmpd");
	}
	else {
	    &B_ch_rc ('SNMP_HPUNIX_START',&getGlobal('FILE', 'chkconfig_snmpd_HP'));
	    &B_ch_rc ('SNMP_MIB2_START',&getGlobal('FILE', 'chkconfig_snmpd_Mib2'));
	    &B_ch_rc ('SNMP_TRAPDEST_START',&getGlobal('FILE', 'chkconfig_snmpd_Trp'));
	    &B_ch_rc ('SNMP_MASTER_START',&getGlobal('FILE', 'chkconfig_snmpd_Master'));
	} # end HP-UX section
    }
}

###
### Should we disable the rest?
###

sub DeactivateAllChkconfig {

    # This routine is a duplicate of msec's functionality -- it turns
    # off all chkconfig-based services with the exception of those in
    # /etc/security/msec/server.4.

    if (&getGlobalConfig("MiscellaneousDaemons","minimize_chkconfig") eq "Y") {
	&B_log("DEBUG","# sub DeactivateAllChkconfig\n");

	open CHKCONFIGS,"/sbin/chkconfig --list |";
	my $line;
	while ($line = <CHKCONFIGS>) {
	    if ($line =~ /^(.*?)\s+0:/) {
		my $service = $1;
		my $chkconfig_this_off = 1;
		my $allowed_service;
		foreach $allowed_service ( "crond","syslog","keytable","network","gpm","xfs","pcmcia","bastille-firewall") {
		    if ($service eq $allowed_service) {
			$chkconfig_this_off=0;
		    }
		}
		
		if ($chkconfig_this_off) {
		    &B_chkconfig_off($service);
		}
	    }
	}
	close CHKCONFIGS;
    }

}

sub DeactivatePTY {
    if (&getGlobalConfig("MiscellaneousDaemons","disable_ptydaemon") eq "Y") {
	&B_log("DEBUG","# sub DeactivatePTY\n");
	&B_ch_rc ('VTDAEMON_START',&getGlobal('FILE', 'chkconfig_vt'));
	&B_ch_rc ('PTYDAEMON_START',&getGlobal('FILE', 'chkconfig_pty'));
    }
}

sub DeactivatePwgrd {
   if (&getGlobalConfig("MiscellaneousDaemons","disable_pwgrd") eq "Y") {
	&B_log("DEBUG","# sub DeactivatePwgrd\n");
	&B_ch_rc ('PWGR',&getGlobal('FILE', 'chkconfig_pwgrd'));
    }
}

sub DeactivateRbootd {
   if (&getGlobalConfig("MiscellaneousDaemons","disable_rbootd") eq "Y") {
	&B_log("DEBUG","# sub DeactivatePwgrd\n");
	&B_ch_rc ('START_RBOOTD',&getGlobal('FILE', 'chkconfig_rbootd'));
    }
}

sub RestrictXaccess {
    if (&getGlobalConfig("MiscellaneousDaemons","xaccess") eq "Y") {
	&B_log("DEBUG","# sub xaccess\n");

	&B_System(&getGlobal('BIN',"dtlogin.rc") . " reset",&getGlobal('BIN',"dtlogin.rc") . " reset");
	&B_create_file (&getGlobal('BFILE', 'Xaccess.bastille'));
	&B_blank_file  (&getGlobal('BFILE', 'Xaccess.bastille'), "Bastille");
	&B_append_line (&getGlobal('BFILE', 'Xaccess.bastille'), "Bastille" ,
			"# This is a blank Xaccess file created by Bastille to prevent \n" .
			"# XDMCP logins.  It is referenced from " . &getGlobal('BFILE', 'Xconfig') . ".\n \n");
	&B_cp(&getGlobal('FILE', 'Xconfig'),&getGlobal('BFILE', 'Xconfig'));
	&B_replace_line(&getGlobal('BFILE', 'Xconfig'), "Dtlogin\.accessFile",
			"Dtlogin\.accessFile:          " .  &getGlobal('BFILE', 'Xaccess.bastille'));
	&B_System(&getGlobal('BIN',"dtlogin.rc") . " reset",&getGlobal('BIN',"dtlogin.rc") . " reset");

    }
}

sub RestrictRendezvous {
    if (&getGlobalConfig("MiscellaneousDaemons","rendezvous") eq "Y") {
	&B_log("DEBUG","# sub rendezvous\n");

	if (&GetDistro =~ /^OSX/) {
	    &B_hash_comment_line('/System/Library/StartupItems/mDNSResponder/mDNSResponder','^\s*\/usr\/sbin\/mDNSResponder\b');
	}
	elsif ( (&GetDistro =~ /^RH/) or ($distro =~ '^MN') or ($distro =~ '^SE') ) {
	    &B_chkconfig_off('mDNSResponder');
	    &B_chkconfig_off('nifd');

	    # Fedora Core 5 appears to use a different set of daemons
  	    # to implement Zeroconf.
	    &B_chkconfig_off('avahi-daemon');
	    &B_chkconfig_off('avahi-dnsconfd');
	}
    }
}

sub RestrictAutoDiskMount {
    if (&getGlobalConfig("MiscellaneousDaemons","autodiskmount") eq "Y") {
	&B_log("DEBUG","# sub autodiskmount\n");

	if (&GetDistro =~ /^OSX/) {
	    &B_replace_line('/System/Library/StartupItems/Disks/Disks','^\s*\/sbin\/autodiskmount\s+\-va',"    /sbin/autodiskmount -v\n");
	}

    }
}

sub RestrictNTPD {
    if (&getGlobalConfig("MiscellaneousDaemons","disable_ntpd") eq "Y") {
	&B_log("DEBUG","# sub disable_ntpd\n");

	if (&GetDistro =~ /^OSX/) {
	    &B_replace_line(&getGlobal('FILE','hostconfig'),'^TIMESYNC=-YES-',"TIMESYNC=-NO-\n");
	}

    }
}


sub RestrictDiagnostics {
    if (&getGlobalConfig("MiscellaneousDaemons","diagnostics_localonly") eq "Y") {
	&B_log('DEBUG',"# sub diagnostics_localonly");
	
        my $setpath="PATH=/usr/bin/; ";
        &B_System("$setpath " . &getGlobal('BIN',"diagnostic") . " stop", 
                  "$setpath " . &getGlobal('BIN',"diagnostic") . " start");
	
        &B_System("$setpath " . &getGlobal('BIN',"toggle_switch") . " stop", 
                  "$setpath " . &getGlobal('BIN',"toggle_switch") . " restart");
	
        &B_create_file(&getGlobal('FILE',"local_only"));
	
        &B_chmod_if_exists(600,&getGlobal('FILE',"local_only"));
	
        &B_System("$setpath " . &getGlobal('BIN',"toggle_switch") . " restart",
                  "$setpath " . &getGlobal('BIN',"toggle_switch") . " stop");
	
        &B_System("$setpath " . &getGlobal('BIN',"diagnostic") . " start", 
                  "$setpath " . &getGlobal('BIN',"diagnostic") . " stop");

    }
}



sub RestrictSyslog {
    if (&getGlobalConfig("MiscellaneousDaemons","syslog_localonly") eq "Y") {
	&B_log("DEBUG","# sub syslog_localonly");

        my $opts = &B_get_rc("SYSLOGD_OPTS");

        if ($opts !~ /-N/) {

	    &B_System("$setpath " . &getGlobal('BIN',"syslogd_init") . " stop", 
		      "$setpath " . &getGlobal('BIN',"syslogd_init") . " start");
	           
	    if ($opts =~ /-/) {
		$opts =~ s/^([^-]*)(-.*)$/$1-N $2/;
	    }
	    else {
		$opts = "\"-N\"";
	    }
	    
	    &B_set_rc("SYSLOGD_OPTS", "$opts");

	    &B_System("$setpath " . &getGlobal('BIN',"syslogd_init") . " start", 
		      "$setpath " . &getGlobal('BIN',"syslogd_init") . " stop");


        }
	else {
	    &B_log('DEBUG',"SYSLOGD_OPTS already contains a '-N' option");
	}
	
	

    }
}

sub DeactivateKudzu {
    if (&getGlobalConfig("MiscellaneousDaemons","disable_kudzu") eq "Y") {
	&B_log("DEBUG","# sub DeactivateKudzu\n");

	my $distro = &GetDistro;
	if ( ($distro =~ '^RH') or ($distro =~ '^MN') or ($distro =~ '^SE') ) {
	    &B_chkconfig_off("kudzu");
	}
	# else {
	# What do we do on Debian and Turbo?
	# }
    }
}

sub DeactivateHPOJ {
    if (&getGlobalConfig("MiscellaneousDaemons","disable_hpoj") eq "Y") {
	&B_log("DEBUG","# sub DeactivateHPOJ\n");

	my $distro = &GetDistro;
	if ( ($distro =~ '^RH') or ($distro =~ '^MN') or ($distro =~ '^SE') ) {
	    &B_chkconfig_off("hpoj");
	}
	# else {
	# What do we do on Debian and Turbo?
	# }
    }
}

sub DeactivateISDN {
    if (&getGlobalConfig("MiscellaneousDaemons","disable_isdn") eq "Y") {
	&B_log("DEBUG","# sub DeactivateISDN\n");

	my $distro = &GetDistro;
	# TODO: confirm that Mandrake also uses /etc/init.d/isdn running isdnlog
	if ( ($distro =~ '^RH') or ($distro =~ '^MN') or ($distro =~ '^SE') ) {
	    &B_chkconfig_off("isdn");
	}
	# else {
	# What do we do on Debian and Turbo?
	# }
    }
}

sub DeactivateBluetooth {
    if (&getGlobalConfig('MiscellaneousDaemons','disable_bluetooth') eq 'Y') {
	&B_log("DEBUG","# sub DeactivateBluetooth\n");
	
	my $distro = &GetDistro;
	if ( ($distro =~ '^RH') or ($distro =~ '^MN') or ($distro =~ '^SE') ) {
	    &B_chkconfig_off('bluetooth');
	}
    }
}    
 
1;
