s3:printing: Allow to run samba-bgqd as a standalone systemd service
[Samba.git] / python / samba / lsa_utils.py
blob043e65f3341bbddb7560b04db7bb0dccae77e667
1 # trust utils
3 # Copyright Isaac Boukris 2020
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 from samba.dcerpc import lsa, drsblobs, misc
20 from samba.ndr import ndr_pack
21 from samba import (
22 NTSTATUSError,
23 aead_aes_256_cbc_hmac_sha512,
24 arcfour_encrypt,
26 from samba.ntstatus import (
27 NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
29 from samba import crypto
30 from secrets import token_bytes
33 def OpenPolicyFallback(
34 conn: lsa.lsarpc,
35 system_name: str,
36 in_version: int,
37 in_revision_info: lsa.revision_info1,
38 sec_qos: bool = False,
39 access_mask: int = 0,
41 attr = lsa.ObjectAttribute()
42 if sec_qos:
43 qos = lsa.QosInfo()
44 qos.len = 0xc
45 qos.impersonation_level = 2
46 qos.context_mode = 1
47 qos.effective_only = 0
49 attr.sec_qos = qos
51 try:
52 out_version, out_rev_info, policy = conn.OpenPolicy3(
53 system_name,
54 attr,
55 access_mask,
56 in_version,
57 in_revision_info
59 except NTSTATUSError as e:
60 if e.args[0] == NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE:
61 out_version = 1
62 out_rev_info = lsa.revision_info1()
63 out_rev_info.revision = 1
64 out_rev_info.supported_features = 0
66 policy = conn.OpenPolicy2(system_name, attr, access_mask)
67 else:
68 raise
70 return out_version, out_rev_info, policy
73 def CreateTrustedDomainRelax(
74 lsaconn: lsa.lsarpc,
75 policy: misc.policy_handle,
76 trust_info: lsa.TrustDomainInfoInfoEx,
77 mask: int,
78 in_blob: drsblobs.trustAuthInOutBlob,
79 out_blob: drsblobs.trustAuthInOutBlob
82 def generate_AuthInfoInternal(session_key, incoming=None, outgoing=None):
83 confounder = list(token_bytes(512))
85 trustpass = drsblobs.trustDomainPasswords()
87 trustpass.confounder = confounder
88 trustpass.outgoing = outgoing
89 trustpass.incoming = incoming
91 trustpass_blob = ndr_pack(trustpass)
93 encrypted_trustpass = arcfour_encrypt(session_key, trustpass_blob)
95 auth_blob = lsa.DATA_BUF2()
96 auth_blob.size = len(encrypted_trustpass)
97 auth_blob.data = list(encrypted_trustpass)
99 auth_info = lsa.TrustDomainInfoAuthInfoInternal()
100 auth_info.auth_blob = auth_blob
102 return auth_info
104 session_key = lsaconn.session_key
106 try:
107 if lsaconn.transport_encrypted():
108 crypto.set_relax_mode()
109 auth_info = generate_AuthInfoInternal(session_key,
110 incoming=in_blob,
111 outgoing=out_blob)
112 finally:
113 crypto.set_strict_mode()
115 return lsaconn.CreateTrustedDomainEx2(policy, trust_info, auth_info, mask)
118 def CreateTrustedDomainFallback(
119 conn: lsa.lsarpc,
120 policy_handle: misc.policy_handle,
121 trust_info: lsa.TrustDomainInfoInfoEx,
122 access_mask: int,
123 srv_version: int,
124 srv_revision_info1: lsa.revision_info1,
125 in_blob: drsblobs.trustAuthInOutBlob,
126 out_blob: drsblobs.trustAuthInOutBlob
128 def generate_AuthInfoInternalAES(
129 session_key,
130 incoming=None,
131 outgoing=None
133 trustpass = drsblobs.trustDomainPasswords()
135 trustpass.outgoing = outgoing
136 trustpass.incoming = incoming
138 trustpass_blob = ndr_pack(trustpass)
140 lsa_aes256_enc_key = (
141 "Microsoft LSAD encryption key AEAD-AES-256-CBC-HMAC-SHA512 16".encode()
142 + b'\x00'
144 lsa_aes256_mac_key = (
145 "Microsoft LSAD MAC key AEAD-AES-256-CBC-HMAC-SHA512 16".encode()
146 + b'\x00'
149 iv = token_bytes(16)
150 ciphertext, auth_data = aead_aes_256_cbc_hmac_sha512(
151 trustpass_blob,
152 session_key,
153 lsa_aes256_enc_key,
154 lsa_aes256_mac_key,
158 return ciphertext, iv, auth_data
160 if (srv_version == 1
161 and srv_revision_info1.revision == 1
162 and (srv_revision_info1.supported_features
163 & lsa.LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER)):
165 ciphertext, iv, auth_data = generate_AuthInfoInternalAES(
166 conn.session_key, in_blob, out_blob
169 auth_blob = lsa.DATA_BUF2()
170 auth_blob.size = len(ciphertext)
171 auth_blob.data = list(ciphertext)
173 auth_info = lsa.TrustDomainInfoAuthInfoInternalAES()
174 auth_info.cipher = auth_blob
175 auth_info.salt = list(iv)
176 auth_info.auth_data = list(auth_data)
178 return conn.CreateTrustedDomainEx3(
179 policy_handle,
180 trust_info,
181 auth_info,
182 access_mask
185 return CreateTrustedDomainRelax(
186 conn,
187 policy_handle,
188 trust_info,
189 access_mask,
190 in_blob,
191 out_blob