From 8b0f54027ca5c836add755899d128467e9b67ebd Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=BCnther=20Deschner?= Date: Sun, 13 Sep 2009 01:35:06 +0200 Subject: [PATCH] s4-schannel: use NL_AUTH_MESSAGE for schannel. Guenther --- source4/auth/gensec/schannel.c | 58 +++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/source4/auth/gensec/schannel.c b/source4/auth/gensec/schannel.c index 720ce77291b..15d64436e39 100644 --- a/source4/auth/gensec/schannel.c +++ b/source4/auth/gensec/schannel.c @@ -48,12 +48,14 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ struct schannel_state *state = (struct schannel_state *)gensec_security->private_data; NTSTATUS status; enum ndr_err_code ndr_err; - struct schannel_bind bind_schannel; - struct schannel_bind_ack bind_schannel_ack; + struct NL_AUTH_MESSAGE bind_schannel; + struct NL_AUTH_MESSAGE bind_schannel_ack; struct netlogon_creds_CredentialState *creds; struct ldb_context *schannel_ldb; const char *workstation; const char *domain; + uint32_t required_flags; + *out = data_blob(NULL, 0); switch (gensec_security->gensec_role) { @@ -65,26 +67,31 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ state->creds = talloc_reference(state, cli_credentials_get_netlogon_creds(gensec_security->credentials)); - bind_schannel.unknown1 = 0; + bind_schannel.MessageType = NL_NEGOTIATE_REQUEST; #if 0 /* to support this we'd need to have access to the full domain name */ - bind_schannel.bind_type = 23; - bind_schannel.u.info23.domain = cli_credentials_get_domain(gensec_security->credentials); - bind_schannel.u.info23.workstation = cli_credentials_get_workstation(gensec_security->credentials); - bind_schannel.u.info23.dnsdomain = cli_credentials_get_realm(gensec_security->credentials); + /* 0x17, 23 */ + bind_schannel.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME | + NL_FLAG_OEM_NETBIOS_COMPUTER_NAME | + NL_FLAG_UTF8_DNS_DOMAIN_NAME | + NL_FLAG_UTF8_NETBIOS_COMPUTER_NAME; + bind_schannel.oem_netbios_domain.a = cli_credentials_get_domain(gensec_security->credentials); + bind_schannel.oem_netbios_computer.a = cli_credentials_get_workstation(gensec_security->credentials); + bind_schannel.utf8_dns_domain = cli_credentials_get_realm(gensec_security->credentials); /* w2k3 refuses us if we use the full DNS workstation? why? perhaps because we don't fill in the dNSHostName attribute in the machine account? */ - bind_schannel.u.info23.dnsworkstation = cli_credentials_get_workstation(gensec_security->credentials); + bind_schannel.utf8_netbios_computer = cli_credentials_get_workstation(gensec_security->credentials); #else - bind_schannel.bind_type = 3; - bind_schannel.u.info3.domain = cli_credentials_get_domain(gensec_security->credentials); - bind_schannel.u.info3.workstation = cli_credentials_get_workstation(gensec_security->credentials); + bind_schannel.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME | + NL_FLAG_OEM_NETBIOS_COMPUTER_NAME; + bind_schannel.oem_netbios_domain.a = cli_credentials_get_domain(gensec_security->credentials); + bind_schannel.oem_netbios_computer.a = cli_credentials_get_workstation(gensec_security->credentials); #endif ndr_err = ndr_push_struct_blob(out, out_mem_ctx, gensec_security->settings->iconv_convenience, &bind_schannel, - (ndr_push_flags_fn_t)ndr_push_schannel_bind); + (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); DEBUG(3, ("Could not create schannel bind: %s\n", @@ -97,6 +104,9 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ return NT_STATUS_MORE_PROCESSING_REQUIRED; case GENSEC_SERVER: + required_flags = NL_FLAG_OEM_NETBIOS_COMPUTER_NAME | + NL_FLAG_OEM_NETBIOS_DOMAIN_NAME; + if (state->state != SCHANNEL_STATE_START) { /* no third leg on this protocol */ return NT_STATUS_INVALID_PARAMETER; @@ -106,7 +116,7 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ ndr_err = ndr_pull_struct_blob(&in, out_mem_ctx, gensec_security->settings->iconv_convenience, &bind_schannel, - (ndr_pull_flags_fn_t)ndr_pull_schannel_bind); + (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); DEBUG(3, ("Could not parse incoming schannel bind: %s\n", @@ -114,14 +124,13 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ return status; } - if (bind_schannel.bind_type == 23) { - workstation = bind_schannel.u.info23.workstation; - domain = bind_schannel.u.info23.domain; - } else { - workstation = bind_schannel.u.info3.workstation; - domain = bind_schannel.u.info3.domain; + if (!(required_flags == (bind_schannel.Flags & required_flags))) { + return NT_STATUS_INVALID_PARAMETER; } + workstation = bind_schannel.oem_netbios_computer.a; + domain = bind_schannel.oem_netbios_domain.a; + if (strcasecmp_m(domain, lp_workgroup(gensec_security->settings->lp_ctx)) != 0) { DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n", domain, lp_workgroup(gensec_security->settings->lp_ctx))); @@ -149,13 +158,16 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ state->creds = talloc_reference(state, creds); - bind_schannel_ack.unknown1 = 1; - bind_schannel_ack.unknown2 = 0; - bind_schannel_ack.unknown3 = 0x6c0000; + bind_schannel_ack.MessageType = NL_NEGOTIATE_RESPONSE; + bind_schannel_ack.Flags = 0; + bind_schannel_ack.Buffer.dummy = 0x6c0000; /* actually I think + * this does not have + * any meaning here + * - gd */ ndr_err = ndr_push_struct_blob(out, out_mem_ctx, gensec_security->settings->iconv_convenience, &bind_schannel_ack, - (ndr_push_flags_fn_t)ndr_push_schannel_bind_ack); + (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); DEBUG(3, ("Could not return schannel bind ack for client %s: %s\n", -- 2.11.4.GIT