/****************************************/
/* This is the checkrc module for   	*/
/* the lsatmain.c program. It checks    */
/* It checks /etc/rcn.d or 		*/
/* /etc/rc.d/init.d depending on sys.   */
/* It scans the startup scripts and  	*/
/* compares them to a known list of 	*/
/* scripts that one should not have.	*/
/*					*/
/* see lsatmain.c for more details	*/
/****************************************/

#include "lsatheader.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int checkrc(release, kernel, distribution, filename, verbose)
char release[]; /* 1st field of uname -a */
char kernel[]; /* 3rd field of uname -a */
int distribution; /* see lsatmain.c for details on this one */
const char *const filename; /* output file name */
int verbose; /* should we be verbose? */
{

	char *rcptr;		/* ptr to passwd file   */
	char *listtptr;		/* ptr to lnxlist or sollist	*/
	char line[30];	/* array for a line	*/
	char temparray[50][30]; /*temparray. */
	char kernver[3][6]={"2.2", "2.4", "SunOS"};  /* kernel versions */
	int i=0;				/* counter variable	*/
	int j=0;				/* counter variable  */
	int fileval; 		/* return val for mkstemp */
	int osflag=1;   /* what OS/kern are we at/on? */
	/* 1= lnx2.2, 2=lnx2.4, 3=Solaris */

	/* NOT a comprehensive list yet.	*/
	/* Need to go over these to make sure...*/
	char lnx2list[13][12] = {"lpd", "inetd", "nfs", "nfslock", "portmap", "rwalld", "rwhod", "rstatd", "sendmail", "ypbind", "ypasswd", "named"};
	int lnx2listnum=10; /* how many items in above list? */
	char lnx4list[18][14] = {"S05kudzu", "S13portmap", "S14nfslock", "S20nfs", "S20rstatd", "S20rwalld", "S20rwhod", "S25netfs", "S34yppasswdd",  "S50snmpd", "S60lpd", "S65identd", "S74ntpd", "S74ypserv", "S74ypxfrd", "S80sendmail", "S95anacron"};
	int lnx4listnum=17;
	char sollist[9][12] = {"S71rpc", "S76smpdx", "S77dmi", "S99dtlogin", "S74autofs", "S88sendmail", "nfs.server", "nfs.client"};
	int sollistnum=8;

	FILE *outfile;		/* output file pointer 	*/
	FILE *rcfile;		/* file pointer to templist file */

	if (verbose == 1)
	{
		printf("Starting checkrc module...\n");
	}

	/* since there is a location difference between */
	/* kernel 2.2 and 2.4, we check the kernel 	*/
	/* release we are on. Also chekc for SunOS, 	*/
	/* which has a different naming convention	*/

	if ((strcmp(kernel, kernver[0])) == 0)
	{
		/* kernel 2.2 */
		osflag=1;
	}	
	if ((strcmp(kernel, kernver[1])) == 0)
	{
		/* kernel 2.4 */
		osflag=2;
	}
	if ((strcmp(release, kernver[2])) == 0)
	{
		/* SunOS */
		osflag=3;
	}
	/* note default is assume 2.2 style... */

	outfile=fopen(filename, "a");
	if (outfile == NULL)
	{
		perror("Can't open outfile!\n");
		perror("Check perms or something...\n");
		perror("Problem was in module checkrc.\n");
		return(-1);
	}

	/* print some header info to the outfile...  */
	fprintf(outfile, "\n");
	fprintf(outfile, "****************************************\n");
	fprintf(outfile, "Checking rc startup scripts:\n");
	fprintf(outfile, "\n");

	if (verbose == 1)
	{
		printf("Checking rc scripts...\n");
	}


	/* create a temp file for storage */
        fileval = mkstemp("/tmp/rclist.txt");
        if (fileval < -1)
        {
                printf("Unable to create tempfile!?\n");
                printf("Problem was in module: checkrc\n");
                return(-1);
        }

	/* perform ls based on which sys we are on */
	/* 2.2 sys...	*/
	if (osflag == 1)
	{
		if (system("ls /etc/rc.d/init.d/ 1>/dev/null 2>/dev/null >/tmp/lslist.txt") < 0)
		{
			perror("Can't perform \"ls\" command. Strange.\n");
			perror("Giving up in checkrc...\n");
			return(-1);
		}
	}
	/* 2.4 sys... */
	/* note here we do same for Solaris. 		*/
	/* Sunos rc dirs are the same structure as 2.4, */
	/* however, we need to know if it is Solaris   	*/
	/* due to the naming convention of the files	*/
	/* in the rc directories on Solaris.		*/
	if ((osflag == 2) || (osflag == 3) )
	{
		/* we peform as two ls's here for ease of reading in  */
		/* the file since for example an ls / /usr will put   */
		/* extra blank lines and the directory name in to the */
		/* output file...				      */
		if(((system("ls /etc/rc2.d/ 1>/dev/null 2>/dev/null >>/tmp/lslist.txt")) < 0) || ((system("ls /etc/rc3.d/ 1>/dev/null 2>/dev/null >>/tmp/lslist.txt"))< 0))
		{
			perror("Can't perform \"ls\" command. Strange.\n");
			perror("Giving up in checkrc...\n");
		}
	}

	/* open the newly created file */
	rcfile=fopen("/tmp/lslist.txt", "r");
	if (rcfile == NULL)
	{
		perror("Can't open templist...\n");
		perror("Strange, we just created that file...\n");
		perror("Giving up in checkrc...\n");
		return(-1);
	}


	/* grab a line from the lslist  */
	/* store it in the tmparray     */
	while (fgets(line, sizeof(line), rcfile) != NULL)
	{
		rcptr = strtok(line, ", \n");
		/* if not while. we guarentee not more than */
		/* one entry per line     */
		if (rcptr != NULL)
		{
			if (sscanf(rcptr, "%s", temparray[i]) < 1)
			{
				perror("sscanf failed.\n");
				perror("Failure was in module: checkrc.\n");
				return(-1);
			}
			i++;
			rcptr = strtok(NULL, ", \n");
			if (rcptr == NULL)
			{
				;
			}
		} /* end while (rcptr != NULL) */
	} /* end while (fgets...) */


	/* now we compare the entries in the tmparray */
	/* to the rc scripts that are problematic.    */
	/* note that we have three lists, one for 2.2 */
	/* based kernels, one for 2.4 based kernels   */
	/* and one for SunOS/Solaris systems.	      */

	/* linux 2.2 based system */
	if (osflag==1)
	{
		for (i = 0; i < 50; i++)
		{
			for (j = 0; j < lnx2listnum; j++)
			{
				if ((strcmp(temparray[i], lnx2list[j])) == 0)
				{
					/* match */
					fprintf(outfile, "%s\n", temparray[i]);
				}
			}
		}
	}

	/* linux 2.4 based system */
	if (osflag == 2)
	{
                for (i = 0; i < 50; i++)
                {
                        for (j = 0; j < lnx4listnum; j++)
                        {
                                if ((strcmp(temparray[i], lnx4list[j])) == 0)
                                {
                                        /* match */
                                        fprintf(outfile, "%s\n", temparray[i]);
                                }
                        }
                }
        }

	/* SunOS/Solaris based system */
	if (osflag == 3)
	{
		for (i = 0; i < 50; i++)
                {
                        for (j = 0; j < sollistnum; j++)
                        {
                                if ((strcmp(temparray[i], sollist[j])) == 0)
                                {
                                        /* match */
                                        fprintf(outfile, "%s\n", temparray[i]);
                                }
                        }
                }
        }

	/* print some footer information */
	fprintf(outfile, "\n");
	if (osflag == 1)
	{
		fprintf(outfile, "The above were found in /etc/rc.d/init.d\n");
	}
	if ((osflag == 2) || (osflag == 3))
	{
		fprintf(outfile, "The above were found in /etc/rc(2/3).d\n");
	}
	fprintf(outfile, "Consider removing or disabling the above services.\n");
	fprintf(outfile, "****************************************\n");

	
	/* clean up */
	fclose(outfile);
	/* close input file */
	fclose(rcfile);
	/* rm the input file */
	if (system("rm -f /tmp/lslist.txt") < 0)
        {
                perror("Can't rm tempfile??\n");
                perror("Strange, we made the file...\n");
                perror("Giving up in checkrc...\n");
                return(-1);
        }

	if (verbose == 1)
	{
		printf("Finished in checkrc module.\n");
	}
	return(0);
}
