At 10:36 AM 11/13/01 +1030, Daniel Falkenberg wrote:
>Hi all,
>
>Can this code below be issued from an actual perl script?
>
>perl -F: -i -ape'$F[3] == 45 && $_ =~ /^test/ && s/^/*/' /etc/passwd

That's a very good question.  Naturally, the answer is Yes.

One way we can 'cheat' is to use B::Deparse, which, confusingly, is invoked 
as though it were called O::Deparse.  It'll tell us what the code 'really' is:

% perl -MO=Deparse -F: -i -ape'$F[3] == 45 && $_ =~ /^test/ && s/^/*/' 
/etc/passwd
LINE: while (defined($_ = <ARGV>)) {
     @F = split(/:/, $_, 0);
     s/^/*/ if $F[3] == 45 and $_ =~ /^test/;
}
continue {
     print $_;
}
-e syntax OK

Well, that's accurate... except for ignoring the -i flag... but not quite 
as good as we'd like, yet it's a nice illustration anyway.  So allow me to 
do a hand translation:

#!/usr/bin/perl
use warnings;
use strict;

open PWD, "/etc/passwd" or die "Can't open /etc/passwd: $!\n";
open TMP, ">/tmp/passwd.$$" or die "Can't write /tmp/passwd.$$: $!\n";
while (<PWD>) {
   my ($user, $gid) = (split /:/)[0,3];
   s/^/*/ if $user =~ /^test/ and $gid == 45;
   print TMP;
}
close PWD;
close TMP;
rename "/tmp/passwd.$$", "/etc/passwd" or die "Problem with rename: $!\n";

Note: the code you posted *rewrites /etc/passwd in place*.  This is *cough* 
risky, at least without knowing exactly what you're doing.  So just because 
I posted code that does the same thing doesn't mean that I've removed any 
of that risk.

And yeah, some people could point out security problems with what I posted, 
ways it could be exploited by a sufficiently malicious, intelligent, and 
lucky hacker on the same machine.  Your one-liner suffered from the same 
problems AFAICT.  You need to be in a position to assess whether that risk 
is significant.
--
Peter Scott
Pacific Systems Design Technologies
http://www.perldebugged.com


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to