*/
#include "includes.h"
+#include "../libcli/auth/libcli_auth.h"
+#include "../librpc/gen_ndr/ndr_schannel.h"
extern struct current_user current_user;
Used to reject unknown binds from Win2k.
*******************************************************************/
-bool check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
- RPC_IFACE* transfer, uint32 context_id)
+static bool check_bind_req(struct pipes_struct *p,
+ struct ndr_syntax_id* abstract,
+ struct ndr_syntax_id* transfer,
+ uint32 context_id)
{
int i=0;
struct pipe_rpc_fns *context_fns;
RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
{
RPC_HDR_AUTH auth_info;
- RPC_AUTH_SCHANNEL_NEG neg;
+ struct NL_AUTH_MESSAGE neg;
RPC_AUTH_VERIFIER auth_verifier;
bool ret;
- struct dcinfo *pdcinfo;
+ NTSTATUS status;
+ struct netlogon_creds_CredentialState *creds;
uint32 flags;
DATA_BLOB session_key;
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+
+ blob = data_blob_const(prs_data_p(rpc_in_p) + prs_offset(rpc_in_p),
+ prs_data_size(rpc_in_p));
- if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) {
+ ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &neg,
+ (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
- return False;
+ return false;
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
+ }
+
+ if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
+ DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
+ return false;
}
/*
- * The neg.myname key here must match the remote computer name
+ * The neg.oem_netbios_computer.a key here must match the remote computer name
* given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
* operations that use credentials.
*/
become_root();
- ret = secrets_restore_schannel_session_info(p->mem_ctx, neg.myname, &pdcinfo);
+ status = schannel_fetch_session_key(p->mem_ctx,
+ neg.oem_netbios_computer.a,
+ &creds);
unbecome_root();
- if (!ret) {
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
return False;
}
p->auth.a_u.schannel_auth = talloc(p, struct schannel_auth_struct);
if (!p->auth.a_u.schannel_auth) {
- TALLOC_FREE(pdcinfo);
+ TALLOC_FREE(creds);
return False;
}
memset(p->auth.a_u.schannel_auth->sess_key, 0, sizeof(p->auth.a_u.schannel_auth->sess_key));
- memcpy(p->auth.a_u.schannel_auth->sess_key, pdcinfo->sess_key,
- sizeof(pdcinfo->sess_key));
+ memcpy(p->auth.a_u.schannel_auth->sess_key, creds->session_key,
+ sizeof(creds->session_key));
- TALLOC_FREE(pdcinfo);
+ TALLOC_FREE(creds);
p->auth.a_u.schannel_auth->seq_num = 0;
}
DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
- neg.domain, neg.myname));
+ neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
/* We're finished with this bind - no more packets. */
p->auth.auth_data_free_func = NULL;
0x1, 0x0, 0x0,
&hdr_rb.rpc_context[0].transfer[0]);
} else {
- RPC_IFACE null_interface;
- ZERO_STRUCT(null_interface);
/* Rejection reason: abstract syntax not supported */
init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN,
RPC_MAX_PDU_FRAG_LEN, assoc_gid,
ack_pipe_name, 0x1, 0x2, 0x1,
- &null_interface);
+ &null_ndr_syntax_id);
p->pipe_bound = False;
}
0x1, 0x0, 0x0,
&hdr_rb.rpc_context[0].transfer[0]);
} else {
- RPC_IFACE null_interface;
- ZERO_STRUCT(null_interface);
/* Rejection reason: abstract syntax not supported */
init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN,
RPC_MAX_PDU_FRAG_LEN, assoc_gid,
ack_pipe_name, 0x1, 0x2, 0x1,
- &null_interface);
+ &null_ndr_syntax_id);
p->pipe_bound = False;
}
auth_len = p->hdr.auth_len;
- if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
+ if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN ||
+ auth_len > RPC_HEADER_LEN +
+ RPC_HDR_REQ_LEN +
+ RPC_HDR_AUTH_LEN +
+ auth_len) {
DEBUG(0,("Incorrect auth_len %u.\n", (unsigned int)auth_len ));
return False;
}