if (new_size <= trans->out.data.length) {
return;
}
- trans->out.data.data = talloc_realloc(trans->out.data.data, new_size);
+ trans->out.data.data = talloc_realloc(req, trans->out.data.data, new_size);
}
{
trans->out.setup_count = setup_count;
if (setup_count != 0) {
- trans->out.setup = talloc_zero(req, sizeof(uint16_t) * setup_count);
+ trans->out.setup = talloc_zero_array_p(req, uint16_t, setup_count);
}
trans->out.params = data_blob_talloc(req, NULL, param_size);
trans->out.data = data_blob_talloc(req, NULL, data_size);
alignment = 1;
if (dest_len > 0) {
SCVAL(trans->out.data.data + offset, 0, 0);
- ret = push_string(NULL, trans->out.data.data + offset + 1, str->s, dest_len-1, flags);
+ ret = push_string(trans->out.data.data + offset + 1, str->s, dest_len-1, flags);
}
} else {
- ret = push_string(NULL, trans->out.data.data + offset, str->s, dest_len, flags);
+ ret = push_string(trans->out.data.data + offset, str->s, dest_len, flags);
}
/* sometimes the string needs to be terminated, but the length
trans2_grow_data(req, trans, offset + ret);
}
+/*
+ align the end of the data section of a trans reply on an even boundary
+*/
+static void trans2_align_data(struct smbsrv_request *req, struct smb_trans2 *trans)
+{
+ if ((trans->out.data.length & 1) == 0) {
+ return;
+ }
+ trans2_grow_data(req, trans, trans->out.data.length+1);
+ SCVAL(trans->out.data.data, trans->out.data.length-1, 0);
+}
+
/*
trans2 qfsinfo implementation
case SMB_QFS_ALLOCATION:
fsinfo.allocation.level = RAW_QFS_ALLOCATION;
- status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+ status = ntvfs_fsinfo(req, &fsinfo);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
case SMB_QFS_VOLUME:
fsinfo.volume.level = RAW_QFS_VOLUME;
- status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+ status = ntvfs_fsinfo(req, &fsinfo);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
case SMB_QFS_VOLUME_INFORMATION:
fsinfo.volume_info.level = RAW_QFS_VOLUME_INFO;
- status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+ status = ntvfs_fsinfo(req, &fsinfo);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
case SMB_QFS_SIZE_INFORMATION:
fsinfo.size_info.level = RAW_QFS_SIZE_INFO;
- status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+ status = ntvfs_fsinfo(req, &fsinfo);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
case SMB_QFS_DEVICE_INFORMATION:
fsinfo.device_info.level = RAW_QFS_DEVICE_INFO;
- status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+ status = ntvfs_fsinfo(req, &fsinfo);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
case SMB_QFS_ATTRIBUTE_INFORMATION:
fsinfo.attribute_info.level = RAW_QFS_ATTRIBUTE_INFO;
- status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+ status = ntvfs_fsinfo(req, &fsinfo);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
case SMB_QFS_QUOTA_INFORMATION:
fsinfo.quota_information.level = RAW_QFS_QUOTA_INFORMATION;
- status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+ status = ntvfs_fsinfo(req, &fsinfo);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
case SMB_QFS_FULL_SIZE_INFORMATION:
fsinfo.full_size_information.level = RAW_QFS_FULL_SIZE_INFORMATION;
- status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+ status = ntvfs_fsinfo(req, &fsinfo);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
case SMB_QFS_OBJECTID_INFORMATION:
fsinfo.objectid_information.level = RAW_QFS_OBJECTID_INFORMATION;
- status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+ status = ntvfs_fsinfo(req, &fsinfo);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
uint16_t level;
/* make sure we got enough parameters */
- if (trans->in.params.length < 8) {
+ if (trans->in.params.length < 2) {
return NT_STATUS_FOOBAR;
}
}
/* call the backend */
- status = req->tcon->ntvfs_ops->qpathinfo(req, &st);
+ status = ntvfs_qpathinfo(req, &st);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
/* call the backend */
- status = req->tcon->ntvfs_ops->qfileinfo(req, &st);
+ status = ntvfs_qfileinfo(req, &st);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
return status;
}
- status = req->tcon->ntvfs_ops->setfileinfo(req, &st);
+ status = ntvfs_setfileinfo(req, &st);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
return status;
}
- status = req->tcon->ntvfs_ops->setpathinfo(req, &st);
+ status = ntvfs_setpathinfo(req, &st);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
24, STR_UNICODE | STR_LEN8BIT);
trans2_append_data_string(req, trans, &file->both_directory_info.name,
ofs + 60, STR_TERMINATE_ASCII);
+ trans2_align_data(req, trans);
data = trans->out.data.data + ofs;
SIVAL(data, 0, trans->out.data.length - ofs);
break;
trans2_setup_reply(req, trans, 10, 0, 0);
/* call the backend */
- status = req->tcon->ntvfs_ops->search_first(req, &search, &state, find_callback);
+ status = ntvfs_search_first(req, &search, &state, find_callback);
if (!NT_STATUS_IS_OK(status)) {
+ trans2_setup_reply(req, trans, 0, 0, 0);
return status;
}
SSVAL(param, VWV(2), search.t2ffirst.out.end_of_search);
SSVAL(param, VWV(3), 0);
SSVAL(param, VWV(4), state.last_entry_offset);
-
+
return NT_STATUS_OK;
}
trans2_setup_reply(req, trans, 8, 0, 0);
/* call the backend */
- status = req->tcon->ntvfs_ops->search_next(req, &search, &state, find_callback);
+ status = ntvfs_search_next(req, &search, &state, find_callback);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
*/
static NTSTATUS trans2_backend(struct smbsrv_request *req, struct smb_trans2 *trans)
{
- if (req->tcon->ntvfs_ops->trans2 != NULL) {
- /* direct trans2 pass thru */
- return req->tcon->ntvfs_ops->trans2(req, trans);
+ NTSTATUS status;
+
+ /* direct trans2 pass thru */
+ status = ntvfs_trans2(req, trans);
+ if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
+ return status;
}
/* must have at least one setup word */
return NT_STATUS_FOOBAR;
}
-
-/*
- backend for trans requests
-*/
-static NTSTATUS trans_backend(struct smbsrv_request *req, struct smb_trans2 *trans)
-{
- if (!req->tcon->ntvfs_ops->trans) {
- return NT_STATUS_NOT_IMPLEMENTED;
- }
- return req->tcon->ntvfs_ops->trans(req, trans);
-}
-
-
/****************************************************************************
Reply to an SMBtrans or SMBtrans2 request
****************************************************************************/
/* its a full request, give it to the backend */
if (command == SMBtrans) {
- status = trans_backend(req, &trans);
+ status = ntvfs_trans(req, &trans);
} else {
status = trans2_backend(req, &trans);
}
params = trans.out.params.data;
data = trans.out.data.data;
- req->control_flags |= REQ_CONTROL_PROTECTED;
-
/* we need to divide up the reply into chunks that fit into
the negotiated buffer size */
do {
params += this_param;
data += this_data;
- /* if this is the last chunk then the request can be destroyed */
- if (params_left == 0 && data_left == 0) {
- req->control_flags &= ~REQ_CONTROL_PROTECTED;
+ /* don't destroy unless this is the last chunk */
+ if (params_left != 0 || data_left != 0) {
+ talloc_increase_ref_count(req);
}
req_send_reply(req);