summaryrefslogtreecommitdiff
path: root/source4/libcli/smb2/getinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli/smb2/getinfo.c')
-rw-r--r--source4/libcli/smb2/getinfo.c142
1 files changed, 115 insertions, 27 deletions
diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c
index 9ad2b77310..7a362b24d9 100644
--- a/source4/libcli/smb2/getinfo.c
+++ b/source4/libcli/smb2/getinfo.c
@@ -113,18 +113,18 @@ NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx,
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);
+ 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.delete_pending = CVAL(blob.data, 0x14);
+ io->size_info.directory = CVAL(blob.data, 0x15);
break;
- case SMB2_GETINFO_FILE_06:
+ case SMB2_GETINFO_FILE_ID:
if (blob.length != 0x8) {
return NT_STATUS_INFO_LENGTH_MISMATCH;
}
- io->unknown06.unknown1 = IVAL(blob.data, 0x00);
- io->unknown06.unknown2 = IVAL(blob.data, 0x04);
+ io->file_id.file_id = BVAL(blob.data, 0x00);
break;
case SMB2_GETINFO_FILE_EA_SIZE:
@@ -172,37 +172,105 @@ NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx,
uint32_t nlen;
ssize_t size;
void *vstr;
- if (blob.length != 0x60) {
+ if (blob.length < 0x64) {
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) {
+ 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.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.delete_pending = CVAL(blob.data, 0x3C);
+ io->all_info.directory = CVAL(blob.data, 0x3D);
+ io->all_info.file_id = BVAL(blob.data, 0x40);
+ 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, 0x60);
+ if (nlen > blob.length - 0x64) {
return NT_STATUS_INFO_LENGTH_MISMATCH;
}
size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX,
- blob.data+0x60, nlen, &vstr);
+ blob.data+0x64, nlen, &vstr);
if (size == -1) {
return NT_STATUS_ILLEGAL_CHARACTER;
}
io->all_info.fname = vstr;
break;
}
+
+ case SMB2_GETINFO_FILE_SHORT_INFO: {
+ uint32_t nlen;
+ ssize_t size;
+ void *vstr;
+ if (blob.length < 0x04) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+ nlen = IVAL(blob.data, 0x00);
+ if (nlen > blob.length - 0x04) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+ size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX,
+ blob.data+0x04, nlen, &vstr);
+ if (size == -1) {
+ return NT_STATUS_ILLEGAL_CHARACTER;
+ }
+ io->short_info.short_name = vstr;
+ break;
+ }
+
+ case SMB2_GETINFO_FILE_STREAM_INFO:
+ return smbcli_parse_stream_info(blob, mem_ctx, &io->stream_info);
+
+ case SMB2_GETINFO_FILE_EOF_INFO:
+ if (blob.length != 0x10) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+ io->eof_info.size = BVAL(blob.data, 0x00);
+ io->eof_info.unknown = BVAL(blob.data, 0x08);
+ break;
+
+ case SMB2_GETINFO_FILE_STANDARD_INFO:
+ if (blob.length != 0x38) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+ io->standard_info.create_time = smbcli_pull_nttime(blob.data, 0x00);
+ io->standard_info.access_time = smbcli_pull_nttime(blob.data, 0x08);
+ io->standard_info.write_time = smbcli_pull_nttime(blob.data, 0x10);
+ io->standard_info.change_time = smbcli_pull_nttime(blob.data, 0x18);
+ io->standard_info.alloc_size = BVAL(blob.data, 0x20);
+ io->standard_info.size = BVAL(blob.data, 0x28);
+ io->standard_info.file_attr = IVAL(blob.data, 0x30);
+ io->standard_info.unknown = IVAL(blob.data, 0x34);
+ break;
+
+ case SMB2_GETINFO_FILE_ATTRIB_INFO:
+ if (blob.length != 0x08) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+ io->standard_info.file_attr = IVAL(blob.data, 0x00);
+ io->standard_info.unknown = IVAL(blob.data, 0x04);
+ break;
+
+ case SMB2_GETINFO_SECURITY: {
+ struct ndr_pull *ndr;
+ NTSTATUS status;
+ ndr = ndr_pull_init_blob(&blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ io->security.sd = talloc(mem_ctx, struct security_descriptor);
+ if (io->security.sd == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, io->security.sd);
+ talloc_free(ndr);
+ return status;
+ }
default:
return NT_STATUS_INVALID_INFO_CLASS;
@@ -230,3 +298,23 @@ NTSTATUS smb2_getinfo_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
return status;
}
+/*
+ level specific getinfo call
+*/
+NTSTATUS smb2_getinfo_level(struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
+ struct smb2_handle handle,
+ uint16_t level, union smb2_fileinfo *io)
+{
+ struct smb2_getinfo b;
+ struct smb2_request *req;
+
+ ZERO_STRUCT(b);
+ b.in.buffer_code = 0x29;
+ b.in.max_response_size = 0x10000;
+ b.in.handle = handle;
+ b.in.level = level;
+
+ req = smb2_getinfo_send(tree, &b);
+
+ return smb2_getinfo_level_recv(req, mem_ctx, level, io);
+}