18626Sguido/************************************************************************
28626Sguido* Copyright 1995 by Wietse Venema.  All rights reserved.
38626Sguido*
48626Sguido* This material was originally written and compiled by Wietse Venema at
58626Sguido* Eindhoven University of Technology, The Netherlands, in 1990, 1991,
68626Sguido* 1992, 1993, 1994 and 1995.
78626Sguido*
88626Sguido* Redistribution and use in source and binary forms are permitted
98626Sguido* provided that this entire copyright notice is duplicated in all such
108874Srgrimes* copies.
118626Sguido*
128626Sguido* This software is provided "as is" and without any expressed or implied
138626Sguido* warranties, including, without limitation, the implied warranties of
148626Sguido* merchantibility and fitness for any particular purpose.
158626Sguido************************************************************************/
162224Sguido/*
172224Sguido    SYNOPSIS
182224Sguido	void login_fbtab(tty, uid, gid)
192224Sguido	char *tty;
202224Sguido	uid_t uid;
212224Sguido	gid_t gid;
222224Sguido
232224Sguido    DESCRIPTION
242224Sguido	This module implements device security as described in the
252224Sguido	SunOS 4.1.x fbtab(5) and SunOS 5.x logindevperm(4) manual
262224Sguido	pages. The program first looks for /etc/fbtab. If that file
272224Sguido	cannot be opened it attempts to process /etc/logindevperm.
28228992Suqs	We expect entries with the following format:
292224Sguido
302224Sguido	    Comments start with a # and extend to the end of the line.
312224Sguido
322224Sguido	    Blank lines or lines with only a comment are ignored.
332224Sguido
342224Sguido	    All other lines consist of three fields delimited by
352224Sguido	    whitespace: a login device (/dev/console), an octal
362224Sguido	    permission number (0600), and a ":"-delimited list of
372224Sguido	    devices (/dev/kbd:/dev/mouse). All device names are
3833358Sjb	    absolute paths. A path that ends in "*" refers to all
392224Sguido	    directory entries except "." and "..".
402224Sguido
412224Sguido	    If the tty argument (relative path) matches a login device
422224Sguido	    name (absolute path), the permissions of the devices in the
432224Sguido	    ":"-delimited list are set as specified in the second
442224Sguido	    field, and their ownership is changed to that of the uid
452224Sguido	    and gid arguments.
462224Sguido
472224Sguido    DIAGNOSTICS
482224Sguido	Problems are reported via the syslog daemon with severity
492224Sguido	LOG_ERR.
502224Sguido
512224Sguido    BUGS
522224Sguido	This module uses strtok(3), which may cause conflicts with other
532224Sguido	uses of that same routine.
542224Sguido
552224Sguido    AUTHOR
562224Sguido	Wietse Venema (wietse@wzv.win.tue.nl)
572224Sguido	Eindhoven University of Technology
582224Sguido	The Netherlands
592224Sguido */
602224Sguido
6187233Smarkm#include <sys/cdefs.h>
6287233Smarkm__FBSDID("$FreeBSD$");
6387233Smarkm
642224Sguido#include <sys/types.h>
6529922Smarkm#include <sys/stat.h>
662224Sguido#include <errno.h>
6785504Srwatson#include <glob.h>
6869793Sobrien#include <paths.h>
6987180Smarkm#include <stdio.h>
7087180Smarkm#include <string.h>
7187180Smarkm#include <syslog.h>
7229922Smarkm#include <unistd.h>
7387173Smarkm
74200462Sdelphij#include "login.h"
752224Sguido#include "pathnames.h"
762224Sguido
7792920Simpstatic void	login_protect(const char *, char *, int, uid_t, gid_t);
782224Sguido
792224Sguido#define	WSPACE		" \t\n"
802224Sguido
812224Sguido/* login_fbtab - apply protections specified in /etc/fbtab or logindevperm */
822224Sguido
832224Sguidovoid
84201382Sedlogin_fbtab(char *tty, uid_t uid, gid_t gid)
852224Sguido{
862224Sguido    FILE   *fp;
872224Sguido    char    buf[BUFSIZ];
882224Sguido    char   *devname;
892224Sguido    char   *cp;
902224Sguido    int     prot;
9187173Smarkm    const char *table;
922224Sguido
93172261Skevlo    if ((fp = fopen(table = _PATH_FBTAB, "r")) == NULL
94172261Skevlo    && (fp = fopen(table = _PATH_LOGINDEVPERM, "r")) == NULL)
952224Sguido	return;
962224Sguido
972224Sguido    while (fgets(buf, sizeof(buf), fp)) {
9829922Smarkm	if ((cp = strchr(buf, '#')))
992224Sguido	    *cp = 0;				/* strip comment */
1002224Sguido	if ((cp = devname = strtok(buf, WSPACE)) == 0)
1012224Sguido	    continue;				/* empty or comment */
10269793Sobrien	if (strncmp(devname, _PATH_DEV, sizeof _PATH_DEV - 1) != 0
103231651Skevlo	       || (cp = strtok(NULL, WSPACE)) == 0
1042224Sguido	       || *cp != '0'
1052224Sguido	       || sscanf(cp, "%o", &prot) == 0
1062224Sguido	       || prot == 0
1072224Sguido	       || (prot & 0777) != prot
108231651Skevlo	       || (cp = strtok(NULL, WSPACE)) == 0) {
1092224Sguido	    syslog(LOG_ERR, "%s: bad entry: %s", table, cp ? cp : "(null)");
1102224Sguido	    continue;
1112224Sguido	}
1122224Sguido	if (strcmp(devname + 5, tty) == 0) {
113231651Skevlo	    for (cp = strtok(cp, ":"); cp; cp = strtok(NULL, ":")) {
1142224Sguido		login_protect(table, cp, prot, uid, gid);
1152224Sguido	    }
1162224Sguido	}
1172224Sguido    }
1182224Sguido    fclose(fp);
1192224Sguido}
1202224Sguido
1212224Sguido/* login_protect - protect one device entry */
1222224Sguido
1232224Sguidovoid
124201382Sedlogin_protect(const char *table, char *pattern, int mask, uid_t uid, gid_t gid)
1252224Sguido{
12685645Srwatson    glob_t  gl;
12785645Srwatson    char   *path;
128169342Sdwmalone    unsigned int     i;
1292224Sguido
13085645Srwatson    if (glob(pattern, GLOB_NOSORT, NULL, &gl) != 0)
13185645Srwatson	return;
13285645Srwatson    for (i = 0; i < gl.gl_pathc; i++) {
13385645Srwatson	path = gl.gl_pathv[i];
13485645Srwatson	/* clear flags of the device */
13585645Srwatson	if (chflags(path, 0) && errno != ENOENT && errno != EOPNOTSUPP)
13685645Srwatson	    syslog(LOG_ERR, "%s: chflags(%s): %m", table, path);
13785645Srwatson	if (chmod(path, mask) && errno != ENOENT)
13885645Srwatson	    syslog(LOG_ERR, "%s: chmod(%s): %m", table, path);
13985645Srwatson	if (chown(path, uid, gid) && errno != ENOENT)
14085645Srwatson	    syslog(LOG_ERR, "%s: chown(%s): %m", table, path);
14185645Srwatson    }
14285645Srwatson    globfree(&gl);
1432224Sguido}
144