Setting chmod

Discussion in 'Perl Misc' started by John, Mar 9, 2008.

  1. John

    John Guest

    $sec=open(TEKST,">test.txt");
    chmod 0600,$sec;
    binmode(TEKST);
    print TEKST ""hello world";
    close TEKST;


    Why is the test.txt not chmodded to 0600 but to 0755
     
    John, Mar 9, 2008
    #1
    1. Advertising

  2. John <> writes:

    > Why is the test.txt not chmodded to 0600 but to 0755


    Because $sec is not a file name or a file handle. It's a good idea to
    check if any file operation succeeded:

    open(TEKST,">test.txt") or die $!;
    chmod 0600,*TEKST or die $!;
    binmode(TEKST);
    print TEKST "hello world";
    close TEKST;


    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 9, 2008
    #2
    1. Advertising

  3. Joost Diepenmaat wrote:
    > John <> writes:
    >> Why is the test.txt not chmodded to 0600 but to 0755

    >
    > Because $sec is not a file name or a file handle. It's a good idea to
    > check if any file operation succeeded:
    >
    > open(TEKST,">test.txt") or die $!;
    > chmod 0600,*TEKST or die $!;


    With sysopen() you can do it in one step:

    sysopen TEKST, 'test.txt', O_WRONLY|O_CREAT, 0600 or die $!;

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Mar 9, 2008
    #3
  4. John

    John Guest

    Joost Diepenmaat <> wrote:

    >John <> writes:
    >
    >> Why is the test.txt not chmodded to 0600 but to 0755

    >
    >Because $sec is not a file name or a file handle. It's a good idea to
    >check if any file operation succeeded:
    >
    >open(TEKST,">test.txt") or die $!;
    >chmod 0600,*TEKST or die $!;
    >binmode(TEKST);
    >print TEKST "hello world";
    >close TEKST;


    I still got different result. This time I've got 0644
     
    John, Mar 9, 2008
    #4
  5. John <> writes:

    > Joost Diepenmaat <> wrote:
    >>Because $sec is not a file name or a file handle. It's a good idea to
    >>check if any file operation succeeded:
    >>
    >>open(TEKST,">test.txt") or die $!;
    >>chmod 0600,*TEKST or die $!;
    >>binmode(TEKST);
    >>print TEKST "hello world";
    >>close TEKST;

    >
    > I still got different result. This time I've got 0644


    That's strange. With that code you should only get permissions of 0600
    or less (when umask is set to something other than 0).

    What are the owners and permissions of text.txt and its containing
    directory prior to running the command?

    What operating system & perl version are you using?

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 9, 2008
    #5
  6. John wrote:
    > Joost Diepenmaat <> wrote:
    >> John <> writes:
    >>> Why is the test.txt not chmodded to 0600 but to 0755

    >>
    >> Because $sec is not a file name or a file handle. It's a good idea to
    >> check if any file operation succeeded:
    >>
    >> open(TEKST,">test.txt") or die $!;
    >> chmod 0600,*TEKST or die $!;
    >> binmode(TEKST);
    >> print TEKST "hello world";
    >> close TEKST;

    >
    > I still got different result. This time I've got 0644


    Did you check the return value from chmod() as suggested? When I run the
    code as above, I got a "No such file or directory" error message. Then I
    tried

    chmod 0600, 'test.txt' or die $!;

    which worked.

    Please also see my other message in this thread.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Mar 9, 2008
    #6
  7. Gunnar Hjalmarsson <> writes:

    >>> open(TEKST,">test.txt") or die $!;
    >>> chmod 0600,*TEKST or die $!;
    >>> binmode(TEKST);
    >>> print TEKST "hello world";
    >>> close TEKST;


    [ ... ]

    > Did you check the return value from chmod() as suggested? When I run
    > the code as above, I got a "No such file or directory" error
    > message.


    AFAIK the code as posted above should work in systems that support
    fchmod() - basically any recent Unix - and should generate a fatal error
    at line 2 on systems that don't.

    Whatever it does it should never give a "No such file or directory
    error". At least not at line 2.

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 9, 2008
    #7
  8. Joost Diepenmaat wrote:
    > Gunnar Hjalmarsson <> writes:
    >
    >>>> open(TEKST,">test.txt") or die $!;
    >>>> chmod 0600,*TEKST or die $!;
    >>>> binmode(TEKST);
    >>>> print TEKST "hello world";
    >>>> close TEKST;

    >
    > [ ... ]
    >
    >> Did you check the return value from chmod() as suggested? When I run
    >> the code as above, I got a "No such file or directory" error
    >> message.

    >
    > AFAIK the code as posted above should work in systems that support
    > fchmod() - basically any recent Unix - and should generate a fatal error
    > at line 2 on systems that don't.
    >
    > Whatever it does it should never give a "No such file or directory
    > error". At least not at line 2.


    $ cat test.pl
    print "$^O\n";
    open(TEKST,">test.txt") or die $!;
    chmod 0600,*TEKST or die $!;
    $ perl test.pl
    linux
    No such file or directory at test.pl line 3.
    $ ls -l test.txt
    -rw-rw-r-- 1 gunnarh gunnarh 0 Mar 9 18:42 test.txt
    $

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Mar 9, 2008
    #8
  9. Gunnar Hjalmarsson <> writes:

    > $ cat test.pl
    > print "$^O\n";
    > open(TEKST,">test.txt") or die $!;
    > chmod 0600,*TEKST or die $!;
    > $ perl test.pl
    > linux
    > No such file or directory at test.pl line 3.
    > $ ls -l test.txt
    > -rw-rw-r-- 1 gunnarh gunnarh 0 Mar 9 18:42 test.txt
    > $


    Agh. I just checked and this code only runs as I described in perl 5.8.8
    and higher. Older perls don't accept file handles as arguments to chmod.


    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 9, 2008
    #9
  10. John

    Ben Morrow Guest

    Quoth Joost Diepenmaat <>:
    > John <> writes:
    >
    > > Why is the test.txt not chmodded to 0600 but to 0755

    >
    > Because $sec is not a file name or a file handle. It's a good idea to
    > check if any file operation succeeded:
    >
    > open(TEKST,">test.txt") or die $!;
    > chmod 0600,*TEKST or die $!;


    Don't use bare globs unless you really have to. They're very magic, and
    it's always safer to use a globref when you can:

    chmod 0600, \*TEKST or die $!;

    Of course, a lexical filehandle would be better again.

    Ben
     
    Ben Morrow, Mar 9, 2008
    #10
  11. Joost Diepenmaat wrote:
    > Gunnar Hjalmarsson <> writes:
    >
    >> $ cat test.pl
    >> print "$^O\n";
    >> open(TEKST,">test.txt") or die $!;
    >> chmod 0600,*TEKST or die $!;
    >> $ perl test.pl
    >> linux
    >> No such file or directory at test.pl line 3.
    >> $ ls -l test.txt
    >> -rw-rw-r-- 1 gunnarh gunnarh 0 Mar 9 18:42 test.txt
    >> $

    >
    > Agh. I just checked and this code only runs as I described in perl 5.8.8
    > and higher. Older perls don't accept file handles as arguments to chmod.


    That explains it; I'm using v5.8.1.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Mar 10, 2008
    #11
  12. John

    John Guest

    Gunnar Hjalmarsson <> wrote:

    >Joost Diepenmaat wrote:
    >> Gunnar Hjalmarsson <> writes:
    >>
    >>> $ cat test.pl
    >>> print "$^O\n";
    >>> open(TEKST,">test.txt") or die $!;
    >>> chmod 0600,*TEKST or die $!;
    >>> $ perl test.pl
    >>> linux
    >>> No such file or directory at test.pl line 3.
    >>> $ ls -l test.txt
    >>> -rw-rw-r-- 1 gunnarh gunnarh 0 Mar 9 18:42 test.txt
    >>> $

    >>
    >> Agh. I just checked and this code only runs as I described in perl 5.8.8
    >> and higher. Older perls don't accept file handles as arguments to chmod.

    >
    >That explains it; I'm using v5.8.1.


    I am confused.
    So what should the chmod line have if I have Perl 5?
    Some say it should be *TEKST, others something else.
     
    John, Mar 10, 2008
    #12
  13. John <> writes:

    > Gunnar Hjalmarsson <> wrote:
    > I am confused.
    > So what should the chmod line have if I have Perl 5?
    > Some say it should be *TEKST, others something else.


    perl 5.8 and 5.10 are also perl 5s, but if you want to be compatible
    with older perls, it's probably best to use the optional PERMS argument
    to sysopen instead of combining open and chmod:

    use Fctnl qw(O_WRONLY);
    sysopen TEXT,"myfile.txt",O_WRONLY,0600 or die $!;

    or, possibly, use the umask() function to change the default permissions
    and then use open().

    and only use chmod() if you want to change the permissions of files
    you're not otherwise writing to.

    See perldoc -f umask and perldoc -f sysopen

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 10, 2008
    #13
  14. John

    John Guest

    Joost Diepenmaat <> wrote:

    >John <> writes:
    >
    >> Gunnar Hjalmarsson <> wrote:
    >> I am confused.
    >> So what should the chmod line have if I have Perl 5?
    >> Some say it should be *TEKST, others something else.

    >
    >perl 5.8 and 5.10 are also perl 5s, but if you want to be compatible
    >with older perls, it's probably best to use the optional PERMS argument
    >to sysopen instead of combining open and chmod:
    >
    >use Fctnl qw(O_WRONLY);
    >sysopen TEXT,"myfile.txt",O_WRONLY,0600 or die $!;
    >
    >or, possibly, use the umask() function to change the default permissions
    >and then use open().
    >
    >and only use chmod() if you want to change the permissions of files
    >you're not otherwise writing to.
    >
    >See perldoc -f umask and perldoc -f sysopen



    OK I finally found what really works without using external library:

    $sec=open(TEKST,">test.txt");
    chmod 0600,"test.txt";
    binmode(TEKST);
    print TEKST ""hello world";
    close TEKST;

    0600 everytime.
     
    John, Mar 10, 2008
    #14
  15. John <> writes:

    > OK I finally found what really works without using external library:
    >
    > $sec=open(TEKST,">test.txt");
    > chmod 0600,"test.txt";
    > binmode(TEKST);
    > print TEKST ""hello world";
    > close TEKST;
    >
    > 0600 everytime.


    Well, almost everytime: if someone else unlinks, overwrites, or moves
    the file (possibly replacing it with another) between the open() and
    chmod() call this won't do what you expect. Which is why using sysopen()
    or umask() and open() (or using perl5.8.8+'s chmod HANDLE) is better if
    you're working in a multi-tasking environment.

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 10, 2008
    #15
  16. John <> writes:

    > $sec=open(TEKST,">test.txt");
    > chmod 0600,"test.txt";


    Addendum:

    You *really* should check the return values of those calls.

    canonically:

    open(TEXT,">test.txt") or die "Can't open test.txt for writing: $!";
    chmod 0600,"test.txt" or die "Can't chmod test.txt: $!";


    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 10, 2008
    #16
  17. Abigail <> writes:
    > Well, if someone else unlinks, overwrites or moves the file, the program
    > most likely doesn't do what you expect, regardless whether this happens
    > before, or after the chmod. And your program doesn't magically do what
    > you expect under such conditions if you use sysopen.


    You're right, of course. It's just one of the things to
    consider. Another is that in this case, the file is supposed to be
    unreadable for anyone but the user writing it, but using
    chmod($filename) after an open() leaves a short time window during which
    someone else could possibly open the file for reading (or maybe even
    read+write), which would give them access to the contents of the file as
    long as they keep the handle.

    Just saying, /if/ you need to specify restrictive permissions, you
    probably want to do that it reliably as possible.

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 10, 2008
    #17
  18. Abigail <> writes:

    > I really, really dislike the attitude of many Perl people to respond
    > to question with suggestions of changing the code that have nothing
    > at all to do with the question; and all for hypothetical situations
    > which may not at all be relevant for the OP. To make matter worse,
    > those hypothetical are usually only revealed after someone asks the
    > reasons behind the suggestion.


    Which is why I said that "John"'s code would work "almost everytime" and
    provided examples of some situations were it wouldn't. Since the poster
    indicated he's new to perl he might also be new to these kinds of
    potential problems.

    I do appreciate you calling me on the above post, by the way: it made me
    think a bit harder about the security implications of the race
    condition.

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 10, 2008
    #18
  19. On 2008-03-10 18:59, Joost Diepenmaat <> wrote:
    > John <> writes:
    >> OK I finally found what really works without using external library:
    >>
    >> $sec=open(TEKST,">test.txt");
    >> chmod 0600,"test.txt";
    >> binmode(TEKST);
    >> print TEKST ""hello world";
    >> close TEKST;
    >>
    >> 0600 everytime.

    >
    > Well, almost everytime: if someone else unlinks, overwrites, or moves
    > the file (possibly replacing it with another) between the open() and
    > chmod() call this won't do what you expect.


    If that's a problem you shouldn't use open to open the file for writing
    in the first place. Another user could create a symlink named "test.txt"
    and you end up overwriting a completely different file.

    Use sysopen with the O_EXCL flag instead. Or, if it's a temporary file
    (the most common case where this is a problem) use the File::Temp
    module.

    hp
     
    Peter J. Holzer, Mar 11, 2008
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael Lubavin
    Replies:
    1
    Views:
    3,095
    Steve Grazzini
    Jul 25, 2003
  2. Brad Cooper

    Chmod from Runtime.Exec

    Brad Cooper, May 13, 2004, in forum: Java
    Replies:
    3
    Views:
    10,133
    Brad Cooper
    May 13, 2004
  3. Bob K.
    Replies:
    9
    Views:
    1,594
    PeterMcC
    Jul 5, 2004
  4. Fuzzyman

    Understanding CHMOD

    Fuzzyman, Feb 13, 2004, in forum: Python
    Replies:
    6
    Views:
    797
    Fuzzyman
    Feb 13, 2004
  5. James Colannino

    Re: weird problem with os.chmod

    James Colannino, Nov 12, 2005, in forum: Python
    Replies:
    6
    Views:
    399
    Fredrik Lundh
    Nov 12, 2005
Loading...

Share This Page