diff options
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/cli_np_tstream.c | 2 | ||||
-rw-r--r-- | source3/libsmb/cli_smb2_fnum.c | 4 | ||||
-rw-r--r-- | source3/libsmb/cli_smb2_fnum.h | 2 | ||||
-rw-r--r-- | source3/libsmb/clifile.c | 73 | ||||
-rw-r--r-- | source3/libsmb/cliquota.c | 2 | ||||
-rw-r--r-- | source3/libsmb/clisymlink.c | 4 | ||||
-rw-r--r-- | source3/libsmb/libsmb_context.c | 17 | ||||
-rw-r--r-- | source3/libsmb/libsmb_setget.c | 17 | ||||
-rw-r--r-- | source3/libsmb/libsmb_xattr.c | 6 | ||||
-rw-r--r-- | source3/libsmb/proto.h | 14 | ||||
-rw-r--r-- | source3/libsmb/pylibsmb.c | 2 |
11 files changed, 117 insertions, 26 deletions
diff --git a/source3/libsmb/cli_np_tstream.c b/source3/libsmb/cli_np_tstream.c index f3a9962f823..bf9a0c370a8 100644 --- a/source3/libsmb/cli_np_tstream.c +++ b/source3/libsmb/cli_np_tstream.c @@ -204,7 +204,7 @@ static void tstream_cli_np_open_done(struct tevent_req *subreq) NTSTATUS status; if (state->is_smb1) { - status = cli_ntcreate_recv(subreq, &state->fnum); + status = cli_ntcreate_recv(subreq, &state->fnum, NULL); } else { status = smb2cli_create_recv(subreq, &state->fid_persistent, diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index 1e2047ef676..8eb776a1324 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -163,7 +163,7 @@ NTSTATUS cli_smb2_create_fnum(struct cli_state *cli, uint32_t create_disposition, uint32_t create_options, uint16_t *pfid, - struct smb2_create_returns *cr) + struct smb_create_returns *cr) { NTSTATUS status; struct smb2_hnd h; @@ -660,7 +660,7 @@ NTSTATUS cli_smb2_qpathinfo_basic(struct cli_state *cli, uint32_t *attributes) { NTSTATUS status; - struct smb2_create_returns cr; + struct smb_create_returns cr; uint16_t fnum = 0xffff; size_t namelen = strlen(name); diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h index a5cae25a2ba..61a0f6851ee 100644 --- a/source3/libsmb/cli_smb2_fnum.h +++ b/source3/libsmb/cli_smb2_fnum.h @@ -34,7 +34,7 @@ NTSTATUS cli_smb2_create_fnum(struct cli_state *cli, uint32_t create_disposition, uint32_t create_options, uint16_t *pfid, - struct smb2_create_returns *cr); + struct smb_create_returns *cr); NTSTATUS cli_smb2_close_fnum(struct cli_state *cli, uint16_t fnum); NTSTATUS cli_smb2_mkdir(struct cli_state *cli, const char *dirname); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 424354b9638..70b769d1bd8 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1795,6 +1795,7 @@ NTSTATUS cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag) struct cli_ntcreate_state { uint16_t vwv[24]; uint16_t fnum; + struct smb_create_returns cr; }; static void cli_ntcreate_done(struct tevent_req *subreq); @@ -1880,17 +1881,29 @@ static void cli_ntcreate_done(struct tevent_req *subreq) uint8_t *bytes; NTSTATUS status; - status = cli_smb_recv(subreq, state, NULL, 3, &wct, &vwv, + status = cli_smb_recv(subreq, state, NULL, 34, &wct, &vwv, &num_bytes, &bytes); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; } + state->cr.oplock_level = CVAL(vwv+2, 0); state->fnum = SVAL(vwv+2, 1); + state->cr.create_action = IVAL(vwv+3, 1); + state->cr.creation_time = BVAL(vwv+5, 1); + state->cr.last_access_time = BVAL(vwv+9, 1); + state->cr.last_write_time = BVAL(vwv+13, 1); + state->cr.change_time = BVAL(vwv+17, 1); + state->cr.file_attributes = IVAL(vwv+21, 1); + state->cr.allocation_size = BVAL(vwv+23, 1); + state->cr.end_of_file = BVAL(vwv+27, 1); + tevent_req_done(req); } -NTSTATUS cli_ntcreate_recv(struct tevent_req *req, uint16_t *pfnum) +NTSTATUS cli_ntcreate_recv(struct tevent_req *req, + uint16_t *pfnum, + struct smb_create_returns *cr) { struct cli_ntcreate_state *state = tevent_req_data( req, struct cli_ntcreate_state); @@ -1900,6 +1913,9 @@ NTSTATUS cli_ntcreate_recv(struct tevent_req *req, uint16_t *pfnum) return status; } *pfnum = state->fnum; + if (cr != NULL) { + *cr = state->cr; + } return NT_STATUS_OK; } @@ -1912,7 +1928,8 @@ NTSTATUS cli_ntcreate(struct cli_state *cli, uint32_t CreateDisposition, uint32_t CreateOptions, uint8_t SecurityFlags, - uint16_t *pfid) + uint16_t *pfid, + struct smb_create_returns *cr) { TALLOC_CTX *frame = NULL; struct tevent_context *ev; @@ -1929,7 +1946,7 @@ NTSTATUS cli_ntcreate(struct cli_state *cli, CreateDisposition, CreateOptions, pfid, - NULL); + cr); } frame = talloc_stackframe(); @@ -1962,7 +1979,7 @@ NTSTATUS cli_ntcreate(struct cli_state *cli, goto fail; } - status = cli_ntcreate_recv(req, pfid); + status = cli_ntcreate_recv(req, pfid, cr); fail: TALLOC_FREE(frame); return status; @@ -1970,6 +1987,7 @@ NTSTATUS cli_ntcreate(struct cli_state *cli, struct cli_nttrans_create_state { uint16_t fnum; + struct smb_create_returns cr; }; static void cli_nttrans_create_done(struct tevent_req *subreq); @@ -2082,12 +2100,24 @@ static void cli_nttrans_create_done(struct tevent_req *subreq) if (tevent_req_nterror(req, status)) { return; } + state->cr.oplock_level = CVAL(param, 0); state->fnum = SVAL(param, 2); + state->cr.create_action = IVAL(param, 4); + state->cr.creation_time = BVAL(param, 12); + state->cr.last_access_time = BVAL(param, 20); + state->cr.last_write_time = BVAL(param, 28); + state->cr.change_time = BVAL(param, 36); + state->cr.file_attributes = IVAL(param, 44); + state->cr.allocation_size = BVAL(param, 48); + state->cr.end_of_file = BVAL(param, 56); + TALLOC_FREE(param); tevent_req_done(req); } -NTSTATUS cli_nttrans_create_recv(struct tevent_req *req, uint16_t *fnum) +NTSTATUS cli_nttrans_create_recv(struct tevent_req *req, + uint16_t *fnum, + struct smb_create_returns *cr) { struct cli_nttrans_create_state *state = tevent_req_data( req, struct cli_nttrans_create_state); @@ -2097,6 +2127,9 @@ NTSTATUS cli_nttrans_create_recv(struct tevent_req *req, uint16_t *fnum) return status; } *fnum = state->fnum; + if (cr != NULL) { + *cr = state->cr; + } return NT_STATUS_OK; } @@ -2112,7 +2145,8 @@ NTSTATUS cli_nttrans_create(struct cli_state *cli, struct security_descriptor *secdesc, struct ea_struct *eas, int num_eas, - uint16_t *pfid) + uint16_t *pfid, + struct smb_create_returns *cr) { TALLOC_CTX *frame = talloc_stackframe(); struct tevent_context *ev; @@ -2141,7 +2175,7 @@ NTSTATUS cli_nttrans_create(struct cli_state *cli, if (!tevent_req_poll_ntstatus(req, ev, &status)) { goto fail; } - status = cli_nttrans_create_recv(req, pfid); + status = cli_nttrans_create_recv(req, pfid, cr); fail: TALLOC_FREE(frame); return status; @@ -2353,6 +2387,7 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags, unsigned int openfn = 0; unsigned int dos_deny = 0; uint32_t access_mask, share_mode, create_disposition, create_options; + struct smb_create_returns cr; /* Do the initial mapping into OpenX parameters. */ if (flags & O_CREAT) { @@ -2433,7 +2468,8 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags, create_disposition, create_options, 0, - pfnum); + pfnum, + &cr); /* Try and cope will all varients of "we don't do this call" and fall back to openX. */ @@ -2450,6 +2486,25 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags, goto try_openx; } + if (NT_STATUS_IS_OK(status) && + (create_options & FILE_NON_DIRECTORY_FILE) && + (cr.file_attributes & FILE_ATTRIBUTE_DIRECTORY)) + { + /* + * Some (broken) servers return a valid handle + * for directories even if FILE_NON_DIRECTORY_FILE + * is set. Just close the handle and set the + * error explicitly to NT_STATUS_FILE_IS_A_DIRECTORY. + */ + status = cli_close(cli, *pfnum); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = NT_STATUS_FILE_IS_A_DIRECTORY; + /* Set this so libsmbclient can retrieve it. */ + cli->raw_status = status; + } + return status; try_openx: diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 9136506e48c..21dc72e35c9 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -29,7 +29,7 @@ NTSTATUS cli_get_quota_handle(struct cli_state *cli, uint16_t *quota_fnum) return cli_ntcreate(cli, FAKE_FILE_NAME_QUOTA_WIN32, 0x00000016, DESIRED_ACCESS_PIPE, 0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_OPEN, 0x00000000, 0x03, quota_fnum); + FILE_OPEN, 0x00000000, 0x03, quota_fnum, NULL); } void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list) diff --git a/source3/libsmb/clisymlink.c b/source3/libsmb/clisymlink.c index 338f932c4e7..eacae85d01d 100644 --- a/source3/libsmb/clisymlink.c +++ b/source3/libsmb/clisymlink.c @@ -90,7 +90,7 @@ static void cli_symlink_create_done(struct tevent_req *subreq) size_t data_len; NTSTATUS status; - status = cli_ntcreate_recv(subreq, &state->fnum); + status = cli_ntcreate_recv(subreq, &state->fnum, NULL); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; @@ -275,7 +275,7 @@ static void cli_readlink_opened(struct tevent_req *subreq) req, struct cli_readlink_state); NTSTATUS status; - status = cli_ntcreate_recv(subreq, &state->fnum); + status = cli_ntcreate_recv(subreq, &state->fnum, NULL); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index c2b88f56927..ffa4d2de921 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -560,6 +560,7 @@ SMBCCTX * smbc_init_context(SMBCCTX *context) { int pid; + TALLOC_CTX *frame; if (!context) { errno = EBADF; @@ -571,11 +572,14 @@ smbc_init_context(SMBCCTX *context) return NULL; } + frame = talloc_stackframe(); + if ((!smbc_getFunctionAuthData(context) && !smbc_getFunctionAuthDataWithContext(context)) || smbc_getDebug(context) < 0 || smbc_getDebug(context) > 100) { + TALLOC_FREE(frame); errno = EINVAL; return NULL; @@ -594,6 +598,7 @@ smbc_init_context(SMBCCTX *context) } if (!user) { + TALLOC_FREE(frame); errno = ENOMEM; return NULL; } @@ -602,6 +607,7 @@ smbc_init_context(SMBCCTX *context) SAFE_FREE(user); if (!smbc_getUser(context)) { + TALLOC_FREE(frame); errno = ENOMEM; return NULL; } @@ -624,6 +630,7 @@ smbc_init_context(SMBCCTX *context) pid = getpid(); netbios_name = (char *)SMB_MALLOC(17); if (!netbios_name) { + TALLOC_FREE(frame); errno = ENOMEM; return NULL; } @@ -632,6 +639,7 @@ smbc_init_context(SMBCCTX *context) } if (!netbios_name) { + TALLOC_FREE(frame); errno = ENOMEM; return NULL; } @@ -640,6 +648,7 @@ smbc_init_context(SMBCCTX *context) SAFE_FREE(netbios_name); if (!smbc_getNetbiosName(context)) { + TALLOC_FREE(frame); errno = ENOMEM; return NULL; } @@ -659,6 +668,7 @@ smbc_init_context(SMBCCTX *context) } if (!workgroup) { + TALLOC_FREE(frame); errno = ENOMEM; return NULL; } @@ -667,6 +677,7 @@ smbc_init_context(SMBCCTX *context) SAFE_FREE(workgroup); if (!smbc_getWorkgroup(context)) { + TALLOC_FREE(frame); errno = ENOMEM; return NULL; } @@ -692,6 +703,7 @@ smbc_init_context(SMBCCTX *context) smb_panic("error unlocking 'initialized_ctx_count'"); } + TALLOC_FREE(frame); return context; } @@ -727,12 +739,15 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, smbc_bool use_kerberos = false; const char *signing_state = "off"; struct user_auth_info *auth_info = NULL; + TALLOC_CTX *frame; if (! context) { return; } + frame = talloc_stackframe(); + if (! workgroup || ! *workgroup) { workgroup = smbc_getWorkgroup(context); } @@ -749,6 +764,7 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, if (! auth_info) { DEBUG(0, ("smbc_set_credentials_with_fallback: allocation fail\n")); + TALLOC_FREE(frame); return; } @@ -777,4 +793,5 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, TALLOC_FREE(context->internal->auth_info); context->internal->auth_info = auth_info; + TALLOC_FREE(frame); } diff --git a/source3/libsmb/libsmb_setget.c b/source3/libsmb/libsmb_setget.c index b8adcca18b9..3255b522bb0 100644 --- a/source3/libsmb/libsmb_setget.c +++ b/source3/libsmb/libsmb_setget.c @@ -91,9 +91,11 @@ void smbc_setDebug(SMBCCTX *c, int debug) { char buf[32]; + TALLOC_CTX *frame = talloc_stackframe(); snprintf(buf, sizeof(buf), "%d", debug); c->debug = debug; lp_set_cmdline("log level", buf); + TALLOC_FREE(frame); } /** @@ -139,10 +141,15 @@ smbc_setPort(SMBCCTX *c, uint16_t port) smbc_bool smbc_getOptionDebugToStderr(SMBCCTX *c) { + smbc_bool ret; + TALLOC_CTX *frame = talloc_stackframe(); + /* Because this is a global concept, it is better to check * what is really set, rather than what we wanted set * (particularly as you cannot go back to stdout). */ - return debug_get_output_is_stderr(); + ret = debug_get_output_is_stderr(); + TALLOC_FREE(frame); + return ret; } /** Set whether to log to standard error instead of standard output. @@ -154,6 +161,7 @@ smbc_getOptionDebugToStderr(SMBCCTX *c) void smbc_setOptionDebugToStderr(SMBCCTX *c, smbc_bool b) { + TALLOC_CTX *frame = talloc_stackframe(); if (b) { /* * We do not have a unique per-thread debug state? For @@ -164,6 +172,7 @@ smbc_setOptionDebugToStderr(SMBCCTX *c, smbc_bool b) */ setup_logging("libsmbclient", DEBUG_STDERR); } + TALLOC_FREE(frame); } /** @@ -498,7 +507,11 @@ smbc_setOptionUseNTHash(SMBCCTX *c, smbc_bool b) smbc_get_auth_data_fn smbc_getFunctionAuthData(SMBCCTX *c) { - return c->callbacks.auth_fn; + smbc_get_auth_data_fn ret; + TALLOC_CTX *frame = talloc_stackframe(); + ret = c->callbacks.auth_fn; + TALLOC_FREE(frame); + return ret; } /** Set the function for obtaining authentication data */ diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index 7d34290b65d..8e6590a5367 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -904,7 +904,7 @@ cacl_get(SMBCCTX *context, status = cli_ntcreate(targetcli, targetpath, 0, CREATE_ACCESS_READ, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_OPEN, 0x0, 0x0, &fnum); + FILE_OPEN, 0x0, 0x0, &fnum, NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("cacl_get failed to open %s: %s\n", targetpath, nt_errstr(status))); @@ -1563,7 +1563,7 @@ cacl_set(SMBCCTX *context, status = cli_ntcreate(targetcli, targetpath, 0, CREATE_ACCESS_READ, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, - 0x0, 0x0, &fnum); + 0x0, 0x0, &fnum, NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("cacl_set failed to open %s: %s\n", targetpath, nt_errstr(status))); @@ -1671,7 +1671,7 @@ cacl_set(SMBCCTX *context, status = cli_ntcreate(targetcli, targetpath, 0, WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, - 0x0, 0x0, &fnum); + 0x0, 0x0, &fnum, NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("cacl_set failed to open %s: %s\n", targetpath, nt_errstr(status))); diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index a1389ff4655..525625cd300 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -356,7 +356,9 @@ struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx, uint32_t CreateDisposition, uint32_t CreateOptions, uint8_t SecurityFlags); -NTSTATUS cli_ntcreate_recv(struct tevent_req *req, uint16_t *pfnum); +NTSTATUS cli_ntcreate_recv(struct tevent_req *req, + uint16_t *pfnum, + struct smb_create_returns *cr); NTSTATUS cli_ntcreate(struct cli_state *cli, const char *fname, uint32_t CreatFlags, @@ -366,7 +368,8 @@ NTSTATUS cli_ntcreate(struct cli_state *cli, uint32_t CreateDisposition, uint32_t CreateOptions, uint8_t SecurityFlags, - uint16_t *pfid); + uint16_t *pfid, + struct smb_create_returns *cr); uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str, size_t str_len, size_t *pconverted_size); uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix, @@ -600,7 +603,9 @@ struct tevent_req *cli_nttrans_create_send(TALLOC_CTX *mem_ctx, 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_recv(struct tevent_req *req, + uint16_t *fnum, + struct smb_create_returns *cr); NTSTATUS cli_nttrans_create(struct cli_state *cli, const char *fname, uint32_t CreatFlags, @@ -613,7 +618,8 @@ NTSTATUS cli_nttrans_create(struct cli_state *cli, struct security_descriptor *secdesc, struct ea_struct *eas, int num_eas, - uint16_t *pfid); + uint16_t *pfid, + struct smb_create_returns *cr); /* The following definitions come from libsmb/clifsinfo.c */ diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c index ae0d6943d0f..e3a5ac7d18a 100644 --- a/source3/libsmb/pylibsmb.c +++ b/source3/libsmb/pylibsmb.c @@ -609,7 +609,7 @@ static PyObject *py_cli_create(struct py_cli_state *self, PyObject *args, if (!py_tevent_req_wait_exc(self->ev, req)) { return NULL; } - status = cli_ntcreate_recv(req, &fnum); + status = cli_ntcreate_recv(req, &fnum, NULL); TALLOC_FREE(req); if (!NT_STATUS_IS_OK(status)) { |