github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/syscall/security_windows.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package syscall 6 7 import ( 8 "unsafe" 9 ) 10 11 const ( 12 STANDARD_RIGHTS_REQUIRED = 0xf0000 13 STANDARD_RIGHTS_READ = 0x20000 14 STANDARD_RIGHTS_WRITE = 0x20000 15 STANDARD_RIGHTS_EXECUTE = 0x20000 16 STANDARD_RIGHTS_ALL = 0x1F0000 17 ) 18 19 const ( 20 NameUnknown = 0 21 NameFullyQualifiedDN = 1 22 NameSamCompatible = 2 23 NameDisplay = 3 24 NameUniqueId = 6 25 NameCanonical = 7 26 NameUserPrincipal = 8 27 NameCanonicalEx = 9 28 NameServicePrincipal = 10 29 NameDnsDomain = 12 30 ) 31 32 // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. 33 // http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx 34 //sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW 35 //sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW 36 37 // TranslateAccountName converts a directory service 38 // object name from one format to another. 39 func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) { 40 u, e := UTF16PtrFromString(username) 41 if e != nil { 42 return "", e 43 } 44 n := uint32(50) 45 for { 46 b := make([]uint16, n) 47 e = TranslateName(u, from, to, &b[0], &n) 48 if e == nil { 49 return UTF16ToString(b[:n]), nil 50 } 51 if e != ERROR_INSUFFICIENT_BUFFER { 52 return "", e 53 } 54 if n <= uint32(len(b)) { 55 return "", e 56 } 57 } 58 } 59 60 const ( 61 // do not reorder 62 NetSetupUnknownStatus = iota 63 NetSetupUnjoined 64 NetSetupWorkgroupName 65 NetSetupDomainName 66 ) 67 68 type UserInfo10 struct { 69 Name *uint16 70 Comment *uint16 71 UsrComment *uint16 72 FullName *uint16 73 } 74 75 //sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo 76 //sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation 77 //sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree 78 79 const ( 80 // do not reorder 81 SidTypeUser = 1 + iota 82 SidTypeGroup 83 SidTypeDomain 84 SidTypeAlias 85 SidTypeWellKnownGroup 86 SidTypeDeletedAccount 87 SidTypeInvalid 88 SidTypeUnknown 89 SidTypeComputer 90 SidTypeLabel 91 ) 92 93 //sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW 94 //sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW 95 //sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW 96 //sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW 97 //sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid 98 //sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid 99 100 // The security identifier (SID) structure is a variable-length 101 // structure used to uniquely identify users or groups. 102 type SID struct{} 103 104 // StringToSid converts a string-format security identifier 105 // sid into a valid, functional sid. 106 func StringToSid(s string) (*SID, error) { 107 var sid *SID 108 p, e := UTF16PtrFromString(s) 109 if e != nil { 110 return nil, e 111 } 112 e = ConvertStringSidToSid(p, &sid) 113 if e != nil { 114 return nil, e 115 } 116 defer LocalFree((Handle)(unsafe.Pointer(sid))) 117 return sid.Copy() 118 } 119 120 // LookupSID retrieves a security identifier sid for the account 121 // and the name of the domain on which the account was found. 122 // System specify target computer to search. 123 func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) { 124 if len(account) == 0 { 125 return nil, "", 0, EINVAL 126 } 127 acc, e := UTF16PtrFromString(account) 128 if e != nil { 129 return nil, "", 0, e 130 } 131 var sys *uint16 132 if len(system) > 0 { 133 sys, e = UTF16PtrFromString(system) 134 if e != nil { 135 return nil, "", 0, e 136 } 137 } 138 n := uint32(50) 139 dn := uint32(50) 140 for { 141 b := make([]byte, n) 142 db := make([]uint16, dn) 143 sid = (*SID)(unsafe.Pointer(&b[0])) 144 e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType) 145 if e == nil { 146 return sid, UTF16ToString(db), accType, nil 147 } 148 if e != ERROR_INSUFFICIENT_BUFFER { 149 return nil, "", 0, e 150 } 151 if n <= uint32(len(b)) { 152 return nil, "", 0, e 153 } 154 } 155 } 156 157 // String converts sid to a string format 158 // suitable for display, storage, or transmission. 159 func (sid *SID) String() (string, error) { 160 var s *uint16 161 e := ConvertSidToStringSid(sid, &s) 162 if e != nil { 163 return "", e 164 } 165 defer LocalFree((Handle)(unsafe.Pointer(s))) 166 return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil 167 } 168 169 // Len returns the length, in bytes, of a valid security identifier sid. 170 func (sid *SID) Len() int { 171 return int(GetLengthSid(sid)) 172 } 173 174 // Copy creates a duplicate of security identifier sid. 175 func (sid *SID) Copy() (*SID, error) { 176 b := make([]byte, sid.Len()) 177 sid2 := (*SID)(unsafe.Pointer(&b[0])) 178 e := CopySid(uint32(len(b)), sid2, sid) 179 if e != nil { 180 return nil, e 181 } 182 return sid2, nil 183 } 184 185 // LookupAccount retrieves the name of the account for this sid 186 // and the name of the first domain on which this sid is found. 187 // System specify target computer to search for. 188 func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) { 189 var sys *uint16 190 if len(system) > 0 { 191 sys, err = UTF16PtrFromString(system) 192 if err != nil { 193 return "", "", 0, err 194 } 195 } 196 n := uint32(50) 197 dn := uint32(50) 198 for { 199 b := make([]uint16, n) 200 db := make([]uint16, dn) 201 e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType) 202 if e == nil { 203 return UTF16ToString(b), UTF16ToString(db), accType, nil 204 } 205 if e != ERROR_INSUFFICIENT_BUFFER { 206 return "", "", 0, e 207 } 208 if n <= uint32(len(b)) { 209 return "", "", 0, e 210 } 211 } 212 } 213 214 const ( 215 // do not reorder 216 TOKEN_ASSIGN_PRIMARY = 1 << iota 217 TOKEN_DUPLICATE 218 TOKEN_IMPERSONATE 219 TOKEN_QUERY 220 TOKEN_QUERY_SOURCE 221 TOKEN_ADJUST_PRIVILEGES 222 TOKEN_ADJUST_GROUPS 223 TOKEN_ADJUST_DEFAULT 224 225 TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | 226 TOKEN_ASSIGN_PRIMARY | 227 TOKEN_DUPLICATE | 228 TOKEN_IMPERSONATE | 229 TOKEN_QUERY | 230 TOKEN_QUERY_SOURCE | 231 TOKEN_ADJUST_PRIVILEGES | 232 TOKEN_ADJUST_GROUPS | 233 TOKEN_ADJUST_DEFAULT 234 TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY 235 TOKEN_WRITE = STANDARD_RIGHTS_WRITE | 236 TOKEN_ADJUST_PRIVILEGES | 237 TOKEN_ADJUST_GROUPS | 238 TOKEN_ADJUST_DEFAULT 239 TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE 240 ) 241 242 const ( 243 // do not reorder 244 TokenUser = 1 + iota 245 TokenGroups 246 TokenPrivileges 247 TokenOwner 248 TokenPrimaryGroup 249 TokenDefaultDacl 250 TokenSource 251 TokenType 252 TokenImpersonationLevel 253 TokenStatistics 254 TokenRestrictedSids 255 TokenSessionId 256 TokenGroupsAndPrivileges 257 TokenSessionReference 258 TokenSandBoxInert 259 TokenAuditPolicy 260 TokenOrigin 261 TokenElevationType 262 TokenLinkedToken 263 TokenElevation 264 TokenHasRestrictions 265 TokenAccessInformation 266 TokenVirtualizationAllowed 267 TokenVirtualizationEnabled 268 TokenIntegrityLevel 269 TokenUIAccess 270 TokenMandatoryPolicy 271 TokenLogonSid 272 MaxTokenInfoClass 273 ) 274 275 type SIDAndAttributes struct { 276 Sid *SID 277 Attributes uint32 278 } 279 280 type Tokenuser struct { 281 User SIDAndAttributes 282 } 283 284 type Tokenprimarygroup struct { 285 PrimaryGroup *SID 286 } 287 288 //sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken 289 //sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation 290 //sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW 291 292 // An access token contains the security information for a logon session. 293 // The system creates an access token when a user logs on, and every 294 // process executed on behalf of the user has a copy of the token. 295 // The token identifies the user, the user's groups, and the user's 296 // privileges. The system uses the token to control access to securable 297 // objects and to control the ability of the user to perform various 298 // system-related operations on the local computer. 299 type Token Handle 300 301 // OpenCurrentProcessToken opens the access token 302 // associated with current process. 303 func OpenCurrentProcessToken() (Token, error) { 304 p, e := GetCurrentProcess() 305 if e != nil { 306 return 0, e 307 } 308 var t Token 309 e = OpenProcessToken(p, TOKEN_QUERY, &t) 310 if e != nil { 311 return 0, e 312 } 313 return t, nil 314 } 315 316 // Close releases access to access token. 317 func (t Token) Close() error { 318 return CloseHandle(Handle(t)) 319 } 320 321 // getInfo retrieves a specified type of information about an access token. 322 func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) { 323 n := uint32(initSize) 324 for { 325 b := make([]byte, n) 326 e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n) 327 if e == nil { 328 return unsafe.Pointer(&b[0]), nil 329 } 330 if e != ERROR_INSUFFICIENT_BUFFER { 331 return nil, e 332 } 333 if n <= uint32(len(b)) { 334 return nil, e 335 } 336 } 337 } 338 339 // GetTokenUser retrieves access token t user account information. 340 func (t Token) GetTokenUser() (*Tokenuser, error) { 341 i, e := t.getInfo(TokenUser, 50) 342 if e != nil { 343 return nil, e 344 } 345 return (*Tokenuser)(i), nil 346 } 347 348 // GetTokenPrimaryGroup retrieves access token t primary group information. 349 // A pointer to a SID structure representing a group that will become 350 // the primary group of any objects created by a process using this access token. 351 func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) { 352 i, e := t.getInfo(TokenPrimaryGroup, 50) 353 if e != nil { 354 return nil, e 355 } 356 return (*Tokenprimarygroup)(i), nil 357 } 358 359 // GetUserProfileDirectory retrieves path to the 360 // root directory of the access token t user's profile. 361 func (t Token) GetUserProfileDirectory() (string, error) { 362 n := uint32(100) 363 for { 364 b := make([]uint16, n) 365 e := GetUserProfileDirectory(t, &b[0], &n) 366 if e == nil { 367 return UTF16ToString(b), nil 368 } 369 if e != ERROR_INSUFFICIENT_BUFFER { 370 return "", e 371 } 372 if n <= uint32(len(b)) { 373 return "", e 374 } 375 } 376 }