Initial Backupper Unraid plugin
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package platform
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ValidateRestoreTarget(target, restoreRoot string, inPlace, confirmed bool) (string, error) {
|
||||
if !filepath.IsAbs(target) {
|
||||
return "", errors.New("validation: restore target must be absolute")
|
||||
}
|
||||
clean := filepath.Clean(target)
|
||||
if clean == "/" || clean == "/boot" || clean == "/etc" || clean == "/usr" || clean == "/var" {
|
||||
return "", errors.New("validation: protected system restore target")
|
||||
}
|
||||
if !inPlace {
|
||||
root := filepath.Clean(restoreRoot)
|
||||
if clean != root && !strings.HasPrefix(clean, root+string(os.PathSeparator)) {
|
||||
return "", errors.New("validation: staging restore must remain below restoreRoot")
|
||||
}
|
||||
if err := rejectSymlinks(root, clean); err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else if !confirmed {
|
||||
return "", errors.New("validation: in-place restore requires explicit confirmation")
|
||||
}
|
||||
if inPlace {
|
||||
anchor := string(os.PathSeparator) + strings.Split(strings.TrimPrefix(clean, string(os.PathSeparator)), string(os.PathSeparator))[0]
|
||||
if err := rejectSymlinks(anchor, clean); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return clean, nil
|
||||
}
|
||||
|
||||
func rejectSymlinks(root, target string) error {
|
||||
relative, err := filepath.Rel(root, target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
current := root
|
||||
for _, component := range strings.Split(relative, string(os.PathSeparator)) {
|
||||
if component == "." || component == "" {
|
||||
continue
|
||||
}
|
||||
current = filepath.Join(current, component)
|
||||
info, err := os.Lstat(current)
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
return errors.New("validation: restore target traverses a symlink")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user