Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FIX(server): Apply context to traverse ACL
Browse files Browse the repository at this point in the history
Hartmnt committed Jul 17, 2024
1 parent b75fe54 commit 0083e39
Showing 1 changed file with 45 additions and 12 deletions.
57 changes: 45 additions & 12 deletions src/ACL.cpp
Original file line number Diff line number Diff line change
@@ -99,6 +99,8 @@ bool ChanACL::hasPermission(ServerUser *p, Channel *chan, QFlags< Perm > perm, A
return ((granted & perm) != None);
}

# include <QDebug>

// Return effective permissions.
QFlags< ChanACL::Perm > ChanACL::effectivePermissions(ServerUser *p, Channel *chan, ACLCache *cache) {
// Superuser
@@ -141,36 +143,67 @@ QFlags< ChanACL::Perm > ChanACL::effectivePermissions(ServerUser *p, Channel *ch
bool write = false;
ChanACL *acl;

// Iterate over all parent channels including the channel the user is in
while (!chanstack.isEmpty()) {
ch = chanstack.pop();
if (!ch->bInheritACL)
if (!ch->bInheritACL) {
granted = def;
}

foreach (acl, ch->qlACL) {
bool matchUser = (acl->iUserId != -1) && (acl->iUserId == p->iId);
bool matchGroup = Group::appliesToUser(*chan, *ch, acl->qsGroup, *p);

bool applyFromSelf = (ch == chan && acl->bApplyHere);
bool applyFromParent = (ch != chan && acl->bApplySubs);
bool applyFromAny = applyFromSelf || applyFromParent;

// Denying traverse is special, because denying it for any parent channel
// implicitly means all sub channels are entirely inaccessible as well.
// However, we still want to make sure that unchecking "applies to
// this channel" for the parent channel is honored.
bool applyDenyTraverse = applyFromParent || acl->bApplyHere;

if (matchUser || matchGroup) {
if (acl->pAllow & Traverse)
if (applyFromAny && acl->pAllow & Traverse) {
traverse = true;
if (acl->pDeny & Traverse)
}
if (applyDenyTraverse && acl->pDeny & Traverse) {
traverse = false;
if (acl->pAllow & Write)
}

if (applyFromAny && acl->pAllow & Write) {
write = true;
if (acl->pDeny & Write)
qDebug() << "Write true from " << ch->iID;
}
if (applyFromAny && acl->pDeny & Write) {
write = false;
if (ch->iId == 0 && chan == ch && acl->bApplyHere) {
if (acl->pAllow & Kick)
qDebug() << "Write false from " << ch->iID;
}

// These permissions are only grantable from the root channel
// as they affect the users globally. For example: You can not
// kick a client from a channel without kicking them from the server.
if (ch->iId == 0 && applyFromSelf) {
if (acl->pAllow & Kick) {
granted |= Kick;
if (acl->pAllow & Ban)
}
if (acl->pAllow & Ban) {
granted |= Ban;
if (acl->pAllow & ResetUserContent)
}
if (acl->pAllow & ResetUserContent) {
granted |= ResetUserContent;
if (acl->pAllow & Register)
}
if (acl->pAllow & Register) {
granted |= Register;
if (acl->pAllow & SelfRegister)
}
if (acl->pAllow & SelfRegister) {
granted |= SelfRegister;
}
}
if ((ch == chan && acl->bApplyHere) || (ch != chan && acl->bApplySubs)) {

// Every other regular ACL is handled here
if (applyFromAny) {
granted |= (acl->pAllow & ~(Kick | Ban | ResetUserContent | Register | SelfRegister | Cached));
granted &= ~acl->pDeny;
}

0 comments on commit 0083e39

Please sign in to comment.