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/acconfig.h | 2 + source3/configure | 60 +++++++++++-- source3/configure.in | 15 +++- source3/include/config.h.in | 5 ++ source3/include/includes.h | 4 + source3/include/smb_acls.h | 42 +++++++++ source3/lib/sysacls.c | 214 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 332 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/acconfig.h b/source3/acconfig.h index 0f8cf580ce..7c15abfd35 100644 --- a/source3/acconfig.h +++ b/source3/acconfig.h @@ -140,4 +140,6 @@ #undef HAVE_POSIX_ACLS #undef HAVE_UNIXWARE_ACLS #undef HAVE_SOLARIS_ACLS +#undef HAVE_IRIX_ACLS +#undef HAVE_XFS_ACLS #undef HAVE_NO_ACLS diff --git a/source3/configure b/source3/configure index ea664c8fd5..a9d1e56fb6 100755 --- a/source3/configure +++ b/source3/configure @@ -2768,7 +2768,7 @@ else fi done -for ac_hdr in sys/acl.h sys/cdefs.h glob.h +for ac_hdr in sys/acl.h sys/cdefs.h glob.h acl/acl.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 @@ -11605,9 +11605,16 @@ EOF EOF ;; + *irix*) + echo "$ac_t""Using IRIX ACLs" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_IRIX_ACLS 1 +EOF + + ;; *) echo $ac_n "checking for acl_get_file in -lacl""... $ac_c" 1>&6 -echo "configure:11611: checking for acl_get_file in -lacl" >&5 +echo "configure:11618: checking for acl_get_file in -lacl" >&5 ac_lib_var=`echo acl'_'acl_get_file | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11615,7 +11622,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lacl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11637: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -11654,13 +11661,13 @@ else fi echo $ac_n "checking for ACL support""... $ac_c" 1>&6 -echo "configure:11658: checking for ACL support" >&5 +echo "configure:11665: checking for ACL support" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_POSIX_ACLS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -11668,7 +11675,7 @@ int main() { acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p); ; return 0; } EOF -if { (eval echo configure:11672: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11679: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_POSIX_ACLS=yes else @@ -11688,6 +11695,41 @@ echo "$ac_t""$samba_cv_HAVE_POSIX_ACLS" 1>&6 EOF fi + echo $ac_n "checking for XFS ACL support""... $ac_c" 1>&6 +echo "configure:11700: checking for XFS ACL support" >&5 +if eval "test \"`echo '$''{'samba_cv_HAVE_XFS_ACLS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include +int main() { + char test_str[13] = SGI_ACL_FILE; +; return 0; } +EOF +if { (eval echo configure:11714: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + samba_cv_HAVE_XFS_ACLS=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + samba_cv_XFS_POSIX_ACLS=no +fi +rm -f conftest* +fi + +echo "$ac_t""$samba_cv_HAVE_XFS_ACLS" 1>&6 + if test x"$samba_cv_HAVE_XFS_ACLS" = x"yes"; then + echo "$ac_t""Using XFS ACLs" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_XFS_ACLS 1 +EOF + + fi ;; esac ;; @@ -11713,11 +11755,11 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "configure OK"; else diff --git a/source3/configure.in b/source3/configure.in index 959071673c..9143cf278e 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -246,7 +246,7 @@ AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/ AC_CHECK_HEADERS(nss.h sys/security.h security/pam_appl.h) AC_CHECK_HEADERS(stropts.h poll.h readline.h history.h readline/readline.h) AC_CHECK_HEADERS(readline/history.h sys/capability.h syscall.h sys/syscall.h) -AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h) +AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h acl/acl.h) # For experimental utmp support (lastlog on some BSD-like systems) AC_CHECK_HEADERS(utmp.h utmpx.h lastlog.h) @@ -1986,6 +1986,10 @@ AC_ARG_WITH(acl-support, AC_MSG_RESULT(Using solaris ACLs) AC_DEFINE(HAVE_SOLARIS_ACLS) ;; + *irix*) + AC_MSG_RESULT(Using IRIX ACLs) + AC_DEFINE(HAVE_IRIX_ACLS) + ;; *) AC_CHECK_LIB(acl,acl_get_file) AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[ @@ -1997,6 +2001,15 @@ samba_cv_HAVE_POSIX_ACLS=yes,samba_cv_HAVE_POSIX_ACLS=no)]) AC_MSG_RESULT(Using posix ACLs) AC_DEFINE(HAVE_POSIX_ACLS) fi + AC_CACHE_CHECK([for XFS ACL support],samba_cv_HAVE_XFS_ACLS,[ + AC_TRY_COMPILE([#include +#include ], +[ char test_str[13] = SGI_ACL_FILE; ], +samba_cv_HAVE_XFS_ACLS=yes,samba_cv_XFS_POSIX_ACLS=no)]) + if test x"$samba_cv_HAVE_XFS_ACLS" = x"yes"; then + AC_MSG_RESULT(Using XFS ACLs) + AC_DEFINE(HAVE_XFS_ACLS) + fi ;; esac ;; diff --git a/source3/include/config.h.in b/source3/include/config.h.in index e60d5ca425..64714b1e91 100644 --- a/source3/include/config.h.in +++ b/source3/include/config.h.in @@ -203,6 +203,8 @@ #undef HAVE_POSIX_ACLS #undef HAVE_UNIXWARE_ACLS #undef HAVE_SOLARIS_ACLS +#undef HAVE_IRIX_ACLS +#undef HAVE_XFS_ACLS #undef HAVE_NO_ACLS /* The number of bytes in a int. */ @@ -715,6 +717,9 @@ /* Define if you have the yp_get_default_domain function. */ #undef HAVE_YP_GET_DEFAULT_DOMAIN +/* Define if you have the header file. */ +#undef HAVE_ACL_ACL_H + /* Define if you have the header file. */ #undef HAVE_ARPA_INET_H diff --git a/source3/include/includes.h b/source3/include/includes.h index 93c756a690..1c72220d4f 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -271,6 +271,10 @@ #include #endif +#ifdef HAVE_XFS_ACLS +#include +#endif + #ifdef HAVE_SYS_FS_S5PARAM_H #include #endif diff --git a/source3/include/smb_acls.h b/source3/include/smb_acls.h index d7a9c53aaa..9de3a5b6a1 100644 --- a/source3/include/smb_acls.h +++ b/source3/include/smb_acls.h @@ -163,6 +163,48 @@ typedef struct SMB_ACL_T { #define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS #define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT +/* XFS ACLS are defined here */ +/* donated by John Trostel (jtrostel@connex.com) */ + +#elif defined(HAVE_XFS_ACLS) + +/* This is an nearly an identity mapping (just remove the SMB_). */ +#define SMB_ACL_TAG_T acl_tag_t +#define SMB_ACL_TYPE_T acl_type_t +//#define SMB_ACL_PERMSET_T acl_permset_t +typedef ushort *SMB_ACL_PERMSET_T; +#define SMB_ACL_PERM_T acl_perm_t +#define SMB_ACL_READ ACL_READ +#define SMB_ACL_WRITE ACL_WRITE +#define SMB_ACL_EXECUTE ACL_EXECUTE + +/* Types of ACLs. */ +#define SMB_ACL_USER ACL_USER +#define SMB_ACL_USER_OBJ ACL_USER_OBJ +#define SMB_ACL_GROUP ACL_GROUP +#define SMB_ACL_GROUP_OBJ ACL_GROUP_OBJ +#define SMB_ACL_OTHER ACL_OTHER_OBJ +#define SMB_ACL_MASK ACL_MASK + +#define SMB_ACL_T acl_t + +#define SMB_ACL_ENTRY_T acl_entry_t + +#define SMB_ACL_FIRST_ENTRY ACL_FIRST_ENTRY +#define SMB_ACL_NEXT_ENTRY ACL_NEXT_ENTRY + +#define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS +#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT + +/* Not yet in Official SGI XFS CVS */ + +#if defined(CONFIG_EXTENDED_PERMISSSION) +#define SMB_ACL_CHOWN ACL_CHOWN +#define SMB_ACL_CHMOD ACL_CHMOD +#define SMB_ACL_DELETE ACL_DELETE +#define EXTENDED_PERM_BITS (ACL_CHOWN|ACL_CHMOD|ACL_DELETE) +#endif /* CONFIG_EXTENDED_PERMISSION */ + #else /* No ACLs. */ /* No ACLS - fake it. */ 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