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