From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Add helper functions to set the NFSv4.1 dacl and sacl attributes. Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> --- include/libacl_nfs4.h | 9 +++++ libnfs4acl/Makefile | 2 + libnfs4acl/nfs4_getacl.c | 83 ++++++++++++++++++++++++++++++++++++++++ libnfs4acl/nfs4_setacl.c | 49 ++++++++++++++++++++++++ 4 files changed, 143 insertions(+) create mode 100644 libnfs4acl/nfs4_getacl.c create mode 100644 libnfs4acl/nfs4_setacl.c diff --git a/include/libacl_nfs4.h b/include/libacl_nfs4.h index d3786c3fabdc..76bbe90af54d 100644 --- a/include/libacl_nfs4.h +++ b/include/libacl_nfs4.h @@ -123,6 +123,8 @@ /* NFS4 acl xattr name */ #define ACL_NFS4_XATTR "system.nfs4_acl" +#define DACL_NFS4_XATTR "system.nfs4_dacl" +#define SACL_NFS4_XATTR "system.nfs4_sacl" /* Macro for finding empty tailqs */ #define TAILQ_IS_EMPTY(head) (head.tqh_first == NULL) @@ -152,6 +154,13 @@ TAILQ_HEAD(ace_container_list_head, ace_container); /**** Public functions ****/ +extern struct nfs4_acl * nfs4_getacl(const char *path); +extern struct nfs4_acl * nfs4_getdacl(const char *path); +extern struct nfs4_acl * nfs4_getsacl(const char *path); +extern int nfs4_setacl(const char *path, struct nfs4_acl *acl); +extern int nfs4_setdacl(const char *path, struct nfs4_acl *acl); +extern int nfs4_setsacl(const char *path, struct nfs4_acl *acl); + /** Manipulation functions **/ extern int acl_nfs4_set_who(struct nfs4_ace*, int, char*); extern struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl *); diff --git a/libnfs4acl/Makefile b/libnfs4acl/Makefile index a598d4ee141f..556b59535e26 100644 --- a/libnfs4acl/Makefile +++ b/libnfs4acl/Makefile @@ -92,6 +92,8 @@ LIBACL_NFS4_CFILES = \ nfs4_get_ace_access.c \ nfs4_get_ace_flags.c \ nfs4_get_ace_type.c \ + nfs4_getacl.c \ + nfs4_setacl.c \ nfs4_insert_file_aces.c \ nfs4_insert_string_aces.c \ nfs4_free_acl.c \ diff --git a/libnfs4acl/nfs4_getacl.c b/libnfs4acl/nfs4_getacl.c new file mode 100644 index 000000000000..753ba9167459 --- /dev/null +++ b/libnfs4acl/nfs4_getacl.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022, Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> + * + * This code is free software; you can redistribute it and/or modify + * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE + * version 2.1 as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU LESSER GENERAL PUBLIC LICENSE for more details. + */ + +#include <sys/types.h> +#include <config.h> +#ifdef HAVE_ATTR_XATTR_H +# include <attr/xattr.h> +#else +# ifdef HAVE_SYS_XATTR_H +# include <sys/xattr.h> +# endif +#endif +#include <sys/stat.h> +#include "libacl_nfs4.h" + +/* 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) +{ + struct nfs4_acl *acl; + struct stat st; + void *buf; + ssize_t ret; + u32 iflags = NFS4_ACL_ISFILE; + + if (path == NULL || *path == 0) { + errno = EFAULT; + return NULL; + } + + /* find necessary buffer size */ + ret = getxattr(path, xattr_name, NULL, 0); + if (ret == -1) + goto err; + + buf = malloc(ret); + if (!buf) + goto err; + + /* reconstruct the ACL */ + ret = getxattr(path, xattr_name, buf, ret); + if (ret == -1) + goto err_free; + + ret = stat(path, &st); + if (ret == -1) + goto err_free; + + if (S_ISDIR(st.st_mode)) + iflags = NFS4_ACL_ISDIR; + + acl = acl_nfs4_xattr_load(buf, ret, iflags); + + free(buf); + return acl; +err_free: + free(buf); +err: + return NULL; +} + +struct nfs4_acl *nfs4_getacl(const char *path) +{ + return nfs4_getacl_byname(path, ACL_NFS4_XATTR); +} +struct nfs4_acl *nfs4_getdacl(const char *path) +{ + return nfs4_getacl_byname(path, DACL_NFS4_XATTR); +} +struct nfs4_acl *nfs4_getsacl(const char *path) +{ + return nfs4_getacl_byname(path, SACL_NFS4_XATTR); +} diff --git a/libnfs4acl/nfs4_setacl.c b/libnfs4acl/nfs4_setacl.c new file mode 100644 index 000000000000..298365ec67c5 --- /dev/null +++ b/libnfs4acl/nfs4_setacl.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022, Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> + * + * This code is free software; you can redistribute it and/or modify + * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE + * version 2.1 as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU LESSER GENERAL PUBLIC LICENSE for more details. + */ + +#include <sys/types.h> +#include <config.h> +#ifdef HAVE_ATTR_XATTR_H +# include <attr/xattr.h> +#else +# ifdef HAVE_SYS_XATTR_H +# include <sys/xattr.h> +# endif +#endif +#include "libacl_nfs4.h" + +static int nfs4_setacl_byname(const char *path, const char *xattr_name, + struct nfs4_acl *acl) +{ + char *xdrbuf = NULL; + int ret; + + ret = acl_nfs4_xattr_pack(acl, &xdrbuf); + if (ret != -1) + ret = setxattr(path, xattr_name, xdrbuf, ret, XATTR_REPLACE); + free(xdrbuf); + return ret; +} + +int nfs4_setacl(const char *path, struct nfs4_acl *acl) +{ + return nfs4_setacl_byname(path, ACL_NFS4_XATTR, acl); +} +int nfs4_setdacl(const char *path, struct nfs4_acl *acl) +{ + return nfs4_setacl_byname(path, DACL_NFS4_XATTR, acl); +} +int nfs4_setsacl(const char *path, struct nfs4_acl *acl) +{ + return nfs4_setacl_byname(path, SACL_NFS4_XATTR, acl); +} -- 2.36.1