fix(windows): protect existing lifecycle child first
This commit is contained in:
@@ -50,14 +50,31 @@ type Transaction struct {
|
|||||||
// Acquire obtains the shared lock used by backup, restore, Pi lifecycle and product updates.
|
// Acquire obtains the shared lock used by backup, restore, Pi lifecycle and product updates.
|
||||||
func Acquire(installation config.Installation) (*Lock, error) {
|
func Acquire(installation config.Installation) (*Lock, error) {
|
||||||
directory := installation.ControlDirectory()
|
directory := installation.ControlDirectory()
|
||||||
// The lifecycle directory is also the restore staging parent. Protect both the shared
|
parent := filepath.Dir(directory)
|
||||||
// .tht directory and this installation's child before any lock or staging artifact is
|
// The lifecycle directory is also the restore staging parent. An existing Windows child
|
||||||
// created; chmod alone does not install an owner-only DACL on Windows.
|
// must be protected before its parent: replacing the parent's inheritable ACL first can
|
||||||
if err := ensurePrivateLifecycleDirectory(filepath.Dir(directory)); err != nil {
|
// remove the child's inherited owner authority before the child receives its protected DACL.
|
||||||
return nil, fmt.Errorf("protect lifecycle control parent: %w", err)
|
// For a new installation the parent must instead exist before safe child creation.
|
||||||
}
|
controlInfo, controlErr := os.Lstat(directory)
|
||||||
if err := ensurePrivateLifecycleDirectory(directory); err != nil {
|
if controlErr == nil {
|
||||||
return nil, fmt.Errorf("protect lifecycle control directory: %w", err)
|
if !controlInfo.IsDir() || controlInfo.Mode()&os.ModeSymlink != 0 {
|
||||||
|
return nil, errors.New("lifecycle control directory is not a regular directory")
|
||||||
|
}
|
||||||
|
if err := ensurePrivateLifecycleDirectory(directory); err != nil {
|
||||||
|
return nil, fmt.Errorf("protect lifecycle control directory: %w", err)
|
||||||
|
}
|
||||||
|
if err := ensurePrivateLifecycleDirectory(parent); err != nil {
|
||||||
|
return nil, fmt.Errorf("protect lifecycle control parent: %w", err)
|
||||||
|
}
|
||||||
|
} else if errors.Is(controlErr, os.ErrNotExist) {
|
||||||
|
if err := ensurePrivateLifecycleDirectory(parent); err != nil {
|
||||||
|
return nil, fmt.Errorf("protect lifecycle control parent: %w", err)
|
||||||
|
}
|
||||||
|
if err := ensurePrivateLifecycleDirectory(directory); err != nil {
|
||||||
|
return nil, fmt.Errorf("protect lifecycle control directory: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("lifecycle control directory is unavailable")
|
||||||
}
|
}
|
||||||
info, err := os.Lstat(directory)
|
info, err := os.Lstat(directory)
|
||||||
if err != nil || !info.IsDir() || info.Mode()&os.ModeSymlink != 0 {
|
if err != nil || !info.IsDir() || info.Mode()&os.ModeSymlink != 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user