@@ -5,18 +5,52 @@ package executor
55import (
66 "context"
77 "os"
8+ "runtime"
89 "strings"
910)
1011
1112func (r * Real ) IsRoot () bool {
1213 return os .Getuid () == 0
1314}
1415
16+ // resolveUserShell returns the given user's configured login shell on macOS by
17+ // consulting Directory Services (dscl). Returns "" on non-darwin platforms, if
18+ // the lookup fails, or if the resolved path isn't an executable file — in which
19+ // case callers should fall back to /bin/bash.
20+ //
21+ // Mirrors stepsecurity-dev-machine-guard.sh:run_as_logged_in_user. Matters when
22+ // the user's PATH (including npm/pnpm/yarn via nvm/fnm/homebrew) is configured
23+ // only in zsh profile files (.zprofile/.zshrc) — bash -l on such a user sources
24+ // nothing and runs with a stripped PATH, producing empty package scans.
25+ func (r * Real ) resolveUserShell (ctx context.Context , username string ) string {
26+ if runtime .GOOS != "darwin" || username == "" {
27+ return ""
28+ }
29+ stdout , _ , _ , err := r .Run (ctx , "dscl" , "." , "-read" , "/Users/" + username , "UserShell" )
30+ if err != nil {
31+ return ""
32+ }
33+ fields := strings .Fields (strings .TrimSpace (stdout ))
34+ if len (fields ) < 2 {
35+ return ""
36+ }
37+ shell := fields [1 ]
38+ info , err := os .Stat (shell )
39+ if err != nil || info .IsDir () || info .Mode ()& 0o111 == 0 {
40+ return ""
41+ }
42+ return shell
43+ }
44+
1545func (r * Real ) RunAsUser (ctx context.Context , username , command string ) (string , error ) {
1646 if ! r .IsRoot () {
1747 stdout , _ , _ , err := r .Run (ctx , "bash" , "-c" , command )
1848 return strings .TrimSpace (stdout ), err
1949 }
20- stdout , _ , _ , err := r .Run (ctx , "sudo" , "-H" , "-u" , username , "bash" , "-l" , "-c" , command )
50+ shell := r .resolveUserShell (ctx , username )
51+ if shell == "" {
52+ shell = "/bin/bash"
53+ }
54+ stdout , _ , _ , err := r .Run (ctx , "sudo" , "-H" , "-u" , username , shell , "-l" , "-c" , command )
2155 return strings .TrimSpace (stdout ), err
2256}
0 commit comments