25 #include <sys/types.h>
30 #ifdef HAVE_NON_POSIX_ACL_EXTENSIONS
31 #include <acl/libacl.h>
33 #include <posixacladdons.h>
36 #include <tqintdict.h>
44 static void printACL( acl_t acl,
const TQString &comment );
45 static TQString aclAsString(
const acl_t acl);
48 class KACL::KACLPrivate {
50 KACLPrivate() : m_acl( 0 ) { init(); }
52 KACLPrivate( acl_t acl )
53 : m_acl( acl ) { init(); }
54 ~KACLPrivate() {
if ( m_acl ) acl_free( m_acl ); }
57 m_usercache.setAutoDelete(
true );
58 m_groupcache.setAutoDelete(
true );
63 TQString getUserName( uid_t uid )
const;
64 TQString getGroupName( gid_t gid )
const;
65 bool setAllUsersOrGroups(
const TQValueList< QPair<TQString, unsigned short> > &list, acl_tag_t type );
66 bool setNamedUserOrGroupPermissions(
const TQString& name,
unsigned short permissions, acl_tag_t type );
72 mutable TQIntDict<TQString> m_usercache;
73 mutable TQIntDict<TQString> m_groupcache;
77 : d( new KACLPrivate )
84 : d(
new KACLPrivate( acl_from_mode( basePermissions ) ) )
86 : d(
new KACLPrivate )
90 Q_UNUSED( basePermissions );
95 : d( new KACLPrivate )
100 : d( new KACLPrivate )
110 bool KACL::operator==(
const KACL& rhs )
const {
112 return ( acl_cmp( d->m_acl, rhs.d->m_acl ) == 0 );
124 valid = ( acl_valid( d->m_acl ) == 0 );
133 return ( acl_equiv_mode( d->m_acl, NULL ) != 0 );
140 static acl_entry_t entryForTag( acl_t acl, acl_tag_t tag )
143 int ret = acl_get_entry( acl, ACL_FIRST_ENTRY, &entry );
145 acl_tag_t currentTag;
146 acl_get_tag_type( entry, ¤tTag );
147 if ( currentTag == tag )
149 ret = acl_get_entry( acl, ACL_NEXT_ENTRY, &entry );
154 static unsigned short entryToPermissions( acl_entry_t entry )
156 if ( entry == 0 )
return 0;
157 acl_permset_t permset;
158 if ( acl_get_permset( entry, &permset ) != 0 )
return 0;
159 return( acl_get_perm( permset, ACL_READ ) << 2 |
160 acl_get_perm( permset, ACL_WRITE ) << 1 |
161 acl_get_perm( permset, ACL_EXECUTE ) );
164 static void permissionsToEntry( acl_entry_t entry,
unsigned short v )
166 if ( entry == 0 )
return;
167 acl_permset_t permset;
168 if ( acl_get_permset( entry, &permset ) != 0 )
return;
169 acl_clear_perms( permset );
170 if ( v & 4 ) acl_add_perm( permset, ACL_READ );
171 if ( v & 2 ) acl_add_perm( permset, ACL_WRITE );
172 if ( v & 1 ) acl_add_perm( permset, ACL_EXECUTE );
175 static void printACL( acl_t acl,
const TQString &comment )
177 kdDebug() << comment << aclAsString( acl ) << endl;
180 static int getUidForName(
const TQString& name )
182 struct passwd *user = getpwnam( name.latin1() );
189 static int getGidForName(
const TQString& name )
191 struct group *group = getgrnam( name.latin1() );
193 return group->gr_gid;
203 return entryToPermissions( entryForTag( d->m_acl, ACL_USER_OBJ ) );
212 permissionsToEntry( entryForTag( d->m_acl, ACL_USER_OBJ ), v );
222 return entryToPermissions( entryForTag( d->m_acl, ACL_GROUP_OBJ ) );
231 permissionsToEntry( entryForTag( d->m_acl, ACL_GROUP_OBJ ), v );
241 return entryToPermissions( entryForTag( d->m_acl, ACL_OTHER ) );
250 permissionsToEntry( entryForTag( d->m_acl, ACL_OTHER ), v );
278 acl_entry_t entry = entryForTag( d->m_acl, ACL_MASK );
283 return entryToPermissions( entry );
290 bool KACL::KACLPrivate::setMaskPermissions(
unsigned short v )
292 acl_entry_t entry = entryForTag( m_acl, ACL_MASK );
294 acl_create_entry( &m_acl, &entry );
295 acl_set_tag_type( entry, ACL_MASK );
297 permissionsToEntry( entry, v );
305 return d->setMaskPermissions( v );
321 int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry );
323 acl_tag_t currentTag;
324 acl_get_tag_type( entry, ¤tTag );
325 if ( currentTag == ACL_USER ) {
326 id = *( (uid_t*) acl_get_qualifier( entry ) );
327 if ( d->getUserName(
id ) == name ) {
329 return entryToPermissions( entry );
332 ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry );
342 bool KACL::KACLPrivate::setNamedUserOrGroupPermissions(
const TQString& name,
unsigned short permissions, acl_tag_t type )
344 bool allIsWell =
true;
345 acl_t newACL = acl_dup( m_acl );
347 bool createdNewEntry =
false;
349 int ret = acl_get_entry( newACL, ACL_FIRST_ENTRY, &entry );
351 acl_tag_t currentTag;
352 acl_get_tag_type( entry, ¤tTag );
353 if ( currentTag == type ) {
354 int id = * (
int*)acl_get_qualifier( entry );
355 const TQString entryName = type == ACL_USER? getUserName(
id ): getGroupName( id );
356 if ( entryName == name ) {
358 permissionsToEntry( entry, permissions );
363 ret = acl_get_entry( newACL, ACL_NEXT_ENTRY, &entry );
366 acl_create_entry( &newACL, &entry );
367 acl_set_tag_type( entry, type );
368 int id = type == ACL_USER? getUidForName( name ): getGidForName( name );
369 if (
id == -1 || acl_set_qualifier( entry, &
id ) != 0 ) {
370 acl_delete_entry( newACL, entry );
373 permissionsToEntry( entry, permissions );
374 createdNewEntry =
true;
377 if ( allIsWell && createdNewEntry ) {
381 if ( entryForTag( newACL, ACL_MASK ) == 0 ) {
382 acl_calc_mask( &newACL );
386 if ( !allIsWell || acl_valid( newACL ) != 0 ) {
400 return d->setNamedUserOrGroupPermissions( name, permissions, ACL_USER );
403 Q_UNUSED( permissions );
410 ACLUserPermissionsList list;
414 int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry );
416 acl_tag_t currentTag;
417 acl_get_tag_type( entry, ¤tTag );
418 if ( currentTag == ACL_USER ) {
419 id = *( (uid_t*) acl_get_qualifier( entry ) );
420 TQString name = d->getUserName(
id );
421 unsigned short permissions = entryToPermissions( entry );
422 ACLUserPermissions pair = qMakePair( name, permissions );
425 ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry );
432 bool KACL::KACLPrivate::setAllUsersOrGroups(
const TQValueList< QPair<TQString, unsigned short> > &list, acl_tag_t type )
434 bool allIsWell =
true;
435 bool atLeastOneUserOrGroup =
false;
438 acl_t newACL = acl_dup( m_acl );
443 int ret = acl_get_entry( newACL, ACL_FIRST_ENTRY, &entry );
445 acl_tag_t currentTag;
446 acl_get_tag_type( entry, ¤tTag );
447 if ( currentTag == type ) {
448 acl_delete_entry( newACL, entry );
451 ret = acl_get_entry( newACL, ACL_FIRST_ENTRY, &entry );
453 ret = acl_get_entry( newACL, ACL_NEXT_ENTRY, &entry );
459 TQValueList< QPair<TQString, unsigned short> >::const_iterator it = list.constBegin();
460 while ( it != list.constEnd() ) {
461 acl_create_entry( &newACL, &entry );
462 acl_set_tag_type( entry, type );
463 int id = type == ACL_USER? getUidForName( (*it).first):getGidForName( (*it).first );
464 if (
id == -1 || acl_set_qualifier( entry, &
id ) != 0 ) {
466 acl_delete_entry( newACL, entry );
470 permissionsToEntry( entry, (*it).second );
471 atLeastOneUserOrGroup =
true;
476 if ( allIsWell && atLeastOneUserOrGroup ) {
480 if ( entryForTag( newACL, ACL_MASK ) == 0 ) {
481 acl_calc_mask( &newACL );
484 if ( allIsWell && ( acl_valid( newACL ) == 0 ) ) {
497 return d->setAllUsersOrGroups( users, ACL_USER );
515 int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry );
517 acl_tag_t currentTag;
518 acl_get_tag_type( entry, ¤tTag );
519 if ( currentTag == ACL_GROUP ) {
520 id = *( (gid_t*) acl_get_qualifier( entry ) );
521 if ( d->getGroupName(
id ) == name ) {
523 return entryToPermissions( entry );
526 ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry );
537 return d->setNamedUserOrGroupPermissions( name, permissions, ACL_GROUP );
540 Q_UNUSED( permissions );
548 ACLGroupPermissionsList list;
552 int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry );
554 acl_tag_t currentTag;
555 acl_get_tag_type( entry, ¤tTag );
556 if ( currentTag == ACL_GROUP ) {
557 id = *( (gid_t*) acl_get_qualifier( entry ) );
558 TQString name = d->getGroupName(
id );
559 unsigned short permissions = entryToPermissions( entry );
560 ACLGroupPermissions pair = qMakePair( name, permissions );
563 ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry );
572 return d->setAllUsersOrGroups( groups, ACL_GROUP );
587 if ( aclStr.isEmpty() )
590 acl_t temp = acl_from_text( aclStr.latin1() );
591 if ( acl_valid( temp ) != 0 ) {
596 acl_free( d->m_acl );
609 return aclAsString( d->m_acl );
611 return TQString::null;
619 TQString KACL::KACLPrivate::getUserName( uid_t uid )
const
622 temp = m_usercache.find( uid );
624 struct passwd *user = getpwuid( uid );
626 m_usercache.insert( uid,
new TQString(TQString::fromLatin1(user->pw_name)) );
627 return TQString::fromLatin1( user->pw_name );
630 return TQString::number( uid );
637 TQString KACL::KACLPrivate::getGroupName( gid_t gid )
const
640 temp = m_groupcache.find( gid );
642 struct group *grp = getgrgid( gid );
644 m_groupcache.insert( gid,
new TQString(TQString::fromLatin1(grp->gr_name)) );
645 return TQString::fromLatin1( grp->gr_name );
648 return TQString::number( gid );
654 static TQString aclAsString(
const acl_t acl)
656 char *aclString = acl_to_text( acl, 0 );
657 TQString ret = TQString::fromLatin1( aclString );
658 acl_free( (
void*)aclString );
665 void KACL::virtual_hook(
int,
void* )
668 TQDataStream & operator<< ( TQDataStream & s,
const KACL & a )
674 TQDataStream & operator>> ( TQDataStream & s,
KACL & a )