perm.c revision 87208
110154Sache/*
27767Sache *  perm.c - check user permission for at(1)
37767Sache *  Copyright (C) 1994  Thomas Koenig
47767Sache *
57767Sache * Redistribution and use in source and binary forms, with or without
67767Sache * modification, are permitted provided that the following conditions
77767Sache * are met:
87767Sache * 1. Redistributions of source code must retain the above copyright
97767Sache *    notice, this list of conditions and the following disclaimer.
107767Sache * 2. The name of the author(s) may not be used to endorse or promote
117767Sache *    products derived from this software without specific prior written
127767Sache *    permission.
137767Sache *
147767Sache * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
157767Sache * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
167767Sache * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1710154Sache * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
187767Sache * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
197767Sache * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
207767Sache * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
217767Sache * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
227767Sache * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
237767Sache * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
247767Sache */
257767Sache
2654158Scharnier#ifndef lint
2754158Scharnierstatic const char rcsid[] =
2854158Scharnier  "$FreeBSD: head/usr.bin/at/perm.c 87208 2001-12-02 12:26:18Z markm $";
2954158Scharnier#endif /* not lint */
3054158Scharnier
317767Sache/* System Headers */
327767Sache
337767Sache#include <sys/types.h>
3454158Scharnier#include <err.h>
357767Sache#include <errno.h>
367767Sache#include <pwd.h>
377767Sache#include <stddef.h>
387767Sache#include <stdio.h>
397767Sache#include <stdlib.h>
407767Sache#include <string.h>
417767Sache#include <unistd.h>
427767Sache
437767Sache/* Local headers */
447767Sache
4587208Smarkm#include "at.h"
4687208Smarkm#include "perm.h"
477767Sache#include "privs.h"
487767Sache
497767Sache/* Macros */
507767Sache
517767Sache#define MAXUSERID 10
527767Sache
537767Sache/* Structures and unions */
547767Sache
557767Sache/* Function declarations */
567767Sache
577767Sachestatic int check_for_user(FILE *fp,const char *name);
587767Sache
597767Sache/* Local functions */
607767Sache
617767Sachestatic int check_for_user(FILE *fp,const char *name)
627767Sache{
637767Sache    char *buffer;
647767Sache    size_t len;
657767Sache    int found = 0;
667767Sache
677767Sache    len = strlen(name);
6880294Sobrien    if ((buffer = malloc(len+2)) == NULL)
6980294Sobrien	errx(EXIT_FAILURE, "virtual memory exhausted");
707767Sache
717767Sache    while(fgets(buffer, len+2, fp) != NULL)
727767Sache    {
737767Sache	if ((strncmp(name, buffer, len) == 0) &&
747767Sache	    (buffer[len] == '\n'))
757767Sache	{
767767Sache	    found = 1;
777767Sache	    break;
787767Sache	}
797767Sache    }
807767Sache    fclose(fp);
817767Sache    free(buffer);
827767Sache    return found;
837767Sache}
847767Sache/* Global functions */
8587208Smarkmint check_permission(void)
867767Sache{
877767Sache    FILE *fp;
887767Sache    uid_t uid = geteuid();
897767Sache    struct passwd *pentry;
907767Sache
917767Sache    if (uid==0)
927767Sache	return 1;
937767Sache
947767Sache    if ((pentry = getpwuid(uid)) == NULL)
9554158Scharnier	err(EXIT_FAILURE, "cannot access user database");
967767Sache
977767Sache    PRIV_START
987767Sache
997767Sache    fp=fopen(PERM_PATH "at.allow","r");
1007767Sache
1017767Sache    PRIV_END
1027767Sache
1037767Sache    if (fp != NULL)
1047767Sache    {
1057767Sache	return check_for_user(fp, pentry->pw_name);
1067767Sache    }
10748386Sbillf    else if (errno == ENOENT)
1087767Sache    {
1097767Sache
1107767Sache	PRIV_START
1117767Sache
1127767Sache	fp=fopen(PERM_PATH "at.deny", "r");
1137767Sache
1147767Sache	PRIV_END
1157767Sache
1167767Sache	if (fp != NULL)
1177767Sache	{
1187767Sache	    return !check_for_user(fp, pentry->pw_name);
1197767Sache	}
12048386Sbillf	else if (errno != ENOENT)
12154158Scharnier	    warn("at.deny");
1227767Sache    }
12348386Sbillf    else
12454158Scharnier	warn("at.allow");
1257767Sache    return 0;
1267767Sache}
127