1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-18 06:04:06 +03:00

Compare commits

...

70 Commits

Author SHA1 Message Date
Stefan Metzmacher
193dc02471 libcli/auth: make use of netlogon_creds_cli_check_transport() in more places
This was somehow missing in commit
7a5ad9f64a905f5744430c6e0796c646baf9432e

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>

Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Thu Nov  7 09:14:33 UTC 2024 on atb-devel-224

(cherry picked from commit f340dce6546a22d857cad440f8afaee9815dbdb1)

Autobuild-User(v4-21-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-21-test): Wed Nov 13 10:05:15 UTC 2024 on atb-devel-224
2024-11-13 10:05:15 +00:00
Stefan Metzmacher
f444707208 libcli/auth: split out netlogon_creds_cli_check_transport()
This will make it easier to implement netr_ServerAuthenticateKerberos()
later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 7a5ad9f64a905f5744430c6e0796c646baf9432e)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
97c1456157 libcli/auth: let netlogon_creds_copy() copy all scalar elements
This version is good for now, as we want it to be backportable.
For master we'll add a ndr_deepcopy_struct() helper in order
to avoid future problems.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 8edbdd65ef78e3f26357d0254b58db3120a32880)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
10e8e230e7 s4:librpc/rpc: make use of netlogon_creds_client_verify()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 132629ee3a9b73d0888d1110e4d0a45ded778e5a)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
4fb7226f77 libcli/auth: make use of netlogon_creds_client_verify()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 1a5984ac6312b204b51590057b8327cf4698383b)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
bd5058538c libcli/auth: split out netlogon_creds_client_verify() that takes auth_{type,level}
This will make it easier to implement netr_ServerAuthenticateKerberos()
later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 45faf6c35a033ec46a546dfb9d5d6aeb2fb2b83c)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
1edb984810 libcli/auth: pass auth_{type,level} to netlogon_creds_server_step_check()
This will make it easier to implement netr_ServerAuthenticateKerberos() later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 2956c7eb3c9fc2161fd2748e5aac1fc94478e8c7)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
15fad537ca libcli/auth: pass auth_{type,level} to schannel_check_creds_state()
This will make it easier to implement netr_ServerAuthenticateKerberos() later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 7b02fb50143ba5044605ec67ed41180391835dcb)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
57b897276c libcli/auth: return INVALID_PARAMETER for DES in netlogon_creds_{de,en}crypt_samlogon_logon
For the NetlogonGenericInformation case we want an error instead of no
encryption if only DES was negotiated...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 131f5c0b251e456c466eaca744525504e1d69492)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
f93fc1e65c s4:rpc_server/netlogon: make use of netlogon_creds_decrypt_SendToSam
This will make it easier to implement netr_ServerAuthenticateKerberos() later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 834197dafef0f3779ba69c8e350cbd7bb9333284)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
9f36351814 s4:rpc_server/netlogon: make use of netlogon_creds_decrypt_samr_CryptPassword
This will make it easier to implement netr_ServerAuthenticateKerberos() later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit f1c1b8661a9121e1ff02784955c98d9f33bca8bd)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
51dca749dd s4:rpc_server/netlogon: make use of netlogon_creds_{de,en}crypt_samr_Password()
This will make it easier to implement netr_ServerAuthenticateKerberos() later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 7a7cb0d0426a891185f5acf825573d98360e98e1)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
9b2c2de4bf s3:rpc_server/netlogon: make use of netlogon_creds_decrypt_samr_CryptPassword()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit a359b4139c8043ee3c3277b7559cb6d4f58f4044)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
cedcfa310b s3:rpc_server/netlogon: make use of netlogon_creds_{de,en}crypt_samr_Password
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 550d20fd3dd04397b3a38f8b9e0cfa574453eea1)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
fea3d0c581 s4:torture/rpc: make use of netlogon_creds_{de,en}crypt_samr_Password
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 172ce406d48916c57f0742b6a0e064ac170ec8ff)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
a8e5bbb268 s4:torture/rpc: make use of netlogon_creds_encrypt_samr_CryptPassword()
This will make it easier to implement netr_ServerAuthenticateKerberos() later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 2d7a47a175337729f4c671d7a6223f6e0ea23ebe)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
c944d1fc37 s4:torture/rpc: make use of netlogon_creds_decrypt_samlogon_validation()
This will make it easier to implement netr_ServerAuthenticateKerberos() later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit a177d15c875030dfc6c11ead3ec3a3ec851261cb)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
7664466f8b s4:torture/rpc: make use of netlogon_creds_encrypt_samlogon_logon()
This will make it easier to catch all places where we need to
implement the logic for netr_ServerAuthenticateKerberos...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 1666d1d74dec3978837ab49f8749d59c0abcf595)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
423ee427b2 libcli/auth: make use of netlogon_creds_{de,en}crypt_samr_Password
This will make it easier to implement netr_ServerAuthenticateKerberos() later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit e92d0509d6b4d7f86e8626ba8c5efc5b786823f1)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
c39ab113af libcli/auth: make use of netlogon_creds_encrypt_SendToSam
This will help when implementing netr_ServerAuthenticateKerberos()...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 2bd77ff7314932dc4116773731a810fe0f7ce4b7)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
44803568fc libcli/auth: make use of netlogon_creds_encrypt_samr_CryptPassword
This will help when implementing netr_ServerAuthenticateKerberos()...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 285ec9ecde712e40e6f0981bcb379ee911bfe9d8)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
104dd940b8 libcli/auth: make netlogon_creds_des_{de,en}crypt_LMKey() static
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 1edcd5df80bdbc4d4da5bdd5e534d7a17ec61f77)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
986e85311b python/tests: use encrypt_netr_PasswordInfo in KDCBaseTest._test_samlogon()
This will make it easier to implement netr_ServerAuthenticateKerberos()
later...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit e7d57fc6e992ca212b834d5dd4d381244bca55c6)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
16486fc89e pycredentials: add py_creds_encrypt_netr_PasswordInfo helper
This will replace py_creds_encrypt_samr_password in the next steps
and prepares the introduction of netr_ServerAuthenticateKerberos().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit fac378485f5f15ac0a11c3d82207c4bc780bfb80)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
63cd352ce4 pycredentials: make use of netlogon_creds_encrypt_samr_CryptPassword in py_creds_encrypt_netr_crypt_password
These will simplify adding the logic for netr_ServerAuthenticateKerberos...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit ea792fa342deebefa75b77832c9057924cdcb6f6)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
1942021a04 libcli/auth: add netlogon_creds_{de,en}crypt_SendToSam()
These will simplify adding the logic for netr_ServerAuthenticateKerberos...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit b8681c165731666bb5eed073ab862490c33ea095)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
a67f23403d libcli/auth: add netlogon_creds_{de,en}crypt_samr_CryptPassword()
These will simplify adding the logic for netr_ServerAuthenticateKerberos...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 8eb95a155de396981375c7f11221695fd3c7f9d5)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
ee30900ece libcli/auth: add netlogon_creds_{de,en}crypt_samr_Password()
These will simplify adding the logic for netr_ServerAuthenticateKerberos...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 851a9b18eccece64c3ae0cedd7c7b26a44f0eec6)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
4da8ed66be libcli/auth: pass auth_{type,level} to netlogon_creds_{de,en}crypt_samlogon_logon()
This will be needed when we implement netr_ServerAuthenticateKerberos...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 3d4ea276bdf44202250246cd6edae2bc17e92c74)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
4410937888 libcli/auth: pass auth_{type,level} to netlogon_creds_{de,en}crypt_samlogon_validation()
This will be needed when we implement netr_ServerAuthenticateKerberos...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit a56356e399339d5bce2e699431cd3e6186229170)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
553db707b5 netlogon.idl: add netr_ServerAuthenticateKerberos() and related stuff
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit de8de55a5fee573d0718fa8dd13168a4f0a14614)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
2a210ec5c4 s3:rpc_server: add DCESRV_COMPAT_NOT_USED_ON_WIRE() helper macro
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 62afadb3ebac49a684fb0e5a1beb6d7db6f5e515)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
c7166d2d61 dcesrv_core: add DCESRV_NOT_USED_ON_WIRE() helper macro
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 01577b93cbb0a26aba3209cde69475be2e1c5fb8)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
30d744d0a6 s4:rpc_server/netlogon: split out dcesrv_netr_ServerAuthenticateGeneric()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit e4132c492ded7cadc60371b524e72e41f71f75e9)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
769588b25a s4:dsdb/common: dsdb_trust_get_incoming_passwords only needs a const ldb_message
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit f92def2f943917d8946b03f71fcf676998701815)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
d7b7db05fd libcli/auth: split out netlogon_creds_alloc()
Review with: git show --patience

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit e9767315cf06bcb257b40014441dd4cd9aad0fb0)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
57c1fb9048 libcli/auth: let netlogon_creds_cli_store_internal check netlogon_creds_CredentialState_legacy
Before storing the structure into a ctdb managed volatile database
we check against netlogon_creds_CredentialState_legacy (the structure
used before recent changes). This makes sure unpatched cluster nodes
would not get a parsing error.

We'll remove this again in master when we try to implement
netr_ServerAuthenticateKerberos() and the related changes
to netlogon_creds_CredentialState, which will break the compat...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 3792fe372884aad6ea2893f2e62629dd1cddc129)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
dcd3c2b9d2 libcli/auth: let netlogon_creds_cli_store_internal() use talloc_stackframe()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 17394ed7bbf8fa50570a5732f1ce84ccd5e69393)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
46b7eb7737 libcli/auth: also use netlogon_creds_CredentialState_extra_info for the client
In order to allow backports and cluster updates we simulate a
dom_sid, so that the old code is able to parse the blob.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 8b972fea0978101575f847eac33b09d2fd8d02e7)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
ef69f55556 s4:torture/rpc: let test_netlogon_capabilities() fail on legacy servers
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 498fc88c155b57a0de6150c3b1e3cfcac181d45b)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
1fecabddeb s4:rpc_server/netlogon: implement netr_LogonGetCapabilities query_level=2
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit fd4b027511b18615e215b66183f95b54bcab683e)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
47e5aa1e36 s3:rpc_server/netlogon: implement netr_LogonGetCapabilities query_level=2
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 484a046d8e179a3b21ead8b5bc3660095314e816)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
c6bfa4dbb2 libcli/auth: remember client_requested_flags and auth_time in netlogon_creds_server_init()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit dfbc5e5a19420311eac3db5ede1c665a9198395d)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
a0ad07e82f libcli/auth: remove unused creds->sid
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit a9308c490cb5ec8908a3e4c13e2ce8a08b9027e9)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
72be93b62f s4:rpc_server/netlogon: make use of creds->ex->client_sid
creds->sid will be removed soon...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 4533afc9e12c4dbbc7d11c13e775888c113d497c)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
39399a49d3 s3:rpc_server/netlogon: make use of creds->ex->client_sid
creds->sid will be removed soon...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 88a84d9330d2bb03176f888a0d8e5066e1e21bf6)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
114e369122 librpc/rpc: make use of creds->ex->client_sid in dcesrv_netr_check_schannel_get_state()
creds->sid will be removed soon.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 453587fbc1ef74a3b997235e84040553261fa13e)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
58f657baf0 libcli/auth: split out netlogon_creds_CredentialState_extra_info
As server we are free to change the netlogon_creds_CredentialState
database record format at will as it uses CLEAR_IF_FIRST.

For now that format doesn't really changes, because we
only move dom_sid into a wrapper structure.

In order to avoid changing all callers in this commit,
we maintain creds->sid as in memory pointer.

In the following patches we'll also use it in order
to store client related information...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 518f57b93bdb84900d3b58cd94bdf1046f82a5a6)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
1a6928892a libcli/auth: pass client_sid to netlogon_creds_server_init()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit c2ef866fca296c8f3eb1620fdd2bb9bf289d96fc)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
e03e2f7639 s4:rpc_server/netlogon: add client_sid helper variables
This will make the following changes simpler...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 2e8949495f601d3fd117cceccd1b464a6ae43251)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
d197dd522f s3:rpc_server/netlogon: add client_sid helper variables
This will make the following changes simpler...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit eda3728a4079c5399f693b1d68e64e5660647c72)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
f4edcf3d0e s4:dsdb/common: samdb_confirm_rodc_allowed_to_repl_to() only needs a const sid
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit c9eaf5e22de730f1e7575f6697f32dbb377eae06)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
b5bf7bc381 s3:cli_netlogon: let rpccli_connect_netlogon() use force_reauth = true on retry
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 7f478656dcf08619bc3a7ad390c7db3bfdef924e)
2024-11-13 08:41:12 +00:00
Stefan Metzmacher
c2796abfdc s4:torture/rpc/netlogon: adjust test_netlogon_capabilities query_level=2 to request_flags
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit d174b6595a962230bf71cc5c2f512a2c93a4cc1b)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
83e9f281ca s4:librpc/rpc: use netr_LogonGetCapabilities query_level=2 to verify the proposed capabilities
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 0b6ac4b082ddec5dae1392537727f3a7123ec279)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
5c7301f799 s4:librpc/rpc: define required schannel flags and enforce them
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 25294685b1c2c8652f0ca0220e8f3729e0b347e2)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
41be718d65 s4:librpc/rpc: don't allow any unexpected upgrades of negotiate_flags
Only remove the unsupported flags from local_negotiate_flags for
the next try...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 69b0cbd13d06fa640a900acab6757425b5b77cac)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
59d8a8715d s4:librpc/rpc: do LogonControl after LogonGetCapabilities downgrade
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 24de5d1cbd25fabae6b01565907b53f5e51ea06d)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
9265852ec7 libcli/auth: use netr_LogonGetCapabilities query_level=2 to verify the proposed capabilities
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 25a2105ca7816c47a9c4a7fded88a922e4ccf88b)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
ea1bb19585 libcli/auth: use a LogonControl after a LogonGetCapabilities downgrade
If LogonGetCapabilities was downgraded by an DCERPC Fault, we
rely on the schannel message ordering to detect failures.

Instead of letting any real winbindd request trigger this,
we do it directly in netlogon_creds_cli_check() with
a LogonControl that is also used for 'wbinfo --ping-dc'.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 276137e950696fbf36450dceebd6c0250c6242d0)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
d73e6c7ab0 libcli/auth: if we require aes we don't need to require arcfour nor strong key
But we can send arcfour and strong key on the wire and don't need to
remove them from the proposed flags.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 3da40f1c6818550eb08a6d7d680c213c3f1d0649)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
48acce5da8 libcli/auth: don't allow any unexpected upgrades of negotiate_flags
Only remove the unsupported flags from state->current_flags for
the next try...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit a9040c8ce76cb9911c4c0c5d623cc479e49f460d)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
6f1d556b40 libcli/auth: make use of netlogon_creds_cli_store_internal() in netlogon_creds_cli_auth_srvauth_done()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 69cb9aea67de0613f467f7ce2d460364ff2be241)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
ced6cbfa6b libcli/auth: remove unused netlogon_creds_client_init_session_key()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit cf0e07a3d2a085d31f7d682633af9ec57c155e57)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
8cf7bf9f61 netlogon.idl: the capabilities in query_level=2 are the ones send by the client
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 86176598eee4c83dc63a9dac163f32c886477129)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
349f314488 s4:rpc_server/netlogon: if we require AES there's no need to remove the ARCFOUR flag
With SAMBA_WEAK_CRYPTO_DISALLOWED dcesrv_netr_ServerAuthenticate3_check_downgrade()
will return DOWNGRADE_DETECTED with negotiate_flags = 0, if AES was not
negotiated...

And if AES was negotiated there's no harm in returning the ARCFOUR
flag...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit a0bc372dee68ad255da005d2e2078da754bbef2a)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
6916bf43d3 s3:rpc_server/netlogon: if we require AES there's no need to remove the ARCFOUR flag
With SAMBA_WEAK_CRYPTO_DISALLOWED we will return DOWNGRADE_DETECTED with negotiate_flags = 0,
if AES was not negotiated...

And if AES was negotiated there's no harm in returning the ARCFOUR
flag...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit e5bc5ee3e04138b10c0630640469a08fad847e56)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
a442241004 s3:rpc_server/netlogon: correctly negotiate flags in ServerAuthenticate2/3
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit b27661f832cc4c56cc582cf7041d90f178736ef7)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
0267772cdf s4:torture/rpc: without weak crypto we should require AES
We should check that we can actually negotiated the strong AES
crypto instead of just checking that NETLOGON_NEG_ARCFOUR is not
there...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 3dcbc8eea5bc53a8332b3ad93ea4c3df99af7830)
2024-11-13 08:41:11 +00:00
Stefan Metzmacher
a65ca95d4d s4:torture/rpc: check that DOWNGRADE_DETECTED has no bits negotiated
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15425

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit 36310650ee7a64603128139f512d3a4e039f8822)
2024-11-13 08:41:11 +00:00
29 changed files with 2036 additions and 712 deletions

View File

@ -1074,9 +1074,11 @@ static PyObject *py_creds_get_old_kerberos_key(PyObject *self, PyObject *args)
static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self, static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self,
PyObject *args) PyObject *args)
{ {
DATA_BLOB data = data_blob_null;
struct cli_credentials *creds = NULL; struct cli_credentials *creds = NULL;
struct netr_CryptPassword *pwd = NULL; struct netr_CryptPassword *pwd = NULL;
struct samr_CryptPassword spwd;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
NTSTATUS status; NTSTATUS status;
PyObject *py_cp = Py_None; PyObject *py_cp = Py_None;
@ -1100,9 +1102,18 @@ static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self,
/* pytalloc_get_type sets TypeError */ /* pytalloc_get_type sets TypeError */
return NULL; return NULL;
} }
data.length = sizeof(struct netr_CryptPassword);
data.data = (uint8_t *)pwd; memcpy(spwd.data, pwd->data, 512);
status = netlogon_creds_session_encrypt(creds->netlogon_creds, data); PUSH_LE_U32(spwd.data, 512, pwd->length);
status = netlogon_creds_encrypt_samr_CryptPassword(creds->netlogon_creds,
&spwd,
auth_type,
auth_level);
memcpy(pwd->data, spwd.data, 512);
pwd->length = PULL_LE_U32(spwd.data, 512);
ZERO_STRUCT(spwd);
PyErr_NTSTATUS_IS_ERR_RAISE(status); PyErr_NTSTATUS_IS_ERR_RAISE(status);
@ -1151,6 +1162,68 @@ static PyObject *py_creds_encrypt_samr_password(PyObject *self,
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static PyObject *py_creds_encrypt_netr_PasswordInfo(PyObject *self,
PyObject *args,
PyObject *kwargs)
{
const char * const kwnames[] = {
"info",
"auth_type",
"auth_level",
NULL
};
struct cli_credentials *creds = NULL;
PyObject *py_info = Py_None;
enum netr_LogonInfoClass level = NetlogonInteractiveInformation;
union netr_LogonLevel logon = { .password = NULL, };
uint8_t auth_type = DCERPC_AUTH_TYPE_NONE;
uint8_t auth_level = DCERPC_AUTH_LEVEL_NONE;
NTSTATUS status;
bool ok;
creds = PyCredentials_AsCliCredentials(self);
if (creds == NULL) {
PyErr_Format(PyExc_TypeError, "Credentials expected");
return NULL;
}
if (creds->netlogon_creds == NULL) {
PyErr_Format(PyExc_ValueError, "NetLogon credentials not set");
return NULL;
}
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Obb",
discard_const_p(char *, kwnames),
&py_info, &auth_type, &auth_level))
{
return NULL;
}
ok = py_check_dcerpc_type(py_info,
"samba.dcerpc.netlogon",
"netr_PasswordInfo");
if (!ok) {
/* py_check_dcerpc_type sets TypeError */
return NULL;
}
logon.password = pytalloc_get_type(py_info, struct netr_PasswordInfo);
if (logon.password == NULL) {
/* pytalloc_get_type sets TypeError */
return NULL;
}
status = netlogon_creds_encrypt_samlogon_logon(creds->netlogon_creds,
level,
&logon,
auth_type,
auth_level);
PyErr_NTSTATUS_IS_ERR_RAISE(status);
Py_RETURN_NONE;
}
static PyObject *py_creds_get_smb_signing(PyObject *self, PyObject *unused) static PyObject *py_creds_get_smb_signing(PyObject *self, PyObject *unused)
{ {
enum smb_signing_setting signing_state; enum smb_signing_setting signing_state;
@ -1684,6 +1757,17 @@ static PyMethodDef py_creds_methods[] = {
"the negotiated encryption algorithm in place\n" "the negotiated encryption algorithm in place\n"
"i.e. it overwrites the original data" "i.e. it overwrites the original data"
}, },
{
.ml_name = "encrypt_netr_PasswordInfo",
.ml_meth = PY_DISCARD_FUNC_SIG(PyCFunction,
py_creds_encrypt_netr_PasswordInfo),
.ml_flags = METH_VARARGS | METH_KEYWORDS,
.ml_doc = "S.encrypt_netr_PasswordInfo(info, "
"auth_type, auth_level) -> None\n"
"Encrypt the supplied password info using the session key and\n"
"the negotiated encryption algorithm in place\n"
"i.e. it overwrites the original data"
},
{ {
.ml_name = "get_smb_signing", .ml_name = "get_smb_signing",
.ml_meth = py_creds_get_smb_signing, .ml_meth = py_creds_get_smb_signing,

View File

@ -290,7 +290,7 @@ static NTSTATUS netlogon_creds_step(struct netlogon_creds_CredentialState *creds
/* /*
DES encrypt a 8 byte LMSessionKey buffer using the Netlogon session key DES encrypt a 8 byte LMSessionKey buffer using the Netlogon session key
*/ */
NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, static NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds,
struct netr_LMSessionKey *key) struct netr_LMSessionKey *key)
{ {
int rc; int rc;
@ -308,7 +308,7 @@ NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState
/* /*
DES decrypt a 8 byte LMSessionKey buffer using the Netlogon session key DES decrypt a 8 byte LMSessionKey buffer using the Netlogon session key
*/ */
NTSTATUS netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, static NTSTATUS netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds,
struct netr_LMSessionKey *key) struct netr_LMSessionKey *key)
{ {
int rc; int rc;
@ -473,6 +473,58 @@ NTSTATUS netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds
return NT_STATUS_OK; return NT_STATUS_OK;
} }
static struct netlogon_creds_CredentialState *
netlogon_creds_alloc(TALLOC_CTX *mem_ctx,
const char *client_account,
const char *client_computer_name,
uint16_t secure_channel_type,
uint32_t client_requested_flags,
const struct dom_sid *client_sid,
uint32_t negotiate_flags)
{
struct netlogon_creds_CredentialState *creds = NULL;
struct timeval tv = timeval_current();
NTTIME now = timeval_to_nttime(&tv);
creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);
if (creds == NULL) {
return NULL;
}
if (client_sid == NULL) {
creds->sequence = tv.tv_sec;
}
creds->negotiate_flags = negotiate_flags;
creds->secure_channel_type = secure_channel_type;
creds->computer_name = talloc_strdup(creds, client_computer_name);
if (!creds->computer_name) {
talloc_free(creds);
return NULL;
}
creds->account_name = talloc_strdup(creds, client_account);
if (!creds->account_name) {
talloc_free(creds);
return NULL;
}
creds->ex = talloc_zero(creds,
struct netlogon_creds_CredentialState_extra_info);
if (creds->ex == NULL) {
talloc_free(creds);
return NULL;
}
creds->ex->client_requested_flags = client_requested_flags;
creds->ex->auth_time = now;
if (client_sid != NULL) {
creds->ex->client_sid = *client_sid;
} else {
creds->ex->client_sid = global_sid_NULL;
}
return creds;
}
/***************************************************************** /*****************************************************************
The above functions are common to the client and server interface The above functions are common to the client and server interface
next comes the client specific functions next comes the client specific functions
@ -491,30 +543,23 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *me
const struct netr_Credential *server_challenge, const struct netr_Credential *server_challenge,
const struct samr_Password *machine_password, const struct samr_Password *machine_password,
struct netr_Credential *initial_credential, struct netr_Credential *initial_credential,
uint32_t client_requested_flags,
uint32_t negotiate_flags) uint32_t negotiate_flags)
{ {
struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState); struct netlogon_creds_CredentialState *creds = NULL;
NTSTATUS status; NTSTATUS status;
creds = netlogon_creds_alloc(mem_ctx,
client_account,
client_computer_name,
secure_channel_type,
client_requested_flags,
NULL, /* client_sid */
negotiate_flags);
if (!creds) { if (!creds) {
return NULL; return NULL;
} }
creds->sequence = time(NULL);
creds->negotiate_flags = negotiate_flags;
creds->secure_channel_type = secure_channel_type;
creds->computer_name = talloc_strdup(creds, client_computer_name);
if (!creds->computer_name) {
talloc_free(creds);
return NULL;
}
creds->account_name = talloc_strdup(creds, client_account);
if (!creds->account_name) {
talloc_free(creds);
return NULL;
}
dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data));
dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data));
dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash)); dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash));
@ -563,25 +608,6 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *me
return creds; return creds;
} }
/*
initialise the credentials structure with only a session key. The caller better know what they are doing!
*/
struct netlogon_creds_CredentialState *netlogon_creds_client_init_session_key(TALLOC_CTX *mem_ctx,
const uint8_t session_key[16])
{
struct netlogon_creds_CredentialState *creds;
creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);
if (!creds) {
return NULL;
}
memcpy(creds->session_key, session_key, 16);
return creds;
}
/* /*
step the credentials to the next element in the chain, updating the step the credentials to the next element in the chain, updating the
current client and server credentials and the seed current client and server credentials and the seed
@ -631,14 +657,34 @@ netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds
/* /*
check that a credentials reply from a server is correct check that a credentials reply from a server is correct
*/ */
bool netlogon_creds_client_check(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_client_verify(struct netlogon_creds_CredentialState *creds,
const struct netr_Credential *received_credentials) const struct netr_Credential *received_credentials,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{ {
if (!received_credentials || if (!received_credentials ||
!mem_equal_const_time(received_credentials->data, creds->server.data, 8)) { !mem_equal_const_time(received_credentials->data, creds->server.data, 8)) {
DEBUG(2,("credentials check failed\n")); DEBUG(2,("credentials check failed\n"));
return NT_STATUS_ACCESS_DENIED;
}
return NT_STATUS_OK;
}
bool netlogon_creds_client_check(struct netlogon_creds_CredentialState *creds,
const struct netr_Credential *received_credentials)
{
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
NTSTATUS status;
status = netlogon_creds_client_verify(creds,
received_credentials,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) {
return false; return false;
} }
return true; return true;
} }
@ -676,20 +722,25 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me
const struct samr_Password *machine_password, const struct samr_Password *machine_password,
const struct netr_Credential *credentials_in, const struct netr_Credential *credentials_in,
struct netr_Credential *credentials_out, struct netr_Credential *credentials_out,
uint32_t client_requested_flags,
const struct dom_sid *client_sid,
uint32_t negotiate_flags) uint32_t negotiate_flags)
{ {
struct netlogon_creds_CredentialState *creds = NULL;
struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);
NTSTATUS status; NTSTATUS status;
bool ok; bool ok;
creds = netlogon_creds_alloc(mem_ctx,
client_account,
client_computer_name,
secure_channel_type,
client_requested_flags,
client_sid,
negotiate_flags);
if (!creds) { if (!creds) {
return NULL; return NULL;
} }
creds->negotiate_flags = negotiate_flags;
creds->secure_channel_type = secure_channel_type;
dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data));
dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data));
dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash)); dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash));
@ -708,17 +759,6 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me
return NULL; return NULL;
} }
creds->computer_name = talloc_strdup(creds, client_computer_name);
if (!creds->computer_name) {
talloc_free(creds);
return NULL;
}
creds->account_name = talloc_strdup(creds, client_account);
if (!creds->account_name) {
talloc_free(creds);
return NULL;
}
if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
status = netlogon_creds_init_hmac_sha256(creds, status = netlogon_creds_init_hmac_sha256(creds,
client_challenge, client_challenge,
@ -778,7 +818,9 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me
NTSTATUS netlogon_creds_server_step_check(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_server_step_check(struct netlogon_creds_CredentialState *creds,
const struct netr_Authenticator *received_authenticator, const struct netr_Authenticator *received_authenticator,
struct netr_Authenticator *return_authenticator) struct netr_Authenticator *return_authenticator,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{ {
NTSTATUS status; NTSTATUS status;
@ -810,6 +852,8 @@ NTSTATUS netlogon_creds_server_step_check(struct netlogon_creds_CredentialState
static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_CredentialState *creds, static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_CredentialState *creds,
uint16_t validation_level, uint16_t validation_level,
union netr_Validation *validation, union netr_Validation *validation,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level,
bool do_encrypt) bool do_encrypt)
{ {
struct netr_SamBaseInfo *base = NULL; struct netr_SamBaseInfo *base = NULL;
@ -925,27 +969,37 @@ static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_C
NTSTATUS netlogon_creds_decrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_decrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds,
uint16_t validation_level, uint16_t validation_level,
union netr_Validation *validation) union netr_Validation *validation,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{ {
return netlogon_creds_crypt_samlogon_validation(creds, return netlogon_creds_crypt_samlogon_validation(creds,
validation_level, validation_level,
validation, validation,
auth_type,
auth_level,
false); false);
} }
NTSTATUS netlogon_creds_encrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_encrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds,
uint16_t validation_level, uint16_t validation_level,
union netr_Validation *validation) union netr_Validation *validation,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{ {
return netlogon_creds_crypt_samlogon_validation(creds, return netlogon_creds_crypt_samlogon_validation(creds,
validation_level, validation_level,
validation, validation,
auth_type,
auth_level,
true); true);
} }
static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_CredentialState *creds, static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
enum netr_LogonInfoClass level, enum netr_LogonInfoClass level,
union netr_LogonLevel *logon, union netr_LogonLevel *logon,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level,
bool do_encrypt) bool do_encrypt)
{ {
NTSTATUS status; NTSTATUS status;
@ -1082,6 +1136,7 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden
} }
} else { } else {
/* Using DES to verify kerberos tickets makes no sense */ /* Using DES to verify kerberos tickets makes no sense */
return NT_STATUS_INVALID_PARAMETER;
} }
break; break;
} }
@ -1091,16 +1146,178 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden
NTSTATUS netlogon_creds_decrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_decrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
enum netr_LogonInfoClass level, enum netr_LogonInfoClass level,
union netr_LogonLevel *logon) union netr_LogonLevel *logon,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{ {
return netlogon_creds_crypt_samlogon_logon(creds, level, logon, false); return netlogon_creds_crypt_samlogon_logon(creds,
level,
logon,
auth_type,
auth_level,
false);
} }
NTSTATUS netlogon_creds_encrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_encrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
enum netr_LogonInfoClass level, enum netr_LogonInfoClass level,
union netr_LogonLevel *logon) union netr_LogonLevel *logon,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{ {
return netlogon_creds_crypt_samlogon_logon(creds, level, logon, true); return netlogon_creds_crypt_samlogon_logon(creds,
level,
logon,
auth_type,
auth_level,
true);
}
static NTSTATUS netlogon_creds_crypt_samr_Password(
struct netlogon_creds_CredentialState *creds,
struct samr_Password *pass,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level,
bool do_encrypt)
{
if (all_zero(pass->hash, ARRAY_SIZE(pass->hash))) {
return NT_STATUS_OK;
}
/*
* Even with NETLOGON_NEG_SUPPORTS_AES or
* NETLOGON_NEG_ARCFOUR this uses DES
*/
if (do_encrypt) {
return netlogon_creds_des_encrypt(creds, pass);
}
return netlogon_creds_des_decrypt(creds, pass);
}
NTSTATUS netlogon_creds_decrypt_samr_Password(struct netlogon_creds_CredentialState *creds,
struct samr_Password *pass,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{
return netlogon_creds_crypt_samr_Password(creds,
pass,
auth_type,
auth_level,
false);
}
NTSTATUS netlogon_creds_encrypt_samr_Password(struct netlogon_creds_CredentialState *creds,
struct samr_Password *pass,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{
return netlogon_creds_crypt_samr_Password(creds,
pass,
auth_type,
auth_level,
true);
}
static NTSTATUS netlogon_creds_crypt_samr_CryptPassword(
struct netlogon_creds_CredentialState *creds,
struct samr_CryptPassword *pass,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level,
bool do_encrypt)
{
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
if (do_encrypt) {
return netlogon_creds_aes_encrypt(creds,
pass->data,
ARRAY_SIZE(pass->data));
}
return netlogon_creds_aes_decrypt(creds,
pass->data,
ARRAY_SIZE(pass->data));
}
return netlogon_creds_arcfour_crypt(creds,
pass->data,
ARRAY_SIZE(pass->data));
}
NTSTATUS netlogon_creds_decrypt_samr_CryptPassword(struct netlogon_creds_CredentialState *creds,
struct samr_CryptPassword *pass,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{
return netlogon_creds_crypt_samr_CryptPassword(creds,
pass,
auth_type,
auth_level,
false);
}
NTSTATUS netlogon_creds_encrypt_samr_CryptPassword(struct netlogon_creds_CredentialState *creds,
struct samr_CryptPassword *pass,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{
return netlogon_creds_crypt_samr_CryptPassword(creds,
pass,
auth_type,
auth_level,
true);
}
static NTSTATUS netlogon_creds_crypt_SendToSam(
struct netlogon_creds_CredentialState *creds,
uint8_t *opaque_data,
size_t opaque_length,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level,
bool do_encrypt)
{
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
if (do_encrypt) {
return netlogon_creds_aes_encrypt(creds,
opaque_data,
opaque_length);
}
return netlogon_creds_aes_decrypt(creds,
opaque_data,
opaque_length);
}
return netlogon_creds_arcfour_crypt(creds,
opaque_data,
opaque_length);
}
NTSTATUS netlogon_creds_decrypt_SendToSam(struct netlogon_creds_CredentialState *creds,
uint8_t *opaque_data,
size_t opaque_length,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{
return netlogon_creds_crypt_SendToSam(creds,
opaque_data,
opaque_length,
auth_type,
auth_level,
false);
}
NTSTATUS netlogon_creds_encrypt_SendToSam(struct netlogon_creds_CredentialState *creds,
uint8_t *opaque_data,
size_t opaque_length,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{
return netlogon_creds_crypt_SendToSam(creds,
opaque_data,
opaque_length,
auth_type,
auth_level,
true);
} }
union netr_LogonLevel *netlogon_creds_shallow_copy_logon(TALLOC_CTX *mem_ctx, union netr_LogonLevel *netlogon_creds_shallow_copy_logon(TALLOC_CTX *mem_ctx,
@ -1190,9 +1407,7 @@ struct netlogon_creds_CredentialState *netlogon_creds_copy(
return NULL; return NULL;
} }
creds->sequence = creds_in->sequence; *creds = *creds_in;
creds->negotiate_flags = creds_in->negotiate_flags;
creds->secure_channel_type = creds_in->secure_channel_type;
creds->computer_name = talloc_strdup(creds, creds_in->computer_name); creds->computer_name = talloc_strdup(creds, creds_in->computer_name);
if (!creds->computer_name) { if (!creds->computer_name) {
@ -1205,18 +1420,15 @@ struct netlogon_creds_CredentialState *netlogon_creds_copy(
return NULL; return NULL;
} }
if (creds_in->sid) { if (creds_in->ex != NULL) {
creds->sid = dom_sid_dup(creds, creds_in->sid); creds->ex = talloc_zero(creds,
if (!creds->sid) { struct netlogon_creds_CredentialState_extra_info);
if (creds->ex == NULL) {
talloc_free(creds); talloc_free(creds);
return NULL; return NULL;
} }
*creds->ex = *creds_in->ex;
} }
memcpy(creds->session_key, creds_in->session_key, sizeof(creds->session_key));
memcpy(creds->seed.data, creds_in->seed.data, sizeof(creds->seed.data));
memcpy(creds->client.data, creds_in->client.data, sizeof(creds->client.data));
memcpy(creds->server.data, creds_in->server.data, sizeof(creds->server.data));
return creds; return creds;
} }

View File

@ -17,6 +17,7 @@
#ifndef __LIBCLI_AUTH_H__ #ifndef __LIBCLI_AUTH_H__
#define __LIBCLI_AUTH_H__ #define __LIBCLI_AUTH_H__
#include "librpc/gen_ndr/dcerpc.h"
#include "librpc/gen_ndr/netlogon.h" #include "librpc/gen_ndr/netlogon.h"
#include "librpc/gen_ndr/wkssvc.h" #include "librpc/gen_ndr/wkssvc.h"
#include "librpc/gen_ndr/schannel.h" #include "librpc/gen_ndr/schannel.h"

File diff suppressed because it is too large Load Diff

View File

@ -16,10 +16,6 @@
bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge); bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge);
void netlogon_creds_random_challenge(struct netr_Credential *challenge); void netlogon_creds_random_challenge(struct netr_Credential *challenge);
NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds,
struct netr_LMSessionKey *key);
NTSTATUS netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds,
struct netr_LMSessionKey *key);
NTSTATUS netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds,
struct samr_Password *pass); struct samr_Password *pass);
NTSTATUS netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds,
@ -46,12 +42,15 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *me
const struct netr_Credential *server_challenge, const struct netr_Credential *server_challenge,
const struct samr_Password *machine_password, const struct samr_Password *machine_password,
struct netr_Credential *initial_credential, struct netr_Credential *initial_credential,
uint32_t client_requested_flags,
uint32_t negotiate_flags); uint32_t negotiate_flags);
struct netlogon_creds_CredentialState *netlogon_creds_client_init_session_key(TALLOC_CTX *mem_ctx,
const uint8_t session_key[16]);
NTSTATUS NTSTATUS
netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds, netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds,
struct netr_Authenticator *next); struct netr_Authenticator *next);
NTSTATUS netlogon_creds_client_verify(struct netlogon_creds_CredentialState *creds,
const struct netr_Credential *received_credentials,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
bool netlogon_creds_client_check(struct netlogon_creds_CredentialState *creds, bool netlogon_creds_client_check(struct netlogon_creds_CredentialState *creds,
const struct netr_Credential *received_credentials); const struct netr_Credential *received_credentials);
struct netlogon_creds_CredentialState *netlogon_creds_copy( struct netlogon_creds_CredentialState *netlogon_creds_copy(
@ -71,22 +70,60 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me
const struct samr_Password *machine_password, const struct samr_Password *machine_password,
const struct netr_Credential *credentials_in, const struct netr_Credential *credentials_in,
struct netr_Credential *credentials_out, struct netr_Credential *credentials_out,
uint32_t client_requested_flags,
const struct dom_sid *client_sid,
uint32_t negotiate_flags); uint32_t negotiate_flags);
NTSTATUS netlogon_creds_server_step_check(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_server_step_check(struct netlogon_creds_CredentialState *creds,
const struct netr_Authenticator *received_authenticator, const struct netr_Authenticator *received_authenticator,
struct netr_Authenticator *return_authenticator) ; struct netr_Authenticator *return_authenticator,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
NTSTATUS netlogon_creds_decrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_decrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds,
uint16_t validation_level, uint16_t validation_level,
union netr_Validation *validation); union netr_Validation *validation,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
NTSTATUS netlogon_creds_encrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_encrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds,
uint16_t validation_level, uint16_t validation_level,
union netr_Validation *validation); union netr_Validation *validation,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
NTSTATUS netlogon_creds_decrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_decrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
enum netr_LogonInfoClass level, enum netr_LogonInfoClass level,
union netr_LogonLevel *logon); union netr_LogonLevel *logon,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
NTSTATUS netlogon_creds_encrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds, NTSTATUS netlogon_creds_encrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
enum netr_LogonInfoClass level, enum netr_LogonInfoClass level,
union netr_LogonLevel *logon); union netr_LogonLevel *logon,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
NTSTATUS netlogon_creds_decrypt_samr_Password(struct netlogon_creds_CredentialState *creds,
struct samr_Password *pass,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
NTSTATUS netlogon_creds_encrypt_samr_Password(struct netlogon_creds_CredentialState *creds,
struct samr_Password *pass,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
NTSTATUS netlogon_creds_decrypt_samr_CryptPassword(struct netlogon_creds_CredentialState *creds,
struct samr_CryptPassword *pass,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
NTSTATUS netlogon_creds_encrypt_samr_CryptPassword(struct netlogon_creds_CredentialState *creds,
struct samr_CryptPassword *pass,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
NTSTATUS netlogon_creds_decrypt_SendToSam(struct netlogon_creds_CredentialState *creds,
uint8_t *opaque_data,
size_t opaque_length,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
NTSTATUS netlogon_creds_encrypt_SendToSam(struct netlogon_creds_CredentialState *creds,
uint8_t *opaque_data,
size_t opaque_length,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level);
union netr_LogonLevel *netlogon_creds_shallow_copy_logon(TALLOC_CTX *mem_ctx, union netr_LogonLevel *netlogon_creds_shallow_copy_logon(TALLOC_CTX *mem_ctx,
enum netr_LogonInfoClass level, enum netr_LogonInfoClass level,
const union netr_LogonLevel *in); const union netr_LogonLevel *in);

View File

@ -37,6 +37,8 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
const char *computer_name, const char *computer_name,
struct netr_Authenticator *received_authenticator, struct netr_Authenticator *received_authenticator,
struct netr_Authenticator *return_authenticator, struct netr_Authenticator *return_authenticator,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level,
struct netlogon_creds_CredentialState **creds_out); struct netlogon_creds_CredentialState **creds_out);
NTSTATUS schannel_get_challenge(struct loadparm_context *lp_ctx, NTSTATUS schannel_get_challenge(struct loadparm_context *lp_ctx,

View File

@ -88,6 +88,10 @@ NTSTATUS schannel_store_session_key_tdb(struct db_context *db_sc,
char *name_upper; char *name_upper;
NTSTATUS status; NTSTATUS status;
if (creds->ex == NULL) {
return NT_STATUS_INTERNAL_ERROR;
}
if (strlen(creds->computer_name) > 15) { if (strlen(creds->computer_name) > 15) {
/* /*
* We may want to check for a completely * We may want to check for a completely
@ -195,6 +199,11 @@ NTSTATUS schannel_fetch_session_key_tdb(struct db_context *db_sc,
NDR_PRINT_DEBUG(netlogon_creds_CredentialState, creds); NDR_PRINT_DEBUG(netlogon_creds_CredentialState, creds);
} }
if (creds->ex == NULL) {
status = NT_STATUS_INTERNAL_ERROR;
goto done;
}
DEBUG(3,("schannel_fetch_session_key_tdb: restored schannel info key %s\n", DEBUG(3,("schannel_fetch_session_key_tdb: restored schannel info key %s\n",
keystr)); keystr));
@ -560,6 +569,8 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
const char *computer_name, const char *computer_name,
struct netr_Authenticator *received_authenticator, struct netr_Authenticator *received_authenticator,
struct netr_Authenticator *return_authenticator, struct netr_Authenticator *return_authenticator,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level,
struct netlogon_creds_CredentialState **creds_out) struct netlogon_creds_CredentialState **creds_out)
{ {
TALLOC_CTX *tmpctx; TALLOC_CTX *tmpctx;
@ -619,7 +630,9 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
status = netlogon_creds_server_step_check(creds, status = netlogon_creds_server_step_check(creds,
received_authenticator, received_authenticator,
return_authenticator); return_authenticator,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
goto done; goto done;
} }

View File

@ -1036,7 +1036,8 @@ interface netlogon
NETLOGON_NEG_SUPPORTS_AES_SHA2 = 0x00400000, NETLOGON_NEG_SUPPORTS_AES_SHA2 = 0x00400000,
NETLOGON_NEG_SUPPORTS_AES = 0x01000000, NETLOGON_NEG_SUPPORTS_AES = 0x01000000,
NETLOGON_NEG_AUTHENTICATED_RPC_LSASS = 0x20000000, NETLOGON_NEG_AUTHENTICATED_RPC_LSASS = 0x20000000,
NETLOGON_NEG_AUTHENTICATED_RPC = 0x40000000 NETLOGON_NEG_AUTHENTICATED_RPC = 0x40000000,
NETLOGON_NEG_SUPPORTS_KERBEROS_AUTH = 0x80000000
} netr_NegotiateFlags; } netr_NegotiateFlags;
const uint32 NETLOGON_NEG_128BIT = NETLOGON_NEG_STRONG_KEYS; const uint32 NETLOGON_NEG_128BIT = NETLOGON_NEG_STRONG_KEYS;
@ -1236,7 +1237,7 @@ interface netlogon
/* Function 0x15 */ /* Function 0x15 */
typedef [switch_type(uint32)] union { typedef [switch_type(uint32)] union {
[case(1)] netr_NegotiateFlags server_capabilities; [case(1)] netr_NegotiateFlags server_capabilities;
[case(2)] netr_NegotiateFlags server_capabilities; [case(2)] netr_NegotiateFlags requested_flags;
} netr_Capabilities; } netr_Capabilities;
NTSTATUS netr_LogonGetCapabilities( NTSTATUS netr_LogonGetCapabilities(
@ -1885,4 +1886,32 @@ interface netlogon
[in] uint32 dns_ttl, [in] uint32 dns_ttl,
[in,out,ref] NL_DNS_NAME_INFO_ARRAY *dns_names [in,out,ref] NL_DNS_NAME_INFO_ARRAY *dns_names
); );
[todo] void netr_Opnum49NotUsedOnWire(void);
[todo] void netr_Opnum50NotUsedOnWire(void);
[todo] void netr_Opnum51NotUsedOnWire(void);
[todo] void netr_Opnum52NotUsedOnWire(void);
[todo] void netr_Opnum53NotUsedOnWire(void);
/**********************/
/* Function 0x36 (54) */
/* from wireshark: */
/* This is documented as 49 (0x31) but it's 54) */
[todo] NTSTATUS netr_ChainSetClientAttributes();
[todo] void netr_Opnum55NotUsedOnWire(void);
[todo] void netr_Opnum56NotUsedOnWire(void);
[todo] void netr_Opnum57NotUsedOnWire(void);
[todo] void netr_Opnum58NotUsedOnWire(void);
/*****************/
/* Function 0x3b (59) */
[public] NTSTATUS netr_ServerAuthenticateKerberos(
[in,unique] [string,charset(UTF16)] uint16 *server_name,
[in] [string,charset(UTF16)] uint16 *account_name,
[in] netr_SchannelType account_type,
[in] [string,charset(UTF16)] uint16 *computer_name,
[in,out,ref] netr_NegotiateFlags *negotiate_flags,
[out,ref] uint32 *rid
);
} }

View File

@ -14,6 +14,77 @@ interface schannel
{ {
/* this structure is used internally in the NETLOGON server */ /* this structure is used internally in the NETLOGON server */
typedef [flag(NDR_PAHEX)] struct {
/*
* These were only used on the server part
* with a single dom_sid for the client_sid.
*
* On the server we use CLEAR_IF_FIRST,
* so db layout changes don't matter there,
* but on the client side we need to handle
* the ctdb case were CLEAR_IF_FIRST only
* works if all cluster nodes are restarted.
*
* As this was a single dom_sid before,
* we add some magic in order to let
* old code (on other nodes to parse the new layout).
*
* We have basically this definition of dom_sid:
*
* typedef struct {
* uint8 sid_rev_num;
* [range(0,15)] int8 num_auths;
* uint8 id_auth[6];
* uint32 sub_auths[num_auths];
* } dom_sid;
*
* It means it consumes at least 8 bytes while
* and it's also 4 byte aligned (before sid_rev_num).
* The largest sid would have 68 bytes.
*
* The old client side code would see a sid like
* this: S-1-RSV-CRF-ATL-ATH-257-0-RID
*
* RSV => reserved (the last 4 bytes of id_auth)
*
* CRF => client_requested_flags (sub_auths[0]
*
* Note NTTIME used ndr_pull_udlong, it's not NTTIME_hyper!
* ATL => low 4 bytes of auth_time (sub_auths[1])
* ATH => high 4 bytes of auth_time (sub_auths[2])
*
* From client_sid (S-1-0-RID): sub_auth[3-5]
*
* 257 => 0x01 0x01 0x00 0x00 =
* (sid_rev_num = 1, num_auths =1,
* id_auth[0] = 0, id_auth[1] = 0)
* 0 => id_auth[2-6]
*
* RID => the RID of the client
*
* It means the magic needs to simulate
* num_auths = 6
*/
[value(0x00000601)] uint32 magic;
[value(0)] uint32 reserved;
netr_NegotiateFlags client_requested_flags;
NTTIME auth_time;
dom_sid client_sid;
} netlogon_creds_CredentialState_extra_info;
typedef [public,flag(NDR_PAHEX)] struct {
netr_NegotiateFlags negotiate_flags;
uint8 session_key[16];
uint32 sequence;
netr_Credential seed;
netr_Credential client;
netr_Credential server;
netr_SchannelType secure_channel_type;
[string,charset(UTF8)] uint8 computer_name[];
[string,charset(UTF8)] uint8 account_name[];
netlogon_creds_CredentialState_extra_info *ex;
} netlogon_creds_CredentialState;
typedef [public,flag(NDR_PAHEX)] struct { typedef [public,flag(NDR_PAHEX)] struct {
netr_NegotiateFlags negotiate_flags; netr_NegotiateFlags negotiate_flags;
uint8 session_key[16]; uint8 session_key[16];
@ -25,7 +96,7 @@ interface schannel
[string,charset(UTF8)] uint8 computer_name[]; [string,charset(UTF8)] uint8 computer_name[];
[string,charset(UTF8)] uint8 account_name[]; [string,charset(UTF8)] uint8 account_name[];
dom_sid *sid; dom_sid *sid;
} netlogon_creds_CredentialState; } netlogon_creds_CredentialState_legacy;
/* This is used in the schannel_store.tdb */ /* This is used in the schannel_store.tdb */
typedef [public] struct { typedef [public] struct {

View File

@ -578,6 +578,14 @@ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
return; \ return; \
} while(0) } while(0)
#define DCESRV_NOT_USED_ON_WIRE(__opname) \
static void dcesrv_## __opname(struct dcesrv_call_state *dce_call,\
TALLOC_CTX *mem_ctx, \
struct __opname *r) \
{ \
DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); \
}
/* a useful macro for checking the validity of a dcerpc policy handle /* a useful macro for checking the validity of a dcerpc policy handle
and giving the right fault code if invalid */ and giving the right fault code if invalid */
#define DCESRV_CHECK_HANDLE(h) do {if (!(h)) DCESRV_FAULT(DCERPC_FAULT_CONTEXT_MISMATCH); } while (0) #define DCESRV_CHECK_HANDLE(h) do {if (!(h)) DCESRV_FAULT(DCERPC_FAULT_CONTEXT_MISMATCH); } while (0)

View File

@ -70,7 +70,7 @@ static NTSTATUS dcesrv_netr_check_schannel_get_state(struct dcesrv_call_state *d
DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC, DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
struct dcesrv_netr_check_schannel_state); struct dcesrv_netr_check_schannel_state);
if (s != NULL) { if (s != NULL) {
if (!dom_sid_equal(&s->account_sid, creds->sid)) { if (!dom_sid_equal(&s->account_sid, &creds->ex->client_sid)) {
goto new_state; goto new_state;
} }
if (s->auth_type != auth_type) { if (s->auth_type != auth_type) {
@ -92,7 +92,7 @@ new_state:
return NT_STATUS_NO_MEMORY; return NT_STATUS_NO_MEMORY;
} }
s->account_sid = *creds->sid; s->account_sid = creds->ex->client_sid;
s->auth_type = auth_type; s->auth_type = auth_type;
s->auth_level = auth_level; s->auth_level = auth_level;
s->result = NT_STATUS_MORE_PROCESSING_REQUIRED; s->result = NT_STATUS_MORE_PROCESSING_REQUIRED;
@ -548,6 +548,8 @@ NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
computer_name, computer_name,
received_authenticator, received_authenticator,
return_authenticator, return_authenticator,
auth_type,
auth_level,
&creds); &creds);
if (!NT_STATUS_IS_OK(nt_status)) { if (!NT_STATUS_IS_OK(nt_status)) {
ZERO_STRUCTP(return_authenticator); ZERO_STRUCTP(return_authenticator);

View File

@ -54,6 +54,7 @@ from samba.credentials import (
from samba.crypto import des_crypt_blob_16, md4_hash_blob from samba.crypto import des_crypt_blob_16, md4_hash_blob
from samba.dcerpc import ( from samba.dcerpc import (
claims, claims,
dcerpc,
drsblobs, drsblobs,
drsuapi, drsuapi,
krb5ccache, krb5ccache,
@ -3702,10 +3703,12 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest):
workstation = domain_joined_mach_creds.get_username() workstation = domain_joined_mach_creds.get_username()
# Calling this initializes netlogon_creds on mach_creds, as is required # Calling this initializes netlogon_creds on mach_creds, as is required
# before calling mach_creds.encrypt_samr_password(). # before calling mach_creds.encrypt_netr_PasswordInfo().
conn = netlogon.netlogon(f'ncacn_ip_tcp:{dc_server}[schannel,seal]', conn = netlogon.netlogon(f'ncacn_ip_tcp:{dc_server}[schannel,seal]',
self.get_lp(), self.get_lp(),
domain_joined_mach_creds) domain_joined_mach_creds)
auth_type = dcerpc.DCERPC_AUTH_TYPE_SCHANNEL
auth_level = dcerpc.DCERPC_AUTH_LEVEL_PRIVACY
if logon_type == netlogon.NetlogonInteractiveInformation: if logon_type == netlogon.NetlogonInteractiveInformation:
logon = netlogon.netr_PasswordInfo() logon = netlogon.netr_PasswordInfo()
@ -3715,11 +3718,14 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest):
nt_pass = samr.Password() nt_pass = samr.Password()
nt_pass.hash = list(creds.get_nt_hash()) nt_pass.hash = list(creds.get_nt_hash())
domain_joined_mach_creds.encrypt_samr_password(nt_pass)
logon.lmpassword = lm_pass logon.lmpassword = lm_pass
logon.ntpassword = nt_pass logon.ntpassword = nt_pass
domain_joined_mach_creds.encrypt_netr_PasswordInfo(info=logon,
auth_type=auth_type,
auth_level=auth_level)
elif logon_type == netlogon.NetlogonNetworkInformation: elif logon_type == netlogon.NetlogonNetworkInformation:
computername = ntlmssp.AV_PAIR() computername = ntlmssp.AV_PAIR()
computername.AvId = ntlmssp.MsvAvNbComputerName computername.AvId = ntlmssp.MsvAvNbComputerName

View File

@ -387,6 +387,7 @@ again:
if (!retry && NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) { if (!retry && NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
DBG_DEBUG("Retrying with serverauthenticate\n"); DBG_DEBUG("Retrying with serverauthenticate\n");
TALLOC_FREE(lck); TALLOC_FREE(lck);
force_reauth = true;
retry = true; retry = true;
goto again; goto again;
} }

View File

@ -896,6 +896,7 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
/* r->in.negotiate_flags is an aliased pointer to r->out.negotiate_flags, /* r->in.negotiate_flags is an aliased pointer to r->out.negotiate_flags,
* so use a copy to avoid destroying the client values. */ * so use a copy to avoid destroying the client values. */
uint32_t in_neg_flags = *r->in.negotiate_flags; uint32_t in_neg_flags = *r->in.negotiate_flags;
uint32_t neg_flags = 0;
const char *fn; const char *fn;
struct loadparm_context *lp_ctx = p->dce_call->conn->dce_ctx->lp_ctx; struct loadparm_context *lp_ctx = p->dce_call->conn->dce_ctx->lp_ctx;
struct dom_sid sid; struct dom_sid sid;
@ -912,7 +913,6 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
* an error or not. * an error or not.
*/ */
/* 0x000001ff */
srv_flgs = NETLOGON_NEG_ACCOUNT_LOCKOUT | srv_flgs = NETLOGON_NEG_ACCOUNT_LOCKOUT |
NETLOGON_NEG_PERSISTENT_SAMREPL | NETLOGON_NEG_PERSISTENT_SAMREPL |
NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_ARCFOUR |
@ -922,20 +922,22 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
NETLOGON_NEG_MULTIPLE_SIDS | NETLOGON_NEG_MULTIPLE_SIDS |
NETLOGON_NEG_REDO | NETLOGON_NEG_REDO |
NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL | NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
NETLOGON_NEG_PASSWORD_SET2; NETLOGON_NEG_PASSWORD_SET2 |
NETLOGON_NEG_STRONG_KEYS |
NETLOGON_NEG_SUPPORTS_AES |
NETLOGON_NEG_SCHANNEL;
/* Ensure we support strong (128-bit) keys. */ /*
if (in_neg_flags & NETLOGON_NEG_STRONG_KEYS) { * With SAMBA_WEAK_CRYPTO_DISALLOWED we will return DOWNGRADE_DETECTED
srv_flgs |= NETLOGON_NEG_STRONG_KEYS; * with negotiate_flags = 0 below, if NETLOGON_NEG_SUPPORTS_AES was not
} * negotiated...
*
if (in_neg_flags & NETLOGON_NEG_SUPPORTS_AES) { * And if NETLOGON_NEG_SUPPORTS_AES was negotiated there's no harm in
srv_flgs |= NETLOGON_NEG_SUPPORTS_AES; * returning the NETLOGON_NEG_ARCFOUR flag too...
} *
* So there's no reason to remove NETLOGON_NEG_ARCFOUR nor
if (in_neg_flags & NETLOGON_NEG_SCHANNEL) { * NETLOGON_NEG_STRONG_KEYS from srv_flgs...
srv_flgs |= NETLOGON_NEG_SCHANNEL; */
}
/* /*
* Support authentication of trusted domains. * Support authentication of trusted domains.
@ -950,12 +952,7 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION; NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION;
} }
/* neg_flags = in_neg_flags & srv_flgs;
* If weak crypto is disabled, do not announce that we support RC4.
*/
if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
srv_flgs &= ~NETLOGON_NEG_ARCFOUR;
}
switch (dce_call->pkt.u.request.opnum) { switch (dce_call->pkt.u.request.opnum) {
case NDR_NETR_SERVERAUTHENTICATE: case NDR_NETR_SERVERAUTHENTICATE:
@ -971,6 +968,19 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
return NT_STATUS_INTERNAL_ERROR; return NT_STATUS_INTERNAL_ERROR;
} }
if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
if (!(neg_flags & NETLOGON_NEG_SUPPORTS_AES)) {
DBG_NOTICE("%s: no AES support negotiated from client %s\n",
fn, r->in.computer_name);
/*
* Here we match Windows 2012 and return no flags.
*/
neg_flags = 0;
status = NT_STATUS_DOWNGRADE_DETECTED;
goto out;
}
}
/* We use this as the key to store the creds: */ /* We use this as the key to store the creds: */
/* r->in.computer_name */ /* r->in.computer_name */
@ -1010,7 +1020,9 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
&mach_pwd, &mach_pwd,
r->in.credentials, r->in.credentials,
r->out.return_credentials, r->out.return_credentials,
srv_flgs); in_neg_flags,
&sid,
neg_flags);
if (!creds) { if (!creds) {
DEBUG(0,("%s: netlogon_creds_server_check failed. Rejecting auth " DEBUG(0,("%s: netlogon_creds_server_check failed. Rejecting auth "
"request from client %s machine account %s\n", "request from client %s machine account %s\n",
@ -1020,12 +1032,6 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
goto out; goto out;
} }
creds->sid = dom_sid_dup(creds, &sid);
if (!creds->sid) {
status = NT_STATUS_NO_MEMORY;
goto out;
}
/* Store off the state so we can continue after client disconnect. */ /* Store off the state so we can continue after client disconnect. */
become_root(); become_root();
status = schannel_save_creds_state(p->mem_ctx, lp_ctx, creds); status = schannel_save_creds_state(p->mem_ctx, lp_ctx, creds);
@ -1042,7 +1048,7 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
out: out:
*r->out.negotiate_flags = srv_flgs; *r->out.negotiate_flags = neg_flags;
return status; return status;
} }
@ -1311,6 +1317,11 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
size_t i; size_t i;
struct netlogon_creds_CredentialState *creds = NULL; struct netlogon_creds_CredentialState *creds = NULL;
struct _samr_Credentials_t cr = { CRED_TYPE_NT_HASH, {0}}; struct _samr_Credentials_t cr = { CRED_TYPE_NT_HASH, {0}};
const struct dom_sid *client_sid = NULL;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__)); DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
@ -1335,11 +1346,15 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
TALLOC_FREE(creds); TALLOC_FREE(creds);
return status; return status;
} }
client_sid = &creds->ex->client_sid;
DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n", DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
r->in.computer_name, creds->computer_name)); r->in.computer_name, creds->computer_name));
status = netlogon_creds_des_decrypt(creds, r->in.new_password); status = netlogon_creds_decrypt_samr_Password(creds,
r->in.new_password,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
return status; return status;
} }
@ -1353,7 +1368,7 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
status = netr_set_machine_account_password(p->mem_ctx, status = netr_set_machine_account_password(p->mem_ctx,
session_info, session_info,
p->msg_ctx, p->msg_ctx,
creds->sid, client_sid,
&cr); &cr);
return status; return status;
} }
@ -1370,6 +1385,7 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
dcesrv_call_session_info(dce_call); dcesrv_call_session_info(dce_call);
NTSTATUS status; NTSTATUS status;
struct netlogon_creds_CredentialState *creds = NULL; struct netlogon_creds_CredentialState *creds = NULL;
const struct dom_sid *client_sid = NULL;
DATA_BLOB plaintext = data_blob_null; DATA_BLOB plaintext = data_blob_null;
DATA_BLOB new_password = data_blob_null; DATA_BLOB new_password = data_blob_null;
size_t confounder_len; size_t confounder_len;
@ -1378,6 +1394,10 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
struct samr_CryptPassword password_buf; struct samr_CryptPassword password_buf;
struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}}; struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}};
bool ok; bool ok;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
become_root(); become_root();
status = dcesrv_netr_creds_server_step_check(p->dce_call, status = dcesrv_netr_creds_server_step_check(p->dce_call,
@ -1395,6 +1415,7 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
TALLOC_FREE(creds); TALLOC_FREE(creds);
return status; return status;
} }
client_sid = &creds->ex->client_sid;
DBG_NOTICE("Server Password Set2 by remote " DBG_NOTICE("Server Password Set2 by remote "
"machine:[%s] on account [%s]\n", "machine:[%s] on account [%s]\n",
@ -1405,15 +1426,10 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
memcpy(password_buf.data, r->in.new_password->data, 512); memcpy(password_buf.data, r->in.new_password->data, 512);
SIVAL(password_buf.data, 512, r->in.new_password->length); SIVAL(password_buf.data, 512, r->in.new_password->length);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { status = netlogon_creds_decrypt_samr_CryptPassword(creds,
status = netlogon_creds_aes_decrypt(creds, &password_buf,
password_buf.data, auth_type,
516); auth_level);
} else {
status = netlogon_creds_arcfour_crypt(creds,
password_buf.data,
516);
}
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(creds); TALLOC_FREE(creds);
return status; return status;
@ -1515,7 +1531,7 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
status = netr_set_machine_account_password(p->mem_ctx, status = netr_set_machine_account_password(p->mem_ctx,
session_info, session_info,
p->msg_ctx, p->msg_ctx,
creds->sid, client_sid,
&cr); &cr);
TALLOC_FREE(creds); TALLOC_FREE(creds);
return status; return status;
@ -1755,7 +1771,9 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
status = netlogon_creds_decrypt_samlogon_logon(creds, status = netlogon_creds_decrypt_samlogon_logon(creds,
r->in.logon_level, r->in.logon_level,
logon); logon,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
return status; return status;
} }
@ -1938,7 +1956,9 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
status = netlogon_creds_encrypt_samlogon_validation(creds, status = netlogon_creds_encrypt_samlogon_validation(creds,
r->in.validation_level, r->in.validation_level,
r->out.validation); r->out.validation,
auth_type,
auth_level);
return status; return status;
} }
@ -2307,12 +2327,7 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
case 1: case 1:
break; break;
case 2: case 2:
/* break;
* Until we know the details behind KB5028166
* just return DCERPC_NCA_S_FAULT_INVALID_TAG
* like an unpatched Windows Server.
*/
FALL_THROUGH;
default: default:
/* /*
* There would not be a way to marshall the * There would not be a way to marshall the
@ -2340,7 +2355,15 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
return status; return status;
} }
switch (r->in.query_level) {
case 1:
r->out.capabilities->server_capabilities = creds->negotiate_flags; r->out.capabilities->server_capabilities = creds->negotiate_flags;
break;
case 2:
r->out.capabilities->requested_flags =
creds->ex->client_requested_flags;
break;
}
return NT_STATUS_OK; return NT_STATUS_OK;
} }
@ -2734,7 +2757,9 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
const DATA_BLOB *trustAuth_blob, const DATA_BLOB *trustAuth_blob,
struct netlogon_creds_CredentialState *creds, struct netlogon_creds_CredentialState *creds,
struct samr_Password *current_pw_enc, struct samr_Password *current_pw_enc,
struct samr_Password *previous_pw_enc) struct samr_Password *previous_pw_enc,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level)
{ {
enum ndr_err_code ndr_err; enum ndr_err_code ndr_err;
struct trustAuthInOutBlob trustAuth; struct trustAuthInOutBlob trustAuth;
@ -2751,7 +2776,10 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
mdfour(current_pw_enc->hash, mdfour(current_pw_enc->hash,
trustAuth.current.array[0].AuthInfo.clear.password, trustAuth.current.array[0].AuthInfo.clear.password,
trustAuth.current.array[0].AuthInfo.clear.size); trustAuth.current.array[0].AuthInfo.clear.size);
status = netlogon_creds_des_encrypt(creds, current_pw_enc); status = netlogon_creds_encrypt_samr_Password(creds,
current_pw_enc,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
return status; return status;
} }
@ -2765,7 +2793,10 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
mdfour(previous_pw_enc->hash, mdfour(previous_pw_enc->hash,
trustAuth.previous.array[0].AuthInfo.clear.password, trustAuth.previous.array[0].AuthInfo.clear.password,
trustAuth.previous.array[0].AuthInfo.clear.size); trustAuth.previous.array[0].AuthInfo.clear.size);
status = netlogon_creds_des_encrypt(creds, previous_pw_enc); status = netlogon_creds_encrypt_samr_Password(creds,
previous_pw_enc,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
return status; return status;
} }
@ -2790,6 +2821,10 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
bool trusted; bool trusted;
struct netr_TrustInfo *trust_info; struct netr_TrustInfo *trust_info;
struct pdb_trusted_domain *td; struct pdb_trusted_domain *td;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
dcesrv_call_auth_info(p->dce_call, &auth_type, &auth_level);
/* TODO: check server name */ /* TODO: check server name */
@ -2866,8 +2901,9 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
&td->trust_auth_incoming, &td->trust_auth_incoming,
creds, creds,
r->out.new_owf_password, r->out.new_owf_password,
r->out.old_owf_password); r->out.old_owf_password,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
return status; return status;
} }
@ -2903,6 +2939,31 @@ NTSTATUS _netr_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
return NT_STATUS_NOT_IMPLEMENTED; return NT_STATUS_NOT_IMPLEMENTED;
} }
DCESRV_COMPAT_NOT_USED_ON_WIRE(netr_Opnum49NotUsedOnWire)
DCESRV_COMPAT_NOT_USED_ON_WIRE(netr_Opnum50NotUsedOnWire)
DCESRV_COMPAT_NOT_USED_ON_WIRE(netr_Opnum51NotUsedOnWire)
DCESRV_COMPAT_NOT_USED_ON_WIRE(netr_Opnum52NotUsedOnWire)
DCESRV_COMPAT_NOT_USED_ON_WIRE(netr_Opnum53NotUsedOnWire)
NTSTATUS _netr_ChainSetClientAttributes(struct pipes_struct *p,
struct netr_ChainSetClientAttributes *r)
{
p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return NT_STATUS_NOT_IMPLEMENTED;
}
DCESRV_COMPAT_NOT_USED_ON_WIRE(netr_Opnum55NotUsedOnWire)
DCESRV_COMPAT_NOT_USED_ON_WIRE(netr_Opnum56NotUsedOnWire)
DCESRV_COMPAT_NOT_USED_ON_WIRE(netr_Opnum57NotUsedOnWire)
DCESRV_COMPAT_NOT_USED_ON_WIRE(netr_Opnum58NotUsedOnWire)
NTSTATUS _netr_ServerAuthenticateKerberos(struct pipes_struct *p,
struct netr_ServerAuthenticateKerberos *r)
{
p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return NT_STATUS_NOT_IMPLEMENTED;
}
/* /*
* Define the bind function that will be used by ndr_netlogon_scompat.c, * Define the bind function that will be used by ndr_netlogon_scompat.c,
* included at the bottom of this file. * included at the bottom of this file.

View File

@ -70,4 +70,10 @@ void *_find_policy_by_hnd(struct pipes_struct *p,
bool close_policy_hnd(struct pipes_struct *p, struct policy_handle *hnd); bool close_policy_hnd(struct pipes_struct *p, struct policy_handle *hnd);
bool pipe_access_check(struct pipes_struct *p); bool pipe_access_check(struct pipes_struct *p);
#define DCESRV_COMPAT_NOT_USED_ON_WIRE(__opname) \
void _## __opname(struct pipes_struct *p, struct __opname *r) \
{ \
p->fault_state = DCERPC_FAULT_OP_RNG_ERROR; \
}
#endif /* _RPC_PIPES_H_ */ #endif /* _RPC_PIPES_H_ */

View File

@ -237,7 +237,7 @@ WERROR samdb_confirm_rodc_allowed_to_repl_to_sid_list(struct ldb_context *sam_ct
* rather than relying on the caller providing those * rather than relying on the caller providing those
*/ */
WERROR samdb_confirm_rodc_allowed_to_repl_to(struct ldb_context *sam_ctx, WERROR samdb_confirm_rodc_allowed_to_repl_to(struct ldb_context *sam_ctx,
struct dom_sid *rodc_machine_account_sid, const struct dom_sid *rodc_machine_account_sid,
struct ldb_message *rodc_msg, struct ldb_message *rodc_msg,
struct ldb_message *obj_msg) struct ldb_message *obj_msg)
{ {

View File

@ -2668,7 +2668,7 @@ NTSTATUS dsdb_trust_search_tdo_by_sid(struct ldb_context *sam_ctx,
return NT_STATUS_OK; return NT_STATUS_OK;
} }
NTSTATUS dsdb_trust_get_incoming_passwords(struct ldb_message *msg, NTSTATUS dsdb_trust_get_incoming_passwords(const struct ldb_message *msg,
TALLOC_CTX *mem_ctx, TALLOC_CTX *mem_ctx,
struct samr_Password **_current, struct samr_Password **_current,
struct samr_Password **_previous) struct samr_Password **_previous)

View File

@ -40,6 +40,8 @@ struct schannel_key_state {
bool dcerpc_schannel_auto; bool dcerpc_schannel_auto;
struct cli_credentials *credentials; struct cli_credentials *credentials;
struct netlogon_creds_CredentialState *creds; struct netlogon_creds_CredentialState *creds;
uint32_t requested_negotiate_flags;
uint32_t required_negotiate_flags;
uint32_t local_negotiate_flags; uint32_t local_negotiate_flags;
uint32_t remote_negotiate_flags; uint32_t remote_negotiate_flags;
struct netr_Credential credentials1; struct netr_Credential credentials1;
@ -55,7 +57,8 @@ static void continue_secondary_connection(struct composite_context *ctx);
static void continue_bind_auth_none(struct composite_context *ctx); static void continue_bind_auth_none(struct composite_context *ctx);
static void continue_srv_challenge(struct tevent_req *subreq); static void continue_srv_challenge(struct tevent_req *subreq);
static void continue_srv_auth2(struct tevent_req *subreq); static void continue_srv_auth2(struct tevent_req *subreq);
static void continue_get_capabilities(struct tevent_req *subreq); static void continue_get_negotiated_capabilities(struct tevent_req *subreq);
static void continue_get_client_capabilities(struct tevent_req *subreq);
/* /*
@ -183,7 +186,7 @@ static void continue_srv_challenge(struct tevent_req *subreq)
s->a.in.secure_channel_type = s->a.in.secure_channel_type =
cli_credentials_get_secure_channel_type(s->credentials); cli_credentials_get_secure_channel_type(s->credentials);
s->a.in.computer_name = cli_credentials_get_workstation(s->credentials); s->a.in.computer_name = cli_credentials_get_workstation(s->credentials);
s->a.in.negotiate_flags = &s->local_negotiate_flags; s->a.in.negotiate_flags = &s->requested_negotiate_flags;
s->a.in.credentials = &s->credentials3; s->a.in.credentials = &s->credentials3;
s->a.out.negotiate_flags = &s->remote_negotiate_flags; s->a.out.negotiate_flags = &s->remote_negotiate_flags;
s->a.out.return_credentials = &s->credentials3; s->a.out.return_credentials = &s->credentials3;
@ -194,6 +197,7 @@ static void continue_srv_challenge(struct tevent_req *subreq)
s->a.in.secure_channel_type, s->a.in.secure_channel_type,
&s->credentials1, &s->credentials2, &s->credentials1, &s->credentials2,
s->mach_pwd, &s->credentials3, s->mach_pwd, &s->credentials3,
s->requested_negotiate_flags,
s->local_negotiate_flags); s->local_negotiate_flags);
if (composite_nomem(s->creds, c)) { if (composite_nomem(s->creds, c)) {
return; return;
@ -218,10 +222,17 @@ static void continue_srv_auth2(struct tevent_req *subreq)
{ {
struct composite_context *c; struct composite_context *c;
struct schannel_key_state *s; struct schannel_key_state *s;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
c = tevent_req_callback_data(subreq, struct composite_context); c = tevent_req_callback_data(subreq, struct composite_context);
s = talloc_get_type(c->private_data, struct schannel_key_state); s = talloc_get_type(c->private_data, struct schannel_key_state);
dcerpc_binding_handle_auth_info(s->pipe2->binding_handle,
&auth_type,
&auth_level);
/* receive rpc request result - auth2 credentials */ /* receive rpc request result - auth2 credentials */
c->status = dcerpc_netr_ServerAuthenticate2_r_recv(subreq, s); c->status = dcerpc_netr_ServerAuthenticate2_r_recv(subreq, s);
TALLOC_FREE(subreq); TALLOC_FREE(subreq);
@ -233,6 +244,29 @@ static void continue_srv_auth2(struct tevent_req *subreq)
return; return;
} }
{
uint32_t rqf = s->required_negotiate_flags;
uint32_t rf = s->remote_negotiate_flags;
uint32_t lf = s->local_negotiate_flags;
if ((rf & NETLOGON_NEG_SUPPORTS_AES) &&
(lf & NETLOGON_NEG_SUPPORTS_AES))
{
rqf &= ~NETLOGON_NEG_ARCFOUR;
rqf &= ~NETLOGON_NEG_STRONG_KEYS;
}
if ((rqf & rf) != rqf) {
rqf = s->required_negotiate_flags;
DBG_ERR("The client capabilities don't match "
"the server capabilities: local[0x%08X] "
"required[0x%08X] remote[0x%08X]\n",
lf, rqf, rf);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return;
}
}
/* /*
* Strong keys could be unsupported (NT4) or disabled. So retry with the * Strong keys could be unsupported (NT4) or disabled. So retry with the
* flags returned by the server. - asn * flags returned by the server. - asn
@ -243,6 +277,14 @@ static void continue_srv_auth2(struct tevent_req *subreq)
uint32_t rf = s->remote_negotiate_flags; uint32_t rf = s->remote_negotiate_flags;
const char *rn = NULL; const char *rn = NULL;
if ((lf & rf) == lf) {
/*
* without a change in flags
* there's no need to retry...
*/
s->dcerpc_schannel_auto = false;
}
if (!s->dcerpc_schannel_auto) { if (!s->dcerpc_schannel_auto) {
composite_error(c, s->a.out.result); composite_error(c, s->a.out.result);
return; return;
@ -277,7 +319,7 @@ static void continue_srv_auth2(struct tevent_req *subreq)
"and retry! local[0x%08X] remote[0x%08X]\n", "and retry! local[0x%08X] remote[0x%08X]\n",
ln, rn, lf, rf)); ln, rn, lf, rf));
s->local_negotiate_flags = s->remote_negotiate_flags; s->local_negotiate_flags &= s->remote_negotiate_flags;
generate_random_buffer(s->credentials1.data, generate_random_buffer(s->credentials1.data,
sizeof(s->credentials1.data)); sizeof(s->credentials1.data));
@ -292,11 +334,30 @@ static void continue_srv_auth2(struct tevent_req *subreq)
return; return;
} }
s->creds->negotiate_flags = s->remote_negotiate_flags;
/* verify credentials */ /* verify credentials */
if (!netlogon_creds_client_check(s->creds, s->a.out.return_credentials)) { status = netlogon_creds_client_verify(s->creds,
composite_error(c, NT_STATUS_UNSUCCESSFUL); s->a.out.return_credentials,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) {
composite_error(c, status);
return;
}
if (s->requested_negotiate_flags == s->local_negotiate_flags) {
/*
* Without a downgrade in the crypto we proposed
* we can adjust the otherwise downgraded flags
* before storing.
*/
s->creds->negotiate_flags &= s->remote_negotiate_flags;
} else if (s->local_negotiate_flags != s->remote_negotiate_flags) {
/*
* We downgraded our crypto once, we should not
* allow any additional downgrade!
*/
DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return; return;
} }
@ -317,6 +378,8 @@ static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
struct composite_context *epm_map_req; struct composite_context *epm_map_req;
enum netr_SchannelType schannel_type = cli_credentials_get_secure_channel_type(credentials); enum netr_SchannelType schannel_type = cli_credentials_get_secure_channel_type(credentials);
struct cli_credentials *epm_creds = NULL; struct cli_credentials *epm_creds = NULL;
bool reject_md5_servers = false;
bool require_strong_key = false;
/* composite context allocation and setup */ /* composite context allocation and setup */
c = composite_create(mem_ctx, p->conn->event_ctx); c = composite_create(mem_ctx, p->conn->event_ctx);
@ -330,19 +393,48 @@ static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
s->pipe = p; s->pipe = p;
s->credentials = credentials; s->credentials = credentials;
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS; s->local_negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
s->required_negotiate_flags = NETLOGON_NEG_AUTHENTICATED_RPC;
/* allocate credentials */ /* allocate credentials */
if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) { if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) {
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
require_strong_key = true;
} }
if (s->pipe->conn->flags & DCERPC_SCHANNEL_AES) { if (s->pipe->conn->flags & DCERPC_SCHANNEL_AES) {
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
s->local_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES; reject_md5_servers = true;
} }
if (s->pipe->conn->flags & DCERPC_SCHANNEL_AUTO) { if (s->pipe->conn->flags & DCERPC_SCHANNEL_AUTO) {
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
s->local_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES; s->local_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES;
s->dcerpc_schannel_auto = true; s->dcerpc_schannel_auto = true;
reject_md5_servers = lpcfg_reject_md5_servers(lp_ctx);
require_strong_key = lpcfg_require_strong_key(lp_ctx);
}
if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
reject_md5_servers = true;
}
if (reject_md5_servers) {
require_strong_key = true;
}
if (require_strong_key) {
s->required_negotiate_flags |= NETLOGON_NEG_ARCFOUR;
s->required_negotiate_flags |= NETLOGON_NEG_STRONG_KEYS;
}
if (reject_md5_servers) {
s->required_negotiate_flags |= NETLOGON_NEG_PASSWORD_SET2;
s->required_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES;
}
s->local_negotiate_flags |= s->required_negotiate_flags;
if (s->required_negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
s->required_negotiate_flags &= ~NETLOGON_NEG_ARCFOUR;
s->required_negotiate_flags &= ~NETLOGON_NEG_STRONG_KEYS;
} }
/* type of authentication depends on schannel type */ /* type of authentication depends on schannel type */
@ -350,9 +442,7 @@ static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
s->local_negotiate_flags |= NETLOGON_NEG_RODC_PASSTHROUGH; s->local_negotiate_flags |= NETLOGON_NEG_RODC_PASSTHROUGH;
} }
if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) { s->requested_negotiate_flags = s->local_negotiate_flags;
s->local_negotiate_flags &= ~NETLOGON_NEG_ARCFOUR;
}
epm_creds = cli_credentials_init_anon(s); epm_creds = cli_credentials_init_anon(s);
if (composite_nomem(epm_creds, c)) return c; if (composite_nomem(epm_creds, c)) return c;
@ -379,7 +469,8 @@ static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
*/ */
static NTSTATUS dcerpc_schannel_key_recv(struct composite_context *c, static NTSTATUS dcerpc_schannel_key_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx, TALLOC_CTX *mem_ctx,
struct netlogon_creds_CredentialState **creds) struct netlogon_creds_CredentialState **creds,
uint32_t *requested_negotiate_flags)
{ {
NTSTATUS status = composite_wait(c); NTSTATUS status = composite_wait(c);
@ -388,6 +479,7 @@ static NTSTATUS dcerpc_schannel_key_recv(struct composite_context *c,
talloc_get_type_abort(c->private_data, talloc_get_type_abort(c->private_data,
struct schannel_key_state); struct schannel_key_state);
*creds = talloc_move(mem_ctx, &s->creds); *creds = talloc_move(mem_ctx, &s->creds);
*requested_negotiate_flags = s->requested_negotiate_flags;
} }
talloc_free(c); talloc_free(c);
@ -398,6 +490,7 @@ static NTSTATUS dcerpc_schannel_key_recv(struct composite_context *c,
struct auth_schannel_state { struct auth_schannel_state {
struct dcerpc_pipe *pipe; struct dcerpc_pipe *pipe;
struct cli_credentials *credentials; struct cli_credentials *credentials;
uint32_t requested_negotiate_flags;
const struct ndr_interface_table *table; const struct ndr_interface_table *table;
struct loadparm_context *lp_ctx; struct loadparm_context *lp_ctx;
uint8_t auth_level; uint8_t auth_level;
@ -406,7 +499,9 @@ struct auth_schannel_state {
struct netr_Authenticator auth; struct netr_Authenticator auth;
struct netr_Authenticator return_auth; struct netr_Authenticator return_auth;
union netr_Capabilities capabilities; union netr_Capabilities capabilities;
union netr_Capabilities client_caps;
struct netr_LogonGetCapabilities c; struct netr_LogonGetCapabilities c;
union netr_CONTROL_QUERY_INFORMATION ctrl_info;
}; };
@ -427,7 +522,11 @@ static void continue_schannel_key(struct composite_context *ctx)
NTSTATUS status; NTSTATUS status;
/* receive schannel key */ /* receive schannel key */
status = c->status = dcerpc_schannel_key_recv(ctx, s, &s->creds_state); c->status = dcerpc_schannel_key_recv(ctx,
s,
&s->creds_state,
&s->requested_negotiate_flags);
status = c->status;
if (!composite_is_ok(c)) { if (!composite_is_ok(c)) {
DEBUG(1, ("Failed to setup credentials: %s\n", nt_errstr(status))); DEBUG(1, ("Failed to setup credentials: %s\n", nt_errstr(status)));
return; return;
@ -496,36 +595,52 @@ static void continue_bind_auth(struct composite_context *ctx)
&s->c); &s->c);
if (composite_nomem(subreq, c)) return; if (composite_nomem(subreq, c)) return;
tevent_req_set_callback(subreq, continue_get_capabilities, c); tevent_req_set_callback(subreq,
continue_get_negotiated_capabilities,
c);
return; return;
} }
composite_done(c); composite_done(c);
} }
static void continue_logon_control_do(struct composite_context *c);
/* /*
Stage 4 of auth_schannel: Get the Logon Capabilities and verify them. Stage 4 of auth_schannel: Get the Logon Capabilities and verify them.
*/ */
static void continue_get_capabilities(struct tevent_req *subreq) static void continue_get_negotiated_capabilities(struct tevent_req *subreq)
{ {
struct composite_context *c; struct composite_context *c;
struct auth_schannel_state *s; struct auth_schannel_state *s;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
c = tevent_req_callback_data(subreq, struct composite_context); c = tevent_req_callback_data(subreq, struct composite_context);
s = talloc_get_type(c->private_data, struct auth_schannel_state); s = talloc_get_type(c->private_data, struct auth_schannel_state);
dcerpc_binding_handle_auth_info(s->pipe->binding_handle,
&auth_type,
&auth_level);
/* receive rpc request result */ /* receive rpc request result */
c->status = dcerpc_netr_LogonGetCapabilities_r_recv(subreq, s); c->status = dcerpc_netr_LogonGetCapabilities_r_recv(subreq, s);
TALLOC_FREE(subreq); TALLOC_FREE(subreq);
if (NT_STATUS_EQUAL(c->status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) { if (NT_STATUS_EQUAL(c->status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
if (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { if (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE); DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return; return;
} else { } else if (s->creds_state->negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
/* This is probably NT */ DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_done(c); composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return; return;
} }
/* This is probably NT */
continue_logon_control_do(c);
return;
} else if (!composite_is_ok(c)) { } else if (!composite_is_ok(c)) {
return; return;
} }
@ -533,7 +648,8 @@ static void continue_get_capabilities(struct tevent_req *subreq)
if (NT_STATUS_EQUAL(s->c.out.result, NT_STATUS_NOT_IMPLEMENTED)) { if (NT_STATUS_EQUAL(s->c.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
if (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { if (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
/* This means AES isn't supported. */ /* This means AES isn't supported. */
composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE); DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return; return;
} }
@ -543,9 +659,12 @@ static void continue_get_capabilities(struct tevent_req *subreq)
} }
/* verify credentials */ /* verify credentials */
if (!netlogon_creds_client_check(&s->save_creds_state, status = netlogon_creds_client_verify(&s->save_creds_state,
&s->c.out.return_authenticator->cred)) { &s->c.out.return_authenticator->cred,
composite_error(c, NT_STATUS_UNSUCCESSFUL); auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) {
composite_error(c, status);
return; return;
} }
@ -559,19 +678,175 @@ static void continue_get_capabilities(struct tevent_req *subreq)
/* compare capabilities */ /* compare capabilities */
if (s->creds_state->negotiate_flags != s->capabilities.server_capabilities) { if (s->creds_state->negotiate_flags != s->capabilities.server_capabilities) {
DEBUG(2, ("The client capabilities don't match the server " DBG_ERR("The client capabilities don't match the server "
"capabilities: local[0x%08X] remote[0x%08X]\n", "capabilities: local[0x%08X] remote[0x%08X]\n",
s->creds_state->negotiate_flags, s->creds_state->negotiate_flags,
s->capabilities.server_capabilities)); s->capabilities.server_capabilities);
composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE); composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return; return;
} }
/* TODO: Add downgrade detection. */ if ((s->requested_negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) &&
(!(s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)))
{
DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return;
}
ZERO_STRUCT(s->return_auth);
s->save_creds_state = *s->creds_state;
status = netlogon_creds_client_authenticator(&s->save_creds_state,
&s->auth);
if (!NT_STATUS_IS_OK(status)) {
composite_error(c, status);
return;
}
s->c.in.credential = &s->auth;
s->c.in.return_authenticator = &s->return_auth;
s->c.in.query_level = 2;
s->c.out.capabilities = &s->client_caps;
s->c.out.return_authenticator = &s->return_auth;
subreq = dcerpc_netr_LogonGetCapabilities_r_send(s,
c->event_ctx,
s->pipe->binding_handle,
&s->c);
if (composite_nomem(subreq, c)) return;
tevent_req_set_callback(subreq, continue_get_client_capabilities, c);
return;
}
static void continue_get_client_capabilities(struct tevent_req *subreq)
{
struct composite_context *c;
struct auth_schannel_state *s;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
c = tevent_req_callback_data(subreq, struct composite_context);
s = talloc_get_type(c->private_data, struct auth_schannel_state);
dcerpc_binding_handle_auth_info(s->pipe->binding_handle,
&auth_type,
&auth_level);
/* receive rpc request result */
c->status = dcerpc_netr_LogonGetCapabilities_r_recv(subreq, s);
TALLOC_FREE(subreq);
if (NT_STATUS_EQUAL(c->status, NT_STATUS_RPC_BAD_STUB_DATA)) {
/*
* unpatched Samba server, see
* https://bugzilla.samba.org/show_bug.cgi?id=15418
*/
c->status = NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE;
}
if (NT_STATUS_EQUAL(c->status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
/*
* Here we know the negotiated flags were already
* verified with query_level=1, which means
* the server supported NETLOGON_NEG_SUPPORTS_AES
* and also NETLOGON_NEG_AUTHENTICATED_RPC
*
* As we're using DCERPC_AUTH_TYPE_SCHANNEL with
* DCERPC_AUTH_LEVEL_INTEGRITY or DCERPC_AUTH_LEVEL_PRIVACY
* we should detect a faked
* NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
* with the next request as the sequence number processing
* gets out of sync.
*
* So we'll do a LogonControl message to check that...
*/
continue_logon_control_do(c);
return;
}
if (!composite_is_ok(c)) {
return;
}
/* verify credentials */
status = netlogon_creds_client_verify(&s->save_creds_state,
&s->c.out.return_authenticator->cred,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) {
composite_error(c, status);
return;
}
if (!NT_STATUS_IS_OK(s->c.out.result)) {
composite_error(c, s->c.out.result);
return;
}
/* compare capabilities */
if (s->requested_negotiate_flags != s->client_caps.requested_flags) {
DBG_ERR("The client requested capabilities did not reach"
"the server! local[0x%08X] remote[0x%08X]\n",
s->requested_negotiate_flags,
s->client_caps.requested_flags);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return;
}
*s->creds_state = s->save_creds_state;
cli_credentials_set_netlogon_creds(s->credentials, s->creds_state);
composite_done(c); composite_done(c);
} }
static void continue_logon_control_done(struct tevent_req *subreq);
static void continue_logon_control_do(struct composite_context *c)
{
struct auth_schannel_state *s = NULL;
struct tevent_req *subreq = NULL;
s = talloc_get_type(c->private_data, struct auth_schannel_state);
subreq = dcerpc_netr_LogonControl_send(s,
c->event_ctx,
s->pipe->binding_handle,
s->c.in.server_name,
NETLOGON_CONTROL_QUERY,
2,
&s->ctrl_info);
if (composite_nomem(subreq, c)) return;
tevent_req_set_callback(subreq, continue_logon_control_done, c);
}
static void continue_logon_control_done(struct tevent_req *subreq)
{
struct composite_context *c = NULL;
struct auth_schannel_state *s = NULL;
WERROR werr;
c = tevent_req_callback_data(subreq, struct composite_context);
s = talloc_get_type(c->private_data, struct auth_schannel_state);
/* receive rpc request result */
c->status = dcerpc_netr_LogonControl_recv(subreq, s, &werr);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(c->status)) {
DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return;
}
if (!W_ERROR_EQUAL(werr, WERR_NOT_SUPPORTED)) {
DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
return;
}
composite_done(c);
}
/* /*
Initiate schannel authentication request Initiate schannel authentication request

View File

@ -388,14 +388,23 @@ return_downgrade:
return orig_status; return orig_status;
} }
/* typedef NTSTATUS (*dcesrv_netr_ServerAuthenticateGenericCallback_fn)(
* Do the actual processing of a netr_ServerAuthenticate3 message. struct dcesrv_call_state *dce_call,
* called from dcesrv_netr_ServerAuthenticate3, which handles the logging. const struct netlogon_server_pipe_state *challenge,
*/ const struct netr_ServerAuthenticate3 *r,
static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( uint32_t client_flags,
const struct dom_sid *client_sid,
uint32_t negotiate_flags,
const struct ldb_message *sam_msg,
const struct ldb_message *tdo_msg,
TALLOC_CTX *mem_ctx,
struct netlogon_creds_CredentialState **_creds);
static NTSTATUS dcesrv_netr_ServerAuthenticateGeneric(
struct dcesrv_call_state *dce_call, struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx, TALLOC_CTX *mem_ctx,
struct netr_ServerAuthenticate3 *r, struct netr_ServerAuthenticate3 *r,
dcesrv_netr_ServerAuthenticateGenericCallback_fn auth_fn,
const char **trust_account_for_search, const char **trust_account_for_search,
const char **trust_account_in_db, const char **trust_account_in_db,
struct dom_sid **sid) struct dom_sid **sid)
@ -405,10 +414,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
struct netlogon_server_pipe_state challenge; struct netlogon_server_pipe_state challenge;
struct netlogon_creds_CredentialState *creds; struct netlogon_creds_CredentialState *creds;
struct ldb_context *sam_ctx; struct ldb_context *sam_ctx;
struct samr_Password *curNtHash = NULL;
struct samr_Password *prevNtHash = NULL;
uint32_t user_account_control; uint32_t user_account_control;
struct ldb_message **msgs; struct ldb_message **msgs;
struct ldb_message *tdo_msg = NULL;
NTSTATUS nt_status; NTSTATUS nt_status;
static const char *attrs[] = { static const char *attrs[] = {
"unicodePwd", "unicodePwd",
@ -422,6 +430,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
"whenCreated", "whenCreated",
NULL}; NULL};
uint32_t server_flags = 0; uint32_t server_flags = 0;
uint32_t client_flags = 0;
uint32_t negotiate_flags = 0; uint32_t negotiate_flags = 0;
ZERO_STRUCTP(r->out.return_credentials); ZERO_STRUCTP(r->out.return_credentials);
@ -503,14 +512,20 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
NETLOGON_NEG_AUTHENTICATED_RPC; NETLOGON_NEG_AUTHENTICATED_RPC;
/* /*
* If weak crypto is disabled, do not announce that we support RC4. * With SAMBA_WEAK_CRYPTO_DISALLOWED
* dcesrv_netr_ServerAuthenticate3_check_downgrade() will return
* DOWNGRADE_DETECTED with negotiate_flags = 0,
* if NETLOGON_NEG_SUPPORTS_AES was not negotiated...
*
* And if NETLOGON_NEG_SUPPORTS_AES was negotiated there's no harm in
* returning the NETLOGON_NEG_ARCFOUR flag too...
*
* So there's no reason to remove NETLOGON_NEG_ARCFOUR nor
* NETLOGON_NEG_STRONG_KEYS from server_flags...
*/ */
if (lpcfg_weak_crypto(dce_call->conn->dce_ctx->lp_ctx) ==
SAMBA_WEAK_CRYPTO_DISALLOWED) {
server_flags &= ~NETLOGON_NEG_ARCFOUR;
}
negotiate_flags = *r->in.negotiate_flags & server_flags; client_flags = *r->in.negotiate_flags;
negotiate_flags = client_flags & server_flags;
switch (r->in.secure_channel_type) { switch (r->in.secure_channel_type) {
case SEC_CHAN_WKSTA: case SEC_CHAN_WKSTA:
@ -544,7 +559,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN)
{ {
struct ldb_message *tdo_msg = NULL;
static const char *const tdo_attrs[] = {"trustAuthIncoming", static const char *const tdo_attrs[] = {"trustAuthIncoming",
"trustAttributes", "trustAttributes",
"flatName", "flatName",
@ -613,22 +627,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
nt_status); nt_status);
} }
nt_status = dsdb_trust_get_incoming_passwords(tdo_msg, mem_ctx,
&curNtHash,
&prevNtHash);
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) {
return dcesrv_netr_ServerAuthenticate3_check_downgrade(
dce_call, r, pipe_state, negotiate_flags,
NULL, /* trust_account_in_db */
NT_STATUS_NO_TRUST_SAM_ACCOUNT);
}
if (!NT_STATUS_IS_OK(nt_status)) {
return dcesrv_netr_ServerAuthenticate3_check_downgrade(
dce_call, r, pipe_state, negotiate_flags,
NULL, /* trust_account_in_db */
nt_status);
}
flatname = ldb_msg_find_attr_as_string(tdo_msg, "flatName", NULL); flatname = ldb_msg_find_attr_as_string(tdo_msg, "flatName", NULL);
if (flatname == NULL) { if (flatname == NULL) {
return dcesrv_netr_ServerAuthenticate3_check_downgrade( return dcesrv_netr_ServerAuthenticate3_check_downgrade(
@ -753,60 +751,28 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
} }
if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) { if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
nt_status = samdb_result_passwords_no_lockout(mem_ctx, tdo_msg = NULL;
dce_call->conn->dce_ctx->lp_ctx, }
msgs[0], &curNtHash);
*sid = samdb_result_dom_sid(mem_ctx, msgs[0], "objectSid");
if (*sid == NULL) {
return NT_STATUS_ACCESS_DENIED;
}
nt_status = auth_fn(dce_call,
challenge_valid ? &challenge : NULL,
r,
client_flags,
*sid,
negotiate_flags,
msgs[0],
tdo_msg,
mem_ctx,
&creds);
if (!NT_STATUS_IS_OK(nt_status)) { if (!NT_STATUS_IS_OK(nt_status)) {
return NT_STATUS_ACCESS_DENIED; ZERO_STRUCTP(r->out.return_credentials);
return nt_status;
} }
}
if (curNtHash == NULL) {
return NT_STATUS_ACCESS_DENIED;
}
if (!challenge_valid) {
DEBUG(1, ("No challenge requested by client [%s/%s], "
"cannot authenticate\n",
log_escape(mem_ctx, r->in.computer_name),
log_escape(mem_ctx, r->in.account_name)));
return NT_STATUS_ACCESS_DENIED;
}
creds = netlogon_creds_server_init(mem_ctx,
r->in.account_name,
r->in.computer_name,
r->in.secure_channel_type,
&challenge.client_challenge,
&challenge.server_challenge,
curNtHash,
r->in.credentials,
r->out.return_credentials,
negotiate_flags);
if (creds == NULL && prevNtHash != NULL) {
/*
* We fallback to the previous password for domain trusts.
*
* Note that lpcfg_old_password_allowed_period() doesn't
* apply here.
*/
creds = netlogon_creds_server_init(mem_ctx,
r->in.account_name,
r->in.computer_name,
r->in.secure_channel_type,
&challenge.client_challenge,
&challenge.server_challenge,
prevNtHash,
r->in.credentials,
r->out.return_credentials,
negotiate_flags);
}
if (creds == NULL) {
return NT_STATUS_ACCESS_DENIED;
}
creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
*sid = talloc_memdup(mem_ctx, creds->sid, sizeof(struct dom_sid));
nt_status = schannel_save_creds_state(mem_ctx, nt_status = schannel_save_creds_state(mem_ctx,
dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->dce_ctx->lp_ctx,
@ -822,6 +788,125 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
return NT_STATUS_OK; return NT_STATUS_OK;
} }
static NTSTATUS dcesrv_netr_ServerAuthenticateNTHash_cb(
struct dcesrv_call_state *dce_call,
const struct netlogon_server_pipe_state *challenge,
const struct netr_ServerAuthenticate3 *r,
uint32_t client_flags,
const struct dom_sid *client_sid,
uint32_t negotiate_flags,
const struct ldb_message *sam_msg,
const struct ldb_message *tdo_msg,
TALLOC_CTX *mem_ctx,
struct netlogon_creds_CredentialState **_creds)
{
TALLOC_CTX *frame = talloc_stackframe();
struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
struct netlogon_creds_CredentialState *creds = NULL;
struct samr_Password *curNtHash = NULL;
struct samr_Password *prevNtHash = NULL;
NTSTATUS status;
if (tdo_msg != NULL) {
status = dsdb_trust_get_incoming_passwords(tdo_msg,
frame,
&curNtHash,
&prevNtHash);
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_DISABLED)) {
status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
}
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(frame);
return status;
}
} else {
status = samdb_result_passwords_no_lockout(frame,
lp_ctx,
sam_msg,
&curNtHash);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(frame);
return NT_STATUS_ACCESS_DENIED;
}
}
if (curNtHash == NULL) {
TALLOC_FREE(frame);
return NT_STATUS_ACCESS_DENIED;
}
if (challenge == NULL) {
TALLOC_FREE(frame);
return NT_STATUS_ACCESS_DENIED;
}
creds = netlogon_creds_server_init(mem_ctx,
r->in.account_name,
r->in.computer_name,
r->in.secure_channel_type,
&challenge->client_challenge,
&challenge->server_challenge,
curNtHash,
r->in.credentials,
r->out.return_credentials,
client_flags,
client_sid,
negotiate_flags);
if (creds == NULL && prevNtHash != NULL) {
/*
* We fallback to the previous password for domain trusts.
*
* Note that lpcfg_old_password_allowed_period() doesn't
* apply here.
*/
creds = netlogon_creds_server_init(mem_ctx,
r->in.account_name,
r->in.computer_name,
r->in.secure_channel_type,
&challenge->client_challenge,
&challenge->server_challenge,
prevNtHash,
r->in.credentials,
r->out.return_credentials,
client_flags,
client_sid,
negotiate_flags);
}
if (creds == NULL) {
TALLOC_FREE(frame);
return NT_STATUS_ACCESS_DENIED;
}
*_creds = creds;
TALLOC_FREE(frame);
return NT_STATUS_OK;
}
/*
* Do the actual processing of a netr_ServerAuthenticate3 message.
* called from dcesrv_netr_ServerAuthenticate3, which handles the logging.
*/
static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct netr_ServerAuthenticate3 *r,
const char **trust_account_for_search,
const char **trust_account_in_db,
struct dom_sid **sid)
{
dcesrv_netr_ServerAuthenticateGenericCallback_fn auth_fn =
dcesrv_netr_ServerAuthenticateNTHash_cb;
return dcesrv_netr_ServerAuthenticateGeneric(dce_call,
mem_ctx,
r,
auth_fn,
trust_account_for_search,
trust_account_in_db,
sid);
}
/* /*
* Log a netr_ServerAuthenticate3 request, and then invoke * Log a netr_ServerAuthenticate3 request, and then invoke
* dcesrv_netr_ServerAuthenticate3_helper to perform the actual processing * dcesrv_netr_ServerAuthenticate3_helper to perform the actual processing
@ -932,8 +1017,13 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call
struct netr_ServerPasswordSet *r) struct netr_ServerPasswordSet *r)
{ {
struct netlogon_creds_CredentialState *creds; struct netlogon_creds_CredentialState *creds;
const struct dom_sid *client_sid = NULL;
struct ldb_context *sam_ctx; struct ldb_context *sam_ctx;
NTSTATUS nt_status; NTSTATUS nt_status;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
nt_status = dcesrv_netr_creds_server_step_check(dce_call, nt_status = dcesrv_netr_creds_server_step_check(dce_call,
mem_ctx, mem_ctx,
@ -941,18 +1031,22 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call
r->in.credential, r->out.return_authenticator, r->in.credential, r->out.return_authenticator,
&creds); &creds);
NT_STATUS_NOT_OK_RETURN(nt_status); NT_STATUS_NOT_OK_RETURN(nt_status);
client_sid = &creds->ex->client_sid;
sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call); sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
if (sam_ctx == NULL) { if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE; return NT_STATUS_INVALID_SYSTEM_SERVICE;
} }
nt_status = netlogon_creds_des_decrypt(creds, r->in.new_password); nt_status = netlogon_creds_decrypt_samr_Password(creds,
r->in.new_password,
auth_type,
auth_level);
NT_STATUS_NOT_OK_RETURN(nt_status); NT_STATUS_NOT_OK_RETURN(nt_status);
/* Using the sid for the account as the key, set the password */ /* Using the sid for the account as the key, set the password */
nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
creds->sid, client_sid,
NULL, /* Don't have version */ NULL, /* Don't have version */
NULL, /* Don't have plaintext */ NULL, /* Don't have plaintext */
r->in.new_password, r->in.new_password,
@ -969,6 +1063,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
struct netr_ServerPasswordSet2 *r) struct netr_ServerPasswordSet2 *r)
{ {
struct netlogon_creds_CredentialState *creds; struct netlogon_creds_CredentialState *creds;
const struct dom_sid *client_sid = NULL;
struct ldb_context *sam_ctx; struct ldb_context *sam_ctx;
struct NL_PASSWORD_VERSION version = {}; struct NL_PASSWORD_VERSION version = {};
const uint32_t *new_version = NULL; const uint32_t *new_version = NULL;
@ -978,6 +1073,10 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
DATA_BLOB dec_blob = data_blob_null; DATA_BLOB dec_blob = data_blob_null;
DATA_BLOB enc_blob = data_blob_null; DATA_BLOB enc_blob = data_blob_null;
struct samr_CryptPassword password_buf; struct samr_CryptPassword password_buf;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
nt_status = dcesrv_netr_creds_server_step_check(dce_call, nt_status = dcesrv_netr_creds_server_step_check(dce_call,
mem_ctx, mem_ctx,
@ -985,6 +1084,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
r->in.credential, r->out.return_authenticator, r->in.credential, r->out.return_authenticator,
&creds); &creds);
NT_STATUS_NOT_OK_RETURN(nt_status); NT_STATUS_NOT_OK_RETURN(nt_status);
client_sid = &creds->ex->client_sid;
sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call); sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
if (sam_ctx == NULL) { if (sam_ctx == NULL) {
@ -994,16 +1094,10 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
memcpy(password_buf.data, r->in.new_password->data, 512); memcpy(password_buf.data, r->in.new_password->data, 512);
SIVAL(password_buf.data, 512, r->in.new_password->length); SIVAL(password_buf.data, 512, r->in.new_password->length);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { nt_status = netlogon_creds_decrypt_samr_CryptPassword(creds,
nt_status = netlogon_creds_aes_decrypt(creds, &password_buf,
password_buf.data, auth_type,
516); auth_level);
} else {
nt_status = netlogon_creds_arcfour_crypt(creds,
password_buf.data,
516);
}
if (!NT_STATUS_IS_OK(nt_status)) { if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status; return nt_status;
} }
@ -1093,7 +1187,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
/* Using the sid for the account as the key, set the password */ /* Using the sid for the account as the key, set the password */
nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
creds->sid, client_sid,
new_version, new_version,
&new_password, /* we have plaintext */ &new_password, /* we have plaintext */
NULL, NULL,
@ -1298,7 +1392,9 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base_call(struct dcesrv_netr_LogonSamL
nt_status = netlogon_creds_decrypt_samlogon_logon(creds, nt_status = netlogon_creds_decrypt_samlogon_logon(creds,
r->in.logon_level, r->in.logon_level,
r->in.logon); r->in.logon,
auth_type,
auth_level);
NT_STATUS_NOT_OK_RETURN(nt_status); NT_STATUS_NOT_OK_RETURN(nt_status);
switch (r->in.logon_level) { switch (r->in.logon_level) {
@ -1335,7 +1431,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base_call(struct dcesrv_netr_LogonSamL
user_info->netlogon_trust_account.account_name user_info->netlogon_trust_account.account_name
= creds->account_name; = creds->account_name;
user_info->netlogon_trust_account.sid user_info->netlogon_trust_account.sid
= creds->sid; = &creds->ex->client_sid;
break; break;
default: default:
@ -1594,9 +1690,16 @@ static void dcesrv_netr_LogonSamLogon_base_reply(
NTSTATUS status; NTSTATUS status;
if (NT_STATUS_IS_OK(r->out.result)) { if (NT_STATUS_IS_OK(r->out.result)) {
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
dcesrv_call_auth_info(state->dce_call, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samlogon_validation(state->creds, status = netlogon_creds_encrypt_samlogon_validation(state->creds,
r->in.validation_level, r->in.validation_level,
r->out.validation); r->out.validation,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("netlogon_creds_encrypt_samlogon_validation() " DBG_ERR("netlogon_creds_encrypt_samlogon_validation() "
"failed - %s\n", "failed - %s\n",
@ -2392,12 +2495,7 @@ static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_c
case 1: case 1:
break; break;
case 2: case 2:
/* break;
* Until we know the details behind KB5028166
* just return DCERPC_NCA_S_FAULT_INVALID_TAG
* like an unpatched Windows Server.
*/
FALL_THROUGH;
default: default:
/* /*
* There would not be a way to marshall the * There would not be a way to marshall the
@ -2423,7 +2521,15 @@ static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_c
} }
NT_STATUS_NOT_OK_RETURN(status); NT_STATUS_NOT_OK_RETURN(status);
switch (r->in.query_level) {
case 1:
r->out.capabilities->server_capabilities = creds->negotiate_flags; r->out.capabilities->server_capabilities = creds->negotiate_flags;
break;
case 2:
r->out.capabilities->requested_flags =
creds->ex->client_requested_flags;
break;
}
return NT_STATUS_OK; return NT_STATUS_OK;
} }
@ -2629,6 +2735,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r) TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r)
{ {
struct netlogon_creds_CredentialState *creds; struct netlogon_creds_CredentialState *creds;
const struct dom_sid *client_sid = NULL;
static const char *const trusts_attrs[] = {"securityIdentifier", static const char *const trusts_attrs[] = {"securityIdentifier",
"flatName", "flatName",
"trustPartner", "trustPartner",
@ -2677,6 +2784,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
talloc_free(frame); talloc_free(frame);
} }
NT_STATUS_NOT_OK_RETURN(status); NT_STATUS_NOT_OK_RETURN(status);
client_sid = &creds->ex->client_sid;
/* We want to avoid connecting as system. */ /* We want to avoid connecting as system. */
sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call); sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
@ -2693,7 +2801,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
/* Prepares the workstation DN */ /* Prepares the workstation DN */
workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>", workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
dom_sid_string(mem_ctx, creds->sid)); dom_sid_string(mem_ctx, client_sid));
NT_STATUS_HAVE_NO_MEMORY(workstation_dn); NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
/* Get the workstation's session info from the database. */ /* Get the workstation's session info from the database. */
@ -3002,7 +3110,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call
static bool sam_rodc_access_check(struct ldb_context *sam_ctx, static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
TALLOC_CTX *mem_ctx, TALLOC_CTX *mem_ctx,
struct dom_sid *user_sid, const struct dom_sid *user_sid,
struct ldb_dn *obj_dn) struct ldb_dn *obj_dn)
{ {
static const char *rodc_attrs[] = {"msDS-NeverRevealGroup", static const char *rodc_attrs[] = {"msDS-NeverRevealGroup",
@ -3057,11 +3165,16 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal
struct netr_NetrLogonSendToSam *r) struct netr_NetrLogonSendToSam *r)
{ {
struct netlogon_creds_CredentialState *creds; struct netlogon_creds_CredentialState *creds;
const struct dom_sid *client_sid = NULL;
struct ldb_context *sam_ctx; struct ldb_context *sam_ctx;
NTSTATUS nt_status; NTSTATUS nt_status;
DATA_BLOB decrypted_blob; DATA_BLOB decrypted_blob;
enum ndr_err_code ndr_err; enum ndr_err_code ndr_err;
struct netr_SendToSamBase base_msg = { 0 }; struct netr_SendToSamBase base_msg = { 0 };
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
nt_status = dcesrv_netr_creds_server_step_check(dce_call, nt_status = dcesrv_netr_creds_server_step_check(dce_call,
mem_ctx, mem_ctx,
@ -3071,6 +3184,7 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal
&creds); &creds);
NT_STATUS_NOT_OK_RETURN(nt_status); NT_STATUS_NOT_OK_RETURN(nt_status);
client_sid = &creds->ex->client_sid;
switch (creds->secure_channel_type) { switch (creds->secure_channel_type) {
case SEC_CHAN_BDC: case SEC_CHAN_BDC:
@ -3093,15 +3207,12 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal
} }
/* Buffer is meant to be 16-bit aligned */ /* Buffer is meant to be 16-bit aligned */
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
nt_status = netlogon_creds_aes_decrypt(creds, nt_status = netlogon_creds_decrypt_SendToSam(creds,
r->in.opaque_buffer, r->in.opaque_buffer,
r->in.buffer_len); r->in.buffer_len,
} else { auth_type,
nt_status = netlogon_creds_arcfour_crypt(creds, auth_level);
r->in.opaque_buffer,
r->in.buffer_len);
}
if (!NT_STATUS_IS_OK(nt_status)) { if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status; return nt_status;
} }
@ -3142,7 +3253,7 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal
} }
if (creds->secure_channel_type == SEC_CHAN_RODC && if (creds->secure_channel_type == SEC_CHAN_RODC &&
!sam_rodc_access_check(sam_ctx, mem_ctx, creds->sid, dn)) { !sam_rodc_access_check(sam_ctx, mem_ctx, client_sid, dn)) {
DEBUG(1, ("Client asked to reset bad password on " DEBUG(1, ("Client asked to reset bad password on "
"an arbitrary user: %s\n", "an arbitrary user: %s\n",
ldb_dn_get_linearized(dn))); ldb_dn_get_linearized(dn)));
@ -4427,6 +4538,7 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal
{ {
struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
struct netlogon_creds_CredentialState *creds = NULL; struct netlogon_creds_CredentialState *creds = NULL;
const struct dom_sid *client_sid = NULL;
struct ldb_context *sam_ctx = NULL; struct ldb_context *sam_ctx = NULL;
static const char * const attrs[] = { static const char * const attrs[] = {
"unicodePwd", "unicodePwd",
@ -4454,6 +4566,10 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal
NULL NULL
}; };
struct netr_TrustInfo *trust_info = NULL; struct netr_TrustInfo *trust_info = NULL;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
ZERO_STRUCTP(r->out.new_owf_password); ZERO_STRUCTP(r->out.new_owf_password);
ZERO_STRUCTP(r->out.old_owf_password); ZERO_STRUCTP(r->out.old_owf_password);
@ -4467,6 +4583,7 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal
if (!NT_STATUS_IS_OK(nt_status)) { if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status; return nt_status;
} }
client_sid = &creds->ex->client_sid;
/* TODO: check r->in.server_name is our name */ /* TODO: check r->in.server_name is our name */
@ -4487,7 +4604,7 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal
return NT_STATUS_INVALID_SYSTEM_SERVICE; return NT_STATUS_INVALID_SYSTEM_SERVICE;
} }
asid = ldap_encode_ndr_dom_sid(mem_ctx, creds->sid); asid = ldap_encode_ndr_dom_sid(mem_ctx, client_sid);
if (asid == NULL) { if (asid == NULL) {
return NT_STATUS_NO_MEMORY; return NT_STATUS_NO_MEMORY;
} }
@ -4584,14 +4701,20 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal
if (curNtHash != NULL) { if (curNtHash != NULL) {
*r->out.new_owf_password = *curNtHash; *r->out.new_owf_password = *curNtHash;
nt_status = netlogon_creds_des_encrypt(creds, r->out.new_owf_password); nt_status = netlogon_creds_encrypt_samr_Password(creds,
r->out.new_owf_password,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(nt_status)) { if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status; return nt_status;
} }
} }
if (prevNtHash != NULL) { if (prevNtHash != NULL) {
*r->out.old_owf_password = *prevNtHash; *r->out.old_owf_password = *prevNtHash;
nt_status = netlogon_creds_des_encrypt(creds, r->out.old_owf_password); nt_status = netlogon_creds_encrypt_samr_Password(creds,
r->out.old_owf_password,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(nt_status)) { if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status; return nt_status;
} }
@ -4656,6 +4779,7 @@ static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call
struct tevent_req *subreq; struct tevent_req *subreq;
struct imessaging_context *imsg_ctx = struct imessaging_context *imsg_ctx =
dcesrv_imessaging_context(dce_call->conn); dcesrv_imessaging_context(dce_call->conn);
struct dom_sid *client_sid = NULL;
nt_status = dcesrv_netr_creds_server_step_check(dce_call, nt_status = dcesrv_netr_creds_server_step_check(dce_call,
mem_ctx, mem_ctx,
@ -4664,6 +4788,7 @@ static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call
r->out.return_authenticator, r->out.return_authenticator,
&creds); &creds);
NT_STATUS_NOT_OK_RETURN(nt_status); NT_STATUS_NOT_OK_RETURN(nt_status);
client_sid = &creds->ex->client_sid;
if (creds->secure_channel_type != SEC_CHAN_RODC) { if (creds->secure_channel_type != SEC_CHAN_RODC) {
return NT_STATUS_ACCESS_DENIED; return NT_STATUS_ACCESS_DENIED;
@ -4677,7 +4802,7 @@ static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call
st->r2 = talloc_zero(st, struct dnsupdate_RODC); st->r2 = talloc_zero(st, struct dnsupdate_RODC);
NT_STATUS_HAVE_NO_MEMORY(st->r2); NT_STATUS_HAVE_NO_MEMORY(st->r2);
st->r2->in.dom_sid = creds->sid; st->r2->in.dom_sid = client_sid;
st->r2->in.site_name = r->in.site_name; st->r2->in.site_name = r->in.site_name;
st->r2->in.dns_ttl = r->in.dns_ttl; st->r2->in.dns_ttl = r->in.dns_ttl;
st->r2->in.dns_names = r->in.dns_names; st->r2->in.dns_names = r->in.dns_names;
@ -4706,6 +4831,36 @@ static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call
return NT_STATUS_OK; return NT_STATUS_OK;
} }
DCESRV_NOT_USED_ON_WIRE(netr_Opnum49NotUsedOnWire)
DCESRV_NOT_USED_ON_WIRE(netr_Opnum50NotUsedOnWire)
DCESRV_NOT_USED_ON_WIRE(netr_Opnum51NotUsedOnWire)
DCESRV_NOT_USED_ON_WIRE(netr_Opnum52NotUsedOnWire)
DCESRV_NOT_USED_ON_WIRE(netr_Opnum53NotUsedOnWire)
/*
netr_ChainSetClientAttributes
*/
static NTSTATUS dcesrv_netr_ChainSetClientAttributes(struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct netr_ChainSetClientAttributes *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
DCESRV_NOT_USED_ON_WIRE(netr_Opnum55NotUsedOnWire)
DCESRV_NOT_USED_ON_WIRE(netr_Opnum56NotUsedOnWire)
DCESRV_NOT_USED_ON_WIRE(netr_Opnum57NotUsedOnWire)
DCESRV_NOT_USED_ON_WIRE(netr_Opnum58NotUsedOnWire)
/*
netr_ServerAuthenticateKerberos
*/
static NTSTATUS dcesrv_netr_ServerAuthenticateKerberos(struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct netr_ServerAuthenticateKerberos *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
/* include the generated boilerplate */ /* include the generated boilerplate */
#include "librpc/gen_ndr/ndr_netlogon_s.c" #include "librpc/gen_ndr/ndr_netlogon_s.c"

View File

@ -119,6 +119,7 @@ static bool test_ntp_signd(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
pwhash, &credentials3, pwhash, &credentials3,
negotiate_flags,
negotiate_flags); negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");

View File

@ -658,6 +658,8 @@ static bool test_validate_trust(struct torture_context *tctx,
struct samr_Password *old_nt_hash; struct samr_Password *old_nt_hash;
char *dummy; char *dummy;
uint32_t trust_attributes = LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE; uint32_t trust_attributes = LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
status = dcerpc_parse_binding(tctx, binding, &b); status = dcerpc_parse_binding(tctx, binding, &b);
torture_assert_ntstatus_ok(tctx, status, "Bad binding string"); torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
@ -733,8 +735,19 @@ static bool test_validate_trust(struct torture_context *tctx,
old_nt_hash = cli_credentials_get_old_nt_hash(credentials, tctx); old_nt_hash = cli_credentials_get_old_nt_hash(credentials, tctx);
torture_assert(tctx, old_nt_hash != NULL, "cli_credentials_get_old_nt_hash()"); torture_assert(tctx, old_nt_hash != NULL, "cli_credentials_get_old_nt_hash()");
netlogon_creds_des_decrypt(creds, &new_owf_password); dcerpc_binding_handle_auth_info(p->binding_handle,
netlogon_creds_des_decrypt(creds, &old_owf_password); &auth_type,
&auth_level);
status = netlogon_creds_decrypt_samr_Password(creds,
&new_owf_password,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "decrypt_samr_Password");
status = netlogon_creds_decrypt_samr_Password(creds,
&old_owf_password,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "decrypt_samr_Password");
dump_data(1, new_owf_password.hash, 16); dump_data(1, new_owf_password.hash, 16);
dump_data(1, new_nt_hash->hash, 16); dump_data(1, new_nt_hash->hash, 16);

View File

@ -2951,6 +2951,7 @@ static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
new_password, &credentials3, new_password, &credentials3,
negotiate_flags,
negotiate_flags); negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -2976,6 +2977,7 @@ static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
old_password, &credentials3, old_password, &credentials3,
negotiate_flags,
negotiate_flags); negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -4368,6 +4370,8 @@ static bool check_dom_trust_pw(struct dcerpc_pipe *p,
struct tsocket_address *dest_addr; struct tsocket_address *dest_addr;
struct cldap_socket *cldap; struct cldap_socket *cldap;
struct cldap_netlogon cldap1; struct cldap_netlogon cldap1;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
incoming_creds = cli_credentials_init(tctx); incoming_creds = cli_credentials_init(tctx);
torture_assert(tctx, incoming_creds, "cli_credentials_init"); torture_assert(tctx, incoming_creds, "cli_credentials_init");
@ -4523,15 +4527,14 @@ static bool check_dom_trust_pw(struct dcerpc_pipe *p,
netlogon_creds_client_authenticator(creds, &req_auth); netlogon_creds_client_authenticator(creds, &req_auth);
ZERO_STRUCT(rep_auth); ZERO_STRUCT(rep_auth);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { dcerpc_binding_handle_auth_info(p2->binding_handle,
netlogon_creds_aes_encrypt(creds, &auth_type,
samr_crypt_password.data, &auth_level);
516); status = netlogon_creds_encrypt_samr_CryptPassword(creds,
} else { &samr_crypt_password,
netlogon_creds_arcfour_crypt(creds, auth_type,
samr_crypt_password.data, auth_level);
516); torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
}
memcpy(netr_crypt_password.data, memcpy(netr_crypt_password.data,
samr_crypt_password.data, 512); samr_crypt_password.data, 512);

View File

@ -180,6 +180,7 @@ bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
mach_password, &credentials3, mach_password, &credentials3,
0,
0); 0);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -251,6 +252,7 @@ bool test_SetupCredentials2ex(struct dcerpc_pipe *p, struct torture_context *tct
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
mach_password, &credentials3, mach_password, &credentials3,
negotiate_flags,
negotiate_flags); negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -349,6 +351,7 @@ bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
negotiate_flags,
negotiate_flags); negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -421,6 +424,7 @@ bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
negotiate_flags,
negotiate_flags); negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -437,6 +441,7 @@ bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
negotiate_flags,
negotiate_flags); negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -541,6 +546,7 @@ static bool test_ServerReqChallenge(
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
mach_password, &credentials3, mach_password, &credentials3,
in_negotiate_flags,
in_negotiate_flags); in_negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -618,6 +624,7 @@ static bool test_ServerReqChallenge_zero_challenge(
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
mach_password, &credentials3, mach_password, &credentials3,
in_negotiate_flags,
in_negotiate_flags); in_negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -702,6 +709,7 @@ static bool test_ServerReqChallenge_5_repeats(
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
mach_password, &credentials3, mach_password, &credentials3,
in_negotiate_flags,
in_negotiate_flags); in_negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -788,6 +796,7 @@ static bool test_ServerReqChallenge_4_repeats(
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
mach_password, &credentials3, mach_password, &credentials3,
in_negotiate_flags,
in_negotiate_flags); in_negotiate_flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -881,6 +890,7 @@ static bool test_ServerAuthenticate2_encrypts_to_zero(
&credentials2, &credentials2,
mach_password, mach_password,
&credentials3, &credentials3,
flags,
flags); flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -922,6 +932,9 @@ static bool test_SetPassword(struct torture_context *tctx,
struct netr_Authenticator credential, return_authenticator; struct netr_Authenticator credential, return_authenticator;
struct samr_Password new_password; struct samr_Password new_password;
struct dcerpc_binding_handle *b = p->binding_handle; struct dcerpc_binding_handle *b = p->binding_handle;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
NTSTATUS status;
if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) { if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
return false; return false;
@ -938,7 +951,12 @@ static bool test_SetPassword(struct torture_context *tctx,
password = generate_random_password(tctx, 8, 255); password = generate_random_password(tctx, 8, 255);
E_md4hash(password, new_password.hash); E_md4hash(password, new_password.hash);
netlogon_creds_des_encrypt(creds, &new_password); dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samr_Password(creds,
&new_password,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_Password");
torture_comment(tctx, "Testing ServerPasswordSet on machine account\n"); torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
torture_comment(tctx, "Changing machine account password to '%s'\n", torture_comment(tctx, "Changing machine account password to '%s'\n",
@ -997,6 +1015,9 @@ static bool test_SetPassword_flags(struct torture_context *tctx,
struct samr_Password new_password; struct samr_Password new_password;
struct dcerpc_pipe *p = NULL; struct dcerpc_pipe *p = NULL;
struct dcerpc_binding_handle *b = NULL; struct dcerpc_binding_handle *b = NULL;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
if (!test_SetupCredentials2(p1, tctx, negotiate_flags, if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
machine_credentials, machine_credentials,
@ -1021,7 +1042,12 @@ static bool test_SetPassword_flags(struct torture_context *tctx,
password = generate_random_password(tctx, 8, 255); password = generate_random_password(tctx, 8, 255);
E_md4hash(password, new_password.hash); E_md4hash(password, new_password.hash);
netlogon_creds_des_encrypt(creds, &new_password); dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samr_Password(creds,
&new_password,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_Password");
torture_comment(tctx, "Testing ServerPasswordSet on machine account\n"); torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
torture_comment(tctx, "Changing machine account password to '%s'\n", torture_comment(tctx, "Changing machine account password to '%s'\n",
@ -1102,6 +1128,9 @@ static bool test_SetPassword2_with_flags(struct torture_context *tctx,
struct netr_CryptPassword new_password; struct netr_CryptPassword new_password;
struct dcerpc_pipe *p = NULL; struct dcerpc_pipe *p = NULL;
struct dcerpc_binding_handle *b = NULL; struct dcerpc_binding_handle *b = NULL;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials, if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials,
cli_credentials_get_secure_channel_type(machine_credentials), cli_credentials_get_secure_channel_type(machine_credentials),
@ -1124,11 +1153,12 @@ static bool test_SetPassword2_with_flags(struct torture_context *tctx,
password = generate_random_password(tctx, 8, 255); password = generate_random_password(tctx, 8, 255);
encode_pw_buffer(password_buf.data, password, STR_UNICODE); encode_pw_buffer(password_buf.data, password, STR_UNICODE);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
netlogon_creds_aes_encrypt(creds, password_buf.data, 516); status = netlogon_creds_encrypt_samr_CryptPassword(creds,
} else { &password_buf,
netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); auth_type,
} auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
memcpy(new_password.data, password_buf.data, 512); memcpy(new_password.data, password_buf.data, 512);
new_password.length = IVAL(password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512);
@ -1158,11 +1188,12 @@ static bool test_SetPassword2_with_flags(struct torture_context *tctx,
*/ */
password = ""; password = "";
encode_pw_buffer(password_buf.data, password, STR_UNICODE); encode_pw_buffer(password_buf.data, password, STR_UNICODE);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
netlogon_creds_aes_encrypt(creds, password_buf.data, 516); status = netlogon_creds_encrypt_samr_CryptPassword(creds,
} else { &password_buf,
netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); auth_type,
} auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
memcpy(new_password.data, password_buf.data, 512); memcpy(new_password.data, password_buf.data, 512);
new_password.length = IVAL(password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512);
@ -1185,11 +1216,12 @@ static bool test_SetPassword2_with_flags(struct torture_context *tctx,
/* now try a random password */ /* now try a random password */
password = generate_random_password(tctx, 8, 255); password = generate_random_password(tctx, 8, 255);
encode_pw_buffer(password_buf.data, password, STR_UNICODE); encode_pw_buffer(password_buf.data, password, STR_UNICODE);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
netlogon_creds_aes_encrypt(creds, password_buf.data, 516); status = netlogon_creds_encrypt_samr_CryptPassword(creds,
} else { &password_buf,
netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); auth_type,
} auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
memcpy(new_password.data, password_buf.data, 512); memcpy(new_password.data, password_buf.data, 512);
new_password.length = IVAL(password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512);
@ -1236,11 +1268,12 @@ static bool test_SetPassword2_with_flags(struct torture_context *tctx,
/* now try a random stream of bytes for a password */ /* now try a random stream of bytes for a password */
set_pw_in_buffer(password_buf.data, &new_random_pass); set_pw_in_buffer(password_buf.data, &new_random_pass);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
netlogon_creds_aes_encrypt(creds, password_buf.data, 516); status = netlogon_creds_encrypt_samr_CryptPassword(creds,
} else { &password_buf,
netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); auth_type,
} auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
memcpy(new_password.data, password_buf.data, 512); memcpy(new_password.data, password_buf.data, 512);
new_password.length = IVAL(password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512);
@ -1289,6 +1322,9 @@ static bool test_SetPassword2_encrypted_to_all_zeros(
struct netr_CryptPassword new_password; struct netr_CryptPassword new_password;
struct dcerpc_pipe *p = NULL; struct dcerpc_pipe *p = NULL;
struct dcerpc_binding_handle *b = NULL; struct dcerpc_binding_handle *b = NULL;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
if (!test_ServerAuthenticate2_encrypts_to_zero( if (!test_ServerAuthenticate2_encrypts_to_zero(
tctx, tctx,
@ -1328,7 +1364,12 @@ static bool test_SetPassword2_encrypted_to_all_zeros(
if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) { if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set"); torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
} }
netlogon_creds_aes_encrypt(creds, password_buf.data, 516); dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samr_CryptPassword(creds,
&password_buf,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
if(!all_zero(password_buf.data, 516)) { if(!all_zero(password_buf.data, 516)) {
torture_fail(tctx, "Password did not encrypt to all zeros\n"); torture_fail(tctx, "Password did not encrypt to all zeros\n");
} }
@ -1375,6 +1416,9 @@ static bool test_SetPassword2_password_encrypts_to_zero(
struct netr_CryptPassword new_password; struct netr_CryptPassword new_password;
struct dcerpc_pipe *p = NULL; struct dcerpc_pipe *p = NULL;
struct dcerpc_binding_handle *b = NULL; struct dcerpc_binding_handle *b = NULL;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
if (!test_ServerAuthenticate2_encrypts_to_zero( if (!test_ServerAuthenticate2_encrypts_to_zero(
tctx, tctx,
@ -1415,7 +1459,12 @@ static bool test_SetPassword2_password_encrypts_to_zero(
if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) { if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set"); torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
} }
netlogon_creds_aes_encrypt(creds, password_buf.data, 516); dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samr_CryptPassword(creds,
&password_buf,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
memcpy(new_password.data, password_buf.data, 512); memcpy(new_password.data, password_buf.data, 512);
new_password.length = IVAL(password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512);
@ -1451,6 +1500,9 @@ static bool test_SetPassword2_confounder(
struct netr_CryptPassword new_password; struct netr_CryptPassword new_password;
struct dcerpc_pipe *p = NULL; struct dcerpc_pipe *p = NULL;
struct dcerpc_binding_handle *b = NULL; struct dcerpc_binding_handle *b = NULL;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
if (!test_ServerAuthenticate2_encrypts_to_zero( if (!test_ServerAuthenticate2_encrypts_to_zero(
tctx, tctx,
@ -1492,7 +1544,12 @@ static bool test_SetPassword2_confounder(
if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) { if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set"); torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
} }
netlogon_creds_aes_encrypt(creds, password_buf.data, 516); dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samr_CryptPassword(creds,
&password_buf,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
memcpy(new_password.data, password_buf.data, 512); memcpy(new_password.data, password_buf.data, 512);
new_password.length = IVAL(password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512);
@ -1528,6 +1585,9 @@ static bool test_SetPassword2_all_zeros(
struct dcerpc_pipe *p = NULL; struct dcerpc_pipe *p = NULL;
struct dcerpc_binding_handle *b = NULL; struct dcerpc_binding_handle *b = NULL;
uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */ uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
if (!test_SetupCredentials2( if (!test_SetupCredentials2(
p1, p1,
@ -1566,7 +1626,12 @@ static bool test_SetPassword2_all_zeros(
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES enabled\n"); torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES enabled\n");
} }
netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samr_CryptPassword(creds,
&password_buf,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
memcpy(new_password.data, password_buf.data, 512); memcpy(new_password.data, password_buf.data, 512);
new_password.length = IVAL(password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512);
@ -1605,6 +1670,9 @@ static bool test_SetPassword2_maximum_length_password(
struct dcerpc_binding_handle *b = NULL; struct dcerpc_binding_handle *b = NULL;
uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES; uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
DATA_BLOB new_random_pass = data_blob_null; DATA_BLOB new_random_pass = data_blob_null;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
if (!test_SetupCredentials2( if (!test_SetupCredentials2(
p1, p1,
@ -1642,11 +1710,12 @@ static bool test_SetPassword2_maximum_length_password(
new_random_pass = netlogon_very_rand_pass(tctx, 256); new_random_pass = netlogon_very_rand_pass(tctx, 256);
set_pw_in_buffer(password_buf.data, &new_random_pass); set_pw_in_buffer(password_buf.data, &new_random_pass);
SIVAL(password_buf.data, 512, 512); SIVAL(password_buf.data, 512, 512);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
netlogon_creds_aes_encrypt(creds, password_buf.data, 516); status = netlogon_creds_encrypt_samr_CryptPassword(creds,
} else { &password_buf,
netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); auth_type,
} auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
memcpy(new_password.data, password_buf.data, 512); memcpy(new_password.data, password_buf.data, 512);
new_password.length = IVAL(password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512);
@ -1687,6 +1756,9 @@ static bool test_SetPassword2_all_zero_password(
struct dcerpc_pipe *p = NULL; struct dcerpc_pipe *p = NULL;
struct dcerpc_binding_handle *b = NULL; struct dcerpc_binding_handle *b = NULL;
uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */ uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
if (!test_SetupCredentials2( if (!test_SetupCredentials2(
p1, p1,
@ -1726,7 +1798,12 @@ static bool test_SetPassword2_all_zero_password(
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES set"); torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES set");
} }
netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samr_CryptPassword(creds,
&password_buf,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
memcpy(new_password.data, password_buf.data, 512); memcpy(new_password.data, password_buf.data, 512);
new_password.length = IVAL(password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512);
@ -2039,6 +2116,7 @@ bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
*/ */
bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx, bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
struct cli_credentials *credentials, struct cli_credentials *credentials,
uint32_t requested_flags,
struct netlogon_creds_CredentialState *creds) struct netlogon_creds_CredentialState *creds)
{ {
NTSTATUS status; NTSTATUS status;
@ -2109,10 +2187,10 @@ bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *t
netlogon_creds_client_authenticator(&tmp_creds, &auth); netlogon_creds_client_authenticator(&tmp_creds, &auth);
status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r); status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed"); torture_assert_ntstatus_ok(tctx, status,
if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) { "LogonGetCapabilities query_level=1 failed");
return true; torture_assert_ntstatus_ok(tctx, r.out.result,
} "LogonGetCapabilities query_level=1 failed");
*creds = tmp_creds; *creds = tmp_creds;
@ -2140,15 +2218,10 @@ bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *t
netlogon_creds_client_authenticator(&tmp_creds, &auth); netlogon_creds_client_authenticator(&tmp_creds, &auth);
status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r); status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) { torture_assert_ntstatus_ok(tctx, status,
/* "LogonGetCapabilities query_level=2 failed");
* an server without KB5028166 returns torture_assert_ntstatus_ok(tctx, r.out.result,
* DCERPC_NCA_S_FAULT_INVALID_TAG => "LogonGetCapabilities query_level=2 failed");
* NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
*/
return true;
}
torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities query_level=2 failed");
*creds = tmp_creds; *creds = tmp_creds;
@ -2156,8 +2229,8 @@ bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *t
&r.out.return_authenticator->cred), &r.out.return_authenticator->cred),
"Credential chaining failed"); "Credential chaining failed");
torture_assert_int_equal(tctx, creds->negotiate_flags, torture_assert_int_equal(tctx, requested_flags,
capabilities.server_capabilities, capabilities.requested_flags,
"negotiate flags"); "negotiate flags");
return true; return true;
@ -2276,6 +2349,7 @@ static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -2365,6 +2439,7 @@ static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -2382,6 +2457,7 @@ static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a), torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a),
@ -2454,6 +2530,7 @@ static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -2471,6 +2548,7 @@ static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a), torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
@ -2544,6 +2622,7 @@ static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -2561,6 +2640,7 @@ static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -2659,6 +2739,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -2676,6 +2757,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a), torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
@ -2735,6 +2817,7 @@ static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -2752,6 +2835,7 @@ static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a), torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
@ -2766,6 +2850,7 @@ static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
&credentials1, &credentials2, &credentials1, &credentials2,
&mach_password, &credentials3, &mach_password, &credentials3,
flags,
flags); flags);
torture_assert(tctx, creds != NULL, "memory allocation"); torture_assert(tctx, creds != NULL, "memory allocation");
@ -4973,6 +5058,9 @@ static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
struct dcerpc_binding_handle *b = NULL; struct dcerpc_binding_handle *b = NULL;
struct samr_Password nt_hash; struct samr_Password nt_hash;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
NTSTATUS status;
if (!test_SetupCredentials3(p1, tctx, negotiate_flags, if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
machine_credentials, &creds)) { machine_credentials, &creds)) {
@ -5004,7 +5092,17 @@ static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash); E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
netlogon_creds_des_decrypt(creds, &new_owf_password); dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_decrypt_samr_Password(creds,
&new_owf_password,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "decrypt_samr_Password");
status = netlogon_creds_decrypt_samr_Password(creds,
&old_owf_password,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "decrypt_samr_Password");
dump_data(1, new_owf_password.hash, 16); dump_data(1, new_owf_password.hash, 16);
dump_data(1, nt_hash.hash, 16); dump_data(1, nt_hash.hash, 16);

View File

@ -124,6 +124,7 @@ static bool test_ServerAuth3Crypto(struct dcerpc_pipe *p,
&netr_creds2, &netr_creds2,
&machine_password, &machine_password,
&netr_creds3, &netr_creds3,
negotiate_flags,
negotiate_flags); negotiate_flags);
GNUTLS_FIPS140_SET_STRICT_MODE(); GNUTLS_FIPS140_SET_STRICT_MODE();
/* Test that we fail to encrypt with RC4 */ /* Test that we fail to encrypt with RC4 */
@ -152,6 +153,8 @@ static bool test_ServerAuth3Crypto(struct dcerpc_pipe *p,
a.out.result, a.out.result,
NT_STATUS_DOWNGRADE_DETECTED, NT_STATUS_DOWNGRADE_DETECTED,
"Unexpected status code"); "Unexpected status code");
torture_assert_int_equal(tctx, negotiate_flags, 0,
"NT_STATUS_DOWNGRADE_DETECTED...");
return false; return false;
} }
torture_assert_ntstatus_ok(tctx, torture_assert_ntstatus_ok(tctx,
@ -167,8 +170,8 @@ static bool test_ServerAuth3Crypto(struct dcerpc_pipe *p,
if (!weak_crypto_allowed) { if (!weak_crypto_allowed) {
torture_assert(tctx, torture_assert(tctx,
(negotiate_flags & NETLOGON_NEG_ARCFOUR) == 0, (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES),
"Server should not announce RC4 support"); "Server negotiate AES support");
} }
/* Prove that requesting a challenge again won't break it */ /* Prove that requesting a challenge again won't break it */

View File

@ -406,6 +406,9 @@ static bool netlogon_validate_pac(struct torture_context *tctx,
struct dcerpc_binding_handle *b = NULL; struct dcerpc_binding_handle *b = NULL;
enum ndr_err_code ndr_err; enum ndr_err_code ndr_err;
DATA_BLOB payload, pac_wrapped; DATA_BLOB payload, pac_wrapped;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
NTSTATUS status;
if (!test_SetupCredentials2(p1, tctx, negotiate_flags, if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
server_creds, secure_channel_type, server_creds, secure_channel_type,
@ -437,11 +440,6 @@ static bool netlogon_validate_pac(struct torture_context *tctx,
torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed"); torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed");
torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption"); torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption");
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
netlogon_creds_aes_encrypt(creds, pac_wrapped.data, pac_wrapped.length);
} else {
netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length);
}
generic.length = pac_wrapped.length; generic.length = pac_wrapped.length;
generic.data = pac_wrapped.data; generic.data = pac_wrapped.data;
@ -471,6 +469,14 @@ static bool netlogon_validate_pac(struct torture_context *tctx,
r.out.authoritative = &authoritative; r.out.authoritative = &authoritative;
r.out.return_authenticator = &return_authenticator; r.out.return_authenticator = &return_authenticator;
dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samlogon_logon(creds,
r.in.logon_level,
r.in.logon,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samlogon_logon");
torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r), torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
"LogonSamLogon failed"); "LogonSamLogon failed");
@ -546,11 +552,6 @@ static bool netlogon_validate_pac(struct torture_context *tctx,
torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed"); torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed");
torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption"); torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption");
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
netlogon_creds_aes_encrypt(creds, pac_wrapped.data, pac_wrapped.length);
} else {
netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length);
}
generic.length = pac_wrapped.length; generic.length = pac_wrapped.length;
generic.data = pac_wrapped.data; generic.data = pac_wrapped.data;
@ -567,6 +568,14 @@ static bool netlogon_validate_pac(struct torture_context *tctx,
r.in.computer_name = cli_credentials_get_workstation(server_creds); r.in.computer_name = cli_credentials_get_workstation(server_creds);
r.in.validation_level = NetlogonValidationGenericInfo2; r.in.validation_level = NetlogonValidationGenericInfo2;
dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samlogon_logon(creds,
r.in.logon_level,
r.in.logon,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samlogon_logon");
torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r), torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
"LogonSamLogon failed"); "LogonSamLogon failed");
@ -598,11 +607,6 @@ static bool netlogon_validate_pac(struct torture_context *tctx,
torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed"); torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed");
torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption"); torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption");
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
netlogon_creds_aes_encrypt(creds, pac_wrapped.data, pac_wrapped.length);
} else {
netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length);
}
generic.length = pac_wrapped.length; generic.length = pac_wrapped.length;
generic.data = pac_wrapped.data; generic.data = pac_wrapped.data;
@ -619,6 +623,14 @@ static bool netlogon_validate_pac(struct torture_context *tctx,
r.in.computer_name = cli_credentials_get_workstation(server_creds); r.in.computer_name = cli_credentials_get_workstation(server_creds);
r.in.validation_level = NetlogonValidationGenericInfo2; r.in.validation_level = NetlogonValidationGenericInfo2;
dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samlogon_logon(creds,
r.in.logon_level,
r.in.logon,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samlogon_logon");
torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r), torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
"LogonSamLogon failed"); "LogonSamLogon failed");

View File

@ -1091,7 +1091,9 @@ static bool auth2(struct torture_context *tctx,
a.in.secure_channel_type, a.in.secure_channel_type,
r.in.credentials, r.in.credentials,
r.out.return_credentials, &mach_pw, r.out.return_credentials, &mach_pw,
&netr_cred, negotiate_flags); &netr_cred,
negotiate_flags,
negotiate_flags);
torture_assert(tctx, (creds_state != NULL), "memory allocation failed"); torture_assert(tctx, (creds_state != NULL), "memory allocation failed");
status = dcerpc_netr_ServerAuthenticate2_r(net_handle, mem_ctx, &a); status = dcerpc_netr_ServerAuthenticate2_r(net_handle, mem_ctx, &a);
@ -1303,6 +1305,8 @@ static bool schan(struct torture_context *tctx,
struct netlogon_creds_CredentialState *creds_state; struct netlogon_creds_CredentialState *creds_state;
struct netr_Authenticator credential, return_authenticator; struct netr_Authenticator credential, return_authenticator;
struct samr_Password new_password; struct samr_Password new_password;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
s.in.server_name = talloc_asprintf( s.in.server_name = talloc_asprintf(
mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
@ -1317,7 +1321,14 @@ static bool schan(struct torture_context *tctx,
E_md4hash(password, new_password.hash); E_md4hash(password, new_password.hash);
creds_state = cli_credentials_get_netlogon_creds(wks_creds); creds_state = cli_credentials_get_netlogon_creds(wks_creds);
netlogon_creds_des_encrypt(creds_state, &new_password); dcerpc_binding_handle_auth_info(net_handle,
&auth_type,
&auth_level);
status = netlogon_creds_encrypt_samr_Password(creds_state,
&new_password,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_Password");
netlogon_creds_client_authenticator(creds_state, &credential); netlogon_creds_client_authenticator(creds_state, &credential);
status = dcerpc_netr_ServerPasswordSet_r(net_handle, mem_ctx, &s); status = dcerpc_netr_ServerPasswordSet_r(net_handle, mem_ctx, &s);
@ -2158,7 +2169,9 @@ static bool torture_samba3_rpc_randomauth2(struct torture_context *torture)
a.in.secure_channel_type, a.in.secure_channel_type,
r.in.credentials, r.in.credentials,
r.out.return_credentials, &mach_pw, r.out.return_credentials, &mach_pw,
&netr_cred, negotiate_flags); &netr_cred,
negotiate_flags,
negotiate_flags);
torture_assert(torture, (creds_state != NULL), "memory allocation failed"); torture_assert(torture, (creds_state != NULL), "memory allocation failed");
status = dcerpc_netr_ServerAuthenticate2_r(net_handle, mem_ctx, &a); status = dcerpc_netr_ServerAuthenticate2_r(net_handle, mem_ctx, &a);

View File

@ -91,6 +91,12 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
struct netr_NetworkInfo ninfo; struct netr_NetworkInfo ninfo;
struct netr_SamBaseInfo *base = NULL; struct netr_SamBaseInfo *base = NULL;
uint16_t validation_level = 0; uint16_t validation_level = 0;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
dcerpc_binding_handle_auth_info(samlogon_state->p->binding_handle,
&auth_type,
&auth_level);
samlogon_state->r.in.logon->network = &ninfo; samlogon_state->r.in.logon->network = &ninfo;
samlogon_state->r_ex.in.logon->network = &ninfo; samlogon_state->r_ex.in.logon->network = &ninfo;
@ -178,7 +184,9 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
status = netlogon_creds_decrypt_samlogon_validation(samlogon_state->creds, status = netlogon_creds_decrypt_samlogon_validation(samlogon_state->creds,
validation_level, validation_level,
r->out.validation); r->out.validation,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
if (error_string) { if (error_string) {
*error_string = strdup(nt_errstr(status)); *error_string = strdup(nt_errstr(status));
@ -218,7 +226,9 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
status = netlogon_creds_decrypt_samlogon_validation(samlogon_state->creds, status = netlogon_creds_decrypt_samlogon_validation(samlogon_state->creds,
validation_level, validation_level,
r_ex->out.validation); r_ex->out.validation,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
if (error_string) { if (error_string) {
*error_string = strdup(nt_errstr(status)); *error_string = strdup(nt_errstr(status));
@ -266,7 +276,9 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
status = netlogon_creds_decrypt_samlogon_validation(samlogon_state->creds, status = netlogon_creds_decrypt_samlogon_validation(samlogon_state->creds,
validation_level, validation_level,
r_flags->out.validation); r_flags->out.validation,
auth_type,
auth_level);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
if (error_string) { if (error_string) {
*error_string = strdup(nt_errstr(status)); *error_string = strdup(nt_errstr(status));
@ -1539,6 +1551,10 @@ bool test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
union netr_Validation validation; union netr_Validation validation;
uint8_t authoritative = 1; uint8_t authoritative = 1;
struct dcerpc_binding_handle *b = p->binding_handle; struct dcerpc_binding_handle *b = p->binding_handle;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
ZERO_STRUCT(a); ZERO_STRUCT(a);
ZERO_STRUCT(r); ZERO_STRUCT(r);
@ -1574,13 +1590,15 @@ bool test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
} }
E_md4hash(plain_pass, pinfo.ntpassword.hash); E_md4hash(plain_pass, pinfo.ntpassword.hash);
if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { status = netlogon_creds_encrypt_samlogon_logon(creds,
netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16); r.in.logon_level,
netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16); r.in.logon,
} else { auth_type,
netlogon_creds_des_encrypt(creds, &pinfo.lmpassword); auth_level);
netlogon_creds_des_encrypt(creds, &pinfo.ntpassword); torture_assert_ntstatus_ok_goto(tctx,
} status,
ret, failed,
"netlogon_creds_encrypt_samlogon_logon");
torture_comment(tctx, "Testing netr_LogonSamLogonWithFlags '%s' (Interactive Logon)\n", comment); torture_comment(tctx, "Testing netr_LogonSamLogonWithFlags '%s' (Interactive Logon)\n", comment);

View File

@ -3607,6 +3607,8 @@ static bool test_SamLogon(struct torture_context *tctx,
struct netlogon_creds_CredentialState *creds; struct netlogon_creds_CredentialState *creds;
struct netr_Authenticator a; struct netr_Authenticator a;
struct dcerpc_binding_handle *b = p->binding_handle; struct dcerpc_binding_handle *b = p->binding_handle;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
torture_assert(tctx, (creds = cli_credentials_get_netlogon_creds(machine_credentials)), ""); torture_assert(tctx, (creds = cli_credentials_get_netlogon_creds(machine_credentials)), "");
@ -3636,17 +3638,6 @@ static bool test_SamLogon(struct torture_context *tctx,
} }
E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash); E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
netlogon_creds_aes_encrypt(creds, pinfo.lmpassword.hash, 16);
netlogon_creds_aes_encrypt(creds, pinfo.ntpassword.hash, 16);
} else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
} else {
netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
}
pinfo.identity_info = identity; pinfo.identity_info = identity;
logon.password = &pinfo; logon.password = &pinfo;
@ -3693,6 +3684,14 @@ static bool test_SamLogon(struct torture_context *tctx,
r.in.validation_level = 6; r.in.validation_level = 6;
dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
status = netlogon_creds_encrypt_samlogon_logon(creds,
r.in.logon_level,
r.in.logon,
auth_type,
auth_level);
torture_assert_ntstatus_ok(tctx, status, "encrypt_samlogon_logon");
torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r), torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
"netr_LogonSamLogonEx failed"); "netr_LogonSamLogonEx failed");
if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) { if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {

View File

@ -32,6 +32,7 @@
#include "libcli/security/security.h" #include "libcli/security/security.h"
#include "system/filesys.h" #include "system/filesys.h"
#include "param/param.h" #include "param/param.h"
#include "param/loadparm.h"
#include "librpc/rpc/dcerpc_proto.h" #include "librpc/rpc/dcerpc_proto.h"
#include "libcli/composite/composite.h" #include "libcli/composite/composite.h"
#include "lib/events/events.h" #include "lib/events/events.h"
@ -63,6 +64,7 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
struct netr_SamBaseInfo *base = NULL; struct netr_SamBaseInfo *base = NULL;
const char *crypto_alg = ""; const char *crypto_alg = "";
bool can_do_validation_6 = true; bool can_do_validation_6 = true;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
if (lpcfg_client_lanman_auth(tctx->lp_ctx)) { if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
@ -136,7 +138,7 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
} }
} }
dcerpc_binding_handle_auth_info(b, NULL, &auth_level); dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
r.in.validation_level = 6; r.in.validation_level = 6;
@ -207,13 +209,12 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
dump_data(1, base->key.key, 16); dump_data(1, base->key.key, 16);
dump_data(1, base->LMSessKey.key, 8); dump_data(1, base->LMSessKey.key, 8);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { status = netlogon_creds_decrypt_samlogon_validation(creds,
netlogon_creds_aes_decrypt(creds, base->key.key, 16); r.in.validation_level,
netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8); r.out.validation,
} else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { auth_type,
netlogon_creds_arcfour_crypt(creds, base->key.key, 16); auth_level);
netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8); torture_assert_ntstatus_ok(tctx, status, "decrypt_samlogon_validation");
}
DEBUG(1,("decrypted keys validation_level %d\n", DEBUG(1,("decrypted keys validation_level %d\n",
validation_levels[i])); validation_levels[i]));
@ -280,6 +281,7 @@ static bool test_netlogon_ex_bug14932(struct dcerpc_pipe *p,
struct netr_SamBaseInfo *base = NULL; struct netr_SamBaseInfo *base = NULL;
const char *crypto_alg = ""; const char *crypto_alg = "";
bool can_do_validation_6 = true; bool can_do_validation_6 = true;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
flags |= CLI_CRED_NTLMv2_AUTH; flags |= CLI_CRED_NTLMv2_AUTH;
@ -345,7 +347,7 @@ static bool test_netlogon_ex_bug14932(struct dcerpc_pipe *p,
} }
} }
dcerpc_binding_handle_auth_info(b, NULL, &auth_level); dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
r.in.validation_level = 6; r.in.validation_level = 6;
@ -416,13 +418,12 @@ static bool test_netlogon_ex_bug14932(struct dcerpc_pipe *p,
dump_data(1, base->key.key, 16); dump_data(1, base->key.key, 16);
dump_data(1, base->LMSessKey.key, 8); dump_data(1, base->LMSessKey.key, 8);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { status = netlogon_creds_decrypt_samlogon_validation(creds,
netlogon_creds_aes_decrypt(creds, base->key.key, 16); r.in.validation_level,
netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8); r.out.validation,
} else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { auth_type,
netlogon_creds_arcfour_crypt(creds, base->key.key, 16); auth_level);
netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8); torture_assert_ntstatus_ok(tctx, status, "decrypt_samlogon_validation");
}
DEBUG(1,("decrypted keys validation_level %d\n", DEBUG(1,("decrypted keys validation_level %d\n",
validation_levels[i])); validation_levels[i]));
@ -595,6 +596,7 @@ static bool test_schannel(struct torture_context *tctx,
struct netlogon_creds_CredentialState *creds; struct netlogon_creds_CredentialState *creds;
struct cli_credentials *credentials; struct cli_credentials *credentials;
enum dcerpc_transport_t transport; enum dcerpc_transport_t transport;
uint32_t requested_flags;
join_ctx = torture_join_domain(tctx, join_ctx = torture_join_domain(tctx,
talloc_asprintf(tctx, "%s%d", TEST_MACHINE_NAME, i), talloc_asprintf(tctx, "%s%d", TEST_MACHINE_NAME, i),
@ -634,8 +636,26 @@ static bool test_schannel(struct torture_context *tctx,
creds = cli_credentials_get_netlogon_creds(credentials); creds = cli_credentials_get_netlogon_creds(credentials);
torture_assert(tctx, (creds != NULL), "schannel creds"); torture_assert(tctx, (creds != NULL), "schannel creds");
requested_flags = NETLOGON_NEG_AUTH2_FLAGS;
if (dcerpc_flags & DCERPC_SCHANNEL_128) {
requested_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
}
if (dcerpc_flags & DCERPC_SCHANNEL_AES) {
requested_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
requested_flags |= NETLOGON_NEG_SUPPORTS_AES;
}
if (dcerpc_flags & DCERPC_SCHANNEL_AUTO) {
requested_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
requested_flags |= NETLOGON_NEG_SUPPORTS_AES;
}
if (lpcfg_weak_crypto(tctx->lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
requested_flags &= ~NETLOGON_NEG_ARCFOUR;
requested_flags |= NETLOGON_NEG_SUPPORTS_AES;
}
/* checks the capabilities */ /* checks the capabilities */
torture_assert(tctx, test_netlogon_capabilities(p_netlogon, tctx, credentials, creds), torture_assert(tctx,
test_netlogon_capabilities(p_netlogon, tctx, credentials, requested_flags, creds),
"Failed to process schannel secured capability ops (on fresh connection)"); "Failed to process schannel secured capability ops (on fresh connection)");
/* do a couple of logins */ /* do a couple of logins */
@ -723,8 +743,26 @@ static bool test_schannel(struct torture_context *tctx,
tctx, &p_netlogon2); tctx, &p_netlogon2);
torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection"); torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
requested_flags = NETLOGON_NEG_AUTH2_FLAGS;
if (dcerpc_flags & DCERPC_SCHANNEL_128) {
requested_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
}
if (dcerpc_flags & DCERPC_SCHANNEL_AES) {
requested_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
requested_flags |= NETLOGON_NEG_SUPPORTS_AES;
}
if (dcerpc_flags & DCERPC_SCHANNEL_AUTO) {
requested_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
requested_flags |= NETLOGON_NEG_SUPPORTS_AES;
}
if (lpcfg_weak_crypto(tctx->lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
requested_flags &= ~NETLOGON_NEG_ARCFOUR;
requested_flags |= NETLOGON_NEG_SUPPORTS_AES;
}
/* checks the capabilities */ /* checks the capabilities */
torture_assert(tctx, test_netlogon_capabilities(p_netlogon2, tctx, credentials, creds), torture_assert(tctx,
test_netlogon_capabilities(p_netlogon2, tctx, credentials, requested_flags, creds),
"Failed to process schannel secured capability ops (on fresh connection)"); "Failed to process schannel secured capability ops (on fresh connection)");
/* Try the schannel-only SamLogonEx operation */ /* Try the schannel-only SamLogonEx operation */
@ -1252,6 +1290,8 @@ bool torture_rpc_schannel_bench1(struct torture_context *torture)
struct dcerpc_pipe *net_pipe; struct dcerpc_pipe *net_pipe;
struct netr_Authenticator credential, return_authenticator; struct netr_Authenticator credential, return_authenticator;
struct samr_Password new_password; struct samr_Password new_password;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
status = dcerpc_pipe_connect_b(s, &net_pipe, s->b, status = dcerpc_pipe_connect_b(s, &net_pipe, s->b,
&ndr_table_netlogon, &ndr_table_netlogon,
@ -1276,7 +1316,14 @@ bool torture_rpc_schannel_bench1(struct torture_context *torture)
creds_state = cli_credentials_get_netlogon_creds( creds_state = cli_credentials_get_netlogon_creds(
s->wks_creds1); s->wks_creds1);
netlogon_creds_des_encrypt(creds_state, &new_password); dcerpc_binding_handle_auth_info(net_pipe->binding_handle,
&auth_type,
&auth_level);
status = netlogon_creds_encrypt_samr_Password(creds_state,
&new_password,
auth_type,
auth_level);
torture_assert_ntstatus_ok(torture, status, "encrypt_samr_Password");
netlogon_creds_client_authenticator(creds_state, &credential); netlogon_creds_client_authenticator(creds_state, &credential);
torture_assert_ntstatus_ok(torture, dcerpc_netr_ServerPasswordSet_r(net_pipe->binding_handle, torture, &pwset), torture_assert_ntstatus_ok(torture, dcerpc_netr_ServerPasswordSet_r(net_pipe->binding_handle, torture, &pwset),