mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-11-04 10:11:18 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			59 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright (c) Tailscale Inc & AUTHORS
 | 
						|
// SPDX-License-Identifier: BSD-3-Clause
 | 
						|
 | 
						|
package syspolicy
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"sync/atomic"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	handlerUsed atomic.Bool
 | 
						|
	handler     Handler = defaultHandler{}
 | 
						|
)
 | 
						|
 | 
						|
// Handler reads system policies from OS-specific storage.
 | 
						|
type Handler interface {
 | 
						|
	// ReadString reads the policy settings value string given the key.
 | 
						|
	ReadString(key string) (string, error)
 | 
						|
	// ReadUInt64 reads the policy settings uint64 value given the key.
 | 
						|
	ReadUInt64(key string) (uint64, error)
 | 
						|
	// ReadBool reads the policy setting's boolean value, given the key.
 | 
						|
	ReadBoolean(key string) (bool, error)
 | 
						|
}
 | 
						|
 | 
						|
// ErrNoSuchKey is returned when the specified key does not have a value set.
 | 
						|
var ErrNoSuchKey = errors.New("no such key")
 | 
						|
 | 
						|
// defaultHandler is the catch all syspolicy type for anything that isn't windows or apple.
 | 
						|
type defaultHandler struct{}
 | 
						|
 | 
						|
func (defaultHandler) ReadString(_ string) (string, error) {
 | 
						|
	return "", ErrNoSuchKey
 | 
						|
}
 | 
						|
 | 
						|
func (defaultHandler) ReadUInt64(_ string) (uint64, error) {
 | 
						|
	return 0, ErrNoSuchKey
 | 
						|
}
 | 
						|
 | 
						|
func (defaultHandler) ReadBoolean(_ string) (bool, error) {
 | 
						|
	return false, ErrNoSuchKey
 | 
						|
}
 | 
						|
 | 
						|
// markHandlerInUse is called before handler methods are called.
 | 
						|
func markHandlerInUse() {
 | 
						|
	handlerUsed.Store(true)
 | 
						|
}
 | 
						|
 | 
						|
// RegisterHandler initializes the policy handler and ensures registration will happen once.
 | 
						|
func RegisterHandler(h Handler) {
 | 
						|
	// Technically this assignment is not concurrency safe, but in the
 | 
						|
	// event that there was any risk of a data race, we will panic due to
 | 
						|
	// the CompareAndSwap failing.
 | 
						|
	handler = h
 | 
						|
	if !handlerUsed.CompareAndSwap(false, true) {
 | 
						|
		panic("handler was already used before registration")
 | 
						|
	}
 | 
						|
}
 |