1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

smbd: pass symlink target path to safe_symlink_target_path()

Moves creating the symlink target path via symlink_target_path() to the
caller. This prepares for using this in non_widelink_open(), where it will
replace symlink_target_below_conn() with the same functionality.

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

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
This commit is contained in:
Ralph Boehme 2024-01-02 12:49:14 +01:00 committed by Volker Lendecke
parent 62cbe145c7
commit 0515dded4d
2 changed files with 38 additions and 39 deletions

View File

@ -704,6 +704,11 @@ struct smb_filename *synthetic_smb_fname(TALLOC_CTX *mem_ctx,
const SMB_STRUCT_STAT *psbuf, const SMB_STRUCT_STAT *psbuf,
NTTIME twrp, NTTIME twrp,
uint32_t flags); uint32_t flags);
NTSTATUS safe_symlink_target_path(TALLOC_CTX *mem_ctx,
const char *connectpath,
const char *target,
size_t unparsed,
char **_relative);
NTSTATUS filename_convert_dirfsp( NTSTATUS filename_convert_dirfsp(
TALLOC_CTX *ctx, TALLOC_CTX *ctx,
connection_struct *conn, connection_struct *conn,

View File

@ -659,44 +659,34 @@ static char *symlink_target_path(
return ret; return ret;
} }
static NTSTATUS safe_symlink_target_path( NTSTATUS safe_symlink_target_path(TALLOC_CTX *mem_ctx,
TALLOC_CTX *mem_ctx, const char *connectpath,
const char *connectpath, const char *target,
const char *name_in, size_t unparsed,
const char *substitute, char **_relative)
size_t unparsed,
char **_name_out)
{ {
char *target = NULL;
char *abs_target = NULL; char *abs_target = NULL;
char *abs_target_canon = NULL; char *abs_target_canon = NULL;
const char *relative = NULL; const char *relative = NULL;
char *name_out = NULL;
NTSTATUS status = NT_STATUS_NO_MEMORY;
bool in_share; bool in_share;
NTSTATUS status = NT_STATUS_NO_MEMORY;
target = symlink_target_path(mem_ctx, name_in, substitute, unparsed); DBG_DEBUG("connectpath [%s] target [%s] unparsed [%zu]\n",
if (target == NULL) { connectpath, target, unparsed);
if (target[0] == '/') {
abs_target = talloc_strdup(mem_ctx, target);
} else {
abs_target = talloc_asprintf(mem_ctx,
"%s/%s",
connectpath,
target);
}
if (abs_target == NULL) {
goto fail; goto fail;
} }
DBG_DEBUG("name_in: %s, substitute: %s, unparsed: %zu, target=%s\n", abs_target_canon = canonicalize_absolute_path(abs_target, abs_target);
name_in,
substitute,
unparsed,
target);
if (target[0] == '/') {
abs_target = target;
} else {
abs_target = talloc_asprintf(
target, "%s/%s", connectpath, target);
if (abs_target == NULL) {
goto fail;
}
}
abs_target_canon = canonicalize_absolute_path(target, abs_target);
if (abs_target_canon == NULL) { if (abs_target_canon == NULL) {
goto fail; goto fail;
} }
@ -712,15 +702,14 @@ static NTSTATUS safe_symlink_target_path(
goto fail; goto fail;
} }
name_out = talloc_strdup(mem_ctx, relative); *_relative = talloc_strdup(mem_ctx, relative);
if (name_out == NULL) { if (*_relative == NULL) {
goto fail; goto fail;
} }
status = NT_STATUS_OK; status = NT_STATUS_OK;
*_name_out = name_out;
fail: fail:
TALLOC_FREE(target); TALLOC_FREE(abs_target);
return status; return status;
} }
@ -1127,8 +1116,8 @@ NTSTATUS filename_convert_dirfsp(
{ {
struct open_symlink_err *symlink_err = NULL; struct open_symlink_err *symlink_err = NULL;
NTSTATUS status; NTSTATUS status;
char *substitute = NULL;
char *target = NULL; char *target = NULL;
char *safe_target = NULL;
size_t symlink_redirects = 0; size_t symlink_redirects = 0;
next: next:
@ -1193,19 +1182,24 @@ next:
* resolve all symlinks locally. * resolve all symlinks locally.
*/ */
substitute = symlink_err->reparse->substitute_name; target = symlink_target_path(mem_ctx,
name_in,
symlink_err->reparse->substitute_name,
symlink_err->unparsed);
if (target == NULL) {
return NT_STATUS_NO_MEMORY;
}
status = safe_symlink_target_path(mem_ctx, status = safe_symlink_target_path(mem_ctx,
conn->connectpath, conn->connectpath,
name_in, target,
substitute,
symlink_err->unparsed, symlink_err->unparsed,
&target); &safe_target);
TALLOC_FREE(symlink_err); TALLOC_FREE(symlink_err);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
return status; return status;
} }
name_in = target; name_in = safe_target;
symlink_redirects += 1; symlink_redirects += 1;