190075Sobrien/*
290075Sobrien *  perm.c - check user permission for at(1)
3169689Skan *  Copyright (C) 1994  Thomas Koenig
4132718Skan *
550397Sobrien * Redistribution and use in source and binary forms, with or without
690075Sobrien * modification, are permitted provided that the following conditions
750397Sobrien * are met:
890075Sobrien * 1. Redistributions of source code must retain the above copyright
990075Sobrien *    notice, this list of conditions and the following disclaimer.
1090075Sobrien * 2. The name of the author(s) may not be used to endorse or promote
1190075Sobrien *    products derived from this software without specific prior written
1252284Sobrien *    permission.
1390075Sobrien *
1490075Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
1590075Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1690075Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1752284Sobrien * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
1852284Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1990075Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20169689Skan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21169689Skan * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2252284Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2350397Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2490075Sobrien */
2590075Sobrien
2690075Sobrien#include <sys/cdefs.h>
27132718Skan__FBSDID("$FreeBSD$");
2852284Sobrien
2952284Sobrien/* System Headers */
3090075Sobrien
3190075Sobrien#include <sys/types.h>
3290075Sobrien#include <err.h>
3390075Sobrien#include <errno.h>
3490075Sobrien#include <pwd.h>
3590075Sobrien#include <stddef.h>
3690075Sobrien#include <stdio.h>
3790075Sobrien#include <stdlib.h>
3890075Sobrien#include <string.h>
3990075Sobrien#include <unistd.h>
4090075Sobrien
4190075Sobrien/* Local headers */
4250397Sobrien
4350397Sobrien#include "at.h"
4450397Sobrien#include "perm.h"
4550397Sobrien#include "privs.h"
4650397Sobrien
4750397Sobrien/* Macros */
4850397Sobrien
49169689Skan#define MAXUSERID 10
50169689Skan
51169689Skan/* Structures and unions */
52169689Skan
53169689Skan/* Function declarations */
5452284Sobrien
5590075Sobrienstatic int check_for_user(FILE *fp,const char *name);
5690075Sobrien
5790075Sobrien/* Local functions */
5852284Sobrien
5990075Sobrienstatic int check_for_user(FILE *fp,const char *name)
6090075Sobrien{
6190075Sobrien    char *buffer;
62132718Skan    size_t len;
6390075Sobrien    int found = 0;
6490075Sobrien
6590075Sobrien    len = strlen(name);
6652284Sobrien    if ((buffer = malloc(len+2)) == NULL)
6790075Sobrien	errx(EXIT_FAILURE, "virtual memory exhausted");
6890075Sobrien
6990075Sobrien    while(fgets(buffer, len+2, fp) != NULL)
7090075Sobrien    {
7190075Sobrien	if ((strncmp(name, buffer, len) == 0) &&
7252284Sobrien	    (buffer[len] == '\n'))
73169689Skan	{
74169689Skan	    found = 1;
75169689Skan	    break;
76169689Skan	}
77169689Skan    }
78169689Skan    fclose(fp);
79169689Skan    free(buffer);
80169689Skan    return found;
81169689Skan}
82169689Skan/* Global functions */
83169689Skanint check_permission(void)
84169689Skan{
8590075Sobrien    FILE *fp;
8690075Sobrien    uid_t uid = geteuid();
8790075Sobrien    struct passwd *pentry;
8890075Sobrien
8952284Sobrien    if (uid==0)
90169689Skan	return 1;
91169689Skan
92169689Skan    if ((pentry = getpwuid(uid)) == NULL)
93169689Skan	err(EXIT_FAILURE, "cannot access user database");
94169689Skan
95169689Skan    PRIV_START
96169689Skan
97169689Skan    fp=fopen(PERM_PATH "at.allow","r");
98169689Skan
99169689Skan    PRIV_END
100169689Skan
101169689Skan    if (fp != NULL)
102169689Skan    {
103169689Skan	return check_for_user(fp, pentry->pw_name);
104169689Skan    }
105169689Skan    else if (errno == ENOENT)
106169689Skan    {
107169689Skan
108169689Skan	PRIV_START
109169689Skan
110169689Skan	fp=fopen(PERM_PATH "at.deny", "r");
111169689Skan
112169689Skan	PRIV_END
113169689Skan
114169689Skan	if (fp != NULL)
115169689Skan	{
116169689Skan	    return !check_for_user(fp, pentry->pw_name);
117169689Skan	}
118169689Skan	else if (errno != ENOENT)
119169689Skan	    warn("at.deny");
120169689Skan    }
121169689Skan    else
122169689Skan	warn("at.allow");
123169689Skan    return 0;
124169689Skan}
125169689Skan