[linux-cifs-client] chmod, chgrp, chown

Martin Koeppe mkoeppe at gmx.de
Sat Jun 4 19:47:39 GMT 2005


Hello,

addressing TODO's missing feature a) chmod/chgrp/chown,
I found out how SFU/Interix manages these things.
(I concentrated on chmod for now, though)

Overview:
- The normal rwx bits are mapped to Windows File Manager
  ACL permissions (and denies)
- The Set bits (chmod 07000) are stored in an Extended Attribute
 
When doing a chmod on Interix, always the following is done:
- all ACLs are removed and replaced by 3 new ACLs,
  one for the windows file owner, one for the POSIX group of the
  file owner and one for Everyone (SSID: S-1-1-0)
- the file's READ ONLY attribute is unset
- other attributes (HIDDEN, SYSTEM, ARCHIVE) are not changed


rwx bits
--------

For storing the rwx attributes, explorer's detailed file permissions
are used, they are (in the order they appear in the window):

name                   mask value
---------------------------------
(FULL)                 0x001f01ff
FILE_TRAVERSE          0x00000020
FILE_LIST_DIRECTORY    0x00000001
FILE_READ_ATTRIBUTES   0x00000080
FILE_READ_EA           0x00000008
FILE_ADD_FILE          0x00000002
FILE_ADD_SUBDIRECTORY  0x00000004
FILE_WRITE_ATTRIBUTES  0x00000100
FILE_WRITE_EA          0x00000010
FILE_DELETE_CHILD      0x00000040
DELETE                 0x00010000
READ_CONTROL           0x00020000
WRITE_DAC              0x00040000
WRITE_OWNER            0x00080000
SYNCRONIZE             0x00100000

For each of the 3 ACLs (owner, group, everybody)
the following mask is always set:
0x00120088 (SYNCRONIZE | READ_CONTROL | FILE_READ_EA | FILE_READ_ATTRIBUTES)

To this value the bits for r,w,x are ORed as follows:
r: 0x00000001  (FILE_LIST_DIRECTORY)
w: 0x00000156  (FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY |
               | FILE_DELETE_CHILD
               | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
x: 0x00000020  (FILE_TRAVERSE)


When  (group_rwx && ~owner_rwx != 0), e.g. the file has
permission -r--rwx---, then an additional DENY ACL for the owner
is created:

deny_rwx = group_rwx && ~owner_rwx; // == -wx

This is mapped to 0x00000156 + 0x00000020,
and the created deny ACL for the owner is:
owner deny: 0x00000176

The same is for Everyone, if everyone's permissions
are not included in group's or owner's.

For simplification, these DENY ACLs can always be set,
if the resulting mask is 0, then Windows removes the entry.
(At least it does so when using the Explorer.)



set bits
--------

If one of the set bits are to be set,
an Extended Attribute is created/updated:
Name:  SETFILEBITS
data:  uint32

chmod 01000  gets   0x00020000
chmod 02000  gets   0x00040000
chmod 04000  gets   0x00080000


readíng permissions
-------------------

When reading the permissions for a file, the READ ONLY attribute is
also taken into account: the mask values from the 3 ACLs above are
tried to read, and the file permissions calculated accordingly. If
file's READ ONLY attribute is set, then all w bits are cleared from
the calculation.


I think this should be implementable for linux-cifs in the same way,
when a Windows NT or above server is contacted.
Setting the permissins like that might default to the
mount option "noperm", as the checking can be done by the server.


Martin


More information about the linux-cifs-client mailing list