[SCM] Samba Shared Repository - branch master updated

Günther Deschner gd at samba.org
Wed Jan 21 09:20:03 MST 2015


The branch, master has been updated
       via  87c5795 libcli/auth: add netlogon_creds_cli_GetForestTrustInformation*()
       via  05a3d98 libcli/auth: add netlogon_creds_cli_ServerGetTrustInfo*()
       via  01c0234 s4:kdc/db-glue: fix supported_enctypes samba_kdc_trust_message2entry()
      from  6da8601 libsmb: provide authinfo domain for encrypted session referrals

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 87c57956ba9ae15d4e7699e31ddfb437e11b35d6
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Dec 22 22:02:04 2014 +0100

    libcli/auth: add netlogon_creds_cli_GetForestTrustInformation*()
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    
    Autobuild-User(master): Günther Deschner <gd at samba.org>
    Autobuild-Date(master): Wed Jan 21 17:19:33 CET 2015 on sn-devel-104

commit 05a3d980f8d9c3b9d53d60c990283b5a307885d7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Dec 22 21:48:18 2014 +0100

    libcli/auth: add netlogon_creds_cli_ServerGetTrustInfo*()
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 01c02340c1700aeb16d167be45f6de8d96a91802
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jan 20 10:52:22 2015 +0000

    s4:kdc/db-glue: fix supported_enctypes samba_kdc_trust_message2entry()
    
    This avoids writing invalid memory, because num_keys was calculated
    in a wrong way...
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 libcli/auth/netlogon_creds_cli.c | 552 +++++++++++++++++++++++++++++++++++++++
 libcli/auth/netlogon_creds_cli.h |  30 +++
 source4/kdc/db-glue.c            |  10 +-
 3 files changed, 587 insertions(+), 5 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
index a461dc6..1ea2f75 100644
--- a/libcli/auth/netlogon_creds_cli.c
+++ b/libcli/auth/netlogon_creds_cli.c
@@ -2839,3 +2839,555 @@ NTSTATUS netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords(
 	TALLOC_FREE(frame);
 	return status;
 }
+
+struct netlogon_creds_cli_ServerGetTrustInfo_state {
+	struct tevent_context *ev;
+	struct netlogon_creds_cli_context *context;
+	struct dcerpc_binding_handle *binding_handle;
+
+	char *srv_name_slash;
+	enum dcerpc_AuthType auth_type;
+	enum dcerpc_AuthLevel auth_level;
+
+	struct samr_Password new_owf_password;
+	struct samr_Password old_owf_password;
+	struct netr_TrustInfo *trust_info;
+
+	struct netlogon_creds_CredentialState *creds;
+	struct netlogon_creds_CredentialState tmp_creds;
+	struct netr_Authenticator req_auth;
+	struct netr_Authenticator rep_auth;
+};
+
+static void netlogon_creds_cli_ServerGetTrustInfo_cleanup(struct tevent_req *req,
+						     NTSTATUS status);
+static void netlogon_creds_cli_ServerGetTrustInfo_locked(struct tevent_req *subreq);
+
+struct tevent_req *netlogon_creds_cli_ServerGetTrustInfo_send(TALLOC_CTX *mem_ctx,
+					struct tevent_context *ev,
+					struct netlogon_creds_cli_context *context,
+					struct dcerpc_binding_handle *b)
+{
+	struct tevent_req *req;
+	struct netlogon_creds_cli_ServerGetTrustInfo_state *state;
+	struct tevent_req *subreq;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct netlogon_creds_cli_ServerGetTrustInfo_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	state->ev = ev;
+	state->context = context;
+	state->binding_handle = b;
+
+	state->srv_name_slash = talloc_asprintf(state, "\\\\%s",
+						context->server.computer);
+	if (tevent_req_nomem(state->srv_name_slash, req)) {
+		return tevent_req_post(req, ev);
+	}
+
+	dcerpc_binding_handle_auth_info(state->binding_handle,
+					&state->auth_type,
+					&state->auth_level);
+
+	subreq = netlogon_creds_cli_lock_send(state, state->ev,
+					      state->context);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+
+	tevent_req_set_callback(subreq,
+				netlogon_creds_cli_ServerGetTrustInfo_locked,
+				req);
+
+	return req;
+}
+
+static void netlogon_creds_cli_ServerGetTrustInfo_cleanup(struct tevent_req *req,
+							 NTSTATUS status)
+{
+	struct netlogon_creds_cli_ServerGetTrustInfo_state *state =
+		tevent_req_data(req,
+		struct netlogon_creds_cli_ServerGetTrustInfo_state);
+
+	if (state->creds == NULL) {
+		return;
+	}
+
+	if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED) &&
+	    !NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) &&
+	    !NT_STATUS_EQUAL(status, NT_STATUS_DOWNGRADE_DETECTED) &&
+	    !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
+	    !NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) {
+		TALLOC_FREE(state->creds);
+		return;
+	}
+
+	netlogon_creds_cli_delete(state->context, &state->creds);
+}
+
+static void netlogon_creds_cli_ServerGetTrustInfo_done(struct tevent_req *subreq);
+
+static void netlogon_creds_cli_ServerGetTrustInfo_locked(struct tevent_req *subreq)
+{
+	struct tevent_req *req =
+		tevent_req_callback_data(subreq,
+		struct tevent_req);
+	struct netlogon_creds_cli_ServerGetTrustInfo_state *state =
+		tevent_req_data(req,
+		struct netlogon_creds_cli_ServerGetTrustInfo_state);
+	NTSTATUS status;
+
+	status = netlogon_creds_cli_lock_recv(subreq, state,
+					      &state->creds);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+
+	if (state->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+		switch (state->auth_level) {
+		case DCERPC_AUTH_LEVEL_PRIVACY:
+			break;
+		default:
+			tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
+			return;
+		}
+	} else {
+		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
+		return;
+	}
+
+	/*
+	 * we defer all callbacks in order to cleanup
+	 * the database record.
+	 */
+	tevent_req_defer_callback(req, state->ev);
+
+	state->tmp_creds = *state->creds;
+	netlogon_creds_client_authenticator(&state->tmp_creds,
+					    &state->req_auth);
+	ZERO_STRUCT(state->rep_auth);
+
+	subreq = dcerpc_netr_ServerGetTrustInfo_send(state, state->ev,
+						     state->binding_handle,
+						     state->srv_name_slash,
+						     state->tmp_creds.account_name,
+						     state->tmp_creds.secure_channel_type,
+						     state->tmp_creds.computer_name,
+						     &state->req_auth,
+						     &state->rep_auth,
+						     &state->new_owf_password,
+						     &state->old_owf_password,
+						     &state->trust_info);
+	if (tevent_req_nomem(subreq, req)) {
+		status = NT_STATUS_NO_MEMORY;
+		netlogon_creds_cli_ServerGetTrustInfo_cleanup(req, status);
+		return;
+	}
+
+	tevent_req_set_callback(subreq,
+				netlogon_creds_cli_ServerGetTrustInfo_done,
+				req);
+}
+
+static void netlogon_creds_cli_ServerGetTrustInfo_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req =
+		tevent_req_callback_data(subreq,
+		struct tevent_req);
+	struct netlogon_creds_cli_ServerGetTrustInfo_state *state =
+		tevent_req_data(req,
+		struct netlogon_creds_cli_ServerGetTrustInfo_state);
+	NTSTATUS status;
+	NTSTATUS result;
+	const struct samr_Password zero = {};
+	int cmp;
+	bool ok;
+
+	/*
+	 * We use state->dns_names as the memory context, as this is
+	 * the only in/out variable and it has been overwritten by the
+	 * out parameter from the server.
+	 *
+	 * We need to preserve the return value until the caller can use it.
+	 */
+	status = dcerpc_netr_ServerGetTrustInfo_recv(subreq, state, &result);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		netlogon_creds_cli_ServerGetTrustInfo_cleanup(req, status);
+		return;
+	}
+
+	ok = netlogon_creds_client_check(&state->tmp_creds,
+					 &state->rep_auth.cred);
+	if (!ok) {
+		status = NT_STATUS_ACCESS_DENIED;
+		tevent_req_nterror(req, status);
+		netlogon_creds_cli_ServerGetTrustInfo_cleanup(req, status);
+		return;
+	}
+
+	if (tevent_req_nterror(req, result)) {
+		netlogon_creds_cli_ServerGetTrustInfo_cleanup(req, result);
+		return;
+	}
+
+	cmp = memcmp(state->new_owf_password.hash,
+		     zero.hash, sizeof(zero.hash));
+	if (cmp != 0) {
+		netlogon_creds_des_decrypt(&state->tmp_creds,
+					   &state->new_owf_password);
+	}
+	cmp = memcmp(state->old_owf_password.hash,
+		     zero.hash, sizeof(zero.hash));
+	if (cmp != 0) {
+		netlogon_creds_des_decrypt(&state->tmp_creds,
+					   &state->old_owf_password);
+	}
+
+	*state->creds = state->tmp_creds;
+	status = netlogon_creds_cli_store(state->context,
+					  &state->creds);
+	if (tevent_req_nterror(req, status)) {
+		netlogon_creds_cli_ServerGetTrustInfo_cleanup(req, status);
+		return;
+	}
+
+	tevent_req_done(req);
+}
+
+NTSTATUS netlogon_creds_cli_ServerGetTrustInfo_recv(struct tevent_req *req,
+					TALLOC_CTX *mem_ctx,
+					struct samr_Password *new_owf_password,
+					struct samr_Password *old_owf_password,
+					struct netr_TrustInfo **trust_info)
+{
+	struct netlogon_creds_cli_ServerGetTrustInfo_state *state =
+		tevent_req_data(req,
+		struct netlogon_creds_cli_ServerGetTrustInfo_state);
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		netlogon_creds_cli_ServerGetTrustInfo_cleanup(req, status);
+		tevent_req_received(req);
+		return status;
+	}
+
+	if (new_owf_password != NULL) {
+		*new_owf_password = state->new_owf_password;
+	}
+	if (old_owf_password != NULL) {
+		*old_owf_password = state->old_owf_password;
+	}
+	if (trust_info != NULL) {
+		*trust_info = talloc_move(mem_ctx, &state->trust_info);
+	}
+
+	tevent_req_received(req);
+	return NT_STATUS_OK;
+}
+
+NTSTATUS netlogon_creds_cli_ServerGetTrustInfo(
+				struct netlogon_creds_cli_context *context,
+				struct dcerpc_binding_handle *b,
+				TALLOC_CTX *mem_ctx,
+				struct samr_Password *new_owf_password,
+				struct samr_Password *old_owf_password,
+				struct netr_TrustInfo **trust_info)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct tevent_context *ev;
+	struct tevent_req *req;
+	NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+	ev = samba_tevent_context_init(frame);
+	if (ev == NULL) {
+		goto fail;
+	}
+	req = netlogon_creds_cli_ServerGetTrustInfo_send(frame, ev, context, b);
+	if (req == NULL) {
+		goto fail;
+	}
+	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+		goto fail;
+	}
+	status = netlogon_creds_cli_ServerGetTrustInfo_recv(req,
+							    mem_ctx,
+							    new_owf_password,
+							    old_owf_password,
+							    trust_info);
+ fail:
+	TALLOC_FREE(frame);
+	return status;
+}
+
+struct netlogon_creds_cli_GetForestTrustInformation_state {
+	struct tevent_context *ev;
+	struct netlogon_creds_cli_context *context;
+	struct dcerpc_binding_handle *binding_handle;
+
+	char *srv_name_slash;
+	enum dcerpc_AuthType auth_type;
+	enum dcerpc_AuthLevel auth_level;
+
+	uint32_t flags;
+	struct lsa_ForestTrustInformation *forest_trust_info;
+
+	struct netlogon_creds_CredentialState *creds;
+	struct netlogon_creds_CredentialState tmp_creds;
+	struct netr_Authenticator req_auth;
+	struct netr_Authenticator rep_auth;
+};
+
+static void netlogon_creds_cli_GetForestTrustInformation_cleanup(struct tevent_req *req,
+						     NTSTATUS status);
+static void netlogon_creds_cli_GetForestTrustInformation_locked(struct tevent_req *subreq);
+
+struct tevent_req *netlogon_creds_cli_GetForestTrustInformation_send(TALLOC_CTX *mem_ctx,
+					struct tevent_context *ev,
+					struct netlogon_creds_cli_context *context,
+					struct dcerpc_binding_handle *b)
+{
+	struct tevent_req *req;
+	struct netlogon_creds_cli_GetForestTrustInformation_state *state;
+	struct tevent_req *subreq;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct netlogon_creds_cli_GetForestTrustInformation_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	state->ev = ev;
+	state->context = context;
+	state->binding_handle = b;
+
+	state->srv_name_slash = talloc_asprintf(state, "\\\\%s",
+						context->server.computer);
+	if (tevent_req_nomem(state->srv_name_slash, req)) {
+		return tevent_req_post(req, ev);
+	}
+
+	state->flags = 0;
+
+	dcerpc_binding_handle_auth_info(state->binding_handle,
+					&state->auth_type,
+					&state->auth_level);
+
+	subreq = netlogon_creds_cli_lock_send(state, state->ev,
+					      state->context);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+
+	tevent_req_set_callback(subreq,
+				netlogon_creds_cli_GetForestTrustInformation_locked,
+				req);
+
+	return req;
+}
+
+static void netlogon_creds_cli_GetForestTrustInformation_cleanup(struct tevent_req *req,
+							 NTSTATUS status)
+{
+	struct netlogon_creds_cli_GetForestTrustInformation_state *state =
+		tevent_req_data(req,
+		struct netlogon_creds_cli_GetForestTrustInformation_state);
+
+	if (state->creds == NULL) {
+		return;
+	}
+
+	if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED) &&
+	    !NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) &&
+	    !NT_STATUS_EQUAL(status, NT_STATUS_DOWNGRADE_DETECTED) &&
+	    !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
+	    !NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) {
+		TALLOC_FREE(state->creds);
+		return;
+	}
+
+	netlogon_creds_cli_delete(state->context, &state->creds);
+}
+
+static void netlogon_creds_cli_GetForestTrustInformation_done(struct tevent_req *subreq);
+
+static void netlogon_creds_cli_GetForestTrustInformation_locked(struct tevent_req *subreq)
+{
+	struct tevent_req *req =
+		tevent_req_callback_data(subreq,
+		struct tevent_req);
+	struct netlogon_creds_cli_GetForestTrustInformation_state *state =
+		tevent_req_data(req,
+		struct netlogon_creds_cli_GetForestTrustInformation_state);
+	NTSTATUS status;
+
+	status = netlogon_creds_cli_lock_recv(subreq, state,
+					      &state->creds);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+
+	if (state->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+		switch (state->auth_level) {
+		case DCERPC_AUTH_LEVEL_INTEGRITY:
+		case DCERPC_AUTH_LEVEL_PRIVACY:
+			break;
+		default:
+			tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
+			return;
+		}
+	} else {
+		uint32_t tmp = state->creds->negotiate_flags;
+
+		if (tmp & NETLOGON_NEG_AUTHENTICATED_RPC) {
+			/*
+			 * if DCERPC_AUTH_TYPE_SCHANNEL is supported
+			 * it should be used, which means
+			 * we had a chance to verify no downgrade
+			 * happened.
+			 *
+			 * This relies on netlogon_creds_cli_check*
+			 * being called before, as first request after
+			 * the DCERPC bind.
+			 */
+			tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
+			return;
+		}
+	}
+
+	/*
+	 * we defer all callbacks in order to cleanup
+	 * the database record.
+	 */
+	tevent_req_defer_callback(req, state->ev);
+
+	state->tmp_creds = *state->creds;
+	netlogon_creds_client_authenticator(&state->tmp_creds,
+					    &state->req_auth);
+	ZERO_STRUCT(state->rep_auth);
+
+	subreq = dcerpc_netr_GetForestTrustInformation_send(state, state->ev,
+						state->binding_handle,
+						state->srv_name_slash,
+						state->tmp_creds.computer_name,
+						&state->req_auth,
+						&state->rep_auth,
+						state->flags,
+						&state->forest_trust_info);
+	if (tevent_req_nomem(subreq, req)) {
+		status = NT_STATUS_NO_MEMORY;
+		netlogon_creds_cli_GetForestTrustInformation_cleanup(req, status);
+		return;
+	}
+
+	tevent_req_set_callback(subreq,
+				netlogon_creds_cli_GetForestTrustInformation_done,
+				req);
+}
+
+static void netlogon_creds_cli_GetForestTrustInformation_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req =
+		tevent_req_callback_data(subreq,
+		struct tevent_req);
+	struct netlogon_creds_cli_GetForestTrustInformation_state *state =
+		tevent_req_data(req,
+		struct netlogon_creds_cli_GetForestTrustInformation_state);
+	NTSTATUS status;
+	NTSTATUS result;
+	bool ok;
+
+	/*
+	 * We use state->dns_names as the memory context, as this is
+	 * the only in/out variable and it has been overwritten by the
+	 * out parameter from the server.
+	 *
+	 * We need to preserve the return value until the caller can use it.
+	 */
+	status = dcerpc_netr_GetForestTrustInformation_recv(subreq, state, &result);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		netlogon_creds_cli_GetForestTrustInformation_cleanup(req, status);
+		return;
+	}
+
+	ok = netlogon_creds_client_check(&state->tmp_creds,
+					 &state->rep_auth.cred);
+	if (!ok) {
+		status = NT_STATUS_ACCESS_DENIED;
+		tevent_req_nterror(req, status);
+		netlogon_creds_cli_GetForestTrustInformation_cleanup(req, status);
+		return;
+	}
+
+	if (tevent_req_nterror(req, result)) {
+		netlogon_creds_cli_GetForestTrustInformation_cleanup(req, result);
+		return;
+	}
+
+	*state->creds = state->tmp_creds;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list