summaryrefslogtreecommitdiff
path: root/smbinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'smbinfo.c')
-rw-r--r--smbinfo.c1296
1 files changed, 0 insertions, 1296 deletions
diff --git a/smbinfo.c b/smbinfo.c
deleted file mode 100644
index 636f1bd..0000000
--- a/smbinfo.c
+++ /dev/null
@@ -1,1296 +0,0 @@
-/*
- * smbinfo
- *
- * Copyright (C) Ronnie Sahlberg (lsahlberg@redhat.com) 2018
- * Copyright (C) Aurelien Aptel (aaptel@suse.com) 2018
- *
- * Display SMB-specific file information using cifs IOCTL
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include <endian.h>
-#include <errno.h>
-#include <getopt.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#define CIFS_IOCTL_MAGIC 0xCF
-
-/* query_info flags */
-#define PASSTHRU_QUERY_INFO 0x00000000
-#define PASSTHRU_FSCTL 0x00000001
-
-struct smb_query_info {
- uint32_t info_type;
- uint32_t file_info_class;
- uint32_t additional_information;
- uint32_t flags;
- uint32_t input_buffer_length;
- uint32_t output_buffer_length;
- /* char buffer[]; */
-} __packed;
-
-#define SMB3_SIGN_KEY_SIZE 16
-struct smb3_key_debug_info {
- uint64_t Suid;
- uint16_t cipher_type;
- uint8_t auth_key[16]; /* SMB2_NTLMV2_SESSKEY_SIZE */
- uint8_t smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
- uint8_t smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
-} __attribute__((packed));
-
-#define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info)
-#define CIFS_DUMP_KEY _IOWR(CIFS_IOCTL_MAGIC, 8, struct smb3_key_debug_info)
-#define INPUT_BUFFER_LENGTH 16384
-
-int verbose;
-
-static void
-usage(char *name)
-{
- fprintf(stderr, "Usage: %s [-V] <command> <file>\n"
- "-V for verbose output\n"
- "-h display this help text\n"
- "-v print smbinfo version\n"
- "Commands are\n"
- " fileaccessinfo:\n"
- " Prints FileAccessInfo for a cifs file.\n"
- " filealigninfo:\n"
- " Prints FileAlignInfo for a cifs file.\n"
- " fileallinfo:\n"
- " Prints FileAllInfo for a cifs file.\n"
- " filebasicinfo:\n"
- " Prints FileBasicInfo for a cifs file.\n"
- " fileeainfo:\n"
- " Prints FileEAInfo for a cifs file.\n"
- " filefsfullsizeinfo:\n"
- " Prints FileFsFullSizeInfo for a cifs share.\n"
- " fileinternalinfo:\n"
- " Prints FileInternalInfo for a cifs file.\n"
- " filemodeinfo:\n"
- " Prints FileModeInfo for a cifs file.\n"
- " filepositioninfo:\n"
- " Prints FilePositionInfo for a cifs file.\n"
- " filestandardinfo:\n"
- " Prints FileStandardInfo for a cifs file.\n"
- " fsctl-getobjid:\n"
- " Prints the objectid of the file and GUID of the underlying volume.\n"
- " getcompression:\n"
- " Prints the compression setting for the file.\n"
- " setcompression <no|default|lznt1>:\n"
- " Sets the compression level for the file.\n"
- " list-snapshots:\n"
- " List the previous versions of the volume that backs this file.\n"
- " quota:\n"
- " Prints the quota for a cifs file.\n"
- " secdesc:\n"
- " Prints the security descriptor for a cifs file.\n"
- " keys:\n"
- " Prints the decryption information needed to view encrypted network traces.\n",
- name);
- exit(1);
-}
-
-static void
-short_usage(char *name)
-{
- fprintf(stderr, "Usage: %s [-v] [-V] <command> <file>\n"
- "Try 'smbinfo -h' for more information.\n", name);
- exit(1);
-}
-
-static void
-win_to_timeval(uint64_t smb2_time, struct timeval *tv)
-{
- tv->tv_usec = (smb2_time / 10) % 1000000;
- tv->tv_sec = (smb2_time - 116444736000000000) / 10000000;
-}
-
-struct bit_string {
- unsigned int bit;
- char *string;
-};
-
-struct bit_string directory_access_mask[] = {
- { 0x00000001, "LIST_DIRECTORY" },
- { 0x00000002, "ADD_FILE" },
- { 0x00000004, "ADD_SUBDIRECTORY" },
- { 0x00000008, "READ_EA" },
- { 0x00000010, "WRITE_EA" },
- { 0x00000020, "TRAVERSE" },
- { 0x00000040, "DELETE_CHILD" },
- { 0x00000080, "READ_ATTRIBUTES" },
- { 0x00000100, "WRITE_ATTRIBUTES" },
- { 0x00010000, "DELETE" },
- { 0x00020000, "READ_CONTROL" },
- { 0x00040000, "WRITE_DAC" },
- { 0x00080000, "WRITE_OWNER" },
- { 0x00100000, "SYNCHRONIZER" },
- { 0x01000000, "ACCESS_SYSTEM_SECURITY" },
- { 0x02000000, "MAXIMUM_ALLOWED" },
- { 0x10000000, "GENERIC_ALL" },
- { 0x20000000, "GENERIC_EXECUTE" },
- { 0x40000000, "GENERIC_WRITE" },
- { 0x80000000, "GENERIC_READ" },
- { 0, NULL }
-};
-
-struct bit_string file_access_mask[] = {
- { 0x00000001, "READ_DATA" },
- { 0x00000002, "WRITE_DATA" },
- { 0x00000004, "APPEND_DATA" },
- { 0x00000008, "READ_EA" },
- { 0x00000010, "WRITE_EA" },
- { 0x00000020, "EXECUTE" },
- { 0x00000040, "DELETE_CHILD" },
- { 0x00000080, "READ_ATTRIBUTES" },
- { 0x00000100, "WRITE_ATTRIBUTES" },
- { 0x00010000, "DELETE" },
- { 0x00020000, "READ_CONTROL" },
- { 0x00040000, "WRITE_DAC" },
- { 0x00080000, "WRITE_OWNER" },
- { 0x00100000, "SYNCHRONIZER" },
- { 0x01000000, "ACCESS_SYSTEM_SECURITY" },
- { 0x02000000, "MAXIMUM_ALLOWED" },
- { 0x10000000, "GENERIC_ALL" },
- { 0x20000000, "GENERIC_EXECUTE" },
- { 0x40000000, "GENERIC_WRITE" },
- { 0x80000000, "GENERIC_READ" },
- { 0, NULL }
-};
-
-static void
-print_bits(uint32_t mask, struct bit_string *bs)
-{
- int first = 1;
-
- if (!verbose)
- return;
-
- while (bs->string) {
- if (mask & bs->bit) {
- printf("%s%s", first?"":",", bs->string);
- first = 0;
- }
- bs++;
- }
- if (!first)
- printf(" ");
-}
-
-static void
-print_guid(uint8_t *sd)
-{
- uint32_t u32;
- uint16_t u16;
- int i;
-
- memcpy(&u32, &sd[0], 4);
- printf("%08x-", le32toh(u32));
-
- memcpy(&u16, &sd[4], 2);
- printf("%04x-", le16toh(u16));
-
- memcpy(&u16, &sd[6], 2);
- printf("%04x-", le16toh(u16));
-
- printf("%02x%02x-", sd[8], sd[9]);
- for (i = 0; i < 6; i++)
- printf("%02x", sd[10 + i]);
-}
-
-static void
-print_objidbuf(uint8_t *sd)
-{
- printf("Object-ID: ");
- print_guid(&sd[0]);
- printf("\n");
-
- printf("Birth-Volume-ID: ");
- print_guid(&sd[16]);
- printf("\n");
-
- printf("Birth-Object-ID: ");
- print_guid(&sd[32]);
- printf("\n");
-
- printf("Domain-ID: ");
- print_guid(&sd[48]);
- printf("\n");
-}
-
-static void
-fsctlgetobjid(int f)
-{
- struct smb_query_info *qi;
- struct stat st;
-
- fstat(f, &st);
-
- qi = malloc(sizeof(struct smb_query_info) + 64);
- memset(qi, 0, sizeof(qi) + 64);
- qi->info_type = 0x9009c;
- qi->file_info_class = 0;
- qi->additional_information = 0;
- qi->input_buffer_length = 64;
- qi->flags = PASSTHRU_FSCTL;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
- print_objidbuf((uint8_t *)(&qi[1]));
-
- free(qi);
-}
-
-static void
-print_getcompression(uint8_t *sd)
-{
- uint16_t u16;
-
- memcpy(&u16, &sd[0], 2);
- u16 = le16toh(u16);
-
- printf("Compression: ");
- switch (u16) {
- case 0:
- printf("(0) NONE\n");
- break;
- case 2:
- printf("(2) LZNT1\n");
- break;
- default:
- printf("(%d) UNKNOWN\n", u16);
- break;
- }
-}
-
-static void
-getcompression(int f)
-{
- struct smb_query_info *qi;
-
- qi = malloc(sizeof(struct smb_query_info) + 2);
- memset(qi, 0, sizeof(qi) + 2);
- qi->info_type = 0x9003c;
- qi->file_info_class = 0;
- qi->additional_information = 0;
- qi->input_buffer_length = 2;
- qi->flags = PASSTHRU_FSCTL;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
- print_getcompression((uint8_t *)(&qi[1]));
-
- free(qi);
-}
-
-static void
-setcompression(int f, uint16_t level)
-{
- struct smb_query_info *qi;
-
- qi = malloc(sizeof(struct smb_query_info) + 2);
- memset(qi, 0, sizeof(qi) + 2);
- qi->info_type = 0x9c040;
- qi->file_info_class = 0;
- qi->additional_information = 0;
- qi->output_buffer_length = 2;
- qi->flags = PASSTHRU_FSCTL;
-
- level = htole16(level);
- memcpy(&qi[1], &level, 2);
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- free(qi);
-}
-
-static void
-print_fileaccessinfo(uint8_t *sd, int type)
-{
- uint32_t access_flags;
-
- memcpy(&access_flags, &sd[0], 4);
- access_flags = le32toh(access_flags);
-
- if (type == S_IFDIR) {
- printf("Directory access flags 0x%08x: ", access_flags);
- print_bits(access_flags, directory_access_mask);
- } else {
- printf("File/Printer access flags 0x%08x: ", access_flags);
- print_bits(access_flags, file_access_mask);
- }
- printf("\n");
-}
-
-static void
-fileaccessinfo(int f)
-{
- struct smb_query_info *qi;
- struct stat st;
-
- fstat(f, &st);
-
- qi = malloc(sizeof(struct smb_query_info) + 4);
- memset(qi, 0, sizeof(qi) + 4);
- qi->info_type = 0x01;
- qi->file_info_class = 8;
- qi->additional_information = 0;
- qi->input_buffer_length = 4;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_fileaccessinfo((uint8_t *)(&qi[1]), st.st_mode & S_IFMT);
- free(qi);
-}
-
-static void
-print_filealigninfo(uint8_t *sd)
-{
- uint32_t mask;
-
- memcpy(&mask, &sd[0], 4);
- mask = le32toh(mask);
-
- printf("File alignment: ");
- if (mask == 0)
- printf("BYTE_ALIGNMENT");
- else if (mask == 1)
- printf("WORD_ALIGNMENT");
- else if (mask == 3)
- printf("LONG_ALIGNMENT");
- else if (mask == 7)
- printf("QUAD_ALIGNMENT");
- else if (mask == 15)
- printf("OCTA_ALIGNMENT");
- else if (mask == 31)
- printf("32_bit_ALIGNMENT");
- else if (mask == 63)
- printf("64_bit_ALIGNMENT");
- else if (mask == 127)
- printf("128_bit_ALIGNMENT");
- else if (mask == 255)
- printf("254_bit_ALIGNMENT");
- else if (mask == 511)
- printf("512_bit_ALIGNMENT");
-
- printf("\n");
-}
-
-static void
-filealigninfo(int f)
-{
- struct smb_query_info *qi;
-
- qi = malloc(sizeof(struct smb_query_info) + 4);
- memset(qi, 0, sizeof(qi) + 4);
- qi->info_type = 0x01;
- qi->file_info_class = 17;
- qi->additional_information = 0;
- qi->input_buffer_length = 4;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_filealigninfo((uint8_t *)(&qi[1]));
- free(qi);
-}
-
-struct bit_string file_attributes_mask[] = {
- { 0x00000001, "READ_ONLY" },
- { 0x00000002, "HIDDEN" },
- { 0x00000004, "SYSTEM" },
- { 0x00000010, "DIRECTORY" },
- { 0x00000020, "ARCHIVE" },
- { 0x00000080, "NORMAL" },
- { 0x00000100, "TEMPORARY" },
- { 0x00000200, "SPARSE_FILE" },
- { 0x00000400, "REPARSE_POINT" },
- { 0x00000800, "COMPRESSED" },
- { 0x00001000, "OFFLINE" },
- { 0x00002000, "NOT_CONTENT_INDEXED" },
- { 0x00004000, "ENCRYPTED" },
- { 0x00008000, "INTEGRITY_STREAM" },
- { 0x00020000, "NO_SCRUB_DATA" },
- { 0, NULL }
-};
-
-static void
-print_filebasicinfo(uint8_t *sd)
-{
- struct timeval tv;
- uint64_t u64;
- uint32_t u32;
-
- memcpy(&u64, &sd[0], 8);
- win_to_timeval(le64toh(u64), &tv);
- printf("Creation Time %s", ctime(&tv.tv_sec));
-
- memcpy(&u64, &sd[8], 8);
- win_to_timeval(le64toh(u64), &tv);
- printf("Last Access Time %s", ctime(&tv.tv_sec));
-
- memcpy(&u64, &sd[16], 8);
- win_to_timeval(le64toh(u64), &tv);
- printf("Last Write Time %s", ctime(&tv.tv_sec));
-
- memcpy(&u64, &sd[24], 8);
- win_to_timeval(le64toh(u64), &tv);
- printf("Last Change Time %s", ctime(&tv.tv_sec));
-
- memcpy(&u32, &sd[32], 4);
- u32 = le32toh(u32);
- printf("File Attributes 0x%08x: ", u32);
- print_bits(u32, file_attributes_mask);
- printf("\n");
-}
-
-static void
-filebasicinfo(int f)
-{
- struct smb_query_info *qi;
-
- qi = malloc(sizeof(struct smb_query_info) + 40);
- memset(qi, 0, sizeof(qi) + 40);
- qi->info_type = 0x01;
- qi->file_info_class = 4;
- qi->additional_information = 0;
- qi->input_buffer_length = 40;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_filebasicinfo((uint8_t *)(&qi[1]));
- free(qi);
-}
-
-static void
-print_filestandardinfo(uint8_t *sd)
-{
- uint64_t u64;
- uint32_t u32;
-
- memcpy(&u64, &sd[0], 8);
- printf("Allocation Size %" PRIu64 "\n", le64toh(u64));
-
- memcpy(&u64, &sd[8], 8);
- printf("End Of File %" PRIu64 "\n", le64toh(u64));
-
- memcpy(&u32, &sd[16], 4);
- printf("Number Of Links %" PRIu32 "\n", le32toh(u32));
-
- printf("Delete Pending %d\n", sd[20]);
- printf("Delete Directory %d\n", sd[21]);
-}
-
-static void
-filestandardinfo(int f)
-{
- struct smb_query_info *qi;
-
- qi = malloc(sizeof(struct smb_query_info) + 24);
- memset(qi, 0, sizeof(qi) + 24);
- qi->info_type = 0x01;
- qi->file_info_class = 5;
- qi->additional_information = 0;
- qi->input_buffer_length = 24;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_filestandardinfo((uint8_t *)(&qi[1]));
- free(qi);
-}
-
-static void
-print_fileinternalinfo(uint8_t *sd)
-{
- uint64_t u64;
-
- memcpy(&u64, &sd[0], 8);
- printf("Index Number %" PRIu64 "\n", le64toh(u64));
-}
-
-static void
-fileinternalinfo(int f)
-{
- struct smb_query_info *qi;
-
- qi = malloc(sizeof(struct smb_query_info) + 8);
- memset(qi, 0, sizeof(qi) + 8);
- qi->info_type = 0x01;
- qi->file_info_class = 6;
- qi->additional_information = 0;
- qi->input_buffer_length = 8;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_fileinternalinfo((uint8_t *)(&qi[1]));
- free(qi);
-}
-
-struct bit_string file_mode_mask[] = {
- { 0x00000002, "WRITE_THROUGH" },
- { 0x00000004, "SEQUENTIAL_ONLY" },
- { 0x00000008, "NO_INTERMEDIATE_BUFFERING" },
- { 0x00000010, "SYNCHRONOUS_IO_ALERT" },
- { 0x00000020, "SYNCHRONOUS_IO_NONALERT" },
- { 0x00001000, "DELETE_ON_CLOSE" },
- { 0, NULL }
-};
-
-static void
-print_filemodeinfo(uint8_t *sd)
-{
- uint32_t u32;
-
- memcpy(&u32, &sd[32], 4);
- u32 = le32toh(u32);
- printf("Mode 0x%08x: ", u32);
- print_bits(u32, file_mode_mask);
- printf("\n");
-}
-
-static void
-filemodeinfo(int f)
-{
- struct smb_query_info *qi;
-
- qi = malloc(sizeof(struct smb_query_info) + 4);
- memset(qi, 0, sizeof(qi) + 4);
- qi->info_type = 0x01;
- qi->file_info_class = 16;
- qi->additional_information = 0;
- qi->input_buffer_length = 4;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_filemodeinfo((uint8_t *)(&qi[1]));
- free(qi);
-}
-
-static void
-print_filepositioninfo(uint8_t *sd)
-{
- uint64_t u64;
-
- memcpy(&u64, &sd[0], 8);
- printf("Current Byte Offset %" PRIu64 "\n", le64toh(u64));
-}
-
-static void
-filepositioninfo(int f)
-{
- struct smb_query_info *qi;
-
- qi = malloc(sizeof(struct smb_query_info) + 8);
- memset(qi, 0, sizeof(qi) + 8);
- qi->info_type = 0x01;
- qi->file_info_class = 14;
- qi->additional_information = 0;
- qi->input_buffer_length = 8;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_filepositioninfo((uint8_t *)(&qi[1]));
- free(qi);
-}
-
-static void
-print_fileeainfo(uint8_t *sd)
-{
- uint32_t u32;
-
- memcpy(&u32, &sd[0], 4);
- printf("Ea Size %" PRIu32 "\n", le32toh(u32));
-}
-
-static void
-fileeainfo(int f)
-{
- struct smb_query_info *qi;
-
- qi = malloc(sizeof(struct smb_query_info) + 4);
- memset(qi, 0, sizeof(qi) + 4);
- qi->info_type = 0x01;
- qi->file_info_class = 7;
- qi->additional_information = 0;
- qi->input_buffer_length = 4;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_fileeainfo((uint8_t *)(&qi[1]));
- free(qi);
-}
-
-static void
-print_filefullsizeinfo(uint8_t *sd)
-{
- uint32_t u32;
- uint64_t u64;
-
- memcpy(&u64, &sd[0], 8);
- printf("Total Allocation Units: %" PRIu64 "\n", le64toh(u64));
-
- memcpy(&u64, &sd[8], 8);
- printf("Caller Available Allocation Units: %" PRIu64 "\n",
- le64toh(u64));
-
- memcpy(&u64, &sd[16], 8);
- printf("Actual Available Allocation Units: %" PRIu64 "\n",
- le64toh(u64));
-
- memcpy(&u32, &sd[24], 4);
- printf("Sectors Per Allocation Unit: %" PRIu32 "\n", le32toh(u32));
-
- memcpy(&u32, &sd[28], 4);
- printf("Bytes Per Sector: %" PRIu32 "\n", le32toh(u32));
-}
-
-static void
-filefsfullsizeinfo(int f)
-{
- struct smb_query_info *qi;
-
- qi = malloc(sizeof(struct smb_query_info) + 32);
- memset(qi, 0, sizeof(qi) + 32);
- qi->info_type = 0x02;
- qi->file_info_class = 7;
- qi->additional_information = 0;
- qi->input_buffer_length = 32;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_filefullsizeinfo((uint8_t *)(&qi[1]));
- free(qi);
-}
-
-static void
-fileallinfo(int f)
-{
- struct smb_query_info *qi;
- struct stat st;
-
- fstat(f, &st);
-
- qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
- memset(qi, 0, sizeof(qi) + INPUT_BUFFER_LENGTH);
- qi->info_type = 0x01;
- qi->file_info_class = 18;
- qi->additional_information = 0;
- qi->input_buffer_length = INPUT_BUFFER_LENGTH;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_filebasicinfo((uint8_t *)(&qi[1]));
- print_filestandardinfo((uint8_t *)(&qi[1]) + 40);
- print_fileinternalinfo((uint8_t *)(&qi[1]) + 64);
- print_fileeainfo((uint8_t *)(&qi[1]) + 72);
- print_fileaccessinfo((uint8_t *)(&qi[1]) + 76, st.st_mode & S_IFMT);
- print_filepositioninfo((uint8_t *)(&qi[1]) + 80);
- print_filemodeinfo((uint8_t *)(&qi[1]) + 88);
- print_filealigninfo((uint8_t *)(&qi[1]) + 92);
- // SMB2 servers like Win16 does not seem to return name info
- free(qi);
-}
-
-static void
-print_sid(unsigned char *sd)
-{
- int i;
- uint32_t subauth;
- uint64_t idauth;
-
- if (sd[0] != 1) {
- fprintf(stderr, "Unknown SID revision\n");
- return;
- }
-
- idauth = 0;
- for (i = 0; i < 6; i++)
- idauth = (idauth << 8) | sd[2 + i];
-
- printf("S-1-%" PRIu64, idauth);
- for (i = 0; i < sd[1]; i++) {
- memcpy(&subauth, &sd[8 + 4 * i], 4);
- subauth = le32toh(subauth);
- printf("-%u", subauth);
- }
-}
-
-static void
-print_ace_type(uint8_t t)
-{
- switch(t) {
- case 0x00: printf("ALLOWED"); break;
- case 0x01: printf("DENIED"); break;
- case 0x02: printf("AUDIT"); break;
- case 0x03: printf("ALARM"); break;
- case 0x04: printf("ALLOWED_COMPOUND"); break;
- case 0x05: printf("ALLOWED_OBJECT"); break;
- case 0x06: printf("DENIED_OBJECT"); break;
- case 0x07: printf("AUDIT_OBJECT"); break;
- case 0x08: printf("ALARM_OBJECT"); break;
- case 0x09: printf("ALLOWED_CALLBACK"); break;
- case 0x0a: printf("DENIED_CALLBACK"); break;
- case 0x0b: printf("ALLOWED_CALLBACK_OBJECT"); break;
- case 0x0c: printf("DENIED_CALLBACK_OBJECT"); break;
- case 0x0d: printf("AUDIT_CALLBACK"); break;
- case 0x0e: printf("ALARM_CALLBACK"); break;
- case 0x0f: printf("AUDIT_CALLBACK_OBJECT"); break;
- case 0x10: printf("ALARM_CALLBACK_OBJECT"); break;
- case 0x11: printf("MANDATORY_LABEL"); break;
- case 0x12: printf("RESOURCE_ATTRIBUTE"); break;
- case 0x13: printf("SCOPED_POLICY_ID"); break;
- default: printf("<UNKNOWN>");
- }
- printf(" ");
-}
-
-struct bit_string ace_flags_mask[] = {
- { 0x80, "FAILED_ACCESS" },
- { 0x40, "SUCCESSFUL_ACCESS" },
- { 0x10, "INHERITED" },
- { 0x08, "INHERIT_ONLY" },
- { 0x04, "NO_PROPAGATE_INHERIT" },
- { 0x02, "CONTAINER_INHERIT" },
- { 0x01, "OBJECT_INHERIT" },
- { 0, NULL }
-};
-
-static void
-print_mask_sid_ace(unsigned char *sd, int type)
-{
- uint32_t u32;
-
- memcpy(&u32, &sd[0], 4);
- printf("Mask:0x%08x ", le32toh(u32));
- if (type == S_IFDIR)
- print_bits(le32toh(u32), directory_access_mask);
- else
- print_bits(le32toh(u32), file_access_mask);
- printf("SID:");
- print_sid(&sd[4]);
- printf("\n");
-}
-
-static int
-print_ace(unsigned char *sd, int type)
-{
- uint16_t size;
- int i;
-
- printf("Type:0x%02x ", sd[0]);
- if (verbose) {
- print_ace_type(sd[0]);
- }
-
- printf("Flags:0x%02x ", sd[1]);
- print_bits(sd[1], ace_flags_mask);
-
- memcpy(&size, &sd[2], 2);
- size = le16toh(size);
-
- switch (sd[0]) {
- case 0x00:
- case 0x01:
- case 0x02:
- print_mask_sid_ace(&sd[4], type);
- break;
- default:
- for (i = 0; i < size; i++)
- printf("%02x", sd[4 + i]);
- }
-
- printf("\n");
- return size;
-}
-
-static void
-print_acl(unsigned char *sd, int type)
-{
- int i, off;
- uint16_t count;
-
- if ((sd[0] != 2) && (sd[0] != 4)) {
- fprintf(stderr, "Unknown ACL revision\n");
- return;
- }
-
- memcpy(&count, &sd[4], 2);
- count = le16toh(count);
- off = 8;
- for (i = 0; i < count; i++)
- off += print_ace(&sd[off], type);
-}
-
-struct bit_string control_bits_mask[] = {
- { 0x8000, "SR" },
- { 0x4000, "RM" },
- { 0x2000, "PS" },
- { 0x1000, "PD" },
- { 0x0800, "SI" },
- { 0x0400, "DI" },
- { 0x0200, "SC" },
- { 0x0100, "DC" },
- { 0x0080, "DT" },
- { 0x0040, "SS" },
- { 0x0020, "SD" },
- { 0x0010, "SP" },
- { 0x0008, "DD" },
- { 0x0004, "DP" },
- { 0x0002, "GD" },
- { 0x0001, "OD" },
- { 0, NULL }
-};
-
-static void
-print_control(uint16_t c)
-{
- printf("Control: 0x%04x ", c);
- print_bits(c, control_bits_mask);
- printf("\n");
-}
-
-static void
-print_sd(uint8_t *sd, int type)
-{
- int offset_owner, offset_group, offset_dacl;
- uint16_t u16;
-
- printf("Revision:%d\n", sd[0]);
- if (sd[0] != 1) {
- fprintf(stderr, "Unknown SD revision\n");
- exit(1);
- }
-
- memcpy(&u16, &sd[2], 2);
- print_control(le16toh(u16));
-
- memcpy(&offset_owner, &sd[4], 4);
- offset_owner = le32toh(offset_owner);
- memcpy(&offset_group, &sd[8], 4);
- offset_group = le32toh(offset_group);
- memcpy(&offset_dacl, &sd[16], 4);
- offset_dacl = le32toh(offset_dacl);
-
- if (offset_owner) {
- printf("Owner: ");
- print_sid(&sd[offset_owner]);
- printf("\n");
- }
- if (offset_group) {
- printf("Group: ");
- print_sid(&sd[offset_group]);
- printf("\n");
- }
- if (offset_dacl) {
- printf("DACL:\n");
- print_acl(&sd[offset_dacl], type);
- }
-}
-
-static void
-secdesc(int f)
-{
- struct smb_query_info *qi;
- struct stat st;
-
- fstat(f, &st);
-
- qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
- memset(qi, 0, sizeof(qi) + INPUT_BUFFER_LENGTH);
- qi->info_type = 0x03;
- qi->file_info_class = 0;
- qi->additional_information = 0x00000007; /* Owner, Group, Dacl */
- qi->input_buffer_length = INPUT_BUFFER_LENGTH;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_sd((uint8_t *)(&qi[1]), st.st_mode & S_IFMT);
- free(qi);
-}
-
-static void
-print_quota(unsigned char *sd)
-{
- uint32_t u32, neo;
- uint64_t u64;
- struct timeval tv;
- int i, off = 0;
-
-one_more:
- memcpy(&u32, &sd[off], 4);
- neo = le32toh(u32);
-
- memcpy(&u32, &sd[off + 4], 4);
- u32 = le32toh(u32);
- printf("SID Length %d\n", u32);
-
- memcpy(&u64, &sd[off + 8], 8);
- win_to_timeval(le64toh(u64), &tv);
- printf("Change Time %s", ctime(&tv.tv_sec));
-
- memcpy(&u64, &sd[off + 16], 8);
- u64 = le32toh(u64);
- printf("Quota Used %" PRIu64 "\n", u64);
-
- memcpy(&u64, &sd[off + 24], 8);
- u64 = le64toh(u64);
- if (u64 == 0xffffffffffffffff)
- printf("Quota Threshold NO THRESHOLD\n");
- else
- printf("Quota Threshold %" PRIu64 "\n", u64);
-
- memcpy(&u64, &sd[off + 32], 8);
- u64 = le64toh(u64);
- if (u64 == 0xffffffffffffffff)
- printf("Quota Limit NO LIMIT\n");
- else
- printf("Quota Limit %" PRIu64 "\n", u64);
-
- printf("SID: S-1");
- u64 = 0;
- for (i = 0; i < 6; i++)
- u64 = (u64 << 8) | sd[off + 42 + i];
- printf("-%" PRIu64, u64);
-
- for (i = 0; i < sd[off + 41]; i++) {
- memcpy(&u32, &sd[off + 48 + 4 * i], 4);
- u32 = le32toh(u32);
- printf("-%u", u32);
- }
- printf("\n\n");
- off += neo;
-
- if (neo != 0)
- goto one_more;
-}
-
-static void
-quota(int f)
-{
- struct smb_query_info *qi;
- char *buf;
- int i;
-
- qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
- memset(qi, 0, sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
- qi->info_type = 0x04;
- qi->file_info_class = 0;
- qi->additional_information = 0; /* Owner, Group, Dacl */
- qi->input_buffer_length = INPUT_BUFFER_LENGTH;
-
- buf = (char *)&qi[1];
- buf[0] = 0; /* return single */
- buf[1] = 1; /* restart scan */
-
- /* sid list length */
- i = 0;
- memcpy(&buf[4], &i, 4);
-
- qi->output_buffer_length = 16;
-
- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_quota((unsigned char *)(&qi[1]));
- free(qi);
-}
-
-
-struct smb_snapshot_array {
- int32_t number_of_snapshots;
- int32_t number_of_snapshots_returned;
- int32_t snapshot_array_size;
- char snapshot_data[0];
-};
-
-
-#define GMT_NAME_LEN 24 /* length of a @GMT- name */
-#define GMT_FORMAT "@GMT-%Y.%m.%d-%H.%M.%S"
-
-#define NTFS_TIME_OFFSET ((unsigned long long)(369*365 + 89) * 24 * 3600 * 10000000)
-
-static void print_snapshots(struct smb_snapshot_array *psnap)
-{
- int current_snapshot_entry = 0;
- char gmt_token[GMT_NAME_LEN + 1] = {0};
- int i;
- int j = 0;
- struct tm tm;
- unsigned long long dce_time;
-
- printf("Number of snapshots: %d Number of snapshots returned: %d\n",
- psnap->number_of_snapshots,
- psnap->number_of_snapshots_returned);
- printf("Snapshot list in GMT (Coordinated UTC Time) and SMB format (100 nanosecond units needed for snapshot mounts):");
- for (i = 0; i < psnap->snapshot_array_size; i++) {
- if (psnap->snapshot_data[i] == '@') {
- j = 0;
- current_snapshot_entry++;
- printf("\n%d) GMT:", current_snapshot_entry);
- }
- if (psnap->snapshot_data[i] != 0) {
- gmt_token[j] = psnap->snapshot_data[i];
- j++;
- }
- if (j == GMT_NAME_LEN) {
- printf("%s", gmt_token);
- j = 0;
- strptime(gmt_token, GMT_FORMAT, &tm);
- dce_time = timegm(&tm) * 10000000 + NTFS_TIME_OFFSET;
- printf("\n SMB3:%llu", dce_time);
- }
- }
- printf("\n");
-}
-
-static void
-dump_keys(int f)
-{
- struct smb3_key_debug_info keys_info;
- uint8_t *psess_id;
-
- if (ioctl(f, CIFS_DUMP_KEY, &keys_info) < 0) {
- fprintf(stderr, "Querying keys information failed with %s\n", strerror(errno));
- exit(1);
- }
-
- if (keys_info.cipher_type == 1)
- printf("CCM encryption");
- else if (keys_info.cipher_type == 2)
- printf("GCM encryption");
- else if (keys_info.cipher_type == 0)
- printf("SMB3.0 CCM encryption");
- else
- printf("unknown encryption type");
-
- printf("\nSession Id: ");
- psess_id = (uint8_t *)&keys_info.Suid;
- for (int i = 0; i < 8; i++)
- printf(" %02x", psess_id[i]);
-
- printf("\nSession Key: ");
- for (int i = 0; i < 16; i++)
- printf(" %02x", keys_info.auth_key[i]);
- printf("\nServer Encryption Key: ");
- for (int i = 0; i < SMB3_SIGN_KEY_SIZE; i++)
- printf(" %02x", keys_info.smb3encryptionkey[i]);
- printf("\nServer Decryption Key: ");
- for (int i = 0; i < SMB3_SIGN_KEY_SIZE; i++)
- printf(" %02x", keys_info.smb3decryptionkey[i]);
- printf("\n");
-}
-
-#define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array)
-
-#define MIN_SNAPSHOT_ARRAY_SIZE 16 /* See MS-SMB2 section 3.3.5.15.1 */
-
-static void
-list_snapshots(int f)
-{
-
- struct smb_snapshot_array snap_inf;
- struct smb_snapshot_array *buf;
-
- /*
- * When first field in structure we pass in here is zero, cifs.ko can
- * recognize that this is the first query and that it must set the SMB3
- * FSCTL response buffer size (in the request) to exactly 16 bytes
- * (which is required by some servers to process the initial query)
- */
- snap_inf.number_of_snapshots = 0;
- snap_inf.number_of_snapshots_returned = 0;
- snap_inf.snapshot_array_size = sizeof(struct smb_snapshot_array);
-
- /* Query the number of snapshots so we know how much to allocate */
- if (ioctl(f, CIFS_ENUMERATE_SNAPSHOTS, &snap_inf) < 0) {
- fprintf(stderr, "Querying snapshots failed with %s\n", strerror(errno));
- exit(1);
- }
-
- if (snap_inf.number_of_snapshots == 0)
- return;
-
- /* Now that we know the size, query the list from the server */
-
- buf = malloc(snap_inf.snapshot_array_size + MIN_SNAPSHOT_ARRAY_SIZE);
-
- if (buf == NULL) {
- printf("Failed, out of memory.\n");
- exit(1);
- }
- /*
- * first parm is non-zero which allows cifs.ko to recognize that this is
- * the second query (it has to set response buf size larger)
- */
- buf->number_of_snapshots = snap_inf.number_of_snapshots;
-
- buf->snapshot_array_size = snap_inf.snapshot_array_size;
-
- if (ioctl(f, CIFS_ENUMERATE_SNAPSHOTS, buf) < 0) {
- fprintf(stderr, "Querying snapshots failed with %s\n", strerror(errno));
- exit(1);
- }
-
- print_snapshots(buf);
- free(buf);
-}
-
-static int
-parse_compression(const char *arg)
-{
- if (!strcmp(arg, "no"))
- return 0;
- else if (!strcmp(arg, "default"))
- return 1;
- else if (!strcmp(arg, "lznt1"))
- return 2;
-
- fprintf(stderr, "compression must be no|default|lznt1\n");
- exit(10);
-}
-
-int main(int argc, char *argv[])
-{
- int c;
- int f;
- int compression = 1;
-
- if (argc < 2) {
- short_usage(argv[0]);
- }
-
- while ((c = getopt_long(argc, argv, "c:vVh", NULL, NULL)) != -1) {
- switch (c) {
- case 'c':
- compression = parse_compression(optarg);
- break;
- case 'v':
- printf("smbinfo version %s\n", VERSION);
- return 0;
- case 'V':
- verbose = 1;
- break;
- case 'h':
- usage(argv[0]);
- break;
- default:
- short_usage(argv[0]);
- }
- }
-
- if (optind >= argc -1)
- short_usage(argv[0]);
-
- if ((f = open(argv[optind + 1 ], O_RDONLY)) < 0) {
- fprintf(stderr, "Failed to open %s\n", argv[optind + 1]);
- exit(1);
- }
-
- if (!strcmp(argv[optind], "fileaccessinfo"))
- fileaccessinfo(f);
- else if (!strcmp(argv[optind], "filealigninfo"))
- filealigninfo(f);
- else if (!strcmp(argv[optind], "fileallinfo"))
- fileallinfo(f);
- else if (!strcmp(argv[optind], "filebasicinfo"))
- filebasicinfo(f);
- else if (!strcmp(argv[optind], "fileeainfo"))
- fileeainfo(f);
- else if (!strcmp(argv[optind], "filefsfullsizeinfo"))
- filefsfullsizeinfo(f);
- else if (!strcmp(argv[optind], "fileinternalinfo"))
- fileinternalinfo(f);
- else if (!strcmp(argv[optind], "filemodeinfo"))
- filemodeinfo(f);
- else if (!strcmp(argv[optind], "filepositioninfo"))
- filepositioninfo(f);
- else if (!strcmp(argv[optind], "filestandardinfo"))
- filestandardinfo(f);
- else if (!strcmp(argv[optind], "fsctl-getobjid"))
- fsctlgetobjid(f);
- else if (!strcmp(argv[opti