From: Ralph Boehme Date: Thu, 21 Jan 2021 16:05:17 +0000 (+0100) Subject: smbd: add parent_pathref() X-Git-Tag: tevent-0.11.0~1912 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6085f6c856e5da0bb703580d878e2302e360a902;p=thirdparty%2Fsamba.git smbd: add parent_pathref() Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- diff --git a/source3/smbd/files.c b/source3/smbd/files.c index eceeaf2c6af..448a284780b 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -674,6 +674,70 @@ NTSTATUS synthetic_pathref(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +static int atname_destructor(struct smb_filename *smb_fname) +{ + destroy_fsp_smb_fname_link(&smb_fname->fsp_link); + return 0; +} + +/** + * Turn a path into a parent pathref and atname + * + * This returns the parent pathref in _parent and the name relative to it. If + * smb_fname was a pathref (ie smb_fname->fsp != NULL), then _atname will be a + * pathref as well, ie _atname->fsp will point at the same fsp as + * smb_fname->fsp. + **/ +NTSTATUS parent_pathref(TALLOC_CTX *mem_ctx, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + struct smb_filename **_parent, + struct smb_filename **_atname) +{ + struct smb_filename *parent = NULL; + struct smb_filename *atname = NULL; + NTSTATUS status; + int ret; + bool ok; + + ok = parent_smb_fname(mem_ctx, + smb_fname, + &parent, + &atname); + if (!ok) { + return NT_STATUS_NO_MEMORY; + } + + ret = vfs_stat(dirfsp->conn, parent); + if (ret != 0) { + TALLOC_FREE(parent); + return map_nt_error_from_unix(errno); + } + + status = openat_pathref_fsp(dirfsp, parent); + if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { + status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(parent); + return status; + } + + if (smb_fname->fsp != NULL) { + status = fsp_smb_fname_link(smb_fname->fsp, + &atname->fsp_link, + &atname->fsp); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(parent); + return status; + } + talloc_set_destructor(atname, atname_destructor); + } + *_parent = parent; + *_atname = atname; + return NT_STATUS_OK; +} + /**************************************************************************** Close all open files for a connection. ****************************************************************************/ diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index a65c786c24d..f67daf2d2be 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -477,6 +477,12 @@ NTSTATUS synthetic_pathref(TALLOC_CTX *mem_ctx, uint32_t flags, struct smb_filename **_smb_fname); +NTSTATUS parent_pathref(TALLOC_CTX *mem_ctx, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + struct smb_filename **_parent, + struct smb_filename **_atname); + /* The following definitions come from smbd/ipc.c */ NTSTATUS nt_status_np_pipe(NTSTATUS status);