| 
									
										
										
										
											2022-03-17 10:11:17 +00:00
										 |  |  | //go:build windows
 | 
					
						
							|  |  |  | // +build windows
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package util | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2022-04-06 07:43:17 +00:00
										 |  |  | 	"log" | 
					
						
							| 
									
										
										
										
											2022-03-17 10:11:17 +00:00
										 |  |  | 	"os" | 
					
						
							|  |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2022-04-06 07:43:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"golang.org/x/sys/windows" | 
					
						
							| 
									
										
										
										
											2022-03-17 10:11:17 +00:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // IsSuperUser returns true, if the current user is a super user
 | 
					
						
							|  |  |  | // A.K.A root, Administrator etc
 | 
					
						
							|  |  |  | func IsSuperUser() bool { | 
					
						
							| 
									
										
										
										
											2022-04-06 07:43:17 +00:00
										 |  |  | 	var sid *windows.SID | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Although this looks scary, it is directly copied from the
 | 
					
						
							|  |  |  | 	// official windows documentation. The Go API for this is a
 | 
					
						
							|  |  |  | 	// direct wrap around the official C++ API.
 | 
					
						
							|  |  |  | 	// See https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-checktokenmembership
 | 
					
						
							|  |  |  | 	err := windows.AllocateAndInitializeSid( | 
					
						
							|  |  |  | 		&windows.SECURITY_NT_AUTHORITY, | 
					
						
							|  |  |  | 		2, | 
					
						
							|  |  |  | 		windows.SECURITY_BUILTIN_DOMAIN_RID, | 
					
						
							|  |  |  | 		windows.DOMAIN_ALIAS_RID_ADMINS, | 
					
						
							|  |  |  | 		0, 0, 0, 0, 0, 0, | 
					
						
							|  |  |  | 		&sid) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		log.Fatalf("SID Error: %s", err) | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer windows.FreeSid(sid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// This appears to cast a null pointer so I'm not sure why this
 | 
					
						
							|  |  |  | 	// works, but this guy says it does and it Works for Me™:
 | 
					
						
							|  |  |  | 	// https://github.com/golang/go/issues/28804#issuecomment-438838144
 | 
					
						
							|  |  |  | 	token := windows.Token(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	member, err := token.IsMember(sid) | 
					
						
							| 
									
										
										
										
											2022-03-17 10:11:17 +00:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-04-06 07:43:17 +00:00
										 |  |  | 		log.Fatalf("Token Membership Error: %s", err) | 
					
						
							| 
									
										
										
										
											2022-03-17 10:11:17 +00:00
										 |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-04-06 07:43:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return member | 
					
						
							| 
									
										
										
										
											2022-03-17 10:11:17 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // GetGlobalConfigurationDirectory returns OS specific location for putting
 | 
					
						
							|  |  |  | // global configuration files
 | 
					
						
							|  |  |  | func GetGlobalConfigurationDirectory(appname string) string { | 
					
						
							|  |  |  | 	return filepath.Join(os.Getenv("APPDATA"), appname) | 
					
						
							|  |  |  | } |