Re: S16: chown, chmod

2008-12-01 Thread Mark Overmeer
* Martin D Kealey ([EMAIL PROTECTED]) [081202 04:37]:
> On Tue, 25 Nov 2008, Dave Whipp wrote:
> 
> sub setstat(String|File $filename, StatBuf $stat) {
> ...
> if $caps.CAP_FOWNER {
>   # we're privileged, so it *should* just work.
>   POSIX::chown $filename, $stat.uid, $stat.gid;
>   POSIX::chmod $filename, Fcntl::ST_PERM($stat.mode);
>   POSIX::utime $filename, $stat.mtime, $stat.atime;
>   return;
> ...
> if catching_exception(IO_error) {
>   throw IO_error(EPERM, $filename, "Can't give file away");

Implementing things this way is as big a mistake as doing this:
(Perl5 syntax)

   if(-r $fn)
   {   open READ, '<', $fn;
   while(  )

For the two reasons:
  (1) you have a race condition: the permission may change between
  the test and the actual open().  In very rare cases, which
  makes those bug hard to trace
  (2) the check itself is flawed: whether you can chown() does not
  only depend on the OS, but also on the disk: might be a CD-ROM.

The only correct way to implement it, is simply try chown() and
handle the error.  Yes, you need quite more code for that.
-- 
   MarkOv


   Mark Overmeer MScMARKOV Solutions
   [EMAIL PROTECTED]  [EMAIL PROTECTED]
http://Mark.Overmeer.net   http://solutions.overmeer.net



Re: S16: chown, chmod

2008-12-01 Thread Martin D Kealey
On Tue, 25 Nov 2008, Dave Whipp wrote:
> Brandon S. Allbery KF8NH wrote:
> > Still misunderstanding, I think.  Yes, it will fail anyway, but in the
> > general case you're checking to see if as a privileged process it is safe to
> > operate on a given file.
>
> I'd actually been thinking that one would use the check in the opposite
> direction:
>
> if need_priv() {
>   sudo { ... }; # might ask user for passwd
> }
> else {
>   ...
> }
>
> But then I'm not an expert in this area: I just want an API that makes it easy
> to hack simple scripts that do what I need. It was C that I really
> wanted to improve the API for; I touched C only because it was adjacent
> in the POD, and it seems reasonable for the two functions/methods to have
> similar look&feel.

I've been wondering about this idiom, used when copying files:

  my $s = POSIX::stat($filename1);
  POSIX_extensions::setstat($filename2, $s);

where setstat() is a combination of chown, chmod and utime -- in the right
order to make them work as best as possible. The type of check contemplated
in this thread would then come in handy for implementing setstat().

If an unprivileged user can give away a file then that change has to be the
last thing done to the file. Otherwise changing the permissions should be
done last, so as to maintain the set*id bits. So I would envisage it would
look a bit like this (please excuse my obvious hand-waving pseudocode):

sub setstat(String|File $filename, StatBuf $stat) {
  use fatal :everything;

  if $stat.uid != any(POSIX::getuid(), POSIX::geteuid()) |
 $stat.gid != any(POSIX::getgid(), POSIX::getegid(), POSIX::getgroups()) {

# we need to give the file away

my $caps = POSIX_1e::capget();

if $caps.CAP_FOWNER {
  # we're privileged, so it *should* just work.
  POSIX::chown $filename, $stat.uid, $stat.gid;
  POSIX::chmod $filename, Fcntl::ST_PERM($stat.mode);
  POSIX::utime $filename, $stat.mtime, $stat.atime;
  return;
}
if $caps.CAP_CHOWN | !chown.need_priv() {
  # we have enough privilege to give the file away, but not enough to
  # touch it after we've done so.
  POSIX::chmod $filename, Fcntl::ST_PERM($stat.mode);
  POSIX::utime $filename, $stat.mtime, $stat.atime;
  POSIX::chown $filename, $stat.uid, $stat.gid;
  return;
}
if catching_exception(IO_error) {
  throw IO_error(EPERM, $filename, "Can't give file away");
}
  }
  # can't (or don't need to) give file away
  POSIX::chmod $filename, Fcntl::ST_PERM($stat.mode);
  POSIX::utime $filename, $stat.mtime, $stat.atime;
}

-Martin


Re: S16: chown, chmod

2008-11-26 Thread Aristotle Pagaltzis
* Brandon S. Allbery KF8NH <[EMAIL PROTECTED]> [2008-11-25 07:25]:
> OTOH Perl has historically not said much about doing that kind
> of thing.

And I’m not in favour of it starting now. All I am saying is that
APIs should be designed to encourage correct designs; arguably
this is the spirit of Perl 6, which says TMTOWTDI yet tries to
provide one good default way of doing any particular thing.

Regards,
-- 
Aristotle Pagaltzis // 


Re: S16: chown, chmod

2008-11-25 Thread Dave Whipp

Brandon S. Allbery KF8NH wrote:
Still misunderstanding, I think.  Yes, it will fail anyway, but in the 
general case you're checking to see if as a privileged process it is 
safe to operate on a given file. 


I'd actually been thinking that one would use the check in the opposite 
direction:


if need_priv() {
  sudo { ... }; # might ask user for passwd
}
else {
  ...
}

But then I'm not an expert in this area: I just want an API that makes 
it easy to hack simple scripts that do what I need. It was C that 
I really wanted to improve the API for; I touched C only because 
it was adjacent in the POD, and it seems reasonable for the two 
functions/methods to have similar look&feel.


Re: S16: chown, chmod

2008-11-24 Thread Brandon S. Allbery KF8NH

On 2008 Nov 24, at 10:45, dpuu wrote:

PS. From S16, q{ ...  On POSIX systems, you can detect this condition
this way:
   use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
   $can_chown_giveaway = not sysconf(_PC_CHOWN_RESTRICTED);
}

From this I inferred that the purpose of this assignment was to do a
check -- I apologize if I misinterpreted it -- and would suggest that
we should either get rid of that text, or else reword to suggest not
using it in bad ways.


The latter, I think; it can be useful to know whether the system  
permits or not (although you also need to use pathconf() to check if  
the filesystem in question allows it or not), but using it as a  
*security* check is a bad idea.  OTOH Perl has historically not said  
much about doing that kind of thing.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH




Re: S16: chown, chmod

2008-11-24 Thread Brandon S. Allbery KF8NH

On 2008 Nov 24, at 10:36, dpuu wrote:

On Nov 23, 3:56 pm, [EMAIL PROTECTED] (Brandon S. Allbery KF8NH)
wrote:

I think you're seeing something other than what we are.  Checking any
external resource before operating on it introduces a race condition
which can allow an attacker to swap resources on you, so the item you
(in this case) chown() isn't the one you tested.


If the "chown" is restricted then it's going to fail anyway, assuming
that the underlying Unix function fails. If "chown" can succeed
incorrectly then there's nothing that P6 can do to prevent that. My


Still misunderstanding, I think.  Yes, it will fail anyway, but in the  
general case you're checking to see if as a privileged process it is  
safe to operate on a given file.  In such case the correct thing to do  
is relinquish privilege and then simply do the operation, trapping any  
error --- not testing and then doing it.


(I grant this isn't quite the same thing --- unless you're trying to  
decide if your root process should chown() a file on behalf of an  
unprivileged process.)


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH




Re: S16: chown, chmod

2008-11-24 Thread dpuu
On Nov 23, 4:55 pm, [EMAIL PROTECTED] (Aristotle Pagaltzis) wrote:

> I don’t see any examples in S16 concerning error handling anyway,
> but even so I don’t see how relying on exceptions would could
> possibly be more complex than guard clauses.

Neither do I. Catching Failure objects is better than explicit checks
(except where performance implications exist and are relevant to the
application -- which isn't the case here).

Dave.


PS. From S16, q{ ...  On POSIX systems, you can detect this condition
this way:
use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
$can_chown_giveaway = not sysconf(_PC_CHOWN_RESTRICTED);
}

>From this I inferred that the purpose of this assignment was to do a
check -- I apologize if I misinterpreted it -- and would suggest that
we should either get rid of that text, or else reword to suggest not
using it in bad ways.



Re: S16: chown, chmod

2008-11-24 Thread dpuu
On Nov 23, 3:56 pm, [EMAIL PROTECTED] (Brandon S. Allbery KF8NH)
wrote:

> I think you're seeing something other than what we are.  Checking any  
> external resource before operating on it introduces a race condition  
> which can allow an attacker to swap resources on you, so the item you  
> (in this case) chown() isn't the one you tested.

If the "chown" is restricted then it's going to fail anyway, assuming
that the underlying Unix function fails. If "chown" can succeed
incorrectly then there's nothing that P6 can do to prevent that. My
only reason for mentioning the "is restricted" check (or, indeed,
knowing that it existed) is that the existing S16 suggested using it.
I completely agree that returning a failure object is a better
approach -- which is why that is what I changed the Synopsis to say.



Re: S16: chown, chmod

2008-11-23 Thread Aristotle Pagaltzis
* dpuu <[EMAIL PROTECTED]> [2008-11-24 00:40]:
> I agree that the specific example of &chown.is_restricted is a
> bad idea, but only because the POSIX API I was wrapping is
> itself flawed.

It is not flawed in the least, as far as the aspect we are
talking about is concerned. (It is generally sane in far more
ways than it is flawed.)

> In general I would continue to pursue the approach of adding
> precondition-checks as methods on functions, a concept that is
> orthogonal to the specific example you are arguing against

In general? Sure. But for filesystem operations? Bad idea.

> I disagree that the code I showed is not simpler that the
> original S16 approach.

I don’t see any examples in S16 concerning error handling anyway,
but even so I don’t see how relying on exceptions would could
possibly be more complex than guard clauses. You *still* have to
handle errors after the guard clause passes and the operation is
attempted.

Regards,
-- 
Aristotle Pagaltzis // 


Re: S16: chown, chmod

2008-11-23 Thread Brandon S. Allbery KF8NH

On 2008 Nov 23, at 18:35, dpuu wrote:

On Nov 23, 2:33 pm, [EMAIL PROTECTED] (Aristotle Pagaltzis) wrote:

The API you propose does not seem to me to shorten code at all
and is likely to lead to problematic code, so it seems like a
bad idea. Interfaces should be designed to encourage people to
do things correctly and to make it hard to even think about the
nearly certainly wrong way.


I'm going to both agree and disagree. I agree that the specific
example of &chown.is_restricted is a bad idea, but only because the
POSIX API I was wrapping is itself flawed. In general I would continue


I think you're seeing something other than what we are.  Checking any  
external resource before operating on it introduces a race condition  
which can allow an attacker to swap resources on you, so the item you  
(in this case) chown() isn't the one you tested.  (In this case, if  
you're chown()ing to root, an attacker might substitute a shell for  
the file you tested.)


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH




Re: S16: chown, chmod

2008-11-23 Thread dpuu
On Nov 23, 2:33 pm, [EMAIL PROTECTED] (Aristotle Pagaltzis) wrote:
> The API you propose does not seem to me to shorten code at all
> and is likely to lead to problematic code, so it seems like a
> bad idea. Interfaces should be designed to encourage people to
> do things correctly and to make it hard to even think about the
> nearly certainly wrong way.

I'm going to both agree and disagree. I agree that the specific
example of &chown.is_restricted is a bad idea, but only because the
POSIX API I was wrapping is itself flawed. In general I would continue
to pursue the approach of adding precondition-checks as methods on
functions, a concept that is orthogonal to the specific example you
are arguing against: I disagree that the code I showed is not simpler
that the original S16 approach.



Re: S16: chown, chmod

2008-11-23 Thread Aristotle Pagaltzis
* Larry Wall <[EMAIL PROTECTED]> [2008-11-21 23:55]:
> Any you could even do it in parallel:
>
> my @status = hyper map { .io.chmod($mode) }, @files
>
> though it's possible your sysadmin will complain about what
> you're doing with the disk drive heads.  :)

Actually I/O subsystems are smart enough these days that this
might be a sensible thing to do. It would distribute to multiple
disks without much affecting the single-disk case.

Over on the git list, Linus Torvalds just implemented naïvely
threaded `stat`ing for certain cases in `git log` and `git diff`,
and people with git repositories on NFS filesystems reported
3–6-fold speedups of these commands, without the local case being
adversely affected.



Regards,
-- 
Aristotle Pagaltzis // 


Re: S16: chown, chmod

2008-11-23 Thread Aristotle Pagaltzis
* dpuu <[EMAIL PROTECTED]> [2008-11-21 19:00]:
> The definition of C includes the statement that it's not
> available on most system unless you're superuser; and this can
> be checked using a POSIX incantation. I was wondering if it
> would be reasonable to provide this as a method on the chown
> function, so that a user could say:
>
>  if &chown.is_restricted {
>...
>  }
>  else {
>chown $user, $group <== @files
>  }

As has been mentioned by others this is a bad idea. All atomic
operations on filesystems boil down to attempting an operation
and dealing with the fallout if it fails. Attempting to check
whether an operation will succeed prior to attempting it almost
invariably leads to broken code. (Worse: subtly broke code, in
most cases.)

The API you propose does not seem to me to shorten code at all
and is likely to lead to problematic code, so it seems like a
bad idea. Interfaces should be designed to encourage people to
do things correctly and to make it hard to even think about the
nearly certainly wrong way.

Regards,
-- 
Aristotle Pagaltzis // 


Re: S16: chown, chmod

2008-11-22 Thread dpuu
On Nov 22, 12:46 am, [EMAIL PROTECTED] (Brandon S. Allbery KF8NH)
wrote:
> On 2008 Nov 21, at 14:13, Dave Whipp wrote:
>
> > The restriction of chown to the superuser is a property of the OS,  
> > not the files. The example from the pod is:
>
> man pathconf

Ah, thanks for that.

It's probably an unproductive rats nest to attempt to add abstractions
for all these APIs, so I assume we'll have a "use IO::pathconf" pragma
that adds a global pathconf function, plus an IO.pathconf method, to
access these properties.



Re: S16: chown, chmod

2008-11-22 Thread Brandon S. Allbery KF8NH

On 2008 Nov 21, at 14:13, Dave Whipp wrote:
The restriction of chown to the superuser is a property of the OS,  
not the files. The example from the pod is:


man pathconf

--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH




Re: S16: chown, chmod

2008-11-22 Thread Brandon S. Allbery KF8NH

On 2008 Nov 21, at 13:20, Larry Wall wrote:

On Fri, Nov 21, 2008 at 09:57:30AM -0800, dpuu wrote:
: On Nov 21, 9:16 am, [EMAIL PROTECTED] (Larry Wall) wrote:
: > Please feel free to whack on the spec
: The definition of C includes the statement that it's not
: available on most system unless you're superuser; and this can be
: checked using a POSIX incantation. I was wondering if it would be
: reasonable to provide this as a method on the chown function, so  
that


This won't work; _PC_CHOWN_RESTRICTED is per filesystem.   
(_POSIX_CHOWN_RESTRICTED is global but insufficient.)


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH




Re: S16: chown, chmod

2008-11-21 Thread Dave Whipp

Larry Wall wrote:

On Fri, Nov 21, 2008 at 11:46:48AM -0800, dpuu wrote:
: before I attempt to change the POD, would this wording be appropriate?

It's a good first whack, though we might want to think about making
it a little less P5ish/Unixish in changing a list of files, and rely
instead of one of P6's distribution mechanisms, such as hypers or maps:

my @status = @files».io».chmod($mode);

> [...]

I think that can be accomplished by adding corresponding methods to the 
IO class.


I don't have write permissions for the pugs repository, so I've attached 
the file, including the addition of chmod and chown methods to the IO class.



=encoding utf8

=head1 Title

DRAFT: Synopsis 16: IPC / IO / Signals

=head1 Version

 Author:Largely, the authors of the related Perl 5 docs.
 Maintainer:Larry Wall <[EMAIL PROTECTED]>
 Contributions: Mark Stosberg <[EMAIL PROTECTED]>
 Date:  12 Sep 2006
 Last Modified: 1 May 2007
 Version:   17

This is a draft document. Many of these functions will work as in Perl
5, except we're trying to rationalize everything into packages.  For
now you can assume most of the important functions will automatically
be in the * namespace.  However, with IO operations in particular,
many of them are really methods on an IO handle, and if there is a
corresponding global function, it's merely an exported version of
the method.

As a starting point, you can help by finding the official Perl 5 documentation
for these functions and copying it here. 

=head1 Filehandles, files, and directories

=over 4

=item IO ~~ :X
X<:r>X<:w>X<:x>X<:o>X<:R>X<:W>X<:X>X<:O>X<:e>X<:z>X<:s>X<:f>X<:d>X<:l>X<:p>
X<:S>X<:b>X<:c>X<:t>X<:u>X<:g>X<:k>X<:T>X<:B>X<:M>X<:A>X<:C>

=item EXPR ~~ :X

  $file.:X
  $file ~~ :X

A file test, where X is one of the letters listed below.  This unary
operator takes one argument, either a filename or a filehandle, and
tests the associated file to see if something is true about it.

A Pair used as a pattern is treated as a file test.

:r  File is readable by effective uid/gid.
:w  File is writable by effective uid/gid.
:x  File is executable by effective uid/gid.
:o  File is owned by effective uid.

:R  File is readable by real uid/gid.
:W  File is writable by real uid/gid.
:X  File is executable by real uid/gid.
:O  File is owned by real uid.

:e  File exists.
:z  File has zero size (is empty).
:s  File has nonzero size (returns size in bytes).

:f  File is a plain file.
:d  File is a directory.
:l  File is a symbolic link.
:p  File is a named pipe (FIFO), or Filehandle is a pipe.
:S  File is a socket.
:b  File is a block special file.
:c  File is a character special file.
:t  Filehandle is opened to a tty.

:u  File has setuid bit set.
:g  File has setgid bit set.
:k  File has sticky bit set.

:T  File is an ASCII text file (heuristic guess).
:B  File is a "binary" file (opposite of :T).

:M  Script start time minus file modification time, in days.
:A  Same for access time.
:C  Same for inode change time (Unix, may differ for other platforms)

The interpretation of the file permission operators C<:r>, C<:R>,
C<:w>, C<:W>, C<:x>, and C<:X> is by default based solely on the mode
of the file and the uids and gids of the user.  There may be other
reasons you can't actually read, write, or execute the file.  Such
reasons may be for example network filesystem access controls, ACLs
(access control lists), read-only filesystems, and unrecognized
executable formats.

Also note that, for the superuser on the local filesystems, the C<:r>,
C<:R>, C<:w>, and C<:W> tests always return 1, and C<:x> and C<:X> return 1
if any execute bit is set in the mode.  Scripts run by the superuser
may thus need to do a stat() to determine the actual mode of the file,
or temporarily set their effective uid to something else.

If you are using ACLs, there is a pragma called C that may
produce more accurate results than the bare stat() mode bits.
When under the C the above-mentioned filetests
will test whether the permission can (not) be granted using the
access() family of system calls.  Also note that the C<:x> and C<:X> may
under this pragma return true even if there are no execute permission
bits set (nor any extra execute permission ACLs).  This strangeness is
due to the underlying system calls' definitions.  Read the
documentation for the C pragma for more information.

The C<:T> and C<:B> switches work as follows.  The first block or so of the
file is examined for odd characters such as strange control codes or
characters with the high bit set.  If too many strange characters (>30%)
are found, it's a C<:B> file; otherwise it's a C<:T> file.  Also, any file
containing null in the first block is considered a binary file.  If C<:T>
or C<:B> is used on a filehandle, the current IO buffer is examined
rather than the first block.  Both C<:T> and C<:B> return true on a null
f

Re: S16: chown, chmod

2008-11-21 Thread Dave Whipp
The restriction of chown to the superuser is a property of the OS, not the 
files. The example from the pod is:

use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
my $can_chown_giveaway = not sysconf(_PC_CHOWN_RESTRICTED);

Thinking about it, perhaps that means that it's a method on $*OS.

The use of filetest operators as a way to specify the desired chmod modes
seems good, but I'm not sure how to specify the signature. I can imagine:

our multi chmod ( Int $mode, [EMAIL PROTECTED] );
our multi chmod ( PermissionModifier :$owner,
  PermissionModifier :$group,
  PermissionModifier :$other,
 [EMAIL PROTECTED]);

but I'm not sure how to define that a PermissionModifer object can be created
as a chain of positive and negative options so that these would work:

@exe_files ==> chmod :owner( :x ), :group( :x ), :other( :!x );
@my_files  ==> chmod :owner( :r :w ), :group( :r :!w ), :other( :!r :!w );

There would be a little less line-noise if these could be passed as:

@my_files ==> chmod :owner :group :other;





From: Moritz Lenz <[EMAIL PROTECTED]>
To: dpuu <[EMAIL PROTECTED]>
Cc: perl6-language@perl.org
Sent: Friday, November 21, 2008 10:30:08 AM
Subject: Re: S16: chown, chmod

dpuu wrote:
> Question: is it appropriate to P6 look&feel to have methods on
> functions?

I don't think that's such a good idea in this case. If a file is
chown'able is not a property of the chown function, but of the file.

> The definition of C includes the statement that it's not
> available on most system unless you're superuser; and this can be
> checked using a POSIX incantation. I was wondering if it would be
> reasonable to provide this as a method on the chown function, so that
> a user could say:
> 
>   if &chown.is_restricted {
> ...
>   }
>   else {
> chown $user, $group <== @files
>   }


I'd rather go with the "try it and fail() if you can't" approach, partly
because of race conditions, partly because it's much more reliable in
the presence of extended security models (think of SeLinux for example).

If 'use fatal' is in effect, that dies, if not, you can check the return
value.


For chmod() I could imagine an interface like this:

$file.chmod(:8<540>);
$file.chmod( :set, :user => :r & :x, :group => :r)
   # both same as 'chmod 540 $file'

$file.chmod( :modifiy, :other => :!x)
   # same as 'chmod o-x $file'

Cheers,
Moritz

-- 
Moritz Lenz
http://perlgeek.de/ |  http://perl-6.de/ | http://sudokugarden.de/


Re: S16: chown, chmod

2008-11-21 Thread Larry Wall
On Fri, Nov 21, 2008 at 11:46:48AM -0800, dpuu wrote:
: before I attempt to change the POD, would this wording be appropriate?

It's a good first whack, though we might want to think about making
it a little less P5ish/Unixish in changing a list of files, and rely
instead of one of P6's distribution mechanisms, such as hypers or maps:

my @status = @files».io».chmod($mode);
my @status = map { .io.chmod($mode) }, @files;
my @status = (for @files { .io.chmod($mode) });

The advantage of this approach is that you don't get complete failure
if only one of the files failed to change.  Any you could even do it
in parallel:

my @status = hyper map { .io.chmod($mode) }, @files

though it's possible your sysadmin will complain about what you're
doing with the disk drive heads.  :)

Of course, along with the methods we could also provide the old-fashioned
functions so that someone can write a FAQ telling people not to use them. :)

It's also possible that «*.c *.h».io.chmod($mode) should do something
dwimmy, given «...» is defined as "shell quoting".  And maybe IO
objects themselves can track multiple files, similar to how we can
turn @*ARGS into a single abstract file handle.

Larry


Re: S16: chown, chmod

2008-11-21 Thread dpuu
before I attempt to change the POD, would this wording be appropriate?

=item chown

our multi chown (Int $uid, Int $gid, Str|IO [EMAIL PROTECTED])
our multi chown (Str $user, Str $group, Str|IO [EMAIL PROTECTED])

Changes the owner (and/or group) of a list of files. The new
ownership can be specified either as integers or as strings.
If an argument is either a negative integer or undefined then
the ownership (or group membership) of the files will be
unchanged.

A True value will be returned if the operation succeeds,
otherwise the function will C.

The list of files may contain strings and/or filehandles.
Strings are interpretted as filenames.  On systems that don't
support C the use of file handles will result in
failure

When $user or $group are passed as strings, the implementation
will convert this name to the underlying uid/gid using a
function such as getpwnam.

On most systems, you are not allowed to change the ownership of
the file unless you?re the superuser, although you should be
able to change the group to any of your secondary groups.  On
insecure systems, these restrictions may be relaxed, but this
is not a portable assumption.  On POSIX systems, you can detect
this condition this way:

use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
$can_chown_giveaway = not sysconf(_PC_CHOWN_RESTRICTED);

=item chmod

our multi chmod( Int $mode, Str|IO [EMAIL PROTECTED] );
our multi chmod( PermissionModifier :$user?, PermissionModifier :
$group?, PermissionModifier :$other?, Str|IO [EMAIL PROTECTED] );

class PermissionModifier {
  submethod BUILD ( Bool :$r, Bool :$w, Bool :$x );
  ...
};

Changes the permissions of a list of files. Returns a true value if
the operation is sucessful on all the files, otherwise C.

The files to modify can be given either as Strings, or FileHandles.

The permissions can be provided as either a single integer,
corresponding
to the underlying Unix permissions mode value, or as named options
using PermissionModifier objects.

A PermissionModifier object is constructed using options similar
to filetest operators. :r, :w and :x (and their inverted forms).
If a given option is not included in the object that the corresponding
permission mode of the file(s) will not be changed.

Examples:

chmod 0o755, @executables;
$mode = '0644'; chmod $mode, 'foo';# !!! sets mode to --
wr-T
$mode = '0o644'; chmod $mode, 'foo';   # this is better
$mode = 0o644;   chmod $mode, 'foo';   # this is best

@executables ==> chmod :user( :x ),# users can execute
these
:group( :x ),  # as can group members
:other( :!x :!r :!w ); # but non-group members
cannot



Re: S16: chown, chmod

2008-11-21 Thread Moritz Lenz
Larry Wall wrote:
> On Fri, Nov 21, 2008 at 07:30:08PM +0100, Moritz Lenz wrote:
> : For chmod() I could imagine an interface like this:
> : 
> : $file.chmod(:8<540>);
> : $file.chmod( :set, :user => :r & :x, :group => :r)
> :# both same as 'chmod 540 $file'
> : 
> : $file.chmod( :modifiy, :other => :!x)
> :# same as 'chmod o-x $file'
> 
> A pair on the left side of => could be construed as a design smell.

oops, I menat 'user => :r' instead of ':user => :r'.
I should take the warning serious that 'sudo' prints out the first time
you use it ;-)

> And I wonder if the set/modify distinction can be better mapped onto
> assignops somehow...

maybe as hash slices?

$file.perms = 1, 0, 1;

Still that would become clumsy if you want to change the rights for
user, group and other at the same time...

Moritz

-- 
Moritz Lenz
http://perlgeek.de/ |  http://perl-6.de/ | http://sudokugarden.de/


Re: S16: chown, chmod

2008-11-21 Thread Larry Wall
On Fri, Nov 21, 2008 at 07:30:08PM +0100, Moritz Lenz wrote:
: For chmod() I could imagine an interface like this:
: 
: $file.chmod(:8<540>);
: $file.chmod( :set, :user => :r & :x, :group => :r)
:# both same as 'chmod 540 $file'
: 
: $file.chmod( :modifiy, :other => :!x)
:# same as 'chmod o-x $file'

A pair on the left side of => could be construed as a design smell.
And I wonder if the set/modify distinction can be better mapped onto
assignops somehow...

Larry


Re: S16: chown, chmod

2008-11-21 Thread Moritz Lenz
dpuu wrote:
> Question: is it appropriate to P6 look&feel to have methods on
> functions?

I don't think that's such a good idea in this case. If a file is
chown'able is not a property of the chown function, but of the file.

> The definition of C includes the statement that it's not
> available on most system unless you're superuser; and this can be
> checked using a POSIX incantation. I was wondering if it would be
> reasonable to provide this as a method on the chown function, so that
> a user could say:
> 
>   if &chown.is_restricted {
> ...
>   }
>   else {
> chown $user, $group <== @files
>   }


I'd rather go with the "try it and fail() if you can't" approach, partly
because of race conditions, partly because it's much more reliable in
the presence of extended security models (think of SeLinux for example).

If 'use fatal' is in effect, that dies, if not, you can check the return
value.


For chmod() I could imagine an interface like this:

$file.chmod(:8<540>);
$file.chmod( :set, :user => :r & :x, :group => :r)
   # both same as 'chmod 540 $file'

$file.chmod( :modifiy, :other => :!x)
   # same as 'chmod o-x $file'

Cheers,
Moritz

-- 
Moritz Lenz
http://perlgeek.de/ |  http://perl-6.de/ | http://sudokugarden.de/


Re: S16: chown, chmod

2008-11-21 Thread Larry Wall
On Fri, Nov 21, 2008 at 09:57:30AM -0800, dpuu wrote:
: On Nov 21, 9:16 am, [EMAIL PROTECTED] (Larry Wall) wrote:
: > Please feel free to whack on the spec
: 
: OK, working on it.
: 
: Question: is it appropriate to P6 look&feel to have methods on
: functions?
: 
: The definition of C includes the statement that it's not
: available on most system unless you're superuser; and this can be
: checked using a POSIX incantation. I was wondering if it would be
: reasonable to provide this as a method on the chown function, so that
: a user could say:
: 
:   if &chown.is_restricted {
: ...
:   }
:   else {
: chown $user, $group <== @files
:   }

On security issues where you often can't really determine in advance
whether something will work without trying it, I'd tend to lean more
towards throwing an exception and letting the user trap it, rather
than introducing more interface.  But that's just a general guideline.

To answer your actual question, yes, there can certainly be methods
on code objects.  But it's not clear to what extent this is a problem
for set theory to get involved with, unless the kernel knows your
set theory and agrees with you.  :)

Another problem with the "can I do this" ask-in-advance approach
is that it opens you up to race conditions, though in this case
it's unlikely (but possible) that another thread would change your
superuser status in between.

Larry


Re: S16: chown, chmod

2008-11-21 Thread dpuu
On Nov 21, 9:16 am, [EMAIL PROTECTED] (Larry Wall) wrote:
> Please feel free to whack on the spec

OK, working on it.

Question: is it appropriate to P6 look&feel to have methods on
functions?

The definition of C includes the statement that it's not
available on most system unless you're superuser; and this can be
checked using a POSIX incantation. I was wondering if it would be
reasonable to provide this as a method on the chown function, so that
a user could say:

  if &chown.is_restricted {
...
  }
  else {
chown $user, $group <== @files
  }



Re: S16: chown, chmod

2008-11-21 Thread Larry Wall
On Fri, Nov 21, 2008 at 08:44:51AM -0800, dpuu wrote:
: Reading S16, I was struck by the lack of abstraction over the
: underlying Unix API for chown and chmod. Nothing wrong with having the
: existing functions lying about in a module that people can "use Unix"
: for; but I do feel that the variants in the global namespace should be
: more user-friendly.

Please feel free to whack on the spec; it's in the pugs repo for that
reason.  (In fact, we're moving all the specs to the pugs repo so that
people can fix things that need fixing without excess interaction with
document "owners".)  Currently, it's called IO.pod, but it'll probably
end up somewhere else in the dir structure with a more S16-io-ish name.

Larry