mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
s3:smb2_ioctl: FSCTL_SRV_ENUMERATE_SNAPSHOTS is handles in SMB_VFS_FSCTL()
metze
This commit is contained in:
parent
5e998b805f
commit
739bd25fe0
@ -377,131 +377,6 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx,
|
||||
req);
|
||||
return req;
|
||||
|
||||
case 0x00144064: /* FSCTL_SRV_ENUMERATE_SNAPSHOTS */
|
||||
{
|
||||
/*
|
||||
* This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
|
||||
* and return their volume names. If max_data_count is 16, then it is just
|
||||
* asking for the number of volumes and length of the combined names.
|
||||
*
|
||||
* pdata is the data allocated by our caller, but that uses
|
||||
* total_data_count (which is 0 in our case) rather than max_data_count.
|
||||
* Allocate the correct amount and return the pointer to let
|
||||
* it be deallocated when we return.
|
||||
*/
|
||||
struct shadow_copy_data *shadow_data = NULL;
|
||||
bool labels = False;
|
||||
uint32_t labels_data_count = 0;
|
||||
uint32_t data_count;
|
||||
uint32_t i;
|
||||
char *pdata;
|
||||
NTSTATUS status;
|
||||
|
||||
if (fsp == NULL) {
|
||||
tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (in_max_output < 16) {
|
||||
DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: "
|
||||
"in_max_output(%u) < 16 is invalid!\n",
|
||||
in_max_output));
|
||||
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (in_max_output > 16) {
|
||||
labels = True;
|
||||
}
|
||||
|
||||
shadow_data = talloc_zero(talloc_tos(),
|
||||
struct shadow_copy_data);
|
||||
if (tevent_req_nomem(shadow_data, req)) {
|
||||
DEBUG(0,("TALLOC_ZERO() failed!\n"));
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call the VFS routine to actually do the work.
|
||||
*/
|
||||
if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)
|
||||
!= 0) {
|
||||
if (errno == ENOSYS) {
|
||||
DEBUG(5, ("FSCTL_GET_SHADOW_COPY_DATA: "
|
||||
"connectpath %s, not supported.\n",
|
||||
smbreq->conn->connectpath));
|
||||
status = NT_STATUS_NOT_SUPPORTED;
|
||||
} else {
|
||||
DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: "
|
||||
"connectpath %s, failed.\n",
|
||||
smbreq->conn->connectpath));
|
||||
status = map_nt_error_from_unix(errno);
|
||||
}
|
||||
TALLOC_FREE(shadow_data);
|
||||
tevent_req_nterror(req, status);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
labels_data_count =
|
||||
(shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))
|
||||
+ 2;
|
||||
|
||||
if (labels) {
|
||||
data_count = 12+labels_data_count+4;
|
||||
} else {
|
||||
data_count = 16;
|
||||
}
|
||||
|
||||
if (labels && (in_max_output < data_count)) {
|
||||
DEBUG(0, ("FSCTL_GET_SHADOW_COPY_DATA: "
|
||||
"in_max_output(%u) too small (%u) bytes "
|
||||
"needed!\n", in_max_output, data_count));
|
||||
TALLOC_FREE(shadow_data);
|
||||
tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
state->out_output = data_blob_talloc(state, NULL, data_count);
|
||||
if (tevent_req_nomem(state->out_output.data, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
pdata = (char *)state->out_output.data;
|
||||
|
||||
/* num_volumes 4 bytes */
|
||||
SIVAL(pdata, 0, shadow_data->num_volumes);
|
||||
|
||||
if (labels) {
|
||||
/* num_labels 4 bytes */
|
||||
SIVAL(pdata, 4, shadow_data->num_volumes);
|
||||
}
|
||||
|
||||
/* needed_data_count 4 bytes */
|
||||
SIVAL(pdata, 8, labels_data_count+4);
|
||||
|
||||
pdata += 12;
|
||||
|
||||
DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for "
|
||||
"path[%s].\n",
|
||||
shadow_data->num_volumes, fsp_str_dbg(fsp)));
|
||||
if (labels && shadow_data->labels) {
|
||||
for (i=0; i<shadow_data->num_volumes; i++) {
|
||||
srvstr_push(pdata, smbreq->flags2,
|
||||
pdata, shadow_data->labels[i],
|
||||
2*sizeof(SHADOW_COPY_LABEL),
|
||||
STR_UNICODE|STR_TERMINATE);
|
||||
pdata += 2*sizeof(SHADOW_COPY_LABEL);
|
||||
DEBUGADD(10, ("Label[%u]: '%s'\n", i,
|
||||
shadow_data->labels[i]));
|
||||
}
|
||||
}
|
||||
|
||||
TALLOC_FREE(shadow_data);
|
||||
|
||||
tevent_req_done(req);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
default: {
|
||||
uint8_t *out_data = NULL;
|
||||
uint32_t out_data_len = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user