2022-05-14 15:54:10

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH 3/6] The NFSv41 DACL and SACL prepend an extra field to the acl

From: Trond Myklebust <[email protected]>

The ACL flags describe the inheritance mode of the acl:
- AUTO_INHERIT
- PROTECTED
- DEFAULTED

Signed-off-by: Trond Myklebust <[email protected]>
---
include/libacl_nfs4.h | 8 ++++++++
include/nfs4.h | 5 +++++
libnfs4acl/acl_nfs4_copy_acl.c | 2 ++
libnfs4acl/acl_nfs4_xattr_load.c | 14 +++++++++++++-
libnfs4acl/acl_nfs4_xattr_pack.c | 22 +++++++++++++++++-----
libnfs4acl/nfs4_getacl.c | 11 ++++++-----
libnfs4acl/nfs4_new_acl.c | 1 +
libnfs4acl/nfs4_setacl.c | 10 +++++-----
8 files changed, 57 insertions(+), 16 deletions(-)

diff --git a/include/libacl_nfs4.h b/include/libacl_nfs4.h
index d54d82f94f97..a486390ac170 100644
--- a/include/libacl_nfs4.h
+++ b/include/libacl_nfs4.h
@@ -142,6 +142,12 @@

typedef u_int32_t u32;

+enum acl_type {
+ ACL_TYPE_ACL,
+ ACL_TYPE_DACL,
+ ACL_TYPE_SACL
+};
+
enum { ACL_NFS4_NOT_USED = 0,
ACL_NFS4_USED
};
@@ -166,7 +172,9 @@ extern int nfs4_setsacl(const char *path, struct nfs4_acl *acl);
extern int acl_nfs4_set_who(struct nfs4_ace*, int, char*);
extern struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl *);
extern struct nfs4_acl * acl_nfs4_xattr_load(char *, int, u32);
+extern struct nfs4_acl * acl_nfs41_xattr_load(char *, int, u32, enum acl_type);
extern int acl_nfs4_xattr_pack(struct nfs4_acl *, char**);
+extern int acl_nfs41_xattr_pack(struct nfs4_acl *, char**, enum acl_type);
extern int acl_nfs4_xattr_size(struct nfs4_acl *);

extern void nfs4_free_acl(struct nfs4_acl *);
diff --git a/include/nfs4.h b/include/nfs4.h
index 20bfa6b99634..d15482e8a720 100644
--- a/include/nfs4.h
+++ b/include/nfs4.h
@@ -55,6 +55,10 @@
#define ACL4_SUPPORT_AUDIT_ACL 0x04
#define ACL4_SUPPORT_ALARM_ACL 0x08

+#define NFS4_ACL_AUTO_INHERIT 0x00000001
+#define NFS4_ACL_PROTECTED 0x00000002
+#define NFS4_ACL_DEFAULTED 0x00000004
+
#define NFS4_ACE_FILE_INHERIT_ACE 0x00000001
#define NFS4_ACE_DIRECTORY_INHERIT_ACE 0x00000002
#define NFS4_ACE_NO_PROPAGATE_INHERIT_ACE 0x00000004
@@ -126,6 +130,7 @@ struct nfs4_acl {
u_int32_t naces;
u_int32_t is_directory;
struct ace_list_head ace_head;
+ u_int32_t aclflag;
};

typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
diff --git a/libnfs4acl/acl_nfs4_copy_acl.c b/libnfs4acl/acl_nfs4_copy_acl.c
index cf09173badc0..7a6d83b1ca64 100644
--- a/libnfs4acl/acl_nfs4_copy_acl.c
+++ b/libnfs4acl/acl_nfs4_copy_acl.c
@@ -54,6 +54,8 @@ struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl * acl)
if (new_acl == NULL)
goto failed;

+ new_acl->aclflag = acl->aclflag;
+
ace = nfs4_get_first_ace(acl);
nace = 1;

diff --git a/libnfs4acl/acl_nfs4_xattr_load.c b/libnfs4acl/acl_nfs4_xattr_load.c
index 089a139142b1..c747e8dac225 100644
--- a/libnfs4acl/acl_nfs4_xattr_load.c
+++ b/libnfs4acl/acl_nfs4_xattr_load.c
@@ -38,7 +38,8 @@
#include "libacl_nfs4.h"


-struct nfs4_acl * acl_nfs4_xattr_load(char *xattr_v, int xattr_size, u32 is_dir)
+struct nfs4_acl *acl_nfs41_xattr_load(char *xattr_v, int xattr_size, u32 is_dir,
+ enum acl_type acl_type)
{
struct nfs4_acl *acl;
struct nfs4_ace *ace;
@@ -61,6 +62,12 @@ struct nfs4_acl * acl_nfs4_xattr_load(char *xattr_v, int xattr_size, u32 is_dir)
return NULL;
}

+ if (acl_type == ACL_TYPE_DACL || acl_type == ACL_TYPE_SACL) {
+ acl->aclflag = (u32)ntohl(*((u32*)(bufp)));
+ bufp += sizeof(u32);
+ bufs -= sizeof(u32);
+ }
+
/* Grab the number of aces in the acl */
num_aces = (u32)ntohl(*((u32*)(bufp)));

@@ -180,3 +187,8 @@ err1:
nfs4_free_acl(acl);
return NULL;
}
+
+struct nfs4_acl *acl_nfs4_xattr_load(char *xattr_v, int xattr_size, u32 is_dir)
+{
+ return acl_nfs41_xattr_load(xattr_v, xattr_size, is_dir, ACL_TYPE_ACL);
+}
diff --git a/libnfs4acl/acl_nfs4_xattr_pack.c b/libnfs4acl/acl_nfs4_xattr_pack.c
index 7c281feed496..2bd3b1b1a229 100644
--- a/libnfs4acl/acl_nfs4_xattr_pack.c
+++ b/libnfs4acl/acl_nfs4_xattr_pack.c
@@ -37,11 +37,12 @@
#include "libacl_nfs4.h"
#include <stdio.h>

-int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp)
+int acl_nfs41_xattr_pack(struct nfs4_acl * acl, char** bufp,
+ enum acl_type acl_type)
{
struct nfs4_ace * ace;
int buflen;
- int rbuflen;
+ int rbuflen = 0;
int num_aces;
int ace_num;
int wholen;
@@ -58,6 +59,9 @@ int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp)
if (buflen < 0)
goto failed;

+ if (acl_type == ACL_TYPE_DACL || acl_type == ACL_TYPE_SACL)
+ buflen += sizeof(u32);
+
*bufp = (char*) malloc(buflen);
if (*bufp == NULL) {
errno = ENOMEM;
@@ -67,11 +71,17 @@ int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp)

p = *bufp;

+ if (acl_type == ACL_TYPE_DACL || acl_type == ACL_TYPE_SACL) {
+ *((u32*)p) = htonl(acl->aclflag);
+ rbuflen += sizeof(u32);
+ p += sizeof(u32);
+ }
+
num_aces = acl->naces;

*((u32*)p) = htonl(num_aces);

- rbuflen = sizeof(u32);
+ rbuflen += sizeof(u32);
p += sizeof(u32);

ace = nfs4_get_first_ace(acl);
@@ -140,5 +150,7 @@ failed:
return -1;
}

-
-
+int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp)
+{
+ return acl_nfs41_xattr_pack(acl, bufp, ACL_TYPE_ACL);
+}
diff --git a/libnfs4acl/nfs4_getacl.c b/libnfs4acl/nfs4_getacl.c
index 753ba9167459..7821da3885fe 100644
--- a/libnfs4acl/nfs4_getacl.c
+++ b/libnfs4acl/nfs4_getacl.c
@@ -25,7 +25,8 @@

/* returns a newly-allocated struct nfs4_acl or NULL on error. */
static struct nfs4_acl *nfs4_getacl_byname(const char *path,
- const char *xattr_name)
+ const char *xattr_name,
+ enum acl_type type)
{
struct nfs4_acl *acl;
struct stat st;
@@ -59,7 +60,7 @@ static struct nfs4_acl *nfs4_getacl_byname(const char *path,
if (S_ISDIR(st.st_mode))
iflags = NFS4_ACL_ISDIR;

- acl = acl_nfs4_xattr_load(buf, ret, iflags);
+ acl = acl_nfs41_xattr_load(buf, ret, iflags, type);

free(buf);
return acl;
@@ -71,13 +72,13 @@ err:

struct nfs4_acl *nfs4_getacl(const char *path)
{
- return nfs4_getacl_byname(path, ACL_NFS4_XATTR);
+ return nfs4_getacl_byname(path, ACL_NFS4_XATTR, ACL_TYPE_ACL);
}
struct nfs4_acl *nfs4_getdacl(const char *path)
{
- return nfs4_getacl_byname(path, DACL_NFS4_XATTR);
+ return nfs4_getacl_byname(path, DACL_NFS4_XATTR, ACL_TYPE_DACL);
}
struct nfs4_acl *nfs4_getsacl(const char *path)
{
- return nfs4_getacl_byname(path, SACL_NFS4_XATTR);
+ return nfs4_getacl_byname(path, SACL_NFS4_XATTR, ACL_TYPE_SACL);
}
diff --git a/libnfs4acl/nfs4_new_acl.c b/libnfs4acl/nfs4_new_acl.c
index 78d4c28e474b..0a5583af3bc5 100644
--- a/libnfs4acl/nfs4_new_acl.c
+++ b/libnfs4acl/nfs4_new_acl.c
@@ -50,6 +50,7 @@ nfs4_new_acl(u32 is_dir)

acl->naces = 0;
acl->is_directory = is_dir;
+ acl->aclflag = 0;

TAILQ_INIT(&acl->ace_head);

diff --git a/libnfs4acl/nfs4_setacl.c b/libnfs4acl/nfs4_setacl.c
index 298365ec67c5..d68450220757 100644
--- a/libnfs4acl/nfs4_setacl.c
+++ b/libnfs4acl/nfs4_setacl.c
@@ -23,12 +23,12 @@
#include "libacl_nfs4.h"

static int nfs4_setacl_byname(const char *path, const char *xattr_name,
- struct nfs4_acl *acl)
+ struct nfs4_acl *acl, enum acl_type type)
{
char *xdrbuf = NULL;
int ret;

- ret = acl_nfs4_xattr_pack(acl, &xdrbuf);
+ ret = acl_nfs41_xattr_pack(acl, &xdrbuf, type);
if (ret != -1)
ret = setxattr(path, xattr_name, xdrbuf, ret, XATTR_REPLACE);
free(xdrbuf);
@@ -37,13 +37,13 @@ static int nfs4_setacl_byname(const char *path, const char *xattr_name,

int nfs4_setacl(const char *path, struct nfs4_acl *acl)
{
- return nfs4_setacl_byname(path, ACL_NFS4_XATTR, acl);
+ return nfs4_setacl_byname(path, ACL_NFS4_XATTR, acl, ACL_TYPE_ACL);
}
int nfs4_setdacl(const char *path, struct nfs4_acl *acl)
{
- return nfs4_setacl_byname(path, DACL_NFS4_XATTR, acl);
+ return nfs4_setacl_byname(path, DACL_NFS4_XATTR, acl, ACL_TYPE_DACL);
}
int nfs4_setsacl(const char *path, struct nfs4_acl *acl)
{
- return nfs4_setacl_byname(path, SACL_NFS4_XATTR, acl);
+ return nfs4_setacl_byname(path, SACL_NFS4_XATTR, acl, ACL_TYPE_SACL);
}
--
2.36.1