Windows users have a different view on their ACL policies enforced by the windows acl-editor is applying rules on files. With ZFS/NFSv4 ACLs, they are able to aplly exactly what they want. But it could lead to have "classic" UNIX permisssion rights set to 000, even if the user keep the right to modify the file in the ACL. In this particular case dosmode.c will refuse access to user ! Starting with the fact that acl(ACE_GETACL,...) is able to give a list on any object, dosmode should ignore UNIX permissions where vfs lib zfsacl is instanciate. Nicolas
Created attachment 3036 [details] some "ls -V" to see acls from ZFS point of view
Created attachment 3037 [details] Configuration
Created attachment 3038 [details] Samba Log File - level 10 - Gzipped
Took a look to log. It may have to different cases : 1) open.c or some object around use posix_acls.c : [2007/12/11 09:59:07, 5] smbd/statcache.c:(140) stat_cache_add: Added entry (4f3a68:size13) TESSAM/~$PLOUF.RTF -> TesSam/~$plouf.rtf [2007/12/11 09:59:07, 5] smbd/filename.c:(241) conversion finished TesSam/~$plouf.rtf -> TesSam/~$plouf.rtf [2007/12/11 09:59:07, 3] smbd/dosmode.c:(142) unix_mode(TesSam/~$plouf.rtf) returning 0744 [2007/12/11 09:59:07, 10] smbd/open.c:(1184) open_file_ntcreate: fname=TesSam/~$plouf.rtf, dos_attrs=0x0 access_mask=0x60080 share_access=0x7 create_disposition = 0x1 create_options=0x20000 0 unix mode=0744 oplock_request=0 [2007/12/11 09:59:07, 8] smbd/dosmode.c:(371) dos_mode: TesSam/~$plouf.rtf [2007/12/11 09:59:07, 8] smbd/dosmode.c:(188) dos_mode_from_sbuf returning a [2007/12/11 09:59:07, 8] smbd/dosmode.c:(409) dos_mode returning a [2007/12/11 09:59:07, 10] smbd/open.c:(1347) open_file_ntcreate: fname=TesSam/~$plouf.rtf, after mapping access_mask=0x60080 [2007/12/11 09:59:07, 5] smbd/files.c:(123) allocated file structure 82, fnum = 4178 (3 used)[2007/12/11 09:59:07, 4] smbd/open.c:(1605) calling open_file with flags=0x0 flags2=0x0 mode=0744, access_mask = 0x60080, open_access_mask = 0x60080 [2007/12/11 09:59:07, 2] smbd/open.c:(391) dorfsman opened file TesSam/~$plouf.rtf read=No write=No (numopen=3) [2007/12/11 09:59:07, 10] locking/locking.c:(681) unparse_share_modes: del: 0, tok = 0, num: 1 [2007/12/11 09:59:07, 10] locking/locking.c:(498) print_share_mode_table: share_mode_entry[0]: pid = 9510, share_access = 0x7, private_options = 0x200000, access_mask = 0x60080, mid = 0x0, type = 0x10, file_id = 71, uid = 102618, flags = 0, dev = 0x401000c, inode = 28681 [2007/12/11 09:59:07, 8] smbd/dosmode.c:(371) dos_mode: TesSam/~$plouf.rtf [2007/12/11 09:59:07, 8] smbd/dosmode.c:(188) dos_mode_from_sbuf returning a [2007/12/11 09:59:07, 8] smbd/dosmode.c:(409) dos_mode returning a [2007/12/11 09:59:07, 10] smbd/posix_acls.c:(4311) can_access_file: requesting 0x2 on file TesSam/~$plouf.rtf [2007/12/11 09:59:07, 5] smbd/nttrans.c:(940) reply_ntcreate_and_X: fnum = 4178, open name = TesSam/~$plouf.rtf [2007/12/11 09:59:07, 5] lib/util.c:(484) 2) other case for directories ? [2007/12/11 09:59:43, 3] smbd/process.c:(926) switch message SMBntcreateX (pid 9510) conn 0x50c3f8 [2007/12/11 09:59:43, 4] smbd/uid.c:(183) change_to_user: Skipping user change - already user [2007/12/11 09:59:43, 10] smbd/nttrans.c:(515) reply_ntcreate_and_X: flags = 0x10, access_mask = 0x110080 file_attributes = 0x0, share_access = 0x7, create_disposition = 0x1 create_options = 0x200000 root_dir_fid = 0x0 [2007/12/11 09:59:43, 5] smbd/filename.c:(147) unix_convert called on file "TesSam/Nouveau dossier" [2007/12/11 09:59:43, 10] smbd/statcache.c:(248) stat_cache_lookup: lookup succeeded for name [TESSAM/NOUVEAU DOSSIER] -> [TesSam/Nouveau dossier] [2007/12/11 09:59:43, 8] smbd/dosmode.c:(371) dos_mode: TesSam/Nouveau dossier [2007/12/11 09:59:43, 8] smbd/dosmode.c:(188) dos_mode_from_sbuf returning d [2007/12/11 09:59:43, 8] smbd/dosmode.c:(409) dos_mode returning d [2007/12/11 09:59:43, 3] smbd/error.c:(106) error packet at smbd/nttrans.c(697) cmd=162 (SMBntcreateX) NT_STATUS_ACCESS_DENIED
You need to store the DOS attributes in extended attributes. Trying to store this in unix permissions inherently conflicts with ACLs. Set : ea support = yes store dos attributes = yes map readonly = no map archive = no map system = no
Created attachment 3043 [details] Log with "store dos attribute"
No change. Except : [2007/12/13 09:11:57, 10] lib/system.c:(2394) attropen FAILED: path: Nouveau dossier, name: user.DOSATTRIB, errno: No such file or directory New log attached.
Issue seems to be in can_delete_file_in_directory(). In nttrans.c line 689 there's a test : if (lp_acl_check_permissions(SNUM(conn)) && (create_disposition != FILE_CREATE) && (share_access & FILE_SHARE_DELETE) && (access_mask & DELETE_ACCESS)) { if ((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY) || !can_delete_file_in_directory(conn, fname)) { restore_case_semantics(conn, file_attributes); END_PROFILE(SMBntcreateX); return ERROR_NT(NT_STATUS_ACCESS_DENIED); } } It works when I remove "!can_delete_file_in_directory(conn, fname)" from the second if. Let's dive into can_delete_file_in_directory() .... Nicolas
Could somebody help me ? Is it normal to call routines in posix_acls.c when zfsacl module is loaded ? Could it be the problem here ? Nicolas
Yep, that *is* the problem. It's just a bit more difficult to solve than you might get from a brief look, we need to make sure that this works reliably *also* for the pure unix permissions and posix acl case. A simple get_nt_acl and se_access_check did not work when I tried last time, this broke some posix acl cases. Volker
Hi Nicolas, (In reply to comment #9) > Could somebody help me ? > > Is it normal to call routines in posix_acls.c when zfsacl module is loaded ? > Could it be the problem here ? Well, it should not be normal. In the patch developed for bug #5023, I have made the function can_delete_file_in_directory() (among others) independent from the posix_acls.c code, using the correct acl implementation. This has gone into 3.0.27a. In the 3.2 branch (v3-2-test), I have also put these general access check functions into a file of their own (smbd/file_acces.c). I have not made this more conecptual step of moving the functions away in the v3-0-test branch to keep the diff smaller in this security/bugfix branch... So the use of can_delete_file_in_directory() should be ok and the problem seems to be more sublte than that. I Have to look more closley... Cheers, Michael
(In reply to comment #11) > Hi Nicolas, Hi Michael, Thank you for your reply. I continue trying to locate the issue. Some comments/questions below. > Well, it should not be normal. In the patch developed for bug #5023, I have > made the function can_delete_file_in_directory() (among others) independent > from the posix_acls.c code, using the correct acl implementation. Right. Routine called in posix_acls.c is can_delete_file_in_directory(), so it may be ok. I added comments to clarify. The access is denied on this test : /* Check primary owner write access. */ if (current_user.ut.uid == sbuf.st_uid) { DEBUG(10,("can_delete_file_in_directory: ut.uid=%d st_uid=%d sbuf.st_mode=%d S_IWUSR=%d\n", current_user.ut.uid, sbuf.st_uid, sbuf.st_mode, S_IWUSR)); return (sbuf.st_mode & S_IWUSR) ? True : False; } debug line told me : [2007/12/18 09:52:31, 10] smbd/posix_acls.c:(4270) can_delete_file_in_directory: ut.uid=102618 st_uid=102618 sbuf.st_mode=16384 S_IWUSR=128 sbuf is set by SMB_VFS_STAT(conn, dname, &sbuf) macro. Im looking for the handler which is called with VFS (hard for for samba-code newbie). > This has > gone into 3.0.27a. In the 3.2 branch (v3-2-test), I have also put these general > access check functions into a file of their own (smbd/file_acces.c). I have not > made this more conecptual step of moving the functions away in the v3-0-test > branch to keep the diff smaller in this security/bugfix branch... What is the best thing to do...switch to 3.2 branch or continue debugging 3.0.27a ? Cheers, Nicolas
I believe I understood. SMB_VFS_STAT should call stat() and populate st_mode with "pure" UNIX permissions. This has to be avoided with ZFS (000 unix perm-bits doesn't imply no rights). A quick grep on source/smbd gave me several lines, of which I guess I could extract these : dosmode.c: if ((sbuf->st_mode & S_IWUSR) == 0) { dosmode.c: if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) { dosmode.c: unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); posix_acls.c: return (sbuf.st_mode & S_IWUSR) ? True : False; continuing. Nicolas
(In reply to comment #13) > I believe I understood. > > SMB_VFS_STAT should call stat() and populate st_mode with "pure" UNIX > permissions. This has to be avoided with ZFS (000 unix perm-bits doesn't imply > no rights). Well...routines like can_delete_file_in_directory() or can_access_file are testing UNIX permission bits and then check acl. It's a non-sens for zfs acl, maybe for several ACLs implementations. Anyway, I'm working on ZFS for now. I'd like to bypass UNIX permissions check when I'm on ZFS, what could be the best ? Check st_fstyp ? TIA Nicolas
No, hard-coding on fstype is not really a good idea IMO. I can imagine scenarios where even a ZFS volume is used only with unix permissions, I can't believe that ZFS *only* has NFSv4 style ACLs. They must have a mode without acls and normal unix permissions. The clean way to solve this would be to use the get_nt_acl call and do a se_access_check on that. get_nt_acl goes via the VFS where you can use different modules. I've used this trick for AFS style ACLs already, but as I told in an earlier comment, this is no ready for upstream because it breaks normal scenarios. So we need to fix get_nt_acl for the posix acl and pure unix perms case. Or just verify that this has already been fixed, my test was at least a year ago. Volker
(In reply to comment #15) > No, hard-coding on fstype is not really a good idea IMO. I can imagine > scenarios where even a ZFS volume is used only with unix permissions, I can't > believe that ZFS *only* has NFSv4 style ACLs. They must have a mode without > acls and normal unix permissions. No, unix permissions on zfs are just a view. zfs is a "pure acl model". Take a look (not a proof, just an illustration : dorfsman@c92-ms168 /export/nicolas]$ cat /etc/hosts > volker [dorfsman@c92-ms168 /export/nicolas]$ ls -l volker -rw-r--r-- 1 dorfsman dep 98 Dec 18 16:19 volker [dorfsman@c92-ms168 /export/nicolas]$ ls -V volker -rw-r--r-- 1 dorfsman dep 98 Dec 18 16:19 volker owner@:--x-----------:------:deny owner@:rw-p---A-W-Co-:------:allow group@:-wxp----------:------:deny group@:r-------------:------:allow everyone@:-wxp---A-W-Co-:------:deny everyone@:r-----a-R-c--s:------:allow Written in docs : http://docs.sun.com/app/docs/doc/819-5461/6n7ht6qsh?a=view Extract: "As implemented with ZFS, ACLs are composed of an array of ACL entries. ZFS provides a pure ACL model, where all files have an ACL. " > The clean way to solve this would be to use > the get_nt_acl call and do a se_access_check on that. get_nt_acl goes via the > VFS where you can use different modules. I've used this trick for AFS style > ACLs already, but as I told in an earlier comment, this is no ready for > upstream because it breaks normal scenarios. So we need to fix get_nt_acl for > the posix acl and pure unix perms case. Or just verify that this has already > been fixed, my test was at least a year ago. It's a lost of time...developer and CPU time. ACL check is sufficient on zfs. Nicolas
The part that scares me on that page you refer to is that they don't mention NFSv4 at all (or did I not see this?). Is this 100% to the NFSv4 spec, or is this yet another subtly different ACL model? Either way, I would still be a bit reluctant to test on fs type. What we IMHO need here is the path through the GET_NT_ACL VFS function and check that. This means that we need a very good mapping of at least ZFS (NFSv4?) ACLs to NT Security Descriptors because we have to emulate the kernel-level checks in user space here. We can't just try to delete a file and hope for EPERM, this is a not easily reversed operation :-) There is code around that does this, but it has not really seen wide testing. Volker
(In reply to comment #17) > The part that scares me on that page you refer to is that they don't mention > NFSv4 at all (or did I not see this?). Is this 100% to the NFSv4 spec, or is > this yet another subtly different ACL model? :-) http://docs.sun.com/app/docs/doc/819-5461/6n7ht6qsg?a=view > Either way, I would still be a bit reluctant to test on fs type. What we IMHO > need here is the path through the GET_NT_ACL VFS function and check that. This > means that we need a very good mapping of at least ZFS (NFSv4?) ACLs to NT > Security Descriptors because we have to emulate the kernel-level checks in user > space here. We can't just try to delete a file and hope for EPERM, this is a > not easily reversed operation :-) There is code around that does this, but it > has not really seen wide testing. Hum...my knowledge in samba code is really too small to argue even I have the feeling to understand what you wrote. And something come to my mind : why should samba code try to make kernel funciton if kernel is able to do it by itself ? I mean....nfsv4/zfs acls have at least the same capcity than NT acls. So, when working on zfs, just set uid and groups of process smbd and let the kernel do the job. Is it completely stupid ?
Ok, this one is quite subtle: When XP tries to delete a file, it does not use the existing smbunlink call that earlier Windows versions used. Instead it opens a file and during that open call it asks for DELETE access permissions. It then sets the so-called delete on close flag and closes the file. The close operation then will delete the file. To get the right error message to the user, Samba needs to reply to the open call with NT_STATUS_ACCESS_DENIED, if it replies to the close call when the real delete happens with ACCESS_DENIED, the client will just ignore this. So to rely on the kernel in this case we would have to try deleting the file. If that succeeds, the file however must still be around because the client is not obliged to actually set the delete on close flag. If it does not and closes the file, then it's gone afterwards. Bummer. So we *have* to emulate the in-kernel access checks in user space, racy as this might be. It is not a security problem though, it is "just" to get the right error message to the client at the right time. The real solution would be to extend the open system call in Unix with a flags field that contains all the fancy NFSv4 access bits in a non-destructive way. But the genious visionaries designing the NFSv4 ACL model just forgot one important piece: A local API. :-( Volker
(In reply to comment #17) > Either way, I would still be a bit reluctant to test on fs type. What we IMHO > need here is the path through the GET_NT_ACL VFS function and check that. This > means that we need a very good mapping of at least ZFS (NFSv4?) ACLs to NT > Security Descriptors because we have to emulate the kernel-level checks in user > space here. We can't just try to delete a file and hope for EPERM, this is a > not easily reversed operation :-) There is code around that does this, but it > has not really seen wide testing. Ok. So, could anyone lead me on this ? I'm volunteer to try to find a solution, but without any diagram of how the code is implemented, it could take me a while ! I'd appreciate at least few explanations on which routines would be evaluated for modifications. Nicolas
The best way to get guidance is to pop up on freenode.net's #samba-technical channel and ask specific questions interactively. Volker
stack analysis of a directory creation : ->smbd/mkdir_internal ->smbd/check_name (....) ->smbd/unix_mode (...) <-smbd/unix_mode ->smbd/vfswrap_mkdir ->smbd/lp_inherit_acls <-smbd/lp_inherit_acls ->smbd/vfswrap_chmod_acl ->smbd/chmod_acl ->smbd/copy_access_acl ->smbd/vfswrap_sys_acl_get_file ->smbd/sys_acl_get_file ->smbd/solarisacl_sys_acl_get_file ->smbd/solaris_acl_get_file <-smbd/solaris_acl_get_file <-smbd/solarisacl_sys_acl_get_file <-smbd/sys_acl_get_file <-smbd/vfswrap_sys_acl_get_file <-smbd/copy_access_acl (....)
Following discussions with obnox, here is a quick list of direct calls to subroutines defined in posix_acls.c: ./modules/nfs4_acls.c set_nt_acl ./modules/nfs4_acls.c try_chown ./modules/nfs4_acls.c unpack_nt_owners ./modules/vfs_afsacl.c set_nt_acl ./modules/vfs_aixacl2.c posix_fget_nt_acl ./modules/vfs_aixacl2.c posix_get_nt_acl ./modules/vfs_aixacl2.c set_nt_acl ./modules/vfs_aixacl2.c try_chown ./modules/vfs_aixacl2.c unpack_nt_owners ./modules/vfs_audit.c chmod_acl ./modules/vfs_audit.c fchmod_acl ./modules/vfs_cap.c chmod_acl ./modules/vfs_cap.c set_nt_acl ./modules/vfs_catia.c chmod_acl ./modules/vfs_catia.c set_nt_acl ./modules/vfs_default.c chmod_acl ./modules/vfs_default.c directory_has_default_acl ./modules/vfs_default.c fchmod_acl ./modules/vfs_default.c posix_fget_nt_acl ./modules/vfs_default.c posix_get_nt_acl ./modules/vfs_default.c set_nt_acl ./modules/vfs_extd_audit.c chmod_acl ./modules/vfs_extd_audit.c fchmod_acl ./modules/vfs_full_audit.c chmod_acl ./modules/vfs_full_audit.c fchmod_acl ./modules/vfs_full_audit.c set_nt_acl ./modules/vfs_gpfs.c posix_fget_nt_acl ./modules/vfs_gpfs.c posix_get_nt_acl ./modules/vfs_gpfs.c set_nt_acl ./modules/vfs_shadow_copy2.c chmod_acl ./modules/vfs_shadow_copy2.c set_nt_acl ./modules/vfs_zfsacl.c set_nt_acl ./profile/profile.c chmod_acl ./profile/profile.c fchmod_acl ./profile/profile.c set_nt_acl ./rpc_server/srv_eventlog_nt.c get_nt_acl_no_snum ./smbd/dosmode.c get_acl_group_bits ./smbd/open.c directory_has_default_acl ./smbd/open.c inherit_access_acl ./smbd/trans2.c free_empty_sys_acl ./smbd/trans2.c inherit_access_acl ./smbd/trans2.c set_unix_posix_acl ./smbd/trans2.c set_unix_posix_default_acl ./utils/status_profile.c chmod_acl ./utils/status_profile.c fchmod_acl ./utils/status_profile.c set_nt_acl
Have you tried 3.2rc2 already? I have not taken the time to reproduce the issue you reported here with 3.0rc2, but just yesterday I have seen some very promising results for some test cases which did not work in 3.0
changing product to samba3.2 since there is no zfsacl module in 3.0
I have pushed patch by Nils Goroll that was submitted for bug #5446 to the v3-2-test, v3-3-test and master branches. This prevents from calling out to posix acl methods by providing emtpy stubs. That Should fix this bug. Cheers - Michael
Hi all, Could anyone generate a tarball from current v3-2-test or explain in few words how to generate it easely behind a firewall ? I'd love to test in my environment . Nicolas
Hi, I'm testing 3.3.2 against this issue. Things are really better, though I still have problems when UNIX-simulated-permissions are too restrictives... I have to check SMB_VFS_OPENDIR which gave some permission denied, even if my directory have got an ACL which allows me to open.
Nicolas, could you please check if the settings and the patch I posted for a similar issue solves your problem? http://lists.samba.org/archive/samba/2008-November/145094.html https://bugzilla.samba.org/show_bug.cgi?id=6050
(In reply to comment #29) > Nicolas, > > could you please check if the settings and the patch I posted for a similar > issue solves your problem? Hi Nils, I read your bug description and took a look to you patch. It seems to be similar to my issue. obnox have made a fantastic job by fixing many bad calls to posix routines. Version 3.3 could be the solution. I'm currently testing 3.3.2, and there is a real difference. I need some time to confirm. My first test was inconclusive because of a simple misunderstanding of some ZFS-ACLs basics. I gave today another test environment to windows admins. I'm waiting for a feedback. Nicolas
Hi all, I get xcopy and robocopy, tools used my teh win sys'admin who made test for me (us). I found funny things. Never try to copy a directory with ACLs if you haven't write access on the source directory. I still have errors on some files...robocopy complains about denied access when timestamping ! It may, or may not, result of other complex ACL which, I think, is applied before timestamping. Stay tuned. Nicolas
Nicolas, thanks for the update. I'd be interested in some more detail, though. It would really be helpful if you could write up the various scenarios you do test and provide detail like the various ACLs, traces etc. Nils
Hi all, I can't find any case where this problem occurs in 3.3.4 . Thanks a lot. Solaris 10 + Samba 3.3.4 + ZFS is working as expected. My share conf is : [Sandbox] path = /export/Sandbox read only = no public = no vfs objects = zfsacl acl map full control = no dos filemode = no zfsacl: acesort = dontcare force unknown acl user = yes ea support = no map readonly = no map system = yes
Hi Nicolas, thanks a lot for the feedback. Cheers - Michael