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 )
198 struct group *
group = getgrnam( name.toLocal8Bit() );
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];
unsigned short namedGroupPermissions(const QString &name, bool *exists) const
Access to the permissions entry for a named group, if such an entry exists.
mode_t basePermissions() const
bool setOwnerPermissions(unsigned short)
Set the owner's permissions entry.
unsigned short ownerPermissions() const
The standard (non-extended) part of an ACL.
bool setAllUserPermissions(const ACLUserPermissionsList &list)
Replace the list of all user permissions with list.
ACLGroupPermissionsList allGroupPermissions() const
Returns the list of all group permission entries.
bool operator==(const KACL &rhs) const
bool isValid() const
Returns whether the KACL object represents a valid acl.
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QDataStream & operator>>(QDataStream &s, KACL &a)
bool operator!=(const KACL &rhs) const
unsigned short namedUserPermissions(const QString &name, bool *exists) const
Access to the permissions entry for a named user, if such an entry exists.
bool setNamedGroupPermissions(const QString &name, unsigned short)
Set the permissions for a group with the name name.
KACL & operator=(const KACL &rhs)
KACL()
Creates an empty KACL.
virtual void virtual_hook(int id, void *data)
bool isExtended() const
The interface to the extended ACL.
unsigned short owningGroupPermissions() const
unsigned short maskPermissions(bool &exists) const
Return the entry for the permissions mask if there is one and sets exists to true.
bool setNamedUserPermissions(const QString &name, unsigned short)
Set the permissions for a user with the name name.
bool setOthersPermissions(unsigned short)
Set the permissions entry for others.
The KACL class encapsulates a POSIX Access Control List.
unsigned short othersPermissions() const
bool setMaskPermissions(unsigned short)
Set the permissions mask for the ACL.
ACLUserPermissionsList allUserPermissions() const
Returns the list of all group permission entries.
QString asString() const
Return a string representation of the ACL.
bool setOwningGroupPermissions(unsigned short)
Set the owning group's permissions entry.
QDataStream & operator<<(QDataStream &s, const KACL &a)
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.
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.