User: Password:
|
|
Subscribe / Log in / New account

Standards, the kernel, and Postfix

Standards, the kernel, and Postfix

Posted Aug 21, 2008 15:12 UTC (Thu) by epa (subscriber, #39769)
In reply to: Standards, the kernel, and Postfix by epa
Parent article: Standards, the kernel, and Postfix

Here is a handy tool to make a collection of hard links to suid or sgid binaries and keep the
collection up to date.  Use as

% mkdir suid_collection
% suid_harvester /sbin /bin /usr/sbin /usr/bin /usr/local/bin suid_collection

#!/usr/bin/perl
use warnings;
use strict;
use 5.010;
use File::Find;
use File::stat;
use Fcntl qw(:mode);
use File::Spec;

sub interesting {
    my $sb = shift;
    my $mode = $sb->mode;
    my $suid = $mode & S_ISUID;
    my $sgid = $mode & S_ISGID;
    my $uid = $sb->uid;
    my $gid = $sb->gid;
    my $xusr = $mode & S_IXUSR;
    my $xgrp = $mode & S_IXGRP;
    my $xoth = $mode & S_IXOTH;

    if ($suid) {
	if ($xoth) {
	    # suid, executable by all.
	    return 1;
	}
	elsif ($xgrp) {
	    # suid, executable by some group.
	    return 1;
	}
    }
    elsif ($sgid) {
	if ($xoth) {
	    # sgid, executable by all.
	    return 1;
	}
	elsif ($uid != 0 and $xusr) {
	    # suid, executable by someone non-root.
	    return 1;
	}
    }
    return 0;
}

die "usage: $0 source... dest\n"
  if @ARGV < 2;
my $dest = pop @ARGV;
my @source = @ARGV;
my $dest_abs = File::Spec->rel2abs($dest);
chdir $dest or die "cannot chdir to $dest: $!";
my %already;
foreach (glob '*') {
    if (/\A([0-9]+)[.].+\z/) {
	my $ino = $1;
	$already{$ino}++ && warn "two files in $dest beginning $ino.\n";
	my $sb = lstat $_;
	warn("cannot lstat $dest/$_, skipping\n"), next if not $sb;
	if (not interesting $sb) {
	    warn "sadly, $_ no longer has useful permissions\n";
	}
    }
}
sub for_each_file {
    my $sb = lstat $_;
    warn("cannot lstat $File::Find::name, skipping\n"), return if not $sb;
    my $ino = $sb->ino;
    $already{$ino}++ && return;
    return if not interesting $sb;
    my $link_to = "$ino.$_";
    say "$File::Find::name -> $link_to";
    link $File::Find::name, "$dest_abs/$link_to"
      or warn "cannot link to $link_to: $!\n";
}
find \&for_each_file, @source;


(Log in to post comments)


Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds