s3:smbd: let mkdir_internal() try VFS_RENAME_HOW_NO_REPLACE first
commit1bacaae5261b157f0dc4efb68fdc82d4cf387eb9
authorStefan Metzmacher <metze@samba.org>
Wed, 7 Aug 2024 15:01:53 +0000 (7 17:01 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 21 Aug 2024 08:02:30 +0000 (21 08:02 +0000)
tree1812ce2aebe67af6e6d378f2d5222d5a959f376e
parentfe8b4617ddc1663d57ab5b0ffdeedb413e19a506
s3:smbd: let mkdir_internal() try VFS_RENAME_HOW_NO_REPLACE first

With renameat2(RENAME_NOREPLACE) being available
it's even better, as we don't even have the short
window where the incomplete directory is visible
to others.

The flow will be this:

tmp_name = ".::TMPNAME:D:$PID:client_name"
mkdirat(tmp_name, mode=client_mode);
prepare_acls(tmp_name);
renameat2(tmp_name, client_name, NOREPLACE);
if (EEXIST) {
   unlinkat(tmp_name);
   return EEXIST;
}
if (EINVAL) {
   /* fallback if NOREPLACE is not supported */
   mkdirat(client_name, mode=0);
   if (EEXIST) {
      unlinkat(tmp_name);
      return EEXIST;
   }
   renameat(tmp_name, client_name);
}

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15693

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/open.c