// Package pac implements Microsoft Privilege Attribute Certificate (PAC) processing.
package pac import ( ) // KERB_VALIDATION_INFO flags. const ( USERFLAG_GUEST = 31 // Authentication was done via the GUEST account; no password was used. USERFLAG_NO_ENCRYPTION_AVAILABLE = 30 // No encryption is available. USERFLAG_LAN_MANAGER_KEY = 28 // LAN Manager key was used for authentication. USERFLAG_SUB_AUTH = 25 // Sub-authentication used; session key came from the sub-authentication package. USERFLAG_EXTRA_SIDS = 26 // Indicates that the ExtraSids field is populated and contains additional SIDs. USERFLAG_MACHINE_ACCOUNT = 24 // Indicates that the account is a machine account. USERFLAG_DC_NTLM2 = 23 // Indicates that the domain controller understands NTLMv2. USERFLAG_RESOURCE_GROUPIDS = 22 // Indicates that the ResourceGroupIds field is populated. USERFLAG_PROFILEPATH = 21 // Indicates that ProfilePath is populated. USERFLAG_NTLM2_NTCHALLENGERESP = 20 // The NTLMv2 response from the NtChallengeResponseFields ([MS-NLMP] section 2.2.1.3) was used for authentication and session key generation. USERFLAG_LM2_LMCHALLENGERESP = 19 // The LMv2 response from the LmChallengeResponseFields ([MS-NLMP] section 2.2.1.3) was used for authentication and session key generation. USERFLAG_AUTH_LMCHALLENGERESP_KEY_NTCHALLENGERESP = 18 // The LMv2 response from the LmChallengeResponseFields ([MS-NLMP] section 2.2.1.3) was used for authentication and the NTLMv2 response from the NtChallengeResponseFields ([MS-NLMP] section 2.2.1.3) was used session key generation. ) // KerbValidationInfo implement https://msdn.microsoft.com/en-us/library/cc237948.aspx type KerbValidationInfo struct { LogOnTime mstypes.FileTime LogOffTime mstypes.FileTime KickOffTime mstypes.FileTime PasswordLastSet mstypes.FileTime PasswordCanChange mstypes.FileTime PasswordMustChange mstypes.FileTime EffectiveName mstypes.RPCUnicodeString FullName mstypes.RPCUnicodeString LogonScript mstypes.RPCUnicodeString ProfilePath mstypes.RPCUnicodeString HomeDirectory mstypes.RPCUnicodeString HomeDirectoryDrive mstypes.RPCUnicodeString LogonCount uint16 BadPasswordCount uint16 UserID uint32 PrimaryGroupID uint32 GroupCount uint32 GroupIDs []mstypes.GroupMembership `ndr:"pointer,conformant"` UserFlags uint32 UserSessionKey mstypes.UserSessionKey LogonServer mstypes.RPCUnicodeString LogonDomainName mstypes.RPCUnicodeString LogonDomainID mstypes.RPCSID `ndr:"pointer"` Reserved1 [2]uint32 // Has 2 elements UserAccountControl uint32 SubAuthStatus uint32 LastSuccessfulILogon mstypes.FileTime LastFailedILogon mstypes.FileTime FailedILogonCount uint32 Reserved3 uint32 SIDCount uint32 ExtraSIDs []mstypes.KerbSidAndAttributes `ndr:"pointer,conformant"` ResourceGroupDomainSID mstypes.RPCSID `ndr:"pointer"` ResourceGroupCount uint32 ResourceGroupIDs []mstypes.GroupMembership `ndr:"pointer,conformant"` } // Unmarshal bytes into the DeviceInfo struct func ( *KerbValidationInfo) ( []byte) ( error) { := ndr.NewDecoder(bytes.NewReader()) = .Decode() if != nil { = fmt.Errorf("error unmarshaling KerbValidationInfo: %v", ) } return } // GetGroupMembershipSIDs returns a slice of strings containing the group membership SIDs found in the PAC. func ( *KerbValidationInfo) () []string { var []string := .LogonDomainID.String() for := range .GroupIDs { = append(, fmt.Sprintf("%s-%d", , .GroupIDs[].RelativeID)) } for , := range .ExtraSIDs { var = false for , := range { if == .SID.String() { = true break } } if ! { = append(, .SID.String()) } } for , := range .ResourceGroupIDs { var = false := fmt.Sprintf("%s-%d", .ResourceGroupDomainSID.String(), .RelativeID) for , := range { if == { = true break } } if ! { = append(, ) } } return }