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:
parent
57e548841f
commit
a2a77842a1
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user