xref: /freebsd/usr.bin/at/perm.c (revision 3ce6c35745dec7bd16c368be854fbf2c85eafa40)
1b89321a5SAndrey A. Chernov /*
2b89321a5SAndrey A. Chernov  *  perm.c - check user permission for at(1)
3b89321a5SAndrey A. Chernov  *  Copyright (C) 1994  Thomas Koenig
4b89321a5SAndrey A. Chernov  *
5b89321a5SAndrey A. Chernov  * Redistribution and use in source and binary forms, with or without
6b89321a5SAndrey A. Chernov  * modification, are permitted provided that the following conditions
7b89321a5SAndrey A. Chernov  * are met:
8b89321a5SAndrey A. Chernov  * 1. Redistributions of source code must retain the above copyright
9b89321a5SAndrey A. Chernov  *    notice, this list of conditions and the following disclaimer.
10b89321a5SAndrey A. Chernov  * 2. The name of the author(s) may not be used to endorse or promote
11b89321a5SAndrey A. Chernov  *    products derived from this software without specific prior written
12b89321a5SAndrey A. Chernov  *    permission.
13b89321a5SAndrey A. Chernov  *
14b89321a5SAndrey A. Chernov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15b89321a5SAndrey A. Chernov  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16b89321a5SAndrey A. Chernov  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17ddcf8022SAndrey A. Chernov  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18b89321a5SAndrey A. Chernov  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19b89321a5SAndrey A. Chernov  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20b89321a5SAndrey A. Chernov  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21b89321a5SAndrey A. Chernov  * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22b89321a5SAndrey A. Chernov  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23b89321a5SAndrey A. Chernov  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24b89321a5SAndrey A. Chernov  */
25b89321a5SAndrey A. Chernov 
2681c8c7a4SPhilippe Charnier #ifndef lint
2781c8c7a4SPhilippe Charnier static const char rcsid[] =
2881c8c7a4SPhilippe Charnier   "$FreeBSD$";
2981c8c7a4SPhilippe Charnier #endif /* not lint */
3081c8c7a4SPhilippe Charnier 
31b89321a5SAndrey A. Chernov /* System Headers */
32b89321a5SAndrey A. Chernov 
33b89321a5SAndrey A. Chernov #include <sys/types.h>
3481c8c7a4SPhilippe Charnier #include <err.h>
35b89321a5SAndrey A. Chernov #include <errno.h>
36b89321a5SAndrey A. Chernov #include <pwd.h>
37b89321a5SAndrey A. Chernov #include <stddef.h>
38b89321a5SAndrey A. Chernov #include <stdio.h>
39b89321a5SAndrey A. Chernov #include <stdlib.h>
40b89321a5SAndrey A. Chernov #include <string.h>
41b89321a5SAndrey A. Chernov #include <unistd.h>
42b89321a5SAndrey A. Chernov 
43b89321a5SAndrey A. Chernov /* Local headers */
44b89321a5SAndrey A. Chernov 
45b89321a5SAndrey A. Chernov #include "at.h"
463ce6c357SMark Murray #include "perm.h"
473ce6c357SMark Murray #include "privs.h"
48b89321a5SAndrey A. Chernov 
49b89321a5SAndrey A. Chernov /* Macros */
50b89321a5SAndrey A. Chernov 
51b89321a5SAndrey A. Chernov #define MAXUSERID 10
52b89321a5SAndrey A. Chernov 
53b89321a5SAndrey A. Chernov /* Structures and unions */
54b89321a5SAndrey A. Chernov 
55b89321a5SAndrey A. Chernov /* Function declarations */
56b89321a5SAndrey A. Chernov 
57b89321a5SAndrey A. Chernov static int check_for_user(FILE *fp,const char *name);
58b89321a5SAndrey A. Chernov 
59b89321a5SAndrey A. Chernov /* Local functions */
60b89321a5SAndrey A. Chernov 
61b89321a5SAndrey A. Chernov static int check_for_user(FILE *fp,const char *name)
62b89321a5SAndrey A. Chernov {
63b89321a5SAndrey A. Chernov     char *buffer;
64b89321a5SAndrey A. Chernov     size_t len;
65b89321a5SAndrey A. Chernov     int found = 0;
66b89321a5SAndrey A. Chernov 
67b89321a5SAndrey A. Chernov     len = strlen(name);
68a9be9be8SDavid E. O'Brien     if ((buffer = malloc(len+2)) == NULL)
69a9be9be8SDavid E. O'Brien 	errx(EXIT_FAILURE, "virtual memory exhausted");
70b89321a5SAndrey A. Chernov 
71b89321a5SAndrey A. Chernov     while(fgets(buffer, len+2, fp) != NULL)
72b89321a5SAndrey A. Chernov     {
73b89321a5SAndrey A. Chernov 	if ((strncmp(name, buffer, len) == 0) &&
74b89321a5SAndrey A. Chernov 	    (buffer[len] == '\n'))
75b89321a5SAndrey A. Chernov 	{
76b89321a5SAndrey A. Chernov 	    found = 1;
77b89321a5SAndrey A. Chernov 	    break;
78b89321a5SAndrey A. Chernov 	}
79b89321a5SAndrey A. Chernov     }
80b89321a5SAndrey A. Chernov     fclose(fp);
81b89321a5SAndrey A. Chernov     free(buffer);
82b89321a5SAndrey A. Chernov     return found;
83b89321a5SAndrey A. Chernov }
84b89321a5SAndrey A. Chernov /* Global functions */
853ce6c357SMark Murray int check_permission(void)
86b89321a5SAndrey A. Chernov {
87b89321a5SAndrey A. Chernov     FILE *fp;
88b89321a5SAndrey A. Chernov     uid_t uid = geteuid();
89b89321a5SAndrey A. Chernov     struct passwd *pentry;
90b89321a5SAndrey A. Chernov 
91b89321a5SAndrey A. Chernov     if (uid==0)
92b89321a5SAndrey A. Chernov 	return 1;
93b89321a5SAndrey A. Chernov 
94b89321a5SAndrey A. Chernov     if ((pentry = getpwuid(uid)) == NULL)
9581c8c7a4SPhilippe Charnier 	err(EXIT_FAILURE, "cannot access user database");
96b89321a5SAndrey A. Chernov 
97b89321a5SAndrey A. Chernov     PRIV_START
98b89321a5SAndrey A. Chernov 
99b89321a5SAndrey A. Chernov     fp=fopen(PERM_PATH "at.allow","r");
100b89321a5SAndrey A. Chernov 
101b89321a5SAndrey A. Chernov     PRIV_END
102b89321a5SAndrey A. Chernov 
103b89321a5SAndrey A. Chernov     if (fp != NULL)
104b89321a5SAndrey A. Chernov     {
105b89321a5SAndrey A. Chernov 	return check_for_user(fp, pentry->pw_name);
106b89321a5SAndrey A. Chernov     }
1074d294cadSBill Fumerola     else if (errno == ENOENT)
108b89321a5SAndrey A. Chernov     {
109b89321a5SAndrey A. Chernov 
110b89321a5SAndrey A. Chernov 	PRIV_START
111b89321a5SAndrey A. Chernov 
112b89321a5SAndrey A. Chernov 	fp=fopen(PERM_PATH "at.deny", "r");
113b89321a5SAndrey A. Chernov 
114b89321a5SAndrey A. Chernov 	PRIV_END
115b89321a5SAndrey A. Chernov 
116b89321a5SAndrey A. Chernov 	if (fp != NULL)
117b89321a5SAndrey A. Chernov 	{
118b89321a5SAndrey A. Chernov 	    return !check_for_user(fp, pentry->pw_name);
119b89321a5SAndrey A. Chernov 	}
1204d294cadSBill Fumerola 	else if (errno != ENOENT)
12181c8c7a4SPhilippe Charnier 	    warn("at.deny");
122b89321a5SAndrey A. Chernov     }
1234d294cadSBill Fumerola     else
12481c8c7a4SPhilippe Charnier 	warn("at.allow");
125b89321a5SAndrey A. Chernov     return 0;
126b89321a5SAndrey A. Chernov }
127