summaryrefslogtreecommitdiff
path: root/libacl/acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libacl/acl.c')
-rw-r--r--libacl/acl.c61
1 files changed, 59 insertions, 2 deletions
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;
+ }
}
/*