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.
|
||||
func Acquire(installation config.Installation) (*Lock, error) {
|
||||
directory := installation.ControlDirectory()
|
||||
// The lifecycle directory is also the restore staging parent. Protect both the shared
|
||||
// .tht directory and this installation's child before any lock or staging artifact is
|
||||
// created; chmod alone does not install an owner-only DACL on Windows.
|
||||
if err := ensurePrivateLifecycleDirectory(filepath.Dir(directory)); 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)
|
||||
parent := filepath.Dir(directory)
|
||||
// The lifecycle directory is also the restore staging parent. An existing Windows child
|
||||
// must be protected before its parent: replacing the parent's inheritable ACL first can
|
||||
// remove the child's inherited owner authority before the child receives its protected DACL.
|
||||
// For a new installation the parent must instead exist before safe child creation.
|
||||
controlInfo, controlErr := os.Lstat(directory)
|
||||
if controlErr == nil {
|
||||
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)
|
||||
if err != nil || !info.IsDir() || info.Mode()&os.ModeSymlink != 0 {
|
||||
|
||||
Reference in New Issue
Block a user