Re: [PATCH] smbinfo: Add more File*Information classes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



An additional minor patch to add help text for the most important of
the newly added info classes (fileallinfo).

See attached.

Also (minor/trivial point) note that in Ronnie's patch, there is a
little bit of extra whitespace.

On Tue, Jan 29, 2019 at 12:54 AM Ronnie Sahlberg <lsahlber@xxxxxxxxxx> wrote:
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx>
> ---
>  smbinfo.c   | 483 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  smbinfo.rst |  34 ++++-
>  2 files changed, 497 insertions(+), 20 deletions(-)
>
> diff --git a/smbinfo.c b/smbinfo.c
> index b1c129b..de9ebf6 100644
> --- a/smbinfo.c
> +++ b/smbinfo.c
> @@ -66,6 +66,447 @@ usage(char *name)
>  }
>
>  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)
> +{
> +        while (bs->string) {
> +               if (mask & bs->bit)
> +                    printf("%s ", bs->string);
> +                bs++;
> +        }
> +}
> +
> +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
> +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;
> @@ -152,10 +593,13 @@ print_sd(uint8_t *sd)
>          }
>  }
>
> -void secdesc(int f) {
> +static void
> +secdesc(int f)
> +{
>          struct smb_query_info *qi;
>
>          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 */
> @@ -167,13 +611,7 @@ void secdesc(int f) {
>          }
>
>          print_sd((uint8_t *)(&qi[1]));
> -}
> -
> -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;
> +       free(qi);
>  }
>
>  static void
> @@ -236,7 +674,9 @@ print_quota(unsigned char *sd)
>          }
>  }
>
> -void quota(int f) {
> +static void
> +quota(int f)
> +{
>          struct smb_query_info *qi;
>          char *buf;
>          int i;
> @@ -264,6 +704,7 @@ void quota(int f) {
>          }
>
>          print_quota((unsigned char *)(&qi[1]));
> +       free(qi);
>  }
>
>  int main(int argc, char *argv[])
> @@ -290,11 +731,29 @@ int main(int argc, char *argv[])
>          }
>
>
> -        if (!strcmp(argv[1], "secdesc")) {
> +        if (!strcmp(argv[1], "fileaccessinfo"))
> +                fileaccessinfo(f);
> +        else if (!strcmp(argv[1], "filealigninfo"))
> +                filealigninfo(f);
> +        else if (!strcmp(argv[1], "fileallinfo"))
> +                fileallinfo(f);
> +        else if (!strcmp(argv[1], "filebasicinfo"))
> +                filebasicinfo(f);
> +        else if (!strcmp(argv[1], "fileeainfo"))
> +                fileeainfo(f);
> +        else if (!strcmp(argv[1], "fileinternalinfo"))
> +                fileinternalinfo(f);
> +        else if (!strcmp(argv[1], "filemodeinfo"))
> +                filemodeinfo(f);
> +        else if (!strcmp(argv[1], "filepositioninfo"))
> +                filepositioninfo(f);
> +        else if (!strcmp(argv[1], "filestandardinfo"))
> +                filestandardinfo(f);
> +        else if (!strcmp(argv[1], "secdesc"))
>                  secdesc(f);
> -        } else if (!strcmp(argv[1], "quota")) {
> +        else if (!strcmp(argv[1], "quota"))
>                  quota(f);
> -        } else {
> +        else {
>                  fprintf(stderr, "Unknown command %s\n", argv[optind]);
>                  exit(1);
>          }
> diff --git a/smbinfo.rst b/smbinfo.rst
> index e37c709..2119f93 100644
> --- a/smbinfo.rst
> +++ b/smbinfo.rst
> @@ -39,14 +39,23 @@ OPTIONS
>  COMMAND
>  *******
>
> -`secdesc`: Print the security descriptor in the form
> -- Revision
> -- Control
> -- Owner SID
> -- Group SID
> -- ACL
> -- File types
> -- File flags
> +`fileaccessinfo`: Prints the FileAccessInformation class
> +
> +`filealigninfo`: Prints the FileAlignmentInformation class
> +
> +`fileallinfo`: Prints the FileAllInformation class
> +
> +`filebasicinfo`: Prints the FileBasicInformation class
> +
> +`fileeainfo`: Prints the FileEaInformation class
> +
> +`fileinternalinfo`: Prints the FileInternalInformation class
> +
> +`filemodeinfo`: Prints the FileModeInformation class
> +
> +`filepositioninfo`: Prints the FilePositionInformation class
> +
> +`filestandardinfo`: Prints the FileStandardInformation class
>
>  `quota`: Print the quota for the volume in the form
>  - SID Length
> @@ -56,6 +65,15 @@ COMMAND
>  - Quota Limit
>  - SID
>
> +`secdesc`: Print the security descriptor in the form
> +- Revision
> +- Control
> +- Owner SID
> +- Group SID
> +- ACL
> +- File types
> +- File flags
> +
>  *****
>  NOTES
>  *****
> --
> 2.13.6
>


-- 
Thanks,

Steve
From 34afd492b3030002bc93b5505dd0df358dce1e69 Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@xxxxxxxxxxxxx>
Date: Tue, 29 Jan 2019 07:03:01 -0600
Subject: [PATCH] smbinfo: update help text

Add description for fileallinfo query option.

Note that there are eight other recently added query options, but they
are mostly a subset a "fileallinfo" so could be of little value
(and may even be very confusing if we documented all nine in the
help text in smbinfo, instead of just this one).  The man page
has a full description of them.

Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
---
 smbinfo.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/smbinfo.c b/smbinfo.c
index de9ebf6..a5a0041 100644
--- a/smbinfo.c
+++ b/smbinfo.c
@@ -57,6 +57,8 @@ usage(char *name)
 {
         fprintf(stderr, "Usage: %s <command> <file>\n"
                 "Commands are\n"
+		"  fileallinfo:\n"
+		"      Prints common metadata associated with a file.\n"
                 "  secdesc:\n"
                 "      Prints the security descriptor for a cifs file.\n"
                 "  quota:\n"
-- 
2.17.1


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux