📄 reply.c
字号:
SSVAL(req->out.vwv, VWV(10),oi->openx.out.devstate); SSVAL(req->out.vwv, VWV(11),oi->openx.out.action); SIVAL(req->out.vwv, VWV(12),oi->openx.out.unique_fid); SSVAL(req->out.vwv, VWV(14),0); /* reserved */ if (oi->openx.in.flags & OPENX_FLAGS_EXTENDED_RETURN) { SIVAL(req->out.vwv, VWV(15),oi->openx.out.access_mask); SMBSRV_VWV_RESERVED(17, 2); } req->chained_fnum = SVAL(req->out.vwv, VWV(2)); smbsrv_chain_reply(req);}/**************************************************************************** Reply to an open and X.****************************************************************************/void smbsrv_reply_open_and_X(struct smbsrv_request *req){ union smb_open *oi; /* parse the request */ SMBSRV_CHECK_WCT(req, 15); SMBSRV_TALLOC_IO_PTR(oi, union smb_open); SMBSRV_SETUP_NTVFS_REQUEST(reply_open_and_X_send, NTVFS_ASYNC_STATE_MAY_ASYNC); oi->openx.level = RAW_OPEN_OPENX; oi->openx.in.flags = SVAL(req->in.vwv, VWV(2)); oi->openx.in.open_mode = SVAL(req->in.vwv, VWV(3)); oi->openx.in.search_attrs = SVAL(req->in.vwv, VWV(4)); oi->openx.in.file_attrs = SVAL(req->in.vwv, VWV(5)); oi->openx.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(6)); oi->openx.in.open_func = SVAL(req->in.vwv, VWV(8)); oi->openx.in.size = IVAL(req->in.vwv, VWV(9)); oi->openx.in.timeout = IVAL(req->in.vwv, VWV(11)); req_pull_ascii4(&req->in.bufinfo, &oi->openx.in.fname, req->in.data, STR_TERMINATE); if (!oi->openx.in.fname) { smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); return; } SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));}/**************************************************************************** Reply to a mknew or a create.****************************************************************************/static void reply_mknew_send(struct ntvfs_request *ntvfs){ struct smbsrv_request *req; union smb_open *oi; SMBSRV_CHECK_ASYNC_STATUS(oi, union smb_open); /* build the reply */ smbsrv_setup_reply(req, 1, 0); smbsrv_push_fnum(req->out.vwv, VWV(0), oi->mknew.out.file.ntvfs); smbsrv_send_reply(req);}/**************************************************************************** Reply to a mknew or a create.****************************************************************************/void smbsrv_reply_mknew(struct smbsrv_request *req){ union smb_open *oi; /* parse the request */ SMBSRV_CHECK_WCT(req, 3); SMBSRV_TALLOC_IO_PTR(oi, union smb_open); SMBSRV_SETUP_NTVFS_REQUEST(reply_mknew_send, NTVFS_ASYNC_STATE_MAY_ASYNC); if (CVAL(req->in.hdr, HDR_COM) == SMBmknew) { oi->mknew.level = RAW_OPEN_MKNEW; } else { oi->mknew.level = RAW_OPEN_CREATE; } oi->mknew.in.attrib = SVAL(req->in.vwv, VWV(0)); oi->mknew.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1)); req_pull_ascii4(&req->in.bufinfo, &oi->mknew.in.fname, req->in.data, STR_TERMINATE); if (!oi->mknew.in.fname) { smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); return; } SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));}/**************************************************************************** Reply to a create temporary file (async reply)****************************************************************************/static void reply_ctemp_send(struct ntvfs_request *ntvfs){ struct smbsrv_request *req; union smb_open *oi; SMBSRV_CHECK_ASYNC_STATUS(oi, union smb_open); /* build the reply */ smbsrv_setup_reply(req, 1, 0); smbsrv_push_fnum(req->out.vwv, VWV(0), oi->ctemp.out.file.ntvfs); /* the returned filename is relative to the directory */ req_push_str(req, NULL, oi->ctemp.out.name, -1, STR_TERMINATE | STR_ASCII); smbsrv_send_reply(req);}/**************************************************************************** Reply to a create temporary file.****************************************************************************/void smbsrv_reply_ctemp(struct smbsrv_request *req){ union smb_open *oi; /* parse the request */ SMBSRV_CHECK_WCT(req, 3); SMBSRV_TALLOC_IO_PTR(oi, union smb_open); SMBSRV_SETUP_NTVFS_REQUEST(reply_ctemp_send, NTVFS_ASYNC_STATE_MAY_ASYNC); oi->ctemp.level = RAW_OPEN_CTEMP; oi->ctemp.in.attrib = SVAL(req->in.vwv, VWV(0)); oi->ctemp.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1)); /* the filename is actually a directory name, the server provides a filename in that directory */ req_pull_ascii4(&req->in.bufinfo, &oi->ctemp.in.directory, req->in.data, STR_TERMINATE); if (!oi->ctemp.in.directory) { smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); return; } SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));}/**************************************************************************** Reply to a unlink****************************************************************************/void smbsrv_reply_unlink(struct smbsrv_request *req){ union smb_unlink *unl; /* parse the request */ SMBSRV_CHECK_WCT(req, 1); SMBSRV_TALLOC_IO_PTR(unl, union smb_unlink); SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC); unl->unlink.in.attrib = SVAL(req->in.vwv, VWV(0)); req_pull_ascii4(&req->in.bufinfo, &unl->unlink.in.pattern, req->in.data, STR_TERMINATE); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_unlink(req->ntvfs, unl));}/**************************************************************************** Reply to a readbraw (core+ protocol). this is a strange packet because it doesn't use a standard SMB header in the reply, only the 4 byte NBT header This command must be replied to synchronously****************************************************************************/void smbsrv_reply_readbraw(struct smbsrv_request *req){ NTSTATUS status; union smb_read io; io.readbraw.level = RAW_READ_READBRAW; /* there are two variants, one with 10 and one with 8 command words */ if (req->in.wct < 8) { goto failed; } io.readbraw.in.file.ntvfs = smbsrv_pull_fnum(req, req->in.vwv, VWV(0)); io.readbraw.in.offset = IVAL(req->in.vwv, VWV(1)); io.readbraw.in.maxcnt = SVAL(req->in.vwv, VWV(3)); io.readbraw.in.mincnt = SVAL(req->in.vwv, VWV(4)); io.readbraw.in.timeout = IVAL(req->in.vwv, VWV(5)); if (!io.readbraw.in.file.ntvfs) { goto failed; } /* the 64 bit variant */ if (req->in.wct == 10) { uint32_t offset_high = IVAL(req->in.vwv, VWV(8)); io.readbraw.in.offset |= (((off_t)offset_high) << 32); } /* before calling the backend we setup the raw buffer. This * saves a copy later */ req->out.size = io.readbraw.in.maxcnt + NBT_HDR_SIZE; req->out.buffer = talloc_size(req, req->out.size); if (req->out.buffer == NULL) { goto failed; } SIVAL(req->out.buffer, 0, 0); /* init NBT header */ /* tell the backend where to put the data */ io.readbraw.out.data = req->out.buffer + NBT_HDR_SIZE; /* prepare the ntvfs request */ req->ntvfs = ntvfs_request_create(req->tcon->ntvfs, req, req->session->session_info, SVAL(req->in.hdr,HDR_PID), req->request_time, req, NULL, 0); if (!req->ntvfs) { goto failed; } /* call the backend */ status = ntvfs_read(req->ntvfs, &io); if (!NT_STATUS_IS_OK(status)) { goto failed; } req->out.size = io.readbraw.out.nread + NBT_HDR_SIZE; smbsrv_send_reply_nosign(req); return;failed: /* any failure in readbraw is equivalent to reading zero bytes */ req->out.size = 4; req->out.buffer = talloc_size(req, req->out.size); SIVAL(req->out.buffer, 0, 0); /* init NBT header */ smbsrv_send_reply_nosign(req);}/**************************************************************************** Reply to a lockread (async reply)****************************************************************************/static void reply_lockread_send(struct ntvfs_request *ntvfs){ struct smbsrv_request *req; union smb_read *io; SMBSRV_CHECK_ASYNC_STATUS(io, union smb_read); /* trim packet */ io->lockread.out.nread = MIN(io->lockread.out.nread, req_max_data(req) - 3); req_grow_data(req, 3 + io->lockread.out.nread); /* construct reply */ SSVAL(req->out.vwv, VWV(0), io->lockread.out.nread); SMBSRV_VWV_RESERVED(1, 4); SCVAL(req->out.data, 0, SMB_DATA_BLOCK); SSVAL(req->out.data, 1, io->lockread.out.nread); smbsrv_send_reply(req);}/**************************************************************************** Reply to a lockread (core+ protocol). note that the lock is a write lock, not a read lock!****************************************************************************/void smbsrv_reply_lockread(struct smbsrv_request *req){ union smb_read *io; /* parse request */ SMBSRV_CHECK_WCT(req, 5); SMBSRV_TALLOC_IO_PTR(io, union smb_read); SMBSRV_SETUP_NTVFS_REQUEST(reply_lockread_send, NTVFS_ASYNC_STATE_MAY_ASYNC); io->lockread.level = RAW_READ_LOCKREAD; io->lockread.in.file.ntvfs= smbsrv_pull_fnum(req, req->in.vwv, VWV(0)); io->lockread.in.count = SVAL(req->in.vwv, VWV(1)); io->lockread.in.offset = IVAL(req->in.vwv, VWV(2)); io->lockread.in.remaining = SVAL(req->in.vwv, VWV(4)); /* setup the reply packet assuming the maximum possible read */ smbsrv_setup_reply(req, 5, 3 + io->lockread.in.count); /* tell the backend where to put the data */ io->lockread.out.data = req->out.data + 3; SMBSRV_CHECK_FILE_HANDLE(io->lockread.in.file.ntvfs); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_read(req->ntvfs, io));}/**************************************************************************** Reply to a read (async reply)****************************************************************************/static void reply_read_send(struct ntvfs_request *ntvfs){ struct smbsrv_request *req; union smb_read *io; SMBSRV_CHECK_ASYNC_STATUS(io, union smb_read); /* trim packet */ io->read.out.nread = MIN(io->read.out.nread, req_max_data(req) - 3); req_grow_data(req, 3 + io->read.out.nread); /* construct reply */ SSVAL(req->out.vwv, VWV(0), io->read.out.nread); SMBSRV_VWV_RESERVED(1, 4); SCVAL(req->out.data, 0, SMB_DATA_BLOCK); SSVAL(req->out.data, 1, io->read.out.nread); smbsrv_send_reply(req);}/**************************************************************************** Reply to a read.****************************************************************************/void smbsrv_reply_read(struct smbsrv_request *req){ union smb_read *io; /* parse request */ SMBSRV_CHECK_WCT(req, 5); SMBSRV_TALLOC_IO_PTR(io, union smb_read); SMBSRV_SETUP_NTVFS_REQUEST(reply_read_send, NTVFS_ASYNC_STATE_MAY_ASYNC); io->read.level = RAW_READ_READ; io->read.in.file.ntvfs = smbsrv_pull_fnum(req, req->in.vwv, VWV(0)); io->read.in.count = SVAL(req->in.vwv, VWV(1)); io->read.in.offset = IVAL(req->in.vwv, VWV(2)); io->read.in.remaining = SVAL(req->in.vwv, VWV(4)); /* setup the reply packet assuming the maximum possible read */ smbsrv_setup_reply(req, 5, 3 + io->read.in.count); /* tell the backend where to put the data */ io->read.out.data = req->out.data + 3; SMBSRV_CHECK_FILE_HANDLE(io->read.in.file.ntvfs); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_read(req->ntvfs, io));}/**************************************************************************** Reply to a read and X (async reply)****************************************************************************/static void reply_read_and_X_send(struct ntvfs_request *ntvfs){ struct smbsrv_request *req; union smb_read *io; SMBSRV_CHECK_ASYNC_STATUS(io, union smb_read); /* readx reply packets can be over-sized */ req->control_flags |= SMBSRV_REQ_CONTROL_LARGE; if (io->readx.in.maxcnt != 0xFFFF && io->readx.in.mincnt != 0xFFFF) { req_grow_data(req, 1 + io->readx.out.nread); SCVAL(req->out.data, 0, 0); /* padding */ } else { req_grow_data(req, io->readx.out.nread); } /* construct reply */ SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), io->readx.out.remaining); SSVAL(req->out.vwv, VWV(3), io->readx.out.compaction_mode); SMBSRV_VWV_RESERVED(4, 1); SSVAL(req->out.vwv, VWV(5), io->readx.out.nread); SSVAL(req->out.vwv, VWV(6), PTR_DIFF(io->readx.out.data, req->out.hdr)); SMBSRV_VWV_RESERVED(7, 5); smbsrv_chain_reply(req);}/**************************************************************************** Reply to a read and X.****************************************************************************/void smbsrv_reply_read_and_X(struct smbsrv_request *req){ union smb_read *io; /* parse request */ if (req->in.wct != 12) { SMBSRV_CHECK_WCT(req, 10); } SMBSRV_TALLOC_IO_PTR(io, union smb_read); SMBSRV_SETUP_NTVFS_REQUEST(reply_read_and_X_send, NTVFS_ASYNC_STATE_MAY_ASYNC); io->readx.level = RAW_READ_READX; io->readx.in.file.ntvfs = smbsrv_pull_fnum(req, req->in.vwv, VWV(2)); io->readx.in.offset = IVAL(req->in.vwv, VWV(3)); io->readx.in.maxcnt = SVAL(req->in.vwv, VWV(5)); io->readx.in.mincnt = SVAL(req->in.vwv, VWV(6)); io->readx.in.remaining = SVAL(req->in.vwv, VWV(9)); if (req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) { io->readx.in.read_for_execute = true; } else { io->readx.in.read_for_execute = false; } if (req->smb_conn->negotiate.client_caps & CAP_LARGE_READX) { uint32_t high_part = IVAL(req->in.vwv, VWV(7)); if (high_part == 1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -