xref: /netbsd-src/usr.bin/write/term_chk.c (revision 44f6d24c7fd3129dd58d6593546cc865568d22dd)
1*44f6d24cSlukem /* $NetBSD: term_chk.c,v 1.8 2009/04/14 07:59:17 lukem Exp $ */
273b3e2aeSchristos 
373b3e2aeSchristos /*
473b3e2aeSchristos  * Copyright (c) 1989, 1993
573b3e2aeSchristos  *	The Regents of the University of California.  All rights reserved.
673b3e2aeSchristos  *
773b3e2aeSchristos  * This code is derived from software contributed to Berkeley by
873b3e2aeSchristos  * Jef Poskanzer and Craig Leres of the Lawrence Berkeley Laboratory.
973b3e2aeSchristos  *
1073b3e2aeSchristos  * Redistribution and use in source and binary forms, with or without
1173b3e2aeSchristos  * modification, are permitted provided that the following conditions
1273b3e2aeSchristos  * are met:
1373b3e2aeSchristos  * 1. Redistributions of source code must retain the above copyright
1473b3e2aeSchristos  *    notice, this list of conditions and the following disclaimer.
1573b3e2aeSchristos  * 2. Redistributions in binary form must reproduce the above copyright
1673b3e2aeSchristos  *    notice, this list of conditions and the following disclaimer in the
1773b3e2aeSchristos  *    documentation and/or other materials provided with the distribution.
1889aaa1bbSagc  * 3. Neither the name of the University nor the names of its contributors
1973b3e2aeSchristos  *    may be used to endorse or promote products derived from this software
2073b3e2aeSchristos  *    without specific prior written permission.
2173b3e2aeSchristos  *
2273b3e2aeSchristos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2373b3e2aeSchristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2473b3e2aeSchristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2573b3e2aeSchristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2673b3e2aeSchristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2773b3e2aeSchristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2873b3e2aeSchristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2973b3e2aeSchristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3073b3e2aeSchristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3173b3e2aeSchristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3273b3e2aeSchristos  * SUCH DAMAGE.
3373b3e2aeSchristos  */
3473b3e2aeSchristos 
3573b3e2aeSchristos #include <sys/cdefs.h>
3673b3e2aeSchristos #ifndef lint
37*44f6d24cSlukem __RCSID("$NetBSD: term_chk.c,v 1.8 2009/04/14 07:59:17 lukem Exp $");
3873b3e2aeSchristos #endif
3973b3e2aeSchristos 
4073b3e2aeSchristos #include <sys/types.h>
4173b3e2aeSchristos #include <sys/param.h>
4273b3e2aeSchristos #include <sys/stat.h>
4373b3e2aeSchristos #include <time.h>
4473b3e2aeSchristos #include <stdio.h>
4573b3e2aeSchristos #include <errno.h>
4673b3e2aeSchristos #include <unistd.h>
4773b3e2aeSchristos #include <paths.h>
4873b3e2aeSchristos #include <fcntl.h>
4973b3e2aeSchristos #include <string.h>
5073b3e2aeSchristos #include <err.h>
5173b3e2aeSchristos 
5273b3e2aeSchristos #include "term_chk.h"
5373b3e2aeSchristos 
5473b3e2aeSchristos /*
5573b3e2aeSchristos  * term_chk - check that a terminal exists, and get the message bit
5673b3e2aeSchristos  *     and the access time
5773b3e2aeSchristos  */
5873b3e2aeSchristos int
term_chk(uid_t uid,const char * tty,int * msgsokP,time_t * atimeP,int ismytty,gid_t saved_egid)5973b3e2aeSchristos term_chk(uid_t uid, const char *tty, int *msgsokP, time_t *atimeP, int ismytty,
6073b3e2aeSchristos     gid_t saved_egid)
6173b3e2aeSchristos {
6273b3e2aeSchristos 	char path[MAXPATHLEN];
6373b3e2aeSchristos 	struct stat s;
6473b3e2aeSchristos 	int i, fd, serrno;
6573b3e2aeSchristos 
6667a132acSchristos 	if (strstr(tty, "../") != NULL) {
67b0eade51Schristos 		errno = EINVAL;
68b0eade51Schristos 		return -1;
6973b3e2aeSchristos 	}
7073b3e2aeSchristos 	i = snprintf(path, sizeof path, _PATH_DEV "%s", tty);
71*44f6d24cSlukem 	if (i < 0 || i >= (int)sizeof(path)) {
72b0eade51Schristos 		errno = ENOMEM;
73b0eade51Schristos 		return -1;
7473b3e2aeSchristos 	}
7573b3e2aeSchristos 
7673b3e2aeSchristos 	(void)setegid(saved_egid);
7773b3e2aeSchristos 	fd = open(path, O_WRONLY, 0);
7873b3e2aeSchristos 	serrno = errno;
7973b3e2aeSchristos 	(void)setegid(getgid());
8073b3e2aeSchristos 	errno = serrno;
8173b3e2aeSchristos 
8273b3e2aeSchristos 	if (fd == -1)
8373b3e2aeSchristos 		return(-1);
8473b3e2aeSchristos 	if (fstat(fd, &s) == -1)
8573b3e2aeSchristos 		goto error;
86b0eade51Schristos 	if (!isatty(fd))
8773b3e2aeSchristos 		goto error;
882d67d54fSchristos 	if (s.st_uid != uid && uid != 0) {
89b0eade51Schristos 		errno = EPERM;
90b0eade51Schristos 		goto error;
91b0eade51Schristos 	}
9274c9d10cSchristos 	if (msgsokP)
9373b3e2aeSchristos 		*msgsokP = (s.st_mode & S_IWGRP) != 0;	/* group write bit */
9474c9d10cSchristos 	if (atimeP)
9573b3e2aeSchristos 		*atimeP = s.st_atime;
9673b3e2aeSchristos 	if (ismytty)
9773b3e2aeSchristos 		(void)close(fd);
98b0eade51Schristos 	return ismytty ? 0 : fd;
9973b3e2aeSchristos error:
10073b3e2aeSchristos 	if (fd != -1) {
10173b3e2aeSchristos 		serrno = errno;
102b0eade51Schristos 		(void)close(fd);
10373b3e2aeSchristos 		errno = serrno;
10473b3e2aeSchristos 	}
105b0eade51Schristos 	return -1;
10673b3e2aeSchristos }
10773b3e2aeSchristos 
10873b3e2aeSchristos char *
check_sender(time_t * atime,uid_t myuid,gid_t saved_egid)10973b3e2aeSchristos check_sender(time_t *atime, uid_t myuid, gid_t saved_egid)
11073b3e2aeSchristos {
11173b3e2aeSchristos 	int myttyfd;
11273b3e2aeSchristos 	int msgsok;
11373b3e2aeSchristos 	char *mytty;
11473b3e2aeSchristos 
11573b3e2aeSchristos 	/* check that sender has write enabled */
11673b3e2aeSchristos 	if (isatty(fileno(stdin)))
11773b3e2aeSchristos 		myttyfd = fileno(stdin);
11873b3e2aeSchristos 	else if (isatty(fileno(stdout)))
11973b3e2aeSchristos 		myttyfd = fileno(stdout);
12073b3e2aeSchristos 	else if (isatty(fileno(stderr)))
12173b3e2aeSchristos 		myttyfd = fileno(stderr);
12274c9d10cSchristos 	else if (atime == NULL)
1234b03e4a9Schristos 		return NULL;
12473b3e2aeSchristos 	else
1254b03e4a9Schristos 		errx(1, "Cannot find your tty");
1264b03e4a9Schristos 	if ((mytty = ttyname(myttyfd)) == NULL)
1274b03e4a9Schristos 		err(1, "Cannot find the name of your tty");
12867a132acSchristos 	if (strncmp(mytty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
12967a132acSchristos 		mytty += sizeof(_PATH_DEV) - 1;
13073b3e2aeSchristos 	if (term_chk(myuid, mytty, &msgsok, atime, 1, saved_egid) == -1)
13173b3e2aeSchristos 		err(1, "%s%s", _PATH_DEV, mytty);
13273b3e2aeSchristos 	if (!msgsok) {
13373b3e2aeSchristos 		warnx(
13473b3e2aeSchristos 		    "You have write permission turned off; no reply possible");
13573b3e2aeSchristos 	}
13673b3e2aeSchristos 	return mytty;
13773b3e2aeSchristos }
138