On Jul 16, 2010, at 6:43 PM, Craig A. Berry wrote:


On Jul 10, 2010, at 2:05 PM, Mark Berryman wrote:

Is the following expected behavior?

With normal default protections set:

$ say := write sys$output
$ say f$env("protection")
SYSTEM=RWED, OWNER=RWED, GROUP=RE, WORLD
$ perl -e "open(F,'>1.1'); print F 1; close F;"
$ dir/sec 1.1

Directory USERS:[BERRYMAN]

1.1;1                [BERRYMAN]                       (RWD,RWD,R,)

However, change the owner default to read-only and:

$ set prot=ow:re/def
$ say f$env("protection")
SYSTEM=RWED, OWNER=RE, GROUP=RE, WORLD
$ perl -e "open(F,'>1.1'); print F 1; close F;"
$ dir/sec 1.1

Directory USERS:[BERRYMAN]

1.1;1                [BERRYMAN]                       (R,R,R,)

Why is the file being created with system only having Read access when the owner default is set to read?


Good question. And the other weird thing is it gives you only read protection when you asked for execute as well. I have a feeling that it's line 2601 of perlio.c, but I need to read up and remind myself how Unix protection masks interact with VMS default protections. The current perlio.c is at:

<http://perl5.git.perl.org/perl.git/blob/HEAD:/perlio.c>

and the lines I'm suspecting look like:

2600             imode = PerlIOUnix_oflags(mode);
2601             perm = 0666;

Should that be 0777 or something in order to assume VMS defaults?


I did a bit more digging, and yes, I think the 0666 permissions on the open() call are where things go wrong. The CRTL docs on umask at <http://h71000.www7.hp.com/doc/732final/5763/5763pro_060.html#umask_routine > state clearly that you should use 0777 without ever calling umask if you want to inherit default VMS permissions, including ACLs and inherited permissions from previous versions of the file.

The most obvious damage apparent from using 0666 is that it turns off execute permission even if it's turned on in your default permissions. I suspect this is intentional and is considered a security feature in a Unix environment where the execute bit is more than just a permission bit.

Testing shows that even with 0666 we still inherit permissions from a previous version of the file. So that's one thing that's not broken. But other important things are broken by using 0666:

1.) The execute bit is lost regardless of whether it's in the default permissions.

2.) Delete permission (which doesn't exist in the Unix permission mask) is copied from write permission, so granting write permission also grants delete even if it's not in the default permission mask.

3.) System permissions (which don't exist in the Unix permission mask) are copied from owner permissions, so any distinction between system and owner is lost.

4.) ACLs are not inherited. For example, setting a default_protection ACE on a directory such that all world access is disallowed will be ignored; world will have the intersection of RWD (the final 6 in 0666) and whatever the default permissions are regardless of what the ACL says.

Luckily, I think the fix will be easy:

$ gdiff -pu perlio.c;-0 perlio.c
--- perlio.c;-0 2010-05-21 14:34:10 -0500
+++ perlio.c    2010-08-07 16:09:12 -0500
@@ -2598,7 +2598,11 @@ PerlIOUnix_open(pTHX_ PerlIO_funcs *self
            mode++;
        else {
            imode = PerlIOUnix_oflags(mode);
+#ifdef VMS
+ perm = 0777; /* preserve RMS defaults, ACL inheritance, etc. */
+#else
            perm = 0666;
+#endif
        }
        if (imode != -1) {
            const char *path = SvPV_nolen_const(*args);
[end]

I'm going to test this now. Anyone else who can, please do the same, and please point out any downside you can think of to switching us so we always create files with 0777.


________________________________________
Craig A. Berry
mailto:craigbe...@mac.com

"... getting out of a sonnet is much more
 difficult than getting in."
                 Brad Leithauser

Reply via email to