package security // http://applehelpwriter.com/2017/05/21/how-to-reveal-hidden-users/ import ( "os/exec" "runtime" "strings" "github.com/wtfutil/wtf/wtf" ) /* -------------------- Exported Functions -------------------- */ func LoggedInUsers() []string { switch runtime.GOOS { case "linux": return loggedInUsersLinux() case "darwin": return loggedInUsersMacOs() case "windows": return loggedInUsersWindows() default: return []string{} } } /* -------------------- Unexported Functions -------------------- */ func cleanUsers(users []string) []string { rejects := []string{"_", "root", "nobody", "daemon", "Guest"} cleaned := []string{} for _, user := range users { clean := true for _, reject := range rejects { if strings.HasPrefix(user, reject) { clean = false continue } } if clean && user != "" { cleaned = append(cleaned, user) } } return cleaned } func loggedInUsersLinux() []string { cmd := exec.Command("who", "-us") users := wtf.ExecuteCommand(cmd) cleaned := []string{} for _, user := range strings.Split(users, "\n") { clean := true col := strings.Split(user, " ") if len(col) > 0 { for _, cleanedU := range cleaned { u := strings.TrimSpace(col[0]) if len(u) == 0 || strings.Compare(cleanedU, col[0]) == 0 { clean = false } } if clean { cleaned = append(cleaned, col[0]) } } } return cleaned } func loggedInUsersMacOs() []string { cmd := exec.Command("dscl", []string{".", "-list", "/Users"}...) users := wtf.ExecuteCommand(cmd) return cleanUsers(strings.Split(users, "\n")) } func loggedInUsersWindows() []string { // We can use either one: // (Get-WMIObject -class Win32_ComputerSystem | select username).username // [System.Security.Principal.WindowsIdentity]::GetCurrent().Name // The original was: // cmd := exec.Command("powershell.exe", "(query user) -replace '\\s{2,}', ','") // But that didn't work! // The real powershell command reads: // powershell.exe -NoProfile -Command "& { [System.Security.Principal.WindowsIdentity]::GetCurrent().Name }" // But we here have to write it as: cmd := exec.Command("powershell.exe", "-NoProfile", "-Command", "& { [System.Security.Principal.WindowsIdentity]::GetCurrent().Name }") // ToDo: Make list for multi-user systems users := wtf.ExecuteCommand(cmd) return cleanUsers(strings.Split(users, "\n")) }