*/
#include "includes.h"
-#include "lib/util/dlinklist.h"
#include "smb_server/smb_server.h"
-#include "librpc/gen_ndr/ndr_misc.h"
#include "ntvfs/ntvfs.h"
#include "libcli/raw/libcliraw.h"
#include "libcli/raw/raw_proto.h"
/* setup a trans2 reply, given the data and params sizes */
static NTSTATUS trans2_setup_reply(struct smb_trans2 *trans,
uint16_t param_size, uint16_t data_size,
- uint16_t setup_count)
+ uint8_t setup_count)
{
trans->out.setup_count = setup_count;
if (setup_count > 0) {
case RAW_SFILEINFO_UNIX_BASIC:
case RAW_SFILEINFO_UNIX_LINK:
case RAW_SFILEINFO_UNIX_HLINK:
- case RAW_SFILEINFO_1023:
+ case RAW_SFILEINFO_PIPE_INFORMATION:
+ case RAW_SFILEINFO_VALID_DATA_INFORMATION:
+ case RAW_SFILEINFO_SHORT_NAME_INFORMATION:
case RAW_SFILEINFO_1025:
+ case RAW_SFILEINFO_1027:
case RAW_SFILEINFO_1029:
+ case RAW_SFILEINFO_1030:
+ case RAW_SFILEINFO_1031:
case RAW_SFILEINFO_1032:
- case RAW_SFILEINFO_1039:
- case RAW_SFILEINFO_1040:
+ case RAW_SFILEINFO_1036:
+ case RAW_SFILEINFO_1041:
+ case RAW_SFILEINFO_1042:
+ case RAW_SFILEINFO_1043:
+ case RAW_SFILEINFO_1044:
return NT_STATUS_INVALID_LEVEL;
default:
struct smbsrv_request *req = state->op->req;
struct smb_trans2 *trans = state->op->trans;
uint8_t *data;
- uint_t ofs = trans->out.data.length;
+ unsigned int ofs = trans->out.data.length;
uint32_t ea_size;
switch (state->data_level) {
SMBSRV_REQ_DEFAULT_STR_FLAGS(req));
case RAW_SEARCH_DATA_UNIX_INFO:
+ case RAW_SEARCH_DATA_UNIX_INFO2:
return NT_STATUS_INVALID_LEVEL;
}
}
/* callback function for trans2 findfirst/findnext */
-static bool find_callback(void *private, const union smb_search_data *file)
+static bool find_callback(void *private_data, const union smb_search_data *file)
{
- struct find_state *state = talloc_get_type(private, struct find_state);
+ struct find_state *state = talloc_get_type(private_data, struct find_state);
struct smb_trans2 *trans = state->op->trans;
- uint_t old_length;
+ unsigned int old_length;
old_length = trans->out.data.length;
return NT_STATUS_FOOBAR;
}
+int smbsrv_trans_partial_destructor(struct smbsrv_trans_partial *tp)
+{
+ DLIST_REMOVE(tp->req->smb_conn->trans_partial, tp);
+ return 0;
+}
+
/*
send a continue request
static void reply_trans_continue(struct smbsrv_request *req, uint8_t command,
struct smb_trans2 *trans)
{
+ struct smbsrv_request *req2;
struct smbsrv_trans_partial *tp;
int count;
tp = talloc(req, struct smbsrv_trans_partial);
- tp->req = talloc_reference(tp, req);
- tp->trans = trans;
+ tp->req = req;
+ tp->u.trans = trans;
tp->command = command;
DLIST_ADD(req->smb_conn->trans_partial, tp);
+ talloc_set_destructor(tp, smbsrv_trans_partial_destructor);
+
+ req2 = smbsrv_setup_secondary_request(req);
/* send a 'please continue' reply */
- smbsrv_setup_reply(req, 0, 0);
- smbsrv_send_reply(req);
+ smbsrv_setup_reply(req2, 0, 0);
+ smbsrv_send_reply(req2);
}
the negotiated buffer size */
do {
uint16_t this_data, this_param, max_bytes;
- uint_t align1 = 1, align2 = (params_left ? 2 : 0);
+ unsigned int align1 = 1, align2 = (params_left ? 2 : 0);
struct smbsrv_request *this_req;
max_bytes = req_max_data(req) - (align1 + align2);
PTR_DIFF(this_req->out.data + this_param, this_req->out.hdr));
SSVAL(this_req->out.vwv, VWV(8), PTR_DIFF(data, trans->out.data.data));
- SSVAL(this_req->out.vwv, VWV(9), trans->out.setup_count);
+ SCVAL(this_req->out.vwv, VWV(9), trans->out.setup_count);
+ SCVAL(this_req->out.vwv, VWV(9)+1, 0); /* reserved */
for (i=0;i<trans->out.setup_count;i++) {
SSVAL(this_req->out.vwv, VWV(10+i), trans->out.setup[i]);
}
uint16_t param_disp, data_disp;
uint16_t param_total, data_total;
DATA_BLOB params, data;
+ uint8_t wct;
+
+ if (command == SMBtrans2) {
+ wct = 9;
+ } else {
+ wct = 8;
+ }
/* parse request */
- if (req->in.wct < 8) {
+ if (req->in.wct != wct) {
+ /*
+ * TODO: add some error code tests
+ * w2k3 returns NT_STATUS_DOS(ERRSRV, ERRerror) here
+ */
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
return;
}
return;
}
- trans = tp->trans;
+ trans = tp->u.trans;
param_total = SVAL(req->in.vwv, VWV(0));
data_total = SVAL(req->in.vwv, VWV(1));
uint8_t,
param_disp + param_count);
if (trans->in.params.data == NULL) {
- goto failed;
+ smbsrv_send_error(tp->req, NT_STATUS_NO_MEMORY);
+ return;
}
trans->in.params.length = param_disp + param_count;
}
uint8_t,
data_disp + data_count);
if (trans->in.data.data == NULL) {
- goto failed;
+ smbsrv_send_error(tp->req, NT_STATUS_NO_MEMORY);
+ return;
}
trans->in.data.length = data_disp + data_count;
}
if (trans->in.params.length == param_total &&
trans->in.data.length == data_total) {
/* its now complete */
- DLIST_REMOVE(tp->req->smb_conn->trans_partial, tp);
- reply_trans_complete(tp->req, command, trans);
+ req = tp->req;
+ talloc_free(tp);
+ reply_trans_complete(req, command, trans);
}
return;
-
-failed:
- smbsrv_send_error(tp->req, NT_STATUS_NO_MEMORY);
- DLIST_REMOVE(req->smb_conn->trans_partial, tp);
- talloc_free(req);
- talloc_free(tp);
}