mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-17 20:19:55 +00:00
91 lines
2.7 KiB
Go
91 lines
2.7 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"google.golang.org/grpc/codes"
|
|
gstatus "google.golang.org/grpc/status"
|
|
|
|
"github.com/netbirdio/netbird/client/mdm"
|
|
"github.com/netbirdio/netbird/client/proto"
|
|
)
|
|
|
|
// loadMDMPolicy is the indirection used by server handlers to read the
|
|
// active MDM policy. Tests override this to inject a fake policy.
|
|
var loadMDMPolicy = mdm.LoadPolicy
|
|
|
|
// requestedMDMManagedKeys returns the names of MDM-managed keys whose
|
|
// corresponding field is set in the SetConfigRequest. Only keys with an
|
|
// MDM mapping are considered; other fields are ignored.
|
|
func requestedMDMManagedKeys(msg *proto.SetConfigRequest) []string {
|
|
if msg == nil {
|
|
return nil
|
|
}
|
|
var keys []string
|
|
if msg.ManagementUrl != "" {
|
|
keys = append(keys, mdm.KeyManagementURL)
|
|
}
|
|
if msg.OptionalPreSharedKey != nil {
|
|
keys = append(keys, mdm.KeyPreSharedKey)
|
|
}
|
|
if msg.RosenpassEnabled != nil {
|
|
keys = append(keys, mdm.KeyRosenpassEnabled)
|
|
}
|
|
if msg.RosenpassPermissive != nil {
|
|
keys = append(keys, mdm.KeyRosenpassPermissive)
|
|
}
|
|
if msg.DisableAutoConnect != nil {
|
|
keys = append(keys, mdm.KeyDisableAutoConnect)
|
|
}
|
|
if msg.ServerSSHAllowed != nil {
|
|
keys = append(keys, mdm.KeyAllowServerSSH)
|
|
}
|
|
if msg.DisableClientRoutes != nil {
|
|
keys = append(keys, mdm.KeyDisableClientRoutes)
|
|
}
|
|
if msg.DisableServerRoutes != nil {
|
|
keys = append(keys, mdm.KeyDisableServerRoutes)
|
|
}
|
|
if msg.BlockInbound != nil {
|
|
keys = append(keys, mdm.KeyBlockInbound)
|
|
}
|
|
if msg.WireguardPort != nil {
|
|
keys = append(keys, mdm.KeyWireguardPort)
|
|
}
|
|
return keys
|
|
}
|
|
|
|
// rejectMDMManagedFieldConflicts returns a FailedPrecondition gRPC error
|
|
// with an MDMManagedFieldsViolation detail when any of the requested keys
|
|
// is MDM-enforced, and nil otherwise. The whole request is rejected on
|
|
// any conflict; non-conflicting fields in the same request are not
|
|
// applied either (no partial apply).
|
|
func rejectMDMManagedFieldConflicts(policy *mdm.Policy, requested []string) error {
|
|
if policy.IsEmpty() || len(requested) == 0 {
|
|
return nil
|
|
}
|
|
var conflicts []string
|
|
for _, k := range requested {
|
|
if policy.HasKey(k) {
|
|
conflicts = append(conflicts, k)
|
|
}
|
|
}
|
|
if len(conflicts) == 0 {
|
|
return nil
|
|
}
|
|
log.Warnf("MDM rejected request: tried to modify %d managed key(s): %v",
|
|
len(conflicts), conflicts)
|
|
st := gstatus.New(
|
|
codes.FailedPrecondition,
|
|
fmt.Sprintf("fields managed by MDM cannot be modified: %v", conflicts),
|
|
)
|
|
detailed, err := st.WithDetails(&proto.MDMManagedFieldsViolation{Fields: conflicts})
|
|
if err != nil {
|
|
// Detail attachment is best-effort; fall back to the plain status
|
|
// so the caller still gets a usable FailedPrecondition.
|
|
return st.Err()
|
|
}
|
|
return detailed.Err()
|
|
}
|