From a6d201a8d7307f8a6342ee131917d6245ab41993 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 Apr 2001 00:40:01 +0000 Subject: Added XFS ACLs on Linux. Code from John Trostel . Jeremy. (This used to be commit 0865366f6b1070a8db3d8421c37c8072b36b96e3) --- source3/lib/sysacls.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) (limited to 'source3/lib/sysacls.c') 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) -- cgit