Operating System - OpenVMS
1751738 Members
5664 Online
108781 Solutions
New Discussion

Re: CIFS rmdir on nonempty directory changes permissions

 
chadjoan
Occasional Contributor

CIFS rmdir on nonempty directory changes permissions

I have an OpenVMS system with a directory shared over CIFS/samba.  This share is then accessed by a Linux machine that mounts the shared directory into its own directory tree.  I'm logged onto the Linux machine and I rmdir a nonempty folder in the shared directory.  What happens next is this: it errors as expected, but then changes the permissions of the directory that was rmdir'd (it removes most of them). 

 

This became a very noticeable problem because we use git for version controlling source files on the VMS system, and git uses rmdir.

 

Here is the post on the git dev list where this was traced to OpenVMS CIFS:

http://git.661346.n2.nabble.com/Git-changes-permissions-on-directories-when-deleting-files-tt6075733.html#a6078432

 

In summary, this happens:

~/vms08/test $ mkdir -p foo/bar && touch foo/bar/baz
~/vms08/test $ ls -ld foo && ls -ld foo/bar && ls -l foo/bar/baz
drwxr-xr-x 1 cjoan cjoan 0 Nov  6  2012 foo
drwxr-xr-x 1 cjoan cjoan 0 Nov  6  2012 foo/bar
-rwxr-x--- 1 cjoan cjoan 0 Nov  6 13:54 foo/bar/baz
~/vms08/test $ rmdir foo/bar
rmdir: failed to remove `foo/bar': Directory not empty
~/vms08/test $ ls -ld foo && ls -ld foo/bar && ls -l foo/bar/baz
drwxr-xr-x 1 cjoan cjoan 0 Nov  6  2012 foo
drw------- 1 cjoan cjoan 0 Nov  6  2012 foo/bar
ls: cannot access foo/bar/baz: Permission denied

 

 

Here is the expected output from a locally mounted directory on the Linux box:

~ $ mkdir -p foo/bar && touch foo/bar/baz
~ $ ls -ld foo && ls -ld foo/bar && ls -l foo/bar/baz
drwxr-xr-x 3 cjoan cjoan 4096 Nov  6 13:57 foo
drwxr-xr-x 2 cjoan cjoan 4096 Nov  6 13:57 foo/bar
-rw-r--r-- 1 cjoan cjoan 0 Nov  6 13:57 foo/bar/baz
~ $ rmdir foo/bar
rmdir: failed to remove `foo/bar': Directory not empty
~ $ ls -ld foo && ls -ld foo/bar && ls -l foo/bar/baz
drwxr-xr-x 3 cjoan cjoan 4096 Nov  6 13:57 foo
drwxr-xr-x 2 cjoan cjoan 4096 Nov  6 13:57 foo/bar
-rw-r--r-- 1 cjoan cjoan 0 Nov  6 13:57 foo/bar/baz

 

 

OpenVMS version:

$ show system /noprocess
OpenVMS V8.4  on node VMS08    6-NOV-2012 15:07:34.20   Uptime  209 20:08:59

 

 

It's an I64.

 

I originally found this over a year ago.  I wanted to submit this bug report back then, but I couldn't (and still can't) find any bug tracker or HP OpenVMS support email to send things like this.  Now I found a moment and decided to see if any devs might see this in the forum.  It's fairly odd behavior, and I worry about what else this might break (especially silent breakage), in addition to the inconvenience of having to patch git every time we do an update. 

8 REPLIES 8
Jeremy Begg
Trusted Contributor

Re: CIFS rmdir on nonempty directory changes permissions

The CIFS home page is http://h71000.www7.hp.com/network/cifs_for_samba.html and there's a feedback link at the bottom of that page.

 

You don't say what version of OpenVMS IA64 or CIFS.  If you're not running CIFS 1.2 ECO 1 you should be.

If you are running that version and have a support contract, log a support case.  There are CIFS updates which are not made generally available except via the support channel.  (Eventually those updates will become another ECO release or version release, but those releases are not frequent.)

 

 

Regards,

Jeremy Begg

Steven Schweda
Honored Contributor

Re: CIFS rmdir on nonempty directory changes permissions

   I know nothing, but ...

   Directories on VMS typically lack Delete protection/permission, so
I'd guess that the CIFS "rmdir" operation first sets O:REWD protection
on the target, and then tries to delete the thing.  Naturally, if the
delete operation fails, the protection has already been changed, and no
one tries to restore it.

   Smart code (I claim) would check for an empty directory before
fiddling with its protection.  Otherwise, it might help to (save and)
restore the original protection if the delete operation fails.  (But I'd
expect those protection changes to change the modification date-time,
even when nothing actually changed, which would be sub-ideal.)

   Of course, actually looking at the CIFS source code might be more
reliably informative than reading my guesses.

> [...] I couldn't (and still can't) find any bug tracker or HP OpenVMS
> support email to send things like this.

   E-mail to OpenVMS.Programs@hp normally gets delivered (unlike
messages left using the various "feedback" Web forms one might find at
hp.com).  Knowing nothing, I'd guess that the Samba folks themselves
might have more interest in this than anyone at HP.

Craig A Berry
Honored Contributor

Re: CIFS rmdir on nonempty directory changes permissions

In order to report a bug directly to HP, you have to buy a support contract for your OpenVMS system.

 

It's not clear to me whether the bug here is in CIFS or in the CRTL rmdir implementation or simply a mismatch between expectations and reality.   I think sources to the CIFS port are available somewhere (sorry, no link handy).  Sources to the CRTL are not freely available as far as I know.

 

Note that on VMS, delete permission is a separate bit from write permission and also directories are normally created with delete permission turned off, even for the owner.  The usual native workflow is to delete all the files in a directory, then explicitly enable delete permission on the directory, then finally delete the directory itself.

 

But calling rmdir on an empty directory that you own and getting EPERM is going to be an unwelcome surprise if one comes to the party with unixy expectations.  One way around this is to have a "smart" rmdir that, if its initial attempt fails, modifies the permission on the directory and tries again.  In other words, it takes the same steps that an interactive user would to delete a directory.

 

I have seen rmdir implementations on VMS that do this.  I don't know if the CRTL or Samba do it, but if one of them does, it would certainly explain the behavior you are seeing.

 

Have you tried enabling unix-style permissions in the environment visible to your CIFS server?  See, for example:

 

$ help crtl feature_log decc$file_permission_unix


CRTL

  Feature_Logical_Names

    DECC$FILE_PERMISSION_UNIX

         With DECC$FILE_PERMISSION_UNIX enabled, the file permissions
         for new files and directories are set according to the file
         creation mode and umask. This includes mode 0777. When an earlier
         version of the file exists, the file permissions for the new file
         are inherited from the earlier version. This mode sets DELETE
         permission for a new directory when WRITE permission is enabled.

         With DECC$FILE_PERMISSION_UNIX disabled, modes 0 and 0777
         indicate using RMS default protection or protection from the
         previous version of the file. Permissions for new directories
         also follow OpenVMS rules, including disabling DELETE
         permissions.

 

I don't know if that would help or not, but it would be pretty cheap to try.  Of course there may be other CIFS users who do not want this behavior, so it may not be a workable solution.

 

I would think you'd also want to review the per-share protection settings in CIFS, documented starting at section 10.1.5 in the manual here.

Hein van den Heuvel
Honored Contributor

Re: CIFS rmdir on nonempty directory changes permissions

 

 

The Crtl rmdir is doing this to you. Submit a bug!

As Craig suspects it sets the D protection, allowing delete, but it drops E

This is emperical (see below) haven't checked the listings.

 

$ dir/secu x
X.DIR;1              [HEIN]                           (RWE,RWE,,)
$ mcr sys$login:rmdir x
-1
$ dir/secu x.dir
X.DIR;1              [HEIN]                           (RWD,RWD,,)
$
$ type rmdir.c
#include <stdio.h>
#include <stdlib.h>
#include  <unistd.h>

main(int argc, char *argv[])
{
    if (argc > 1) printf ( "%d\n", rmdir(argv[1]) );
}

 

Hein

 

 

 

Craig A Berry
Honored Contributor

Re: CIFS rmdir on nonempty directory changes permissions

Hein is correct and it's actually somewhat worse than he indicates because it wipes all group and world permissions if you have any (which Hein didn't in his example).

 

Running Hein's rmdir with SET WATCH FILE/CLASS=ALL enabled demonstrates that the change operation to modify the permissions happens before the delete operation.  In other words, it doesn't attempt the delete and then retry if it fails, nor does it check the permissions to see if it already has delete access before modifying the permissions.

 

The Unix permission setting I mentioned before wouldn't do any good because it would cause mkdir to add delete permission, but rmdir would still modify the permissions for the directory not empty case.

 

What we do in the rmdir implementation in Perl is call SYS$ERASE.  If it fails with RMS$_PRV, we then modify the permissions using SYS$CHANGE_ACL and try again.  If that fails, we try to set the permissions back the way they were.  The code isn't especially pretty but is freely available at http://perl5.git.perl.org/perl.git/blob/maint-5.16:/vms/vms.c#l1841.  N.B.  SYS$CHANGE_ACL has been deprecated and replaced by SYS$SET_SECURITY but the old one still works and I haven't bothered to change it (yet).

 

This is not very efficient and may even be vulnerable to a race condition if something changes in between the first erase attempt and the second attempt.  However, it generally does the right thing, which the CRTL version apparently doesn't do.

 

The OP might well want to look into using Mercurial directly on OpenVMS or alternately try NFS instead of CIFS for serving up the files (though it might still suffer from the same problem).  

Paul Nunez
Respected Contributor

Re: CIFS rmdir on nonempty directory changes permissions

Hi,

 

Using Hein's replicator code, I can't duplicate the behavior on my I64 v8.4 system:

 


$ creat/dir [.x]/prot=(s:rwe,o:rwe,g,w)
$ dir/sec x

Directory SYS$SYSDEVICE:[NUNEZPE]

X.DIR;1              [CIFS,NUNEZPE]                   (RWE,RWE,,)

Total of 1 file.
$ mc []ren x
0
$ dir/sec x
%DIRECT-W-NOFILES, no files found
$ sh proc/priv

 9-NOV-2012 09:10:13.49   User: NUNEZPE          Process ID:   00000448
                          Node: AGRESV           Process name: "NUNEZPE"

Authorized privileges:
 NETMBX       TMPMBX

Process privileges:
 NETMBX               may create network device
 TMPMBX               may create temporary mailbox

Process rights:
 NUNEZPE                           resource
 INTERACTIVE
 REMOTE

System rights:
 SYS$NODE_AGRESV

 

The system has UPDATE V0700 installed which contains:

 

Image Identification Information

                  Image name: DECC$SHR
    Global Symbol Table name: DECC$SHR
   Image file identification: V8.4-00
  Image build identification: 0100000070
         Link identification: Linker I02-37
              Link Date/Time: 12-MAR-2012 17:23:11.35
             Patch Date/Time: Never
      Manipulation Date/Time: Never
  Image Dynamic Data Version: 1.3

 

Paul

Craig A Berry
Honored Contributor

Re: CIFS rmdir on nonempty directory changes permissions

Paul, you didn't put anything in the directory, so it didn't fail with directory not empty.  All you've demonstrated is that it does add the delete permission and successfully deletes the (empty) directory.  The problem under discussion is the cases where it cannot delete the directory but leaves the permissions whacked.

Paul Nunez
Respected Contributor

Re: CIFS rmdir on nonempty directory changes permissions

Yep, I missed that crucial piece - I'm seeing the same behavior as OP...

 

Paul