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< TQPair<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< TQPair<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< TQPair<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 )
The KCAL class encapsulates a POSIX Access Control List.
bool setNamedGroupPermissions(const TQString &name, unsigned short)
Set the permissions for a group with the name name.
KACL()
Creates an empty KACL.
unsigned short maskPermissions(bool &exists) const
Return the entry for the permissions mask if there is one and sets exists to true.
TQString asString() const
Return a string representation of the ACL.
bool isExtended() const
The interface to the extended ACL.
bool setOthersPermissions(unsigned short)
Set the permissions entry for others.
bool setMaskPermissions(unsigned short)
Set the permissions mask for the ACL.
unsigned short namedUserPermissions(const TQString &name, bool *exists) const
Access to the permissions entry for a named user, if such an entry exists.
mode_t basePermissions() const
bool isValid() const
Returns whether the KACL object represents a valid acl.
bool setOwningGroupPermissions(unsigned short)
Set the owning group's permissions entry.
ACLGroupPermissionsList allGroupPermissions() const
Returns the list of all group permission entries.
bool setOwnerPermissions(unsigned short)
Set the owner's permissions entry.
bool setACL(const TQString &aclStr)
Sets the whole list from a string.
unsigned short namedGroupPermissions(const TQString &name, bool *exists) const
Access to the permissions entry for a named group, if such an entry exists.
unsigned short othersPermissions() const
bool setAllUserPermissions(const ACLUserPermissionsList &list)
Replace the list of all user permissions with list.
ACLUserPermissionsList allUserPermissions() const
Returns the list of all group permission entries.
bool setNamedUserPermissions(const TQString &name, unsigned short)
Set the permissions for a user with the name name.
bool setAllGroupPermissions(const ACLGroupPermissionsList &)
Replace the list of all user permissions with list.
unsigned short ownerPermissions() const
The standard (non-extended) part of an ACL.
unsigned short owningGroupPermissions() const