/****************************************/
/* This is the checkumask module for    */
/* the lsatmain.c program. It checks    */
/* It checks /etc/csh.login and profile */
/* for the umask setting. It makes sure */
/* that is it set at 022, 027 or 077.	*/
/*					*/
/* see lsatmain.c for more details	*/
/****************************************/

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

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

    char *umaskptr;
    char *uarrayptr;
    char uline[80];	/* array for a line	*/
    char utemparray[20][80]; /*temparray. */
    int i=0;				/* counter variable	*/
    int j=0;				/* counter variable  */
    int numread;
    int field;			/* field counter	*/
    int fileval=0;		/* return val 	*/

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

    /* init array to zero */
    for (i=0; i<10; i++)
    {
        for (j=0; j<20; j++)
        {
            utemparray[i][j]=0;
        }
    }

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


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

    /* print some header info to the outfile...  */
    fprintf(outfile, "\n");
    fprintf(outfile, "****************************************\n");
    fprintf(outfile, "Checking default umask on system:\n");
    fprintf(outfile, "\n");

    if (verbose == 1)
    {
        printf("Checking umask file...\n");
    }

    /* create a temp file for storage */
    if ((fileval = open("/tmp/ulist.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 checkumask...\n");
        exit(-1);
    }

    /* ok, grep through the files for umask */
    /* NOTE: Redhat systems use User Private*/
    /* Groups and a umask of 002 is ok.     */
    /* If we see 002, check for RedHat...   */

    /* had a problem with this... this 	*/
    /* should be ok on redhat & debian...   */
    if (system("grep umask /etc/* 2>/dev/null |awk -F \"umask\" 'length($1 $2) > 0 {print($1 $2)}' |grep -v \\#  >/tmp/ulist.txt") < 0)
    {
        perror("Can't read /etc/??\n");
        perror("Check perms??\n");
        perror("Error was in checkumask module...\n");
        return(-1);
    }


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


    /* due to the format of the files we grep through */
    /* (note that only csh.login and profile should   */
    /* have umask), there should be only 3 fields     */
    /* per line in the umasklist.txt file.		  */
    /* we therefore know that for each one we will 	  */
    /* have 3 entries in the temparray, the file,     */
    /* "umask" and the umask number.		  */

    /* reset counter */
    i = 0;
    numread = 0;
    while (fgets(uline, sizeof(uline), umaskfile) != NULL)
    {
        numread++;
        umaskptr = strtok(uline, ", \n");
        while (umaskptr != NULL)
        {
            if (sscanf(umaskptr, "%s", utemparray[i]) < 1)
            {
                perror("sscanf failed.\n");
                perror("Failure was in module: checkumask.\n");
                return(-1);
            }
            i++;
            umaskptr = strtok(NULL, ", \n");
            if (umaskptr == NULL)
            {
                ;
            }
        } /* end while (passptr != NULL) */
    } /* end while (fgets...) */


    /* just print out the umask & filename  */
    /* for the user...			*/
    for (i = 0; i < numread; i++)
    {
        /* matched "good" masks*/
        fprintf(outfile, "file %s, umask %s\n", utemparray[i*2], utemparray[i+i+1]);
    } /* end for (i=0...) */


    /* print some footer information */
    fprintf(outfile, "Default umask should be 022 or 027.\n");
    fprintf(outfile, "Check above for compliance.\n");
    fprintf(outfile, "RedHat: 002 is ok, RH uses User Private Groups.\n");
    fprintf(outfile, "****************************************\n");

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

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