[linux-cifs-client] Windows ACL support

Martin Koeppe mkoeppe at gmx.de
Sat Feb 23 14:21:33 GMT 2008


Hi all,

I just wanted to post some information about Windows ACL to Unix 
owner, group and mode bits mapping, which I found out while using SFU 
and Server for NFS. I hope this info can be useful for 
designing/improving ACL support in linux-cifs, addressing TODO list 
item a).


1. NTFS features
----------------
Files stored on a NTFS volume have an owner (saved as SID) AND a group 
(often named "primary group" in windows docs), also saved as a SID.
This group info isn't shown in Explorer anywhere, but there is a tool, 
SubInACL.exe, which can display and change a file's GID-SID:
http://www.microsoft.com/downloads/details.aspx?FamilyID=e8ba3e56-d8fe-4a91-93cf-ed6985e3927b&displaylang=en 
So it is possible to store Unix owner and group information on NTFS.


2. Mapping SIDs to UIDs and GIDs
--------------------------------
In MS SFU 3.5 or in Windows Server 2003 R2 there is an Server for NFS 
included, which exports NTFS folders for Unix NFS clients. This Server 
for NFS has the same problem of mapping Windows ACLs to Unix 
owner/group/mode as linux-cifs has.
The mapping of the Windows SIDs used for owner and group on NTFS to 
the Unix numeric UID and GID can be done there by 2 different ways:

The first (and older one) is User Name Mapping. This is a service 
which can be configured manually to map specific SIDs to the desired 
UID or GID. Server for NFS then queries this service to translate the 
SID to UID/GID and vice versa.

The second is new with 2003 R2. If installed, the AD structure is 
enhanced to also store Unix UID info together with an AD user object 
resp. Unix GID together with an AD group object. This info then can 
alternatively be used for mapping by Server for NFS.

Both of these services run on Windows, but may be connected to via 
network, so it should be possible to let linux-cifs use them.

Interix (also part of SFU 3.5 or SUA 5.2 aka 2003R2) OTOH, i.e. the 
kernel subsystem letting e.g. bash run on windows, uses another way to 
map SIDs to UIDs and GIDs. It's not a configurable mapping, but 
instead an algorithmic way to extract some local (i.e. not related to 
the domain) number from the SID and take this as UID or GID. E.g. the 
local default Administrator user with the well-known SID 
S-1-5-Domain-500 maps to UID 197108. (In hex it is: S-1-5-...-1F4 
which maps to 301F4).

Server for NFS isn't built on top of the Interix subsystem, so it 
doesn't use this algorithmic mapping. The UNM or AD method seems more 
reasonnable for linux-cifs purposes.


3. ACL to mode bit mapping
--------------------------
How the mode bits are calculated from ACLs I already wrote some time 
ago here:
http://marc.info/?l=linux-cifs-client&m=111791448926374&w=2

I now found also these pages:
http://technet2.microsoft.com/windowsserver/en/library/d342b911-6d7f-432a-a992-230948510cfe1033.mspx?mfr=true
http://blogs.msdn.com/sfu/archive/2007/05/11/how-user-name-mapping-works.aspx

If the NFS server gets a request to list the mode bits for a file, it 
takes the file's owner Windows SID. Then it authenticates this SID, 
probably (I'm not sure here) getting a list of all Windows group SIDs 
back, where the user SID is member of. I'm not sure if obtaining such 
a list remotely is possible, but it would simplify (or make 
it possible) for linux-cifs to calculate the mode bits.

It now processes the file's ACL and calculates the mode bits as 
described in my earlier posting, i.e. going though all ACEs and 
looking if they match one of the user's SIDs. The same is done for the 
file's group SID to get the group mode bits.

When storing a new file, Server for NFS has 2 modes how the ACL can be 
set. The default mode is to only add those ACEs to the ACL that 
represent the owner and the group of the file, thus exactly what Unix 
would do. The other more interesting thing is a setting called 
"KeepInheritance". If activated, all inherited ACEs are preserved 
in addition to the just created ACEs. This can have the effect that 
users may have access to files where the mode bits wouldn't permit 
access.

Example: a file's owner is user A, group is G. The ACEs let A 
and G have rwx rights to the file resulting in mode bits -rwxrwx---.
Now take another user B which is in group H, but not in G. In the Unix 
world he couldn't access the file. But with KeepInheritance on, there 
may be an inherited ACE which grants access to B or H, thus B may be 
able to read the file. So it's possible to make use of the more 
flexible Windows ACLs from within Unix.

This may be useful for linux-cifs also: A SMB session is created for 
one user C mounting the share. The files on the share may have 
different owners/groups, say D/H and E/K. When listing files from such 
a share via linux-cifs, it could look as follows:

-rwxrwx---  D  H   file1
-rwxrwx---  E  K   file2

Nevertheless linux-cifs should not block an access to one of these 
files, as there may be additional ACEs granting access to C, 
which cannot expressed via the mode bits.


4. Sym Links
------------
This posting shouldn't be about symlinks, but I just read this recent 
posting from Steve:

> It would be possible for cifs to create symlinks as SUA (Windows 
> Services for Unix) does, since it can read them (although they are 
> often in a useless format with drive letters in the path) but it 
> would need minor changes to write such a feature for servers which 
> do not support the Unix Extensions.

This is not quite right. SFU/SUA symlinks store the Unix-like file 
names, so they never contain drive letters! Server for NFS and Interix 
kernel subsystem use the same format (a system file beginning with 
"IntxLNK") to store the link target, in Unix format, e.g. a link
L -> /usr/local/tmp/posix:\valid*file?name
is stored exactly in this way, i.e. the Unix path and unix file name, 
even though some of the file name characters are not valid windows 
file name characters. It is stored in Unicode though.

When the link is then followed, then the Unix file name to look up is 
first translated to valid windows file names, i.e. adding 0xf000 to 
all these ASCII chars [:\*?] which aren't valid for Windows.

So linux-cifs should not translate any symlink content wrt. drive 
letters etc. besides from simply convert Unicode to ASCII. Only when 
real file names are asked for, they need to be translated first with 
+0xf000 before asking the SMB server.


I can do further tests with Server for NFS, Interix or linux-cifs if 
required.

Martin


More information about the linux-cifs-client mailing list