MOON
Server: Apache/2.2.31 (Unix) mod_ssl/2.2.31 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4
System: Linux csr818.wilogic.com 2.6.18-419.el5xen #1 SMP Fri Feb 24 22:50:37 UTC 2017 x86_64
User: digitals (531)
PHP: 5.4.45
Disabled: NONE
Upload Files
File: //proc/self/root/proc/self/root/scripts.20110531.215904.25158/safetybits.pl
#!/usr/bin/perl

#map (removed) - not safe with perlcc

################################################################
# safe_chown - Operates exactly like perl's chown, only it does
#   NOT chown hard or soft linked files.
# Params:
#    UID - User's numeric ID or user's name.
#    GID - User's numeric ID, or undef if user name is provided.
#    Files- A list of files to chown.
sub safe_chown {
   my ($uid, $gid, @files) = @_;
   my $count = 0;

   if ($uid !~ m/^\d+$/) { 
     $uid = (getpwnam($uid))[2]; 
   }
   if ($gid !~ m/^\d+$/) {
     $gid = (getgrnam($gid))[2];
   } elsif ($gid == -2) {
      $gid = (getpwuid($uid))[3];
   }

   if ($uid eq "" || $gid eq "") { print "safe_chown: Error Fetching the uid/gid"; return(); }
 
   foreach my $file (@files) {
      if ( (-l $file) || (ishardlink($file)) ) {
	 #print "${file} is a link. Not changing ownership.\n";
         next;
      }
      chown $uid, $gid, $file;
      $count++;
   }
   return $count;
}

##################################################################
# safe_recchown
#    See safe_chown.
#    This function provides the same functionality as safe_chown
#  only it provides a recursive interface for chowning entire 
#  directory trees.
sub safe_recchown {
   my ($uid,$gid,@files) = @_;
   my $count = 0;
   if ($uid !~ m/^\d+$/) { 
     $uid = (getpwnam($uid))[2]; 
   }
   if ($gid !~ m/^\d+$/) {
     $gid = (getgrnam($gid))[2];
   } elsif ($gid == -2) {
      $gid = (getpwuid($uid))[3];
   }
   if ($uid eq "" || $gid eq "") { print "safe_recchown: Error Fetching the uid/gid"; return(); }
   foreach my $file (@files) {
      next if (-l $file) || (ishardlink($file));
      if (-d $file) {
         opendir(DIR,$file);
         my @nfiles = grep { !/^\.+$/ } readdir(DIR);
	      my @newfiles;
	      foreach my $nfile (@nfiles) {
		      push(@newfiles,"${file}/${nfile}");
	      }
         closedir(DIR);
         $count += safe_recchown($uid,$gid,@newfiles);
      }
      $file =~ /(.*)/; $file = $1;
      chown $uid, $gid, $file;
      $count++;
   }
   return $count;
}


##################################################################
# safe_lrecchown
#    See safe_chown.
#    This function provides the same functionality as safe_chown
#  only it provides a recursive interface for chowning entire 
#  directory trees.  However it only checks for symlinks and 
#  not hard links
sub safe_lrecchown {
   my ($uid,$gid,@files) = @_;
   my $count = 0;


   if ($uid !~ m/^\d+$/) { 
     $uid = (getpwnam($uid))[2]; 
   }
   if ($gid !~ m/^\d+$/) {
     $gid = (getgrnam($gid))[2];
   } elsif ($gid == -2) {
      $gid = (getpwuid($uid))[3];
   }

   if ($uid eq "" || $gid eq "") { print "safe_lrecchown: Error Fetching the uid/gid"; return(); }

   foreach my $file (@files) {
      next if (-l $file);
      if (-d $file) {
         opendir(DIR,$file);
         my @nfiles = grep { !/^\.+$/ } readdir(DIR);
	      my @newfiles;
	      foreach my $nfile (@nfiles) {
		      push(@newfiles,"${file}/${nfile}");
	      }
         closedir(DIR);
         $count += safe_lrecchown($uid,$gid,@newfiles);
      }
      $file =~ /(.*)/; $file = $1;
      chown $uid, $gid, $file;
      $count++;
   }
   return $count;
}


#################################################################
sub ishardlink {
   my ($file) = @_;
   return if ( -d $file );

   my $linkage = (stat($file))[3];
   
   return ($linkage > 1)?1:0;
}


################################################################
# safe_chmod - Provides a perl-like interface to chmod.
#    Prior to chmoding a file, safe_chmod setuid's to the
#    given user.
# Params:
#    Perms  - Numeric permissions to chmod the file.
#    User   - User's UID or User name.
#    Files  - Array of files to chmod.
sub safe_chmod {
   my ($perms, $user, @files) = @_;
                                                                                                                                                             
   if ($user !~ m/^-?\d+$/) { $user = (getpwnam($user))[2]; }

   my @dirs = ();
   my @files2 = ();
   my $dircnt = 0;


   foreach my $file (@files) {
       if (-d "$file") {
           push(@dirs,"$file");
       } else {
           push(@files2,"$file");
       }
   }
   # Allow setgid directories that are not the user's group
   if (@dirs) {

       foreach my $dir (@dirs) {
           if ($user == ((stat("$dir"))[4])) {
               $dircnt = $dircnt + chmod $perms,$dir;
           }
       }
   }

   if (@files2) {

       if ($pid = fork()) {
           waitpid($pid,0);
       } else {
	      if ($> != ${user}) {
		      setuids($user);
	      }
           foreach my $file (@files2) {
               chmod $perms,$file;
           }
	   exit();
       }
   }
   return (($#files2 + 1) + $dircnt);
}

################################################################
# safe_recchmod - A recursive version of safe_chmod
sub safe_recchmod {
   my ($perms, $user, @files) = @_;
   my $count=0;

   if ($user !~ m/^\d+$/) { $user = (getpwnam($user))[2]; }

   if ($pid = fork()) {
      waitpid($pid,0);
   } else {
      if ($> != ${user}) {
	      setuids($user);
      }
      foreach my $file (@files) {
         if ( -d $file ) {
            opendir(DIR,$file);
            my @nfiles = grep { !/^\./ } readdir(DIR);
            my @newfiles;
            foreach my $nfile (@nfiles) {
               $nfile =~ s/(.*)/$1/;
               push @newfiles, "${file}/${nfile}";
            }
            closedir(DIR);
            $count += safe_recchmod($perms,$user,@newfiles);
         }
         $file =~ /(.*)/; $file = $1;
         chmod $perms,$file;
         $count++;
      }
      exit();
   }
   return $count;
}


################################################################
sub setuids {
   my($user) = $_[0];
   my($uid,$gid);

   if ($< != 0) { warn "Attempting to setuid as user $>"; return(); }

   if ($user !~ /^\d+$/) {
      (undef,undef,$uid,$gid) = getpwnam($user);
   }
   else { 
      $uid = $user;
      $gid = (getpwuid($uid))[3];
   }
   if ( ! ($( = int($gid)) ) {
         print "error setting gid\n";
         exit;
   }
                                                                                                                                                             
   if ( ! ($) = "$gid $gid") ) {
      print "error setting gid\n";
      exit;
   }
   if (! (($< = $uid) && ($> = $uid)) ) {
      die "error setting uid ($uid) [$user]\n";
   }
   return $uid;
}


sub runasuser {
	my($user,@CMDS) = @_;

	if ($pid = fork()) {
		waitpid($pid,0);
	} else {
		setuids($user);
		exec(@CMDS);
		exit();
	}
}
1;