#include "trans2.h"
#include "ntioctl.h"
#include "libcli/security/secdesc.h"
+#include "../libcli/smb/smbXcli_base.h"
/***********************************************************
Common function for pushing stings, used by smb_bytes_push_str()
SSVAL(state->param, 0, level);
state->param = trans2_bytes_push_str(
- state->param, cli_ucs2(cli), path, strlen(path)+1, NULL);
+ state->param, smbXcli_conn_use_unicode(cli->conn), path, strlen(path)+1, NULL);
if (tevent_req_nomem(state->param, req)) {
return tevent_req_post(req, ev);
}
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
return tevent_req_post(req, ev);
}
state->data = trans2_bytes_push_str(
- state->data, cli_ucs2(cli), oldname, strlen(oldname)+1, NULL);
+ state->data, smbXcli_conn_use_unicode(cli->conn), oldname, strlen(oldname)+1, NULL);
subreq = cli_setpathinfo_send(
state, ev, cli, level, newname,
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
{
struct tevent_req *req = NULL, *subreq = NULL;
struct readlink_state *state = NULL;
- uint32_t maxbytelen = (uint32_t)(cli_ucs2(cli) ? len*3 : len);
+ uint32_t maxbytelen = (uint32_t)(smbXcli_conn_use_unicode(cli->conn) ? len*3 : len);
req = tevent_req_create(mem_ctx, &state, struct readlink_state);
if (req == NULL) {
}
/* The returned data is a pushed string, not raw data. */
if (!convert_string_talloc(state,
- cli_ucs2(cli) ? CH_UTF16LE : CH_DOS,
+ smbXcli_conn_use_unicode(cli->conn) ? CH_UTF16LE : CH_DOS,
CH_UNIX,
state->data,
state->num_data,
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
return tevent_req_post(req, ev);
}
bytes[0] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname_src,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), fname_src,
strlen(fname_src)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
return tevent_req_post(req, ev);
}
bytes[talloc_get_size(bytes)-1] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname_dst,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), fname_dst,
strlen(fname_dst)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
return tevent_req_post(req, ev);
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
return tevent_req_post(req, ev);
}
bytes[0] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname_src,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), fname_src,
strlen(fname_src)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
return tevent_req_post(req, ev);
}
bytes[talloc_get_size(bytes)-1] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname_dst,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), fname_dst,
strlen(fname_dst)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
return tevent_req_post(req, ev);
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
return tevent_req_post(req, ev);
}
bytes[0] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), fname,
strlen(fname)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
return tevent_req_post(req, ev);
}
bytes[0] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), dname,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), dname,
strlen(dname)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
return tevent_req_post(req, ev);
}
bytes[0] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), dname,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), dname,
strlen(dname)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
SIVAL(vwv+13, 1, FileAttributes);
SIVAL(vwv+15, 1, ShareAccess);
SIVAL(vwv+17, 1, CreateDisposition);
- SIVAL(vwv+19, 1, CreateOptions);
+ SIVAL(vwv+19, 1, CreateOptions |
+ (cli->backup_intent ? FILE_OPEN_FOR_BACKUP_INTENT : 0));
SIVAL(vwv+21, 1, 0x02); /* ImpersonationLevel */
SCVAL(vwv+23, 1, SecurityFlags);
bytes = talloc_array(state, uint8_t, 0);
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
fname, strlen(fname)+1,
&converted_len);
/* sigh. this copes with broken netapp filer behaviour */
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, NULL);
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, NULL);
if (tevent_req_nomem(bytes, req)) {
return tevent_req_post(req, ev);
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
return tevent_req_post(req, ev);
}
- param = trans2_bytes_push_str(param, cli_ucs2(cli),
+ param = trans2_bytes_push_str(param, smbXcli_conn_use_unicode(cli->conn),
fname, strlen(fname),
&converted_len);
if (tevent_req_nomem(param, req)) {
SIVAL(param, 20, FileAttributes);
SIVAL(param, 24, ShareAccess);
SIVAL(param, 28, CreateDisposition);
- SIVAL(param, 32, CreateOptions);
+ SIVAL(param, 32, CreateOptions |
+ (cli->backup_intent ? FILE_OPEN_FOR_BACKUP_INTENT : 0));
SIVAL(param, 36, secdesc_len);
SIVAL(param, 40, 0); /* EA length*/
SIVAL(param, 44, converted_len);
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
WARNING: if you open with O_WRONLY then getattrE won't work!
****************************************************************************/
-struct cli_open_state {
- struct tevent_context *ev;
- struct cli_state *cli;
+struct cli_openx_state {
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_open_done(struct tevent_req *subreq);
-static void cli_open_ntcreate_done(struct tevent_req *subreq);
+static void cli_openx_done(struct tevent_req *subreq);
-struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx,
+struct tevent_req *cli_openx_create(TALLOC_CTX *mem_ctx,
struct event_context *ev,
struct cli_state *cli, const char *fname,
int flags, int share_mode,
struct tevent_req **psmbreq)
{
struct tevent_req *req, *subreq;
- struct cli_open_state *state;
+ 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_open_state);
+ 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);
}
bytes = talloc_array(state, uint8_t, 0);
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), fname,
strlen(fname)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
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);
return NULL;
}
- tevent_req_set_callback(subreq, cli_open_done, req);
+ tevent_req_set_callback(subreq, cli_openx_done, req);
*psmbreq = subreq;
return req;
}
-struct tevent_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+struct tevent_req *cli_openx_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct cli_state *cli, const char *fname,
int flags, int share_mode)
{
struct tevent_req *req, *subreq;
NTSTATUS status;
- req = cli_open_create(mem_ctx, ev, cli, fname, flags, share_mode,
+ req = cli_openx_create(mem_ctx, ev, cli, fname, flags, share_mode,
&subreq);
if (req == NULL) {
return NULL;
return req;
}
-static void cli_open_done(struct tevent_req *subreq)
+static void cli_openx_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
- struct cli_open_state *state = tevent_req_data(
- req, struct cli_open_state);
+ struct cli_openx_state *state = tevent_req_data(
+ req, struct cli_openx_state);
uint8_t wct;
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_open_state *state = tevent_req_data(
- req, struct cli_open_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);
}
-NTSTATUS cli_open_recv(struct tevent_req *req, uint16_t *pfnum)
+NTSTATUS cli_openx_recv(struct tevent_req *req, uint16_t *pfnum)
{
- struct cli_open_state *state = tevent_req_data(
- req, struct cli_open_state);
+ struct cli_openx_state *state = tevent_req_data(
+ req, struct cli_openx_state);
NTSTATUS status;
if (tevent_req_is_nterror(req, &status)) {
return NT_STATUS_OK;
}
-NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags,
+NTSTATUS cli_openx(struct cli_state *cli, const char *fname, int flags,
int share_mode, uint16_t *pfnum)
{
TALLOC_CTX *frame = talloc_stackframe();
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
goto fail;
}
- req = cli_open_send(frame, ev, cli, fname, flags, share_mode);
+ req = cli_openx_send(frame, ev, cli, fname, flags, share_mode);
if (req == NULL) {
status = NT_STATUS_NO_MEMORY;
goto fail;
goto fail;
}
- status = cli_open_recv(req, pfnum);
+ status = cli_openx_recv(req, pfnum);
fail:
TALLOC_FREE(frame);
return status;
}
+/****************************************************************************
+ Synchronous wrapper function that does an NtCreateX open by preference
+ and falls back to openX if this fails.
+****************************************************************************/
+
+NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags,
+ int share_mode_in, uint16_t *pfnum)
+{
+ NTSTATUS status;
+ unsigned int openfn = 0;
+ unsigned int dos_deny = 0;
+ uint32_t access_mask, share_mode, create_disposition, create_options;
+
+ /* Do the initial mapping into OpenX parameters. */
+ if (flags & O_CREAT) {
+ openfn |= (1<<4);
+ }
+ if (!(flags & O_EXCL)) {
+ if (flags & O_TRUNC)
+ openfn |= (1<<1);
+ else
+ openfn |= (1<<0);
+ }
+
+ dos_deny = (share_mode_in<<4);
+
+ if ((flags & O_ACCMODE) == O_RDWR) {
+ dos_deny |= 2;
+ } else if ((flags & O_ACCMODE) == O_WRONLY) {
+ dos_deny |= 1;
+ }
+
+#if defined(O_SYNC)
+ if ((flags & O_SYNC) == O_SYNC) {
+ dos_deny |= (1<<14);
+ }
+#endif /* O_SYNC */
+
+ if (share_mode_in == DENY_FCB) {
+ dos_deny = 0xFF;
+ }
+
+#if 0
+ /* Hmmm. This is what I think the above code
+ should look like if it's using the constants
+ we #define. JRA. */
+
+ if (flags & O_CREAT) {
+ openfn |= OPENX_FILE_CREATE_IF_NOT_EXIST;
+ }
+ if (!(flags & O_EXCL)) {
+ if (flags & O_TRUNC)
+ openfn |= OPENX_FILE_EXISTS_TRUNCATE;
+ else
+ openfn |= OPENX_FILE_EXISTS_OPEN;
+ }
+
+ dos_deny = SET_DENY_MODE(share_mode_in);
+
+ if ((flags & O_ACCMODE) == O_RDWR) {
+ dos_deny |= DOS_OPEN_RDWR;
+ } else if ((flags & O_ACCMODE) == O_WRONLY) {
+ dos_deny |= DOS_OPEN_WRONLY;
+ }
+
+#if defined(O_SYNC)
+ if ((flags & O_SYNC) == O_SYNC) {
+ dos_deny |= FILE_SYNC_OPENMODE;
+ }
+#endif /* O_SYNC */
+
+ if (share_mode_in == DENY_FCB) {
+ dos_deny = 0xFF;
+ }
+#endif
+
+ if (!map_open_params_to_ntcreate(fname, dos_deny,
+ openfn, &access_mask,
+ &share_mode, &create_disposition,
+ &create_options, NULL)) {
+ goto try_openx;
+ }
+
+ status = cli_ntcreate(cli,
+ fname,
+ 0,
+ access_mask,
+ 0,
+ share_mode,
+ create_disposition,
+ create_options,
+ 0,
+ pfnum);
+
+ /* Try and cope will all varients of "we don't do this call"
+ and fall back to openX. */
+
+ if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_IMPLEMENTED) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_INVALID_INFO_CLASS) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_PROCEDURE_NOT_FOUND) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_INVALID_LEVEL) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_INVALID_PARAMETER) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_INVALID_DEVICE_REQUEST) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_INVALID_DEVICE_STATE) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_CTL_FILE_NOT_SUPPORTED) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_UNSUCCESSFUL)) {
+ goto try_openx;
+ }
+
+ return status;
+
+ try_openx:
+
+ return cli_openx(cli, fname, flags, share_mode_in, pfnum);
+}
/****************************************************************************
Close a file.
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
int ltype;
NTSTATUS status;
- if (! (cli_state_capabilities(cli) & CAP_LARGE_FILES)) {
+ if (! (smb1cli_conn_capabilities(cli->conn) & CAP_LARGE_FILES)) {
return cli_lock32(cli, fnum, offset, len, timeout, lock_type);
}
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (! (cli_state_capabilities(cli) & CAP_LARGE_FILES)) {
+ if (! (smb1cli_conn_capabilities(cli->conn) & CAP_LARGE_FILES)) {
return cli_unlock(cli, fnum, offset, len);
}
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
uint16_t vwv[1];
int zone_offset;
uint16_t attr;
- SMB_OFF_T size;
+ off_t size;
time_t change_time;
time_t access_time;
time_t write_time;
return NULL;
}
- state->zone_offset = cli->serverzone;
+ state->zone_offset = smb1cli_conn_server_time_zone(cli->conn);
SSVAL(state->vwv+0,0,fnum);
subreq = cli_smb_send(state, ev, cli, SMBgetattrE, additional_flags,
return;
}
- state->size = (SMB_OFF_T)IVAL(vwv+6,0);
+ state->size = (off_t)IVAL(vwv+6,0);
state->attr = SVAL(vwv+10,0);
state->change_time = make_unix_date2(vwv+0, state->zone_offset);
state->access_time = make_unix_date2(vwv+2, state->zone_offset);
NTSTATUS cli_getattrE_recv(struct tevent_req *req,
uint16_t *attr,
- SMB_OFF_T *size,
+ off_t *size,
time_t *change_time,
time_t *access_time,
time_t *write_time)
NTSTATUS cli_getattrE(struct cli_state *cli,
uint16_t fnum,
uint16_t *attr,
- SMB_OFF_T *size,
+ off_t *size,
time_t *change_time,
time_t *access_time,
time_t *write_time)
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct cli_getatr_state {
int zone_offset;
uint16_t attr;
- SMB_OFF_T size;
+ off_t size;
time_t write_time;
};
return NULL;
}
- state->zone_offset = cli->serverzone;
+ state->zone_offset = smb1cli_conn_server_time_zone(cli->conn);
bytes = talloc_array(state, uint8_t, 1);
if (tevent_req_nomem(bytes, req)) {
return tevent_req_post(req, ev);
}
bytes[0] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), fname,
strlen(fname)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
}
state->attr = SVAL(vwv+0,0);
- state->size = (SMB_OFF_T)IVAL(vwv+3,0);
+ state->size = (off_t)IVAL(vwv+3,0);
state->write_time = make_unix_date3(vwv+1, state->zone_offset);
tevent_req_done(req);
NTSTATUS cli_getatr_recv(struct tevent_req *req,
uint16_t *attr,
- SMB_OFF_T *size,
+ off_t *size,
time_t *write_time)
{
struct cli_getatr_state *state = tevent_req_data(
NTSTATUS cli_getatr(struct cli_state *cli,
const char *fname,
uint16_t *attr,
- SMB_OFF_T *size,
+ off_t *size,
time_t *write_time)
{
TALLOC_CTX *frame = talloc_stackframe();
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
SSVAL(state->vwv+0, 0, fnum);
push_dos_date2((uint8_t *)&state->vwv[1], 0, change_time,
- cli->serverzone);
+ smb1cli_conn_server_time_zone(cli->conn));
push_dos_date2((uint8_t *)&state->vwv[3], 0, access_time,
- cli->serverzone);
+ smb1cli_conn_server_time_zone(cli->conn));
push_dos_date2((uint8_t *)&state->vwv[5], 0, write_time,
- cli->serverzone);
+ smb1cli_conn_server_time_zone(cli->conn));
subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags,
7, state->vwv, 0, NULL);
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
}
SSVAL(state->vwv+0, 0, attr);
- push_dos_date3((uint8_t *)&state->vwv[1], 0, mtime, cli->serverzone);
+ push_dos_date3((uint8_t *)&state->vwv[1], 0, mtime, smb1cli_conn_server_time_zone(cli->conn));
bytes = talloc_array(state, uint8_t, 1);
if (tevent_req_nomem(bytes, req)) {
return tevent_req_post(req, ev);
}
bytes[0] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), fname,
strlen(fname)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
return tevent_req_post(req, ev);
}
bytes[talloc_get_size(bytes)-1] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "",
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "",
1, NULL);
if (tevent_req_nomem(bytes, req)) {
return tevent_req_post(req, ev);
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
return tevent_req_post(req, ev);
}
bytes[0] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), fname,
strlen(fname)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
char *path2 = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
return tevent_req_post(req, ev);
}
bytes[0] = 4;
- bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), path,
+ bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), path,
strlen(path)+1, NULL);
if (tevent_req_nomem(bytes, req)) {
return tevent_req_post(req, ev);
struct tevent_req *req;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
if (ea_namelen == 0 && ea_len == 0) {
data_len = 4;
- data = (uint8_t *)SMB_MALLOC(data_len);
+ data = talloc_array(talloc_tos(),
+ uint8_t,
+ data_len);
if (!data) {
return NT_STATUS_NO_MEMORY;
}
SIVAL(p,0,data_len);
} else {
data_len = 4 + 4 + ea_namelen + 1 + ea_len;
- data = (uint8_t *)SMB_MALLOC(data_len);
+ data = talloc_array(talloc_tos(),
+ uint8_t,
+ data_len);
if (!data) {
return NT_STATUS_NO_MEMORY;
}
NULL, 0, NULL, /* rsetup */
NULL, 0, NULL, /* rparam */
NULL, 0, NULL); /* rdata */
- SAFE_FREE(data);
+ talloc_free(data);
return status;
}
SSVAL(param,2,0);
SSVAL(param,4,0);
- param = trans2_bytes_push_str(param, cli_ucs2(cli),
+ param = trans2_bytes_push_str(param, smbXcli_conn_use_unicode(cli->conn),
path, strlen(path)+1,
NULL);
param_len = talloc_get_size(param);
status = cli_set_ea(cli, TRANSACT2_SETPATHINFO, param, param_len,
ea_name, ea_val, ea_len);
- SAFE_FREE(frame);
+ talloc_free(frame);
return status;
}
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_NO_MEMORY;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
memset(state->param, '\0', 6);
SSVAL(state->param, 0, SMB_POSIX_PATH_OPEN);
- state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
+ state->param = trans2_bytes_push_str(state->param, smbXcli_conn_use_unicode(cli->conn), fname,
strlen(fname)+1, NULL);
if (tevent_req_nomem(state->param, req)) {
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
{
struct tevent_req *req, *subreq;
struct cli_notify_state *state;
+ unsigned old_timeout;
req = tevent_req_create(mem_ctx, &state, struct cli_notify_state);
if (req == NULL) {
SSVAL(state->setup, 4, fnum);
SSVAL(state->setup, 6, recursive);
+ /*
+ * Notifies should not time out
+ */
+ old_timeout = cli_set_timeout(cli, 0);
+
subreq = cli_trans_send(
state, /* mem ctx. */
ev, /* event ctx. */
0, /* num data. */
0); /* max returned data. */
+ cli_set_timeout(cli, old_timeout);
+
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
ofs = 0;
while (num_params - ofs > 12) {
- uint32_t len = IVAL(params, ofs);
+ uint32_t next = IVAL(params, ofs);
state->num_changes += 1;
- if ((len == 0) || (ofs+len >= num_params)) {
+ if ((next == 0) || (ofs+next >= num_params)) {
break;
}
- ofs += len;
+ ofs += next;
}
state->changes = talloc_array(state, struct notify_change,
ssize_t ret;
char *name;
- if ((next != 0) && (len+12 != next)) {
+ if (trans_oob(num_params, ofs + 12, len)) {
TALLOC_FREE(params);
tevent_req_nterror(
req, NT_STATUS_INVALID_NETWORK_RESPONSE);
return NT_STATUS_OK;
}
+NTSTATUS cli_notify(struct cli_state *cli, uint16_t fnum, uint32_t buffer_size,
+ uint32_t completion_filter, bool recursive,
+ TALLOC_CTX *mem_ctx, uint32_t *pnum_changes,
+ struct notify_change **pchanges)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct tevent_context *ev;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+ ev = tevent_context_init(frame);
+ if (ev == NULL) {
+ goto fail;
+ }
+ req = cli_notify_send(ev, ev, cli, fnum, buffer_size,
+ completion_filter, recursive);
+ if (req == NULL) {
+ goto fail;
+ }
+ if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+ goto fail;
+ }
+ status = cli_notify_recv(req, mem_ctx, pnum_changes, pchanges);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
+}
+
struct cli_qpathinfo_state {
uint8_t *param;
uint8_t *data;
}
SSVAL(state->param, 0, level);
state->param = trans2_bytes_push_str(
- state->param, cli_ucs2(cli), fname, strlen(fname)+1, NULL);
+ state->param, smbXcli_conn_use_unicode(cli->conn), fname, strlen(fname)+1, NULL);
if (tevent_req_nomem(state->param, req)) {
return tevent_req_post(req, ev);
}
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
- if (cli_has_async_calls(cli)) {
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
* Can't use sync call while an async call is in flight
*/