return NT_STATUS_NOT_A_REPARSE_POINT;
}
+static NTSTATUS check_reparse_data_buffer(
+ const uint8_t *in_data, size_t in_len)
+{
+ uint16_t reparse_data_length;
+
+ if (in_len == 0) {
+ DBG_DEBUG("in_len=0\n");
+ return NT_STATUS_INVALID_BUFFER_SIZE;
+ }
+ if (in_len < 8) {
+ DBG_DEBUG("in_len=%zu\n", in_len);
+ return NT_STATUS_IO_REPARSE_DATA_INVALID;
+ }
+
+ reparse_data_length = PULL_LE_U16(in_data, 4);
+
+ if (reparse_data_length != (in_len - 8)) {
+ DBG_DEBUG("in_len=%zu, reparse_data_length=%"PRIu16"\n",
+ in_len,
+ reparse_data_length);
+ return NT_STATUS_IO_REPARSE_DATA_INVALID;
+ }
+
+ return NT_STATUS_OK;
+}
+
NTSTATUS fsctl_set_reparse_point(struct files_struct *fsp,
TALLOC_CTX *mem_ctx,
const uint8_t *in_data,
uint32_t in_len)
{
+ NTSTATUS status;
+
DBG_DEBUG("Called on %s\n", fsp_str_dbg(fsp));
+
+ status = check_reparse_data_buffer(in_data, in_len);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
return NT_STATUS_NOT_A_REPARSE_POINT;
}
printf("FSCTL_GET_REPARSE_POINT returned correct status \n");
/* Fill in for FSCTL_SET_REPARSE_POINT and call cli_trans ... */
- SIVAL(setup, 0, FSCTL_SET_REPARSE_POINT); /* returns NOT A REPARSE POINT */
+ SIVAL(setup, 0, FSCTL_SET_REPARSE_POINT); /* returns INVALID_BUFFER_SIZE */
SSVAL(setup, 4, fnum);
SCVAL(setup, 6, 0x1); /* It is an fsctl */
SCVAL(setup, 7, 0x0);
NULL, 0, NULL, /* rsetup, min_rsetup, num_rsetup */
NULL, 0, NULL, /* rparam, min_rparam, num_rparam */
NULL, 0, NULL); /* rdata, ... */
- if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_REPARSE_POINT)) {
- d_fprintf(stderr, "cli_trans of FSCTL_SET_REPARSE_POINT returned %s instead of NT_STATUS_NOT_A_REPARSE_POINT\n",
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_BUFFER_SIZE)) {
+ d_fprintf(stderr,
+ "cli_trans of FSCTL_SET_REPARSE_POINT returned %s "
+ "instead of NT_STATUS_INVALID_BUFFER_SIZE\n",
nt_errstr(status));
goto fail;
}