]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
libsmb: Introduce "struct symlink_reparse_struct"
authorVolker Lendecke <vl@samba.org>
Sun, 24 Oct 2021 13:24:42 +0000 (15:24 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 11 Nov 2021 19:08:37 +0000 (19:08 +0000)
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>
source3/libsmb/clisymlink.c
source3/libsmb/reparse_symlink.c
source3/libsmb/reparse_symlink.h

index ac8d2e74c9b666cd46d8e13377e35bcba675edbe..36202d9e1f19a81e12234c80931c05665b1a7d9c 100644 (file)
@@ -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;
 }
 
index d7a4d542552dec59a1c5b3ef4fd5b86a52d9a944..48895813961b3eea78cd6ac11d089b4363b8db9d 100644 (file)
@@ -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;
 }
index 6492578ebebd6e99955a7e7c44f0c118cbe3e8bd..b561fa9fc985f793d63e2673c004f2fe51d7c5a0 100644 (file)
 #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