Annotation of src/usr.bin/login/login_fbtab.c, Revision 1.1
1.1 ! deraadt 1: /************************************************************************
! 2: * Copyright 1995 by Wietse Venema. All rights reserved.
! 3: *
! 4: * This material was originally written and compiled by Wietse Venema at
! 5: * Eindhoven University of Technology, The Netherlands, in 1990, 1991,
! 6: * 1992, 1993, 1994 and 1995.
! 7: *
! 8: * Redistribution and use in source and binary forms are permitted
! 9: * provided that this entire copyright notice is duplicated in all such
! 10: * copies.
! 11: *
! 12: * This software is provided "as is" and without any expressed or implied
! 13: * warranties, including, without limitation, the implied warranties of
! 14: * merchantibility and fitness for any particular purpose.
! 15: ************************************************************************/
! 16: /*
! 17: SYNOPSIS
! 18: void login_fbtab(tty, uid, gid)
! 19: char *tty;
! 20: uid_t uid;
! 21: gid_t gid;
! 22:
! 23: DESCRIPTION
! 24: This module implements device security as described in the
! 25: SunOS 4.1.x fbtab(5) and SunOS 5.x logindevperm(4) manual
! 26: pages. The program first looks for /etc/fbtab. If that file
! 27: cannot be opened it attempts to process /etc/logindevperm.
! 28: We expect entries with the folowing format:
! 29:
! 30: Comments start with a # and extend to the end of the line.
! 31:
! 32: Blank lines or lines with only a comment are ignored.
! 33:
! 34: All other lines consist of three fields delimited by
! 35: whitespace: a login device (/dev/console), an octal
! 36: permission number (0600), and a ":"-delimited list of
! 37: devices (/dev/kbd:/dev/mouse). All device names are
! 38: absolute paths. A path that ends in "*" refers to all
! 39: directory entries except "." and "..".
! 40:
! 41: If the tty argument (relative path) matches a login device
! 42: name (absolute path), the permissions of the devices in the
! 43: ":"-delimited list are set as specified in the second
! 44: field, and their ownership is changed to that of the uid
! 45: and gid arguments.
! 46:
! 47: DIAGNOSTICS
! 48: Problems are reported via the syslog daemon with severity
! 49: LOG_ERR.
! 50:
! 51: BUGS
! 52: This module uses strtok(3), which may cause conflicts with other
! 53: uses of that same routine.
! 54:
! 55: AUTHOR
! 56: Wietse Venema (wietse@wzv.win.tue.nl)
! 57: Eindhoven University of Technology
! 58: The Netherlands
! 59: */
! 60:
! 61: #include <sys/types.h>
! 62: #include <stdio.h>
! 63: #include <syslog.h>
! 64: #include <string.h>
! 65: #include <errno.h>
! 66: #include <dirent.h>
! 67: #include "pathnames.h"
! 68:
! 69: void login_protect __P((char *, char *, int, uid_t, gid_t));
! 70: void login_fbtab __P((char *tty, uid_t uid, gid_t gid));
! 71:
! 72: #define WSPACE " \t\n"
! 73:
! 74: /*
! 75: * login_fbtab - apply protections specified in /etc/fbtab or logindevperm
! 76: */
! 77: void
! 78: login_fbtab(tty, uid, gid)
! 79: char *tty;
! 80: uid_t uid;
! 81: gid_t gid;
! 82: {
! 83: FILE *fp;
! 84: char buf[BUFSIZ], *devname, *cp, *table;
! 85: int prot;
! 86:
! 87: if ((fp = fopen(table = _PATH_FBTAB, "r")) == NULL)
! 88: return;
! 89:
! 90: while (fgets(buf, sizeof(buf), fp)) {
! 91: if (cp = strchr(buf, '#'))
! 92: *cp = 0; /* strip comment */
! 93: if ((cp = devname = strtok(buf, WSPACE)) == 0)
! 94: continue; /* empty or comment */
! 95: if (strncmp(devname, "/dev/", sizeof("/dev/")) != 0 ||
! 96: (cp = strtok((char *) 0, WSPACE)) == 0 ||
! 97: *cp != '0' ||
! 98: sscanf(cp, "%o", &prot) == 0 ||
! 99: prot == 0 ||
! 100: (prot & 0777) != prot ||
! 101: (cp = strtok((char *) 0, WSPACE)) == 0) {
! 102: syslog(LOG_ERR, "%s: bad entry: %s", table,
! 103: cp ? cp : "(null)");
! 104: continue;
! 105: }
! 106: if (strcmp(devname + 5, tty) == 0)
! 107: for (cp = strtok(cp, ":"); cp; cp = strtok(NULL, ":"))
! 108: login_protect(table, cp, prot, uid, gid);
! 109: }
! 110: fclose(fp);
! 111: }
! 112:
! 113: /*
! 114: * login_protect - protect one device entry
! 115: */
! 116: void
! 117: login_protect(table, path, mask, uid, gid)
! 118: char *table;
! 119: char *path;
! 120: int mask;
! 121: uid_t uid;
! 122: gid_t gid;
! 123: {
! 124: char buf[BUFSIZ];
! 125: int pathlen = strlen(path);
! 126: struct dirent *ent;
! 127: DIR *dir;
! 128:
! 129: if (strcmp("/*", path + pathlen - 2) != 0) {
! 130: if (chmod(path, mask) && errno != ENOENT)
! 131: syslog(LOG_ERR, "%s: chmod(%s): %m", table, path);
! 132: if (chown(path, uid, gid) && errno != ENOENT)
! 133: syslog(LOG_ERR, "%s: chown(%s): %m", table, path);
! 134: } else {
! 135: strncpy(buf, path, sizeof buf);
! 136: buf[pathlen - 1] = 0;
! 137: if ((dir = opendir(buf)) == 0) {
! 138: syslog(LOG_ERR, "%s: opendir(%s): %m", table, path);
! 139: } else {
! 140: while ((ent = readdir(dir))) {
! 141: if (strcmp(ent->d_name, ".") &&
! 142: strcmp(ent->d_name, "..")) {
! 143: strncpy(buf + pathlen - 1, ent->d_name,
! 144: sizeof(buf) - pathlen - 1);
! 145: login_protect(table, buf, mask,
! 146: uid, gid);
! 147: }
! 148: }
! 149: closedir(dir);
! 150: }
! 151: }
! 152: }