libsmb: Pass symlink error up through cli_smb2_create_fnum_recv()
authorVolker Lendecke <vl@samba.org>
Tue, 20 Sep 2022 12:31:31 +0000 (14:31 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 22 Nov 2022 18:27:33 +0000 (18:27 +0000)
Not passing through the sync wrapper yet. Not needed right now, and
it's simple to add if required.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
examples/fuse/clifuse.c
source3/libsmb/cli_smb2_fnum.c
source3/libsmb/cli_smb2_fnum.h
source3/libsmb/clifile.c
source3/libsmb/pylibsmb.c

index 721b282baf0e72e40426185f8c88a48e588e100b..2d9edad5f47b618cdcc423c877676bc962abdc62 100644 (file)
@@ -178,7 +178,7 @@ static void cli_ll_create_done(struct tevent_req *req)
        uint16_t fnum;
        NTSTATUS status;
 
-       status = cli_smb2_create_fnum_recv(req, &fnum, NULL, NULL, NULL);
+       status = cli_smb2_create_fnum_recv(req, &fnum, NULL, NULL, NULL, NULL);
        TALLOC_FREE(req);
        if (!NT_STATUS_IS_OK(status)) {
                fuse_reply_err(state->freq, map_errno_from_nt_status(status));
@@ -875,7 +875,7 @@ static void cli_ll_open_done(struct tevent_req *req)
        uint16_t fnum;
        NTSTATUS status;
 
-       status = cli_smb2_create_fnum_recv(req, &fnum, NULL, NULL, NULL);
+       status = cli_smb2_create_fnum_recv(req, &fnum, NULL, NULL, NULL, NULL);
        TALLOC_FREE(req);
        if (!NT_STATUS_IS_OK(status)) {
                fuse_reply_err(state->freq, map_errno_from_nt_status(status));
index 0f753f61d85696953e04c1ac899b6b175732d680..a0323d701c39da8af6767782e3bad2916445a078 100644 (file)
@@ -198,6 +198,7 @@ struct cli_smb2_create_fnum_state {
        struct smb2_create_blobs in_cblobs;
        struct smb2_create_blobs out_cblobs;
        struct smb_create_returns cr;
+       struct symlink_reparse_struct *symlink;
        uint16_t fnum;
        struct tevent_req *subreq;
 };
@@ -344,7 +345,7 @@ static void cli_smb2_create_fnum_done(struct tevent_req *subreq)
                &h.fid_volatile, &state->cr,
                state,
                &state->out_cblobs,
-               NULL);
+               &state->symlink);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -369,13 +370,18 @@ NTSTATUS cli_smb2_create_fnum_recv(
        uint16_t *pfnum,
        struct smb_create_returns *cr,
        TALLOC_CTX *mem_ctx,
-       struct smb2_create_blobs *out_cblobs)
+       struct smb2_create_blobs *out_cblobs,
+       struct symlink_reparse_struct **symlink)
 {
        struct cli_smb2_create_fnum_state *state = tevent_req_data(
                req, struct cli_smb2_create_fnum_state);
        NTSTATUS status;
 
        if (tevent_req_is_nterror(req, &status)) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) &&
+                   (symlink != NULL)) {
+                       *symlink = talloc_move(mem_ctx, &state->symlink);
+               }
                state->cli->raw_status = status;
                return status;
        }
@@ -447,7 +453,8 @@ NTSTATUS cli_smb2_create_fnum(
        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
                goto fail;
        }
-       status = cli_smb2_create_fnum_recv(req, pfid, cr, mem_ctx, out_cblobs);
+       status = cli_smb2_create_fnum_recv(
+               req, pfid, cr, mem_ctx, out_cblobs, NULL);
  fail:
        TALLOC_FREE(frame);
        return status;
@@ -841,7 +848,8 @@ static void cli_smb2_mkdir_opened(struct tevent_req *subreq)
        NTSTATUS status;
        uint16_t fnum = 0xffff;
 
-       status = cli_smb2_create_fnum_recv(subreq, &fnum, NULL, NULL, NULL);
+       status = cli_smb2_create_fnum_recv(
+               subreq, &fnum, NULL, NULL, NULL, NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -927,7 +935,7 @@ static void cli_smb2_rmdir_opened1(struct tevent_req *subreq)
        NTSTATUS status;
 
        status = cli_smb2_create_fnum_recv(
-               subreq, &state->fnum, NULL, NULL, NULL);
+               subreq, &state->fnum, NULL, NULL, NULL, NULL);
        TALLOC_FREE(subreq);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
@@ -980,7 +988,7 @@ static void cli_smb2_rmdir_opened2(struct tevent_req *subreq)
        NTSTATUS status;
 
        status = cli_smb2_create_fnum_recv(
-               subreq, &state->fnum, NULL, NULL, NULL);
+               subreq, &state->fnum, NULL, NULL, NULL, NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -1099,7 +1107,8 @@ static void cli_smb2_unlink_opened1(struct tevent_req *subreq)
        uint16_t fnum = 0xffff;
        NTSTATUS status;
 
-       status = cli_smb2_create_fnum_recv(subreq, &fnum, NULL, NULL, NULL);
+       status = cli_smb2_create_fnum_recv(
+               subreq, &fnum, NULL, NULL, NULL, NULL);
        TALLOC_FREE(subreq);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) ||
@@ -1153,7 +1162,8 @@ static void cli_smb2_unlink_opened2(struct tevent_req *subreq)
        uint16_t fnum = 0xffff;
        NTSTATUS status;
 
-       status = cli_smb2_create_fnum_recv(subreq, &fnum, NULL, NULL, NULL);
+       status = cli_smb2_create_fnum_recv(
+               subreq, &fnum, NULL, NULL, NULL, NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -1369,7 +1379,7 @@ static void cli_smb2_list_opened(struct tevent_req *subreq)
        NTSTATUS status;
 
        status = cli_smb2_create_fnum_recv(
-               subreq, &state->fnum, NULL, NULL, NULL);
+               subreq, &state->fnum, NULL, NULL, NULL, NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -1885,7 +1895,7 @@ static void get_fnum_from_path_opened_file(struct tevent_req *subreq)
        NTSTATUS status;
 
        status = cli_smb2_create_fnum_recv(
-               subreq, &state->fnum, NULL, NULL, NULL);
+               subreq, &state->fnum, NULL, NULL, NULL, NULL);
        TALLOC_FREE(subreq);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
@@ -1955,7 +1965,7 @@ static void get_fnum_from_path_opened_reparse(struct tevent_req *subreq)
        struct get_fnum_from_path_state *state = tevent_req_data(
                req, struct get_fnum_from_path_state);
        NTSTATUS status = cli_smb2_create_fnum_recv(
-               subreq, &state->fnum, NULL, NULL, NULL);
+               subreq, &state->fnum, NULL, NULL, NULL, NULL);
        tevent_req_simple_finish_ntstatus(subreq, status);
 }
 
@@ -2913,7 +2923,7 @@ static void cli_smb2_mxac_opened(struct tevent_req *subreq)
        NTSTATUS status;
 
        status = cli_smb2_create_fnum_recv(
-               subreq, &state->fnum, NULL, state, &out_cblobs);
+               subreq, &state->fnum, NULL, state, &out_cblobs, NULL);
        TALLOC_FREE(subreq);
 
        if (tevent_req_nterror(req, status)) {
index 8940313c5cbb717320133871b6c5217a1fca32f2..73a82b5551d73af3764b13187a2207bccdc8cf62 100644 (file)
@@ -24,6 +24,7 @@ struct smbXcli_conn;
 struct smbXcli_session;
 struct cli_state;
 struct file_info;
+struct symlink_reparse_struct;
 
 struct tevent_req *cli_smb2_create_fnum_send(
        TALLOC_CTX *mem_ctx,
@@ -43,7 +44,8 @@ NTSTATUS cli_smb2_create_fnum_recv(
        uint16_t *pfnum,
        struct smb_create_returns *cr,
        TALLOC_CTX *mem_ctx,
-       struct smb2_create_blobs *out_cblobs);
+       struct smb2_create_blobs *out_cblobs,
+       struct symlink_reparse_struct **symlink);
 NTSTATUS cli_smb2_create_fnum(
        struct cli_state *cli,
        const char *fname,
index 039bbcb076a4ff5c09b0f9b1ba7ed91ea7cd5c43..31776a58621aeef3bd54cf1a6db6c1c1312f1a74 100644 (file)
@@ -1814,7 +1814,7 @@ static void cli_smb2_hardlink_opened(struct tevent_req *subreq)
        bool ok;
 
        status = cli_smb2_create_fnum_recv(
-               subreq, &state->fnum_src, NULL, NULL, NULL);
+               subreq, &state->fnum_src, NULL, NULL, NULL, NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -2774,6 +2774,7 @@ static void cli_ntcreate_done_smb2(struct tevent_req *subreq)
                &state->fnum,
                &state->cr,
                NULL,
+               NULL,
                NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
index dea156d623ccda5309497d19177ca63977d69b09..eaff6d68bef9f9aa6c4a106f369a8c766ca16dfc 100644 (file)
@@ -1118,7 +1118,7 @@ static PyObject *py_cli_create_ex(
 
        if (smbXcli_conn_protocol(self->cli->conn) >= PROTOCOL_SMB2_02) {
                status = cli_smb2_create_fnum_recv(
-                       req, &fnum, &cr, NULL, &create_contexts_out);
+                       req, &fnum, &cr, NULL, &create_contexts_out, NULL);
        } else {
                status = cli_ntcreate_recv(req, &fnum, &cr);
        }