We have FreeNAS-188.8.131.52-RELEASE-x64 providing a samba share to IIS (hosted by 2012 R2, if that's relevant)
ssasan01# smbd --version
The freenas server is joined to an AD provided by windows servers. Domain is "AD". IIS sites run as an active directory user unique to that site. Both the application pool (each site has it's own one) identity and the "physical path credentials" for the site in IIS are configured to be the same active directory user.
For the most part everything is working except folder creates. In a folder, that the IIS user has access to (write/modify/read/execute) (App_Data, actually) application code attempts to create a folder using DirectoryInfo.Create The resulting folder is created successfully on disk, and appear to inherit the ACL permissions from the parent, however the create call returns an error.
Access to the path --snip--\App_Data\packages\created\__testFolder__ is denied. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.UnauthorizedAccessException: Access to the path --snip--\App_Data\packages\created\__testFolder__ is denied.
The following error appears in the log samba log (level is currently 1 as this is a production server)
Sep 8 17:28:05 ssasan01 smbd: [2014/09/08 17:28:05.026127, 0] ../source3/smbd/open.c:543(change_dir_owner_to_parent)
Sep 8 17:28:05 ssasan01 smbd: change_dir_owner_to_parent: failed to change current working directory to --snip--/App_Data/packages/created/__testFolder__. Error was Permission denied
(--snip-- replacing the base path)
Files seem to work correctly. If I view the created folder via SSH, I see this:
d-w-rwx---+ 2 AD\applicationpoolidentity group 2 Sep 8 17:28 __testFolder__
(AD\applicationpoolidentity is the user for the site, group is the same as the other folders)
The same error/problem occurs if I try to create a folder using windows explorer while logged in as a user that has access to the share (and write access to the folder in question). The folder, at least, according to windows, is set to inherit permissions. In this case, the newly created folder doesn't get any ACLs assigned to it (explorer has no permission to the created folder) but I suspect this is most likely due to an order-of-operations type issue as when IIS/.net creates the folder in the other scenario, things happen in a different order than when you create a folder via explorer.
I have reviewed the smb.conf file by hand to eliminate potential GUI issues, here are any that I think might be relevant from searching google for this issue. I added 'force create mode' and 'force directory mode' while testing.
unix extensions = no acl check permissions = true acl map full control = true create mask = 0666 directory mask = 0777 force create mode = 0666 force directory mode = 0777 inherit owner = yes inherit permissions = yes inherit acls = yes writeable = yes browseable = yes
Note: all folders and files are created via samba client (not from the linux shell directly) either via IIS code executing as a user that has rights to that folder, or via a windows explorer window while logged into the server as a user that has rights to create files and folders. Files seem to work correctly.
We are using freenas here due to ZFS snapshotting plus redundancy, it is also providing NFS services to other machines and iSCSI to other machines, so replacing this server with a windows based file server (or for that matter, another SAN/NAS server), while, not out of the question, would not be an easy job.
One possible oddity is that the owner of all folders and files for the whole tree is an administrative level user (not administrator!), to allow us to be able to access and change permissions as administrators.
Update 1: Working from the error in the log, it looks like the folder is created successfully but then the samba process does not have permission to change into that folder in order to set the permissions.
The parent folder (in this case, 'created') was configured with the following mask:
chmod 777 created (the folder I am trying to create new folders within) then the IIS process (and windows explorer) both can create and delete the folders successfully within that subdirectory.
We are testing with two different processes: When testing with windows explorer, I'm logged onto windows as a domain user which is the "owner" and "group" of the parent folder. That same user also has full control granted via ACL. Group has rwx via mask. When testing via .net/IIS, the pool is running as a user which has write/modify/read (everything except full control) granted via ACL. This user is not owner or group and there are no mask permissions for everyone.
The error goes away and everything works right if I
chmod 777 the folder that is the immediate parent to the one I'm trying to create. I don't think this solves the problem as it's not secure to 777 everything, especially given we're using full ACL.
Update 2 007 works, 000 fails - seems the public mask bit is being used here, regardless of the ACL and regardless as the user that is being used for share access. Is this because the user who is accessing the share is not the owner or the group? We don't want to add all site users to a group and give the group write via unix masks, since that would allow a path traversal security vulnerability (one site user would then have access to all other site folders as they're a member of the group), wouldn't it? We could selectively apply "owner" '700' and chown the site roots and their children to the site user, but that seems pretty unmaintainable and bypasses the use of ACLs and inheritance? Or is 007/777 safe in this case because of the use of ACLs as another layer?
Update 3 Checked the samba source for open.c to see what change_dir_owner_to_parent was actually doing. First it gets the folder using getwd (cached according to getwd_cache) and then it performs a cwd into that folder to "lock" it so that the owner change is not in a race condition. This is where my tests seem to fail. In previous testing/updates, I have found that if I grant xx7 to anything then it works and continues to work even after I take the everyone mask away again. I assume this is caching of the permission checks, so the problem will reoccur once the cache expires/invalidates. I am not sure which cache variable applies to this. I found a folder which was not working (had 070) and confirmed I could not create new folders correctly. I then used chmod to grant 074 to the folder and confirmed that this resolved the problem. So that's better than 777 but still unsure why this is even required? Do I need to chmod -R 074 * the entire share?
Update 4 Found another folder that was broken (had 070) - confirmed broken by using the CMS user interface and created a folder, confirming that the process that creates the folder did not work. Then applied chmod 000 to the parent via SSH. Now the process creates the folder successfully. What is going on?! I haven't touched the windows ACLs for any of these tests.
Update 5 Running out of broken folders to test with... took a folder that was 070 and not working (verified in CMS) and then chmod 070 it (same permissions as it currently had) and now I can create items inside the folder via the CMS (using windows ACLs which provide the permissions) So if I chmod the broken folder -to anything- then it starts working?