summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-04-03 00:40:01 +0000
committerJeremy Allison <jra@samba.org>2001-04-03 00:40:01 +0000
commita6d201a8d7307f8a6342ee131917d6245ab41993 (patch)
tree5262cee32c71cd1023fb1e0861352a645ca3fac5 /source3/lib
parent6c0c14a7425b76da349fbaf1defe3d4efa250764 (diff)
downloadsamba-a6d201a8d7307f8a6342ee131917d6245ab41993.tar.gz
samba-a6d201a8d7307f8a6342ee131917d6245ab41993.tar.bz2
samba-a6d201a8d7307f8a6342ee131917d6245ab41993.zip
Added XFS ACLs on Linux. Code from John Trostel <jtrostel@connex.com>.
Jeremy. (This used to be commit 0865366f6b1070a8db3d8421c37c8072b36b96e3)
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/sysacls.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c
index 809aa32974..a01667ce36 100644
--- a/source3/lib/sysacls.c
+++ b/source3/lib/sysacls.c
@@ -1513,6 +1513,220 @@ int sys_acl_free_acl(SMB_ACL_T acl_d)
return 0;
}
+#elif defined(HAVE_XFS_ACLS)
+/* For Linux SGI/XFS Filesystems
+ * contributed by J Trostel, Connex
+ * */
+
+/* based on the implementation for Solaris by Toomas Soome.. which is
+ * based on the implementation by Micheal Davidson for Unixware...
+ *
+ * Linux XFS is a 'work-in-progress'
+ * This interface may change...
+ * You've been warned ;-> */
+
+/* First, do the identity mapping */
+
+int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
+{
+ if( acl_get_entry( the_acl, entry_id, entry_p) >= 0) {
+ return 1;
+ }
+ else {
+ return -1;
+ }
+}
+
+SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
+{
+ return acl_get_file( path_p, type);
+}
+
+SMB_ACL_T sys_acl_get_fd(int fd)
+{
+ return acl_get_fd(fd);
+}
+
+char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
+{
+ return acl_to_text( the_acl, plen);
+}
+
+int sys_acl_valid( SMB_ACL_T theacl )
+{
+ return acl_valid(theacl);
+}
+
+int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+{
+ return acl_set_file(name, acltype, theacl);
+}
+
+int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
+{
+ return acl_set_fd(fd, theacl);
+}
+
+/* Now the functions I need to define for XFS */
+
+int sys_acl_create_entry( SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
+{
+ acl_t acl, newacl;
+ acl_entry_t ace;
+ int cnt;
+
+ acl = *acl_p;
+ ace = *entry_p;
+
+ if((*acl_p == NULL) || (ace == NULL)){
+ errno = EINVAL;
+ return -1;
+ }
+
+ cnt = acl->acl_cnt;
+ if( (cnt + 1) > ACL_MAX_ENTRIES ){
+ errno = ENOSPC;
+ return -1;
+ }
+
+ newacl = (acl_t)malloc(sizeof(struct acl));
+ if(newacl == NULL){
+ errno = ENOMEM;
+ return -1;
+ }
+
+ *newacl = *acl;
+ newacl->acl_entry[cnt] = *ace;
+ newacl->acl_cnt = cnt + 1;
+
+ acl_free(*acl_p);
+ *acl_p = newacl;
+ *entry_p = &newacl->acl_entry[cnt];
+ return 0;
+}
+
+
+int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
+{
+ *tag_type_p = entry_d->ae_tag;
+ return 0;
+}
+
+int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
+{
+ *permset_p = &entry_d->ae_perm;
+ return 0;
+}
+
+void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
+{
+ if (entry_d->ae_tag != SMB_ACL_USER
+ && entry_d->ae_tag != SMB_ACL_GROUP) {
+ errno = EINVAL;
+ return NULL;
+ }
+ return &entry_d->ae_id;
+}
+
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
+{
+ *permset = 0;
+ return 0;
+}
+
+int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+{
+ return (*permset & perm);
+}
+
+int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+{
+
+// TO DO: Add in ALL possible permissions here
+// TO DO: Include extended ones!!
+
+ if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE && perm != SMB_ACL_EXECUTE) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if(permset == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ *permset |= perm;
+
+ return 0;
+}
+
+SMB_ACL_T sys_acl_init( int count)
+{
+ SMB_ACL_T a;
+ if((count > ACL_MAX_ENTRIES) || (count < 0)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ else {
+ a = (struct acl *)malloc(sizeof(struct acl)); // where is this memory freed?
+ a->acl_cnt = 0;
+ return a;
+ }
+}
+
+int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
+{
+
+ switch (tag_type) {
+ case SMB_ACL_USER:
+ case SMB_ACL_USER_OBJ:
+ case SMB_ACL_GROUP:
+ case SMB_ACL_GROUP_OBJ:
+ case SMB_ACL_OTHER:
+ case SMB_ACL_MASK:
+ entry_d->ae_tag = tag_type;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
+int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry_d, void *qual_p)
+{
+ if(entry_d->ae_tag != SMB_ACL_GROUP &&
+ entry_d->ae_tag != SMB_ACL_USER) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ entry_d->ae_id = *((uid_t *)qual_p);
+
+ return 0;
+}
+
+int sys_acl_set_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
+{
+// TO DO: expand to extended permissions eventually!
+
+ if(*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+int sys_acl_free_text(char *text)
+{
+ return acl_free(text);
+}
+
+int sys_acl_free_acl(SMB_ACL_T the_acl)
+{
+ return acl_free(the_acl);
+}
+
#else /* No ACLs. */
int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)