home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
-
- # Usage: suidscript [dirlist]
-
- # Make list of filenames to do find on.
-
- if ($#ARGV >= 0) {
- @list = @ARGV;
- foreach $name (@ARGV) {
- die "You must use absolute pathnames.\n"
- unless $name =~ m|^/|;
- }
- }
- else {
- open(MT,"/etc/mount|") || die "Can't run /etc/mount: $!\n";
-
- while (<MT>) {
- chop;
- $_ .= <MT> if length($_) < 50;
- @ary = split;
- push(@list,$ary[2]) if ($ary[0] =~ m|^/dev|);
- }
- close MT;
- $? && die "Couldn't run mount.\n";
- }
-
- die "Can't find local filesystems" unless @list;
-
- # Find all the set-id files.
-
- open(FIND, "find @list -xdev -type f " .
- "\\( -perm -04000 -o -perm -02000 \\) -print|");
-
- while (<FIND>) {
- chop;
- next unless -T; # Not a text file.
-
- # Move script out of the way.
-
- print "Fixing ", $_, "\n";
- ($dir,$file) = m#(.*)/(.*)#;
- chdir $dir || die "Can't chdir to $dir: $!\n";
- ($dev,$ino,$mode,$nlink,$uid,$gid) = stat($file);
- die "Can't stat $_" unless $ino;
- chmod $mode & 01777, $file; # wipe out set[ug]id bits
- rename($file,".$file");
-
- # Now write the wrapper.
-
- open(C,">.tmp$$.c") || die "Can't write C program for $_";
- $real = "$dir/.$file";
- print C <<EOW;
- main(argc,argv)
- int argc;
- char **argv;
- {
- execv("$real",argv);
- }
- EOW
- close C;
-
- # Now compile the wrapper.
-
- system '/bin/cc', ".tmp$$.c", '-o', $file;
- die "Can't compile new $_" if $?;
-
- # Straighten out loose ends.
-
- chown $uid, $gid, $file;
- chmod $mode, $file;
- unlink ".tmp$$.c";
- chdir '/';
- }
-