#include "libsmb/clirap.h"
#include "trans2.h"
#include "../libcli/smb/smbXcli_base.h"
+#include "cli_smb2_fnum.h"
#define PIPE_LANMAN "\\PIPE\\LANMAN"
* talloc
*/
- *rparam = (char *)memdup(my_rparam, num_my_rparam);
+ *rparam = (char *)smb_memdup(my_rparam, num_my_rparam);
if (*rparam == NULL) {
goto fail;
}
*rprcnt = num_my_rparam;
TALLOC_FREE(my_rparam);
- *rdata = (char *)memdup(my_rdata, num_my_rdata);
+ *rdata = (char *)smb_memdup(my_rdata, num_my_rdata);
if (*rdata == NULL) {
goto fail;
}
SSVAL(p,0,1);
p += 2;
strlcpy(p,user,sizeof(param)-PTR_DIFF(p,param));
- strupper_m(p);
+ if (!strupper_m(p)) {
+ return false;
+ }
p += 21;
p++;
p += 15;
p++;
strlcpy(p, workstation,sizeof(param)-PTR_DIFF(p,param));
- strupper_m(p);
+ if (!strupper_m(p)) {
+ return false;
+ }
p += 16;
SSVAL(p, 0, CLI_BUFFER_SIZE);
p += 2;
Call a NetShareEnum - try and browse available connections on a host.
****************************************************************************/
-int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state)
+int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32_t, const char *, void *), void *state)
{
char *rparam = NULL;
char *rdata = NULL;
the comment and a state pointer.
****************************************************************************/
-bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
- void (*fn)(const char *, uint32, const char *, void *),
+bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32_t stype,
+ void (*fn)(const char *, uint32_t, const char *, void *),
void *state)
{
char *rparam = NULL;
char param[1024];
int uLevel = 1;
size_t len;
- uint32 func = RAP_NetServerEnum2;
+ uint32_t func = RAP_NetServerEnum2;
char *last_entry = NULL;
int total_cnt = 0;
int return_cnt = 0;
sizeof(param) - PTR_DIFF(p,param) - 1,
STR_TERMINATE|STR_UPPER);
- if (len == (size_t)-1) {
+ if (len == 0) {
SAFE_FREE(last_entry);
return false;
}
sizeof(param) - PTR_DIFF(p,param) - 1,
STR_TERMINATE);
- if (len == (size_t)-1) {
+ if (len == 0) {
SAFE_FREE(last_entry);
return false;
}
static void cli_qpathinfo1_done(struct tevent_req *subreq);
struct tevent_req *cli_qpathinfo1_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
+ struct tevent_context *ev,
struct cli_state *cli,
const char *fname)
{
time_t *access_time,
time_t *write_time,
off_t *size,
- uint16 *mode)
+ uint16_t *mode)
{
struct cli_qpathinfo1_state *state = tevent_req_data(
req, struct cli_qpathinfo1_state);
time_t *access_time,
time_t *write_time,
off_t *size,
- uint16 *mode)
+ uint16_t *mode)
{
TALLOC_CTX *frame = talloc_stackframe();
- struct event_context *ev;
+ struct tevent_context *ev;
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
status = NT_STATUS_INVALID_PARAMETER;
goto fail;
}
- ev = event_context_init(frame);
+ ev = samba_tevent_context_init(frame);
if (ev == NULL) {
goto fail;
}
time_t access_time,
time_t write_time,
time_t change_time,
- uint16 mode)
+ uint16_t mode)
{
unsigned int data_len = 0;
char data[40];
put_long_date(p, change_time);
p += 8;
- /* Add attributes */
- SIVAL(p, 0, mode);
+ if (mode == (uint16_t)-1 || mode == FILE_ATTRIBUTE_NORMAL) {
+ /* No change. */
+ mode = 0;
+ } else if (mode == 0) {
+ /* Clear all existing attributes. */
+ mode = FILE_ATTRIBUTE_NORMAL;
+ }
+
+ /* Add attributes */
+ SIVAL(p, 0, mode);
+
p += 4;
/* Add padding */
data_len = PTR_DIFF(p, data);
+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+ DATA_BLOB in_data = data_blob_const(data, data_len);
+ /*
+ * Split out SMB2 here as we need to select
+ * the correct info type and level.
+ */
+ return cli_smb2_setpathinfo(cli,
+ fname,
+ 1, /* SMB2_SETINFO_FILE */
+ SMB_FILE_BASIC_INFORMATION - 1000,
+ &in_data);
+ }
+
return cli_setpathinfo(cli, SMB_FILE_BASIC_INFORMATION, fname,
(uint8_t *)data, data_len);
}
static void cli_qpathinfo2_done(struct tevent_req *subreq);
struct tevent_req *cli_qpathinfo2_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
+ struct tevent_context *ev,
struct cli_state *cli,
const char *fname)
{
struct timespec *access_time,
struct timespec *write_time,
struct timespec *change_time,
- off_t *size, uint16 *mode,
+ off_t *size, uint16_t *mode,
SMB_INO_T *ino)
{
struct cli_qpathinfo2_state *state = tevent_req_data(
struct timespec *access_time,
struct timespec *write_time,
struct timespec *change_time,
- off_t *size, uint16 *mode,
+ off_t *size, uint16_t *mode,
SMB_INO_T *ino)
{
- TALLOC_CTX *frame = talloc_stackframe();
- struct event_context *ev;
+ TALLOC_CTX *frame = NULL;
+ struct tevent_context *ev;
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+ return cli_smb2_qpathinfo2(cli,
+ fname,
+ create_time,
+ access_time,
+ write_time,
+ change_time,
+ size,
+ mode,
+ ino);
+ }
+
+ frame = talloc_stackframe();
+
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 = event_context_init(frame);
+ ev = samba_tevent_context_init(frame);
if (ev == NULL) {
goto fail;
}
Get the stream info
****************************************************************************/
-static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *data,
- size_t data_len,
- unsigned int *pnum_streams,
- struct stream_struct **pstreams);
-
struct cli_qpathinfo_streams_state {
uint32_t num_data;
uint8_t *data;
unsigned int *pnum_streams,
struct stream_struct **pstreams)
{
- TALLOC_CTX *frame = talloc_stackframe();
- struct event_context *ev;
+ TALLOC_CTX *frame = NULL;
+ struct tevent_context *ev;
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+ return cli_smb2_qpathinfo_streams(cli,
+ fname,
+ mem_ctx,
+ pnum_streams,
+ pstreams);
+ }
+
+ frame = talloc_stackframe();
+
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 = event_context_init(frame);
+ ev = samba_tevent_context_init(frame);
if (ev == NULL) {
goto fail;
}
return status;
}
-static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *rdata,
+bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *rdata,
size_t data_len,
unsigned int *pnum_streams,
struct stream_struct **pstreams)
****************************************************************************/
NTSTATUS cli_qfileinfo_basic(struct cli_state *cli, uint16_t fnum,
- uint16 *mode, off_t *size,
+ uint16_t *mode, off_t *size,
struct timespec *create_time,
struct timespec *access_time,
struct timespec *write_time,
uint32_t num_rdata;
NTSTATUS status;
+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+ return cli_smb2_qfileinfo_basic(cli,
+ fnum,
+ mode,
+ size,
+ create_time,
+ access_time,
+ write_time,
+ change_time,
+ ino);
+ }
+
/* if its a win95 server then fail this - win95 totally screws it
up */
if (cli->win95) {
static void cli_qpathinfo_basic_done(struct tevent_req *subreq);
struct tevent_req *cli_qpathinfo_basic_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
+ struct tevent_context *ev,
struct cli_state *cli,
const char *fname)
{
}
NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req,
- SMB_STRUCT_STAT *sbuf, uint32 *attributes)
+ SMB_STRUCT_STAT *sbuf, uint32_t *attributes)
{
struct cli_qpathinfo_basic_state *state = tevent_req_data(
req, struct cli_qpathinfo_basic_state);
return status;
}
+ sbuf->st_ex_btime = interpret_long_date((char *)state->data);
sbuf->st_ex_atime = interpret_long_date((char *)state->data+8);
sbuf->st_ex_mtime = interpret_long_date((char *)state->data+16);
sbuf->st_ex_ctime = interpret_long_date((char *)state->data+24);
}
NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name,
- SMB_STRUCT_STAT *sbuf, uint32 *attributes)
+ SMB_STRUCT_STAT *sbuf, uint32_t *attributes)
{
- TALLOC_CTX *frame = talloc_stackframe();
- struct event_context *ev;
+ TALLOC_CTX *frame = NULL;
+ struct tevent_context *ev;
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+ return cli_smb2_qpathinfo_basic(cli,
+ name,
+ sbuf,
+ attributes);
+ }
+
+ frame = talloc_stackframe();
+
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 = event_context_init(frame);
+ ev = samba_tevent_context_init(frame);
if (ev == NULL) {
goto fail;
}
size_t converted_size = 0;
NTSTATUS status;
+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+ return cli_smb2_qpathinfo_alt_name(cli,
+ fname,
+ alt_name);
+ }
+
status = cli_qpathinfo(talloc_tos(), cli, fname,
SMB_QUERY_FILE_ALT_NAME_INFO,
4, CLI_BUFFER_SIZE, &rdata, &num_rdata);
return NT_STATUS_OK;
}
+
+/****************************************************************************
+ Send a qpathinfo SMB_QUERY_FILE_STADNDARD_INFO call.
+****************************************************************************/
+
+NTSTATUS cli_qpathinfo_standard(struct cli_state *cli, const char *fname,
+ uint64_t *allocated, uint64_t *size,
+ uint32_t *nlinks,
+ bool *is_del_pending, bool *is_dir)
+{
+ uint8_t *rdata;
+ uint32_t num_rdata;
+ NTSTATUS status;
+
+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+
+ status = cli_qpathinfo(talloc_tos(), cli, fname,
+ SMB_QUERY_FILE_STANDARD_INFO,
+ 24, CLI_BUFFER_SIZE, &rdata, &num_rdata);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (allocated) {
+ *allocated = BVAL(rdata, 0);
+ }
+
+ if (size) {
+ *size = BVAL(rdata, 8);
+ }
+
+ if (nlinks) {
+ *nlinks = IVAL(rdata, 16);
+ }
+
+ if (is_del_pending) {
+ *is_del_pending = CVAL(rdata, 20);
+ }
+
+ if (is_dir) {
+ *is_dir = CVAL(rdata, 20);
+ }
+
+ TALLOC_FREE(rdata);
+
+ return NT_STATUS_OK;
+}
+
+
+/* like cli_qpathinfo2 but do not use SMB_QUERY_FILE_ALL_INFO with smb1 */
+NTSTATUS cli_qpathinfo3(struct cli_state *cli, const char *fname,
+ struct timespec *create_time,
+ struct timespec *access_time,
+ struct timespec *write_time,
+ struct timespec *change_time,
+ off_t *size, uint16_t *mode,
+ SMB_INO_T *ino)
+{
+ NTSTATUS status = NT_STATUS_OK;
+ SMB_STRUCT_STAT st = { 0 };
+ uint32_t attr;
+ uint64_t pos;
+
+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+ return cli_qpathinfo2(cli, fname,
+ create_time, access_time, write_time, change_time,
+ size, mode, ino);
+ }
+
+ if (create_time || access_time || write_time || change_time || mode) {
+ status = cli_qpathinfo_basic(cli, fname, &st, &attr);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
+ if (size) {
+ status = cli_qpathinfo_standard(cli, fname,
+ NULL, &pos, NULL, NULL, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ *size = pos;
+ }
+
+ if (create_time) {
+ *create_time = st.st_ex_btime;
+ }
+ if (access_time) {
+ *access_time = st.st_ex_atime;
+ }
+ if (write_time) {
+ *write_time = st.st_ex_mtime;
+ }
+ if (change_time) {
+ *change_time = st.st_ex_ctime;
+ }
+ if (mode) {
+ *mode = attr;
+ }
+ if (ino) {
+ *ino = 0;
+ }
+
+ return NT_STATUS_OK;
+}