Serialize enrollment install with enrolling.lock
Concurrent enroll-url launches could both pass the enrollment
marker check and run overlapping elevated installs, racing on
LoadOrExchangeAPIKey and overwriting agent.key.
Add an exclusive flock on {configDir}/enrolling.lock for the
full install path and re-check IsEnrolled under that lock so
only one install exchanges a token and configures the device.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
This commit is contained in:
@@ -36,6 +36,9 @@ var ErrServerURLMismatch = errors.New("server URL does not match persisted confi
|
||||
// only when serverURL matches the server_url persisted in config.json.
|
||||
// Otherwise the enrollment token is exchanged, the key and server binding
|
||||
// are saved to disk immediately, and then the key is returned.
|
||||
//
|
||||
// Concurrent callers are serialized with an exclusive lock so only one
|
||||
// process exchanges a one-shot enrollment token for a given state dir.
|
||||
func LoadOrExchangeAPIKey(
|
||||
ctx context.Context,
|
||||
dir string,
|
||||
@@ -48,6 +51,12 @@ func LoadOrExchangeAPIKey(
|
||||
return "", fmt.Errorf("invalid server URL: %w", err)
|
||||
}
|
||||
|
||||
release, err := AcquireEnrollmentLock(dir)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot acquire enrollment lock: %w", err)
|
||||
}
|
||||
defer release()
|
||||
|
||||
apiKey, err := LoadAPIKey(dir)
|
||||
if err == nil {
|
||||
if err := validatePersistedServerURL(dir, normalized); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user