feat: robust username detection and CI updates

Add platform-specific username detection for Control D metadata:
- macOS: directory services (dscl) with console user fallback
- Linux: systemd loginctl, utmp, /etc/passwd traversal
- Windows: WTS session enumeration, registry, token lookup
This commit is contained in:
Codescribe
2026-03-03 02:07:11 -05:00
committed by Cuong Manh Le
parent 0a7bbb99e8
commit 023969ff6d
7 changed files with 824 additions and 37 deletions

View File

@@ -2,8 +2,6 @@ package ctrld
import (
"context"
"os"
"os/user"
"github.com/cuonglm/osinfo"
@@ -24,8 +22,21 @@ var (
chassisVendor string
)
// SystemMetadata collects system and user-related SystemMetadata and returns it as a map.
// SystemMetadata collects full system metadata including username discovery.
// Use for initial provisioning and first-run config validation where full
// device identification is needed.
func SystemMetadata(ctx context.Context) map[string]string {
return systemMetadata(ctx, true)
}
// SystemMetadataRuntime collects system metadata without username discovery.
// Use for runtime API calls (config reload, self-uninstall check, deactivation
// pin refresh) to avoid repeated user enumeration that can trigger EDR alerts.
func SystemMetadataRuntime(ctx context.Context) map[string]string {
return systemMetadata(ctx, false)
}
func systemMetadata(ctx context.Context, includeUsername bool) map[string]string {
logger := LoggerFromCtx(ctx)
m := make(map[string]string)
oi := osinfo.New()
@@ -40,7 +51,9 @@ func SystemMetadata(ctx context.Context) map[string]string {
}
m[metadataChassisTypeKey] = chassisType
m[metadataChassisVendorKey] = chassisVendor
m[metadataUsernameKey] = currentLoginUser(ctx)
if includeUsername {
m[metadataUsernameKey] = DiscoverMainUser(ctx)
}
m[metadataDomainOrWorkgroupKey] = partOfDomainOrWorkgroup(ctx)
domain, err := system.GetActiveDirectoryDomain()
if err != nil {
@@ -50,35 +63,3 @@ func SystemMetadata(ctx context.Context) map[string]string {
return m
}
// currentLoginUser attempts to find the actual login user, even if the process is running as root.
func currentLoginUser(ctx context.Context) string {
logger := LoggerFromCtx(ctx)
// 1. Check SUDO_USER: This is the most reliable way to find the original user
// when a script is run via 'sudo'.
if sudoUser := os.Getenv("SUDO_USER"); sudoUser != "" {
return sudoUser
}
// 2. Check general user login variables. LOGNAME is often preferred over USER.
if logName := os.Getenv("LOGNAME"); logName != "" {
return logName
}
// 3. Fallback to USER variable.
if userEnv := os.Getenv("USER"); userEnv != "" {
return userEnv
}
// 4. Final fallback: Use the standard library function to get the *effective* user.
// This will return "root" if the process is running as root.
currentUser, err := user.Current()
if err != nil {
// Handle error gracefully, returning a placeholder
logger.Debug().Err(err).Msg("Failed to get current user")
return "unknown"
}
return currentUser.Username
}