2000-12-06 05:32:48 +03:00
/*
Unix SMB / Netbios implementation .
Version 2.2 .
Samba system utilities for ACL support .
Copyright ( C ) Jeremy Allison 2000.
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
extern int DEBUGLEVEL ;
/*
This file wraps all differing system ACL interfaces into a consistent
one based on the POSIX interface . It also returns the correct errors
for older UNIX systems that don ' t support ACLs .
The interfaces that each ACL implementation must support are as follows :
2001-01-12 01:37:59 +03:00
int sys_acl_get_entry ( SMB_ACL_T theacl , int entry_id , SMB_ACL_ENTRY_T * entry_p )
2000-12-06 05:32:48 +03:00
int sys_acl_get_tag_type ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_TAG_T * tag_type_p )
int sys_acl_get_permset ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_PERMSET_T * permset_p
void * sys_acl_get_qualifier ( SMB_ACL_ENTRY_T entry_d )
SMB_ACL_T sys_acl_get_file ( const char * path_p , SMB_ACL_TYPE_T type )
SMB_ACL_T sys_acl_get_fd ( int fd )
2000-12-07 08:38:01 +03:00
int sys_acl_clear_perms ( SMB_ACL_PERMSET_T permset ) ;
int sys_acl_add_perm ( SMB_ACL_PERMSET_T permset , SMB_ACL_PERM_T perm ) ;
2001-01-12 01:37:59 +03:00
char * sys_acl_to_text ( SMB_ACL_T theacl , ssize_t * plen )
SMB_ACL_T sys_acl_init ( int count )
int sys_acl_create_entry ( SMB_ACL_T * pacl , SMB_ACL_ENTRY_T * pentry )
int sys_acl_set_tag_type ( SMB_ACL_ENTRY_T entry , SMB_ACL_TAG_T tagtype )
int sys_acl_set_qualifier ( SMB_ACL_ENTRY_T entry , void * qual )
int sys_acl_set_permset ( SMB_ACL_ENTRY_T entry , SMB_ACL_PERMSET_T permset )
int sys_acl_valid ( SMB_ACL_T theacl )
2001-06-08 23:29:57 +04:00
int sys_acl_set_file ( const char * name , SMB_ACL_TYPE_T acltype , SMB_ACL_T theacl )
2001-01-12 02:41:33 +03:00
int sys_acl_set_fd ( int fd , SMB_ACL_T theacl )
2001-06-08 23:29:57 +04:00
int sys_acl_delete_def_file ( const char * path )
2000-12-07 08:38:01 +03:00
This next one is not POSIX complient - but we * have * to have it !
More POSIX braindamage .
int sys_acl_get_perm ( SMB_ACL_PERMSET_T permset , SMB_ACL_PERM_T perm )
2000-12-19 21:41:51 +03:00
The generic POSIX free is the following call . We split this into
several different free functions as we may need to add tag info
to structures when emulating the POSIX interface .
int sys_acl_free ( void * obj_p )
The calls we actually use are :
int sys_acl_free_text ( char * text ) - free acl_to_text
int sys_acl_free_acl ( SMB_ACL_T posix_acl )
2001-04-14 01:11:57 +04:00
int sys_acl_free_qualifier ( SMB_ACL_T posix_acl )
2000-12-19 21:41:51 +03:00
2000-12-06 05:32:48 +03:00
*/
# if defined(HAVE_POSIX_ACLS)
/* Identity mapping - easy. */
2000-12-14 08:38:05 +03:00
int sys_acl_get_entry ( SMB_ACL_T the_acl , int entry_id , SMB_ACL_ENTRY_T * entry_p )
2000-12-06 05:32:48 +03:00
{
2000-12-14 08:38:05 +03:00
return acl_get_entry ( the_acl , entry_id , entry_p ) ;
2000-12-06 05:32:48 +03:00
}
int sys_acl_get_tag_type ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_TAG_T * tag_type_p )
{
return acl_get_tag_type ( entry_d , tag_type_p ) ;
}
int sys_acl_get_permset ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_PERMSET_T * permset_p )
{
return acl_get_permset ( entry_d , permset_p ) ;
}
void * sys_acl_get_qualifier ( SMB_ACL_ENTRY_T entry_d )
{
return acl_get_qualifier ( entry_d ) ;
}
SMB_ACL_T sys_acl_get_file ( const char * path_p , SMB_ACL_TYPE_T type )
{
2000-12-07 09:23:01 +03:00
return acl_get_file ( path_p , type ) ;
2000-12-06 05:32:48 +03:00
}
SMB_ACL_T sys_acl_get_fd ( int fd )
{
return acl_get_fd ( fd ) ;
}
2000-12-07 08:38:01 +03:00
int sys_acl_clear_perms ( SMB_ACL_PERMSET_T permset )
{
return acl_clear_perms ( permset ) ;
}
int sys_acl_add_perm ( SMB_ACL_PERMSET_T permset , SMB_ACL_PERM_T perm )
{
return acl_add_perm ( permset , perm ) ;
}
int sys_acl_get_perm ( SMB_ACL_PERMSET_T permset , SMB_ACL_PERM_T perm )
{
2001-04-14 23:46:28 +04:00
# if defined(HAVE_ACL_GET_PERM_NP)
/*
* Required for TrustedBSD - based ACL implementations where
* non - POSIX .1 e functions are denoted by a _np ( non - portable )
* suffix .
*/
return acl_get_perm_np ( permset , perm ) ;
# else
2000-12-07 08:38:01 +03:00
return acl_get_perm ( permset , perm ) ;
2001-04-14 23:46:28 +04:00
# endif
2000-12-07 08:38:01 +03:00
}
2000-12-14 08:38:05 +03:00
char * sys_acl_to_text ( SMB_ACL_T the_acl , ssize_t * plen )
2000-12-07 08:38:01 +03:00
{
2000-12-14 08:38:05 +03:00
return acl_to_text ( the_acl , plen ) ;
2000-12-07 08:38:01 +03:00
}
2001-01-12 01:37:59 +03:00
SMB_ACL_T sys_acl_init ( int count )
{
return acl_init ( count ) ;
}
int sys_acl_create_entry ( SMB_ACL_T * pacl , SMB_ACL_ENTRY_T * pentry )
{
return acl_create_entry ( pacl , pentry ) ;
}
int sys_acl_set_tag_type ( SMB_ACL_ENTRY_T entry , SMB_ACL_TAG_T tagtype )
{
return acl_set_tag_type ( entry , tagtype ) ;
}
int sys_acl_set_qualifier ( SMB_ACL_ENTRY_T entry , void * qual )
{
return acl_set_qualifier ( entry , qual ) ;
}
int sys_acl_set_permset ( SMB_ACL_ENTRY_T entry , SMB_ACL_PERMSET_T permset )
{
return acl_set_permset ( entry , permset ) ;
}
int sys_acl_valid ( SMB_ACL_T theacl )
{
2001-01-12 02:41:33 +03:00
return acl_valid ( theacl ) ;
2001-01-12 01:37:59 +03:00
}
2001-06-08 23:29:57 +04:00
int sys_acl_set_file ( const char * name , SMB_ACL_TYPE_T acltype , SMB_ACL_T theacl )
2001-01-12 01:37:59 +03:00
{
return acl_set_file ( name , acltype , theacl ) ;
}
2001-01-12 02:41:33 +03:00
int sys_acl_set_fd ( int fd , SMB_ACL_T theacl )
2001-01-12 01:37:59 +03:00
{
2001-01-12 02:41:33 +03:00
return acl_set_fd ( fd , theacl ) ;
2001-01-12 01:37:59 +03:00
}
2001-06-08 23:29:57 +04:00
int sys_acl_delete_def_file ( const char * name )
{
return acl_delete_def_file ( name ) ;
}
2000-12-19 21:41:51 +03:00
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 ) ;
}
2001-04-14 01:11:57 +04:00
int sys_acl_free_qualifier ( void * qual )
{
return acl_free ( qual ) ;
}
2001-04-06 00:52:02 +04:00
# elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
2001-02-15 22:56:10 +03:00
/*
2001-04-06 00:52:02 +04:00
* Donated by Michael Davidson < md @ sco . COM > for UnixWare / OpenUNIX .
* Modified by Toomas Soome < tsoome @ ut . ee > for Solaris .
2001-02-15 22:56:10 +03:00
*/
2001-04-06 00:52:02 +04:00
/*
* Note that while this code implements sufficient functionality
* to support the sys_acl_ * interfaces it does not provide all
* of the semantics of the POSIX ACL interfaces .
*
* In particular , an ACL entry descriptor ( SMB_ACL_ENTRY_T ) returned
* from a call to sys_acl_get_entry ( ) should not be assumed to be
* valid after calling any of the following functions , which may
* reorder the entries in the ACL .
*
* sys_acl_valid ( )
* sys_acl_set_file ( )
* sys_acl_set_fd ( )
*/
2001-02-15 22:56:10 +03:00
2001-04-06 00:52:02 +04:00
/*
* The only difference between Solaris and UnixWare / OpenUNIX is
* that the # defines for the ACL operations have different names
*/
# if defined(HAVE_UNIXWARE_ACLS)
2001-02-15 22:56:10 +03:00
2001-04-06 00:52:02 +04:00
# define SETACL ACL_SET
# define GETACL ACL_GET
2001-02-15 22:56:10 +03:00
# define GETACLCNT ACL_CNT
# endif
int sys_acl_get_entry ( SMB_ACL_T acl_d , int entry_id , SMB_ACL_ENTRY_T * entry_p )
{
if ( entry_id ! = SMB_ACL_FIRST_ENTRY & & entry_id ! = SMB_ACL_NEXT_ENTRY ) {
errno = EINVAL ;
return - 1 ;
}
if ( entry_p = = NULL ) {
errno = EINVAL ;
return - 1 ;
}
if ( entry_id = = SMB_ACL_FIRST_ENTRY ) {
acl_d - > next = 0 ;
}
if ( acl_d - > next < 0 ) {
errno = EINVAL ;
return - 1 ;
}
if ( acl_d - > next > = acl_d - > count ) {
return 0 ;
}
* entry_p = & acl_d - > acl [ acl_d - > next + + ] ;
return 1 ;
}
int sys_acl_get_tag_type ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_TAG_T * type_p )
{
* type_p = entry_d - > a_type ;
return 0 ;
}
int sys_acl_get_permset ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_PERMSET_T * permset_p )
{
* permset_p = & entry_d - > a_perm ;
return 0 ;
}
void * sys_acl_get_qualifier ( SMB_ACL_ENTRY_T entry_d )
{
if ( entry_d - > a_type ! = SMB_ACL_USER
& & entry_d - > a_type ! = SMB_ACL_GROUP ) {
errno = EINVAL ;
return NULL ;
}
return & entry_d - > a_id ;
}
2001-04-06 00:52:02 +04:00
/*
* There is no way of knowing what size the ACL returned by
* GETACL will be unless you first call GETACLCNT which means
* making an additional system call .
*
* In the hope of avoiding the cost of the additional system
* call in most cases , we initially allocate enough space for
* an ACL with INITIAL_ACL_SIZE entries . If this turns out to
* be too small then we use GETACLCNT to find out the actual
* size , reallocate the ACL buffer , and then call GETACL again .
*/
# define INITIAL_ACL_SIZE 16
2001-02-15 22:56:10 +03:00
SMB_ACL_T sys_acl_get_file ( const char * path_p , SMB_ACL_TYPE_T type )
{
SMB_ACL_T acl_d ;
int count ; /* # of ACL entries allocated */
int naccess ; /* # of access ACL entries */
int ndefault ; /* # of default ACL entries */
if ( type ! = SMB_ACL_TYPE_ACCESS & & type ! = SMB_ACL_TYPE_DEFAULT ) {
errno = EINVAL ;
return NULL ;
}
count = INITIAL_ACL_SIZE ;
if ( ( acl_d = sys_acl_init ( count ) ) = = NULL ) {
return NULL ;
}
2001-04-06 00:52:02 +04:00
/*
* If there isn ' t enough space for the ACL entries we use
* GETACLCNT to determine the actual number of ACL entries
* reallocate and try again . This is in a loop because it
* is possible that someone else could modify the ACL and
* increase the number of entries between the call to
* GETACLCNT and the call to GETACL .
*/
2001-02-15 22:56:10 +03:00
while ( ( count = acl ( path_p , GETACL , count , & acl_d - > acl [ 0 ] ) ) < 0
& & errno = = ENOSPC ) {
2001-04-11 06:02:45 +04:00
sys_acl_free_acl ( acl_d ) ;
2001-02-15 22:56:10 +03:00
if ( ( count = acl ( path_p , GETACLCNT , 0 , NULL ) ) < 0 ) {
return NULL ;
}
if ( ( acl_d = sys_acl_init ( count ) ) = = NULL ) {
return NULL ;
}
}
if ( count < 0 ) {
2001-04-11 06:02:45 +04:00
sys_acl_free_acl ( acl_d ) ;
2001-02-15 22:56:10 +03:00
return NULL ;
}
/*
* calculate the number of access and default ACL entries
*
* Note : we assume that the acl ( ) system call returned a
* well formed ACL which is sorted so that all of the
* access ACL entries preceed any default ACL entries
*/
for ( naccess = 0 ; naccess < count ; naccess + + ) {
if ( acl_d - > acl [ naccess ] . a_type & ACL_DEFAULT )
break ;
}
ndefault = count - naccess ;
/*
* if the caller wants the default ACL we have to copy
* the entries down to the start of the acl [ ] buffer
* and mask out the ACL_DEFAULT flag from the type field
*/
if ( type = = SMB_ACL_TYPE_DEFAULT ) {
int i , j ;
for ( i = 0 , j = naccess ; i < ndefault ; i + + , j + + ) {
acl_d - > acl [ i ] = acl_d - > acl [ j ] ;
acl_d - > acl [ i ] . a_type & = ~ ACL_DEFAULT ;
}
acl_d - > count = ndefault ;
} else {
acl_d - > count = naccess ;
}
return acl_d ;
}
SMB_ACL_T sys_acl_get_fd ( int fd )
{
SMB_ACL_T acl_d ;
int count ; /* # of ACL entries allocated */
int naccess ; /* # of access ACL entries */
count = INITIAL_ACL_SIZE ;
if ( ( acl_d = sys_acl_init ( count ) ) = = NULL ) {
return NULL ;
}
while ( ( count = facl ( fd , GETACL , count , & acl_d - > acl [ 0 ] ) ) < 0
& & errno = = ENOSPC ) {
2001-04-11 06:02:45 +04:00
sys_acl_free_acl ( acl_d ) ;
2001-02-15 22:56:10 +03:00
if ( ( count = facl ( fd , GETACLCNT , 0 , NULL ) ) < 0 ) {
return NULL ;
}
if ( ( acl_d = sys_acl_init ( count ) ) = = NULL ) {
return NULL ;
}
}
if ( count < 0 ) {
2001-04-11 06:02:45 +04:00
sys_acl_free_acl ( acl_d ) ;
2001-02-15 22:56:10 +03:00
return NULL ;
}
/*
* calculate the number of access ACL entries
*/
for ( naccess = 0 ; naccess < count ; naccess + + ) {
if ( acl_d - > acl [ naccess ] . a_type & ACL_DEFAULT )
break ;
}
acl_d - > count = naccess ;
return acl_d ;
}
int sys_acl_clear_perms ( SMB_ACL_PERMSET_T permset_d )
{
* permset_d = 0 ;
return 0 ;
}
int sys_acl_add_perm ( SMB_ACL_PERMSET_T permset_d , SMB_ACL_PERM_T perm )
{
if ( perm ! = SMB_ACL_READ & & perm ! = SMB_ACL_WRITE
& & perm ! = SMB_ACL_EXECUTE ) {
errno = EINVAL ;
return - 1 ;
}
if ( permset_d = = NULL ) {
errno = EINVAL ;
return - 1 ;
}
* permset_d | = perm ;
return 0 ;
}
int sys_acl_get_perm ( SMB_ACL_PERMSET_T permset_d , SMB_ACL_PERM_T perm )
{
return * permset_d & perm ;
}
char * sys_acl_to_text ( SMB_ACL_T acl_d , ssize_t * len_p )
{
int i ;
int len , maxlen ;
char * text ;
/*
* use an initial estimate of 20 bytes per ACL entry
* when allocating memory for the text representation
* of the ACL
*/
len = 0 ;
maxlen = 20 * acl_d - > count ;
if ( ( text = malloc ( maxlen ) ) = = NULL ) {
errno = ENOMEM ;
return NULL ;
}
for ( i = 0 ; i < acl_d - > count ; i + + ) {
struct acl * ap = & acl_d - > acl [ i ] ;
struct passwd * pw ;
struct group * gr ;
char tagbuf [ 12 ] ;
char idbuf [ 12 ] ;
char * tag ;
char * id = " " ;
char perms [ 4 ] ;
int nbytes ;
switch ( ap - > a_type ) {
/*
* for debugging purposes it ' s probably more
* useful to dump unknown tag types rather
* than just returning an error
*/
default :
2001-02-16 22:21:18 +03:00
slprintf ( tagbuf , sizeof ( tagbuf ) - 1 , " 0x%x " ,
2001-02-15 22:56:10 +03:00
ap - > a_type ) ;
tag = tagbuf ;
2001-02-16 22:21:18 +03:00
slprintf ( idbuf , sizeof ( idbuf ) - 1 , " %ld " ,
2001-02-15 22:56:10 +03:00
( long ) ap - > a_id ) ;
id = idbuf ;
break ;
case SMB_ACL_USER :
2001-03-01 08:21:19 +03:00
if ( ( pw = sys_getpwuid ( ap - > a_id ) ) = = NULL ) {
2001-02-16 22:21:18 +03:00
slprintf ( idbuf , sizeof ( idbuf ) - 1 , " %ld " ,
2001-02-15 22:56:10 +03:00
( long ) ap - > a_id ) ;
id = idbuf ;
} else {
id = pw - > pw_name ;
}
case SMB_ACL_USER_OBJ :
tag = " user " ;
break ;
case SMB_ACL_GROUP :
if ( ( gr = getgrgid ( ap - > a_id ) ) = = NULL ) {
2001-02-16 22:21:18 +03:00
slprintf ( idbuf , sizeof ( idbuf ) - 1 , " %ld " ,
2001-02-15 22:56:10 +03:00
( long ) ap - > a_id ) ;
id = idbuf ;
} else {
id = gr - > gr_name ;
}
case SMB_ACL_GROUP_OBJ :
tag = " group " ;
break ;
case SMB_ACL_OTHER :
tag = " other " ;
break ;
case SMB_ACL_MASK :
tag = " mask " ;
break ;
}
2001-04-06 00:52:02 +04:00
perms [ 0 ] = ( ap - > a_perm & SMB_ACL_READ ) ? ' r ' : ' - ' ;
perms [ 1 ] = ( ap - > a_perm & SMB_ACL_WRITE ) ? ' w ' : ' - ' ;
perms [ 2 ] = ( ap - > a_perm & SMB_ACL_EXECUTE ) ? ' x ' : ' - ' ;
2001-02-15 22:56:10 +03:00
perms [ 3 ] = ' \0 ' ;
/* <tag> : <qualifier> : rwx \n \0 */
nbytes = strlen ( tag ) + 1 + strlen ( id ) + 1 + 3 + 1 + 1 ;
/*
2001-04-06 00:52:02 +04:00
* If this entry would overflow the buffer
* allocate enough additional memory for this
* entry and an estimate of another 20 bytes
* for each entry still to be processed
2001-02-15 22:56:10 +03:00
*/
2001-04-06 00:52:02 +04:00
if ( ( len + nbytes ) > maxlen ) {
char * oldtext = text ;
2001-02-15 22:56:10 +03:00
2001-02-25 03:24:54 +03:00
maxlen + = nbytes + 20 * ( acl_d - > count - i ) ;
2001-04-06 00:52:02 +04:00
if ( ( text = realloc ( oldtext , maxlen ) ) = = NULL ) {
free ( oldtext ) ;
2001-02-25 03:24:54 +03:00
errno = ENOMEM ;
return NULL ;
}
}
slprintf ( & text [ len ] , nbytes - 1 , " %s:%s:%s \n " , tag , id , perms ) ;
len + = nbytes - 1 ;
}
if ( len_p )
* len_p = len ;
return text ;
}
SMB_ACL_T sys_acl_init ( int count )
{
SMB_ACL_T a ;
if ( count < 0 ) {
errno = EINVAL ;
return NULL ;
}
/*
* note that since the definition of the structure pointed
* to by the SMB_ACL_T includes the first element of the
* acl [ ] array , this actually allocates an ACL with room
* for ( count + 1 ) entries
*/
if ( ( a = malloc ( sizeof ( * a ) + count * sizeof ( struct acl ) ) ) = = NULL ) {
errno = ENOMEM ;
return NULL ;
}
a - > size = count + 1 ;
a - > count = 0 ;
a - > next = - 1 ;
return a ;
}
int sys_acl_create_entry ( SMB_ACL_T * acl_p , SMB_ACL_ENTRY_T * entry_p )
{
SMB_ACL_T acl_d ;
SMB_ACL_ENTRY_T entry_d ;
if ( acl_p = = NULL | | entry_p = = NULL | | ( acl_d = * acl_p ) = = NULL ) {
errno = EINVAL ;
return - 1 ;
}
if ( acl_d - > count > = acl_d - > size ) {
errno = ENOSPC ;
return - 1 ;
}
entry_d = & acl_d - > acl [ acl_d - > count + + ] ;
entry_d - > a_type = 0 ;
entry_d - > a_id = - 1 ;
entry_d - > a_perm = 0 ;
* entry_p = entry_d ;
return 0 ;
}
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 - > a_type = 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 - > a_type ! = SMB_ACL_GROUP
& & entry_d - > a_type ! = SMB_ACL_USER ) {
errno = EINVAL ;
return - 1 ;
}
entry_d - > a_id = * ( ( id_t * ) qual_p ) ;
return 0 ;
}
int sys_acl_set_permset ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_PERMSET_T permset_d )
{
if ( * permset_d & ~ ( SMB_ACL_READ | SMB_ACL_WRITE | SMB_ACL_EXECUTE ) ) {
return EINVAL ;
}
entry_d - > a_perm = * permset_d ;
return 0 ;
}
2001-06-08 23:55:47 +04:00
/*
* sort the ACL and check it for validity
*
* if it ' s a minimal ACL with only 4 entries then we
* need to recalculate the mask permissions to make
* sure that they are the same as the GROUP_OBJ
* permissions as required by the UnixWare acl ( ) system call .
*
* ( note : since POSIX allows minimal ACLs which only contain
* 3 entries - ie there is no mask entry - we should , in theory ,
* check for this and add a mask entry if necessary - however
* we " know " that the caller of this interface always specifies
* a mask so , in practice " this never happens " ( tm ) - if it * does *
* happen aclsort ( ) will fail and return an error and someone will
* have to fix it . . . )
*/
static int acl_sort ( SMB_ACL_T acl_d )
2001-02-25 03:24:54 +03:00
{
2001-06-08 23:55:47 +04:00
int fixmask = ( acl_d - > count < = 4 ) ;
if ( aclsort ( acl_d - > count , fixmask , acl_d - > acl ) ! = 0 ) {
2001-02-25 03:24:54 +03:00
errno = EINVAL ;
return - 1 ;
}
return 0 ;
}
2001-06-08 23:55:47 +04:00
int sys_acl_valid ( SMB_ACL_T acl_d )
{
return acl_sort ( acl_d ) ;
}
2001-02-25 03:24:54 +03:00
2001-06-08 23:29:57 +04:00
int sys_acl_set_file ( const char * name , SMB_ACL_TYPE_T type , SMB_ACL_T acl_d )
2001-02-25 03:24:54 +03:00
{
struct stat s ;
struct acl * acl_p ;
int acl_count ;
struct acl * acl_buf = NULL ;
int ret ;
if ( type ! = SMB_ACL_TYPE_ACCESS & & type ! = SMB_ACL_TYPE_DEFAULT ) {
errno = EINVAL ;
return - 1 ;
}
2001-06-08 23:55:47 +04:00
if ( acl_sort ( acl_d ) ! = 0 ) {
2001-02-25 03:24:54 +03:00
return - 1 ;
}
acl_p = & acl_d - > acl [ 0 ] ;
acl_count = acl_d - > count ;
/*
* if it ' s a directory there is extra work to do
* since the acl ( ) system call will replace both
* the access ACLs and the default ACLs ( if any )
*/
2001-06-08 23:55:47 +04:00
if ( stat ( name , & s ) ! = 0 ) {
return - 1 ;
}
2001-02-25 03:24:54 +03:00
if ( S_ISDIR ( s . st_mode ) ) {
SMB_ACL_T acc_acl ;
SMB_ACL_T def_acl ;
SMB_ACL_T tmp_acl ;
int i ;
if ( type = = SMB_ACL_TYPE_ACCESS ) {
acc_acl = acl_d ;
2001-06-08 23:55:47 +04:00
def_acl = tmp_acl = sys_acl_get_file ( name , SMB_ACL_TYPE_DEFAULT ) ;
2001-02-25 03:24:54 +03:00
} else {
def_acl = acl_d ;
2001-06-08 23:55:47 +04:00
acc_acl = tmp_acl = sys_acl_get_file ( name , SMB_ACL_TYPE_ACCESS ) ;
2001-02-25 03:24:54 +03:00
}
if ( tmp_acl = = NULL ) {
return - 1 ;
}
/*
* allocate a temporary buffer for the complete ACL
*/
2001-06-08 23:55:47 +04:00
acl_count = acc_acl - > count + def_acl - > count ;
acl_p = acl_buf = malloc ( acl_count * sizeof ( acl_buf [ 0 ] ) ) ;
2001-02-25 03:24:54 +03:00
if ( acl_buf = = NULL ) {
sys_acl_free_acl ( tmp_acl ) ;
errno = ENOMEM ;
return - 1 ;
}
/*
* copy the access control and default entries into the buffer
*/
memcpy ( & acl_buf [ 0 ] , & acc_acl - > acl [ 0 ] ,
acc_acl - > count * sizeof ( acl_buf [ 0 ] ) ) ;
memcpy ( & acl_buf [ acc_acl - > count ] , & def_acl - > acl [ 0 ] ,
def_acl - > count * sizeof ( acl_buf [ 0 ] ) ) ;
/*
* set the ACL_DEFAULT flag on the default entries
*/
for ( i = acc_acl - > count ; i < acl_count ; i + + ) {
acl_buf [ i ] . a_type | = ACL_DEFAULT ;
}
sys_acl_free_acl ( tmp_acl ) ;
} else if ( type ! = SMB_ACL_TYPE_ACCESS ) {
errno = EINVAL ;
return - 1 ;
}
2001-06-08 23:55:47 +04:00
ret = acl ( name , SETACL , acl_count , acl_p ) ;
2001-02-25 03:24:54 +03:00
if ( acl_buf ) {
free ( acl_buf ) ;
}
return ret ;
}
int sys_acl_set_fd ( int fd , SMB_ACL_T acl_d )
{
2001-06-08 23:55:47 +04:00
if ( acl_sort ( acl_d ) {
2001-02-25 03:24:54 +03:00
return - 1 ;
}
return facl ( fd , SETACL , acl_d - > count , & acl_d - > acl [ 0 ] ) ;
}
2001-06-08 23:55:47 +04:00
int sys_acl_delete_def_file ( const char * path )
{
SMB_ACL_T acl_d ;
int ret ;
/*
* fetching the access ACL and rewriting it has
* the effect of deleting the default ACL
*/
if ( ( acl_d = sys_acl_get_file ( path , SMB_ACL_TYPE_ACCESS ) ) = = NULL ) {
return - 1 ;
}
ret = acl ( path , SETACL , acl_d - > count , acl_d - > acl ) ;
sys_acl_free_acl ( acl_d ) ;
return ret ;
}
2001-02-25 03:24:54 +03:00
int sys_acl_free_text ( char * text )
{
free ( text ) ;
return 0 ;
}
int sys_acl_free_acl ( SMB_ACL_T acl_d )
{
free ( acl_d ) ;
return 0 ;
}
2001-04-14 01:11:57 +04:00
int sys_acl_free_qualifier ( void * qual )
{
return 0 ;
}
2000-12-06 05:32:48 +03:00
# elif defined(HAVE_IRIX_ACLS)
2001-04-03 03:05:25 +04:00
int sys_acl_get_entry ( SMB_ACL_T acl_d , int entry_id , SMB_ACL_ENTRY_T * entry_p )
{
if ( entry_id ! = SMB_ACL_FIRST_ENTRY & & entry_id ! = SMB_ACL_NEXT_ENTRY ) {
errno = EINVAL ;
return - 1 ;
}
if ( entry_p = = NULL ) {
errno = EINVAL ;
return - 1 ;
}
if ( entry_id = = SMB_ACL_FIRST_ENTRY ) {
acl_d - > next = 0 ;
}
if ( acl_d - > next < 0 ) {
errno = EINVAL ;
return - 1 ;
}
if ( acl_d - > next > = acl_d - > aclp - > acl_cnt ) {
return 0 ;
}
* entry_p = & acl_d - > aclp - > acl_entry [ acl_d - > next + + ] ;
return 1 ;
}
int sys_acl_get_tag_type ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_TAG_T * type_p )
{
* 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 ;
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 ;
}
SMB_ACL_T sys_acl_get_file ( const char * path_p , SMB_ACL_TYPE_T type )
{
SMB_ACL_T a ;
if ( ( a = malloc ( sizeof ( * a ) ) ) = = NULL ) {
errno = ENOMEM ;
return NULL ;
}
if ( ( a - > aclp = acl_get_file ( path_p , type ) ) = = NULL ) {
free ( a ) ;
return NULL ;
}
a - > next = - 1 ;
a - > freeaclp = True ;
return a ;
}
SMB_ACL_T sys_acl_get_fd ( int fd )
{
SMB_ACL_T a ;
if ( ( a = malloc ( sizeof ( * a ) ) ) = = NULL ) {
errno = ENOMEM ;
return NULL ;
}
if ( ( a - > aclp = acl_get_fd ( fd ) ) = = NULL ) {
free ( a ) ;
return NULL ;
}
a - > next = - 1 ;
a - > freeaclp = True ;
return a ;
}
int sys_acl_clear_perms ( SMB_ACL_PERMSET_T permset_d )
{
permset_d - > ae_perm = 0 ;
return 0 ;
}
int sys_acl_add_perm ( SMB_ACL_PERMSET_T permset_d , SMB_ACL_PERM_T perm )
{
if ( perm ! = SMB_ACL_READ & & perm ! = SMB_ACL_WRITE
& & perm ! = SMB_ACL_EXECUTE ) {
errno = EINVAL ;
return - 1 ;
}
if ( permset_d = = NULL ) {
errno = EINVAL ;
return - 1 ;
}
permset_d - > ae_perm | = perm ;
return 0 ;
}
int sys_acl_get_perm ( SMB_ACL_PERMSET_T permset_d , SMB_ACL_PERM_T perm )
{
return permset_d - > ae_perm & perm ;
}
char * sys_acl_to_text ( SMB_ACL_T acl_d , ssize_t * len_p )
{
return acl_to_text ( acl_d - > aclp , len_p ) ;
}
SMB_ACL_T sys_acl_init ( int count )
{
SMB_ACL_T a ;
if ( count < 0 ) {
errno = EINVAL ;
return NULL ;
}
if ( ( a = malloc ( sizeof ( * a ) + sizeof ( struct acl ) ) ) = = NULL ) {
errno = ENOMEM ;
return NULL ;
}
a - > next = - 1 ;
a - > freeaclp = False ;
a - > aclp = ( struct acl * ) ( & a - > aclp + sizeof ( struct acl * ) ) ;
a - > aclp - > acl_cnt = 0 ;
return a ;
}
int sys_acl_create_entry ( SMB_ACL_T * acl_p , SMB_ACL_ENTRY_T * entry_p )
{
SMB_ACL_T acl_d ;
SMB_ACL_ENTRY_T entry_d ;
if ( acl_p = = NULL | | entry_p = = NULL | | ( acl_d = * acl_p ) = = NULL ) {
errno = EINVAL ;
return - 1 ;
}
if ( acl_d - > aclp - > acl_cnt > = ACL_MAX_ENTRIES ) {
errno = ENOSPC ;
return - 1 ;
}
entry_d = & acl_d - > aclp - > acl_entry [ acl_d - > aclp - > acl_cnt + + ] ;
entry_d - > ae_tag = 0 ;
entry_d - > ae_id = 0 ;
entry_d - > ae_perm = 0 ;
* entry_p = entry_d ;
return 0 ;
}
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 = * ( ( id_t * ) qual_p ) ;
return 0 ;
}
int sys_acl_set_permset ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_PERMSET_T permset_d )
{
if ( permset_d - > ae_perm & ~ ( SMB_ACL_READ | SMB_ACL_WRITE | SMB_ACL_EXECUTE ) ) {
return EINVAL ;
}
entry_d - > ae_perm = permset_d - > ae_perm ;
return 0 ;
}
int sys_acl_valid ( SMB_ACL_T acl_d )
{
return acl_valid ( acl_d - > aclp ) ;
}
2001-06-08 23:29:57 +04:00
int sys_acl_set_file ( const char * name , SMB_ACL_TYPE_T type , SMB_ACL_T acl_d )
2001-04-03 03:05:25 +04:00
{
return acl_set_file ( name , type , acl_d - > aclp ) ;
}
int sys_acl_set_fd ( int fd , SMB_ACL_T acl_d )
{
return acl_set_fd ( fd , acl_d - > aclp ) ;
}
int sys_acl_free_text ( char * text )
{
return acl_free ( text ) ;
}
int sys_acl_free_acl ( SMB_ACL_T acl_d )
{
if ( acl_d - > freeaclp ) {
acl_free ( acl_d - > aclp ) ;
}
acl_free ( acl_d ) ;
return 0 ;
}
2001-04-14 01:11:57 +04:00
int sys_acl_free_qualifier ( void * qual )
{
return 0 ;
}
2001-04-03 04:40:01 +04:00
# 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 ) ;
}
2001-06-08 23:29:57 +04:00
int sys_acl_set_file ( const char * name , SMB_ACL_TYPE_T acltype , SMB_ACL_T theacl )
2001-04-03 04:40:01 +04:00
{
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 )
{
2001-04-17 09:41:07 +04:00
/* TO DO: Add in ALL possible permissions here */
/* TO DO: Include extended ones!! */
2001-04-03 04:40:01 +04:00
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 {
2001-04-17 09:41:07 +04:00
a = ( struct acl * ) malloc ( sizeof ( struct acl ) ) ; /* where is this memory freed? */
2001-04-03 04:40:01 +04:00
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 )
{
2001-04-17 09:41:07 +04:00
/* TO DO: expand to extended permissions eventually! */
2001-04-03 04:40:01 +04:00
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 ) ;
}
2001-04-14 01:11:57 +04:00
int sys_acl_free_qualifier ( void * qual )
{
return 0 ;
2001-04-17 09:41:07 +04:00
}
# elif defined(HAVE_AIX_ACLS)
/* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
int sys_acl_get_entry ( SMB_ACL_T theacl , int entry_id , SMB_ACL_ENTRY_T * entry_p )
{
struct acl_entry_link * link ;
struct new_acl_entry * entry ;
int keep_going ;
DEBUG ( 10 , ( " This is the count: %d \n " , theacl - > count ) ) ;
/* Check if count was previously set to -1. *
* If it was , that means we reached the end *
* of the acl last time . */
if ( theacl - > count = = - 1 )
return ( 0 ) ;
link = theacl ;
/* To get to the next acl, traverse linked list until index *
* of acl matches the count we are keeping . This count is *
* incremented each time we return an acl entry . */
for ( keep_going = 0 ; keep_going < theacl - > count ; keep_going + + )
link = link - > nextp ;
entry = * entry_p = link - > entryp ;
DEBUG ( 10 , ( " *entry_p is %d \n " , entry_p ) ) ;
DEBUG ( 10 , ( " *entry_p->ace_access is %d \n " , entry - > ace_access ) ) ;
/* Increment count */
theacl - > count + + ;
if ( link - > nextp = = NULL )
theacl - > count = - 1 ;
return ( 1 ) ;
}
int sys_acl_get_tag_type ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_TAG_T * tag_type_p )
{
/* Initialize tag type */
* tag_type_p = - 1 ;
DEBUG ( 10 , ( " the tagtype is %d \n " , entry_d - > ace_id - > id_type ) ) ;
/* Depending on what type of entry we have, *
* return tag type . */
switch ( entry_d - > ace_id - > id_type ) {
case ACEID_USER :
* tag_type_p = SMB_ACL_USER ;
break ;
case ACEID_GROUP :
* tag_type_p = SMB_ACL_GROUP ;
break ;
case SMB_ACL_USER_OBJ :
case SMB_ACL_GROUP_OBJ :
case SMB_ACL_OTHER :
* tag_type_p = entry_d - > ace_id - > id_type ;
break ;
default :
return ( - 1 ) ;
}
return ( 0 ) ;
}
int sys_acl_get_permset ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_PERMSET_T * permset_p )
{
DEBUG ( 10 , ( " Starting AIX sys_acl_get_permset \n " ) ) ;
* permset_p = & entry_d - > ace_access ;
DEBUG ( 10 , ( " **permset_p is %d \n " , * * permset_p ) ) ;
if ( ! ( * * permset_p & S_IXUSR ) & &
! ( * * permset_p & S_IWUSR ) & &
! ( * * permset_p & S_IRUSR ) & &
( * * permset_p ! = 0 ) )
return ( - 1 ) ;
DEBUG ( 10 , ( " Ending AIX sys_acl_get_permset \n " ) ) ;
return ( 0 ) ;
}
void * sys_acl_get_qualifier ( SMB_ACL_ENTRY_T entry_d )
{
return ( entry_d - > ace_id - > id_data ) ;
}
SMB_ACL_T sys_acl_get_file ( const char * path_p , SMB_ACL_TYPE_T type )
{
struct acl * file_acl = ( struct acl * ) NULL ;
struct acl_entry * acl_entry ;
struct new_acl_entry * new_acl_entry ;
struct ace_id * idp ;
struct acl_entry_link * acl_entry_link ;
struct acl_entry_link * acl_entry_link_head ;
int i ;
int rc = 0 ;
uid_t user_id ;
/* Get the acl using statacl */
DEBUG ( 10 , ( " Entering sys_acl_get_file \n " ) ) ;
DEBUG ( 10 , ( " path_p is %s \n " , path_p ) ) ;
file_acl = ( struct acl * ) malloc ( BUFSIZ ) ;
if ( file_acl = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in AIX sys_acl_get_file: %d \n " , errno ) ) ;
return ( NULL ) ;
}
memset ( file_acl , 0 , BUFSIZ ) ;
rc = statacl ( ( char * ) path_p , 0 , file_acl , BUFSIZ ) ;
if ( rc = = - 1 ) {
DEBUG ( 0 , ( " statacl returned %d with errno %d \n " , rc , errno ) ) ;
free ( file_acl ) ;
return ( NULL ) ;
}
DEBUG ( 10 , ( " Got facl and returned it \n " ) ) ;
/* Point to the first acl entry in the acl */
acl_entry = file_acl - > acl_ext ;
/* Begin setting up the head of the linked list *
* that will be used for the storing the acl *
* in a way that is useful for the posix_acls . c *
* code . */
acl_entry_link_head = acl_entry_link = sys_acl_init ( 0 ) ;
if ( acl_entry_link_head = = NULL )
return ( NULL ) ;
acl_entry_link - > entryp = ( struct new_acl_entry * ) malloc ( sizeof ( struct new_acl_entry ) ) ;
if ( acl_entry_link - > entryp = = NULL ) {
free ( file_acl ) ;
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in AIX sys_acl_get_file is %d \n " , errno ) ) ;
return ( NULL ) ;
}
DEBUG ( 10 , ( " acl_entry is %d \n " , acl_entry ) ) ;
DEBUG ( 10 , ( " acl_last(file_acl) id %d \n " , acl_last ( file_acl ) ) ) ;
/* Check if the extended acl bit is on. *
* If it isn ' t , do not show the *
* contents of the acl since AIX intends *
* the extended info to remain unused */
if ( file_acl - > acl_mode & S_IXACL ) {
/* while we are not pointing to the very end */
while ( acl_entry < acl_last ( file_acl ) ) {
/* before we malloc anything, make sure this is */
/* a valid acl entry and one that we want to map */
idp = id_nxt ( acl_entry - > ace_id ) ;
if ( ( acl_entry - > ace_type = = ACC_SPECIFY | |
( acl_entry - > ace_type = = ACC_PERMIT ) ) & & ( idp ! = id_last ( acl_entry ) ) ) {
acl_entry = acl_nxt ( acl_entry ) ;
continue ;
}
idp = acl_entry - > ace_id ;
/* Check if this is the first entry in the linked list. *
* The first entry needs to keep prevp pointing to NULL *
* and already has entryp allocated . */
if ( acl_entry_link_head - > count ! = 0 ) {
acl_entry_link - > nextp = ( struct acl_entry_link * )
malloc ( sizeof ( struct acl_entry_link ) ) ;
if ( acl_entry_link - > nextp = = NULL ) {
free ( file_acl ) ;
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in AIX sys_acl_get_file is %d \n " , errno ) ) ;
return ( NULL ) ;
}
acl_entry_link - > nextp - > prevp = acl_entry_link ;
acl_entry_link = acl_entry_link - > nextp ;
acl_entry_link - > entryp = ( struct new_acl_entry * ) malloc ( sizeof ( struct new_acl_entry ) ) ;
if ( acl_entry_link - > entryp = = NULL ) {
free ( file_acl ) ;
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in AIX sys_acl_get_file is %d \n " , errno ) ) ;
return ( NULL ) ;
}
acl_entry_link - > nextp = NULL ;
}
acl_entry_link - > entryp - > ace_len = acl_entry - > ace_len ;
/* Don't really need this since all types are going *
* to be specified but , it ' s better than leaving it 0 */
acl_entry_link - > entryp - > ace_type = acl_entry - > ace_type ;
acl_entry_link - > entryp - > ace_access = acl_entry - > ace_access ;
memcpy ( acl_entry_link - > entryp - > ace_id , idp , sizeof ( struct ace_id ) ) ;
/* The access in the acl entries must be left shifted by *
* three bites , because they will ultimately be compared *
* to S_IRUSR , S_IWUSR , and S_IXUSR . */
switch ( acl_entry - > ace_type ) {
case ACC_PERMIT :
case ACC_SPECIFY :
acl_entry_link - > entryp - > ace_access = acl_entry - > ace_access ;
acl_entry_link - > entryp - > ace_access < < = 6 ;
acl_entry_link_head - > count + + ;
break ;
case ACC_DENY :
/* Since there is no way to return a DENY acl entry *
* change to PERMIT and then shift . */
DEBUG ( 10 , ( " acl_entry->ace_access is %d \n " , acl_entry - > ace_access ) ) ;
acl_entry_link - > entryp - > ace_access = ~ acl_entry - > ace_access & 7 ;
DEBUG ( 10 , ( " acl_entry_link->entryp->ace_access is %d \n " , acl_entry_link - > entryp - > ace_access ) ) ;
acl_entry_link - > entryp - > ace_access < < = 6 ;
acl_entry_link_head - > count + + ;
break ;
default :
return ( 0 ) ;
}
DEBUG ( 10 , ( " acl_entry = %d \n " , acl_entry ) ) ;
DEBUG ( 10 , ( " The ace_type is %d \n " , acl_entry - > ace_type ) ) ;
acl_entry = acl_nxt ( acl_entry ) ;
}
} /* end of if enabled */
/* Since owner, group, other acl entries are not *
* part of the acl entries in an acl , they must *
* be dummied up to become part of the list . */
for ( i = 1 ; i < 4 ; i + + ) {
DEBUG ( 10 , ( " i is %d \n " , i ) ) ;
if ( acl_entry_link_head - > count ! = 0 ) {
acl_entry_link - > nextp = ( struct acl_entry_link * ) malloc ( sizeof ( struct acl_entry_link ) ) ;
if ( acl_entry_link - > nextp = = NULL ) {
free ( file_acl ) ;
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in AIX sys_acl_get_file is %d \n " , errno ) ) ;
return ( NULL ) ;
}
acl_entry_link - > nextp - > prevp = acl_entry_link ;
acl_entry_link = acl_entry_link - > nextp ;
acl_entry_link - > entryp = ( struct new_acl_entry * ) malloc ( sizeof ( struct new_acl_entry ) ) ;
if ( acl_entry_link - > entryp = = NULL ) {
free ( file_acl ) ;
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in AIX sys_acl_get_file is %d \n " , errno ) ) ;
return ( NULL ) ;
}
}
acl_entry_link - > nextp = NULL ;
new_acl_entry = acl_entry_link - > entryp ;
idp = new_acl_entry - > ace_id ;
new_acl_entry - > ace_len = sizeof ( struct acl_entry ) ;
new_acl_entry - > ace_type = ACC_PERMIT ;
idp - > id_len = sizeof ( struct ace_id ) ;
DEBUG ( 10 , ( " idp->id_len = %d \n " , idp - > id_len ) ) ;
memset ( idp - > id_data , 0 , sizeof ( uid_t ) ) ;
switch ( i ) {
case 2 :
new_acl_entry - > ace_access = file_acl - > g_access < < 6 ;
idp - > id_type = SMB_ACL_GROUP_OBJ ;
break ;
case 3 :
new_acl_entry - > ace_access = file_acl - > o_access < < 6 ;
idp - > id_type = SMB_ACL_OTHER ;
break ;
case 1 :
new_acl_entry - > ace_access = file_acl - > u_access < < 6 ;
idp - > id_type = SMB_ACL_USER_OBJ ;
break ;
default :
return ( NULL ) ;
}
acl_entry_link_head - > count + + ;
DEBUG ( 10 , ( " new_acl_entry->ace_access = %d \n " , new_acl_entry - > ace_access ) ) ;
}
acl_entry_link_head - > count = 0 ;
free ( file_acl ) ;
return ( acl_entry_link_head ) ;
}
SMB_ACL_T sys_acl_get_fd ( int fd )
{
struct acl * file_acl = ( struct acl * ) NULL ;
struct acl_entry * acl_entry ;
struct new_acl_entry * new_acl_entry ;
struct ace_id * idp ;
struct acl_entry_link * acl_entry_link ;
struct acl_entry_link * acl_entry_link_head ;
int i ;
int rc = 0 ;
uid_t user_id ;
/* Get the acl using fstatacl */
DEBUG ( 10 , ( " Entering sys_acl_get_fd \n " ) ) ;
DEBUG ( 10 , ( " fd is %d \n " , fd ) ) ;
file_acl = ( struct acl * ) malloc ( BUFSIZ ) ;
if ( file_acl = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_get_fd is %d \n " , errno ) ) ;
return ( NULL ) ;
}
memset ( file_acl , 0 , BUFSIZ ) ;
rc = fstatacl ( fd , 0 , file_acl , BUFSIZ ) ;
if ( rc = = - 1 ) {
DEBUG ( 0 , ( " The fstatacl call returned %d with errno %d \n " , rc , errno ) ) ;
free ( file_acl ) ;
return ( NULL ) ;
}
DEBUG ( 10 , ( " Got facl and returned it \n " ) ) ;
/* Point to the first acl entry in the acl */
acl_entry = file_acl - > acl_ext ;
/* Begin setting up the head of the linked list *
* that will be used for the storing the acl *
* in a way that is useful for the posix_acls . c *
* code . */
acl_entry_link_head = acl_entry_link = sys_acl_init ( 0 ) ;
if ( acl_entry_link_head = = NULL ) {
free ( file_acl ) ;
return ( NULL ) ;
}
acl_entry_link - > entryp = ( struct new_acl_entry * ) malloc ( sizeof ( struct new_acl_entry ) ) ;
if ( acl_entry_link - > entryp = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_get_fd is %d \n " , errno ) ) ;
free ( file_acl ) ;
return ( NULL ) ;
}
DEBUG ( 10 , ( " acl_entry is %d \n " , acl_entry ) ) ;
DEBUG ( 10 , ( " acl_last(file_acl) id %d \n " , acl_last ( file_acl ) ) ) ;
/* Check if the extended acl bit is on. *
* If it isn ' t , do not show the *
* contents of the acl since AIX intends *
* the extended info to remain unused */
if ( file_acl - > acl_mode & S_IXACL ) {
/* while we are not pointing to the very end */
while ( acl_entry < acl_last ( file_acl ) ) {
/* before we malloc anything, make sure this is */
/* a valid acl entry and one that we want to map */
idp = id_nxt ( acl_entry - > ace_id ) ;
if ( ( acl_entry - > ace_type = = ACC_SPECIFY | |
( acl_entry - > ace_type = = ACC_PERMIT ) ) & & ( idp ! = id_last ( acl_entry ) ) ) {
acl_entry = acl_nxt ( acl_entry ) ;
continue ;
}
idp = acl_entry - > ace_id ;
/* Check if this is the first entry in the linked list. *
* The first entry needs to keep prevp pointing to NULL *
* and already has entryp allocated . */
if ( acl_entry_link_head - > count ! = 0 ) {
acl_entry_link - > nextp = ( struct acl_entry_link * ) malloc ( sizeof ( struct acl_entry_link ) ) ;
if ( acl_entry_link - > nextp = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_get_fd is %d \n " , errno ) ) ;
free ( file_acl ) ;
return ( NULL ) ;
}
acl_entry_link - > nextp - > prevp = acl_entry_link ;
acl_entry_link = acl_entry_link - > nextp ;
acl_entry_link - > entryp = ( struct new_acl_entry * ) malloc ( sizeof ( struct new_acl_entry ) ) ;
if ( acl_entry_link - > entryp = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_get_fd is %d \n " , errno ) ) ;
free ( file_acl ) ;
return ( NULL ) ;
}
acl_entry_link - > nextp = NULL ;
}
acl_entry_link - > entryp - > ace_len = acl_entry - > ace_len ;
/* Don't really need this since all types are going *
* to be specified but , it ' s better than leaving it 0 */
acl_entry_link - > entryp - > ace_type = acl_entry - > ace_type ;
acl_entry_link - > entryp - > ace_access = acl_entry - > ace_access ;
memcpy ( acl_entry_link - > entryp - > ace_id , idp , sizeof ( struct ace_id ) ) ;
/* The access in the acl entries must be left shifted by *
* three bites , because they will ultimately be compared *
* to S_IRUSR , S_IWUSR , and S_IXUSR . */
switch ( acl_entry - > ace_type ) {
case ACC_PERMIT :
case ACC_SPECIFY :
acl_entry_link - > entryp - > ace_access = acl_entry - > ace_access ;
acl_entry_link - > entryp - > ace_access < < = 6 ;
acl_entry_link_head - > count + + ;
break ;
case ACC_DENY :
/* Since there is no way to return a DENY acl entry *
* change to PERMIT and then shift . */
DEBUG ( 10 , ( " acl_entry->ace_access is %d \n " , acl_entry - > ace_access ) ) ;
acl_entry_link - > entryp - > ace_access = ~ acl_entry - > ace_access & 7 ;
DEBUG ( 10 , ( " acl_entry_link->entryp->ace_access is %d \n " , acl_entry_link - > entryp - > ace_access ) ) ;
acl_entry_link - > entryp - > ace_access < < = 6 ;
acl_entry_link_head - > count + + ;
break ;
default :
return ( 0 ) ;
}
DEBUG ( 10 , ( " acl_entry = %d \n " , acl_entry ) ) ;
DEBUG ( 10 , ( " The ace_type is %d \n " , acl_entry - > ace_type ) ) ;
acl_entry = acl_nxt ( acl_entry ) ;
}
} /* end of if enabled */
/* Since owner, group, other acl entries are not *
* part of the acl entries in an acl , they must *
* be dummied up to become part of the list . */
for ( i = 1 ; i < 4 ; i + + ) {
DEBUG ( 10 , ( " i is %d \n " , i ) ) ;
if ( acl_entry_link_head - > count ! = 0 ) {
acl_entry_link - > nextp = ( struct acl_entry_link * ) malloc ( sizeof ( struct acl_entry_link ) ) ;
if ( acl_entry_link - > nextp = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_get_fd is %d \n " , errno ) ) ;
free ( file_acl ) ;
return ( NULL ) ;
}
acl_entry_link - > nextp - > prevp = acl_entry_link ;
acl_entry_link = acl_entry_link - > nextp ;
acl_entry_link - > entryp = ( struct new_acl_entry * ) malloc ( sizeof ( struct new_acl_entry ) ) ;
if ( acl_entry_link - > entryp = = NULL ) {
free ( file_acl ) ;
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_get_fd is %d \n " , errno ) ) ;
return ( NULL ) ;
}
}
acl_entry_link - > nextp = NULL ;
new_acl_entry = acl_entry_link - > entryp ;
idp = new_acl_entry - > ace_id ;
new_acl_entry - > ace_len = sizeof ( struct acl_entry ) ;
new_acl_entry - > ace_type = ACC_PERMIT ;
idp - > id_len = sizeof ( struct ace_id ) ;
DEBUG ( 10 , ( " idp->id_len = %d \n " , idp - > id_len ) ) ;
memset ( idp - > id_data , 0 , sizeof ( uid_t ) ) ;
switch ( i ) {
case 2 :
new_acl_entry - > ace_access = file_acl - > g_access < < 6 ;
idp - > id_type = SMB_ACL_GROUP_OBJ ;
break ;
case 3 :
new_acl_entry - > ace_access = file_acl - > o_access < < 6 ;
idp - > id_type = SMB_ACL_OTHER ;
break ;
case 1 :
new_acl_entry - > ace_access = file_acl - > u_access < < 6 ;
idp - > id_type = SMB_ACL_USER_OBJ ;
break ;
default :
return ( NULL ) ;
}
acl_entry_link_head - > count + + ;
DEBUG ( 10 , ( " new_acl_entry->ace_access = %d \n " , new_acl_entry - > ace_access ) ) ;
}
acl_entry_link_head - > count = 0 ;
free ( file_acl ) ;
return ( acl_entry_link_head ) ;
}
int sys_acl_clear_perms ( SMB_ACL_PERMSET_T permset )
{
* permset = * permset & ~ 0777 ;
return ( 0 ) ;
}
int sys_acl_add_perm ( SMB_ACL_PERMSET_T permset , SMB_ACL_PERM_T perm )
{
if ( ( perm ! = 0 ) & &
( perm & ( S_IXUSR | S_IWUSR | S_IRUSR ) ) = = 0 )
return ( - 1 ) ;
* permset | = perm ;
DEBUG ( 10 , ( " This is the permset now: %d \n " , * permset ) ) ;
return ( 0 ) ;
}
char * sys_acl_to_text ( SMB_ACL_T theacl , ssize_t * plen )
{
return ( NULL ) ;
}
SMB_ACL_T sys_acl_init ( int count )
{
struct acl_entry_link * theacl = NULL ;
DEBUG ( 10 , ( " Entering sys_acl_init \n " ) ) ;
theacl = ( struct acl_entry_link * ) malloc ( sizeof ( struct acl_entry_link ) ) ;
if ( theacl = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_init is %d \n " , errno ) ) ;
return ( NULL ) ;
}
theacl - > count = 0 ;
theacl - > nextp = NULL ;
theacl - > prevp = NULL ;
theacl - > entryp = NULL ;
DEBUG ( 10 , ( " Exiting sys_acl_init \n " ) ) ;
return ( theacl ) ;
}
int sys_acl_create_entry ( SMB_ACL_T * pacl , SMB_ACL_ENTRY_T * pentry )
{
struct acl_entry_link * theacl ;
struct acl_entry_link * acl_entryp ;
struct acl_entry_link * temp_entry ;
int counting ;
DEBUG ( 10 , ( " Entering the sys_acl_create_entry \n " ) ) ;
theacl = acl_entryp = * pacl ;
/* Get to the end of the acl before adding entry */
for ( counting = 0 ; counting < theacl - > count ; counting + + ) {
DEBUG ( 10 , ( " The acl_entryp is %d \n " , acl_entryp ) ) ;
temp_entry = acl_entryp ;
acl_entryp = acl_entryp - > nextp ;
}
if ( theacl - > count ! = 0 ) {
temp_entry - > nextp = acl_entryp = ( struct acl_entry_link * ) malloc ( sizeof ( struct acl_entry_link ) ) ;
if ( acl_entryp = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_create_entry is %d \n " , errno ) ) ;
return ( - 1 ) ;
}
DEBUG ( 10 , ( " The acl_entryp is %d \n " , acl_entryp ) ) ;
acl_entryp - > prevp = temp_entry ;
DEBUG ( 10 , ( " The acl_entryp->prevp is %d \n " , acl_entryp - > prevp ) ) ;
}
* pentry = acl_entryp - > entryp = ( struct new_acl_entry * ) malloc ( sizeof ( struct new_acl_entry ) ) ;
if ( * pentry = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_create_entry is %d \n " , errno ) ) ;
return ( - 1 ) ;
}
memset ( * pentry , 0 , sizeof ( struct new_acl_entry ) ) ;
acl_entryp - > entryp - > ace_len = sizeof ( struct acl_entry ) ;
acl_entryp - > entryp - > ace_type = ACC_PERMIT ;
acl_entryp - > entryp - > ace_id - > id_len = sizeof ( struct ace_id ) ;
acl_entryp - > nextp = NULL ;
theacl - > count + + ;
DEBUG ( 10 , ( " Exiting sys_acl_create_entry \n " ) ) ;
return ( 0 ) ;
}
int sys_acl_set_tag_type ( SMB_ACL_ENTRY_T entry , SMB_ACL_TAG_T tagtype )
{
DEBUG ( 10 , ( " Starting AIX sys_acl_set_tag_type \n " ) ) ;
entry - > ace_id - > id_type = tagtype ;
DEBUG ( 10 , ( " The tag type is %d \n " , entry - > ace_id - > id_type ) ) ;
DEBUG ( 10 , ( " Ending AIX sys_acl_set_tag_type \n " ) ) ;
}
int sys_acl_set_qualifier ( SMB_ACL_ENTRY_T entry , void * qual )
{
DEBUG ( 10 , ( " Starting AIX sys_acl_set_qualifier \n " ) ) ;
memcpy ( entry - > ace_id - > id_data , qual , sizeof ( uid_t ) ) ;
DEBUG ( 10 , ( " Ending AIX sys_acl_set_qualifier \n " ) ) ;
return ( 0 ) ;
}
int sys_acl_set_permset ( SMB_ACL_ENTRY_T entry , SMB_ACL_PERMSET_T permset )
{
DEBUG ( 10 , ( " Starting AIX sys_acl_set_permset \n " ) ) ;
if ( ! ( * permset & S_IXUSR ) & &
! ( * permset & S_IWUSR ) & &
! ( * permset & S_IRUSR ) & &
( * permset ! = 0 ) )
return ( - 1 ) ;
entry - > ace_access = * permset ;
DEBUG ( 10 , ( " entry->ace_access = %d \n " , entry - > ace_access ) ) ;
DEBUG ( 10 , ( " Ending AIX sys_acl_set_permset \n " ) ) ;
return ( 0 ) ;
}
int sys_acl_valid ( SMB_ACL_T theacl )
{
int user_obj = 0 ;
int group_obj = 0 ;
int other_obj = 0 ;
struct acl_entry_link * acl_entry ;
for ( acl_entry = theacl ; acl_entry ! = NULL ; acl_entry = acl_entry - > nextp ) {
user_obj + = ( acl_entry - > entryp - > ace_id - > id_type = = SMB_ACL_USER_OBJ ) ;
group_obj + = ( acl_entry - > entryp - > ace_id - > id_type = = SMB_ACL_GROUP_OBJ ) ;
other_obj + = ( acl_entry - > entryp - > ace_id - > id_type = = SMB_ACL_OTHER ) ;
}
DEBUG ( 10 , ( " user_obj=%d, group_obj=%d, other_obj=%d \n " , user_obj , group_obj , other_obj ) ) ;
if ( user_obj ! = 1 | | group_obj ! = 1 | | other_obj ! = 1 )
return ( - 1 ) ;
return ( 0 ) ;
}
2001-06-08 23:29:57 +04:00
int sys_acl_set_file ( const char * name , SMB_ACL_TYPE_T acltype , SMB_ACL_T theacl )
2001-04-17 09:41:07 +04:00
{
struct acl_entry_link * acl_entry_link = NULL ;
struct acl * file_acl = NULL ;
struct acl * file_acl_temp = NULL ;
struct acl_entry * acl_entry = NULL ;
struct ace_id * ace_id = NULL ;
uint id_type ;
uint ace_access ;
uint user_id ;
uint acl_length ;
uint rc ;
DEBUG ( 10 , ( " Entering sys_acl_set_file \n " ) ) ;
DEBUG ( 10 , ( " File name is %s \n " , name ) ) ;
/* AIX has no default ACL */
if ( acltype = = SMB_ACL_TYPE_DEFAULT )
return ( 0 ) ;
acl_length = BUFSIZ ;
file_acl = ( struct acl * ) malloc ( BUFSIZ ) ;
if ( file_acl = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_set_file is %d \n " , errno ) ) ;
return ( - 1 ) ;
}
memset ( file_acl , 0 , BUFSIZ ) ;
file_acl - > acl_len = ACL_SIZ ;
file_acl - > acl_mode = S_IXACL ;
for ( acl_entry_link = theacl ; acl_entry_link ! = NULL ; acl_entry_link = acl_entry_link - > nextp ) {
acl_entry_link - > entryp - > ace_access > > = 6 ;
id_type = acl_entry_link - > entryp - > ace_id - > id_type ;
switch ( id_type ) {
case SMB_ACL_USER_OBJ :
file_acl - > u_access = acl_entry_link - > entryp - > ace_access ;
continue ;
case SMB_ACL_GROUP_OBJ :
file_acl - > g_access = acl_entry_link - > entryp - > ace_access ;
continue ;
case SMB_ACL_OTHER :
file_acl - > o_access = acl_entry_link - > entryp - > ace_access ;
continue ;
case SMB_ACL_MASK :
continue ;
}
if ( ( file_acl - > acl_len + sizeof ( struct acl_entry ) ) > acl_length ) {
acl_length + = sizeof ( struct acl_entry ) ;
file_acl_temp = ( struct acl * ) malloc ( acl_length ) ;
if ( file_acl_temp = = NULL ) {
free ( file_acl ) ;
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_set_file is %d \n " , errno ) ) ;
return ( - 1 ) ;
}
memcpy ( file_acl_temp , file_acl , file_acl - > acl_len ) ;
free ( file_acl ) ;
file_acl = file_acl_temp ;
}
acl_entry = ( struct acl_entry * ) ( ( char * ) file_acl + file_acl - > acl_len ) ;
file_acl - > acl_len + = sizeof ( struct acl_entry ) ;
acl_entry - > ace_len = acl_entry_link - > entryp - > ace_len ;
acl_entry - > ace_access = acl_entry_link - > entryp - > ace_access ;
/* In order to use this, we'll need to wait until we can get denies */
/* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
acl_entry - > ace_type = ACC_SPECIFY ; */
acl_entry - > ace_type = ACC_SPECIFY ;
ace_id = acl_entry - > ace_id ;
ace_id - > id_type = acl_entry_link - > entryp - > ace_id - > id_type ;
DEBUG ( 10 , ( " The id type is %d \n " , ace_id - > id_type ) ) ;
ace_id - > id_len = acl_entry_link - > entryp - > ace_id - > id_len ;
memcpy ( & user_id , acl_entry_link - > entryp - > ace_id - > id_data , sizeof ( uid_t ) ) ;
memcpy ( acl_entry - > ace_id - > id_data , & user_id , sizeof ( uid_t ) ) ;
}
rc = chacl ( name , file_acl , file_acl - > acl_len ) ;
DEBUG ( 10 , ( " errno is %d \n " , errno ) ) ;
DEBUG ( 10 , ( " return code is %d \n " , rc ) ) ;
free ( file_acl ) ;
DEBUG ( 10 , ( " Exiting the sys_acl_set_file \n " ) ) ;
return ( rc ) ;
}
int sys_acl_set_fd ( int fd , SMB_ACL_T theacl )
{
struct acl_entry_link * acl_entry_link = NULL ;
struct acl * file_acl = NULL ;
struct acl * file_acl_temp = NULL ;
struct acl_entry * acl_entry = NULL ;
struct ace_id * ace_id = NULL ;
uint id_type ;
uint user_id ;
uint acl_length ;
uint rc ;
DEBUG ( 10 , ( " Entering sys_acl_set_fd \n " ) ) ;
acl_length = BUFSIZ ;
file_acl = ( struct acl * ) malloc ( BUFSIZ ) ;
if ( file_acl = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_set_fd is %d \n " , errno ) ) ;
return ( - 1 ) ;
}
memset ( file_acl , 0 , BUFSIZ ) ;
file_acl - > acl_len = ACL_SIZ ;
file_acl - > acl_mode = S_IXACL ;
for ( acl_entry_link = theacl ; acl_entry_link ! = NULL ; acl_entry_link = acl_entry_link - > nextp ) {
acl_entry_link - > entryp - > ace_access > > = 6 ;
id_type = acl_entry_link - > entryp - > ace_id - > id_type ;
DEBUG ( 10 , ( " The id_type is %d \n " , id_type ) ) ;
switch ( id_type ) {
case SMB_ACL_USER_OBJ :
file_acl - > u_access = acl_entry_link - > entryp - > ace_access ;
continue ;
case SMB_ACL_GROUP_OBJ :
file_acl - > g_access = acl_entry_link - > entryp - > ace_access ;
continue ;
case SMB_ACL_OTHER :
file_acl - > o_access = acl_entry_link - > entryp - > ace_access ;
continue ;
case SMB_ACL_MASK :
continue ;
}
if ( ( file_acl - > acl_len + sizeof ( struct acl_entry ) ) > acl_length ) {
acl_length + = sizeof ( struct acl_entry ) ;
file_acl_temp = ( struct acl * ) malloc ( acl_length ) ;
if ( file_acl_temp = = NULL ) {
free ( file_acl ) ;
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in sys_acl_set_fd is %d \n " , errno ) ) ;
return ( - 1 ) ;
}
memcpy ( file_acl_temp , file_acl , file_acl - > acl_len ) ;
free ( file_acl ) ;
file_acl = file_acl_temp ;
}
acl_entry = ( struct acl_entry * ) ( ( char * ) file_acl + file_acl - > acl_len ) ;
file_acl - > acl_len + = sizeof ( struct acl_entry ) ;
acl_entry - > ace_len = acl_entry_link - > entryp - > ace_len ;
acl_entry - > ace_access = acl_entry_link - > entryp - > ace_access ;
/* In order to use this, we'll need to wait until we can get denies */
/* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
acl_entry - > ace_type = ACC_SPECIFY ; */
acl_entry - > ace_type = ACC_SPECIFY ;
ace_id = acl_entry - > ace_id ;
ace_id - > id_type = acl_entry_link - > entryp - > ace_id - > id_type ;
DEBUG ( 10 , ( " The id type is %d \n " , ace_id - > id_type ) ) ;
ace_id - > id_len = acl_entry_link - > entryp - > ace_id - > id_len ;
memcpy ( & user_id , acl_entry_link - > entryp - > ace_id - > id_data , sizeof ( uid_t ) ) ;
memcpy ( ace_id - > id_data , & user_id , sizeof ( uid_t ) ) ;
}
rc = fchacl ( fd , file_acl , file_acl - > acl_len ) ;
DEBUG ( 10 , ( " errno is %d \n " , errno ) ) ;
DEBUG ( 10 , ( " return code is %d \n " , rc ) ) ;
free ( file_acl ) ;
DEBUG ( 10 , ( " Exiting sys_acl_set_fd \n " ) ) ;
return ( rc ) ;
}
int sys_acl_get_perm ( SMB_ACL_PERMSET_T permset , SMB_ACL_PERM_T perm )
{
return ( * permset & perm ) ;
}
int sys_acl_free_text ( char * text )
{
return ( 0 ) ;
}
int sys_acl_free_acl ( SMB_ACL_T posix_acl )
{
struct acl_entry_link * acl_entry_link ;
for ( acl_entry_link = posix_acl - > nextp ; acl_entry_link - > nextp ! = NULL ; acl_entry_link = acl_entry_link - > nextp ) {
free ( acl_entry_link - > prevp - > entryp ) ;
free ( acl_entry_link - > prevp ) ;
}
free ( acl_entry_link - > prevp - > entryp ) ;
free ( acl_entry_link - > prevp ) ;
free ( acl_entry_link - > entryp ) ;
free ( acl_entry_link ) ;
return ( 0 ) ;
}
int sys_acl_free_qualifier ( void * qual )
{
return ( 0 ) ;
2001-04-14 01:11:57 +04:00
}
2000-12-06 05:32:48 +03:00
# else /* No ACLs. */
2000-12-07 02:24:31 +03:00
2000-12-14 08:38:05 +03:00
int sys_acl_get_entry ( SMB_ACL_T the_acl , int entry_id , SMB_ACL_ENTRY_T * entry_p )
2000-12-06 05:32:48 +03:00
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-07 02:24:31 +03:00
return - 1 ;
2000-12-06 05:32:48 +03:00
}
int sys_acl_get_tag_type ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_TAG_T * tag_type_p )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-07 02:24:31 +03:00
return - 1 ;
2000-12-06 05:32:48 +03:00
}
int sys_acl_get_permset ( SMB_ACL_ENTRY_T entry_d , SMB_ACL_PERMSET_T * permset_p )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-07 02:24:31 +03:00
return - 1 ;
2000-12-06 05:32:48 +03:00
}
void * sys_acl_get_qualifier ( SMB_ACL_ENTRY_T entry_d )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-07 02:24:31 +03:00
return NULL ;
2000-12-06 05:32:48 +03:00
}
SMB_ACL_T sys_acl_get_file ( const char * path_p , SMB_ACL_TYPE_T type )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-07 02:24:31 +03:00
return ( SMB_ACL_T ) NULL ;
}
SMB_ACL_T sys_acl_get_fd ( int fd )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-07 02:24:31 +03:00
return ( SMB_ACL_T ) NULL ;
2000-12-06 05:32:48 +03:00
}
2000-12-07 08:38:01 +03:00
int sys_acl_clear_perms ( SMB_ACL_PERMSET_T permset )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-07 08:38:01 +03:00
return - 1 ;
}
int sys_acl_add_perm ( SMB_ACL_PERMSET_T permset , SMB_ACL_PERM_T perm )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-07 08:38:01 +03:00
return - 1 ;
}
int sys_acl_get_perm ( SMB_ACL_PERMSET_T permset , SMB_ACL_PERM_T perm )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-07 08:38:01 +03:00
return ( permset & perm ) ? 1 : 0 ;
}
2000-12-14 08:38:05 +03:00
char * sys_acl_to_text ( SMB_ACL_T the_acl , ssize_t * plen )
2000-12-07 08:38:01 +03:00
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-07 08:38:01 +03:00
return NULL ;
}
2000-12-19 21:41:51 +03:00
int sys_acl_free_text ( char * text )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-19 21:41:51 +03:00
return - 1 ;
}
2001-01-12 01:37:59 +03:00
SMB_ACL_T sys_acl_init ( int count )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2001-01-12 01:37:59 +03:00
return NULL ;
}
int sys_acl_create_entry ( SMB_ACL_T * pacl , SMB_ACL_ENTRY_T * pentry )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2001-01-12 01:37:59 +03:00
return - 1 ;
}
int sys_acl_set_tag_type ( SMB_ACL_ENTRY_T entry , SMB_ACL_TAG_T tagtype )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2001-01-12 01:37:59 +03:00
return - 1 ;
}
int sys_acl_set_qualifier ( SMB_ACL_ENTRY_T entry , void * qual )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2001-01-12 01:37:59 +03:00
return - 1 ;
}
int sys_acl_set_permset ( SMB_ACL_ENTRY_T entry , SMB_ACL_PERMSET_T permset )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2001-01-12 01:37:59 +03:00
return - 1 ;
}
int sys_acl_valid ( SMB_ACL_T theacl )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2001-01-12 01:37:59 +03:00
return - 1 ;
}
2001-06-08 23:29:57 +04:00
int sys_acl_set_file ( const char * name , SMB_ACL_TYPE_T acltype , SMB_ACL_T theacl )
2001-01-12 01:37:59 +03:00
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2001-01-12 01:37:59 +03:00
return - 1 ;
}
2001-01-12 02:41:33 +03:00
int sys_acl_set_fd ( int fd , SMB_ACL_T theacl )
2001-01-12 01:37:59 +03:00
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2001-01-12 01:37:59 +03:00
return - 1 ;
}
2001-06-08 23:29:57 +04:00
int sys_acl_delete_def_file ( const char * name )
{
errno = ENOSYS ;
return - 1 ;
}
2000-12-19 21:41:51 +03:00
int sys_acl_free_acl ( SMB_ACL_T the_acl )
{
2001-03-22 04:26:37 +03:00
errno = ENOSYS ;
2000-12-19 21:41:51 +03:00
return - 1 ;
}
2001-04-14 01:11:57 +04:00
int sys_acl_free_qualifier ( void * qual )
{
errno = ENOSYS ;
return - 1 ;
}
2000-12-06 05:32:48 +03:00
# endif /* No ACLs. */