1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-05 20:58:40 +03:00

libcli/auth: pass the cleartext blob to netlogon_creds_cli_ServerPasswordSet*()

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
Stefan Metzmacher 2017-06-13 11:18:37 +02:00
parent 1b48c8515e
commit 0f5945a06d
4 changed files with 63 additions and 19 deletions

View File

@ -37,6 +37,7 @@
#include "source3/include/messages.h" #include "source3/include/messages.h"
#include "source3/include/g_lock.h" #include "source3/include/g_lock.h"
#include "libds/common/roles.h" #include "libds/common/roles.h"
#include "lib/crypto/crypto.h"
struct netlogon_creds_cli_locked_state; struct netlogon_creds_cli_locked_state;
@ -1751,7 +1752,7 @@ struct tevent_req *netlogon_creds_cli_ServerPasswordSet_send(TALLOC_CTX *mem_ctx
struct tevent_context *ev, struct tevent_context *ev,
struct netlogon_creds_cli_context *context, struct netlogon_creds_cli_context *context,
struct dcerpc_binding_handle *b, struct dcerpc_binding_handle *b,
const char *new_password, const DATA_BLOB *new_password,
const uint32_t *new_version) const uint32_t *new_version)
{ {
struct tevent_req *req; struct tevent_req *req;
@ -1769,20 +1770,21 @@ struct tevent_req *netlogon_creds_cli_ServerPasswordSet_send(TALLOC_CTX *mem_ctx
state->context = context; state->context = context;
state->binding_handle = b; state->binding_handle = b;
/* if (new_password->length < 14) {
* netr_ServerPasswordSet
*/
ok = E_md4hash(new_password, state->samr_password.hash);
if (!ok) {
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
return tevent_req_post(req, ev); return tevent_req_post(req, ev);
} }
/*
* netr_ServerPasswordSet
*/
mdfour(state->samr_password.hash, new_password->data, new_password->length);
/* /*
* netr_ServerPasswordSet2 * netr_ServerPasswordSet2
*/ */
ok = encode_pw_buffer(state->samr_crypt_password.data, ok = set_pw_in_buffer(state->samr_crypt_password.data,
new_password, STR_UNICODE); new_password);
if (!ok) { if (!ok) {
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
return tevent_req_post(req, ev); return tevent_req_post(req, ev);
@ -2052,7 +2054,7 @@ NTSTATUS netlogon_creds_cli_ServerPasswordSet_recv(struct tevent_req *req)
NTSTATUS netlogon_creds_cli_ServerPasswordSet( NTSTATUS netlogon_creds_cli_ServerPasswordSet(
struct netlogon_creds_cli_context *context, struct netlogon_creds_cli_context *context,
struct dcerpc_binding_handle *b, struct dcerpc_binding_handle *b,
const char *new_password, const DATA_BLOB *new_password,
const uint32_t *new_version) const uint32_t *new_version)
{ {
TALLOC_CTX *frame = talloc_stackframe(); TALLOC_CTX *frame = talloc_stackframe();

View File

@ -106,13 +106,13 @@ struct tevent_req *netlogon_creds_cli_ServerPasswordSet_send(TALLOC_CTX *mem_ctx
struct tevent_context *ev, struct tevent_context *ev,
struct netlogon_creds_cli_context *context, struct netlogon_creds_cli_context *context,
struct dcerpc_binding_handle *b, struct dcerpc_binding_handle *b,
const char *new_password, const DATA_BLOB *new_password,
const uint32_t *new_version); const uint32_t *new_version);
NTSTATUS netlogon_creds_cli_ServerPasswordSet_recv(struct tevent_req *req); NTSTATUS netlogon_creds_cli_ServerPasswordSet_recv(struct tevent_req *req);
NTSTATUS netlogon_creds_cli_ServerPasswordSet( NTSTATUS netlogon_creds_cli_ServerPasswordSet(
struct netlogon_creds_cli_context *context, struct netlogon_creds_cli_context *context,
struct dcerpc_binding_handle *b, struct dcerpc_binding_handle *b,
const char *new_password, const DATA_BLOB *new_password,
const uint32_t *new_version); const uint32_t *new_version);
struct tevent_req *netlogon_creds_cli_LogonSamLogon_send(TALLOC_CTX *mem_ctx, struct tevent_req *netlogon_creds_cli_LogonSamLogon_send(TALLOC_CTX *mem_ctx,

View File

@ -1140,6 +1140,9 @@ static NTSTATUS libnet_join_joindomain_rpc_unsecure(TALLOC_CTX *mem_ctx,
struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *netlogon_pipe = NULL;
struct netlogon_creds_cli_context *netlogon_creds = NULL; struct netlogon_creds_cli_context *netlogon_creds = NULL;
struct samr_Password current_nt_hash; struct samr_Password current_nt_hash;
size_t len = 0;
bool ok;
DATA_BLOB new_trust_blob = data_blob_null;
NTSTATUS status; NTSTATUS status;
status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon, status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon,
@ -1186,9 +1189,23 @@ static NTSTATUS libnet_join_joindomain_rpc_unsecure(TALLOC_CTX *mem_ctx,
return status; return status;
} }
len = strlen(r->in.machine_password);
ok = convert_string_talloc(frame, CH_UNIX, CH_UTF16,
r->in.machine_password, len,
(void **)&new_trust_blob.data,
&new_trust_blob.length);
if (!ok) {
status = NT_STATUS_UNMAPPABLE_CHARACTER;
if (errno == ENOMEM) {
status = NT_STATUS_NO_MEMORY;
}
TALLOC_FREE(frame);
return status;
}
status = netlogon_creds_cli_ServerPasswordSet(netlogon_creds, status = netlogon_creds_cli_ServerPasswordSet(netlogon_creds,
netlogon_pipe->binding_handle, netlogon_pipe->binding_handle,
r->in.machine_password, &new_trust_blob,
NULL); /* new_version */ NULL); /* new_version */
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(frame); TALLOC_FREE(frame);

View File

@ -125,7 +125,9 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
struct timeval g_timeout = { 0, }; struct timeval g_timeout = { 0, };
int timeout = 0; int timeout = 0;
struct timeval tv = { 0, }; struct timeval tv = { 0, };
char *new_trust_passwd = NULL; char *new_trust_pw_str = NULL;
size_t len = 0;
DATA_BLOB new_trust_pw_blob = data_blob_null;
uint32_t new_version = 0; uint32_t new_version = 0;
uint32_t *new_trust_version = NULL; uint32_t *new_trust_version = NULL;
NTSTATUS status; NTSTATUS status;
@ -239,14 +241,31 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
* We create a random buffer and convert that to utf8. * We create a random buffer and convert that to utf8.
* This is similar to what windows is doing. * This is similar to what windows is doing.
*/ */
new_trust_passwd = trust_pw_new_value(frame, sec_channel_type, new_trust_pw_str = trust_pw_new_value(frame, sec_channel_type,
lp_security()); lp_security());
if (new_trust_passwd == NULL) { if (new_trust_pw_str == NULL) {
DEBUG(0, ("trust_pw_new_value() failed\n")); DEBUG(0, ("trust_pw_new_value() failed\n"));
TALLOC_FREE(frame); TALLOC_FREE(frame);
return NT_STATUS_NO_MEMORY; return NT_STATUS_NO_MEMORY;
} }
len = strlen(new_trust_pw_str);
ok = convert_string_talloc(frame, CH_UNIX, CH_UTF16,
new_trust_pw_str, len,
(void **)&new_trust_pw_blob.data,
&new_trust_pw_blob.length);
if (!ok) {
status = NT_STATUS_UNMAPPABLE_CHARACTER;
if (errno == ENOMEM) {
status = NT_STATUS_NO_MEMORY;
}
DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
"failed for of %s - %s\n",
domain, nt_errstr(status));
TALLOC_FREE(frame);
return status;
}
nt_hashes[0] = current_nt_hash; nt_hashes[0] = current_nt_hash;
num_nt_hashes = 1; num_nt_hashes = 1;
@ -287,13 +306,16 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
case SEC_CHAN_WKSTA: case SEC_CHAN_WKSTA:
case SEC_CHAN_BDC: case SEC_CHAN_BDC:
ok = secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type); ok = secrets_store_machine_password(new_trust_pw_str,
domain,
sec_channel_type);
if (!ok) { if (!ok) {
DEBUG(0, ("secrets_store_machine_password failed for domain %s!\n", DEBUG(0, ("secrets_store_machine_password failed for domain %s!\n",
domain)); domain));
TALLOC_FREE(frame); TALLOC_FREE(frame);
return NT_STATUS_INTERNAL_DB_CORRUPTION; return NT_STATUS_INTERNAL_DB_CORRUPTION;
} }
TALLOC_FREE(new_trust_pw_str);
break; break;
case SEC_CHAN_DNS_DOMAIN: case SEC_CHAN_DNS_DOMAIN:
@ -302,7 +324,7 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
* we need to get the sid first for the * we need to get the sid first for the
* pdb_set_trusteddom_pw call * pdb_set_trusteddom_pw call
*/ */
ok = pdb_set_trusteddom_pw(domain, new_trust_passwd, ok = pdb_set_trusteddom_pw(domain, new_trust_pw_str,
&td->security_identifier); &td->security_identifier);
if (!ok) { if (!ok) {
DEBUG(0, ("pdb_set_trusteddom_pw() failed for domain %s!\n", DEBUG(0, ("pdb_set_trusteddom_pw() failed for domain %s!\n",
@ -310,6 +332,7 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
TALLOC_FREE(frame); TALLOC_FREE(frame);
return NT_STATUS_INTERNAL_DB_CORRUPTION; return NT_STATUS_INTERNAL_DB_CORRUPTION;
} }
TALLOC_FREE(new_trust_pw_str);
break; break;
default: default:
@ -321,7 +344,7 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
current_timestring(talloc_tos(), false), __func__, domain)); current_timestring(talloc_tos(), false), __func__, domain));
status = netlogon_creds_cli_ServerPasswordSet(context, b, status = netlogon_creds_cli_ServerPasswordSet(context, b,
new_trust_passwd, &new_trust_pw_blob,
new_trust_version); new_trust_version);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("%s : %s(%s) remote password change set with %s failed - %s\n", DEBUG(0,("%s : %s(%s) remote password change set with %s failed - %s\n",
@ -336,7 +359,9 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
current_timestring(talloc_tos(), false), current_timestring(talloc_tos(), false),
__func__, domain, context_name)); __func__, domain, context_name));
ok = cli_credentials_set_password(creds, new_trust_passwd, CRED_SPECIFIED); ok = cli_credentials_set_utf16_password(creds,
&new_trust_pw_blob,
CRED_SPECIFIED);
if (!ok) { if (!ok) {
DEBUG(0, ("cli_credentials_set_password failed for domain %s!\n", DEBUG(0, ("cli_credentials_set_password failed for domain %s!\n",
domain)); domain));