From bd57946148b82afe7c3e73b6d1ba7a5b8f73f36e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 16 Apr 2015 13:31:16 +0200 Subject: [PATCH] Add output of effective rights to getfacl * getfacl.c (usage): Align more closely to Linux version. Add new options -c, -e, -E. Change formatting to accommodate longer options. (longopts): Rename --noname to --numeric. Keep --noname for backward compatibility. Add --omit-header, --all-effective and --no-effective options. (opts): Add -c, -e and -E option. (main): Handle new -c, -e, and -E options. Signed-off-by: Corinna Vinschen --- winsup/doc/ChangeLog | 4 + winsup/doc/utils.xml | 13 +-- winsup/utils/ChangeLog | 10 +++ winsup/utils/getfacl.c | 185 ++++++++++++++++++++++++++++------------- 4 files changed, 147 insertions(+), 65 deletions(-) diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog index a0507a4c6..05cf5199a 100644 --- a/winsup/doc/ChangeLog +++ b/winsup/doc/ChangeLog @@ -1,3 +1,7 @@ +2015-04-16 Corinna Vinschen + + * utils.xml (getfacl): Show new option output. + 2015-04-10 Corinna Vinschen * new-features.xml (ov-new2.0): Rename from ov-new1.7.36 and change diff --git a/winsup/doc/utils.xml b/winsup/doc/utils.xml index adafc2b7d..d711cf242 100644 --- a/winsup/doc/utils.xml +++ b/winsup/doc/utils.xml @@ -519,11 +519,14 @@ Usage: getfacl [-adn] FILE [FILE2...] Display file and directory access control lists (ACLs). - -a, --access display the file access control list - -d, --default display the default access control list - -h, --help print help explaining the command line options - -n, --noname display user and group IDs instead of names - -V, --version output version information and exit + -a, --access display the file access control list only + -d, --default display the default access control list only + -c, --omit-header do not display the comment header + -e, --all-effective print all effective rights + -E, --no-effective print no effective rights + -n, --numeric print numeric user/group identifiers + -V, --version print version and exit + -h, --help this help text When multiple files are specified on the command line, a blank line separates the ACLs for each file. diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog index ef6d32e7d..5e7025da6 100644 --- a/winsup/utils/ChangeLog +++ b/winsup/utils/ChangeLog @@ -1,3 +1,13 @@ +2015-04-16 Corinna Vinschen + + * getfacl.c (usage): Align more closely to Linux version. Add new + options -c, -e, -E. Change formatting to accommodate longer options. + (longopts): Rename --noname to --numeric. Keep --noname for backward + compatibility. Add --omit-header, --all-effective and --no-effective + options. + (opts): Add -c, -e and -E option. + (main): Handle new -c, -e, and -E options. + 2015-02-28 Corinna Vinschen * getfacl.c (usage): Change --all to --access, --dir to --default. diff --git a/winsup/utils/getfacl.c b/winsup/utils/getfacl.c index 0bc484877..07d8a8a9f 100644 --- a/winsup/utils/getfacl.c +++ b/winsup/utils/getfacl.c @@ -66,61 +66,68 @@ static void usage (FILE * stream) { fprintf (stream, "Usage: %s [-adn] FILE [FILE2...]\n" - "\n" - "Display file and directory access control lists (ACLs).\n" - "\n" - " -a, --access display the file access control list\n" - " -d, --default display the default access control list\n" - " -h, --help print help explaining the command line options\n" - " -n, --noname display user and group IDs instead of names\n" - " -V, --version output version information and exit\n" - "\n" - "When multiple files are specified on the command line, a blank\n" - "line separates the ACLs for each file.\n", prog_name); + "\n" + "Display file and directory access control lists (ACLs).\n" + "\n" + " -a, --access display the file access control list only\n" + " -d, --default display the default access control list only\n" + " -c, --omit-header do not display the comment header\n" + " -e, --all-effective print all effective rights\n" + " -E, --no-effective print no effective rights\n" + " -n, --numeric print numeric user/group identifiers\n" + " -V, --version print version and exit\n" + " -h, --help this help text\n" + "\n" + "When multiple files are specified on the command line, a blank\n" + "line separates the ACLs for each file.\n", prog_name); if (stream == stdout) { fprintf (stream, "" - "For each argument that is a regular file, special file or\n" - "directory, getfacl displays the owner, the group, and the ACL.\n" - "For directories getfacl displays additionally the default ACL.\n" - "\n" - "With no options specified, getfacl displays the filename, the\n" - "owner, the group, the setuid (s), setgid (s), and sticky (t)\n" - "bits if available, and both the ACL and the default ACL, if it\n" - "exists.\n" - "\n" - "The format for ACL output is as follows:\n" - " # file: filename\n" - " # owner: name or uid\n" - " # group: name or uid\n" - " # flags: sst\n" - " user::perm\n" - " user:name or uid:perm\n" - " group::perm\n" - " group:name or gid:perm\n" - " mask:perm\n" - " other:perm\n" - " default:user::perm\n" - " default:user:name or uid:perm\n" - " default:group::perm\n" - " default:group:name or gid:perm\n" - " default:mask:perm\n" - " default:other:perm\n" - "\n"); + "For each argument that is a regular file, special file or\n" + "directory, getfacl displays the owner, the group, and the ACL.\n" + "For directories getfacl displays additionally the default ACL.\n" + "\n" + "With no options specified, getfacl displays the filename, the\n" + "owner, the group, the setuid (s), setgid (s), and sticky (t)\n" + "bits if available, and both the ACL and the default ACL, if it\n" + "exists.\n" + "\n" + "The format for ACL output is as follows:\n" + " # file: filename\n" + " # owner: name or uid\n" + " # group: name or uid\n" + " # flags: sst\n" + " user::perm\n" + " user:name or uid:perm\n" + " group::perm\n" + " group:name or gid:perm\n" + " mask:perm\n" + " other:perm\n" + " default:user::perm\n" + " default:user:name or uid:perm\n" + " default:group::perm\n" + " default:group:name or gid:perm\n" + " default:mask:perm\n" + " default:other:perm\n" + "\n"); } } struct option longopts[] = { {"access", no_argument, NULL, 'a'}, {"all", no_argument, NULL, 'a'}, + {"omit-header", no_argument, NULL, 'c'}, + {"all-effective", no_argument, NULL, 'e'}, + {"no-effective", no_argument, NULL, 'E'}, {"default", no_argument, NULL, 'd'}, {"dir", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, - {"noname", no_argument, NULL, 'n'}, + {"noname", no_argument, NULL, 'n'}, /* Backward compat */ + {"numeric", no_argument, NULL, 'n'}, {"version", no_argument, NULL, 'V'}, {0, no_argument, NULL, 0} }; -const char *opts = "adhnV"; +const char *opts = "acdeEhnV"; static void print_version () @@ -142,8 +149,11 @@ main (int argc, char **argv) int c; int ret = 0; int aopt = 0; + int copt = 0; + int eopt = 0; int dopt = 0; int nopt = 0; + int istty = isatty (fileno (stdout)); struct stat st; aclent_t acls[MAX_ACL_ENTRIES]; @@ -155,9 +165,18 @@ main (int argc, char **argv) case 'a': aopt = 1; break; + case 'c': + copt = 1; + break; case 'd': dopt = 1; break; + case 'e': + eopt = 1; + break; + case 'E': + eopt = -1; + break; case 'h': usage (stdout); return 0; @@ -179,6 +198,8 @@ main (int argc, char **argv) for (; optind < argc; ++optind) { int i, num_acls; + mode_t mask = S_IRWXO, def_mask = S_IRWXO; + if (stat (argv[optind], &st) || (num_acls = acl (argv[optind], GETACL, MAX_ACL_ENTRIES, acls)) < 0) { @@ -187,28 +208,42 @@ main (int argc, char **argv) ret = 2; continue; } - printf ("# file: %s\n", argv[optind]); - if (nopt) + if (!copt) { - printf ("# owner: %lu\n", (unsigned long)st.st_uid); - printf ("# group: %lu\n", (unsigned long)st.st_gid); + printf ("# file: %s\n", argv[optind]); + if (nopt) + { + printf ("# owner: %lu\n", (unsigned long)st.st_uid); + printf ("# group: %lu\n", (unsigned long)st.st_gid); + } + else + { + printf ("# owner: %s\n", username (st.st_uid)); + printf ("# group: %s\n", groupname (st.st_gid)); + } + if (st.st_mode & (S_ISUID | S_ISGID | S_ISVTX)) + printf ("# flags: %c%c%c\n", (st.st_mode & S_ISUID) ? 's' : '-', + (st.st_mode & S_ISGID) ? 's' : '-', + (st.st_mode & S_ISVTX) ? 't' : '-'); } - else - { - printf ("# owner: %s\n", username (st.st_uid)); - printf ("# group: %s\n", groupname (st.st_gid)); - } - if (st.st_mode & (S_ISUID | S_ISGID | S_ISVTX)) - printf ("# flags: %c%c%c\n", (st.st_mode & S_ISUID) ? 's' : '-', - (st.st_mode & S_ISGID) ? 's' : '-', - (st.st_mode & S_ISVTX) ? 't' : '-'); for (i = 0; i < num_acls; ++i) { + if (acls[i].a_type == CLASS_OBJ) + mask = acls[i].a_perm; + else if (acls[i].a_type == DEF_CLASS_OBJ) + def_mask = acls[i].a_perm; + } + for (i = 0; i < num_acls; ++i) + { + int n = 0; + int print_effective = 0; + mode_t effective = acls[i].a_perm; + if (acls[i].a_type & ACL_DEFAULT) { if (aopt) continue; - printf ("default:"); + n += printf ("default:"); } else if (dopt) continue; @@ -219,18 +254,18 @@ main (int argc, char **argv) break; case USER: if (nopt) - printf ("user:%lu:", (unsigned long)acls[i].a_id); + n += printf ("user:%lu:", (unsigned long)acls[i].a_id); else - printf ("user:%s:", username (acls[i].a_id)); + n += printf ("user:%s:", username (acls[i].a_id)); break; case GROUP_OBJ: - printf ("group::"); + n += printf ("group::"); break; case GROUP: if (nopt) - printf ("group:%lu:", (unsigned long)acls[i].a_id); + n += printf ("group:%lu:", (unsigned long)acls[i].a_id); else - printf ("group:%s:", groupname (acls[i].a_id)); + n += printf ("group:%s:", groupname (acls[i].a_id)); break; case CLASS_OBJ: printf ("mask:"); @@ -239,7 +274,37 @@ main (int argc, char **argv) printf ("other:"); break; } - printf ("%s\n", permstr (acls[i].a_perm)); + n += printf ("%s", permstr (acls[i].a_perm)); + switch (acls[i].a_type) + { + case USER: + case GROUP_OBJ: + case GROUP: + effective = acls[i].a_perm & mask; + print_effective = 1; + break; + case DEF_USER: + case DEF_GROUP_OBJ: + case DEF_GROUP: + effective = acls[i].a_perm & def_mask; + print_effective = 1; + break; + } + if (print_effective && eopt >= 0 + && (eopt > 0 || effective != acls[i].a_perm)) + { + if (istty) + { + n = 40 - n; + if (n <= 0) + n = 1; + printf ("%*s", n, " "); + } + else + putchar ('\t'); + printf ("#effective:%s", permstr (effective)); + } + putchar ('\n'); } putchar ('\n'); }