github.com/jcmturner/gokrb5/v8@v8.4.4/pac/kerb_validation_info.go (about) 1 // Package pac implements Microsoft Privilege Attribute Certificate (PAC) processing. 2 package pac 3 4 import ( 5 "bytes" 6 "fmt" 7 8 "github.com/jcmturner/rpc/v2/mstypes" 9 "github.com/jcmturner/rpc/v2/ndr" 10 ) 11 12 // KERB_VALIDATION_INFO flags. 13 const ( 14 USERFLAG_GUEST = 31 // Authentication was done via the GUEST account; no password was used. 15 USERFLAG_NO_ENCRYPTION_AVAILABLE = 30 // No encryption is available. 16 USERFLAG_LAN_MANAGER_KEY = 28 // LAN Manager key was used for authentication. 17 USERFLAG_SUB_AUTH = 25 // Sub-authentication used; session key came from the sub-authentication package. 18 USERFLAG_EXTRA_SIDS = 26 // Indicates that the ExtraSids field is populated and contains additional SIDs. 19 USERFLAG_MACHINE_ACCOUNT = 24 // Indicates that the account is a machine account. 20 USERFLAG_DC_NTLM2 = 23 // Indicates that the domain controller understands NTLMv2. 21 USERFLAG_RESOURCE_GROUPIDS = 22 // Indicates that the ResourceGroupIds field is populated. 22 USERFLAG_PROFILEPATH = 21 // Indicates that ProfilePath is populated. 23 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. 24 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. 25 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. 26 ) 27 28 // KerbValidationInfo implement https://msdn.microsoft.com/en-us/library/cc237948.aspx 29 type KerbValidationInfo struct { 30 LogOnTime mstypes.FileTime 31 LogOffTime mstypes.FileTime 32 KickOffTime mstypes.FileTime 33 PasswordLastSet mstypes.FileTime 34 PasswordCanChange mstypes.FileTime 35 PasswordMustChange mstypes.FileTime 36 EffectiveName mstypes.RPCUnicodeString 37 FullName mstypes.RPCUnicodeString 38 LogonScript mstypes.RPCUnicodeString 39 ProfilePath mstypes.RPCUnicodeString 40 HomeDirectory mstypes.RPCUnicodeString 41 HomeDirectoryDrive mstypes.RPCUnicodeString 42 LogonCount uint16 43 BadPasswordCount uint16 44 UserID uint32 45 PrimaryGroupID uint32 46 GroupCount uint32 47 GroupIDs []mstypes.GroupMembership `ndr:"pointer,conformant"` 48 UserFlags uint32 49 UserSessionKey mstypes.UserSessionKey 50 LogonServer mstypes.RPCUnicodeString 51 LogonDomainName mstypes.RPCUnicodeString 52 LogonDomainID mstypes.RPCSID `ndr:"pointer"` 53 Reserved1 [2]uint32 // Has 2 elements 54 UserAccountControl uint32 55 SubAuthStatus uint32 56 LastSuccessfulILogon mstypes.FileTime 57 LastFailedILogon mstypes.FileTime 58 FailedILogonCount uint32 59 Reserved3 uint32 60 SIDCount uint32 61 ExtraSIDs []mstypes.KerbSidAndAttributes `ndr:"pointer,conformant"` 62 ResourceGroupDomainSID mstypes.RPCSID `ndr:"pointer"` 63 ResourceGroupCount uint32 64 ResourceGroupIDs []mstypes.GroupMembership `ndr:"pointer,conformant"` 65 } 66 67 // Unmarshal bytes into the DeviceInfo struct 68 func (k *KerbValidationInfo) Unmarshal(b []byte) (err error) { 69 dec := ndr.NewDecoder(bytes.NewReader(b)) 70 err = dec.Decode(k) 71 if err != nil { 72 err = fmt.Errorf("error unmarshaling KerbValidationInfo: %v", err) 73 } 74 return 75 } 76 77 // GetGroupMembershipSIDs returns a slice of strings containing the group membership SIDs found in the PAC. 78 func (k *KerbValidationInfo) GetGroupMembershipSIDs() []string { 79 var g []string 80 lSID := k.LogonDomainID.String() 81 for i := range k.GroupIDs { 82 g = append(g, fmt.Sprintf("%s-%d", lSID, k.GroupIDs[i].RelativeID)) 83 } 84 for _, s := range k.ExtraSIDs { 85 var exists = false 86 for _, es := range g { 87 if es == s.SID.String() { 88 exists = true 89 break 90 } 91 } 92 if !exists { 93 g = append(g, s.SID.String()) 94 } 95 } 96 for _, r := range k.ResourceGroupIDs { 97 var exists = false 98 s := fmt.Sprintf("%s-%d", k.ResourceGroupDomainSID.String(), r.RelativeID) 99 for _, es := range g { 100 if es == s { 101 exists = true 102 break 103 } 104 } 105 if !exists { 106 g = append(g, s) 107 } 108 } 109 return g 110 }