smbd: add synthetic_pathref()
authorRalph Boehme <slow@samba.org>
Thu, 21 Jan 2021 14:04:57 +0000 (15:04 +0100)
committerJeremy Allison <jra@samba.org>
Thu, 28 Jan 2021 08:11:49 +0000 (08:11 +0000)
Similar to synthetic_smb_fname(), but also opens a pathref fsp.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/files.c
source3/smbd/proto.h

index f60d5979f533ca45fc95c912ae3fbf931c25e14f..eceeaf2c6af80d91448bcfcf71cdb005290af485 100644 (file)
@@ -622,6 +622,58 @@ NTSTATUS move_smb_fname_fsp_link(struct smb_filename *smb_fname_dst,
        return NT_STATUS_OK;
 }
 
+/**
+ * Create an smb_fname and open smb_fname->fsp pathref
+ **/
+NTSTATUS synthetic_pathref(TALLOC_CTX *mem_ctx,
+                          struct files_struct *dirfsp,
+                          const char *base_name,
+                          const char *stream_name,
+                          const SMB_STRUCT_STAT *psbuf,
+                          NTTIME twrp,
+                          uint32_t flags,
+                          struct smb_filename **_smb_fname)
+{
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
+       int ret;
+
+       smb_fname = synthetic_smb_fname(mem_ctx,
+                                       base_name,
+                                       stream_name,
+                                       psbuf,
+                                       twrp,
+                                       flags);
+       if (smb_fname == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!VALID_STAT(smb_fname->st)) {
+               ret = vfs_stat(dirfsp->conn, smb_fname);
+               if (ret != 0) {
+                       DBG_ERR("stat [%s] failed: %s",
+                               smb_fname_str_dbg(smb_fname),
+                               strerror(errno));
+                       TALLOC_FREE(smb_fname);
+                       return map_nt_error_from_unix(errno);
+               }
+       }
+
+       status = openat_pathref_fsp(dirfsp, smb_fname);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
+               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("opening [%s] failed\n",
+                       smb_fname_str_dbg(smb_fname));
+               TALLOC_FREE(smb_fname);
+               return status;
+       }
+
+       *_smb_fname = smb_fname;
+       return NT_STATUS_OK;
+}
+
 /****************************************************************************
  Close all open files for a connection.
 ****************************************************************************/
index 2e181a94e9198771ed3b542018d2c2794cf6dd1a..a65c786c24df1fad094607b6dbc4b26a25b417c0 100644 (file)
@@ -468,6 +468,15 @@ void smb_fname_fsp_unlink(struct smb_filename *smb_fname);
 NTSTATUS move_smb_fname_fsp_link(struct smb_filename *smb_fname_dst,
                                 struct smb_filename *smb_fname_src);
 
+NTSTATUS synthetic_pathref(TALLOC_CTX *mem_ctx,
+                          struct files_struct *dirfsp,
+                          const char *base_name,
+                          const char *stream_name,
+                          const SMB_STRUCT_STAT *psbuf,
+                          NTTIME twrp,
+                          uint32_t flags,
+                          struct smb_filename **_smb_fname);
+
 /* The following definitions come from smbd/ipc.c  */
 
 NTSTATUS nt_status_np_pipe(NTSTATUS status);