libsmb: add in/out cblobs to cli_smb2_create_fnum
authorVolker Lendecke <vl@samba.org>
Wed, 20 Feb 2019 16:23:46 +0000 (17:23 +0100)
committerJeremy Allison <jra@samba.org>
Fri, 1 Mar 2019 00:32:12 +0000 (00:32 +0000)
This is driven by the imminent smb2 unix extensions, we'll want to make use of
it from source3/libsmb.

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

index 3814c9801dd92b916f10871b724b694cc9eda972..954c412f09cddb0166b112b3590f8bd4e33f4ac5 100644 (file)
@@ -159,7 +159,8 @@ static void cli_ll_create(fuse_req_t freq, fuse_ino_t parent, const char *name,
                FILE_ATTRIBUTE_NORMAL,
                FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                FILE_CREATE,
-               FILE_NON_DIRECTORY_FILE);
+               FILE_NON_DIRECTORY_FILE,
+               NULL);
        if (req == NULL) {
                TALLOC_FREE(state);
                fuse_reply_err(freq, ENOMEM);
@@ -177,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);
+       status = cli_smb2_create_fnum_recv(req, &fnum, NULL, NULL, NULL);
        TALLOC_FREE(req);
        if (!NT_STATUS_IS_OK(status)) {
                fuse_reply_err(state->freq, map_errno_from_nt_status(status));
@@ -851,7 +852,8 @@ static void cli_ll_open(fuse_req_t freq, fuse_ino_t ino,
                FILE_ATTRIBUTE_NORMAL,
                FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                FILE_OPEN,
-               FILE_NON_DIRECTORY_FILE);
+               FILE_NON_DIRECTORY_FILE,
+               NULL);
        if (req == NULL) {
                TALLOC_FREE(state);
                fuse_reply_err(freq, ENOMEM);
@@ -867,7 +869,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);
+       status = cli_smb2_create_fnum_recv(req, &fnum, NULL, NULL, NULL);
        TALLOC_FREE(req);
        if (!NT_STATUS_IS_OK(status)) {
                fuse_reply_err(state->freq, map_errno_from_nt_status(status));
index 181078507a1260cb2bac0001d5952e79933244c2..cd713d93c6cafe6572b512a04698d9bc58d4b0ae 100644 (file)
@@ -158,7 +158,8 @@ static uint8_t flags_to_smb2_oplock(uint32_t create_flags)
 
 struct cli_smb2_create_fnum_state {
        struct cli_state *cli;
-       struct smb2_create_blobs cblobs;
+       struct smb2_create_blobs in_cblobs;
+       struct smb2_create_blobs out_cblobs;
        struct smb_create_returns cr;
        uint16_t fnum;
        struct tevent_req *subreq;
@@ -178,7 +179,8 @@ struct tevent_req *cli_smb2_create_fnum_send(
        uint32_t file_attributes,
        uint32_t share_access,
        uint32_t create_disposition,
-       uint32_t create_options)
+       uint32_t create_options,
+       const struct smb2_create_blobs *in_cblobs)
 {
        struct tevent_req *req, *subreq;
        struct cli_smb2_create_fnum_state *state;
@@ -186,6 +188,7 @@ struct tevent_req *cli_smb2_create_fnum_send(
        const char *startp = NULL;
        const char *endp = NULL;
        time_t tstamp = (time_t)0;
+       NTSTATUS status;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct cli_smb2_create_fnum_state);
@@ -210,7 +213,6 @@ struct tevent_req *cli_smb2_create_fnum_send(
                size_t len_after_gmt = fname + fname_len - endp;
                DATA_BLOB twrp_blob;
                NTTIME ntt;
-               NTSTATUS status;
 
                char *new_fname = talloc_array(state, char,
                                len_before_gmt + len_after_gmt + 1);
@@ -229,7 +231,7 @@ struct tevent_req *cli_smb2_create_fnum_send(
 
                status = smb2_create_blob_add(
                        state,
-                       &state->cblobs,
+                       &state->in_cblobs,
                        SMB2_CREATE_TAG_TWRP,
                        twrp_blob);
                if (!NT_STATUS_IS_OK(status)) {
@@ -238,6 +240,19 @@ struct tevent_req *cli_smb2_create_fnum_send(
                }
        }
 
+       if (in_cblobs != NULL) {
+               uint32_t i;
+               for (i=0; i<in_cblobs->num_blobs; i++) {
+                       struct smb2_create_blob *b = &in_cblobs->blobs[i];
+                       status = smb2_create_blob_add(
+                               state, &state->in_cblobs, b->tag, b->data);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               tevent_req_nterror(req, status);
+                               return tevent_req_post(req, ev);
+                       }
+               }
+       }
+
        /* SMB2 is pickier about pathnames. Ensure it doesn't
           start in a '\' */
        if (*fname == '\\') {
@@ -268,7 +283,7 @@ struct tevent_req *cli_smb2_create_fnum_send(
                                     share_access,
                                     create_disposition,
                                     create_options,
-                                    &state->cblobs);
+                                    &state->in_cblobs);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
@@ -289,8 +304,12 @@ static void cli_smb2_create_fnum_done(struct tevent_req *subreq)
        struct smb2_hnd h;
        NTSTATUS status;
 
-       status = smb2cli_create_recv(subreq, &h.fid_persistent,
-                                    &h.fid_volatile, &state->cr, NULL, NULL);
+       status = smb2cli_create_recv(
+               subreq,
+               &h.fid_persistent,
+               &h.fid_volatile, &state->cr,
+               state,
+               &state->out_cblobs);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -310,8 +329,12 @@ static bool cli_smb2_create_fnum_cancel(struct tevent_req *req)
        return tevent_req_cancel(state->subreq);
 }
 
-NTSTATUS cli_smb2_create_fnum_recv(struct tevent_req *req, uint16_t *pfnum,
-                                  struct smb_create_returns *cr)
+NTSTATUS cli_smb2_create_fnum_recv(
+       struct tevent_req *req,
+       uint16_t *pfnum,
+       struct smb_create_returns *cr,
+       TALLOC_CTX *mem_ctx,
+       struct smb2_create_blobs *out_cblobs)
 {
        struct cli_smb2_create_fnum_state *state = tevent_req_data(
                req, struct cli_smb2_create_fnum_state);
@@ -327,6 +350,13 @@ NTSTATUS cli_smb2_create_fnum_recv(struct tevent_req *req, uint16_t *pfnum,
        if (cr != NULL) {
                *cr = state->cr;
        }
+       if (out_cblobs != NULL) {
+               *out_cblobs = (struct smb2_create_blobs) {
+                       .num_blobs = state->out_cblobs.num_blobs,
+                       .blobs = talloc_move(
+                               mem_ctx, &state->out_cblobs.blobs),
+               };
+       }
        state->cli->raw_status = NT_STATUS_OK;
        return NT_STATUS_OK;
 }
@@ -341,8 +371,11 @@ NTSTATUS cli_smb2_create_fnum(
        uint32_t share_access,
        uint32_t create_disposition,
        uint32_t create_options,
+       const struct smb2_create_blobs *in_cblobs,
        uint16_t *pfid,
-       struct smb_create_returns *cr)
+       struct smb_create_returns *cr,
+       TALLOC_CTX *mem_ctx,
+       struct smb2_create_blobs *out_cblobs)
 {
        TALLOC_CTX *frame = talloc_stackframe();
        struct tevent_context *ev;
@@ -371,14 +404,15 @@ NTSTATUS cli_smb2_create_fnum(
                file_attributes,
                share_access,
                create_disposition,
-               create_options);
+               create_options,
+               in_cblobs);
        if (req == NULL) {
                goto fail;
        }
        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
                goto fail;
        }
-       status = cli_smb2_create_fnum_recv(req, pfid, cr);
+       status = cli_smb2_create_fnum_recv(req, pfid, cr, mem_ctx, out_cblobs);
  fail:
        TALLOC_FREE(frame);
        return status;
@@ -657,7 +691,10 @@ NTSTATUS cli_smb2_mkdir(struct cli_state *cli, const char *dname)
                        FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
                        FILE_CREATE,            /* create_disposition */
                        FILE_DIRECTORY_FILE,    /* create_options */
+                       NULL,
                        &fnum,
+                       NULL,
+                       NULL,
                        NULL);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -696,7 +733,10 @@ NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dname)
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
                        FILE_OPEN,              /* create_disposition */
                        FILE_DIRECTORY_FILE,    /* create_options */
+                       NULL,
                        &fnum,
+                       NULL,
+                       NULL,
                        NULL);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
@@ -717,7 +757,10 @@ NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dname)
                        FILE_DIRECTORY_FILE|
                                FILE_DELETE_ON_CLOSE|
                                FILE_OPEN_REPARSE_POINT, /* create_options */
+                       NULL,
                        &fnum,
+                       NULL,
+                       NULL,
                        NULL);
        }
 
@@ -764,7 +807,10 @@ NTSTATUS cli_smb2_unlink(struct cli_state *cli, const char *fname)
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
                        FILE_OPEN,              /* create_disposition */
                        FILE_DELETE_ON_CLOSE,   /* create_options */
+                       NULL,
                        &fnum,
+                       NULL,
+                       NULL,
                        NULL);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
@@ -784,7 +830,10 @@ NTSTATUS cli_smb2_unlink(struct cli_state *cli, const char *fname)
                        FILE_OPEN,              /* create_disposition */
                        FILE_DELETE_ON_CLOSE|
                                FILE_OPEN_REPARSE_POINT, /* create_options */
+                       NULL,
                        &fnum,
+                       NULL,
+                       NULL,
                        NULL);
        }
 
@@ -965,7 +1014,10 @@ NTSTATUS cli_smb2_list(struct cli_state *cli,
                        FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
                        FILE_OPEN,              /* create_disposition */
                        FILE_DIRECTORY_FILE,    /* create_options */
+                       NULL,
                        &fnum,
+                       NULL,
+                       NULL,
                        NULL);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -1152,8 +1204,11 @@ NTSTATUS cli_smb2_qpathinfo_basic(struct cli_state *cli,
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
                        FILE_OPEN,              /* create_disposition */
                        FILE_DIRECTORY_FILE,    /* create_options */
+                       NULL,
                        &fnum,
-                       &cr);
+                       &cr,
+                       NULL,
+                       NULL);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
                /* Maybe a file ? */
@@ -1166,8 +1221,11 @@ NTSTATUS cli_smb2_qpathinfo_basic(struct cli_state *cli,
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
                        FILE_OPEN,              /* create_disposition */
                        0,      /* create_options */
+                       NULL,
                        &fnum,
-                       &cr);
+                       &cr,
+                       NULL,
+                       NULL);
        }
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -1219,7 +1277,10 @@ NTSTATUS cli_smb2_chkpath(struct cli_state *cli,
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
                        FILE_OPEN,              /* create_disposition */
                        FILE_DIRECTORY_FILE,    /* create_options */
+                       NULL,
                        &fnum,
+                       NULL,
+                       NULL,
                        NULL);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -1265,7 +1326,10 @@ static NTSTATUS get_fnum_from_path(struct cli_state *cli,
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
                        FILE_OPEN,              /* create_disposition */
                        create_options,
+                       NULL,
                        pfnum,
+                       NULL,
+                       NULL,
                        NULL);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
@@ -1285,7 +1349,10 @@ static NTSTATUS get_fnum_from_path(struct cli_state *cli,
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
                        FILE_OPEN,              /* create_disposition */
                        create_options,
+                       NULL,
                        pfnum,
+                       NULL,
+                       NULL,
                        NULL);
        }
 
@@ -1300,7 +1367,10 @@ static NTSTATUS get_fnum_from_path(struct cli_state *cli,
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
                        FILE_OPEN,              /* create_disposition */
                        FILE_DIRECTORY_FILE,    /* create_options */
+                       NULL,
                        pfnum,
+                       NULL,
+                       NULL,
                        NULL);
        }
 
@@ -2036,7 +2106,10 @@ NTSTATUS cli_smb2_dskattr(struct cli_state *cli, const char *path,
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
                        FILE_OPEN,              /* create_disposition */
                        FILE_DIRECTORY_FILE,    /* create_options */
+                       NULL,
                        &fnum,
+                       NULL,
+                       NULL,
                        NULL);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -2147,7 +2220,10 @@ NTSTATUS cli_smb2_get_fs_full_size_info(struct cli_state *cli,
                                     FILE_SHARE_DELETE, /* share_access */
                                 FILE_OPEN,             /* create_disposition */
                                 FILE_DIRECTORY_FILE,   /* create_options */
+                                NULL,
                                 &fnum,
+                                NULL,
+                                NULL,
                                 NULL);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -2240,7 +2316,10 @@ NTSTATUS cli_smb2_get_fs_attr_info(struct cli_state *cli, uint32_t *fs_attr)
                                     FILE_SHARE_DELETE, /* share_access */
                                 FILE_OPEN,             /* create_disposition */
                                 FILE_DIRECTORY_FILE,   /* create_options */
+                                NULL,
                                 &fnum,
+                                NULL,
+                                NULL,
                                 NULL);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -2326,7 +2405,10 @@ NTSTATUS cli_smb2_get_fs_volume_info(struct cli_state *cli,
                                     FILE_SHARE_DELETE, /* share_access */
                                 FILE_OPEN,             /* create_disposition */
                                 FILE_DIRECTORY_FILE,   /* create_options */
+                                NULL,
                                 &fnum,
+                                NULL,
+                                NULL,
                                 NULL);
 
        if (!NT_STATUS_IS_OK(status)) {
index 9dfa93eab666ec33127a984078c18ac1746ed367..9e259482f4a4654fd73ad92b66bfffc3b844c372 100644 (file)
@@ -36,9 +36,14 @@ struct tevent_req *cli_smb2_create_fnum_send(
        uint32_t file_attributes,
        uint32_t share_access,
        uint32_t create_disposition,
-       uint32_t create_options);
-NTSTATUS cli_smb2_create_fnum_recv(struct tevent_req *req, uint16_t *pfnum,
-                                  struct smb_create_returns *cr);
+       uint32_t create_options,
+       const struct smb2_create_blobs *in_cblobs);
+NTSTATUS cli_smb2_create_fnum_recv(
+       struct tevent_req *req,
+       uint16_t *pfnum,
+       struct smb_create_returns *cr,
+       TALLOC_CTX *mem_ctx,
+       struct smb2_create_blobs *out_cblobs);
 NTSTATUS cli_smb2_create_fnum(
        struct cli_state *cli,
        const char *fname,
@@ -49,8 +54,11 @@ NTSTATUS cli_smb2_create_fnum(
        uint32_t share_access,
        uint32_t create_disposition,
        uint32_t create_options,
+       const struct smb2_create_blobs *in_cblobs,
        uint16_t *pfid,
-       struct smb_create_returns *cr);
+       struct smb_create_returns *cr,
+       TALLOC_CTX *mem_ctx,
+       struct smb2_create_blobs *out_cblobs);
 
 struct tevent_req *cli_smb2_close_fnum_send(TALLOC_CTX *mem_ctx,
                                            struct tevent_context *ev,
index 6940858c6406c4cf717f916793a42b8f673d4553..7d72dc82858eb665a019faf0a67a37cf25228f02 100644 (file)
@@ -2125,7 +2125,8 @@ struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx,
                        file_attributes,
                        share_access,
                        create_disposition,
-                       create_options);
+                       create_options,
+                       NULL);
                if (tevent_req_nomem(subreq, req)) {
                        return tevent_req_post(req, ev);
                }
@@ -2171,7 +2172,12 @@ static void cli_ntcreate_done_smb2(struct tevent_req *subreq)
                req, struct cli_ntcreate_state);
        NTSTATUS status;
 
-       status = cli_smb2_create_fnum_recv(subreq, &state->fnum, &state->cr);
+       status = cli_smb2_create_fnum_recv(
+               subreq,
+               &state->fnum,
+               &state->cr,
+               NULL,
+               NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;