static void smbd_smb2_request_create_done(struct tevent_req *tsubreq) { struct smbd_smb2_request *smb2req = tevent_req_callback_data(tsubreq, struct smbd_smb2_request); int i = smb2req->current_idx; uint8_t *outhdr; DATA_BLOB outbody; DATA_BLOB outdyn; uint8_t out_oplock_level = 0; uint32_t out_create_action = 0; NTTIME out_creation_time = 0; NTTIME out_last_access_time = 0; NTTIME out_last_write_time = 0; NTTIME out_change_time = 0; uint64_t out_allocation_size = 0; uint64_t out_end_of_file = 0; uint32_t out_file_attributes = 0; uint64_t out_file_id_persistent = 0; uint64_t out_file_id_volatile = 0; struct smb2_create_blobs out_context_blobs; DATA_BLOB out_context_buffer; uint16_t out_context_buffer_offset = 0; NTSTATUS status; NTSTATUS error; /* transport error */ if (smb2req->cancelled) { uint64_t mid = get_mid_from_smb2req(smb2req); DEBUG(10,("smbd_smb2_request_create_done: cancelled mid %llu\n", (unsigned long long)mid )); error = smbd_smb2_request_error(smb2req, NT_STATUS_CANCELLED); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(smb2req->sconn, nt_errstr(error)); return; } return; } status = smbd_smb2_create_recv(tsubreq, smb2req, &out_oplock_level, &out_create_action, &out_creation_time, &out_last_access_time, &out_last_write_time, &out_change_time, &out_allocation_size, &out_end_of_file, &out_file_attributes, &out_file_id_persistent, &out_file_id_volatile, &out_context_blobs); if (!NT_STATUS_IS_OK(status)) { error = smbd_smb2_request_error(smb2req, status); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(smb2req->sconn, nt_errstr(error)); return; } return; } status = smb2_create_blob_push(smb2req, &out_context_buffer, out_context_blobs); if (!NT_STATUS_IS_OK(status)) { error = smbd_smb2_request_error(smb2req, status); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(smb2req->sconn, nt_errstr(error)); return; } return; } if (out_context_buffer.length > 0) { out_context_buffer_offset = SMB2_HDR_BODY + 0x58; } outhdr = (uint8_t *)smb2req->out.vector[i].iov_base; outbody = data_blob_talloc(smb2req->out.vector, NULL, 0x58); if (outbody.data == NULL) { error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(smb2req->sconn, nt_errstr(error)); return; } return; } SSVAL(outbody.data, 0x00, 0x58 + 1); /* struct size */ SCVAL(outbody.data, 0x02, out_oplock_level); /* oplock level */ SCVAL(outbody.data, 0x03, 0); /* reserved */ SIVAL(outbody.data, 0x04, out_create_action); /* create action */ SBVAL(outbody.data, 0x08, out_creation_time); /* creation time */ SBVAL(outbody.data, 0x10, out_last_access_time); /* last access time */ SBVAL(outbody.data, 0x18, out_last_write_time); /* last write time */ SBVAL(outbody.data, 0x20, out_change_time); /* change time */ SBVAL(outbody.data, 0x28, out_allocation_size); /* allocation size */ SBVAL(outbody.data, 0x30, out_end_of_file); /* end of file */ SIVAL(outbody.data, 0x38, out_file_attributes); /* file attributes */ SIVAL(outbody.data, 0x3C, 0); /* reserved */ SBVAL(outbody.data, 0x40, out_file_id_persistent); /* file id (persistent) */ SBVAL(outbody.data, 0x48, out_file_id_volatile); /* file id (volatile) */ SIVAL(outbody.data, 0x50, out_context_buffer_offset); /* create contexts offset */ SIVAL(outbody.data, 0x54, out_context_buffer.length); /* create contexts length */ outdyn = out_context_buffer; error = smbd_smb2_request_done(smb2req, outbody, &outdyn); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(smb2req->sconn, nt_errstr(error)); return; } }
static void smbd_smb2_request_create_done(struct tevent_req *tsubreq) { struct smbd_smb2_request *smb2req = tevent_req_callback_data(tsubreq, struct smbd_smb2_request); DATA_BLOB outbody; DATA_BLOB outdyn; uint8_t out_oplock_level = 0; uint32_t out_create_action = 0; connection_struct *conn = smb2req->tcon->compat; struct timespec out_creation_ts = { 0, }; struct timespec out_last_access_ts = { 0, }; struct timespec out_last_write_ts = { 0, }; struct timespec out_change_ts = { 0, }; uint64_t out_allocation_size = 0; uint64_t out_end_of_file = 0; uint32_t out_file_attributes = 0; uint64_t out_file_id_persistent = 0; uint64_t out_file_id_volatile = 0; struct smb2_create_blobs out_context_blobs; DATA_BLOB out_context_buffer; uint16_t out_context_buffer_offset = 0; NTSTATUS status; NTSTATUS error; /* transport error */ status = smbd_smb2_create_recv(tsubreq, smb2req, &out_oplock_level, &out_create_action, &out_creation_ts, &out_last_access_ts, &out_last_write_ts, &out_change_ts, &out_allocation_size, &out_end_of_file, &out_file_attributes, &out_file_id_persistent, &out_file_id_volatile, &out_context_blobs); if (!NT_STATUS_IS_OK(status)) { error = smbd_smb2_request_error(smb2req, status); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(smb2req->xconn, nt_errstr(error)); return; } return; } status = smb2_create_blob_push(smb2req, &out_context_buffer, out_context_blobs); if (!NT_STATUS_IS_OK(status)) { error = smbd_smb2_request_error(smb2req, status); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(smb2req->xconn, nt_errstr(error)); return; } return; } if (out_context_buffer.length > 0) { out_context_buffer_offset = SMB2_HDR_BODY + 0x58; } outbody = smbd_smb2_generate_outbody(smb2req, 0x58); if (outbody.data == NULL) { error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(smb2req->xconn, nt_errstr(error)); return; } return; } SSVAL(outbody.data, 0x00, 0x58 + 1); /* struct size */ SCVAL(outbody.data, 0x02, out_oplock_level); /* oplock level */ SCVAL(outbody.data, 0x03, 0); /* reserved */ SIVAL(outbody.data, 0x04, out_create_action); /* create action */ put_long_date_timespec(conn->ts_res, (char *)outbody.data + 0x08, out_creation_ts); /* creation time */ put_long_date_timespec(conn->ts_res, (char *)outbody.data + 0x10, out_last_access_ts); /* last access time */ put_long_date_timespec(conn->ts_res, (char *)outbody.data + 0x18, out_last_write_ts); /* last write time */ put_long_date_timespec(conn->ts_res, (char *)outbody.data + 0x20, out_change_ts); /* change time */ SBVAL(outbody.data, 0x28, out_allocation_size); /* allocation size */ SBVAL(outbody.data, 0x30, out_end_of_file); /* end of file */ SIVAL(outbody.data, 0x38, out_file_attributes); /* file attributes */ SIVAL(outbody.data, 0x3C, 0); /* reserved */ SBVAL(outbody.data, 0x40, out_file_id_persistent); /* file id (persistent) */ SBVAL(outbody.data, 0x48, out_file_id_volatile); /* file id (volatile) */ SIVAL(outbody.data, 0x50, out_context_buffer_offset); /* create contexts offset */ SIVAL(outbody.data, 0x54, out_context_buffer.length); /* create contexts length */ outdyn = out_context_buffer; error = smbd_smb2_request_done(smb2req, outbody, &outdyn); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(smb2req->xconn, nt_errstr(error)); return; } }