diff options
-rw-r--r-- | source3/libsmb/clifile.c | 87 |
1 files changed, 19 insertions, 68 deletions
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index ee37808a22..168dd4bb4c 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -2112,19 +2112,13 @@ NTSTATUS cli_nttrans_create(struct cli_state *cli, ****************************************************************************/ struct cli_openx_state { - struct tevent_context *ev; - struct cli_state *cli; const char *fname; uint16_t vwv[15]; uint16_t fnum; - unsigned openfn; - unsigned dos_deny; - uint8_t additional_flags; struct iovec bytes; }; static void cli_openx_done(struct tevent_req *subreq); -static void cli_open_ntcreate_done(struct tevent_req *subreq); struct tevent_req *cli_openx_create(TALLOC_CTX *mem_ctx, struct event_context *ev, @@ -2134,61 +2128,64 @@ struct tevent_req *cli_openx_create(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct cli_openx_state *state; + unsigned openfn; + unsigned accessmode; + uint8_t additional_flags; uint8_t *bytes; req = tevent_req_create(mem_ctx, &state, struct cli_openx_state); if (req == NULL) { return NULL; } - state->ev = ev; - state->cli = cli; - state->fname = fname; + openfn = 0; if (flags & O_CREAT) { - state->openfn |= (1<<4); + openfn |= (1<<4); } if (!(flags & O_EXCL)) { if (flags & O_TRUNC) - state->openfn |= (1<<1); + openfn |= (1<<1); else - state->openfn |= (1<<0); + openfn |= (1<<0); } - state->dos_deny = (share_mode<<4); + accessmode = (share_mode<<4); if ((flags & O_ACCMODE) == O_RDWR) { - state->dos_deny |= 2; + accessmode |= 2; } else if ((flags & O_ACCMODE) == O_WRONLY) { - state->dos_deny |= 1; + accessmode |= 1; } #if defined(O_SYNC) if ((flags & O_SYNC) == O_SYNC) { - state->dos_deny |= (1<<14); + accessmode |= (1<<14); } #endif /* O_SYNC */ if (share_mode == DENY_FCB) { - state->dos_deny = 0xFF; + accessmode = 0xFF; } SCVAL(state->vwv + 0, 0, 0xFF); SCVAL(state->vwv + 0, 1, 0); SSVAL(state->vwv + 1, 0, 0); SSVAL(state->vwv + 2, 0, 0); /* no additional info */ - SSVAL(state->vwv + 3, 0, state->dos_deny); + SSVAL(state->vwv + 3, 0, accessmode); SSVAL(state->vwv + 4, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); SSVAL(state->vwv + 5, 0, 0); SIVAL(state->vwv + 6, 0, 0); - SSVAL(state->vwv + 8, 0, state->openfn); + SSVAL(state->vwv + 8, 0, openfn); SIVAL(state->vwv + 9, 0, 0); SIVAL(state->vwv + 11, 0, 0); SIVAL(state->vwv + 13, 0, 0); + additional_flags = 0; + if (cli->use_oplocks) { /* if using oplocks then ask for a batch oplock via core and extended methods */ - state->additional_flags = + additional_flags = FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK; SSVAL(state->vwv+2, 0, SVAL(state->vwv+2, 0) | 6); } @@ -2204,8 +2201,7 @@ struct tevent_req *cli_openx_create(TALLOC_CTX *mem_ctx, state->bytes.iov_base = (void *)bytes; state->bytes.iov_len = talloc_get_size(bytes); - subreq = cli_smb_req_create(state, ev, cli, SMBopenX, - state->additional_flags, + subreq = cli_smb_req_create(state, ev, cli, SMBopenX, additional_flags, 15, state->vwv, 1, &state->bytes); if (subreq == NULL) { TALLOC_FREE(req); @@ -2246,59 +2242,14 @@ static void cli_openx_done(struct tevent_req *subreq) uint16_t *vwv; uint8_t *inbuf; NTSTATUS status; - uint32_t access_mask, share_mode, create_disposition, create_options; status = cli_smb_recv(subreq, state, &inbuf, 3, &wct, &vwv, NULL, NULL); TALLOC_FREE(subreq); - - if (NT_STATUS_IS_OK(status)) { - state->fnum = SVAL(vwv+2, 0); - tevent_req_done(req); - return; - } - - if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { - tevent_req_nterror(req, status); - return; - } - - /* - * For the new shiny OS/X Lion SMB server, try a ntcreate - * fallback. - */ - - if (!map_open_params_to_ntcreate(state->fname, state->dos_deny, - state->openfn, &access_mask, - &share_mode, &create_disposition, - &create_options, NULL)) { - tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); - return; - } - - subreq = cli_ntcreate_send(state, state->ev, state->cli, - state->fname, 0, access_mask, - 0, share_mode, create_disposition, - create_options, 0); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, cli_open_ntcreate_done, req); -} - -static void cli_open_ntcreate_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct cli_openx_state *state = tevent_req_data( - req, struct cli_openx_state); - NTSTATUS status; - - status = cli_ntcreate_recv(subreq, &state->fnum); - TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; } + state->fnum = SVAL(vwv+2, 0); tevent_req_done(req); } |