1*00709a77SThomas Cort /* $NetBSD: term_chk.c,v 1.8 2009/04/14 07:59:17 lukem Exp $ */
2*00709a77SThomas Cort
3*00709a77SThomas Cort /*
4*00709a77SThomas Cort * Copyright (c) 1989, 1993
5*00709a77SThomas Cort * The Regents of the University of California. All rights reserved.
6*00709a77SThomas Cort *
7*00709a77SThomas Cort * This code is derived from software contributed to Berkeley by
8*00709a77SThomas Cort * Jef Poskanzer and Craig Leres of the Lawrence Berkeley Laboratory.
9*00709a77SThomas Cort *
10*00709a77SThomas Cort * Redistribution and use in source and binary forms, with or without
11*00709a77SThomas Cort * modification, are permitted provided that the following conditions
12*00709a77SThomas Cort * are met:
13*00709a77SThomas Cort * 1. Redistributions of source code must retain the above copyright
14*00709a77SThomas Cort * notice, this list of conditions and the following disclaimer.
15*00709a77SThomas Cort * 2. Redistributions in binary form must reproduce the above copyright
16*00709a77SThomas Cort * notice, this list of conditions and the following disclaimer in the
17*00709a77SThomas Cort * documentation and/or other materials provided with the distribution.
18*00709a77SThomas Cort * 3. Neither the name of the University nor the names of its contributors
19*00709a77SThomas Cort * may be used to endorse or promote products derived from this software
20*00709a77SThomas Cort * without specific prior written permission.
21*00709a77SThomas Cort *
22*00709a77SThomas Cort * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23*00709a77SThomas Cort * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24*00709a77SThomas Cort * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25*00709a77SThomas Cort * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26*00709a77SThomas Cort * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27*00709a77SThomas Cort * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28*00709a77SThomas Cort * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29*00709a77SThomas Cort * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30*00709a77SThomas Cort * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31*00709a77SThomas Cort * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32*00709a77SThomas Cort * SUCH DAMAGE.
33*00709a77SThomas Cort */
34*00709a77SThomas Cort
35*00709a77SThomas Cort #include <sys/cdefs.h>
36*00709a77SThomas Cort #ifndef lint
37*00709a77SThomas Cort __RCSID("$NetBSD: term_chk.c,v 1.8 2009/04/14 07:59:17 lukem Exp $");
38*00709a77SThomas Cort #endif
39*00709a77SThomas Cort
40*00709a77SThomas Cort #include <sys/types.h>
41*00709a77SThomas Cort #include <sys/param.h>
42*00709a77SThomas Cort #include <sys/stat.h>
43*00709a77SThomas Cort #include <time.h>
44*00709a77SThomas Cort #include <stdio.h>
45*00709a77SThomas Cort #include <errno.h>
46*00709a77SThomas Cort #include <unistd.h>
47*00709a77SThomas Cort #include <paths.h>
48*00709a77SThomas Cort #include <fcntl.h>
49*00709a77SThomas Cort #include <string.h>
50*00709a77SThomas Cort #include <err.h>
51*00709a77SThomas Cort
52*00709a77SThomas Cort #include "term_chk.h"
53*00709a77SThomas Cort
54*00709a77SThomas Cort /*
55*00709a77SThomas Cort * term_chk - check that a terminal exists, and get the message bit
56*00709a77SThomas Cort * and the access time
57*00709a77SThomas Cort */
58*00709a77SThomas Cort int
term_chk(uid_t uid,const char * tty,int * msgsokP,time_t * atimeP,int ismytty,gid_t saved_egid)59*00709a77SThomas Cort term_chk(uid_t uid, const char *tty, int *msgsokP, time_t *atimeP, int ismytty,
60*00709a77SThomas Cort gid_t saved_egid)
61*00709a77SThomas Cort {
62*00709a77SThomas Cort char path[MAXPATHLEN];
63*00709a77SThomas Cort struct stat s;
64*00709a77SThomas Cort int i, fd, serrno;
65*00709a77SThomas Cort
66*00709a77SThomas Cort if (strstr(tty, "../") != NULL) {
67*00709a77SThomas Cort errno = EINVAL;
68*00709a77SThomas Cort return -1;
69*00709a77SThomas Cort }
70*00709a77SThomas Cort i = snprintf(path, sizeof path, _PATH_DEV "%s", tty);
71*00709a77SThomas Cort if (i < 0 || i >= (int)sizeof(path)) {
72*00709a77SThomas Cort errno = ENOMEM;
73*00709a77SThomas Cort return -1;
74*00709a77SThomas Cort }
75*00709a77SThomas Cort
76*00709a77SThomas Cort (void)setegid(saved_egid);
77*00709a77SThomas Cort fd = open(path, O_WRONLY, 0);
78*00709a77SThomas Cort serrno = errno;
79*00709a77SThomas Cort (void)setegid(getgid());
80*00709a77SThomas Cort errno = serrno;
81*00709a77SThomas Cort
82*00709a77SThomas Cort if (fd == -1)
83*00709a77SThomas Cort return(-1);
84*00709a77SThomas Cort if (fstat(fd, &s) == -1)
85*00709a77SThomas Cort goto error;
86*00709a77SThomas Cort if (!isatty(fd))
87*00709a77SThomas Cort goto error;
88*00709a77SThomas Cort if (s.st_uid != uid && uid != 0) {
89*00709a77SThomas Cort errno = EPERM;
90*00709a77SThomas Cort goto error;
91*00709a77SThomas Cort }
92*00709a77SThomas Cort if (msgsokP)
93*00709a77SThomas Cort *msgsokP = (s.st_mode & S_IWGRP) != 0; /* group write bit */
94*00709a77SThomas Cort if (atimeP)
95*00709a77SThomas Cort *atimeP = s.st_atime;
96*00709a77SThomas Cort if (ismytty)
97*00709a77SThomas Cort (void)close(fd);
98*00709a77SThomas Cort return ismytty ? 0 : fd;
99*00709a77SThomas Cort error:
100*00709a77SThomas Cort if (fd != -1) {
101*00709a77SThomas Cort serrno = errno;
102*00709a77SThomas Cort (void)close(fd);
103*00709a77SThomas Cort errno = serrno;
104*00709a77SThomas Cort }
105*00709a77SThomas Cort return -1;
106*00709a77SThomas Cort }
107*00709a77SThomas Cort
108*00709a77SThomas Cort char *
check_sender(time_t * atime,uid_t myuid,gid_t saved_egid)109*00709a77SThomas Cort check_sender(time_t *atime, uid_t myuid, gid_t saved_egid)
110*00709a77SThomas Cort {
111*00709a77SThomas Cort int myttyfd;
112*00709a77SThomas Cort int msgsok;
113*00709a77SThomas Cort char *mytty;
114*00709a77SThomas Cort
115*00709a77SThomas Cort /* check that sender has write enabled */
116*00709a77SThomas Cort if (isatty(fileno(stdin)))
117*00709a77SThomas Cort myttyfd = fileno(stdin);
118*00709a77SThomas Cort else if (isatty(fileno(stdout)))
119*00709a77SThomas Cort myttyfd = fileno(stdout);
120*00709a77SThomas Cort else if (isatty(fileno(stderr)))
121*00709a77SThomas Cort myttyfd = fileno(stderr);
122*00709a77SThomas Cort else if (atime == NULL)
123*00709a77SThomas Cort return NULL;
124*00709a77SThomas Cort else
125*00709a77SThomas Cort errx(1, "Cannot find your tty");
126*00709a77SThomas Cort if ((mytty = ttyname(myttyfd)) == NULL)
127*00709a77SThomas Cort err(1, "Cannot find the name of your tty");
128*00709a77SThomas Cort if (strncmp(mytty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
129*00709a77SThomas Cort mytty += sizeof(_PATH_DEV) - 1;
130*00709a77SThomas Cort if (term_chk(myuid, mytty, &msgsok, atime, 1, saved_egid) == -1)
131*00709a77SThomas Cort err(1, "%s%s", _PATH_DEV, mytty);
132*00709a77SThomas Cort if (!msgsok) {
133*00709a77SThomas Cort warnx(
134*00709a77SThomas Cort "You have write permission turned off; no reply possible");
135*00709a77SThomas Cort }
136*00709a77SThomas Cort return mytty;
137*00709a77SThomas Cort }
138