summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2021-10-24 15:24:42 +0200
committerJeremy Allison <jra@samba.org>2021-11-11 19:08:37 +0000
commit5823634b46ef7c1ef959916dd427656e11f76e61 (patch)
tree498829e5433567e7b17d08633fc33060c9188dac
parent58c8289b2ff8bf3a413e82f1d4dc05ab10a6e2d6 (diff)
downloadsamba-5823634b46ef7c1ef959916dd427656e11f76e61.tar.gz
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 <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
-rw-r--r--source3/libsmb/clisymlink.c22
-rw-r--r--source3/libsmb/reparse_symlink.c81
-rw-r--r--source3/libsmb/reparse_symlink.h12
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 <talloc.h>
+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