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;
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;
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);
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);
status = smb2_create_blob_add(
state,
- &state->cblobs,
+ &state->in_cblobs,
SMB2_CREATE_TAG_TWRP,
twrp_blob);
if (!NT_STATUS_IS_OK(status)) {
}
}
+ 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 == '\\') {
share_access,
create_disposition,
create_options,
- &state->cblobs);
+ &state->in_cblobs);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
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;
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);
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;
}
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;
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;
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)) {
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)) {
FILE_DIRECTORY_FILE|
FILE_DELETE_ON_CLOSE|
FILE_OPEN_REPARSE_POINT, /* create_options */
+ NULL,
&fnum,
+ NULL,
+ NULL,
NULL);
}
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)) {
FILE_OPEN, /* create_disposition */
FILE_DELETE_ON_CLOSE|
FILE_OPEN_REPARSE_POINT, /* create_options */
+ NULL,
&fnum,
+ NULL,
+ NULL,
NULL);
}
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)) {
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 ? */
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)) {
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)) {
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)) {
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
FILE_OPEN, /* create_disposition */
create_options,
+ NULL,
pfnum,
+ NULL,
+ NULL,
NULL);
}
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);
}
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)) {
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)) {
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)) {
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)) {