summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chacl/chacl.c11
-rw-r--r--include/acl.h15
-rw-r--r--libacl/acl.c61
-rw-r--r--man/man3/acl_get_fd.320
-rw-r--r--man/man3/acl_get_file.324
-rw-r--r--man/man3/acl_set_compat.334
6 files changed, 148 insertions, 17 deletions
diff --git a/chacl/chacl.c b/chacl/chacl.c
index 2807ce5..102d65c 100644
--- a/chacl/chacl.c
+++ b/chacl/chacl.c
@@ -84,14 +84,7 @@ main (int argc, char *argv[])
p = strrchr (argv[0], '/');
program = p != NULL ? p + 1 : argv[0];
-#ifdef HIDDEN
- /* continue only if ACLs enabled */
- if (sysconf (_SC_ACL) <= 0)
- {
- fprintf (stderr, "%s ACLs not enabled.\n", program);
- return (1);
- }
-#endif
+ acl_set_compat(ACL_COMPAT_IRIXGET);
/* parse arguments */
while ((c = getopt (argc, argv, "bdlRDB")) != -1)
@@ -271,7 +264,7 @@ list_acl(char *file)
program, file, strerror(errno));
return 0;
}
- if (dacl->acl_cnt != ACL_NOT_PRESENT) {
+ if (dacl->acl_cnt > 0) {
buf_dacl = acl_to_short_text (dacl, (ssize_t *) NULL);
if (buf_dacl == NULL) {
fprintf (stderr, "%s: error converting default ACL to short text "
diff --git a/include/acl.h b/include/acl.h
index 150c7ab..6564c52 100644
--- a/include/acl.h
+++ b/include/acl.h
@@ -46,7 +46,14 @@ extern "C" {
#define SGI_ACL_FILE_SIZE 12
#define SGI_ACL_DEFAULT_SIZE 15
+/*
+ * An IRIX defined macro not in P1003.1e
+ * With ACL_COMPAT_IRIXGET set
+ * it used to signify an empty ACL.
+ * It is also used to delete an ACL.
+ */
#define ACL_NOT_PRESENT -1
+
/*
* Number of "base" ACL entries
* (USER_OBJ, GROUP_OBJ, MASK, & OTHER_OBJ)
@@ -108,14 +115,22 @@ struct acl {
*/
#define ACL_UNDEFINED_ID ((unsigned int)-1)
+/*
+ * Values for acl compatibility
+ */
+#define ACL_COMPAT_DEFAULT 0x00
+#define ACL_COMPAT_IRIXGET 0x01
+
typedef struct acl * acl_t;
typedef acl_perm_t * acl_permset_t;
+typedef unsigned int acl_compat_t;
/*
* User-space POSIX data types and functions.
*/
#ifndef __KERNEL__
+extern void acl_set_compat(acl_compat_t);
extern int acl_add_perm(acl_permset_t, acl_perm_t);
extern int acl_clear_perms(acl_permset_t);
extern ssize_t acl_copy_ext(void *, acl_t, ssize_t);
diff --git a/libacl/acl.c b/libacl/acl.c
index 12add10..8082e53 100644
--- a/libacl/acl.c
+++ b/libacl/acl.c
@@ -33,7 +33,9 @@
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
+#include <sys/stat.h>
#include <sys/types.h>
+#include <unistd.h>
#include <acl.h>
#include <pwd.h>
#include <grp.h>
@@ -56,6 +58,12 @@
#define setoserror(E) errno = (E)
+/*
+ * Compatibility flag for IRIX functionality
+ * Default is to support common Linux/Posix ACL functionality
+ * and thus is set to zero.
+ */
+static acl_compat_t acl_compat = 0;
static char *
skip_white(char *s)
@@ -565,6 +573,32 @@ acl_delete_def_file (const char *path_p)
return 0;
}
+void
+acl_set_compat(acl_compat_t compat_bits)
+{
+ if (compat_bits)
+ acl_compat |= compat_bits;
+ else
+ acl_compat = 0;
+}
+
+static void
+acl_from_mode(acl_t aclp, uid_t uid, gid_t gid, mode_t mode)
+{
+ aclp->acl_cnt = 3;
+ aclp->acl_entry[0].ae_tag = ACL_USER_OBJ;
+ aclp->acl_entry[0].ae_id = uid;
+ aclp->acl_entry[0].ae_perm = (mode & S_IRWXU) >> 6;
+
+ aclp->acl_entry[1].ae_tag = ACL_GROUP_OBJ;
+ aclp->acl_entry[1].ae_id = gid;
+ aclp->acl_entry[1].ae_perm = (mode & S_IRWXG) >> 3;
+
+ aclp->acl_entry[2].ae_tag = ACL_OTHER_OBJ;
+ aclp->acl_entry[2].ae_id = ACL_UNDEFINED_ID;
+ aclp->acl_entry[2].ae_perm = (mode & S_IRWXO);
+}
+
/*
* Get an ACL by file descriptor.
*/
@@ -584,8 +618,17 @@ acl_get_fd (int fd)
free ((void *) aclp);
return (NULL);
}
- else
+ else if (acl_compat & ACL_COMPAT_IRIXGET) {
return aclp;
+ }
+ else {
+ /* copy over a minimum ACL from mode bits */
+ struct stat st;
+ if (fstat(fd, &st) != 0)
+ return NULL;
+ acl_from_mode(aclp, st.st_uid, st.st_gid, st.st_mode);
+ return aclp;
+ }
}
/*
@@ -625,8 +668,22 @@ acl_get_file (const char *path_p, acl_type_t type)
free ((void *) aclp);
return (NULL);
}
- else
+ else if (acl_compat & ACL_COMPAT_IRIXGET) {
return aclp;
+ }
+ else if (type == ACL_TYPE_ACCESS) {
+ /* copy over a minimum ACL from mode bits */
+ struct stat st;
+ if (stat(path_p, &st) != 0)
+ return NULL;
+ acl_from_mode(aclp, st.st_uid, st.st_gid, st.st_mode);
+ return aclp;
+ }
+ else { /* default ACL */
+ /* empty ACL and NOT ACL_NOT_PRESENT */
+ aclp->acl_cnt = 0;
+ return aclp;
+ }
}
/*
diff --git a/man/man3/acl_get_fd.3 b/man/man3/acl_get_fd.3
index cf829f1..69bba24 100644
--- a/man/man3/acl_get_fd.3
+++ b/man/man3/acl_get_fd.3
@@ -14,6 +14,13 @@ open file referred to by \f2fd\fP.
If
.B _POSIX_MAC
is in effect, then the process must have MAC read access to the object.
+If no access ACL is associated with the \f2fd\fP, then the resultant ACL
+is dependent on the ACL compatibility mode (see
+.BR acl_set_compat (8)
+). If \f2ACL_COMPAT_IRIXGET\f1 is
+set then an ACL with a count of ACL_NOT_PRESENT is returned. Otherwise,
+when no compatibility mode has been set, a mininum 3 ACE ACL based on the
+file's mode is returned.
.PP
.I acl_set_fd
sets the ACL for the open file referred to by \f2fd\fP from the \f2struct acl\fP
@@ -52,7 +59,10 @@ ENOMEM
allocation of the \f2struct acl\fP failed.
.TP 16
ENOSYS
-ACL support is not available (not installed).
+ACL support is not configured in kernel.
+.TP 16
+EOPNOTSUPP (ENOTSUP)
+ACL support is not available for given filesystem.
.PP
.I acl_set_fd:
.TP 16
@@ -70,7 +80,10 @@ The file system is full or some other resource needed for the ACL storage
is not available.
.TP 16
ENOSYS
-ACL support is not available (not installed).
+ACL support is not configured in kernel.
+.TP 16
+EOPNOTSUPP (ENOTSUP)
+ACL support is not available for given filesystem.
.TP 16
EPERM
The process does not have appropriate privilege to
@@ -79,3 +92,6 @@ perform the operation to set the ACL.
EROFS
This function requires modification of a file system which is currently
read-only.
+.SH SEE ALSO
+.BR acl_get_file (8),
+.BR acl_set_compat (8).
diff --git a/man/man3/acl_get_file.3 b/man/man3/acl_get_file.3
index 47fb7b5..95ce798 100644
--- a/man/man3/acl_get_file.3
+++ b/man/man3/acl_get_file.3
@@ -12,11 +12,18 @@ acl_get_file, acl_set_file \- get or set the ACL for a pathname
returns a pointer to an allocated \f2struct acl\fP associated with the
pathname pointed to by \f2path\fP. \f2type\fP determines whether the
default ACL (\f2type == ACL_TYPE_DEFAULT\fP) or access ACL (\f2type == ACL_TYPE_ACCESS\fP) is returned. The default ACL is available only for directories.
-If there is no default ACL associated with the specified directory, an
-ACL containing zero entries is returned.
If
.B _POSIX_MAC
is in effect, then the process must have MAC read access to the object.
+If no ACL is associated with the \f2path\fP, then the resultant ACL
+is dependent on the ACL compatibility mode (see
+.BR acl_set_compat (8)
+). If \f2ACL_COMPAT_IRIXGET\f1 is
+set then an ACL with a count of ACL_NOT_PRESENT is returned.
+If no compatibility mode has been set and the ACL is an access ACL then
+a mininum 3 ACE ACL based on the file's mode is returned.
+If no compatibility mode has been set and the ACL is a default ACL then
+an ACL with a count of zero entries is returned.
.PP
.I acl_set_file
sets the ACL of the specified pathname. \f2type\fP indicates which ACL,
@@ -63,7 +70,10 @@ ENOMEM
allocation of the \f2struct acl\fP failed.
.TP 16
ENOSYS
-ACL support is not available (not installed).
+ACL support is not configured in kernel.
+.TP 16
+EOPNOTSUPP (ENOTSUP)
+ACL support is not available for given filesystem.
.TP 16
ENOTDIR
A component of the path prefix is not a directory.
@@ -91,7 +101,10 @@ The file system is full or some other resource needed for the ACL storage
is not available.
.TP 16
ENOSYS
-ACL support is not available (not installed).
+ACL support is not configured in kernel.
+.TP 16
+EOPNOTSUPP (ENOTSUP)
+ACL support is not available for given filesystem.
.TP 16
ENOTDIR
A component of the path prefix is not a directory.
@@ -103,3 +116,6 @@ perform the operation to set the ACL.
EROFS
This function requires modification of a file system which is currently
read-only.
+.SH SEE ALSO
+.BR acl_get_fd (8),
+.BR acl_set_compat (8).
diff --git a/man/man3/acl_set_compat.3 b/man/man3/acl_set_compat.3
new file mode 100644
index 0000000..8cc8530
--- /dev/null
+++ b/man/man3/acl_set_compat.3
@@ -0,0 +1,34 @@
+.TH ACL_SET_COMPAT 3
+.SH NAME
+acl_set_compat \- set compatibility mode for ACL library
+.SH SYNOPSIS
+.B #include <acl/acl.h>
+.PP
+.B void acl_set_compat(acl_compat_t compat_bits);
+.SH DESCRIPTION
+.I acl_set_compat
+sets the compatibility mode for various IRIX and Linux ACL functionality.
+The ACL semantics for IRIX even though they are based on the Posix 1003.1e
+withdrawn ACL standard, are subtly different from the semantics of
+ext2 ACLs and BSD ACLs. The default semantics used are that of the ext2
+Posix ACLs and a call to this function should only be made to gain
+IRIX compatibility.
+.PP
+\f2Compat_bits\f1 is a bit-vector formed by or'ing compatiblity macros
+with the prefix of \f2ACL_COMPAT_\f1. Each call to this function will
+add to the current compatibility vector. Given a \f2compat_bits\f1 value
+of zero will reset it.
+If \f2compat_bits\f1 is set to \f2ACL_COMPAT_IRIXGET\f1 then the semantics for
+.BR acl_get_fd (8)
+and
+.BR acl_get_file (8)
+are changed in the cases where no ACL was ever explicitly set for
+a file or directory.
+Please refer to
+.BR acl_get_fd (8)
+and
+.BR acl_get_file (8)
+for a description of the differing semantics.
+.SH SEE ALSO
+.BR acl_get_fd (8),
+.BR acl_get_file (8).