LPM: Testing for File Trustworthiness on NT

David Hempy hempy at ket.org
Thu Mar 23 22:38:48 CST 2000


Here's some food for thought:

 From the Cookbook...

>8.17. Testing a File for Trustworthiness
>
>Problem
>
>You want to read from a file, perhaps because it has configuration 
>information. You only want to use the file if it can't be written to (or 
>perhaps not even be read from) by anyone else than its owner. [...] If the 
>file is writable by someone other than the owner or is owned by someone 
>other than the current user or the superuser, it shouldn't be trusted.


I have a slight variation.  I am generating web pages in a perl 
program.   I do not want to stomp on someone's handcrafted pride and joy 
that might have the same name (such as index.html).  This is a certain 
eventuality in our environment of cohabitating generated and 
manually-created web pages.

Fortunately, the solution is the same.

Unfortunately, the Cookbook's solution doesn't work under NT, with its 
vision beyond user-group-world.


My solution:
I use the same mentality of Cookbook 8:17, using Win32::FileSecurity.

After generating the file I set the permissions such that I 
(Win32::LoginName, to be precise) have full access, and Everyone has Read 
access:


>## Takes one parameter, a file name.
>## Grants FULL access to the file for the current user.
>## Changes permissions for any others listed to READ access.
>## Returns true on success.
>sub MakeFileSafe {
>         my $file        = shift;
>
>         return 0 unless -e $file;
>
>         my $me  = Win32::DomainName . '\\' . Win32::LoginName;
>         my (%perms, $name, $mask);
>         my $readonly_access     = Win32::FileSecurity::MakeMask( qw( READ 
> ) );
>         my $full_access         = Win32::FileSecurity::MakeMask( qw( FULL 
> ) );
>
>
>         unless (Win32::FileSecurity::Get($file, \%perms) ) {
>                 warn "Can't Win32::FileSecurity::Get($file)\n<br>\n";
>                 return 0;
>         }
>
>
>         foreach my $user (keys %perms) {
>                 $perms{$user} = $readonly_access;
>         }
>
>         $perms{$me} = $full_access;
>
>         unless (Win32::FileSecurity::Set($file, \%perms) ) {
>                 warn "Can't Win32::FileSecurity::Set($file)\n<br>\n";
>                 return 0;
>         }
>
>
>         return 1;
>}



When testing to see if I can overwrite an existing file, I check to see 
that these permissions are still set.  If so, I can be reasonably sure that 
I am only overwriting my own work.  If not, I complain and ask the user to 
move or delete the offending file if they really want the target file 
generated.


>## Returns true if no other users can write to a file.
>## Takes one parameter, a file name.
>## note: Returns true if the file does not exist.
>sub FileIsSafe {
>         my $file        = shift;
>
>         return 1 unless -e $file;               ## No File is a Safe File.
>
>         my $me  = Win32::DomainName . '\\' . Win32::LoginName;
>         my (%perms, $name, $mask);
>         my $readonly_access     = Win32::FileSecurity::MakeMask( qw( READ 
> ) );
>         my $full_access         = Win32::FileSecurity::MakeMask( qw( FULL 
> ) );
>
>         Win32::FileSecurity::Get( $file, \%perms ) ;
>
>         while( ($name, $mask) = each %perms ) {
>                 #print "\n$name: $mask\n\t";
>                 #print "Read Rights\n\t"                if ($mask == 
> $readonly_access);
>                 #print "Full Rights\n\t"                if ($mask == 
> $full_access);
>
>                 unless
>                         (  $mask == $readonly_access
>                         || $name eq $me
>                         || $name =~ /\bUnknown\b/               ### This 
> appears some times with access...not sure why.
>                         ) {
>                                 #print "HEY!  $name has more than 
> read-only access!\n";
>                                 #Win32::FileSecurity::EnumerateRights( 
> $mask, \@rights ) ;
>                                 #print join( "\n\t", @rights ), "\n";
>                                 return 0;
>                 }#else {
>                 #               print "Cool... $name has appropriate 
> access!\n";
>                 #}
>
>         }
>
>         return 1;
>}


One benefit of this (the inspiration for it, actually) is that users cannot 
(readily) edit the generated html files.  If they ever *think* they do, 
they actually need to:

         1. Edit the source data,
         2. Edit the template, or
         3. Con me into fixing a bug/featurelack in the program.

"Editing the generated file" will never belong on this list.  Doing so will 
cause headaches for the user the next time the file is generated.  When 
they come to me asking permission to edit the output file, I will direct 
them to the appropriate action from the list above.  ;-)


-dave



--
David Hempy
Internet Database Administrator
Kentucky Educational Television
<hempy at ket.org> -- (606)258-7164 -- (800)333-9764




More information about the Lexington-pm mailing list