1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

smbd: Simplify smb_q_posix_symlink()

Use the dirfsp from call_trans2qpathinfo(), avoid a call to parent_pathref()

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Volker Lendecke 2024-02-11 13:10:01 +01:00 committed by Jeremy Allison
parent e35b3af2e8
commit 88921ac177

View File

@ -2529,16 +2529,14 @@ static NTSTATUS smb_q_posix_acl(
static NTSTATUS smb_q_posix_symlink( static NTSTATUS smb_q_posix_symlink(
struct connection_struct *conn, struct connection_struct *conn,
struct smb_request *req, struct smb_request *req,
struct files_struct *dirfsp,
struct smb_filename *smb_fname, struct smb_filename *smb_fname,
char **ppdata, char **ppdata,
int *ptotal_data) int *ptotal_data)
{ {
char buffer[PATH_MAX+1]; char *target = NULL;
size_t needed, len; size_t needed, len;
int link_len;
char *pdata = NULL; char *pdata = NULL;
struct smb_filename *parent_fname = NULL;
struct smb_filename *base_name = NULL;
NTSTATUS status; NTSTATUS status;
DBG_DEBUG("SMB_QUERY_FILE_UNIX_LINK for file %s\n", DBG_DEBUG("SMB_QUERY_FILE_UNIX_LINK for file %s\n",
@ -2548,40 +2546,39 @@ static NTSTATUS smb_q_posix_symlink(
return NT_STATUS_DOS(ERRSRV, ERRbadlink); return NT_STATUS_DOS(ERRSRV, ERRbadlink);
} }
status = parent_pathref( if (fsp_get_pathref_fd(smb_fname->fsp) != -1) {
talloc_tos(), /*
conn->cwd_fsp, * fsp is an O_PATH open, Linux does a "freadlink"
smb_fname, * with an empty name argument to readlinkat
&parent_fname, */
&base_name); status = readlink_talloc(talloc_tos(),
smb_fname->fsp,
NULL,
&target);
} else {
struct smb_filename smb_fname_rel = *smb_fname;
char *slash = NULL;
slash = strrchr_m(smb_fname->base_name, '/');
if (slash != NULL) {
smb_fname_rel.base_name = slash + 1;
}
status = readlink_talloc(talloc_tos(),
dirfsp,
&smb_fname_rel,
&target);
}
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
DBG_DEBUG("parent_pathref failed: %s\n", nt_errstr(status)); DBG_DEBUG("readlink_talloc() failed: %s\n", nt_errstr(status));
return status; return status;
} }
link_len = SMB_VFS_READLINKAT( needed = talloc_get_size(target) * 2;
conn,
parent_fname->fsp,
base_name,
buffer,
sizeof(buffer)-1);
TALLOC_FREE(parent_fname);
if (link_len == -1) {
status = map_nt_error_from_unix(errno);
DBG_DEBUG("READLINKAT failed: %s\n", nt_errstr(status));
return status;
}
if (link_len >= sizeof(buffer)) {
return NT_STATUS_INTERNAL_ERROR;
}
buffer[link_len] = 0;
needed = (link_len+1)*2;
*ppdata = SMB_REALLOC(*ppdata, needed); *ppdata = SMB_REALLOC(*ppdata, needed);
if (*ppdata == NULL) { if (*ppdata == NULL) {
TALLOC_FREE(target);
return NT_STATUS_NO_MEMORY; return NT_STATUS_NO_MEMORY;
} }
pdata = *ppdata; pdata = *ppdata;
@ -2590,10 +2587,11 @@ static NTSTATUS smb_q_posix_symlink(
pdata, pdata,
req->flags2, req->flags2,
pdata, pdata,
buffer, target,
needed, needed,
STR_TERMINATE, STR_TERMINATE,
&len); &len);
TALLOC_FREE(target);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
return status; return status;
} }
@ -2783,6 +2781,7 @@ static void call_trans2qpathinfo(
status = smb_q_posix_symlink( status = smb_q_posix_symlink(
conn, conn,
req, req,
dirfsp,
smb_fname, smb_fname,
ppdata, ppdata,
&total_data); &total_data);