xref: /netbsd-src/usr.bin/at/perm.c (revision d9047ae69bf92f9915971c583f8f86db60a3ee29)
1*d9047ae6Sdholland /*	$NetBSD: perm.c,v 1.4 2016/03/13 00:32:09 dholland Exp $	*/
2ce0c0e02Schristos 
3ce0c0e02Schristos /*
4ce0c0e02Schristos  * perm.c - check user permission for at(1)
5ce0c0e02Schristos  * Copyright (C) 1994  Thomas Koenig
6ce0c0e02Schristos  *
7ce0c0e02Schristos  * Redistribution and use in source and binary forms, with or without
8ce0c0e02Schristos  * modification, are permitted provided that the following conditions
9ce0c0e02Schristos  * are met:
10ce0c0e02Schristos  * 1. Redistributions of source code must retain the above copyright
11ce0c0e02Schristos  *    notice, this list of conditions and the following disclaimer.
12ce0c0e02Schristos  * 2. The name of the author(s) may not be used to endorse or promote
13ce0c0e02Schristos  *    products derived from this software without specific prior written
14ce0c0e02Schristos  *    permission.
15ce0c0e02Schristos  *
16ce0c0e02Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
17ce0c0e02Schristos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18ce0c0e02Schristos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19ce0c0e02Schristos  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20ce0c0e02Schristos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21ce0c0e02Schristos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22ce0c0e02Schristos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23ce0c0e02Schristos  * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24ce0c0e02Schristos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25ce0c0e02Schristos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26ce0c0e02Schristos  */
27ce0c0e02Schristos 
28ce0c0e02Schristos /* System Headers */
29ce0c0e02Schristos 
30ce0c0e02Schristos #include <sys/types.h>
31ce0c0e02Schristos #include <errno.h>
32ce0c0e02Schristos #include <pwd.h>
335f256bd3Schristos #include <stdbool.h>
34ce0c0e02Schristos #include <stddef.h>
35ce0c0e02Schristos #include <stdio.h>
36ce0c0e02Schristos #include <stdlib.h>
37ce0c0e02Schristos #include <string.h>
38ce0c0e02Schristos #include <unistd.h>
39ce0c0e02Schristos 
40ce0c0e02Schristos /* Local headers */
41ce0c0e02Schristos 
42ce0c0e02Schristos #include "at.h"
43ce0c0e02Schristos #include "panic.h"
44ce0c0e02Schristos #include "pathnames.h"
45ce0c0e02Schristos #include "privs.h"
46ce0c0e02Schristos #include "perm.h"
47ce0c0e02Schristos 
48ce0c0e02Schristos /* File scope variables */
49ce0c0e02Schristos 
50ce0c0e02Schristos #ifndef lint
51ce0c0e02Schristos #if 0
52ce0c0e02Schristos static char rcsid[] = "$OpenBSD: perm.c,v 1.1 1997/03/01 23:40:12 millert Exp $";
53ce0c0e02Schristos #else
54*d9047ae6Sdholland __RCSID("$NetBSD: perm.c,v 1.4 2016/03/13 00:32:09 dholland Exp $");
55ce0c0e02Schristos #endif
56ce0c0e02Schristos #endif
57ce0c0e02Schristos 
58ce0c0e02Schristos /* Local functions */
59ce0c0e02Schristos 
605f256bd3Schristos static bool
check_for_user(FILE * fp,const char * name)619ff98d4dSmjl check_for_user(FILE *fp, const char *name)
62ce0c0e02Schristos {
63ce0c0e02Schristos 	char *buffer;
64ce0c0e02Schristos 	size_t len;
655f256bd3Schristos 	bool found = false;
66ce0c0e02Schristos 
67ce0c0e02Schristos 	len = strlen(name);
68ce0c0e02Schristos 	if ((buffer = malloc(len + 2)) == NULL)
69ce0c0e02Schristos 		panic("Insufficient virtual memory");
70ce0c0e02Schristos 
715f256bd3Schristos 	while (fgets(buffer, (int)len + 2, fp) != NULL) {
72ce0c0e02Schristos 		if (strncmp(name, buffer, len) == 0 && buffer[len] == '\n') {
735f256bd3Schristos 			found = true;
74ce0c0e02Schristos 			break;
75ce0c0e02Schristos 		}
76ce0c0e02Schristos 	}
77ce0c0e02Schristos 	(void)fclose(fp);
78ce0c0e02Schristos 	free(buffer);
795f256bd3Schristos 	return found;
80ce0c0e02Schristos }
81ce0c0e02Schristos 
82ce0c0e02Schristos /* Global functions */
83ce0c0e02Schristos 
845f256bd3Schristos bool
check_permission(void)859ff98d4dSmjl check_permission(void)
86ce0c0e02Schristos {
87ce0c0e02Schristos 	FILE *fp;
88ce0c0e02Schristos 	uid_t uid = geteuid();
89ce0c0e02Schristos 	struct passwd *pentry;
90ce0c0e02Schristos 
91ce0c0e02Schristos 	if (uid == 0)
925f256bd3Schristos 		return true;
93ce0c0e02Schristos 
94ce0c0e02Schristos 	if ((pentry = getpwuid(uid)) == NULL) {
95ce0c0e02Schristos 		perror("Cannot access user database");
96ce0c0e02Schristos 		exit(EXIT_FAILURE);
97ce0c0e02Schristos 	}
98ce0c0e02Schristos 
99*d9047ae6Sdholland 	privs_enter();
100ce0c0e02Schristos 
101ce0c0e02Schristos 	fp = fopen(_PATH_AT_ALLOW, "r");
102ce0c0e02Schristos 
103*d9047ae6Sdholland 	privs_exit();
104ce0c0e02Schristos 
105ce0c0e02Schristos 	if (fp != NULL) {
1065f256bd3Schristos 		return check_for_user(fp, pentry->pw_name);
107ce0c0e02Schristos 	} else {
108*d9047ae6Sdholland 		privs_enter();
109ce0c0e02Schristos 
110ce0c0e02Schristos 		fp = fopen(_PATH_AT_DENY, "r");
111ce0c0e02Schristos 
112*d9047ae6Sdholland 		privs_exit();
113ce0c0e02Schristos 
114ce0c0e02Schristos 		if (fp != NULL)
1155f256bd3Schristos 			return !check_for_user(fp, pentry->pw_name);
116ce0c0e02Schristos 	}
1175f256bd3Schristos 	return false;
118ce0c0e02Schristos }
119