00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "posixacladdons.h"
00021
00022 #if defined(USE_POSIX_ACL) && !defined(HAVE_NON_POSIX_ACL_EXTENSIONS)
00023
00024 #include <kdemacros.h>
00025
00026 #include <errno.h>
00027 #include <sys/stat.h>
00028
00029 #include <tqptrlist.h>
00030
00031 class SortedEntryList : public TQPtrList<acl_entry_t>
00032 {
00033 protected:
00034 int compareItems( TQPtrCollection::Item i1,
00035 TQPtrCollection::Item i2 )
00036 {
00037 acl_entry_t *e1 = static_cast<acl_entry_t*>( i1 );
00038 acl_entry_t *e2 = static_cast<acl_entry_t*>( i2 );
00039
00040 acl_tag_t tag1, tag2;
00041 uid_t uid1 = 0, uid2 = 0;
00042
00043 acl_get_tag_type( *e1, &tag1 );
00044 acl_get_tag_type( *e2, &tag2 );
00045
00046 if ( tag1 == ACL_USER || tag1 == ACL_GROUP )
00047 uid1 = *( (uid_t*) acl_get_qualifier( *e1 ) );
00048
00049 if ( tag2 == ACL_USER || tag2 == ACL_GROUP )
00050 uid2 = *( (uid_t*) acl_get_qualifier( *e2 ) );
00051
00052 if ( tag1 < tag2 )
00053 return -1;
00054 else if ( tag1 > tag2 )
00055 return 1;
00056
00057 if ( uid1 < uid2 )
00058 return -1;
00059 else if ( uid1 > uid2 )
00060 return 1;
00061
00062 return 0;
00063 }
00064 };
00065
00066 KDE_EXPORT int acl_cmp(acl_t acl1, acl_t acl2)
00067 {
00068 if ( !acl1 || !acl2 )
00069 return -1;
00070
00071 SortedEntryList entries1, entries2;
00072 entries1.setAutoDelete( true );
00073 entries2.setAutoDelete( true );
00074
00075
00076 acl_entry_t *entry = new acl_entry_t;
00077 int ret = acl_get_entry( acl1, ACL_FIRST_ENTRY, entry );
00078 while( ret == 1 ) {
00079 entries1.append( entry );
00080 entry = new acl_entry_t;
00081 ret = acl_get_entry( acl1, ACL_NEXT_ENTRY, entry );
00082 }
00083 delete entry;
00084
00085 entry = new acl_entry_t;
00086 ret = acl_get_entry( acl2, ACL_FIRST_ENTRY, entry );
00087 while ( ret == 1 ) {
00088 entries2.append( entry );
00089 entry = new acl_entry_t;
00090 ret = acl_get_entry( acl2, ACL_NEXT_ENTRY, entry );
00091 }
00092 delete entry;
00093
00094
00095 if ( entries1.count() != entries2.count() )
00096 return 1;
00097
00098
00099 entries1.sort();
00100 entries2.sort();
00101
00102
00103 acl_permset_t permset1, permset2;
00104 acl_tag_t tag1, tag2;
00105 uid_t uid1, uid2;
00106 acl_entry_t *e1, *e2;
00107
00108 for ( e1 = entries1.first(), e2 = entries2.first(); e1; e1 = entries1.next(), e2 = entries2.next() ) {
00109
00110 if ( acl_get_tag_type( *e1, &tag1 ) != 0 ) return 1;
00111 if ( acl_get_tag_type( *e2, &tag2 ) != 0 ) return 1;
00112 if ( tag1 != tag2 ) return 1;
00113
00114
00115 if ( acl_get_permset( *e1, &permset1 ) != 0 ) return 1;
00116 if ( acl_get_permset( *e2, &permset2 ) != 0 ) return 1;
00117 if ( *permset1 != *permset2) return 1;
00118
00119
00120 switch( tag1 ) {
00121 case ACL_USER:
00122 case ACL_GROUP:
00123 uid1 = *( (uid_t*) acl_get_qualifier( *e1 ) );
00124 uid2 = *( (uid_t*) acl_get_qualifier( *e2 ) );
00125 if ( uid1 != uid2 ) return 1;
00126 }
00127 }
00128
00129 return 0;
00130 }
00131
00132 KDE_EXPORT acl_t acl_from_mode(mode_t mode)
00133 {
00134 acl_t newACL = acl_init( 3 );
00135 acl_entry_t entry;
00136 acl_permset_t permset;
00137 int error = 0;
00138
00139
00140 if ( ( error = acl_create_entry( &newACL, &entry ) ) == 0 ) {
00141
00142 acl_set_tag_type( entry, ACL_USER_OBJ );
00143 acl_get_permset( entry, &permset );
00144 acl_clear_perms( permset );
00145 if ( mode & S_IRUSR ) acl_add_perm( permset, ACL_READ );
00146 if ( mode & S_IWUSR ) acl_add_perm( permset, ACL_WRITE );
00147 if ( mode & S_IXUSR ) acl_add_perm( permset, ACL_EXECUTE );
00148 acl_set_permset( entry, permset );
00149
00150
00151 if ( ( error = acl_create_entry( &newACL, &entry ) ) == 0 ) {
00152
00153 acl_set_tag_type( entry, ACL_GROUP_OBJ );
00154 acl_get_permset( entry, &permset );
00155 acl_clear_perms( permset );
00156 if ( mode & S_IRGRP ) acl_add_perm( permset, ACL_READ );
00157 if ( mode & S_IWGRP ) acl_add_perm( permset, ACL_WRITE );
00158 if ( mode & S_IXGRP ) acl_add_perm( permset, ACL_EXECUTE );
00159 acl_set_permset( entry, permset );
00160
00161
00162 if ( ( error = acl_create_entry( &newACL, &entry ) ) == 0) {
00163
00164 acl_set_tag_type( entry, ACL_OTHER );
00165 acl_get_permset( entry, &permset );
00166 acl_clear_perms( permset );
00167 if ( mode & S_IROTH ) acl_add_perm( permset, ACL_READ );
00168 if ( mode & S_IWOTH ) acl_add_perm( permset, ACL_WRITE );
00169 if ( mode & S_IXOTH ) acl_add_perm( permset, ACL_EXECUTE );
00170 acl_set_permset( entry, permset );
00171 }
00172 }
00173 }
00174
00175 if ( error ) {
00176 acl_free ( &newACL );
00177 return NULL;
00178 }
00179
00180 return newACL;
00181 }
00182
00183 KDE_EXPORT int acl_equiv_mode(acl_t acl, mode_t *mode_p)
00184 {
00185 acl_entry_t entry;
00186 acl_tag_t tag;
00187 acl_permset_t permset;
00188 mode_t mode = 0;
00189 int notEquiv = 0;
00190
00191 if ( !acl )
00192 return -1;
00193
00194 int ret = acl_get_entry( acl, ACL_FIRST_ENTRY, &entry );
00195 while ( ret == 1 ) {
00196 acl_get_tag_type( entry, &tag );
00197 acl_get_permset( entry, &permset );
00198
00199 switch( tag ) {
00200 case ACL_USER_OBJ:
00201 if ( acl_get_perm( permset, ACL_READ ) ) mode |= S_IRUSR;
00202 if ( acl_get_perm( permset, ACL_WRITE ) ) mode |= S_IWUSR;
00203 if ( acl_get_perm( permset, ACL_EXECUTE ) ) mode |= S_IXUSR;
00204 break;
00205
00206 case ACL_GROUP_OBJ:
00207 if ( acl_get_perm( permset, ACL_READ ) ) mode |= S_IRGRP;
00208 if ( acl_get_perm( permset, ACL_WRITE ) ) mode |= S_IWGRP;
00209 if ( acl_get_perm( permset, ACL_EXECUTE ) ) mode |= S_IXGRP;
00210 break;
00211
00212 case ACL_OTHER:
00213 if ( acl_get_perm( permset, ACL_READ ) ) mode |= S_IROTH;
00214 if ( acl_get_perm( permset, ACL_WRITE ) ) mode |= S_IWOTH;
00215 if ( acl_get_perm( permset, ACL_EXECUTE ) ) mode |= S_IXOTH;
00216 break;
00217
00218 case ACL_USER:
00219 case ACL_GROUP:
00220 case ACL_MASK:
00221 notEquiv = 1;
00222 break;
00223
00224 default:
00225 errno = EINVAL;
00226 return -1;
00227 }
00228
00229 ret = acl_get_entry( acl, ACL_NEXT_ENTRY, &entry );
00230 }
00231
00232 if (mode_p)
00233 *mode_p = mode;
00234
00235 return notEquiv;
00236 }
00237
00238 #endif // USE_POSIX_ACL