Changeset 740 for vendor/current/source3/smbd/smb2_ioctl.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified vendor/current/source3/smbd/smb2_ioctl.c ¶
r414 r740 20 20 21 21 #include "includes.h" 22 #include "smbd/smbd.h" 22 23 #include "smbd/globals.h" 23 24 #include "../libcli/smb/smb_common.h" 25 #include "../lib/util/tevent_ntstatus.h" 26 #include "rpc_server/srv_pipe_hnd.h" 27 #include "include/ntioctl.h" 24 28 25 29 static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx, … … 89 93 in_file_id_volatile == UINT64_MAX) { 90 94 /* without a handle */ 91 } else if (in_file_id_persistent != 0) {95 } else if (in_file_id_persistent != in_file_id_volatile) { 92 96 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 93 97 } … … 128 132 129 133 status = smbd_smb2_ioctl_recv(subreq, req, &out_output_buffer); 134 135 DEBUG(10,("smbd_smb2_request_ioctl_done: smbd_smb2_ioctl_recv returned " 136 "%u status %s\n", 137 (unsigned int)out_output_buffer.length, 138 nt_errstr(status) )); 139 130 140 TALLOC_FREE(subreq); 131 141 if (NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { … … 354 364 } 355 365 366 DEBUG(10,("smbd_smb2_ioctl_send: np_write_send of size %u\n", 367 (unsigned int)in_input.length )); 368 356 369 subreq = np_write_send(state, ev, 357 370 fsp->fake_file_handle, … … 365 378 req); 366 379 return req; 380 381 case 0x00144064: /* FSCTL_SRV_ENUMERATE_SNAPSHOTS */ 382 { 383 /* 384 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots) 385 * and return their volume names. If max_data_count is 16, then it is just 386 * asking for the number of volumes and length of the combined names. 387 * 388 * pdata is the data allocated by our caller, but that uses 389 * total_data_count (which is 0 in our case) rather than max_data_count. 390 * Allocate the correct amount and return the pointer to let 391 * it be deallocated when we return. 392 */ 393 struct shadow_copy_data *shadow_data = NULL; 394 bool labels = False; 395 uint32_t labels_data_count = 0; 396 uint32_t data_count; 397 uint32_t i; 398 char *pdata; 399 NTSTATUS status; 400 401 if (fsp == NULL) { 402 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED); 403 return tevent_req_post(req, ev); 404 } 405 406 if (in_max_output < 16) { 407 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: " 408 "in_max_output(%u) < 16 is invalid!\n", 409 in_max_output)); 410 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 411 return tevent_req_post(req, ev); 412 } 413 414 if (in_max_output > 16) { 415 labels = True; 416 } 417 418 shadow_data = TALLOC_ZERO_P(talloc_tos(), 419 struct shadow_copy_data); 420 if (tevent_req_nomem(shadow_data, req)) { 421 DEBUG(0,("TALLOC_ZERO() failed!\n")); 422 return tevent_req_post(req, ev); 423 } 424 425 /* 426 * Call the VFS routine to actually do the work. 427 */ 428 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels) 429 != 0) { 430 if (errno == ENOSYS) { 431 DEBUG(5, ("FSCTL_GET_SHADOW_COPY_DATA: " 432 "connectpath %s, not supported.\n", 433 smbreq->conn->connectpath)); 434 status = NT_STATUS_NOT_SUPPORTED; 435 } else { 436 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: " 437 "connectpath %s, failed.\n", 438 smbreq->conn->connectpath)); 439 status = map_nt_error_from_unix(errno); 440 } 441 TALLOC_FREE(shadow_data); 442 tevent_req_nterror(req, status); 443 return tevent_req_post(req, ev); 444 } 445 446 labels_data_count = 447 (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL)) 448 + 2; 449 450 if (labels) { 451 data_count = 12+labels_data_count+4; 452 } else { 453 data_count = 16; 454 } 455 456 if (labels && (in_max_output < data_count)) { 457 DEBUG(0, ("FSCTL_GET_SHADOW_COPY_DATA: " 458 "in_max_output(%u) too small (%u) bytes " 459 "needed!\n", in_max_output, data_count)); 460 TALLOC_FREE(shadow_data); 461 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); 462 return tevent_req_post(req, ev); 463 } 464 465 state->out_output = data_blob_talloc(state, NULL, data_count); 466 if (tevent_req_nomem(state->out_output.data, req)) { 467 return tevent_req_post(req, ev); 468 } 469 470 pdata = (char *)state->out_output.data; 471 472 /* num_volumes 4 bytes */ 473 SIVAL(pdata, 0, shadow_data->num_volumes); 474 475 if (labels) { 476 /* num_labels 4 bytes */ 477 SIVAL(pdata, 4, shadow_data->num_volumes); 478 } 479 480 /* needed_data_count 4 bytes */ 481 SIVAL(pdata, 8, labels_data_count+4); 482 483 pdata += 12; 484 485 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for " 486 "path[%s].\n", 487 shadow_data->num_volumes, fsp_str_dbg(fsp))); 488 if (labels && shadow_data->labels) { 489 for (i=0; i<shadow_data->num_volumes; i++) { 490 srvstr_push(pdata, smbreq->flags2, 491 pdata, shadow_data->labels[i], 492 2*sizeof(SHADOW_COPY_LABEL), 493 STR_UNICODE|STR_TERMINATE); 494 pdata += 2*sizeof(SHADOW_COPY_LABEL); 495 DEBUGADD(10, ("Label[%u]: '%s'\n", i, 496 shadow_data->labels[i])); 497 } 498 } 499 500 TALLOC_FREE(shadow_data); 501 502 tevent_req_done(req); 503 return tevent_req_post(req, ev); 504 } 367 505 368 506 default: … … 389 527 390 528 status = np_write_recv(subreq, &nwritten); 529 530 DEBUG(10,("smbd_smb2_ioctl_pipe_write_done: received %ld\n", 531 (long int)nwritten )); 532 391 533 TALLOC_FREE(subreq); 392 534 if (!NT_STATUS_IS_OK(status)) { … … 406 548 } 407 549 550 DEBUG(10,("smbd_smb2_ioctl_pipe_write_done: issuing np_read_send " 551 "of size %u\n", 552 (unsigned int)state->out_output.length )); 553 554 TALLOC_FREE(subreq); 408 555 subreq = np_read_send(state->smbreq->conn, 409 556 state->smb2req->sconn->smb2.event_ctx, … … 424 571 struct smbd_smb2_ioctl_state); 425 572 NTSTATUS status; 426 ssize_t nread ;427 bool is_data_outstanding ;573 ssize_t nread = -1; 574 bool is_data_outstanding = false; 428 575 429 576 status = np_read_recv(subreq, &nread, &is_data_outstanding); 577 578 DEBUG(10,("smbd_smb2_ioctl_pipe_read_done: np_read_recv nread = %d " 579 "is_data_outstanding = %d, status = %s\n", 580 (int)nread, 581 (int)is_data_outstanding, 582 nt_errstr(status) )); 583 430 584 TALLOC_FREE(subreq); 431 585 if (!NT_STATUS_IS_OK(status)) { … … 435 589 436 590 state->out_output.length = nread; 591 592 if (is_data_outstanding) { 593 tevent_req_nterror(req, STATUS_BUFFER_OVERFLOW); 594 return; 595 } 437 596 438 597 tevent_req_done(req); … … 443 602 DATA_BLOB *out_output) 444 603 { 445 NTSTATUS status ;604 NTSTATUS status = NT_STATUS_OK; 446 605 struct smbd_smb2_ioctl_state *state = tevent_req_data(req, 447 606 struct smbd_smb2_ioctl_state);
Note:
See TracChangeset
for help on using the changeset viewer.