// getInfo retrieves a specified type of information about an access token. func getInfo(t syscall.Token, class uint32, initSize int) (unsafe.Pointer, error) { b := make([]byte, initSize) var n uint32 e := syscall.GetTokenInformation(t, class, &b[0], uint32(len(b)), &n) if e != nil { if e != syscall.ERROR_INSUFFICIENT_BUFFER { return nil, e } // make receive buffers of requested size and try again b = make([]byte, n) e = syscall.GetTokenInformation(t, class, &b[0], uint32(len(b)), &n) if e != nil { return nil, e } } return unsafe.Pointer(&b[0]), nil }
// GetTokenPrivileges returns a list of privileges associated with a token. // The provided token must have at a minimum TOKEN_QUERY access. This is a // wrapper around the GetTokenInformation function. // https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx func GetTokenPrivileges(token syscall.Token) (map[string]Privilege, error) { // Determine the required buffer size. var size uint32 syscall.GetTokenInformation(token, syscall.TokenPrivileges, nil, 0, &size) // This buffer will receive a TOKEN_PRIVILEGE structure. b := bytes.NewBuffer(make([]byte, size)) err := syscall.GetTokenInformation(token, syscall.TokenPrivileges, &b.Bytes()[0], uint32(b.Len()), &size) if err != nil { return nil, errors.Wrap(err, "GetTokenInformation failed") } var privilegeCount uint32 err = binary.Read(b, binary.LittleEndian, &privilegeCount) if err != nil { return nil, errors.Wrap(err, "failed to read PrivilegeCount") } rtn := make(map[string]Privilege, privilegeCount) for i := 0; i < int(privilegeCount); i++ { var luid int64 err = binary.Read(b, binary.LittleEndian, &luid) if err != nil { return nil, errors.Wrap(err, "failed to read LUID value") } var attributes uint32 err = binary.Read(b, binary.LittleEndian, &attributes) if err != nil { return nil, errors.Wrap(err, "failed to read attributes") } name, err := LookupPrivilegeName("", luid) if err != nil { return nil, errors.Wrapf(err, "LookupPrivilegeName failed for LUID=%v", luid) } rtn[name] = Privilege{ LUID: luid, Name: name, EnabledByDefault: (attributes & _SE_PRIVILEGE_ENABLED_BY_DEFAULT) > 0, Enabled: (attributes & _SE_PRIVILEGE_ENABLED) > 0, Removed: (attributes & _SE_PRIVILEGE_REMOVED) > 0, Used: (attributes & _SE_PRIVILEGE_USED_FOR_ACCESS) > 0, } } return rtn, nil }