As a result of a customer situation I have found that Windows will allow a CreateFile to succeed for what Samba calls OVERWRITE_IF, CREATE and OPEN_IF when the requester asks for DELETE_ON_CLOSE and DELETE access but does not have DELETE or DELETE_CHILD in the directory the file is being created in. However, in the case of OVERWRITE_IF and OPEN_IF, only allows the operation to succeed if the requested file does not exist. Otherwise it returns ACCESS_DENIED.
Samba only allows this when CREATE is used.
I believe that the following code is at fault:
/* This is the correct thing to do (check every time) but can_delete
* is expensive (it may have to read the parent directory
* permissions). So for now we're not doing it unless we have a strong
* hint the client is really going to delete this file. If the client
* is forcing FILE_CREATE let the filesystem take care of the
* permissions. */
/* Setting FILE_SHARE_DELETE is the hint. */
if ((create_disposition != FILE_CREATE)
&& (access_mask & DELETE_ACCESS)
&& (!(can_delete_file_in_directory(conn, smb_fname) ||
can_access_file_acl(conn, smb_fname, DELETE_ACCESS)))) {
status = NT_STATUS_ACCESS_DENIED;
DEBUG(10,("create_file_unixpath: open file %s "
"for delete ACCESS_DENIED\n",
smb_fname_str_dbg(smb_fname)));
goto fail;
}
It should check the other two disposition values and defer the decision about needing can_delete_file_in_directory until we know whether or not the file exists.
If have checked the master branch as well, and while the code has been moved around, and in particular the checking has now been deferred to can_set_delete_on_close, but that too does not allow it in the cases Windows would, I believe.