From c6395a30b057c87de8ce410d5ea5ebe2e017093d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Nov 2005 05:09:26 +0000 Subject: r11715: added SMB2 read and write requests (This used to be commit d3556cbfa38447d2d385b697c1855b3c13d42744) --- source4/libcli/smb2/getinfo.c | 149 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 3 deletions(-) (limited to 'source4/libcli/smb2/getinfo.c') diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c index c8976e4230..a7935526e5 100644 --- a/source4/libcli/smb2/getinfo.c +++ b/source4/libcli/smb2/getinfo.c @@ -39,11 +39,10 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getin SSVAL(req->out.body, 0x02, io->in.level); SIVAL(req->out.body, 0x04, io->in.max_response_size); SIVAL(req->out.body, 0x08, io->in.unknown1); - SIVAL(req->out.body, 0x0C, io->in.unknown2); + SIVAL(req->out.body, 0x0C, io->in.flags); SIVAL(req->out.body, 0x10, io->in.unknown3); SIVAL(req->out.body, 0x14, io->in.unknown4); - SBVAL(req->out.body, 0x18, io->in.handle.data[0]); - SBVAL(req->out.body, 0x20, io->in.handle.data[1]); + smb2_put_handle(req->out.body+0x18, io->in.handle); smb2_transport_send(req); @@ -88,3 +87,147 @@ NTSTATUS smb2_getinfo(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, struct smb2_request *req = smb2_getinfo_send(tree, io); return smb2_getinfo_recv(req, mem_ctx, io); } + + +/* + parse a returned getinfo data blob +*/ +NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx, + uint16_t level, + DATA_BLOB blob, + union smb2_fileinfo *io) +{ + switch (level) { + case SMB2_GETINFO_FILE_BASIC_INFO: + if (blob.length != 0x28) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->basic_info.create_time = smbcli_pull_nttime(blob.data, 0x00); + io->basic_info.access_time = smbcli_pull_nttime(blob.data, 0x08); + io->basic_info.write_time = smbcli_pull_nttime(blob.data, 0x10); + io->basic_info.change_time = smbcli_pull_nttime(blob.data, 0x18); + io->basic_info.file_attr = IVAL(blob.data, 0x20); + io->basic_info.unknown = IVAL(blob.data, 0x24); + break; + + case SMB2_GETINFO_FILE_SIZE_INFO: + if (blob.length != 0x18) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->size_info.alloc_size = BVAL(blob.data, 0x00); + io->size_info.size = BVAL(blob.data, 0x08); + io->size_info.nlink = IVAL(blob.data, 0x10); + io->size_info.unknown = IVAL(blob.data, 0x14); + break; + + case SMB2_GETINFO_FILE_06: + if (blob.length != 0x8) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->unknown06.unknown1 = IVAL(blob.data, 0x00); + io->unknown06.unknown2 = IVAL(blob.data, 0x04); + break; + + case SMB2_GETINFO_FILE_EA_SIZE: + if (blob.length != 0x4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->ea_size.ea_size = IVAL(blob.data, 0x00); + break; + + case SMB2_GETINFO_FILE_ACCESS_INFO: + if (blob.length != 0x4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->access_info.access_mask = IVAL(blob.data, 0x00); + break; + + case SMB2_GETINFO_FILE_0E: + if (blob.length != 0x8) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->unknown0e.unknown1 = IVAL(blob.data, 0x00); + io->unknown0e.unknown2 = IVAL(blob.data, 0x04); + break; + + case SMB2_GETINFO_FILE_ALL_EAS: + return ea_pull_list(&blob, mem_ctx, + &io->all_eas.eas.num_eas, + &io->all_eas.eas.eas); + + case SMB2_GETINFO_FILE_10: + if (blob.length != 0x4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->unknown10.unknown = IVAL(blob.data, 0x00); + break; + + case SMB2_GETINFO_FILE_11: + if (blob.length != 0x4) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->unknown11.unknown = IVAL(blob.data, 0x00); + break; + + case SMB2_GETINFO_FILE_ALL_INFO: { + uint32_t nlen; + ssize_t size; + void *vstr; + if (blob.length != 0x60) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + io->all_info.create_time = smbcli_pull_nttime(blob.data, 0x00); + io->all_info.access_time = smbcli_pull_nttime(blob.data, 0x08); + io->all_info.write_time = smbcli_pull_nttime(blob.data, 0x10); + io->all_info.change_time = smbcli_pull_nttime(blob.data, 0x18); + io->all_info.file_attr = IVAL(blob.data, 0x20); + io->all_info.unknown1 = IVAL(blob.data, 0x24); + io->all_info.alloc_size = BVAL(blob.data, 0x28); + io->all_info.size = BVAL(blob.data, 0x30); + io->all_info.nlink = IVAL(blob.data, 0x38); + io->all_info.unknown2 = IVAL(blob.data, 0x3C); + io->all_info.unknown3 = IVAL(blob.data, 0x40); + io->all_info.unknown4 = IVAL(blob.data, 0x44); + io->all_info.ea_size = IVAL(blob.data, 0x48); + io->all_info.access_mask = IVAL(blob.data, 0x4C); + io->all_info.unknown5 = BVAL(blob.data, 0x50); + io->all_info.unknown6 = BVAL(blob.data, 0x58); + nlen = IVAL(blob.data, 0x5C); + if (nlen > blob.length - 0x60) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + blob.data+0x60, nlen, &vstr); + if (size == -1) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + io->all_info.fname = vstr; + break; + } + + default: + return NT_STATUS_INVALID_INFO_CLASS; + } + + return NT_STATUS_OK; +} + + +/* + recv a getinfo reply and parse the level info +*/ +NTSTATUS smb2_getinfo_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + uint16_t level, union smb2_fileinfo *io) +{ + struct smb2_getinfo b; + NTSTATUS status; + + status = smb2_getinfo_recv(req, mem_ctx, &b); + NT_STATUS_NOT_OK_RETURN(status); + + status = smb2_getinfo_parse(mem_ctx, level, b.out.blob, io); + data_blob_free(&b.out.blob); + + return status; +} + -- cgit