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> 6887180Smarkm#include <stdio.h> 6987180Smarkm#include <string.h> 7087180Smarkm#include <syslog.h> 7129922Smarkm#include <unistd.h> 7287173Smarkm 73200462Sdelphij#include "login.h" 742224Sguido#include "pathnames.h" 752224Sguido 7692920Simpstatic void login_protect(const char *, char *, int, uid_t, gid_t); 772224Sguido 782224Sguido#define WSPACE " \t\n" 792224Sguido 802224Sguido/* login_fbtab - apply protections specified in /etc/fbtab or logindevperm */ 812224Sguido 822224Sguidovoid 83201382Sedlogin_fbtab(char *tty, uid_t uid, gid_t gid) 842224Sguido{ 852224Sguido FILE *fp; 862224Sguido char buf[BUFSIZ]; 872224Sguido char *devname; 882224Sguido char *cp; 892224Sguido int prot; 9087173Smarkm const char *table; 912224Sguido 92172261Skevlo if ((fp = fopen(table = _PATH_FBTAB, "r")) == NULL 93172261Skevlo && (fp = fopen(table = _PATH_LOGINDEVPERM, "r")) == NULL) 942224Sguido return; 952224Sguido 962224Sguido while (fgets(buf, sizeof(buf), fp)) { 9729922Smarkm if ((cp = strchr(buf, '#'))) 982224Sguido *cp = 0; /* strip comment */ 992224Sguido if ((cp = devname = strtok(buf, WSPACE)) == 0) 1002224Sguido continue; /* empty or comment */ 10169793Sobrien if (strncmp(devname, _PATH_DEV, sizeof _PATH_DEV - 1) != 0 102231651Skevlo || (cp = strtok(NULL, WSPACE)) == 0 1032224Sguido || *cp != '0' 1042224Sguido || sscanf(cp, "%o", &prot) == 0 1052224Sguido || prot == 0 1062224Sguido || (prot & 0777) != prot 107231651Skevlo || (cp = strtok(NULL, WSPACE)) == 0) { 1082224Sguido syslog(LOG_ERR, "%s: bad entry: %s", table, cp ? cp : "(null)"); 1092224Sguido continue; 1102224Sguido } 1112224Sguido if (strcmp(devname + 5, tty) == 0) { 112231651Skevlo for (cp = strtok(cp, ":"); cp; cp = strtok(NULL, ":")) { 1132224Sguido login_protect(table, cp, prot, uid, gid); 1142224Sguido } 1152224Sguido } 1162224Sguido } 1172224Sguido fclose(fp); 1182224Sguido} 1192224Sguido 1202224Sguido/* login_protect - protect one device entry */ 1212224Sguido 122288164Sdelphijstatic void 123201382Sedlogin_protect(const char *table, char *pattern, int mask, uid_t uid, gid_t gid) 1242224Sguido{ 12585645Srwatson glob_t gl; 12685645Srwatson char *path; 127169342Sdwmalone unsigned int i; 1282224Sguido 12985645Srwatson if (glob(pattern, GLOB_NOSORT, NULL, &gl) != 0) 13085645Srwatson return; 13185645Srwatson for (i = 0; i < gl.gl_pathc; i++) { 13285645Srwatson path = gl.gl_pathv[i]; 13385645Srwatson /* clear flags of the device */ 13485645Srwatson if (chflags(path, 0) && errno != ENOENT && errno != EOPNOTSUPP) 13585645Srwatson syslog(LOG_ERR, "%s: chflags(%s): %m", table, path); 13685645Srwatson if (chmod(path, mask) && errno != ENOENT) 13785645Srwatson syslog(LOG_ERR, "%s: chmod(%s): %m", table, path); 13885645Srwatson if (chown(path, uid, gid) && errno != ENOENT) 13985645Srwatson syslog(LOG_ERR, "%s: chown(%s): %m", table, path); 14085645Srwatson } 14185645Srwatson globfree(&gl); 1422224Sguido} 143