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