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

Compare commits

...

71 Commits

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

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 f340dce654)

Autobuild-User(v4-20-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-20-test): Wed Nov 13 11:36:37 UTC 2024 on atb-devel-224
2024-11-13 11:36:37 +00:00
Stefan Metzmacher
aa4add0053 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 7a5ad9f64a)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
21e9355630 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 8edbdd65ef)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
75e62cc19b 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 132629ee3a)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
77a02d6e79 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 1a5984ac63)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
1de6cffa68 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 45faf6c35a)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
0c61920c88 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 2956c7eb3c)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
200fc14fb8 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 7b02fb5014)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
270499b1c9 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 131f5c0b25)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
6b32dcf6ea 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 834197dafe)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
dc7ab826ef 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 f1c1b8661a)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
3aefe6a54a 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 7a7cb0d042)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
cb5ed3bf75 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 a359b4139c)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
27ae047ba5 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 550d20fd3d)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
5792c2ce9d 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 172ce406d4)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
3768134cae 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 2d7a47a175)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
78ff2be859 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 a177d15c87)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
c9c23c1a96 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 1666d1d74d)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
856aaaf881 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 e92d0509d6)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
8f035b8022 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 2bd77ff731)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
b85a1d526c 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 285ec9ecde)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
a03fb78413 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 1edcd5df80)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
10da7c803b 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 e7d57fc6e9)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
254440c71a 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 fac378485f)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
7f1db18b44 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 ea792fa342)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
a616dcc89d 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 b8681c1657)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
536080d084 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 8eb95a155d)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
1aa11e2af6 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 851a9b18ec)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
838e5257d2 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 3d4ea276bd)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
91154188e2 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 a56356e399)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
1637e23c35 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 de8de55a5f)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
86ebe5e4e6 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 62afadb3eb)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
447a9c782b 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 01577b93cb)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
6a50b1aea3 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 e4132c492d)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
6bd5d4d204 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 f92def2f94)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
c3b5697dd2 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 e9767315cf)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
4419fc6c48 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 3792fe3728)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
bc8dcaa109 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 17394ed7bb)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
1debb3d374 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 8b972fea09)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
4aa40fd5be 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 498fc88c15)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
fa49a8ad2b 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 fd4b027511)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
1acd16876b 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 484a046d8e)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
5c74014ae8 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 dfbc5e5a19)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
71c0e18766 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 a9308c490c)
2024-11-13 10:39:12 +00:00
Stefan Metzmacher
0b85452df0 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 4533afc9e1)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
6d117ea4c8 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 88a84d9330)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
9ff331f9b9 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 453587fbc1)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
02bc35458b 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 518f57b93b)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
878482663e 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 c2ef866fca)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
dcb07d4504 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 2e8949495f)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
ca97536d7d 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 eda3728a40)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
a3b8c49a99 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 c9eaf5e22d)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
8d4d6fc8d2 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 7f478656dc)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
adcd2436bf 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 d174b6595a)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
d0b2469385 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 0b6ac4b082)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
620065e13d 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 25294685b1)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
a73571c074 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 69b0cbd13d)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
20661a24ff 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 24de5d1cbd)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
560aa3e3db 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 25a2105ca7)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
3a33457f23 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 276137e950)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
28a7372c58 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 3da40f1c68)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
84f4313aa9 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 a9040c8ce7)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
b3fd6d36e9 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 69cb9aea67)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
1dcb72dcac 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 cf0e07a3d2)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
e476b15d1b 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 86176598ee)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
92fc4f2b68 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 a0bc372dee)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
41a60326a3 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 e5bc5ee3e0)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
e39ca0ed85 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 b27661f832)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
f467f83fbd 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 3dcbc8eea5)
2024-11-13 10:39:11 +00:00
Stefan Metzmacher
e463774b7c 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 36310650ee)
2024-11-13 10:39:11 +00:00
Jo Sutton
568ebd48af s4:rpc_server: Make some arrays static
Signed-off-by: Jo Sutton <josutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
(cherry picked from commit beaeeaff50)

Backported for https://bugzilla.samba.org/show_bug.cgi?id=15425
2024-11-13 10:39:11 +00:00
29 changed files with 2072 additions and 739 deletions

View File

@ -1024,9 +1024,11 @@ static PyObject *py_creds_get_aes256_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;
@ -1045,9 +1047,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);
@ -1096,6 +1107,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;
@ -1611,6 +1684,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

@ -51,6 +51,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,
@ -3685,10 +3686,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()
@ -3698,11 +3701,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

@ -886,6 +886,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;
@ -902,7 +903,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 |
@ -912,20 +912,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.
@ -940,12 +942,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:
@ -961,6 +958,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 */
@ -1000,7 +1010,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",
@ -1010,12 +1022,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);
@ -1032,7 +1038,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;
} }
@ -1301,6 +1307,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__));
@ -1325,11 +1336,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;
} }
@ -1343,7 +1358,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;
} }
@ -1360,6 +1375,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;
@ -1368,6 +1384,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,
@ -1385,6 +1405,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",
@ -1395,15 +1416,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;
@ -1505,7 +1521,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;
@ -1745,7 +1761,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;
} }
@ -1928,7 +1946,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;
} }
@ -2297,12 +2317,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
@ -2330,7 +2345,15 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
return status; return status;
} }
r->out.capabilities->server_capabilities = creds->negotiate_flags; switch (r->in.query_level) {
case 1:
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;
} }
@ -2724,7 +2747,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;
@ -2741,7 +2766,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;
} }
@ -2755,7 +2783,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;
} }
@ -2780,6 +2811,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 */
@ -2856,8 +2891,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;
} }
@ -2893,6 +2929,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

@ -2646,7 +2646,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

@ -387,14 +387,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)
@ -404,15 +413,18 @@ 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;
int num_records; int num_records;
struct ldb_message **msgs; struct ldb_message **msgs;
struct ldb_message *tdo_msg = NULL;
NTSTATUS nt_status; NTSTATUS nt_status;
const char *attrs[] = {"unicodePwd", "userAccountControl", static const char *attrs[] = {"unicodePwd",
"objectSid", "samAccountName", NULL}; "userAccountControl",
"objectSid",
"samAccountName",
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);
@ -494,14 +506,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:
@ -535,13 +553,10 @@ 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",
const char * const tdo_attrs[] = { "trustAttributes",
"trustAuthIncoming", "flatName",
"trustAttributes", NULL};
"flatName",
NULL
};
char *encoded_name = NULL; char *encoded_name = NULL;
size_t len; size_t len;
const char *flatname = NULL; const char *flatname = NULL;
@ -606,22 +621,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(
@ -742,61 +741,29 @@ 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);
if (!NT_STATUS_IS_OK(nt_status)) {
return NT_STATUS_ACCESS_DENIED;
}
} }
if (curNtHash == NULL) { *sid = samdb_result_dom_sid(mem_ctx, msgs[0], "objectSid");
if (*sid == NULL) {
return NT_STATUS_ACCESS_DENIED; return NT_STATUS_ACCESS_DENIED;
} }
if (!challenge_valid) { nt_status = auth_fn(dce_call,
DEBUG(1, ("No challenge requested by client [%s/%s], " challenge_valid ? &challenge : NULL,
"cannot authenticate\n", r,
log_escape(mem_ctx, r->in.computer_name), client_flags,
log_escape(mem_ctx, r->in.account_name))); *sid,
return NT_STATUS_ACCESS_DENIED; negotiate_flags,
msgs[0],
tdo_msg,
mem_ctx,
&creds);
if (!NT_STATUS_IS_OK(nt_status)) {
ZERO_STRUCTP(r->out.return_credentials);
return nt_status;
} }
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,
creds); creds);
@ -811,6 +778,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
@ -921,8 +1007,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,
@ -930,18 +1021,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,
@ -958,6 +1053,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;
@ -967,6 +1063,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,
@ -974,6 +1074,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) {
@ -983,16 +1084,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;
} }
@ -1082,7 +1177,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,
@ -1287,7 +1382,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) {
@ -1324,7 +1421,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:
@ -1583,9 +1680,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",
@ -2381,12 +2485,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
@ -2412,7 +2511,15 @@ static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_c
} }
NT_STATUS_NOT_OK_RETURN(status); NT_STATUS_NOT_OK_RETURN(status);
r->out.capabilities->server_capabilities = creds->negotiate_flags; switch (r->in.query_level) {
case 1:
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;
} }
@ -2618,17 +2725,18 @@ 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 char * const trusts_attrs[] = { const struct dom_sid *client_sid = NULL;
"securityIdentifier", static const char *const trusts_attrs[] = {"securityIdentifier",
"flatName", "flatName",
"trustPartner", "trustPartner",
"trustAttributes", "trustAttributes",
"trustDirection", "trustDirection",
"trustType", "trustType",
NULL NULL};
}; static const char *const attrs2[] = {"sAMAccountName",
const char * const attrs2[] = { "sAMAccountName", "dNSHostName", "dNSHostName",
"msDS-SupportedEncryptionTypes", NULL }; "msDS-SupportedEncryptionTypes",
NULL};
const char *sam_account_name, *old_dns_hostname; const char *sam_account_name, *old_dns_hostname;
struct ldb_context *sam_ctx; struct ldb_context *sam_ctx;
const struct GUID *our_domain_guid = NULL; const struct GUID *our_domain_guid = NULL;
@ -2666,6 +2774,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);
@ -2682,7 +2791,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. */
@ -2991,14 +3100,18 @@ 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)
{ {
const char *rodc_attrs[] = { "msDS-NeverRevealGroup", static const char *rodc_attrs[] = {"msDS-NeverRevealGroup",
"msDS-RevealOnDemandGroup", "msDS-RevealOnDemandGroup",
"userAccountControl", "userAccountControl",
NULL }; NULL};
const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL }; static const char *obj_attrs[] = {"tokenGroups",
"objectSid",
"UserAccountControl",
"msDS-KrbTgtLinkBL",
NULL};
struct ldb_dn *rodc_dn; struct ldb_dn *rodc_dn;
int ret; int ret;
struct ldb_result *rodc_res = NULL, *obj_res = NULL; struct ldb_result *rodc_res = NULL, *obj_res = NULL;
@ -3042,11 +3155,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,
@ -3056,6 +3174,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:
@ -3078,15 +3197,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;
} }
@ -3127,7 +3243,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)));
@ -3938,9 +4054,13 @@ static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
{ {
struct ldb_dn *system_dn; struct ldb_dn *system_dn;
struct ldb_message **dom_res = NULL; struct ldb_message **dom_res = NULL;
const char *trust_attrs[] = { "flatname", "trustPartner", static const char *trust_attrs[] = {"flatname",
"securityIdentifier", "trustDirection", "trustPartner",
"trustType", "trustAttributes", NULL }; "securityIdentifier",
"trustDirection",
"trustType",
"trustAttributes",
NULL};
uint32_t n; uint32_t n;
int i; int i;
int ret; int ret;
@ -4408,6 +4528,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;
const char * const attrs[] = { const char * const attrs[] = {
"unicodePwd", "unicodePwd",
@ -4429,6 +4550,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);
@ -4442,6 +4567,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 */
@ -4462,7 +4588,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;
} }
@ -4545,14 +4671,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;
} }
@ -4617,6 +4749,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,
@ -4625,6 +4758,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;
@ -4638,7 +4772,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;
@ -4667,6 +4801,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

@ -533,6 +533,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");
@ -608,8 +610,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

@ -3064,6 +3064,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");
@ -3089,6 +3090,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");
@ -4481,6 +4483,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");
@ -4636,15 +4640,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");
@ -4969,6 +5054,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)) {
@ -5000,7 +5088,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]));
@ -276,6 +277,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;
@ -341,7 +343,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;
@ -412,13 +414,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]));
@ -591,6 +592,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),
@ -630,8 +632,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 */
@ -719,8 +739,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 */
@ -1248,6 +1286,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,
@ -1272,7 +1312,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),