Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Questions with sysopen (code)

by deprecated (Priest)
on Sep 19, 2002 at 18:59 UTC ( #199259=perlquestion: print w/ replies, xml ) Need Help??
deprecated has asked for the wisdom of the Perl Monks concerning the following question:

A friend of mine gave me the below code today and tells me it is exhibiting some strange behaviour. He is using sysopen to modify a passwd file to edit it in place. His hope is that should a user need to read it, he isn't going to clobber it while they're reading it. I'm not sure how much traffic is involved here, but he is concerned about it, so I didn't ask any questions.
#!/usr/local/bin/perl use strict; use warnings; use Fcntl qw(:DEFAULT :flock); # sysopen(PASSWD, "./passwd", O_RDWR) open (PASSWD, "+>>./passwd") or die "can't open passwd file ($!)"; flock(PASSWD, LOCK_EX); # or die "can't get lock on passwd file ($!)"; my @temp; foreach my $readLine (PASSWD) { chomp $readline; my ( $name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell ) = split /:/, $readLine; if ($name eq "www") { $shell =~ s[/bin/bash][/dev/null]; } my $line = join ':', ($name,$passwd,$uid,$gid,$quota,$comment,$gcos, +$dir,$shell); push @temp, $line; } truncate (PASSWD, 0); foreach my $user (@temp) { print PASSWD "$user\n"; } close (PASSWD);
He says that what it eventually does is obliterate the file and replace it with the text
PASSWD::::::::
This strikes me as rather bizarre. Now, this is on linux on x86, and perl 5.5. I suggested he use File::Slurp (/me bows down and worships File::Slurp). However, this script needs to be deployed to > 4000 machines, and installing modules is simply not an option (I have entertained the possibility of just taking the code from the module and putting it in the script, that seems reasonable).

I'm concerned because I can't think of any reason why it would be doing this. Any ideas, Monks?

el dep mas fina

--
Laziness, Impatience, Hubris, and Generosity.

Comment on Questions with sysopen (code)
Select or Download Code
Re: Questions with sysopen (code)
by Zaxo (Archbishop) on Sep 19, 2002 at 19:32 UTC

    That is a cumbersome way to do it. Have your friend look at getpwent, setpwent and friends. User::pwent is in the standard distribution, and preferred to the core functions.

    That said, is it a typo in line 16 that PASSWD lacks the diamond operator? The symptoms you describe suggest that reading fails, unchecked, followed by truncate. That is reckless.

    After Compline,
    Zaxo

Re: Questions with sysopen (code)
by VSarkiss (Monsignor) on Sep 19, 2002 at 19:32 UTC

    It may be just a copy-and-paste artifact, but this line: foreach my $readLine (PASSWD) {
    should have angle brackets: foreach my $readLine (<PASSWD>) {
    (Surmise: he's not using strict.)

    Now, if that loop does nothing, the rest of the program will truncate the file and write a single line to it, the result you're seeing. Of course, File::Slurp doesn't have this problem because the loop isn't needed.

    The fact that it works sometimes makes me think there may be something else going on, but this is something to check.

    HTH

Re: Questions with sysopen (code)
by Thelonius (Curate) on Sep 19, 2002 at 19:35 UTC
    The immediate problem is this line:
    foreach my $readLine (PASSWD) {
    Perhaps you meant something like <PASSWD>?

    However, you should never do this:

    truncate (PASSWD, 0);
    with an important file like passwd! What you do is write a new file that has the changes you want and then mv the new file over the old file.
      ...after cp'ing the old file to passwd.bak, just in case your script REALLY screws up...
      --
      Mike
Re: passwd + command line options
by fglock (Vicar) on Sep 19, 2002 at 19:53 UTC

    If you'd play with perl command-line options (such as -p, -l and -i) this line might have all you need (you could use -a and -F/:/ for splitting too)

    s[:/bin/bash$][:/dev/null$] if /^www:/

    Note: You have to check how it works under shared access.

Re: Questions with sysopen (code)
by Aristotle (Chancellor) on Sep 19, 2002 at 20:34 UTC
    Use /bin/false over /dev/null. Also, no need to use Perl. # chsh -s /bin/false www
    See man chsh.

    Makeshifts last the longest.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://199259]
Approved by dws
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2014-09-24 02:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (244 votes), past polls