1#!/usr/bin/perl -w 2# 3# Copyright (c) 1996, 2001, 2002 Todd C. Miller <millert@openbsd.org> 4# 5# Permission to use, copy, modify, and distribute this software for any 6# purpose with or without fee is hereby granted, provided that the above 7# copyright notice and this permission notice appear in all copies. 8# 9# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16# 17# Sponsored in part by the Defense Advanced Research Projects 18# Agency (DARPA) and Air Force Research Laboratory, Air Force 19# Materiel Command, USAF, under agreement number F39502-99-1-0512. 20# 21# Prune commented out, bogus, and crufty entries from /etc/skey 22# usage: skeyprune [days] 23# 24# $OpenBSD: skeyprune.pl,v 1.8 2019/01/25 00:19:26 millert Exp $ 25# 26 27use POSIX qw(S_ISREG); 28use Fcntl qw(:DEFAULT :flock); 29 30# Keep out the stupid 31die "Only root may run $0.\n" if $>; 32die "usage: $0 [days]\n" if $#ARGV > 0; 33 34# Pathnames 35$skeydir = '/etc/skey'; 36 37# Remove entries that haven't been modified in this many days. 38$days_old = $ARGV[0] || -1; 39 40# Safe umask 41umask(077); 42 43# Current time 44$now = time(); 45 46# Slurp mode 47undef $/; 48 49chdir($skeydir) || die "$0: Can't cd to $skeydir: $!\n"; 50opendir(SKEYDIR, ".") || die "$0: Can't open $skeydir: $!\n"; 51while (defined($user = readdir(SKEYDIR))) { 52 next if $user =~ /^\./; 53 if (!sysopen(SKEY, $user, 0, O_RDWR | O_NONBLOCK | O_NOFOLLOW)) { 54 warn "$0: Can't open $user: $!\n"; 55 next; 56 } 57 if (!flock(SKEY, LOCK_EX)) { 58 warn "$0: Can't lock $user: $!\n"; 59 close(SKEY); 60 next; 61 } 62 63 if (!stat(SKEY)) { 64 warn "$0: Can't stat $user: $!\n"; 65 close(SKEY); 66 next; 67 } 68 69 # Sanity checks. 70 if (!S_ISREG((stat(_))[2])) { 71 warn "$0: $user is not a regular file\n"; 72 close(SKEY); 73 next; 74 } 75 if (((stat(_))[2] & 07777) != 0600) { 76 printf STDERR ("%s: Bad mode for %s: 0%o\n", $0, $user, 77 (stat(_))[2]); 78 close(SKEY); 79 next; 80 } 81 if ((stat(_))[3] != 1) { 82 printf STDERR ("%s: Bad link count for %s: %d\n", $0, $user, 83 (stat(_))[3]); 84 close(SKEY); 85 next; 86 } 87 88 # Remove zero size entries 89 if (-z _) { 90 unlink($user) || warn "$0: Can't unlink $user: $!\n"; 91 close(SKEY); 92 next; 93 } 94 95 # Prune out old entries if asked to 96 if ($days_old > 0) { 97 $then = (stat(_))[9]; 98 if (($now - $then) / (60 * 60 * 24) - 1 > $days_old) { 99 unlink($user) || warn "$0: Can't unlink $user: $!\n"; 100 close(SKEY); 101 next; 102 } 103 } 104 105 # Read in the entry and check its contents. 106 $entry = <SKEY>; 107 if ($entry !~ /^\S+[\r\n]+\S+[\r\n]+\d+[\r\n]+[A-z0-9]+[\r\n]+[a-f0-9]+[\r\n]+$/) { 108 warn "$0: Invalid entry for $user:\n$entry"; 109 } 110 111 close(SKEY); 112} 113exit(0); 114