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

smbd: Make read_symlink_reparse() return a reparse_data_buffer

Will make generalized handling of reparse point error returns easier
once we will also allow creating symlink reparse point files over smb.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
Volker Lendecke 2024-02-04 16:07:22 +01:00 committed by Andreas Schneider
parent 57e548841f
commit a2a77842a1
3 changed files with 37 additions and 33 deletions

View File

@ -1127,6 +1127,7 @@ NTSTATUS filename_convert_dirfsp(
struct smb_filename **_smb_fname)
{
struct open_symlink_err *symlink_err = NULL;
struct symlink_reparse_struct *lnk = NULL;
NTSTATUS status;
char *target = NULL;
char *safe_target = NULL;
@ -1161,13 +1162,14 @@ next:
if (!NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
return status;
}
lnk = &symlink_err->reparse->parsed.lnk;
/*
* If we're on an MSDFS share, see if this is
* an MSDFS link.
*/
if (lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) &&
strnequal(symlink_err->reparse->substitute_name, "msdfs:", 6))
strnequal(lnk->substitute_name, "msdfs:", 6))
{
TALLOC_FREE(*_smb_fname);
TALLOC_FREE(symlink_err);
@ -1196,7 +1198,7 @@ next:
target = symlink_target_path(mem_ctx,
name_in,
symlink_err->reparse->substitute_name,
lnk->substitute_name,
symlink_err->unparsed);
if (target == NULL) {
return NT_STATUS_NO_MEMORY;

View File

@ -733,28 +733,34 @@ NTSTATUS readlink_talloc(
return NT_STATUS_OK;
}
NTSTATUS read_symlink_reparse(
TALLOC_CTX *mem_ctx,
struct files_struct *dirfsp,
struct smb_filename *smb_relname,
struct symlink_reparse_struct **_symlink)
NTSTATUS read_symlink_reparse(TALLOC_CTX *mem_ctx,
struct files_struct *dirfsp,
struct smb_filename *smb_relname,
struct reparse_data_buffer **_reparse)
{
struct symlink_reparse_struct *symlink = NULL;
struct reparse_data_buffer *reparse = NULL;
struct symlink_reparse_struct *lnk = NULL;
NTSTATUS status;
symlink = talloc_zero(mem_ctx, struct symlink_reparse_struct);
if (symlink == NULL) {
reparse = talloc_zero(mem_ctx, struct reparse_data_buffer);
if (reparse == NULL) {
goto nomem;
}
*reparse = (struct reparse_data_buffer){
.tag = IO_REPARSE_TAG_SYMLINK,
};
lnk = &reparse->parsed.lnk;
status = readlink_talloc(
symlink, dirfsp, smb_relname, &symlink->substitute_name);
status = readlink_talloc(reparse,
dirfsp,
smb_relname,
&lnk->substitute_name);
if (!NT_STATUS_IS_OK(status)) {
DBG_DEBUG("readlink_talloc failed: %s\n", nt_errstr(status));
goto fail;
}
if (symlink->substitute_name[0] == '/') {
if (lnk->substitute_name[0] == '/') {
char *subdir_path = NULL;
char *abs_target_canon = NULL;
const char *relative = NULL;
@ -768,9 +774,8 @@ NTSTATUS read_symlink_reparse(
goto nomem;
}
abs_target_canon =
canonicalize_absolute_path(talloc_tos(),
symlink->substitute_name);
abs_target_canon = canonicalize_absolute_path(
talloc_tos(), lnk->substitute_name);
if (abs_target_canon == NULL) {
goto nomem;
}
@ -780,25 +785,25 @@ NTSTATUS read_symlink_reparse(
abs_target_canon,
&relative);
if (in_share) {
TALLOC_FREE(symlink->substitute_name);
symlink->substitute_name =
talloc_strdup(symlink, relative);
if (symlink->substitute_name == NULL) {
TALLOC_FREE(lnk->substitute_name);
lnk->substitute_name = talloc_strdup(reparse,
relative);
if (lnk->substitute_name == NULL) {
goto nomem;
}
}
}
if (!IS_DIRECTORY_SEP(symlink->substitute_name[0])) {
symlink->flags |= SYMLINK_FLAG_RELATIVE;
if (!IS_DIRECTORY_SEP(lnk->substitute_name[0])) {
lnk->flags |= SYMLINK_FLAG_RELATIVE;
}
*_symlink = symlink;
*_reparse = reparse;
return NT_STATUS_OK;
nomem:
status = NT_STATUS_NO_MEMORY;
fail:
TALLOC_FREE(symlink);
TALLOC_FREE(reparse);
return status;
}

View File

@ -377,12 +377,10 @@ NTSTATUS open_stream_pathref_fsp(
struct files_struct **_base_fsp,
struct smb_filename *smb_fname);
struct symlink_reparse_struct;
struct open_symlink_err {
struct stat_ex st;
size_t unparsed;
struct symlink_reparse_struct *reparse;
struct reparse_data_buffer *reparse;
};
NTSTATUS create_open_symlink_err(TALLOC_CTX *mem_ctx,
@ -407,13 +405,12 @@ NTSTATUS readlink_talloc(
struct smb_filename *smb_relname,
char **_substitute);
struct symlink_reparse_struct;
struct reparse_data_buffer;
NTSTATUS read_symlink_reparse(
TALLOC_CTX *mem_ctx,
struct files_struct *dirfsp,
struct smb_filename *smb_relname,
struct symlink_reparse_struct **_symlink);
NTSTATUS read_symlink_reparse(TALLOC_CTX *mem_ctx,
struct files_struct *dirfsp,
struct smb_filename *smb_relname,
struct reparse_data_buffer **_reparse);
void smb_fname_fsp_unlink(struct smb_filename *smb_fname);