From 5823634b46ef7c1ef959916dd427656e11f76e61 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Oct 2021 15:24:42 +0200 Subject: libsmb: Introduce "struct symlink_reparse_struct" Simplify symlink_reparse_buffer_parse() slightly, failure cleanup becomes simpler with that, and this struct will be useful elsewhere Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- source3/libsmb/clisymlink.c | 22 +++++------ source3/libsmb/reparse_symlink.c | 81 ++++++++++++++++++++++------------------ source3/libsmb/reparse_symlink.h | 12 ++++-- 3 files changed, 65 insertions(+), 50 deletions(-) diff --git a/source3/libsmb/clisymlink.c b/source3/libsmb/clisymlink.c index ac8d2e74c9b..36202d9e1f1 100644 --- a/source3/libsmb/clisymlink.c +++ b/source3/libsmb/clisymlink.c @@ -378,34 +378,34 @@ NTSTATUS cli_readlink_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, { struct cli_readlink_state *state = tevent_req_data( req, struct cli_readlink_state); + struct symlink_reparse_struct *symlink = NULL; NTSTATUS status; - char *substitute_name; - char *print_name; - uint32_t flags; if (tevent_req_is_nterror(req, &status)) { return status; } - if (!symlink_reparse_buffer_parse(state->data, state->num_data, - talloc_tos(), &substitute_name, - &print_name, &flags)) { + symlink = symlink_reparse_buffer_parse( + talloc_tos(), state->data, state->num_data); + if (symlink == NULL) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } if (psubstitute_name != NULL) { - *psubstitute_name = talloc_move(mem_ctx, &substitute_name); + *psubstitute_name = talloc_move( + mem_ctx, &symlink->substitute_name); } - TALLOC_FREE(substitute_name); if (pprint_name != NULL) { - *pprint_name = talloc_move(mem_ctx, &print_name); + *pprint_name = talloc_move(mem_ctx, &symlink->print_name); } - TALLOC_FREE(print_name); if (pflags != NULL) { - *pflags = flags; + *pflags = symlink->flags; } + + TALLOC_FREE(symlink); + return NT_STATUS_OK; } diff --git a/source3/libsmb/reparse_symlink.c b/source3/libsmb/reparse_symlink.c index d7a4d542552..48895813961 100644 --- a/source3/libsmb/reparse_symlink.c +++ b/source3/libsmb/reparse_symlink.c @@ -99,25 +99,23 @@ fail: return false; } -bool symlink_reparse_buffer_parse( - const uint8_t *src, size_t srclen, TALLOC_CTX *mem_ctx, - char **psubstitute_name, char **pprint_name, uint32_t *pflags) +struct symlink_reparse_struct *symlink_reparse_buffer_parse( + TALLOC_CTX *mem_ctx, const uint8_t *src, size_t srclen) { + struct symlink_reparse_struct *result = NULL; uint16_t reparse_data_length; uint16_t substitute_name_offset, substitute_name_length; uint16_t print_name_offset, print_name_length; - uint32_t flags; - char *substitute_name = NULL; - char *print_name = NULL; + bool ok; if (srclen < 20) { DEBUG(10, ("srclen = %d, expected >= 20\n", (int)srclen)); - return false; + goto fail; } if (IVAL(src, 0) != IO_REPARSE_TAG_SYMLINK) { DEBUG(10, ("Got ReparseTag %8.8x, expected %8.8x\n", IVAL(src, 0), IO_REPARSE_TAG_SYMLINK)); - return false; + goto fail; } reparse_data_length = SVAL(src, 4); @@ -125,18 +123,17 @@ bool symlink_reparse_buffer_parse( substitute_name_length = SVAL(src, 10); print_name_offset = SVAL(src, 12); print_name_length = SVAL(src, 14); - flags = IVAL(src, 16); if (reparse_data_length < 12) { DEBUG(10, ("reparse_data_length = %d, expected >= 12\n", (int)reparse_data_length)); - return false; + goto fail; } if (smb_buffer_oob(srclen - 8, reparse_data_length, 0)) { DEBUG(10, ("reparse_data_length (%d) too large for " "src_len (%d)\n", (int)reparse_data_length, (int)srclen)); - return false; + goto fail; } if (smb_buffer_oob(reparse_data_length - 12, substitute_name_offset, substitute_name_length)) { @@ -145,7 +142,7 @@ bool symlink_reparse_buffer_parse( (int)substitute_name_offset, (int)substitute_name_length, (int)reparse_data_length - 12)); - return false; + goto fail; } if (smb_buffer_oob(reparse_data_length - 12, print_name_offset, print_name_length)) { @@ -154,36 +151,48 @@ bool symlink_reparse_buffer_parse( (int)print_name_offset, (int)print_name_length, (int)reparse_data_length - 12)); - return false; + goto fail; } - if ((psubstitute_name != NULL) && - !convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, - src + 20 + substitute_name_offset, - substitute_name_length, - &substitute_name, NULL)) { + result = talloc_zero(mem_ctx, struct symlink_reparse_struct); + if (result == NULL) { + DBG_DEBUG("talloc failed\n"); + goto fail; + } + + ok = convert_string_talloc( + result, + CH_UTF16, + CH_UNIX, + src + 20 + substitute_name_offset, + substitute_name_length, + &result->substitute_name, + NULL); + if (!ok) { DEBUG(10, ("convert_string_talloc for substitute_name " "failed\n")); - return false; + goto fail; } - if ((pprint_name != NULL) && - !convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, - src + 20 + print_name_offset, - print_name_length, - &print_name, NULL)) { + + ok = convert_string_talloc( + result, + CH_UTF16, + CH_UNIX, + src + 20 + print_name_offset, + print_name_length, + &result->print_name, + NULL); + if (!ok) { DEBUG(10, ("convert_string_talloc for print_name " "failed\n")); - TALLOC_FREE(substitute_name); - return false; - } - if (psubstitute_name != NULL) { - *psubstitute_name = substitute_name; - } - if (pprint_name != NULL) { - *pprint_name = print_name; - } - if (pflags != NULL) { - *pflags = flags; + goto fail; } - return true; + + result->unparsed_path_length = SVAL(src, 6); + result->flags = IVAL(src, 16); + + return result; +fail: + TALLOC_FREE(result); + return NULL; } diff --git a/source3/libsmb/reparse_symlink.h b/source3/libsmb/reparse_symlink.h index 6492578ebeb..b561fa9fc98 100644 --- a/source3/libsmb/reparse_symlink.h +++ b/source3/libsmb/reparse_symlink.h @@ -26,11 +26,17 @@ #include "replace.h" #include +struct symlink_reparse_struct { + uint16_t unparsed_path_length; /* reserved for the reparse point */ + char *substitute_name; + char *print_name; + uint32_t flags; +}; + bool symlink_reparse_buffer_marshall( const char *substitute, const char *printname, uint32_t flags, TALLOC_CTX *mem_ctx, uint8_t **pdst, size_t *pdstlen); -bool symlink_reparse_buffer_parse( - const uint8_t *src, size_t srclen, TALLOC_CTX *mem_ctx, - char **psubstitute_name, char **pprint_name, uint32_t *pflags); +struct symlink_reparse_struct *symlink_reparse_buffer_parse( + TALLOC_CTX *mem_ctx, const uint8_t *src, size_t srclen); #endif -- cgit v1.2.1