mirror of
https://github.com/samba-team/samba.git
synced 2025-01-03 01:18:10 +03:00
Compare commits
71 Commits
cc3a119585
...
7b4629ef84
Author | SHA1 | Date | |
---|---|---|---|
|
7b4629ef84 | ||
|
aa4add0053 | ||
|
21e9355630 | ||
|
75e62cc19b | ||
|
77a02d6e79 | ||
|
1de6cffa68 | ||
|
0c61920c88 | ||
|
200fc14fb8 | ||
|
270499b1c9 | ||
|
6b32dcf6ea | ||
|
dc7ab826ef | ||
|
3aefe6a54a | ||
|
cb5ed3bf75 | ||
|
27ae047ba5 | ||
|
5792c2ce9d | ||
|
3768134cae | ||
|
78ff2be859 | ||
|
c9c23c1a96 | ||
|
856aaaf881 | ||
|
8f035b8022 | ||
|
b85a1d526c | ||
|
a03fb78413 | ||
|
10da7c803b | ||
|
254440c71a | ||
|
7f1db18b44 | ||
|
a616dcc89d | ||
|
536080d084 | ||
|
1aa11e2af6 | ||
|
838e5257d2 | ||
|
91154188e2 | ||
|
1637e23c35 | ||
|
86ebe5e4e6 | ||
|
447a9c782b | ||
|
6a50b1aea3 | ||
|
6bd5d4d204 | ||
|
c3b5697dd2 | ||
|
4419fc6c48 | ||
|
bc8dcaa109 | ||
|
1debb3d374 | ||
|
4aa40fd5be | ||
|
fa49a8ad2b | ||
|
1acd16876b | ||
|
5c74014ae8 | ||
|
71c0e18766 | ||
|
0b85452df0 | ||
|
6d117ea4c8 | ||
|
9ff331f9b9 | ||
|
02bc35458b | ||
|
878482663e | ||
|
dcb07d4504 | ||
|
ca97536d7d | ||
|
a3b8c49a99 | ||
|
8d4d6fc8d2 | ||
|
adcd2436bf | ||
|
d0b2469385 | ||
|
620065e13d | ||
|
a73571c074 | ||
|
20661a24ff | ||
|
560aa3e3db | ||
|
3a33457f23 | ||
|
28a7372c58 | ||
|
84f4313aa9 | ||
|
b3fd6d36e9 | ||
|
1dcb72dcac | ||
|
e476b15d1b | ||
|
92fc4f2b68 | ||
|
41a60326a3 | ||
|
e39ca0ed85 | ||
|
f467f83fbd | ||
|
e463774b7c | ||
|
568ebd48af |
@ -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,
|
||||
PyObject *args)
|
||||
{
|
||||
DATA_BLOB data = data_blob_null;
|
||||
struct cli_credentials *creds = 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;
|
||||
PyObject *py_cp = Py_None;
|
||||
|
||||
@ -1045,9 +1047,18 @@ static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self,
|
||||
/* pytalloc_get_type sets TypeError */
|
||||
return NULL;
|
||||
}
|
||||
data.length = sizeof(struct netr_CryptPassword);
|
||||
data.data = (uint8_t *)pwd;
|
||||
status = netlogon_creds_session_encrypt(creds->netlogon_creds, data);
|
||||
|
||||
memcpy(spwd.data, pwd->data, 512);
|
||||
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);
|
||||
|
||||
@ -1096,6 +1107,68 @@ static PyObject *py_creds_encrypt_samr_password(PyObject *self,
|
||||
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)
|
||||
{
|
||||
enum smb_signing_setting signing_state;
|
||||
@ -1611,6 +1684,17 @@ static PyMethodDef py_creds_methods[] = {
|
||||
"the negotiated encryption algorithm in place\n"
|
||||
"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_meth = py_creds_get_smb_signing,
|
||||
|
@ -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
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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
|
||||
*/
|
||||
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)
|
||||
{
|
||||
int rc;
|
||||
@ -473,6 +473,58 @@ NTSTATUS netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds
|
||||
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
|
||||
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 samr_Password *machine_password,
|
||||
struct netr_Credential *initial_credential,
|
||||
uint32_t client_requested_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;
|
||||
|
||||
creds = netlogon_creds_alloc(mem_ctx,
|
||||
client_account,
|
||||
client_computer_name,
|
||||
secure_channel_type,
|
||||
client_requested_flags,
|
||||
NULL, /* client_sid */
|
||||
negotiate_flags);
|
||||
if (!creds) {
|
||||
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("Server chall", server_challenge->data, sizeof(server_challenge->data));
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
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
|
||||
*/
|
||||
bool netlogon_creds_client_check(struct netlogon_creds_CredentialState *creds,
|
||||
const struct netr_Credential *received_credentials)
|
||||
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)
|
||||
{
|
||||
if (!received_credentials ||
|
||||
!mem_equal_const_time(received_credentials->data, creds->server.data, 8)) {
|
||||
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 true;
|
||||
}
|
||||
|
||||
@ -676,20 +722,25 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me
|
||||
const struct samr_Password *machine_password,
|
||||
const struct netr_Credential *credentials_in,
|
||||
struct netr_Credential *credentials_out,
|
||||
uint32_t client_requested_flags,
|
||||
const struct dom_sid *client_sid,
|
||||
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;
|
||||
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) {
|
||||
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("Server chall", server_challenge->data, sizeof(server_challenge->data));
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
status = netlogon_creds_init_hmac_sha256(creds,
|
||||
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,
|
||||
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;
|
||||
|
||||
@ -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,
|
||||
uint16_t validation_level,
|
||||
union netr_Validation *validation,
|
||||
enum dcerpc_AuthType auth_type,
|
||||
enum dcerpc_AuthLevel auth_level,
|
||||
bool do_encrypt)
|
||||
{
|
||||
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,
|
||||
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,
|
||||
validation_level,
|
||||
validation,
|
||||
auth_type,
|
||||
auth_level,
|
||||
false);
|
||||
}
|
||||
|
||||
NTSTATUS netlogon_creds_encrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds,
|
||||
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,
|
||||
validation_level,
|
||||
validation,
|
||||
auth_type,
|
||||
auth_level,
|
||||
true);
|
||||
}
|
||||
|
||||
static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
|
||||
enum netr_LogonInfoClass level,
|
||||
union netr_LogonLevel *logon,
|
||||
enum dcerpc_AuthType auth_type,
|
||||
enum dcerpc_AuthLevel auth_level,
|
||||
bool do_encrypt)
|
||||
{
|
||||
NTSTATUS status;
|
||||
@ -1082,6 +1136,7 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden
|
||||
}
|
||||
} else {
|
||||
/* Using DES to verify kerberos tickets makes no sense */
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
@ -1190,9 +1407,7 @@ struct netlogon_creds_CredentialState *netlogon_creds_copy(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
creds->sequence = creds_in->sequence;
|
||||
creds->negotiate_flags = creds_in->negotiate_flags;
|
||||
creds->secure_channel_type = creds_in->secure_channel_type;
|
||||
*creds = *creds_in;
|
||||
|
||||
creds->computer_name = talloc_strdup(creds, creds_in->computer_name);
|
||||
if (!creds->computer_name) {
|
||||
@ -1205,18 +1420,15 @@ struct netlogon_creds_CredentialState *netlogon_creds_copy(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (creds_in->sid) {
|
||||
creds->sid = dom_sid_dup(creds, creds_in->sid);
|
||||
if (!creds->sid) {
|
||||
if (creds_in->ex != NULL) {
|
||||
creds->ex = talloc_zero(creds,
|
||||
struct netlogon_creds_CredentialState_extra_info);
|
||||
if (creds->ex == NULL) {
|
||||
talloc_free(creds);
|
||||
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;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#ifndef __LIBCLI_AUTH_H__
|
||||
#define __LIBCLI_AUTH_H__
|
||||
|
||||
#include "librpc/gen_ndr/dcerpc.h"
|
||||
#include "librpc/gen_ndr/netlogon.h"
|
||||
#include "librpc/gen_ndr/wkssvc.h"
|
||||
#include "librpc/gen_ndr/schannel.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,10 +16,6 @@
|
||||
bool netlogon_creds_is_random_challenge(const 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,
|
||||
struct samr_Password *pass);
|
||||
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 samr_Password *machine_password,
|
||||
struct netr_Credential *initial_credential,
|
||||
uint32_t client_requested_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
|
||||
netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds,
|
||||
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,
|
||||
const struct netr_Credential *received_credentials);
|
||||
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 netr_Credential *credentials_in,
|
||||
struct netr_Credential *credentials_out,
|
||||
uint32_t client_requested_flags,
|
||||
const struct dom_sid *client_sid,
|
||||
uint32_t negotiate_flags);
|
||||
NTSTATUS netlogon_creds_server_step_check(struct netlogon_creds_CredentialState *creds,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
enum netr_LogonInfoClass level,
|
||||
const union netr_LogonLevel *in);
|
||||
|
@ -37,6 +37,8 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
|
||||
const char *computer_name,
|
||||
struct netr_Authenticator *received_authenticator,
|
||||
struct netr_Authenticator *return_authenticator,
|
||||
enum dcerpc_AuthType auth_type,
|
||||
enum dcerpc_AuthLevel auth_level,
|
||||
struct netlogon_creds_CredentialState **creds_out);
|
||||
|
||||
NTSTATUS schannel_get_challenge(struct loadparm_context *lp_ctx,
|
||||
|
@ -88,6 +88,10 @@ NTSTATUS schannel_store_session_key_tdb(struct db_context *db_sc,
|
||||
char *name_upper;
|
||||
NTSTATUS status;
|
||||
|
||||
if (creds->ex == NULL) {
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (strlen(creds->computer_name) > 15) {
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
if (creds->ex == NULL) {
|
||||
status = NT_STATUS_INTERNAL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
DEBUG(3,("schannel_fetch_session_key_tdb: restored schannel info key %s\n",
|
||||
keystr));
|
||||
|
||||
@ -560,6 +569,8 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
|
||||
const char *computer_name,
|
||||
struct netr_Authenticator *received_authenticator,
|
||||
struct netr_Authenticator *return_authenticator,
|
||||
enum dcerpc_AuthType auth_type,
|
||||
enum dcerpc_AuthLevel auth_level,
|
||||
struct netlogon_creds_CredentialState **creds_out)
|
||||
{
|
||||
TALLOC_CTX *tmpctx;
|
||||
@ -619,7 +630,9 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
|
||||
|
||||
status = netlogon_creds_server_step_check(creds,
|
||||
received_authenticator,
|
||||
return_authenticator);
|
||||
return_authenticator,
|
||||
auth_type,
|
||||
auth_level);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto done;
|
||||
}
|
||||
|
@ -1036,7 +1036,8 @@ interface netlogon
|
||||
NETLOGON_NEG_SUPPORTS_AES_SHA2 = 0x00400000,
|
||||
NETLOGON_NEG_SUPPORTS_AES = 0x01000000,
|
||||
NETLOGON_NEG_AUTHENTICATED_RPC_LSASS = 0x20000000,
|
||||
NETLOGON_NEG_AUTHENTICATED_RPC = 0x40000000
|
||||
NETLOGON_NEG_AUTHENTICATED_RPC = 0x40000000,
|
||||
NETLOGON_NEG_SUPPORTS_KERBEROS_AUTH = 0x80000000
|
||||
} netr_NegotiateFlags;
|
||||
|
||||
const uint32 NETLOGON_NEG_128BIT = NETLOGON_NEG_STRONG_KEYS;
|
||||
@ -1236,7 +1237,7 @@ interface netlogon
|
||||
/* Function 0x15 */
|
||||
typedef [switch_type(uint32)] union {
|
||||
[case(1)] netr_NegotiateFlags server_capabilities;
|
||||
[case(2)] netr_NegotiateFlags server_capabilities;
|
||||
[case(2)] netr_NegotiateFlags requested_flags;
|
||||
} netr_Capabilities;
|
||||
|
||||
NTSTATUS netr_LogonGetCapabilities(
|
||||
@ -1885,4 +1886,32 @@ interface netlogon
|
||||
[in] uint32 dns_ttl,
|
||||
[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
|
||||
);
|
||||
}
|
||||
|
@ -14,6 +14,77 @@ interface schannel
|
||||
{
|
||||
/* 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 {
|
||||
netr_NegotiateFlags negotiate_flags;
|
||||
uint8 session_key[16];
|
||||
@ -25,7 +96,7 @@ interface schannel
|
||||
[string,charset(UTF8)] uint8 computer_name[];
|
||||
[string,charset(UTF8)] uint8 account_name[];
|
||||
dom_sid *sid;
|
||||
} netlogon_creds_CredentialState;
|
||||
} netlogon_creds_CredentialState_legacy;
|
||||
|
||||
/* This is used in the schannel_store.tdb */
|
||||
typedef [public] struct {
|
||||
|
@ -578,6 +578,14 @@ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
|
||||
return; \
|
||||
} 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
|
||||
and giving the right fault code if invalid */
|
||||
#define DCESRV_CHECK_HANDLE(h) do {if (!(h)) DCESRV_FAULT(DCERPC_FAULT_CONTEXT_MISMATCH); } while (0)
|
||||
|
@ -70,7 +70,7 @@ static NTSTATUS dcesrv_netr_check_schannel_get_state(struct dcesrv_call_state *d
|
||||
DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
|
||||
struct dcesrv_netr_check_schannel_state);
|
||||
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;
|
||||
}
|
||||
if (s->auth_type != auth_type) {
|
||||
@ -92,7 +92,7 @@ new_state:
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
s->account_sid = *creds->sid;
|
||||
s->account_sid = creds->ex->client_sid;
|
||||
s->auth_type = auth_type;
|
||||
s->auth_level = auth_level;
|
||||
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,
|
||||
received_authenticator,
|
||||
return_authenticator,
|
||||
auth_type,
|
||||
auth_level,
|
||||
&creds);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
ZERO_STRUCTP(return_authenticator);
|
||||
|
@ -51,6 +51,7 @@ from samba.credentials import (
|
||||
from samba.crypto import des_crypt_blob_16, md4_hash_blob
|
||||
from samba.dcerpc import (
|
||||
claims,
|
||||
dcerpc,
|
||||
drsblobs,
|
||||
drsuapi,
|
||||
krb5ccache,
|
||||
@ -3685,10 +3686,12 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest):
|
||||
workstation = domain_joined_mach_creds.get_username()
|
||||
|
||||
# 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]',
|
||||
self.get_lp(),
|
||||
domain_joined_mach_creds)
|
||||
auth_type = dcerpc.DCERPC_AUTH_TYPE_SCHANNEL
|
||||
auth_level = dcerpc.DCERPC_AUTH_LEVEL_PRIVACY
|
||||
|
||||
if logon_type == netlogon.NetlogonInteractiveInformation:
|
||||
logon = netlogon.netr_PasswordInfo()
|
||||
@ -3698,11 +3701,14 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest):
|
||||
|
||||
nt_pass = samr.Password()
|
||||
nt_pass.hash = list(creds.get_nt_hash())
|
||||
domain_joined_mach_creds.encrypt_samr_password(nt_pass)
|
||||
|
||||
logon.lmpassword = lm_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:
|
||||
computername = ntlmssp.AV_PAIR()
|
||||
computername.AvId = ntlmssp.MsvAvNbComputerName
|
||||
|
@ -387,6 +387,7 @@ again:
|
||||
if (!retry && NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
|
||||
DBG_DEBUG("Retrying with serverauthenticate\n");
|
||||
TALLOC_FREE(lck);
|
||||
force_reauth = true;
|
||||
retry = true;
|
||||
goto again;
|
||||
}
|
||||
|
@ -886,6 +886,7 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
|
||||
/* r->in.negotiate_flags is an aliased pointer to r->out.negotiate_flags,
|
||||
* so use a copy to avoid destroying the client values. */
|
||||
uint32_t in_neg_flags = *r->in.negotiate_flags;
|
||||
uint32_t neg_flags = 0;
|
||||
const char *fn;
|
||||
struct loadparm_context *lp_ctx = p->dce_call->conn->dce_ctx->lp_ctx;
|
||||
struct dom_sid sid;
|
||||
@ -902,7 +903,6 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
|
||||
* an error or not.
|
||||
*/
|
||||
|
||||
/* 0x000001ff */
|
||||
srv_flgs = NETLOGON_NEG_ACCOUNT_LOCKOUT |
|
||||
NETLOGON_NEG_PERSISTENT_SAMREPL |
|
||||
NETLOGON_NEG_ARCFOUR |
|
||||
@ -912,20 +912,22 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
|
||||
NETLOGON_NEG_MULTIPLE_SIDS |
|
||||
NETLOGON_NEG_REDO |
|
||||
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) {
|
||||
srv_flgs |= NETLOGON_NEG_STRONG_KEYS;
|
||||
}
|
||||
|
||||
if (in_neg_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
srv_flgs |= NETLOGON_NEG_SUPPORTS_AES;
|
||||
}
|
||||
|
||||
if (in_neg_flags & NETLOGON_NEG_SCHANNEL) {
|
||||
srv_flgs |= NETLOGON_NEG_SCHANNEL;
|
||||
}
|
||||
/*
|
||||
* With SAMBA_WEAK_CRYPTO_DISALLOWED we will return DOWNGRADE_DETECTED
|
||||
* with negotiate_flags = 0 below, 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 srv_flgs...
|
||||
*/
|
||||
|
||||
/*
|
||||
* Support authentication of trusted domains.
|
||||
@ -940,12 +942,7 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
|
||||
NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
neg_flags = in_neg_flags & srv_flgs;
|
||||
|
||||
switch (dce_call->pkt.u.request.opnum) {
|
||||
case NDR_NETR_SERVERAUTHENTICATE:
|
||||
@ -961,6 +958,19 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
|
||||
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: */
|
||||
/* r->in.computer_name */
|
||||
|
||||
@ -1000,7 +1010,9 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
|
||||
&mach_pwd,
|
||||
r->in.credentials,
|
||||
r->out.return_credentials,
|
||||
srv_flgs);
|
||||
in_neg_flags,
|
||||
&sid,
|
||||
neg_flags);
|
||||
if (!creds) {
|
||||
DEBUG(0,("%s: netlogon_creds_server_check failed. Rejecting auth "
|
||||
"request from client %s machine account %s\n",
|
||||
@ -1010,12 +1022,6 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
|
||||
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. */
|
||||
become_root();
|
||||
status = schannel_save_creds_state(p->mem_ctx, lp_ctx, creds);
|
||||
@ -1032,7 +1038,7 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
|
||||
|
||||
out:
|
||||
|
||||
*r->out.negotiate_flags = srv_flgs;
|
||||
*r->out.negotiate_flags = neg_flags;
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1301,6 +1307,11 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
|
||||
size_t i;
|
||||
struct netlogon_creds_CredentialState *creds = NULL;
|
||||
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__));
|
||||
|
||||
@ -1325,11 +1336,15 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
|
||||
TALLOC_FREE(creds);
|
||||
return status;
|
||||
}
|
||||
client_sid = &creds->ex->client_sid;
|
||||
|
||||
DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
|
||||
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)) {
|
||||
return status;
|
||||
}
|
||||
@ -1343,7 +1358,7 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
|
||||
status = netr_set_machine_account_password(p->mem_ctx,
|
||||
session_info,
|
||||
p->msg_ctx,
|
||||
creds->sid,
|
||||
client_sid,
|
||||
&cr);
|
||||
return status;
|
||||
}
|
||||
@ -1360,6 +1375,7 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
|
||||
dcesrv_call_session_info(dce_call);
|
||||
NTSTATUS status;
|
||||
struct netlogon_creds_CredentialState *creds = NULL;
|
||||
const struct dom_sid *client_sid = NULL;
|
||||
DATA_BLOB plaintext = data_blob_null;
|
||||
DATA_BLOB new_password = data_blob_null;
|
||||
size_t confounder_len;
|
||||
@ -1368,6 +1384,10 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
|
||||
struct samr_CryptPassword password_buf;
|
||||
struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}};
|
||||
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();
|
||||
status = dcesrv_netr_creds_server_step_check(p->dce_call,
|
||||
@ -1385,6 +1405,7 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
|
||||
TALLOC_FREE(creds);
|
||||
return status;
|
||||
}
|
||||
client_sid = &creds->ex->client_sid;
|
||||
|
||||
DBG_NOTICE("Server Password Set2 by remote "
|
||||
"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);
|
||||
SIVAL(password_buf.data, 512, r->in.new_password->length);
|
||||
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
status = netlogon_creds_aes_decrypt(creds,
|
||||
password_buf.data,
|
||||
516);
|
||||
} else {
|
||||
status = netlogon_creds_arcfour_crypt(creds,
|
||||
password_buf.data,
|
||||
516);
|
||||
}
|
||||
status = netlogon_creds_decrypt_samr_CryptPassword(creds,
|
||||
&password_buf,
|
||||
auth_type,
|
||||
auth_level);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(creds);
|
||||
return status;
|
||||
@ -1505,7 +1521,7 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
|
||||
status = netr_set_machine_account_password(p->mem_ctx,
|
||||
session_info,
|
||||
p->msg_ctx,
|
||||
creds->sid,
|
||||
client_sid,
|
||||
&cr);
|
||||
TALLOC_FREE(creds);
|
||||
return status;
|
||||
@ -1745,7 +1761,9 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
|
||||
|
||||
status = netlogon_creds_decrypt_samlogon_logon(creds,
|
||||
r->in.logon_level,
|
||||
logon);
|
||||
logon,
|
||||
auth_type,
|
||||
auth_level);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -1928,7 +1946,9 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
|
||||
|
||||
status = netlogon_creds_encrypt_samlogon_validation(creds,
|
||||
r->in.validation_level,
|
||||
r->out.validation);
|
||||
r->out.validation,
|
||||
auth_type,
|
||||
auth_level);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -2297,12 +2317,7 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
/*
|
||||
* Until we know the details behind KB5028166
|
||||
* just return DCERPC_NCA_S_FAULT_INVALID_TAG
|
||||
* like an unpatched Windows Server.
|
||||
*/
|
||||
FALL_THROUGH;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* There would not be a way to marshall the
|
||||
@ -2330,7 +2345,15 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
|
||||
return status;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -2724,7 +2747,9 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
|
||||
const DATA_BLOB *trustAuth_blob,
|
||||
struct netlogon_creds_CredentialState *creds,
|
||||
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;
|
||||
struct trustAuthInOutBlob trustAuth;
|
||||
@ -2741,7 +2766,10 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
|
||||
mdfour(current_pw_enc->hash,
|
||||
trustAuth.current.array[0].AuthInfo.clear.password,
|
||||
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)) {
|
||||
return status;
|
||||
}
|
||||
@ -2755,7 +2783,10 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
|
||||
mdfour(previous_pw_enc->hash,
|
||||
trustAuth.previous.array[0].AuthInfo.clear.password,
|
||||
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)) {
|
||||
return status;
|
||||
}
|
||||
@ -2780,6 +2811,10 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
|
||||
bool trusted;
|
||||
struct netr_TrustInfo *trust_info;
|
||||
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 */
|
||||
|
||||
@ -2856,8 +2891,9 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
|
||||
&td->trust_auth_incoming,
|
||||
creds,
|
||||
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)) {
|
||||
return status;
|
||||
}
|
||||
@ -2893,6 +2929,31 @@ NTSTATUS _netr_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
|
||||
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,
|
||||
* included at the bottom of this 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 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_ */
|
||||
|
@ -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
|
||||
*/
|
||||
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 *obj_msg)
|
||||
{
|
||||
|
@ -2646,7 +2646,7 @@ NTSTATUS dsdb_trust_search_tdo_by_sid(struct ldb_context *sam_ctx,
|
||||
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,
|
||||
struct samr_Password **_current,
|
||||
struct samr_Password **_previous)
|
||||
|
@ -40,6 +40,8 @@ struct schannel_key_state {
|
||||
bool dcerpc_schannel_auto;
|
||||
struct cli_credentials *credentials;
|
||||
struct netlogon_creds_CredentialState *creds;
|
||||
uint32_t requested_negotiate_flags;
|
||||
uint32_t required_negotiate_flags;
|
||||
uint32_t local_negotiate_flags;
|
||||
uint32_t remote_negotiate_flags;
|
||||
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_srv_challenge(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 =
|
||||
cli_credentials_get_secure_channel_type(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.out.negotiate_flags = &s->remote_negotiate_flags;
|
||||
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->credentials1, &s->credentials2,
|
||||
s->mach_pwd, &s->credentials3,
|
||||
s->requested_negotiate_flags,
|
||||
s->local_negotiate_flags);
|
||||
if (composite_nomem(s->creds, c)) {
|
||||
return;
|
||||
@ -218,10 +222,17 @@ static void continue_srv_auth2(struct tevent_req *subreq)
|
||||
{
|
||||
struct composite_context *c;
|
||||
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);
|
||||
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 */
|
||||
c->status = dcerpc_netr_ServerAuthenticate2_r_recv(subreq, s);
|
||||
TALLOC_FREE(subreq);
|
||||
@ -233,6 +244,29 @@ static void continue_srv_auth2(struct tevent_req *subreq)
|
||||
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
|
||||
* 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;
|
||||
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) {
|
||||
composite_error(c, s->a.out.result);
|
||||
return;
|
||||
@ -277,7 +319,7 @@ static void continue_srv_auth2(struct tevent_req *subreq)
|
||||
"and retry! local[0x%08X] remote[0x%08X]\n",
|
||||
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,
|
||||
sizeof(s->credentials1.data));
|
||||
@ -292,11 +334,30 @@ static void continue_srv_auth2(struct tevent_req *subreq)
|
||||
return;
|
||||
}
|
||||
|
||||
s->creds->negotiate_flags = s->remote_negotiate_flags;
|
||||
|
||||
/* verify credentials */
|
||||
if (!netlogon_creds_client_check(s->creds, s->a.out.return_credentials)) {
|
||||
composite_error(c, NT_STATUS_UNSUCCESSFUL);
|
||||
status = netlogon_creds_client_verify(s->creds,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -317,6 +378,8 @@ static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
|
||||
struct composite_context *epm_map_req;
|
||||
enum netr_SchannelType schannel_type = cli_credentials_get_secure_channel_type(credentials);
|
||||
struct cli_credentials *epm_creds = NULL;
|
||||
bool reject_md5_servers = false;
|
||||
bool require_strong_key = false;
|
||||
|
||||
/* composite context allocation and setup */
|
||||
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->credentials = credentials;
|
||||
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
|
||||
s->required_negotiate_flags = NETLOGON_NEG_AUTHENTICATED_RPC;
|
||||
|
||||
/* allocate credentials */
|
||||
if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) {
|
||||
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
|
||||
require_strong_key = true;
|
||||
}
|
||||
if (s->pipe->conn->flags & DCERPC_SCHANNEL_AES) {
|
||||
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) {
|
||||
s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
|
||||
s->local_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES;
|
||||
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 */
|
||||
@ -350,9 +442,7 @@ static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
|
||||
s->local_negotiate_flags |= NETLOGON_NEG_RODC_PASSTHROUGH;
|
||||
}
|
||||
|
||||
if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
|
||||
s->local_negotiate_flags &= ~NETLOGON_NEG_ARCFOUR;
|
||||
}
|
||||
s->requested_negotiate_flags = s->local_negotiate_flags;
|
||||
|
||||
epm_creds = cli_credentials_init_anon(s);
|
||||
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,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct netlogon_creds_CredentialState **creds)
|
||||
struct netlogon_creds_CredentialState **creds,
|
||||
uint32_t *requested_negotiate_flags)
|
||||
{
|
||||
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,
|
||||
struct schannel_key_state);
|
||||
*creds = talloc_move(mem_ctx, &s->creds);
|
||||
*requested_negotiate_flags = s->requested_negotiate_flags;
|
||||
}
|
||||
|
||||
talloc_free(c);
|
||||
@ -398,6 +490,7 @@ static NTSTATUS dcerpc_schannel_key_recv(struct composite_context *c,
|
||||
struct auth_schannel_state {
|
||||
struct dcerpc_pipe *pipe;
|
||||
struct cli_credentials *credentials;
|
||||
uint32_t requested_negotiate_flags;
|
||||
const struct ndr_interface_table *table;
|
||||
struct loadparm_context *lp_ctx;
|
||||
uint8_t auth_level;
|
||||
@ -406,7 +499,9 @@ struct auth_schannel_state {
|
||||
struct netr_Authenticator auth;
|
||||
struct netr_Authenticator return_auth;
|
||||
union netr_Capabilities capabilities;
|
||||
union netr_Capabilities client_caps;
|
||||
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;
|
||||
|
||||
/* 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)) {
|
||||
DEBUG(1, ("Failed to setup credentials: %s\n", nt_errstr(status)));
|
||||
return;
|
||||
@ -496,36 +595,52 @@ static void continue_bind_auth(struct composite_context *ctx)
|
||||
&s->c);
|
||||
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;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
static void continue_get_capabilities(struct tevent_req *subreq)
|
||||
static void continue_get_negotiated_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_PROCNUM_OUT_OF_RANGE)) {
|
||||
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;
|
||||
} else {
|
||||
/* This is probably NT */
|
||||
composite_done(c);
|
||||
} else if (s->creds_state->negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
|
||||
DBG_ERR("%s: NT_STATUS_DOWNGRADE_DETECTED\n", __location__);
|
||||
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is probably NT */
|
||||
continue_logon_control_do(c);
|
||||
return;
|
||||
} else if (!composite_is_ok(c)) {
|
||||
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 (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -543,9 +659,12 @@ static void continue_get_capabilities(struct tevent_req *subreq)
|
||||
}
|
||||
|
||||
/* verify credentials */
|
||||
if (!netlogon_creds_client_check(&s->save_creds_state,
|
||||
&s->c.out.return_authenticator->cred)) {
|
||||
composite_error(c, NT_STATUS_UNSUCCESSFUL);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -559,19 +678,175 @@ static void continue_get_capabilities(struct tevent_req *subreq)
|
||||
|
||||
/* compare 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",
|
||||
s->creds_state->negotiate_flags,
|
||||
s->capabilities.server_capabilities));
|
||||
composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
|
||||
s->capabilities.server_capabilities);
|
||||
composite_error(c, NT_STATUS_DOWNGRADE_DETECTED);
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -387,14 +387,23 @@ return_downgrade:
|
||||
return orig_status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the actual processing of a netr_ServerAuthenticate3 message.
|
||||
* called from dcesrv_netr_ServerAuthenticate3, which handles the logging.
|
||||
*/
|
||||
static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
|
||||
typedef NTSTATUS (*dcesrv_netr_ServerAuthenticateGenericCallback_fn)(
|
||||
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);
|
||||
|
||||
static NTSTATUS dcesrv_netr_ServerAuthenticateGeneric(
|
||||
struct dcesrv_call_state *dce_call,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct netr_ServerAuthenticate3 *r,
|
||||
dcesrv_netr_ServerAuthenticateGenericCallback_fn auth_fn,
|
||||
const char **trust_account_for_search,
|
||||
const char **trust_account_in_db,
|
||||
struct dom_sid **sid)
|
||||
@ -404,15 +413,18 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
|
||||
struct netlogon_server_pipe_state challenge;
|
||||
struct netlogon_creds_CredentialState *creds;
|
||||
struct ldb_context *sam_ctx;
|
||||
struct samr_Password *curNtHash = NULL;
|
||||
struct samr_Password *prevNtHash = NULL;
|
||||
uint32_t user_account_control;
|
||||
int num_records;
|
||||
struct ldb_message **msgs;
|
||||
struct ldb_message *tdo_msg = NULL;
|
||||
NTSTATUS nt_status;
|
||||
const char *attrs[] = {"unicodePwd", "userAccountControl",
|
||||
"objectSid", "samAccountName", NULL};
|
||||
static const char *attrs[] = {"unicodePwd",
|
||||
"userAccountControl",
|
||||
"objectSid",
|
||||
"samAccountName",
|
||||
NULL};
|
||||
uint32_t server_flags = 0;
|
||||
uint32_t client_flags = 0;
|
||||
uint32_t negotiate_flags = 0;
|
||||
|
||||
ZERO_STRUCTP(r->out.return_credentials);
|
||||
@ -494,14 +506,20 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
|
||||
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) {
|
||||
case SEC_CHAN_WKSTA:
|
||||
@ -535,13 +553,10 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
|
||||
if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
|
||||
r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN)
|
||||
{
|
||||
struct ldb_message *tdo_msg = NULL;
|
||||
const char * const tdo_attrs[] = {
|
||||
"trustAuthIncoming",
|
||||
static const char *const tdo_attrs[] = {"trustAuthIncoming",
|
||||
"trustAttributes",
|
||||
"flatName",
|
||||
NULL
|
||||
};
|
||||
NULL};
|
||||
char *encoded_name = NULL;
|
||||
size_t len;
|
||||
const char *flatname = NULL;
|
||||
@ -606,22 +621,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
|
||||
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);
|
||||
if (flatname == NULL) {
|
||||
return dcesrv_netr_ServerAuthenticate3_check_downgrade(
|
||||
@ -742,60 +741,28 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
|
||||
}
|
||||
|
||||
if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
|
||||
nt_status = samdb_result_passwords_no_lockout(mem_ctx,
|
||||
dce_call->conn->dce_ctx->lp_ctx,
|
||||
msgs[0], &curNtHash);
|
||||
tdo_msg = NULL;
|
||||
}
|
||||
|
||||
*sid = samdb_result_dom_sid(mem_ctx, msgs[0], "objectSid");
|
||||
if (*sid == NULL) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
nt_status = auth_fn(dce_call,
|
||||
challenge_valid ? &challenge : NULL,
|
||||
r,
|
||||
client_flags,
|
||||
*sid,
|
||||
negotiate_flags,
|
||||
msgs[0],
|
||||
tdo_msg,
|
||||
mem_ctx,
|
||||
&creds);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
ZERO_STRUCTP(r->out.return_credentials);
|
||||
return nt_status;
|
||||
}
|
||||
}
|
||||
|
||||
if (curNtHash == NULL) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (!challenge_valid) {
|
||||
DEBUG(1, ("No challenge requested by client [%s/%s], "
|
||||
"cannot authenticate\n",
|
||||
log_escape(mem_ctx, r->in.computer_name),
|
||||
log_escape(mem_ctx, r->in.account_name)));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
creds = netlogon_creds_server_init(mem_ctx,
|
||||
r->in.account_name,
|
||||
r->in.computer_name,
|
||||
r->in.secure_channel_type,
|
||||
&challenge.client_challenge,
|
||||
&challenge.server_challenge,
|
||||
curNtHash,
|
||||
r->in.credentials,
|
||||
r->out.return_credentials,
|
||||
negotiate_flags);
|
||||
if (creds == NULL && prevNtHash != NULL) {
|
||||
/*
|
||||
* We fallback to the previous password for domain trusts.
|
||||
*
|
||||
* Note that lpcfg_old_password_allowed_period() doesn't
|
||||
* apply here.
|
||||
*/
|
||||
creds = netlogon_creds_server_init(mem_ctx,
|
||||
r->in.account_name,
|
||||
r->in.computer_name,
|
||||
r->in.secure_channel_type,
|
||||
&challenge.client_challenge,
|
||||
&challenge.server_challenge,
|
||||
prevNtHash,
|
||||
r->in.credentials,
|
||||
r->out.return_credentials,
|
||||
negotiate_flags);
|
||||
}
|
||||
|
||||
if (creds == NULL) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
|
||||
*sid = talloc_memdup(mem_ctx, creds->sid, sizeof(struct dom_sid));
|
||||
|
||||
nt_status = schannel_save_creds_state(mem_ctx,
|
||||
dce_call->conn->dce_ctx->lp_ctx,
|
||||
@ -811,6 +778,125 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
|
||||
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
|
||||
* 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 netlogon_creds_CredentialState *creds;
|
||||
const struct dom_sid *client_sid = NULL;
|
||||
struct ldb_context *sam_ctx;
|
||||
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,
|
||||
mem_ctx,
|
||||
@ -930,18 +1021,22 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call
|
||||
r->in.credential, r->out.return_authenticator,
|
||||
&creds);
|
||||
NT_STATUS_NOT_OK_RETURN(nt_status);
|
||||
client_sid = &creds->ex->client_sid;
|
||||
|
||||
sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
|
||||
if (sam_ctx == NULL) {
|
||||
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);
|
||||
|
||||
/* Using the sid for the account as the key, set the password */
|
||||
nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
|
||||
creds->sid,
|
||||
client_sid,
|
||||
NULL, /* Don't have version */
|
||||
NULL, /* Don't have plaintext */
|
||||
r->in.new_password,
|
||||
@ -958,6 +1053,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
|
||||
struct netr_ServerPasswordSet2 *r)
|
||||
{
|
||||
struct netlogon_creds_CredentialState *creds;
|
||||
const struct dom_sid *client_sid = NULL;
|
||||
struct ldb_context *sam_ctx;
|
||||
struct NL_PASSWORD_VERSION version = {};
|
||||
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 enc_blob = data_blob_null;
|
||||
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,
|
||||
mem_ctx,
|
||||
@ -974,6 +1074,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
|
||||
r->in.credential, r->out.return_authenticator,
|
||||
&creds);
|
||||
NT_STATUS_NOT_OK_RETURN(nt_status);
|
||||
client_sid = &creds->ex->client_sid;
|
||||
|
||||
sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
|
||||
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);
|
||||
SIVAL(password_buf.data, 512, r->in.new_password->length);
|
||||
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
nt_status = netlogon_creds_aes_decrypt(creds,
|
||||
password_buf.data,
|
||||
516);
|
||||
} else {
|
||||
nt_status = netlogon_creds_arcfour_crypt(creds,
|
||||
password_buf.data,
|
||||
516);
|
||||
}
|
||||
|
||||
nt_status = netlogon_creds_decrypt_samr_CryptPassword(creds,
|
||||
&password_buf,
|
||||
auth_type,
|
||||
auth_level);
|
||||
if (!NT_STATUS_IS_OK(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 */
|
||||
nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
|
||||
creds->sid,
|
||||
client_sid,
|
||||
new_version,
|
||||
&new_password, /* we have plaintext */
|
||||
NULL,
|
||||
@ -1287,7 +1382,9 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base_call(struct dcesrv_netr_LogonSamL
|
||||
|
||||
nt_status = netlogon_creds_decrypt_samlogon_logon(creds,
|
||||
r->in.logon_level,
|
||||
r->in.logon);
|
||||
r->in.logon,
|
||||
auth_type,
|
||||
auth_level);
|
||||
NT_STATUS_NOT_OK_RETURN(nt_status);
|
||||
|
||||
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
|
||||
= creds->account_name;
|
||||
user_info->netlogon_trust_account.sid
|
||||
= creds->sid;
|
||||
= &creds->ex->client_sid;
|
||||
|
||||
break;
|
||||
default:
|
||||
@ -1583,9 +1680,16 @@ static void dcesrv_netr_LogonSamLogon_base_reply(
|
||||
NTSTATUS status;
|
||||
|
||||
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,
|
||||
r->in.validation_level,
|
||||
r->out.validation);
|
||||
r->out.validation,
|
||||
auth_type,
|
||||
auth_level);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DBG_ERR("netlogon_creds_encrypt_samlogon_validation() "
|
||||
"failed - %s\n",
|
||||
@ -2381,12 +2485,7 @@ static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_c
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
/*
|
||||
* Until we know the details behind KB5028166
|
||||
* just return DCERPC_NCA_S_FAULT_INVALID_TAG
|
||||
* like an unpatched Windows Server.
|
||||
*/
|
||||
FALL_THROUGH;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* 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);
|
||||
|
||||
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;
|
||||
}
|
||||
@ -2618,17 +2725,18 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
|
||||
TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r)
|
||||
{
|
||||
struct netlogon_creds_CredentialState *creds;
|
||||
const char * const trusts_attrs[] = {
|
||||
"securityIdentifier",
|
||||
const struct dom_sid *client_sid = NULL;
|
||||
static const char *const trusts_attrs[] = {"securityIdentifier",
|
||||
"flatName",
|
||||
"trustPartner",
|
||||
"trustAttributes",
|
||||
"trustDirection",
|
||||
"trustType",
|
||||
NULL
|
||||
};
|
||||
const char * const attrs2[] = { "sAMAccountName", "dNSHostName",
|
||||
"msDS-SupportedEncryptionTypes", NULL };
|
||||
NULL};
|
||||
static const char *const attrs2[] = {"sAMAccountName",
|
||||
"dNSHostName",
|
||||
"msDS-SupportedEncryptionTypes",
|
||||
NULL};
|
||||
const char *sam_account_name, *old_dns_hostname;
|
||||
struct ldb_context *sam_ctx;
|
||||
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);
|
||||
}
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
client_sid = &creds->ex->client_sid;
|
||||
|
||||
/* We want to avoid connecting as system. */
|
||||
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 */
|
||||
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);
|
||||
|
||||
/* 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,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct dom_sid *user_sid,
|
||||
const struct dom_sid *user_sid,
|
||||
struct ldb_dn *obj_dn)
|
||||
{
|
||||
const char *rodc_attrs[] = { "msDS-NeverRevealGroup",
|
||||
static const char *rodc_attrs[] = {"msDS-NeverRevealGroup",
|
||||
"msDS-RevealOnDemandGroup",
|
||||
"userAccountControl",
|
||||
NULL };
|
||||
const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL };
|
||||
NULL};
|
||||
static const char *obj_attrs[] = {"tokenGroups",
|
||||
"objectSid",
|
||||
"UserAccountControl",
|
||||
"msDS-KrbTgtLinkBL",
|
||||
NULL};
|
||||
struct ldb_dn *rodc_dn;
|
||||
int ret;
|
||||
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 netlogon_creds_CredentialState *creds;
|
||||
const struct dom_sid *client_sid = NULL;
|
||||
struct ldb_context *sam_ctx;
|
||||
NTSTATUS nt_status;
|
||||
DATA_BLOB decrypted_blob;
|
||||
enum ndr_err_code ndr_err;
|
||||
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,
|
||||
mem_ctx,
|
||||
@ -3056,6 +3174,7 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal
|
||||
&creds);
|
||||
|
||||
NT_STATUS_NOT_OK_RETURN(nt_status);
|
||||
client_sid = &creds->ex->client_sid;
|
||||
|
||||
switch (creds->secure_channel_type) {
|
||||
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 */
|
||||
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.buffer_len);
|
||||
} else {
|
||||
nt_status = netlogon_creds_arcfour_crypt(creds,
|
||||
r->in.opaque_buffer,
|
||||
r->in.buffer_len);
|
||||
}
|
||||
r->in.buffer_len,
|
||||
auth_type,
|
||||
auth_level);
|
||||
if (!NT_STATUS_IS_OK(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 &&
|
||||
!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 "
|
||||
"an arbitrary user: %s\n",
|
||||
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_message **dom_res = NULL;
|
||||
const char *trust_attrs[] = { "flatname", "trustPartner",
|
||||
"securityIdentifier", "trustDirection",
|
||||
"trustType", "trustAttributes", NULL };
|
||||
static const char *trust_attrs[] = {"flatname",
|
||||
"trustPartner",
|
||||
"securityIdentifier",
|
||||
"trustDirection",
|
||||
"trustType",
|
||||
"trustAttributes",
|
||||
NULL};
|
||||
uint32_t n;
|
||||
int i;
|
||||
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 netlogon_creds_CredentialState *creds = NULL;
|
||||
const struct dom_sid *client_sid = NULL;
|
||||
struct ldb_context *sam_ctx = NULL;
|
||||
const char * const attrs[] = {
|
||||
"unicodePwd",
|
||||
@ -4429,6 +4550,10 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal
|
||||
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.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)) {
|
||||
return nt_status;
|
||||
}
|
||||
client_sid = &creds->ex->client_sid;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
asid = ldap_encode_ndr_dom_sid(mem_ctx, creds->sid);
|
||||
asid = ldap_encode_ndr_dom_sid(mem_ctx, client_sid);
|
||||
if (asid == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
@ -4545,14 +4671,20 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal
|
||||
|
||||
if (curNtHash != NULL) {
|
||||
*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)) {
|
||||
return nt_status;
|
||||
}
|
||||
}
|
||||
if (prevNtHash != NULL) {
|
||||
*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)) {
|
||||
return nt_status;
|
||||
}
|
||||
@ -4617,6 +4749,7 @@ static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call
|
||||
struct tevent_req *subreq;
|
||||
struct imessaging_context *imsg_ctx =
|
||||
dcesrv_imessaging_context(dce_call->conn);
|
||||
struct dom_sid *client_sid = NULL;
|
||||
|
||||
nt_status = dcesrv_netr_creds_server_step_check(dce_call,
|
||||
mem_ctx,
|
||||
@ -4625,6 +4758,7 @@ static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call
|
||||
r->out.return_authenticator,
|
||||
&creds);
|
||||
NT_STATUS_NOT_OK_RETURN(nt_status);
|
||||
client_sid = &creds->ex->client_sid;
|
||||
|
||||
if (creds->secure_channel_type != SEC_CHAN_RODC) {
|
||||
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);
|
||||
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.dns_ttl = r->in.dns_ttl;
|
||||
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;
|
||||
}
|
||||
|
||||
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 "librpc/gen_ndr/ndr_netlogon_s.c"
|
||||
|
@ -119,6 +119,7 @@ static bool test_ntp_signd(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
pwhash, &credentials3,
|
||||
negotiate_flags,
|
||||
negotiate_flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
|
@ -533,6 +533,8 @@ static bool test_validate_trust(struct torture_context *tctx,
|
||||
struct samr_Password *old_nt_hash;
|
||||
char *dummy;
|
||||
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);
|
||||
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);
|
||||
torture_assert(tctx, old_nt_hash != NULL, "cli_credentials_get_old_nt_hash()");
|
||||
|
||||
netlogon_creds_des_decrypt(creds, &new_owf_password);
|
||||
netlogon_creds_des_decrypt(creds, &old_owf_password);
|
||||
dcerpc_binding_handle_auth_info(p->binding_handle,
|
||||
&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_nt_hash->hash, 16);
|
||||
|
@ -3064,6 +3064,7 @@ static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
new_password, &credentials3,
|
||||
negotiate_flags,
|
||||
negotiate_flags);
|
||||
|
||||
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,
|
||||
&credentials1, &credentials2,
|
||||
old_password, &credentials3,
|
||||
negotiate_flags,
|
||||
negotiate_flags);
|
||||
|
||||
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 cldap_socket *cldap;
|
||||
struct cldap_netlogon cldap1;
|
||||
enum dcerpc_AuthType auth_type;
|
||||
enum dcerpc_AuthLevel auth_level;
|
||||
|
||||
incoming_creds = cli_credentials_init(tctx);
|
||||
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);
|
||||
ZERO_STRUCT(rep_auth);
|
||||
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
netlogon_creds_aes_encrypt(creds,
|
||||
samr_crypt_password.data,
|
||||
516);
|
||||
} else {
|
||||
netlogon_creds_arcfour_crypt(creds,
|
||||
samr_crypt_password.data,
|
||||
516);
|
||||
}
|
||||
dcerpc_binding_handle_auth_info(p2->binding_handle,
|
||||
&auth_type,
|
||||
&auth_level);
|
||||
status = netlogon_creds_encrypt_samr_CryptPassword(creds,
|
||||
&samr_crypt_password,
|
||||
auth_type,
|
||||
auth_level);
|
||||
torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
|
||||
|
||||
memcpy(netr_crypt_password.data,
|
||||
samr_crypt_password.data, 512);
|
||||
|
@ -180,6 +180,7 @@ bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
mach_password, &credentials3,
|
||||
0,
|
||||
0);
|
||||
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,
|
||||
&credentials1, &credentials2,
|
||||
mach_password, &credentials3,
|
||||
negotiate_flags,
|
||||
negotiate_flags);
|
||||
|
||||
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,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
negotiate_flags,
|
||||
negotiate_flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -421,6 +424,7 @@ bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
negotiate_flags,
|
||||
negotiate_flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -437,6 +441,7 @@ bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
negotiate_flags,
|
||||
negotiate_flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -541,6 +546,7 @@ static bool test_ServerReqChallenge(
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
mach_password, &credentials3,
|
||||
in_negotiate_flags,
|
||||
in_negotiate_flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -618,6 +624,7 @@ static bool test_ServerReqChallenge_zero_challenge(
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
mach_password, &credentials3,
|
||||
in_negotiate_flags,
|
||||
in_negotiate_flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -702,6 +709,7 @@ static bool test_ServerReqChallenge_5_repeats(
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
mach_password, &credentials3,
|
||||
in_negotiate_flags,
|
||||
in_negotiate_flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -788,6 +796,7 @@ static bool test_ServerReqChallenge_4_repeats(
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
mach_password, &credentials3,
|
||||
in_negotiate_flags,
|
||||
in_negotiate_flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -881,6 +890,7 @@ static bool test_ServerAuthenticate2_encrypts_to_zero(
|
||||
&credentials2,
|
||||
mach_password,
|
||||
&credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
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 samr_Password new_password;
|
||||
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)) {
|
||||
return false;
|
||||
@ -938,7 +951,12 @@ static bool test_SetPassword(struct torture_context *tctx,
|
||||
password = generate_random_password(tctx, 8, 255);
|
||||
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, "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 dcerpc_pipe *p = 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,
|
||||
machine_credentials,
|
||||
@ -1021,7 +1042,12 @@ static bool test_SetPassword_flags(struct torture_context *tctx,
|
||||
password = generate_random_password(tctx, 8, 255);
|
||||
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, "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 dcerpc_pipe *p = 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,
|
||||
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);
|
||||
encode_pw_buffer(password_buf.data, password, STR_UNICODE);
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
|
||||
} else {
|
||||
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);
|
||||
new_password.length = IVAL(password_buf.data, 512);
|
||||
@ -1158,11 +1188,12 @@ static bool test_SetPassword2_with_flags(struct torture_context *tctx,
|
||||
*/
|
||||
password = "";
|
||||
encode_pw_buffer(password_buf.data, password, STR_UNICODE);
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
|
||||
} else {
|
||||
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);
|
||||
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 */
|
||||
password = generate_random_password(tctx, 8, 255);
|
||||
encode_pw_buffer(password_buf.data, password, STR_UNICODE);
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
|
||||
} else {
|
||||
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);
|
||||
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 */
|
||||
set_pw_in_buffer(password_buf.data, &new_random_pass);
|
||||
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
|
||||
} else {
|
||||
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);
|
||||
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 dcerpc_pipe *p = 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(
|
||||
tctx,
|
||||
@ -1328,7 +1364,12 @@ static bool test_SetPassword2_encrypted_to_all_zeros(
|
||||
if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
|
||||
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)) {
|
||||
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 dcerpc_pipe *p = 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(
|
||||
tctx,
|
||||
@ -1415,7 +1459,12 @@ static bool test_SetPassword2_password_encrypts_to_zero(
|
||||
if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
|
||||
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);
|
||||
new_password.length = IVAL(password_buf.data, 512);
|
||||
@ -1451,6 +1500,9 @@ static bool test_SetPassword2_confounder(
|
||||
struct netr_CryptPassword new_password;
|
||||
struct dcerpc_pipe *p = 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(
|
||||
tctx,
|
||||
@ -1492,7 +1544,12 @@ static bool test_SetPassword2_confounder(
|
||||
if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
|
||||
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);
|
||||
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_binding_handle *b = NULL;
|
||||
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(
|
||||
p1,
|
||||
@ -1566,7 +1626,12 @@ static bool test_SetPassword2_all_zeros(
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
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);
|
||||
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;
|
||||
uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
|
||||
DATA_BLOB new_random_pass = data_blob_null;
|
||||
enum dcerpc_AuthType auth_type;
|
||||
enum dcerpc_AuthLevel auth_level;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!test_SetupCredentials2(
|
||||
p1,
|
||||
@ -1642,11 +1710,12 @@ static bool test_SetPassword2_maximum_length_password(
|
||||
new_random_pass = netlogon_very_rand_pass(tctx, 256);
|
||||
set_pw_in_buffer(password_buf.data, &new_random_pass);
|
||||
SIVAL(password_buf.data, 512, 512);
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
|
||||
} else {
|
||||
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);
|
||||
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_binding_handle *b = NULL;
|
||||
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(
|
||||
p1,
|
||||
@ -1726,7 +1798,12 @@ static bool test_SetPassword2_all_zero_password(
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
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);
|
||||
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,
|
||||
struct cli_credentials *credentials,
|
||||
uint32_t requested_flags,
|
||||
struct netlogon_creds_CredentialState *creds)
|
||||
{
|
||||
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);
|
||||
|
||||
status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
|
||||
torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
|
||||
if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
|
||||
return true;
|
||||
}
|
||||
torture_assert_ntstatus_ok(tctx, status,
|
||||
"LogonGetCapabilities query_level=1 failed");
|
||||
torture_assert_ntstatus_ok(tctx, r.out.result,
|
||||
"LogonGetCapabilities query_level=1 failed");
|
||||
|
||||
*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);
|
||||
|
||||
status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
|
||||
/*
|
||||
* an server without KB5028166 returns
|
||||
* DCERPC_NCA_S_FAULT_INVALID_TAG =>
|
||||
* NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities query_level=2 failed");
|
||||
torture_assert_ntstatus_ok(tctx, status,
|
||||
"LogonGetCapabilities query_level=2 failed");
|
||||
torture_assert_ntstatus_ok(tctx, r.out.result,
|
||||
"LogonGetCapabilities query_level=2 failed");
|
||||
|
||||
*creds = tmp_creds;
|
||||
|
||||
@ -2156,8 +2229,8 @@ bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *t
|
||||
&r.out.return_authenticator->cred),
|
||||
"Credential chaining failed");
|
||||
|
||||
torture_assert_int_equal(tctx, creds->negotiate_flags,
|
||||
capabilities.server_capabilities,
|
||||
torture_assert_int_equal(tctx, requested_flags,
|
||||
capabilities.requested_flags,
|
||||
"negotiate flags");
|
||||
|
||||
return true;
|
||||
@ -2276,6 +2349,7 @@ static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -2365,6 +2439,7 @@ static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -2382,6 +2457,7 @@ static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
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,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -2471,6 +2548,7 @@ static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
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,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -2561,6 +2640,7 @@ static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -2659,6 +2739,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -2676,6 +2757,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
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,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
torture_assert(tctx, creds != NULL, "memory allocation");
|
||||
@ -2752,6 +2835,7 @@ static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
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,
|
||||
&credentials1, &credentials2,
|
||||
&mach_password, &credentials3,
|
||||
flags,
|
||||
flags);
|
||||
|
||||
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 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,
|
||||
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);
|
||||
|
||||
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, nt_hash.hash, 16);
|
||||
|
@ -124,6 +124,7 @@ static bool test_ServerAuth3Crypto(struct dcerpc_pipe *p,
|
||||
&netr_creds2,
|
||||
&machine_password,
|
||||
&netr_creds3,
|
||||
negotiate_flags,
|
||||
negotiate_flags);
|
||||
GNUTLS_FIPS140_SET_STRICT_MODE();
|
||||
/* Test that we fail to encrypt with RC4 */
|
||||
@ -152,6 +153,8 @@ static bool test_ServerAuth3Crypto(struct dcerpc_pipe *p,
|
||||
a.out.result,
|
||||
NT_STATUS_DOWNGRADE_DETECTED,
|
||||
"Unexpected status code");
|
||||
torture_assert_int_equal(tctx, negotiate_flags, 0,
|
||||
"NT_STATUS_DOWNGRADE_DETECTED...");
|
||||
return false;
|
||||
}
|
||||
torture_assert_ntstatus_ok(tctx,
|
||||
@ -167,8 +170,8 @@ static bool test_ServerAuth3Crypto(struct dcerpc_pipe *p,
|
||||
|
||||
if (!weak_crypto_allowed) {
|
||||
torture_assert(tctx,
|
||||
(negotiate_flags & NETLOGON_NEG_ARCFOUR) == 0,
|
||||
"Server should not announce RC4 support");
|
||||
(negotiate_flags & NETLOGON_NEG_SUPPORTS_AES),
|
||||
"Server negotiate AES support");
|
||||
}
|
||||
|
||||
/* Prove that requesting a challenge again won't break it */
|
||||
|
@ -406,6 +406,9 @@ static bool netlogon_validate_pac(struct torture_context *tctx,
|
||||
struct dcerpc_binding_handle *b = NULL;
|
||||
enum ndr_err_code ndr_err;
|
||||
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,
|
||||
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, (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.data = pac_wrapped.data;
|
||||
@ -471,6 +469,14 @@ static bool netlogon_validate_pac(struct torture_context *tctx,
|
||||
r.out.authoritative = &authoritative;
|
||||
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),
|
||||
"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, (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.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.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),
|
||||
"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, (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.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.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),
|
||||
"LogonSamLogon failed");
|
||||
|
||||
|
@ -1091,7 +1091,9 @@ static bool auth2(struct torture_context *tctx,
|
||||
a.in.secure_channel_type,
|
||||
r.in.credentials,
|
||||
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");
|
||||
|
||||
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 netr_Authenticator credential, return_authenticator;
|
||||
struct samr_Password new_password;
|
||||
enum dcerpc_AuthType auth_type;
|
||||
enum dcerpc_AuthLevel auth_level;
|
||||
|
||||
s.in.server_name = talloc_asprintf(
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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,
|
||||
r.in.credentials,
|
||||
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");
|
||||
|
||||
status = dcerpc_netr_ServerAuthenticate2_r(net_handle, mem_ctx, &a);
|
||||
|
@ -91,6 +91,12 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
|
||||
struct netr_NetworkInfo ninfo;
|
||||
struct netr_SamBaseInfo *base = NULL;
|
||||
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_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,
|
||||
validation_level,
|
||||
r->out.validation);
|
||||
r->out.validation,
|
||||
auth_type,
|
||||
auth_level);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (error_string) {
|
||||
*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,
|
||||
validation_level,
|
||||
r_ex->out.validation);
|
||||
r_ex->out.validation,
|
||||
auth_type,
|
||||
auth_level);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (error_string) {
|
||||
*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,
|
||||
validation_level,
|
||||
r_flags->out.validation);
|
||||
r_flags->out.validation,
|
||||
auth_type,
|
||||
auth_level);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (error_string) {
|
||||
*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;
|
||||
uint8_t authoritative = 1;
|
||||
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(r);
|
||||
@ -1574,13 +1590,15 @@ bool test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
E_md4hash(plain_pass, pinfo.ntpassword.hash);
|
||||
|
||||
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);
|
||||
}
|
||||
status = netlogon_creds_encrypt_samlogon_logon(creds,
|
||||
r.in.logon_level,
|
||||
r.in.logon,
|
||||
auth_type,
|
||||
auth_level);
|
||||
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);
|
||||
|
||||
|
@ -3607,6 +3607,8 @@ static bool test_SamLogon(struct torture_context *tctx,
|
||||
struct netlogon_creds_CredentialState *creds;
|
||||
struct netr_Authenticator a;
|
||||
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)), "");
|
||||
|
||||
@ -3636,17 +3638,6 @@ static bool test_SamLogon(struct torture_context *tctx,
|
||||
}
|
||||
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;
|
||||
logon.password = &pinfo;
|
||||
|
||||
@ -3693,6 +3684,14 @@ static bool test_SamLogon(struct torture_context *tctx,
|
||||
|
||||
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),
|
||||
"netr_LogonSamLogonEx failed");
|
||||
if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "libcli/security/security.h"
|
||||
#include "system/filesys.h"
|
||||
#include "param/param.h"
|
||||
#include "param/loadparm.h"
|
||||
#include "librpc/rpc/dcerpc_proto.h"
|
||||
#include "libcli/composite/composite.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;
|
||||
const char *crypto_alg = "";
|
||||
bool can_do_validation_6 = true;
|
||||
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
|
||||
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
|
||||
|
||||
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) {
|
||||
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->LMSessKey.key, 8);
|
||||
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
netlogon_creds_aes_decrypt(creds, base->key.key, 16);
|
||||
netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8);
|
||||
} else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
|
||||
netlogon_creds_arcfour_crypt(creds, base->key.key, 16);
|
||||
netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8);
|
||||
}
|
||||
status = netlogon_creds_decrypt_samlogon_validation(creds,
|
||||
r.in.validation_level,
|
||||
r.out.validation,
|
||||
auth_type,
|
||||
auth_level);
|
||||
torture_assert_ntstatus_ok(tctx, status, "decrypt_samlogon_validation");
|
||||
|
||||
DEBUG(1,("decrypted keys validation_level %d\n",
|
||||
validation_levels[i]));
|
||||
@ -276,6 +277,7 @@ static bool test_netlogon_ex_bug14932(struct dcerpc_pipe *p,
|
||||
struct netr_SamBaseInfo *base = NULL;
|
||||
const char *crypto_alg = "";
|
||||
bool can_do_validation_6 = true;
|
||||
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
|
||||
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
|
||||
|
||||
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) {
|
||||
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->LMSessKey.key, 8);
|
||||
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
netlogon_creds_aes_decrypt(creds, base->key.key, 16);
|
||||
netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8);
|
||||
} else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
|
||||
netlogon_creds_arcfour_crypt(creds, base->key.key, 16);
|
||||
netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8);
|
||||
}
|
||||
status = netlogon_creds_decrypt_samlogon_validation(creds,
|
||||
r.in.validation_level,
|
||||
r.out.validation,
|
||||
auth_type,
|
||||
auth_level);
|
||||
torture_assert_ntstatus_ok(tctx, status, "decrypt_samlogon_validation");
|
||||
|
||||
DEBUG(1,("decrypted keys validation_level %d\n",
|
||||
validation_levels[i]));
|
||||
@ -591,6 +592,7 @@ static bool test_schannel(struct torture_context *tctx,
|
||||
struct netlogon_creds_CredentialState *creds;
|
||||
struct cli_credentials *credentials;
|
||||
enum dcerpc_transport_t transport;
|
||||
uint32_t requested_flags;
|
||||
|
||||
join_ctx = torture_join_domain(tctx,
|
||||
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);
|
||||
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 */
|
||||
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)");
|
||||
|
||||
/* do a couple of logins */
|
||||
@ -719,8 +739,26 @@ static bool test_schannel(struct torture_context *tctx,
|
||||
tctx, &p_netlogon2);
|
||||
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 */
|
||||
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)");
|
||||
|
||||
/* 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 netr_Authenticator credential, return_authenticator;
|
||||
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,
|
||||
&ndr_table_netlogon,
|
||||
@ -1272,7 +1312,14 @@ bool torture_rpc_schannel_bench1(struct torture_context *torture)
|
||||
|
||||
creds_state = cli_credentials_get_netlogon_creds(
|
||||
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);
|
||||
|
||||
torture_assert_ntstatus_ok(torture, dcerpc_netr_ServerPasswordSet_r(net_pipe->binding_handle, torture, &pwset),
|
||||
|
Loading…
Reference in New Issue
Block a user