diff options
author | Jeremy Allison <jra@samba.org> | 2017-11-28 15:46:40 -0800 |
---|---|---|
committer | Ralph Boehme <slow@samba.org> | 2017-12-06 15:02:16 +0100 |
commit | eb3028a46f263642b9ab4afddbd2d0034443eb0b (patch) | |
tree | 1505c7aaa9273ef78b504a09260baa90e01386a8 | |
parent | cd0e0b112001e122ef1e4fa3434eda32ffd50e46 (diff) | |
download | samba-eb3028a46f263642b9ab4afddbd2d0034443eb0b.tar.gz |
s3: libsmb: Do a naive response to SMB2 "stopped on symlink". Assume the last component was the reparse point.
Attempt re-open with FILE_OPEN_REPARSE_POINT. This matches the SMB1
behavior for smbclient.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13159
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Böhme <slow@samba.org>
-rw-r--r-- | source3/libsmb/cli_smb2_fnum.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index f8861e53345..c40d6dd3a45 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -686,6 +686,27 @@ NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dname) &fnum, NULL); + if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { + /* + * Naive option to match our SMB1 code. Assume the + * symlink path that tripped us up was the last + * component and try again. Eventually we will have to + * deal with the returned path unprocessed component. JRA. + */ + status = cli_smb2_create_fnum(cli, + dname, + 0, /* create_flags */ + DELETE_ACCESS, /* desired_access */ + FILE_ATTRIBUTE_DIRECTORY, /* file attributes */ + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */ + FILE_OPEN, /* create_disposition */ + FILE_DIRECTORY_FILE| + FILE_DELETE_ON_CLOSE| + FILE_OPEN_REPARSE_POINT, /* create_options */ + &fnum, + NULL); + } + if (!NT_STATUS_IS_OK(status)) { return status; } @@ -724,6 +745,26 @@ NTSTATUS cli_smb2_unlink(struct cli_state *cli, const char *fname) &fnum, NULL); + if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { + /* + * Naive option to match our SMB1 code. Assume the + * symlink path that tripped us up was the last + * component and try again. Eventually we will have to + * deal with the returned path unprocessed component. JRA. + */ + status = cli_smb2_create_fnum(cli, + fname, + 0, /* create_flags */ + DELETE_ACCESS, /* desired_access */ + FILE_ATTRIBUTE_NORMAL, /* file attributes */ + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */ + FILE_OPEN, /* create_disposition */ + FILE_DELETE_ON_CLOSE| + FILE_OPEN_REPARSE_POINT, /* create_options */ + &fnum, + NULL); + } + if (!NT_STATUS_IS_OK(status)) { return status; } @@ -1157,6 +1198,7 @@ static NTSTATUS get_fnum_from_path(struct cli_state *cli, NTSTATUS status; size_t namelen = strlen(name); TALLOC_CTX *frame = talloc_stackframe(); + uint32_t create_options = 0; /* SMB2 is pickier about pathnames. Ensure it doesn't end in a '\' */ @@ -1178,11 +1220,32 @@ static NTSTATUS get_fnum_from_path(struct cli_state *cli, 0, /* file attributes */ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */ FILE_OPEN, /* create_disposition */ - 0, /* create_options */ + create_options, + pfnum, + NULL); + + if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { + /* + * Naive option to match our SMB1 code. Assume the + * symlink path that tripped us up was the last + * component and try again. Eventually we will have to + * deal with the returned path unprocessed component. JRA. + */ + create_options |= FILE_OPEN_REPARSE_POINT; + status = cli_smb2_create_fnum(cli, + name, + 0, /* create_flags */ + desired_access, + 0, /* file attributes */ + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */ + FILE_OPEN, /* create_disposition */ + create_options, pfnum, NULL); + } if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) { + create_options |= FILE_DIRECTORY_FILE; status = cli_smb2_create_fnum(cli, name, 0, /* create_flags */ |