diff options
-rw-r--r-- | source3/libsmb/clifile.c | 179 | ||||
-rw-r--r-- | source3/libsmb/proto.h | 29 |
2 files changed, 208 insertions, 0 deletions
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 5f93ced6af6..88cecd505ce 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -26,6 +26,7 @@ #include "libsmb/clirap.h" #include "trans2.h" #include "ntioctl.h" +#include "libcli/security/secdesc.h" /*********************************************************** Common function for pushing stings, used by smb_bytes_push_str() @@ -1906,6 +1907,184 @@ NTSTATUS cli_ntcreate(struct cli_state *cli, return status; } +struct cli_nttrans_create_state { + uint16_t fnum; +}; + +static void cli_nttrans_create_done(struct tevent_req *subreq); + +struct tevent_req *cli_nttrans_create_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uint32_t CreatFlags, + uint32_t DesiredAccess, + uint32_t FileAttributes, + uint32_t ShareAccess, + uint32_t CreateDisposition, + uint32_t CreateOptions, + uint8_t SecurityFlags, + struct security_descriptor *secdesc, + struct ea_struct *eas, + int num_eas) +{ + struct tevent_req *req, *subreq; + struct cli_nttrans_create_state *state; + uint8_t *param; + uint8_t *secdesc_buf; + size_t secdesc_len; + NTSTATUS status; + size_t converted_len; + + req = tevent_req_create(mem_ctx, + &state, struct cli_nttrans_create_state); + if (req == NULL) { + return NULL; + } + + if (secdesc != NULL) { + status = marshall_sec_desc(talloc_tos(), secdesc, + &secdesc_buf, &secdesc_len); + if (tevent_req_nterror(req, status)) { + DEBUG(10, ("marshall_sec_desc failed: %s\n", + nt_errstr(status))); + return tevent_req_post(req, ev); + } + } else { + secdesc_buf = NULL; + secdesc_len = 0; + } + + if (num_eas != 0) { + /* + * TODO ;-) + */ + tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + return tevent_req_post(req, ev); + } + + param = talloc_array(state, uint8_t, 53); + if (tevent_req_nomem(param, req)) { + return tevent_req_post(req, ev); + } + + param = trans2_bytes_push_str(param, cli_ucs2(cli), + fname, strlen(fname), + &converted_len); + if (tevent_req_nomem(param, req)) { + return tevent_req_post(req, ev); + } + + SIVAL(param, 0, CreatFlags); + SIVAL(param, 4, 0x0); /* RootDirectoryFid */ + SIVAL(param, 8, DesiredAccess); + SIVAL(param, 12, 0x0); /* AllocationSize */ + SIVAL(param, 16, 0x0); /* AllocationSize */ + SIVAL(param, 20, FileAttributes); + SIVAL(param, 24, ShareAccess); + SIVAL(param, 28, CreateDisposition); + SIVAL(param, 32, CreateOptions); + SIVAL(param, 36, secdesc_len); + SIVAL(param, 40, 0); /* EA length*/ + SIVAL(param, 44, converted_len); + SIVAL(param, 48, 0x02); /* ImpersonationLevel */ + SCVAL(param, 52, SecurityFlags); + + subreq = cli_trans_send(state, ev, cli, SMBnttrans, + NULL, -1, /* name, fid */ + NT_TRANSACT_CREATE, 0, + NULL, 0, 0, /* setup */ + param, talloc_get_size(param), 128, /* param */ + secdesc_buf, secdesc_len, 0); /* data */ + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_nttrans_create_done, req); + return req; +} + +static void cli_nttrans_create_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_nttrans_create_state *state = tevent_req_data( + req, struct cli_nttrans_create_state); + uint8_t *param; + uint32_t num_param; + NTSTATUS status; + + status = cli_trans_recv(subreq, talloc_tos(), NULL, + NULL, 0, NULL, /* rsetup */ + ¶m, 69, &num_param, + NULL, 0, NULL); + if (tevent_req_nterror(req, status)) { + return; + } + state->fnum = SVAL(param, 2); + TALLOC_FREE(param); + tevent_req_done(req); +} + +NTSTATUS cli_nttrans_create_recv(struct tevent_req *req, uint16_t *fnum) +{ + struct cli_nttrans_create_state *state = tevent_req_data( + req, struct cli_nttrans_create_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + *fnum = state->fnum; + return NT_STATUS_OK; +} + +NTSTATUS cli_nttrans_create(struct cli_state *cli, + const char *fname, + uint32_t CreatFlags, + uint32_t DesiredAccess, + uint32_t FileAttributes, + uint32_t ShareAccess, + uint32_t CreateDisposition, + uint32_t CreateOptions, + uint8_t SecurityFlags, + struct security_descriptor *secdesc, + struct ea_struct *eas, + int num_eas, + uint16_t *pfid) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_nttrans_create_send(frame, ev, cli, fname, CreatFlags, + DesiredAccess, FileAttributes, + ShareAccess, CreateDisposition, + CreateOptions, SecurityFlags, + secdesc, eas, num_eas); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_nttrans_create_recv(req, pfid); + fail: + TALLOC_FREE(frame); + return status; +} + /**************************************************************************** Open a file WARNING: if you open with O_WRONLY then getattrE won't work! diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index 5166ef3e970..f88a891d585 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -557,6 +557,35 @@ NTSTATUS cli_notify_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint32_t *pnum_changes, struct notify_change **pchanges); +struct tevent_req *cli_nttrans_create_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uint32_t CreatFlags, + uint32_t DesiredAccess, + uint32_t FileAttributes, + uint32_t ShareAccess, + uint32_t CreateDisposition, + uint32_t CreateOptions, + uint8_t SecurityFlags, + struct security_descriptor *secdesc, + struct ea_struct *eas, + int num_eas); +NTSTATUS cli_nttrans_create_recv(struct tevent_req *req, uint16_t *fnum); +NTSTATUS cli_nttrans_create(struct cli_state *cli, + const char *fname, + uint32_t CreatFlags, + uint32_t DesiredAccess, + uint32_t FileAttributes, + uint32_t ShareAccess, + uint32_t CreateDisposition, + uint32_t CreateOptions, + uint8_t SecurityFlags, + struct security_descriptor *secdesc, + struct ea_struct *eas, + int num_eas, + uint16_t *pfid); + /* The following definitions come from libsmb/clifsinfo.c */ struct tevent_req *cli_unix_extensions_version_send(TALLOC_CTX *mem_ctx, |