mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-01-30 12:32:22 -08:00
parent
6ab687553d
commit
0ae2725481
|
@ -6,11 +6,11 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/v3/host"
|
"github.com/shirou/gopsutil/v3/host"
|
||||||
terminal "github.com/wayneashleyberry/terminal-dimensions"
|
terminal "github.com/wayneashleyberry/terminal-dimensions"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (env *Shell) Root() bool {
|
func (env *Shell) Root() bool {
|
||||||
|
@ -126,35 +126,7 @@ func (env *Shell) LookWinAppPath(file string) (string, error) {
|
||||||
|
|
||||||
func (env *Shell) DirIsWritable(path string) bool {
|
func (env *Shell) DirIsWritable(path string) bool {
|
||||||
defer env.Trace(time.Now(), "DirIsWritable", path)
|
defer env.Trace(time.Now(), "DirIsWritable", path)
|
||||||
info, err := os.Stat(path)
|
return unix.Access(path, unix.W_OK) == nil
|
||||||
if err != nil {
|
|
||||||
env.Log(Error, "DirIsWritable", err.Error())
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if !info.IsDir() {
|
|
||||||
env.Log(Error, "DirIsWritable", "Path isn't a directory")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user bit is enabled in file permission
|
|
||||||
if info.Mode().Perm()&(1<<(uint(7))) == 0 {
|
|
||||||
env.Log(Error, "DirIsWritable", "Write permission bit is not set on this file for user")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var stat syscall.Stat_t
|
|
||||||
if err = syscall.Stat(path, &stat); err != nil {
|
|
||||||
env.Log(Error, "DirIsWritable", err.Error())
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if uint32(os.Geteuid()) != stat.Uid {
|
|
||||||
env.Log(Error, "DirIsWritable", "User doesn't have permission to write to this directory")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (env *Shell) Connection(connectionType ConnectionType) (*Connection, error) {
|
func (env *Shell) Connection(connectionType ConnectionType) (*Connection, error) {
|
||||||
|
|
|
@ -235,24 +235,7 @@ func (env *Shell) ConvertToLinuxPath(path string) string {
|
||||||
|
|
||||||
func (env *Shell) DirIsWritable(path string) bool {
|
func (env *Shell) DirIsWritable(path string) bool {
|
||||||
defer env.Trace(time.Now(), "DirIsWritable")
|
defer env.Trace(time.Now(), "DirIsWritable")
|
||||||
info, err := os.Stat(path)
|
return isWriteable(path)
|
||||||
if err != nil {
|
|
||||||
env.Log(Error, "DirIsWritable", err.Error())
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if !info.IsDir() {
|
|
||||||
env.Log(Error, "DirIsWritable", "Path isn't a directory")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user bit is enabled in file permission
|
|
||||||
if info.Mode().Perm()&(1<<(uint(7))) == 0 {
|
|
||||||
env.Log(Error, "DirIsWritable", "Write permission bit is not set on this file for user")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (env *Shell) Connection(connectionType ConnectionType) (*Connection, error) {
|
func (env *Shell) Connection(connectionType ConnectionType) (*Connection, error) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package platform
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"oh-my-posh/regex"
|
"oh-my-posh/regex"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
|
@ -194,3 +195,76 @@ func readWinAppLink(path string) (string, error) {
|
||||||
}
|
}
|
||||||
return appExecLink.Path()
|
return appExecLink.Path()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
advapi = syscall.NewLazyDLL("advapi32.dll")
|
||||||
|
procGetAce = advapi.NewProc("GetAce")
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ACCESS_DENIED_ACE_TYPE = 1 //nolint: revive
|
||||||
|
)
|
||||||
|
|
||||||
|
type AccessAllowedAce struct {
|
||||||
|
AceType uint8
|
||||||
|
AceFlags uint8
|
||||||
|
AceSize uint16
|
||||||
|
AccessMask uint32
|
||||||
|
SidStart uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCurrentUser() (sid *windows.SID, err error) {
|
||||||
|
token := windows.GetCurrentProcessToken()
|
||||||
|
defer token.Close()
|
||||||
|
|
||||||
|
tokenuser, err := token.GetTokenUser()
|
||||||
|
sid = tokenuser.User.Sid
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func isWriteable(folder string) bool {
|
||||||
|
cu, err := getCurrentUser()
|
||||||
|
if err != nil {
|
||||||
|
// unable to get current user
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
si, err := windows.GetNamedSecurityInfo(folder, windows.SE_FILE_OBJECT, windows.DACL_SECURITY_INFORMATION)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
dacl, _, err := si.DACL()
|
||||||
|
if err != nil || dacl == nil {
|
||||||
|
// no dacl implies full access
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
rs := reflect.ValueOf(dacl).Elem()
|
||||||
|
aceCount := rs.Field(3).Uint()
|
||||||
|
|
||||||
|
for i := uint64(0); i < aceCount; i++ {
|
||||||
|
ace := &AccessAllowedAce{}
|
||||||
|
|
||||||
|
ret, _, _ := procGetAce.Call(uintptr(unsafe.Pointer(dacl)), uintptr(i), uintptr(unsafe.Pointer(&ace)))
|
||||||
|
if ret == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if ace.AceType == ACCESS_DENIED_ACE_TYPE {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
aceSid := (*windows.SID)(unsafe.Pointer(&ace.SidStart))
|
||||||
|
|
||||||
|
if !aceSid.Equals(cu) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
allowMask := ^(windows.GENERIC_WRITE | windows.GENERIC_ALL)
|
||||||
|
if ace.AccessMask&uint32(allowMask) != 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue