/****************************************/
/* This is the checkset.c module for 	*/
/* lsat program. This module checks for */
/* setuid and setgid files on the 	*/
/* local system and prints them to the  */
/* outfile.                             */
/*					*/
/* 4/5/2002, added code to check for    */
/* files in /dev that do not belong.    */
/*					*/
/* See lsatmain.c for more details.	*/
/****************************************/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

checkset(filename, verbose)
const char *const filename;
int verbose;
{

    char line[80];  /* for reading lines		*/
    int  fileval=0; /* return val 	*/
    FILE *outfile; 	/* file pointer for outfile	*/
    FILE *fileptr;	/* file pointer for infile	*/

    if (verbose == 1)
    {
        printf("In checkset module...\n");
    }

    /* 1st off generate a list of setuid files 	*/
    /* this should be done from /, but use -xdev so	*/
    /* that we don't traverse other filesystems	*/
    /* note, we use -mount for compatibility with 	*/
    /* other versions of find.			*/

    if (verbose == 1)
    {
        printf("Creating list of setuid files...\n");
        printf("Note: we are not traversing \"other\" filesystems.\n");
    }

    /* create a temp file for storage */
    if ((fileval = open("/tmp/findlist.txt", O_RDWR | O_CREAT, 0600)) < 0)
    {
        perror("Could not make file w/perms 0600...\n");
        perror("Possible link attack while creating/opening file!\n");
        perror("Bailing in checkset...\n");
        exit(-1);
    }

    if (system("find / -mount -perm -4000 1>/dev/null 2>/dev/null >/tmp/findlist.txt") == 2)
    {
        perror("Problem writing file to tmp.\n");
        perror("Problem was in module: checkset.c\n");
        return(-1);
    }

    /* now simply read through them and print them 	*/
    /* out to the outfile with a header.		*/

    /* open the outfile for append			*/
    outfile = fopen(filename, "a");
    if (outfile == NULL)
    {
        perror("Error opening outfile!\n");
        perror("Problem was in module: checkset.c\n");
        return(-1);
    }

    /* open the file with setuid files for read	*/
    fileptr = fopen("/tmp/findlist.txt", "r");
    if (fileptr == NULL)
    {
        perror("Error opening file for read!\n");
        perror("Problem was in module: checkset.c\n");
        return(-1);
    }

    /* write out a header to the outfile		*/
    fprintf(outfile, "****************************************\n");
    fprintf(outfile, "This is a list of SUID and SGID files\n");
    fprintf(outfile, "on the system. Keep track of them, and\n");
    fprintf(outfile, "consider changing perms or locking them\n");
    fprintf(outfile, "down...\n");
    fprintf(outfile, "Search google or sans for more info.\n");
    fprintf(outfile, "**********\n");
    fprintf(outfile, "\nSetUID files found:\n");

    /* ok, now just print them out...		*/
    while (fgets(line, sizeof(line), fileptr) != NULL)
    {
        fprintf(outfile, "%s\n", line);
    }

    /* close the input file and rm it		*/
    fclose(fileptr);
    if ((system("rm -f /tmp/findlist.txt")) < 0)
    {
        /* rhut-rho... problems.. */
        perror("Can't rm tempfile...\n");
        perror("Permissions problem??\n");
        return(-1);
    }

    if (verbose == 1)
    {
        printf("Creating list of setgid files...\n");
        printf("Note: we are not traversing \"other\" filesystems.\n");
    }

    /* create a temp file for storage */
    if ((fileval = open("/tmp/findlist.txt", O_RDWR | O_CREAT, 0600)) < 0)
    {
        perror("Could not make file w/perms 0600...\n");
        perror("Possible link attack while creating/opening file!\n");
        perror("Bailing in checkset...\n");
        exit(-1);
    }

    /* get a list of setgid files 			*/
    if (system("find / -mount -perm -2000 1>/dev/null 2>/dev/null >/tmp/findlist.txt") == 2)
    {
        perror("Problem writing file to tmp.\n");
        perror("Problem was in module: checkset.c\n");
        return(-1);
    }

    /* open the file with setgid files for read     */
    fileptr = fopen("/tmp/findlist.txt", "r");
    if (fileptr == NULL)
    {
        perror("Error opening file for read!\n");
        perror("Problem was in module: checkset.c\n");
        return(-1);
    }

    /* print a small header				*/
    fprintf(outfile, "\n**********\n");
    fprintf(outfile, "SetGID files found:\n");

    /* ok, now just print them out...               */
    while (fgets(line, sizeof(line), fileptr) != NULL)
    {
        fprintf(outfile, "%s\n", line);
    }

    /* close the input file and rm it               */
    fclose(fileptr);
    if ((system("rm -f /tmp/findlist.txt")) < 0)
    {
        /* rhut-rho... problems.. */
        perror("Can't rm tempfile...\n");
        perror("Permissions problem??\n");
        return(-1);
    }


    if (verbose == 1)
    {
        printf("Creating list of non block/char files in /dev...\n");
    }

    /* create a temp file for storage */
    if ((fileval = open("/tmp/findlist.txt", O_RDWR | O_CREAT, 0600)) < 0)
    {
        perror("Could not make file w/perms 0600...\n");
        perror("Possible link attack while creating/opening file!\n");
        perror("Bailing in checkset...\n");
        exit(-1);
    }

    /* get a list of files in dev which are not  */
    /* block or character special files...       */
    if (system("find / -mount \\( -type b -o -type c \\) 1>/dev/null 2>/dev/null | grep -v /dev 1>/dev/null 2>/dev/null >/tmp/findlist.txt") == 2)
    {
        perror("Problem writing file to tmp.\n");
        perror("Problem was in module: checkset.c\n");
        return(-1);
    }

    /* open the file with setgid files for read     */
    fileptr = fopen("/tmp/findlist.txt", "r");
    if (fileptr == NULL)
    {
        perror("Error opening file for read!\n");
        perror("Problem was in module: checkset.c\n");
        return(-1);
    }

    /* print a small header                         */
    fprintf(outfile, "\n**********\n");
    fprintf(outfile, "Non block/char files in /dev:\n");

    /* ok, now just print them out...               */
    while (fgets(line, sizeof(line), fileptr) != NULL)
    {
        fprintf(outfile, "%s\n", line);
    }

    /* close the input file and rm it               */
    fclose(fileptr);
    if ((system("rm -f /tmp/findlist.txt")) < 0)
    {
        /* rhut-rho... problems.. */
        perror("Can't rm tempfile...\n");
        perror("Permissions problem??\n");
        return(-1);
    }

    /* print out a footer... */
    fprintf(outfile, "\n");
    fprintf(outfile, "****************************************\n");

    /* close up */
    fclose(outfile);

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

    return(0);
}
