blob: 9dd69d2b3d64d01f25d6473545f7c3f22a0d2cbc [file] [log] [blame]
Scott Baker8461e152019-10-01 14:44:30 -07001// Package pac implements Microsoft Privilege Attribute Certificate (PAC) processing.
2package pac
3
4import (
5 "bytes"
6 "fmt"
7
8 "gopkg.in/jcmturner/rpc.v1/mstypes"
9 "gopkg.in/jcmturner/rpc.v1/ndr"
10)
11
12// KERB_VALIDATION_INFO flags.
13const (
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// The KERB_VALIDATION_INFO structure defines the user's logon and authorization information
30// provided by the DC. The KERB_VALIDATION_INFO structure is a subset of the
31// NETLOGON_VALIDATION_SAM_INFO4 structure ([MS-NRPC] section 2.2.1.4.13).
32// It is a subset due to historical reasons and to the use of the common Active Directory to generate this information.
33// The KERB_VALIDATION_INFO structure is marshaled by RPC [MS-RPCE].
34type KerbValidationInfo struct {
35 LogOnTime mstypes.FileTime
36 LogOffTime mstypes.FileTime
37 KickOffTime mstypes.FileTime
38 PasswordLastSet mstypes.FileTime
39 PasswordCanChange mstypes.FileTime
40 PasswordMustChange mstypes.FileTime
41 EffectiveName mstypes.RPCUnicodeString
42 FullName mstypes.RPCUnicodeString
43 LogonScript mstypes.RPCUnicodeString
44 ProfilePath mstypes.RPCUnicodeString
45 HomeDirectory mstypes.RPCUnicodeString
46 HomeDirectoryDrive mstypes.RPCUnicodeString
47 LogonCount uint16
48 BadPasswordCount uint16
49 UserID uint32
50 PrimaryGroupID uint32
51 GroupCount uint32
52 GroupIDs []mstypes.GroupMembership `ndr:"pointer,conformant"`
53 UserFlags uint32
54 UserSessionKey mstypes.UserSessionKey
55 LogonServer mstypes.RPCUnicodeString
56 LogonDomainName mstypes.RPCUnicodeString
57 LogonDomainID mstypes.RPCSID `ndr:"pointer"`
58 Reserved1 [2]uint32 // Has 2 elements
59 UserAccountControl uint32
60 SubAuthStatus uint32
61 LastSuccessfulILogon mstypes.FileTime
62 LastFailedILogon mstypes.FileTime
63 FailedILogonCount uint32
64 Reserved3 uint32
65 SIDCount uint32
66 ExtraSIDs []mstypes.KerbSidAndAttributes `ndr:"pointer,conformant"`
67 ResourceGroupDomainSID mstypes.RPCSID `ndr:"pointer"`
68 ResourceGroupCount uint32
69 ResourceGroupIDs []mstypes.GroupMembership `ndr:"pointer,conformant"`
70}
71
72// Unmarshal bytes into the DeviceInfo struct
73func (k *KerbValidationInfo) Unmarshal(b []byte) (err error) {
74 dec := ndr.NewDecoder(bytes.NewReader(b))
75 err = dec.Decode(k)
76 if err != nil {
77 err = fmt.Errorf("error unmarshaling KerbValidationInfo: %v", err)
78 }
79 return
80}
81
82// GetGroupMembershipSIDs returns a slice of strings containing the group membership SIDs found in the PAC.
83func (k *KerbValidationInfo) GetGroupMembershipSIDs() []string {
84 var g []string
85 lSID := k.LogonDomainID.String()
86 for i := range k.GroupIDs {
87 g = append(g, fmt.Sprintf("%s-%d", lSID, k.GroupIDs[i].RelativeID))
88 }
89 for _, s := range k.ExtraSIDs {
90 var exists = false
91 for _, es := range g {
92 if es == s.SID.String() {
93 exists = true
94 break
95 }
96 }
97 if !exists {
98 g = append(g, s.SID.String())
99 }
100 }
101 for _, r := range k.ResourceGroupIDs {
102 var exists = false
103 s := fmt.Sprintf("%s-%d", k.ResourceGroupDomainSID.String(), r.RelativeID)
104 for _, es := range g {
105 if es == s {
106 exists = true
107 break
108 }
109 }
110 if !exists {
111 g = append(g, s)
112 }
113 }
114 return g
115}