xref: /minix3/usr.bin/write/term_chk.c (revision 00709a7737e9715e29a192fe59a95679b88d2887)
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