2022-05-14 14:54:12

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH 4/6] nfs4_getacl: Add support for the --dacl and --sacl options

From: Trond Myklebust <[email protected]>

Add support for the NFSv4.1 dacl and sacl attributes.

Signed-off-by: Trond Myklebust <[email protected]>
---
nfs4_getfacl/nfs4_getfacl.c | 72 +++++++++++++++++++++++++++++++++----
1 file changed, 65 insertions(+), 7 deletions(-)

diff --git a/nfs4_getfacl/nfs4_getfacl.c b/nfs4_getfacl/nfs4_getfacl.c
index 1222dd907c9e..954cf7edb19a 100644
--- a/nfs4_getfacl/nfs4_getfacl.c
+++ b/nfs4_getfacl/nfs4_getfacl.c
@@ -42,15 +42,30 @@
#include <ftw.h>
#include <getopt.h>

+#define OPT_DACL 0x98
+#define OPT_SACL 0x99
+
static void usage(int);
static void more_help();
static char *execname;
-static void print_acl_from_path();
+static void print_acl_from_path(const char *, enum acl_type);
static int ignore_comment = 0;

-static int recursive(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf)
+static int print_acl(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf)
+{
+ print_acl_from_path(fpath, ACL_TYPE_ACL);
+ return 0;
+}
+
+static int print_dacl(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf)
{
- print_acl_from_path(fpath);
+ print_acl_from_path(fpath, ACL_TYPE_DACL);
+ return 0;
+}
+
+static int print_sacl(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf)
+{
+ print_acl_from_path(fpath, ACL_TYPE_SACL);
return 0;
}

@@ -59,6 +74,8 @@ static struct option long_options[] = {
{"help", 0, 0, 'h' },
{"recursive", 0, 0, 'R' },
{"omit-header", 0, 0, 'c'},
+ {"dacl", 0, 0, OPT_DACL},
+ {"sacl", 0, 0, OPT_SACL},
{ NULL, 0, 0, 0, },
};

@@ -66,6 +83,9 @@ int main(int argc, char **argv)
{
int opt, res = 1;
int do_recursive = 0;
+ int (*recursive)(const char *fpath, const struct stat *sb,
+ int tflag, struct FTW *ftwbuf) = print_acl;
+ enum acl_type type = ACL_TYPE_ACL;

execname = basename(argv[0]);

@@ -88,6 +108,14 @@ int main(int argc, char **argv)
case 'c':
ignore_comment = 1;
break;
+ case OPT_DACL:
+ type = ACL_TYPE_DACL;
+ recursive = print_dacl;
+ break;
+ case OPT_SACL:
+ type = ACL_TYPE_SACL;
+ recursive = print_sacl;
+ break;
case 'h':
usage(1);
res = 0;
@@ -111,23 +139,51 @@ int main(int argc, char **argv)
printf("Invalid filename: %s\n", argv[optind]);
}
else
- print_acl_from_path(argv[optind]);
+ print_acl_from_path(argv[optind], type);
res = 0;
}
out:
return res;
}

-static void print_acl_from_path(const char *fpath)
+static void print_acl_from_path(const char *fpath, enum acl_type type)
{
struct nfs4_acl *acl;
- acl = nfs4_acl_for_path(fpath);
+
+ switch (type) {
+ case ACL_TYPE_ACL:
+ acl = nfs4_getacl(fpath);
+ break;
+ case ACL_TYPE_DACL:
+ acl = nfs4_getdacl(fpath);
+ break;
+ case ACL_TYPE_SACL:
+ acl = nfs4_getsacl(fpath);
+ break;
+ }
+
if (acl != NULL) {
if (ignore_comment == 0)
printf("# file: %s\n", fpath);
nfs4_print_acl(stdout, acl);
printf("\n");
nfs4_free_acl(acl);
+ } else {
+ switch (errno) {
+ case ENODATA:
+ fprintf(stderr,"Attribute not found on file: %s\n",
+ fpath);
+ break;
+ case EREMOTEIO:
+ fprintf(stderr,"An NFS server error occurred.\n");
+ break;
+ case EOPNOTSUPP:
+ fprintf(stderr,"Operation to request attribute not "
+ "supported: %s\n", fpath);
+ break;
+ default:
+ perror("Failed operation");
+ }
}
}

@@ -142,7 +198,9 @@ static void usage(int label)
" -H, --more-help display ACL format information\n"
" -h, --help display this help text\n"
" -R, --recursive recurse into subdirectories\n"
- " -c, --omit-header Do not display the comment header (Do not print filename)\n";
+ " -c, --omit-header Do not display the comment header (Do not print filename)\n"
+ " --dacl display the NFSv4.1 dacl\n"
+ " --sacl display the NFSv4.1 sacl\n";

fprintf(stderr, gfusage, execname);
}
--
2.36.1



2022-05-14 15:07:50

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH 5/6] nfs4_setacl: Add support for the --dacl and --sacl options

From: Trond Myklebust <[email protected]>

Add support for the NFSv4.1 dacl and sacl attributes.

Signed-off-by: Trond Myklebust <[email protected]>
---
nfs4_setfacl/nfs4_setfacl.c | 67 +++++++++++++++++++++++++++++++++++--
1 file changed, 64 insertions(+), 3 deletions(-)

diff --git a/nfs4_setfacl/nfs4_setfacl.c b/nfs4_setfacl/nfs4_setfacl.c
index d0485ad53024..e5816085c8b0 100644
--- a/nfs4_setfacl/nfs4_setfacl.c
+++ b/nfs4_setfacl/nfs4_setfacl.c
@@ -79,6 +79,9 @@
#define EDITOR "vi" /* <- evangelism! */
#define u32 u_int32_t

+#define OPT_DACL 0x98
+#define OPT_SACL 0x99
+
static int apply_action(const char *, const struct stat *, int, struct FTW *);
static int do_apply_action(const char *, const struct stat *);
static int open_editor(const char *);
@@ -110,6 +113,8 @@ static struct option long_options[] = {
{ "recursive", 0, 0, 'R' },
{ "physical", 0, 0, 'P' },
{ "logical", 0, 0, 'L' },
+ { "dacl", 0, 0, OPT_DACL },
+ { "sacl", 0, 0, OPT_SACL },
{ NULL, 0, 0, 0, },
};

@@ -124,6 +129,8 @@ static char *mod_string;
static char *from_ace;
static char *to_ace;

+static enum acl_type acl_type = ACL_TYPE_ACL;
+
/* XXX: things we need to handle:
*
* - we need some sort of 'purge' operation that completely clears an ACL.
@@ -272,6 +279,13 @@ int main(int argc, char **argv)
paths[numpaths++] = optarg;
break;

+ case OPT_DACL:
+ acl_type = ACL_TYPE_DACL;
+ break;
+ case OPT_SACL:
+ acl_type = ACL_TYPE_SACL;
+ break;
+
case 'h':
case '?':
default:
@@ -334,6 +348,50 @@ out:
return err;
}

+static void nfs4_print_acl_error(const char *path)
+{
+ switch (errno) {
+ case ENODATA:
+ fprintf(stderr,"Attribute not found on file: %s\n", path);
+ break;
+ case EREMOTEIO:
+ fprintf(stderr,"An NFS server error occurred.\n");
+ break;
+ case EOPNOTSUPP:
+ fprintf(stderr,"Operation to request attribute not supported: "
+ "%s\n", path);
+ break;
+ default:
+ perror("Failed operation");
+ }
+}
+
+static struct nfs4_acl *nfs4_retrieve_acl(const char *path,
+ enum acl_type type)
+{
+ switch (type) {
+ case ACL_TYPE_DACL:
+ return nfs4_getdacl(path);
+ case ACL_TYPE_SACL:
+ return nfs4_getsacl(path);
+ default:
+ return nfs4_getacl(path);
+ }
+}
+
+static int nfs4_apply_acl(const char *path, struct nfs4_acl *acl,
+ enum acl_type type)
+{
+ switch (type) {
+ case ACL_TYPE_DACL:
+ return nfs4_setdacl(path, acl);
+ case ACL_TYPE_SACL:
+ return nfs4_setsacl(path, acl);
+ default:
+ return nfs4_setacl(path, acl);
+ }
+}
+
/* returns 0 on success, nonzero on failure */
static int apply_action(const char *_path, const struct stat *stat, int flag, struct FTW *ftw)
{
@@ -378,7 +436,7 @@ static int do_apply_action(const char *path, const struct stat *_st)
if (action == SUBSTITUTE_ACTION)
acl = nfs4_new_acl(S_ISDIR(st->st_mode));
else
- acl = nfs4_acl_for_path(path);
+ acl = nfs4_retrieve_acl(path, acl_type);

if (acl == NULL) {
fprintf(stderr, "Failed to instantiate ACL.\n");
@@ -438,8 +496,11 @@ static int do_apply_action(const char *path, const struct stat *_st)
if (is_test) {
fprintf(stderr, "## Test mode only - the resulting ACL for \"%s\": \n", path);
nfs4_print_acl(stdout, acl);
- } else
- err = nfs4_set_acl(acl, path);
+ } else {
+ err = nfs4_apply_acl(path, acl, acl_type);
+ if (err == -1)
+ nfs4_print_acl_error(path);
+ }

out:
nfs4_free_acl(acl);
--
2.36.1


2022-05-14 16:49:01

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH 6/6] Edit manpages to document the new --dacl, --sacl and inheritance features

From: Trond Myklebust <[email protected]>

Signed-off-by: Trond Myklebust <[email protected]>
---
man/man1/nfs4_getfacl.1 | 14 ++++++++++++++
man/man1/nfs4_setfacl.1 | 8 ++++++++
man/man5/nfs4_acl.5 | 10 ++++++++++
3 files changed, 32 insertions(+)

diff --git a/man/man1/nfs4_getfacl.1 b/man/man1/nfs4_getfacl.1
index 7cf7cbf2cd0b..2a618fc356f9 100644
--- a/man/man1/nfs4_getfacl.1
+++ b/man/man1/nfs4_getfacl.1
@@ -34,6 +34,20 @@ flag is specified,
.B nfs4_getfacl
will not display the comment header (Do not print filename).

+If the
+.BR --dacl
+flag is specified,
+.B nfs4_getfacl
+will retrieve the dacl. This functionality is only available if
+the server supports NFSv4 minor version 1 or newer.
+
+If the
+.BR --sacl
+flag is specified,
+.B nfs4_getfacl
+will retrieve the sacl. This functionality is only available if
+the server supports NFSv4 minor version 1 or newer.
+
The output format for an NFSv4 file ACL, e.g., is:
.RS
.nf
diff --git a/man/man1/nfs4_setfacl.1 b/man/man1/nfs4_setfacl.1
index 7144f0447ef9..47ab517c258c 100644
--- a/man/man1/nfs4_setfacl.1
+++ b/man/man1/nfs4_setfacl.1
@@ -101,6 +101,14 @@ in conjunction with
in conjunction with
.BR -R / --recursive ", a physical walk skips all symbolic links."
.TP
+.BR "--dacl"
+acts on the dacl only. This functionality is only available if
+the server supports NFSv4 minor version 1 or newer.
+.TP
+.BR "--sacl"
+acts on the sacl only. This functionality is only available if
+the server supports NFSv4 minor version 1 or newer.
+.TP
.BR --test
display results of
.BR COMMAND ,
diff --git a/man/man5/nfs4_acl.5 b/man/man5/nfs4_acl.5
index e0b2a0a57e8b..7036ab72bc35 100644
--- a/man/man5/nfs4_acl.5
+++ b/man/man5/nfs4_acl.5
@@ -125,6 +125,16 @@ group - indicates that
.I principal
represents a group instead of a user.
.TP
+.BR "INHERITED FLAG" " - can be used in any ACE"
+.TP
+.B I
+inherited - indicates that the ACE was inherited from the parent directory.
+This flag can only be used with the NFSv4.1 protocol or newer when using the
+.BR --dacl
+or
+.BR --sacl
+options.
+.TP
.BR "INHERITANCE FLAGS" " - can be used in any directory ACE"
.TP
.B d
--
2.36.1