#
# This will check for servers on the machine that possibly shouldn't
# be running.  It gets the rpcinfo of the machine to check for valid
# rpc based services.  It then reads in $services to get the
# names and port definitions to use when it reads $inetd.
#
# Armed with this data, it does a netstat -a and looks for any servers
# bound to a port.  If there is a server, it looks up to see if it
# should be running, and reports information about the server if
# unsure.
#

$warn     = 0;

&pcheck("Server Check");

#
# Index the RPC Services to find their ports
#
@rpc_state = `$rpcinfo -p localhost`;
shift(@rpc_state);

foreach $service (@rpc_state) {
	@parts = split(/\s+/,$service);
	@active[@parts[4]] = @parts[5];
}


#
# Read the $services to determine which ports things run on
#
if (open(SERVICES, $services)) {
	while (<SERVICES>) {
		next if (/^#/);
		next unless (/\d\/tcp/);

		@parts = split(/\s+/);
	
		$service = shift(@parts);
		$port    = shift(@parts);
		($port)  = split(/\//,$port);
		$alias   = shift(@parts);

		$services{$service} = $port;

		while (($alias ne "") && !($alias =~ /^#/)) {
			$services{$alias} = $port;
			$alias = shift(@parts);
		}

	}
} else {
	&report("ERROR: Cannot open $services.\n");
	&error;
	exit;
}


#
# Read $inetd.conf to determine which services are active
#
if (open(INETD, $inetd)) {
	while (<INETD>) {
		next if (/^#/);
		next unless (/\stcp\s+/);
		$port = 0;

		($service) = split(/\s/);
		$port = $services{$service};

		if ($port == 0) {
			&report("ERROR: $service is not in $services.\n");
			$fail = 1;
		} else {
			@active[$port] = $service;
		}
	}
} else {
	&report("ERROR: Cannot open $inetd.\n");
	&error;
	exit;
}


#
# Read the netstat output and look for servers
#
$netstat_out = `$netstat`;
@netstat_out = split(/\n/,$netstat_out);
@servers = grep(/LISTEN/,@netstat_out);

foreach $server (@servers) {

	@parts = split(/\s+/,$server);
	($t,$location) = split(/\./,@parts[3]);


	if ($location =~ /^\d+$/) {
		if (!(defined(@active[$location]))) {

			$warn = 1;
			&report("WARNING: An unknown service is located on port: $location\n");

			if (!(defined($ps_out))) {
				$ps_out    = `$ps`;
				@ps_out    = split(/\n/,$ps_out);
			}

			if ($fuser ne "") {
				$fuser_out = `$fuser -u $location/tcp 2>&1`;
				@fuser_out = split(/\s+/,$fuser_out);
				shift(@fuser_out);

				&report("Port Associated Process Listing:\n");
				foreach $user (@fuser_out) {
					($pid,$user) = split(/o\(/,$user);
					$user =~ s/\)//g;

					@process = grep(/^\s*$user\s+$pid/,@ps_out);
					&report("@process[0]\n");
				}
				&report("\n");
			}

		}

	}
}


if ($fail) {
	&failed;
} elsif ($warn) {
	&warn;
} else {
	&passed;
}

exit 0;
