mirror of
https://github.com/juanfont/headscale.git
synced 2026-10-05 06:13:37 +09:00
policy,state: authorize reauth tags against the authenticating user
Re-authenticating a tagged node with --advertise-tags checked the tag-owned
node, not the authenticating user, so every tag was rejected.
Fixes #3374
(cherry picked from commit 6275e3a356)
This commit is contained in:
committed by
Kristoffer Dalby
parent
1fccdb18bd
commit
4a1e77359d
@@ -30,6 +30,12 @@ type PolicyManager interface {
|
||||
// NodeCanHaveTag reports whether the given node can have the given tag.
|
||||
NodeCanHaveTag(node types.NodeView, tag string) bool
|
||||
|
||||
// UserCanHaveTag reports whether the given user owns the given tag, i.e.
|
||||
// is listed (directly or via a group) in the tag's tagOwners. This is the
|
||||
// user half of NodeCanHaveTag, used to authorise re-auth tag changes
|
||||
// against the authenticating user rather than the node's stale ownership.
|
||||
UserCanHaveTag(user types.UserView, tag string) bool
|
||||
|
||||
// TagExists reports whether the given tag is defined in the policy.
|
||||
TagExists(tag string) bool
|
||||
|
||||
|
||||
@@ -964,6 +964,37 @@ func (pm *PolicyManager) NodeCanHaveTag(node types.NodeView, tag string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// UserCanHaveTag reports whether the given user is one of the tag's owners
|
||||
// (directly or via a group). It is the user half of [PolicyManager.NodeCanHaveTag]:
|
||||
// re-authentication authorises requested tags against the authenticating user,
|
||||
// because a tag-owned node carries no user and its IP is not in any owner set,
|
||||
// so only the user presenting the credential can prove ownership.
|
||||
func (pm *PolicyManager) UserCanHaveTag(user types.UserView, tag string) bool {
|
||||
if pm == nil || !user.Valid() {
|
||||
return false
|
||||
}
|
||||
|
||||
pm.mu.RLock()
|
||||
defer pm.mu.RUnlock()
|
||||
|
||||
if pm.pol == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
owners, exists := pm.pol.TagOwners[Tag(tag)]
|
||||
if !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, owner := range owners {
|
||||
if pm.userMatchesOwner(user, owner) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// userMatchesOwner checks if a user matches a tag owner entry.
|
||||
// This is used as a fallback when the node's IP is not in the [PolicyManager.tagOwnerMap].
|
||||
func (pm *PolicyManager) userMatchesOwner(user types.UserView, owner Owner) bool {
|
||||
|
||||
Reference in New Issue
Block a user