Message ID | 20190301020558.16091-1-lsahlber@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | smbinfo: decode the ACEs | expand |
чт, 28 февр. 2019 г. в 18:12, Ronnie Sahlberg <lsahlber@redhat.com>: > > Decode the most common ACE types and provide a [-V]erbose option > to show the individual mask bits by name. > > Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> > --- > smbinfo.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- > smbinfo.rst | 5 +- > 2 files changed, 168 insertions(+), 34 deletions(-) > > diff --git a/smbinfo.c b/smbinfo.c > index 02910c6..6b63f9d 100644 > --- a/smbinfo.c > +++ b/smbinfo.c > @@ -52,10 +52,13 @@ struct smb_query_info { > #define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info) > #define INPUT_BUFFER_LENGTH 16384 > > +int verbose; > + > static void > usage(char *name) > { > - fprintf(stderr, "Usage: %s <command> <file>\n" > + fprintf(stderr, "Usage: %s [-V] <command> <file>\n" > + "-V for verbose output\n" > "Commands are\n" > " fileaccessinfo:\n" > " Prints FileAccessInfo for a cifs file.\n" > @@ -148,11 +151,22 @@ struct bit_string file_access_mask[] = { > 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 ", bs->string); > + if (mask & bs->bit) { > + printf("%s%s", first?"":",", bs->string); > + first = 0; > + } > bs++; > } > + if (!first) { > + printf(" "); > + } > } > > static void > @@ -591,17 +605,106 @@ print_sid(unsigned char *sd) > for (i = 0; i < sd[1]; i++) { > memcpy(&subauth, &sd[8 + 4 * i], 4); > subauth = le32toh(subauth); > - printf("-%d", subauth); > + printf("-%u", subauth); > } > } > > static void > -print_acl(unsigned char *sd) > +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, j, off; > - uint16_t count, size; > + int i, off; > + uint16_t count; > > - if (sd[0] != 2) { > + if ((sd[0] != 2) && (sd[0] != 4)) { > fprintf(stderr, "Unknown ACL revision\n"); > return; > } > @@ -610,22 +713,43 @@ print_acl(unsigned char *sd) > count = le16toh(count); > off = 8; > for (i = 0; i < count; i++) { > - printf("Type:%02x Flags:%02x ", sd[off], sd[off + 1]); > - memcpy(&size, &sd[off + 2], 2); > - size = le16toh(size); > + off += print_ace(&sd[off], type); > + } > +} > > - for (j = 0; j < size; j++) > - printf("%02x", sd[off + 4 + j]); > +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 } > +}; > > - off += size; > - printf("\n"); > - } > +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) > +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) { > @@ -633,7 +757,8 @@ print_sd(uint8_t *sd) > exit(1); > } > > - printf("Control: %02x%02x\n", sd[2], sd[3]); > + memcpy(&u16, &sd[2], 2); > + print_control(le16toh(u16)); > > memcpy(&offset_owner, &sd[4], 4); > offset_owner = le32toh(offset_owner); > @@ -654,7 +779,7 @@ print_sd(uint8_t *sd) > } > if (offset_dacl) { > printf("DACL:\n"); > - print_acl(&sd[offset_dacl]); > + print_acl(&sd[offset_dacl], type); > } > } > > @@ -662,6 +787,9 @@ 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); > @@ -675,7 +803,7 @@ secdesc(int f) > exit(1); > } > > - print_sd((uint8_t *)(&qi[1])); > + print_sd((uint8_t *)(&qi[1]), st.st_mode & S_IFMT); > free(qi); > } > > @@ -777,11 +905,14 @@ int main(int argc, char *argv[]) > int c; > int f; > > - while ((c = getopt_long(argc, argv, "v", NULL, NULL)) != -1) { > + while ((c = getopt_long(argc, argv, "vV", NULL, NULL)) != -1) { > switch (c) { > case 'v': > printf("smbinfo version %s\n", VERSION); > return 0; > + case 'V': > + verbose = 1; > + break; > default: > usage(argv[0]); > } > @@ -796,29 +927,29 @@ int main(int argc, char *argv[]) > } > > > - if (!strcmp(argv[1], "fileaccessinfo")) > + if (!strcmp(argv[optind], "fileaccessinfo")) > fileaccessinfo(f); > - else if (!strcmp(argv[1], "filealigninfo")) > + else if (!strcmp(argv[optind], "filealigninfo")) > filealigninfo(f); > - else if (!strcmp(argv[1], "fileallinfo")) > + else if (!strcmp(argv[optind], "fileallinfo")) > fileallinfo(f); > - else if (!strcmp(argv[1], "filebasicinfo")) > + else if (!strcmp(argv[optind], "filebasicinfo")) > filebasicinfo(f); > - else if (!strcmp(argv[1], "fileeainfo")) > + else if (!strcmp(argv[optind], "fileeainfo")) > fileeainfo(f); > - else if (!strcmp(argv[1], "filefsfullsizeinfo")) > + else if (!strcmp(argv[optind], "filefsfullsizeinfo")) > filefsfullsizeinfo(f); > - else if (!strcmp(argv[1], "fileinternalinfo")) > + else if (!strcmp(argv[optind], "fileinternalinfo")) > fileinternalinfo(f); > - else if (!strcmp(argv[1], "filemodeinfo")) > + else if (!strcmp(argv[optind], "filemodeinfo")) > filemodeinfo(f); > - else if (!strcmp(argv[1], "filepositioninfo")) > + else if (!strcmp(argv[optind], "filepositioninfo")) > filepositioninfo(f); > - else if (!strcmp(argv[1], "filestandardinfo")) > + else if (!strcmp(argv[optind], "filestandardinfo")) > filestandardinfo(f); > - else if (!strcmp(argv[1], "secdesc")) > + else if (!strcmp(argv[optind], "secdesc")) > secdesc(f); > - else if (!strcmp(argv[1], "quota")) > + else if (!strcmp(argv[optind], "quota")) > quota(f); > else { > fprintf(stderr, "Unknown command %s\n", argv[optind]); > diff --git a/smbinfo.rst b/smbinfo.rst > index 5222a71..9bfd313 100644 > --- a/smbinfo.rst > +++ b/smbinfo.rst > @@ -11,7 +11,7 @@ Userspace helper to display SMB-specific file information for the Linux SMB clie > SYNOPSIS > ******** > > - smbinfo [-v] {command} {file system object} > + smbinfo [-v] [-V] {command} {file system object} > > *********** > DESCRIPTION > @@ -35,6 +35,9 @@ OPTIONS > -v > Print version number and exit. > > +-V > + Verbose output. > + > ******* > COMMAND > ******* > -- > 2.15.1 > merged, thanks. -- Best regards, Pavel Shilovsky
diff --git a/smbinfo.c b/smbinfo.c index 02910c6..6b63f9d 100644 --- a/smbinfo.c +++ b/smbinfo.c @@ -52,10 +52,13 @@ struct smb_query_info { #define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info) #define INPUT_BUFFER_LENGTH 16384 +int verbose; + static void usage(char *name) { - fprintf(stderr, "Usage: %s <command> <file>\n" + fprintf(stderr, "Usage: %s [-V] <command> <file>\n" + "-V for verbose output\n" "Commands are\n" " fileaccessinfo:\n" " Prints FileAccessInfo for a cifs file.\n" @@ -148,11 +151,22 @@ struct bit_string file_access_mask[] = { 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 ", bs->string); + if (mask & bs->bit) { + printf("%s%s", first?"":",", bs->string); + first = 0; + } bs++; } + if (!first) { + printf(" "); + } } static void @@ -591,17 +605,106 @@ print_sid(unsigned char *sd) for (i = 0; i < sd[1]; i++) { memcpy(&subauth, &sd[8 + 4 * i], 4); subauth = le32toh(subauth); - printf("-%d", subauth); + printf("-%u", subauth); } } static void -print_acl(unsigned char *sd) +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, j, off; - uint16_t count, size; + int i, off; + uint16_t count; - if (sd[0] != 2) { + if ((sd[0] != 2) && (sd[0] != 4)) { fprintf(stderr, "Unknown ACL revision\n"); return; } @@ -610,22 +713,43 @@ print_acl(unsigned char *sd) count = le16toh(count); off = 8; for (i = 0; i < count; i++) { - printf("Type:%02x Flags:%02x ", sd[off], sd[off + 1]); - memcpy(&size, &sd[off + 2], 2); - size = le16toh(size); + off += print_ace(&sd[off], type); + } +} - for (j = 0; j < size; j++) - printf("%02x", sd[off + 4 + j]); +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 } +}; - off += size; - printf("\n"); - } +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) +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) { @@ -633,7 +757,8 @@ print_sd(uint8_t *sd) exit(1); } - printf("Control: %02x%02x\n", sd[2], sd[3]); + memcpy(&u16, &sd[2], 2); + print_control(le16toh(u16)); memcpy(&offset_owner, &sd[4], 4); offset_owner = le32toh(offset_owner); @@ -654,7 +779,7 @@ print_sd(uint8_t *sd) } if (offset_dacl) { printf("DACL:\n"); - print_acl(&sd[offset_dacl]); + print_acl(&sd[offset_dacl], type); } } @@ -662,6 +787,9 @@ 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); @@ -675,7 +803,7 @@ secdesc(int f) exit(1); } - print_sd((uint8_t *)(&qi[1])); + print_sd((uint8_t *)(&qi[1]), st.st_mode & S_IFMT); free(qi); } @@ -777,11 +905,14 @@ int main(int argc, char *argv[]) int c; int f; - while ((c = getopt_long(argc, argv, "v", NULL, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "vV", NULL, NULL)) != -1) { switch (c) { case 'v': printf("smbinfo version %s\n", VERSION); return 0; + case 'V': + verbose = 1; + break; default: usage(argv[0]); } @@ -796,29 +927,29 @@ int main(int argc, char *argv[]) } - if (!strcmp(argv[1], "fileaccessinfo")) + if (!strcmp(argv[optind], "fileaccessinfo")) fileaccessinfo(f); - else if (!strcmp(argv[1], "filealigninfo")) + else if (!strcmp(argv[optind], "filealigninfo")) filealigninfo(f); - else if (!strcmp(argv[1], "fileallinfo")) + else if (!strcmp(argv[optind], "fileallinfo")) fileallinfo(f); - else if (!strcmp(argv[1], "filebasicinfo")) + else if (!strcmp(argv[optind], "filebasicinfo")) filebasicinfo(f); - else if (!strcmp(argv[1], "fileeainfo")) + else if (!strcmp(argv[optind], "fileeainfo")) fileeainfo(f); - else if (!strcmp(argv[1], "filefsfullsizeinfo")) + else if (!strcmp(argv[optind], "filefsfullsizeinfo")) filefsfullsizeinfo(f); - else if (!strcmp(argv[1], "fileinternalinfo")) + else if (!strcmp(argv[optind], "fileinternalinfo")) fileinternalinfo(f); - else if (!strcmp(argv[1], "filemodeinfo")) + else if (!strcmp(argv[optind], "filemodeinfo")) filemodeinfo(f); - else if (!strcmp(argv[1], "filepositioninfo")) + else if (!strcmp(argv[optind], "filepositioninfo")) filepositioninfo(f); - else if (!strcmp(argv[1], "filestandardinfo")) + else if (!strcmp(argv[optind], "filestandardinfo")) filestandardinfo(f); - else if (!strcmp(argv[1], "secdesc")) + else if (!strcmp(argv[optind], "secdesc")) secdesc(f); - else if (!strcmp(argv[1], "quota")) + else if (!strcmp(argv[optind], "quota")) quota(f); else { fprintf(stderr, "Unknown command %s\n", argv[optind]); diff --git a/smbinfo.rst b/smbinfo.rst index 5222a71..9bfd313 100644 --- a/smbinfo.rst +++ b/smbinfo.rst @@ -11,7 +11,7 @@ Userspace helper to display SMB-specific file information for the Linux SMB clie SYNOPSIS ******** - smbinfo [-v] {command} {file system object} + smbinfo [-v] [-V] {command} {file system object} *********** DESCRIPTION @@ -35,6 +35,9 @@ OPTIONS -v Print version number and exit. +-V + Verbose output. + ******* COMMAND *******
Decode the most common ACE types and provide a [-V]erbose option to show the individual mask bits by name. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> --- smbinfo.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- smbinfo.rst | 5 +- 2 files changed, 168 insertions(+), 34 deletions(-)