pbsdr: escrow seed writes in place (config dir is root-owned; tmp+rename impossible for the non-root agent — demo live finding); recovery copy parked in the state dir
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -407,12 +407,26 @@ func (m *Manager) seedEscrowStorageID(storageID string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmp := m.configPath + ".pbsdr-tmp"
|
||||
if err := os.WriteFile(tmp, out, st.Mode().Perm()); err != nil {
|
||||
// The config DIRECTORY (/etc/felhom-agent) is root-owned while the FILE is agent-owned —
|
||||
// tmp+rename is impossible for the non-root agent (rename mutates the directory; live
|
||||
// finding on the demo). So: park a recovery copy in the agent state dir, then rewrite the
|
||||
// file IN PLACE (O_TRUNC). The agent is the file's only writer and the content is small;
|
||||
// a torn write is recoverable from the parked copy.
|
||||
if err := os.MkdirAll(m.stateDir, 0o700); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Rename(tmp, m.configPath); err != nil {
|
||||
os.Remove(tmp)
|
||||
if err := os.WriteFile(filepath.Join(m.stateDir, "agent.json.pre-seed"), raw, 0o600); err != nil {
|
||||
return fmt.Errorf("parking the pre-seed copy: %w", err)
|
||||
}
|
||||
f, err := os.OpenFile(m.configPath, os.O_WRONLY|os.O_TRUNC, st.Mode().Perm())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := f.Write(out); err != nil {
|
||||
f.Close()
|
||||
return err
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
m.logger.Info("pbsdr: seeded escrow.pbs_storage_id (the ceremony one-liner needs no flags)", "storage_id", storageID)
|
||||
|
||||
Reference in New Issue
Block a user