23 #include <config-acl.h> 25 #include <sys/types.h> 31 #include <acl/libacl.h> 41 class KACL::KACLPrivate {
43 KACLPrivate() : m_acl( 0 ) {}
45 KACLPrivate( acl_t acl )
47 ~KACLPrivate() {
if ( m_acl ) acl_free( m_acl ); }
52 QString getUserName( uid_t uid )
const;
53 QString getGroupName( gid_t gid )
const;
55 bool setNamedUserOrGroupPermissions(
const QString& name,
unsigned short permissions, acl_tag_t type );
66 : d( new KACLPrivate )
73 : d(
new KACLPrivate( acl_from_mode( basePermissions ) ) )
75 : d(
new KACLPrivate )
78 #ifndef HAVE_POSIX_ACL 79 Q_UNUSED( basePermissions );
84 : d( new KACLPrivate )
89 : d( new KACLPrivate )
107 #ifdef HAVE_POSIX_ACL 108 return ( acl_cmp( d->m_acl, rhs.d->m_acl ) == 0 );
123 #ifdef HAVE_POSIX_ACL 125 valid = ( acl_valid( d->m_acl ) == 0 );
133 #ifdef HAVE_POSIX_ACL 134 return ( acl_equiv_mode( d->m_acl, NULL ) != 0 );
140 #ifdef HAVE_POSIX_ACL 141 static acl_entry_t entryForTag( acl_t acl, acl_tag_t tag )
144 int ret = acl_get_entry( acl, ACL_FIRST_ENTRY, &entry );
146 acl_tag_t currentTag;
147 acl_get_tag_type( entry, ¤tTag );
148 if ( currentTag == tag )
150 ret = acl_get_entry( acl, ACL_NEXT_ENTRY, &entry );
155 static unsigned short entryToPermissions( acl_entry_t entry )
157 if ( entry == 0 )
return 0;
158 acl_permset_t permset;
159 if ( acl_get_permset( entry, &permset ) != 0 )
return 0;
160 return( acl_get_perm( permset, ACL_READ ) << 2 |
161 acl_get_perm( permset, ACL_WRITE ) << 1 |
162 acl_get_perm( permset, ACL_EXECUTE ) );
165 static void permissionsToEntry( acl_entry_t entry,
unsigned short v )
167 if ( entry == 0 )
return;
168 acl_permset_t permset;
169 if ( acl_get_permset( entry, &permset ) != 0 )
return;
170 acl_clear_perms( permset );
171 if ( v & 4 ) acl_add_perm( permset, ACL_READ );
172 if ( v & 2 ) acl_add_perm( permset, ACL_WRITE );
173 if ( v & 1 ) acl_add_perm( permset, ACL_EXECUTE );
176 #ifdef HAVE_POSIX_ACL 178 static void printACL( acl_t acl,
const QString &comment )
180 const char* txt = acl_to_text(acl);
181 kDebug() << comment << txt;
187 static int getUidForName(
const QString& name )
189 struct passwd *user = getpwnam(
name.toLocal8Bit() );
196 static int getGidForName(
const QString& name )
200 return group->gr_gid;
209 #ifdef HAVE_POSIX_ACL 210 return entryToPermissions( entryForTag( d->m_acl, ACL_USER_OBJ ) );
218 #ifdef HAVE_POSIX_ACL 219 permissionsToEntry( entryForTag( d->m_acl, ACL_USER_OBJ ), v );
228 #ifdef HAVE_POSIX_ACL 229 return entryToPermissions( entryForTag( d->m_acl, ACL_GROUP_OBJ ) );
237 #ifdef HAVE_POSIX_ACL 238 permissionsToEntry( entryForTag( d->m_acl, ACL_GROUP_OBJ ), v );
247 #ifdef HAVE_POSIX_ACL 248 return entryToPermissions( entryForTag( d->m_acl, ACL_OTHER ) );
256 #ifdef HAVE_POSIX_ACL 257 permissionsToEntry( entryForTag( d->m_acl, ACL_OTHER ), v );
267 #ifdef HAVE_POSIX_ACL 284 #ifdef HAVE_POSIX_ACL 285 acl_entry_t entry = entryForTag( d->m_acl, ACL_MASK );
290 return entryToPermissions( entry );
296 #ifdef HAVE_POSIX_ACL 297 bool KACL::KACLPrivate::setMaskPermissions(
unsigned short v )
299 acl_entry_t entry = entryForTag( m_acl, ACL_MASK );
301 acl_create_entry( &m_acl, &entry );
302 acl_set_tag_type( entry, ACL_MASK );
304 permissionsToEntry( entry, v );
311 #ifdef HAVE_POSIX_ACL 312 return d->setMaskPermissions( v );
324 #ifdef HAVE_POSIX_ACL 328 int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry );
330 acl_tag_t currentTag;
331 acl_get_tag_type( entry, ¤tTag );
332 if ( currentTag == ACL_USER ) {
333 id = *( (uid_t*) acl_get_qualifier( entry ) );
334 if ( d->getUserName(
id ) ==
name ) {
336 return entryToPermissions( entry );
339 ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry );
348 #ifdef HAVE_POSIX_ACL 349 bool KACL::KACLPrivate::setNamedUserOrGroupPermissions(
const QString& name,
unsigned short permissions, acl_tag_t type )
351 bool allIsWell =
true;
352 acl_t newACL = acl_dup( m_acl );
354 bool createdNewEntry =
false;
356 int ret = acl_get_entry( newACL, ACL_FIRST_ENTRY, &entry );
358 acl_tag_t currentTag;
359 acl_get_tag_type( entry, ¤tTag );
360 if ( currentTag == type ) {
361 int id = * (
int*)acl_get_qualifier( entry );
362 const QString entryName = type == ACL_USER? getUserName(
id ): getGroupName( id );
363 if ( entryName == name ) {
365 permissionsToEntry( entry, permissions );
370 ret = acl_get_entry( newACL, ACL_NEXT_ENTRY, &entry );
373 acl_create_entry( &newACL, &entry );
374 acl_set_tag_type( entry, type );
375 int id = type == ACL_USER? getUidForName( name ): getGidForName(
name );
376 if (
id == -1 || acl_set_qualifier( entry, &
id ) != 0 ) {
377 acl_delete_entry( newACL, entry );
380 permissionsToEntry( entry, permissions );
381 createdNewEntry =
true;
384 if ( allIsWell && createdNewEntry ) {
388 if ( entryForTag( newACL, ACL_MASK ) == 0 ) {
389 acl_calc_mask( &newACL );
393 if ( !allIsWell || acl_valid( newACL ) != 0 ) {
406 #ifdef HAVE_POSIX_ACL 407 return d->setNamedUserOrGroupPermissions(
name, permissions, ACL_USER );
410 Q_UNUSED( permissions );
418 #ifdef HAVE_POSIX_ACL 421 int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry );
423 acl_tag_t currentTag;
424 acl_get_tag_type( entry, ¤tTag );
425 if ( currentTag == ACL_USER ) {
426 id = *( (uid_t*) acl_get_qualifier( entry ) );
427 QString
name = d->getUserName(
id );
428 unsigned short permissions = entryToPermissions( entry );
432 ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry );
438 #ifdef HAVE_POSIX_ACL 441 bool allIsWell =
true;
442 bool atLeastOneUserOrGroup =
false;
445 acl_t newACL = acl_dup( m_acl );
450 int ret = acl_get_entry( newACL, ACL_FIRST_ENTRY, &entry );
452 acl_tag_t currentTag;
453 acl_get_tag_type( entry, ¤tTag );
454 if ( currentTag == type ) {
455 acl_delete_entry( newACL, entry );
458 ret = acl_get_entry( newACL, ACL_FIRST_ENTRY, &entry );
460 ret = acl_get_entry( newACL, ACL_NEXT_ENTRY, &entry );
467 while ( it !=
list.constEnd() ) {
468 acl_create_entry( &newACL, &entry );
469 acl_set_tag_type( entry, type );
470 int id = type == ACL_USER? getUidForName( (*it).first):getGidForName( (*it).first );
471 if (
id == -1 || acl_set_qualifier( entry, &
id ) != 0 ) {
473 acl_delete_entry( newACL, entry );
477 permissionsToEntry( entry, (*it).second );
478 atLeastOneUserOrGroup =
true;
483 if ( allIsWell && atLeastOneUserOrGroup ) {
487 if ( entryForTag( newACL, ACL_MASK ) == 0 ) {
488 acl_calc_mask( &newACL );
491 if ( allIsWell && ( acl_valid( newACL ) == 0 ) ) {
503 #ifdef HAVE_POSIX_ACL 504 return d->setAllUsersOrGroups( users, ACL_USER );
519 #ifdef HAVE_POSIX_ACL 522 int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry );
524 acl_tag_t currentTag;
525 acl_get_tag_type( entry, ¤tTag );
526 if ( currentTag == ACL_GROUP ) {
527 id = *( (gid_t*) acl_get_qualifier( entry ) );
528 if ( d->getGroupName(
id ) ==
name ) {
530 return entryToPermissions( entry );
533 ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry );
543 #ifdef HAVE_POSIX_ACL 544 return d->setNamedUserOrGroupPermissions(
name, permissions, ACL_GROUP );
547 Q_UNUSED( permissions );
556 #ifdef HAVE_POSIX_ACL 559 int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry );
561 acl_tag_t currentTag;
562 acl_get_tag_type( entry, ¤tTag );
563 if ( currentTag == ACL_GROUP ) {
564 id = *( (gid_t*) acl_get_qualifier( entry ) );
565 QString
name = d->getGroupName(
id );
566 unsigned short permissions = entryToPermissions( entry );
570 ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry );
578 #ifdef HAVE_POSIX_ACL 579 return d->setAllUsersOrGroups( groups, ACL_GROUP );
593 #ifdef HAVE_POSIX_ACL 594 acl_t temp = acl_from_text( aclStr.toLatin1() );
595 if ( acl_valid( temp ) != 0 ) {
600 acl_free( d->m_acl );
612 #ifdef HAVE_POSIX_ACL 614 char* txt = acl_to_text(d->m_acl, &size);
615 const QString ret = QString::fromLatin1(txt, size);
626 #ifdef HAVE_POSIX_ACL 627 QString KACL::KACLPrivate::getUserName( uid_t uid )
const 629 if ( !m_usercache.contains( uid ) ) {
630 struct passwd *user = getpwuid( uid );
632 m_usercache.insert( uid, QString::fromLatin1(user->pw_name) );
637 return m_usercache[uid];
641 QString KACL::KACLPrivate::getGroupName( gid_t gid )
const 643 if ( !m_groupcache.contains( gid ) ) {
644 struct group *grp = getgrgid( gid );
646 m_groupcache.insert( gid, QString::fromLatin1(grp->gr_name) );
651 return m_groupcache[gid];
bool isExtended() const
The interface to the extended ACL.
bool setOwnerPermissions(unsigned short)
Set the owner's permissions entry.
bool setAllUserPermissions(const ACLUserPermissionsList &list)
Replace the list of all user permissions with list.
const char * name(StandardAction id)
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
bool isValid() const
Returns whether the KACL object represents a valid acl.
unsigned short othersPermissions() const
unsigned short namedGroupPermissions(const QString &name, bool *exists) const
Access to the permissions entry for a named group, if such an entry exists.
QDataStream & operator>>(QDataStream &s, KACL &a)
ACLGroupPermissionsList allGroupPermissions() const
Returns the list of all group permission entries.
mode_t basePermissions() const
unsigned short owningGroupPermissions() const
unsigned short ownerPermissions() const
The standard (non-extended) part of an ACL.
bool setNamedGroupPermissions(const QString &name, unsigned short)
Set the permissions for a group with the name name.
bool operator!=(const KACL &rhs) const
KACL & operator=(const KACL &rhs)
KACL()
Creates an empty KACL.
virtual void virtual_hook(int id, void *data)
QString asString() const
Return a string representation of the ACL.
ACLUserPermissionsList allUserPermissions() const
Returns the list of all group permission entries.
bool setNamedUserPermissions(const QString &name, unsigned short)
Set the permissions for a user with the name name.
unsigned short maskPermissions(bool &exists) const
Return the entry for the permissions mask if there is one and sets exists to true.
bool setOthersPermissions(unsigned short)
Set the permissions entry for others.
The KACL class encapsulates a POSIX Access Control List.
bool setMaskPermissions(unsigned short)
Set the permissions mask for the ACL.
bool setOwningGroupPermissions(unsigned short)
Set the owning group's permissions entry.
QDataStream & operator<<(QDataStream &s, const KACL &a)
bool operator==(const KACL &rhs) const
bool setACL(const QString &aclStr)
Sets the whole list from a string.
bool setAllGroupPermissions(const ACLGroupPermissionsList &)
Replace the list of all user permissions with list.
unsigned short namedUserPermissions(const QString &name, bool *exists) const
Access to the permissions entry for a named user, if such an entry exists.
QString number(KIO::filesize_t size)
Converts a size to a string representation Not unlike QString::number(...)
QStringList list(const QString &fileClass)
Returns a list of directories associated with this file-class.