summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r--source4/librpc/rpc/dcerpc.c58
-rw-r--r--source4/librpc/rpc/dcerpc.h30
-rw-r--r--source4/librpc/rpc/dcerpc_auth.c63
-rw-r--r--source4/librpc/rpc/dcerpc_ntlm.c132
-rw-r--r--source4/librpc/rpc/dcerpc_schannel.c194
-rw-r--r--source4/librpc/rpc/dcerpc_util.c4
6 files changed, 162 insertions, 319 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index 82b6fa9a4e..5d5469da7f 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -42,9 +42,9 @@ struct dcerpc_pipe *dcerpc_pipe_init(void)
p->mem_ctx = mem_ctx;
p->call_id = 1;
p->security_state.auth_info = NULL;
- ZERO_STRUCT(p->security_state.user);
- p->security_state.private_data = NULL;
- p->security_state.ops = NULL;
+ ZERO_STRUCT(p->security_state.generic_state.user);
+ p->security_state.generic_state.private_data = NULL;
+ p->security_state.generic_state.ops = NULL;
p->binding_string = NULL;
p->flags = 0;
p->srv_max_xmit_frag = 0;
@@ -60,8 +60,8 @@ void dcerpc_pipe_close(struct dcerpc_pipe *p)
if (!p) return;
p->reference_count--;
if (p->reference_count <= 0) {
- if (p->security_state.ops) {
- p->security_state.ops->end(&p->security_state);
+ if (p->security_state.generic_state.ops) {
+ p->security_state.generic_state.ops->end(&p->security_state.generic_state);
}
p->transport.shutdown_pipe(p);
talloc_destroy(p->mem_ctx);
@@ -132,7 +132,7 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
DATA_BLOB auth_blob;
/* non-signed packets are simpler */
- if (!p->security_state.auth_info || !p->security_state.ops) {
+ if (!p->security_state.auth_info || !p->security_state.generic_state.ops) {
return dcerpc_pull(blob, mem_ctx, pkt);
}
@@ -186,19 +186,21 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
/* check signature or unseal the packet */
switch (p->security_state.auth_info->auth_level) {
case DCERPC_AUTH_LEVEL_PRIVACY:
- status = p->security_state.ops->unseal(&p->security_state,
- mem_ctx,
- pkt->u.response.stub_and_verifier.data,
- pkt->u.response.stub_and_verifier.length,
- &auth.credentials);
+ status = p->security_state
+ .generic_state.ops->unseal(&p->security_state.generic_state,
+ mem_ctx,
+ pkt->u.response.stub_and_verifier.data,
+ pkt->u.response.stub_and_verifier.length,
+ &auth.credentials);
break;
case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = p->security_state.ops->check_sig(&p->security_state,
- mem_ctx,
- pkt->u.response.stub_and_verifier.data,
- pkt->u.response.stub_and_verifier.length,
- &auth.credentials);
+ status = p->security_state
+ .generic_state.ops->check_sig(&p->security_state.generic_state,
+ mem_ctx,
+ pkt->u.response.stub_and_verifier.data,
+ pkt->u.response.stub_and_verifier.length,
+ &auth.credentials);
break;
case DCERPC_AUTH_LEVEL_NONE:
@@ -230,7 +232,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
struct ndr_push *ndr;
/* non-signed packets are simpler */
- if (!p->security_state.auth_info || !p->security_state.ops) {
+ if (!p->security_state.auth_info || !p->security_state.generic_state.ops) {
return dcerpc_push_auth(blob, mem_ctx, pkt, p->security_state.auth_info);
}
@@ -255,19 +257,21 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
/* sign or seal the packet */
switch (p->security_state.auth_info->auth_level) {
case DCERPC_AUTH_LEVEL_PRIVACY:
- status = p->security_state.ops->seal(&p->security_state,
- mem_ctx,
- ndr->data + DCERPC_REQUEST_LENGTH,
- ndr->offset - DCERPC_REQUEST_LENGTH,
- &p->security_state.auth_info->credentials);
+ status = p->security_state
+ .generic_state.ops->seal(&p->security_state.generic_state,
+ mem_ctx,
+ ndr->data + DCERPC_REQUEST_LENGTH,
+ ndr->offset - DCERPC_REQUEST_LENGTH,
+ &p->security_state.auth_info->credentials);
break;
case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = p->security_state.ops->sign(&p->security_state,
- mem_ctx,
- ndr->data + DCERPC_REQUEST_LENGTH,
- ndr->offset - DCERPC_REQUEST_LENGTH,
- &p->security_state.auth_info->credentials);
+ status = p->security_state
+ .generic_state.ops->sign(&p->security_state.generic_state,
+ mem_ctx,
+ ndr->data + DCERPC_REQUEST_LENGTH,
+ ndr->offset - DCERPC_REQUEST_LENGTH,
+ &p->security_state.auth_info->credentials);
break;
case DCERPC_AUTH_LEVEL_NONE:
diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h
index 7694a9c230..a513b72a16 100644
--- a/source4/librpc/rpc/dcerpc.h
+++ b/source4/librpc/rpc/dcerpc.h
@@ -25,38 +25,10 @@ enum dcerpc_transport_t {NCACN_NP, NCACN_IP_TCP};
/*
this defines a generic security context for signed/sealed dcerpc pipes.
*/
-struct dcerpc_security;
struct dcerpc_pipe;
-
-struct dcerpc_user {
- const char *domain;
- const char *name;
- const char *password;
-};
-
-struct dcesrv_security_ops {
- const char *name;
- uint8 auth_type;
- NTSTATUS (*start)(struct dcerpc_pipe *dce_pipe, struct dcerpc_security *dce_sec);
- NTSTATUS (*update)(struct dcerpc_security *dce_sec, TALLOC_CTX *out_mem_ctx,
- const DATA_BLOB in, DATA_BLOB *out);
- NTSTATUS (*seal)(struct dcerpc_security *dce_sec, TALLOC_CTX *sig_mem_ctx,
- uint8_t *data, size_t length, DATA_BLOB *sig);
- NTSTATUS (*sign)(struct dcerpc_security *dce_sec, TALLOC_CTX *sig_mem_ctx,
- const uint8_t *data, size_t length, DATA_BLOB *sig);
- NTSTATUS (*check_sig)(struct dcerpc_security *dce_sec, TALLOC_CTX *sig_mem_ctx,
- const uint8_t *data, size_t length, const DATA_BLOB *sig);
- NTSTATUS (*unseal)(struct dcerpc_security *dce_sec, TALLOC_CTX *sig_mem_ctx,
- uint8_t *data, size_t length, DATA_BLOB *sig);
- NTSTATUS (*session_key)(struct dcerpc_security *, DATA_BLOB *session_key);
- void (*end)(struct dcerpc_security *dce_sec);
-};
-
struct dcerpc_security {
struct dcerpc_auth *auth_info;
- struct dcerpc_user user;
- void *private_data;
- const struct dcesrv_security_ops *ops;
+ struct gensec_security generic_state;
};
struct dcerpc_pipe {
diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c
index 021249847a..e5fad1f082 100644
--- a/source4/librpc/rpc/dcerpc_auth.c
+++ b/source4/librpc/rpc/dcerpc_auth.c
@@ -1,9 +1,11 @@
/*
Unix SMB/CIFS implementation.
- dcerpc authentication operations
+ Generic Authentication Interface
Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -42,24 +44,8 @@ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p,
return status;
}
-const struct dcesrv_security_ops *dcerpc_security_by_authtype(uint8_t auth_type)
-{
- switch (auth_type) {
- case DCERPC_AUTH_TYPE_SCHANNEL:
- return dcerpc_schannel_security_get_ops();
-
- case DCERPC_AUTH_TYPE_NTLMSSP:
- return dcerpc_ntlmssp_security_get_ops();
- }
-
- return NULL;
-}
-
NTSTATUS dcerpc_bind_auth(struct dcerpc_pipe *p, uint8_t auth_type,
- const char *uuid, uint_t version,
- const char *domain,
- const char *username,
- const char *password)
+ const char *uuid, uint_t version)
{
NTSTATUS status;
TALLOC_CTX *mem_ctx;
@@ -69,20 +55,19 @@ NTSTATUS dcerpc_bind_auth(struct dcerpc_pipe *p, uint8_t auth_type,
if (!mem_ctx) {
return NT_STATUS_NO_MEMORY;
}
-
- p->security_state.ops = dcerpc_security_by_authtype(auth_type);
- if (!p->security_state.ops) {
- status = NT_STATUS_INVALID_PARAMETER;
- goto done;
- }
-
- p->security_state.user.domain = domain;
- p->security_state.user.name = username;
- p->security_state.user.password = password;
-
- status = p->security_state.ops->start(p, &p->security_state);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+
+ if (!p->security_state.generic_state.ops) {
+
+ p->security_state.generic_state.ops = gensec_security_by_authtype(auth_type);
+ if (!p->security_state.generic_state.ops) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ status = p->security_state.generic_state.ops->client_start(&p->security_state.generic_state);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
p->security_state.auth_info = talloc(p->mem_ctx, sizeof(*p->security_state.auth_info));
@@ -105,9 +90,9 @@ NTSTATUS dcerpc_bind_auth(struct dcerpc_pipe *p, uint8_t auth_type,
p->security_state.auth_info->auth_level = DCERPC_AUTH_LEVEL_NONE;
}
- status = p->security_state.ops->update(&p->security_state, mem_ctx,
- p->security_state.auth_info->credentials,
- &credentials);
+ status = p->security_state.generic_state.ops->update(&p->security_state.generic_state, mem_ctx,
+ p->security_state.auth_info->credentials,
+ &credentials);
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
goto done;
@@ -120,9 +105,9 @@ NTSTATUS dcerpc_bind_auth(struct dcerpc_pipe *p, uint8_t auth_type,
goto done;
}
- status = p->security_state.ops->update(&p->security_state, mem_ctx,
- p->security_state.auth_info->credentials,
- &credentials);
+ status = p->security_state.generic_state.ops->update(&p->security_state.generic_state, mem_ctx,
+ p->security_state.auth_info->credentials,
+ &credentials);
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
goto done;
@@ -140,3 +125,5 @@ done:
return status;
}
+
+
diff --git a/source4/librpc/rpc/dcerpc_ntlm.c b/source4/librpc/rpc/dcerpc_ntlm.c
index 2cfecd939f..398e3f1aa3 100644
--- a/source4/librpc/rpc/dcerpc_ntlm.c
+++ b/source4/librpc/rpc/dcerpc_ntlm.c
@@ -23,127 +23,7 @@
#include "includes.h"
/*
- wrappers for the ntlmssp_*() functions
-*/
-static NTSTATUS dcerpc_ntlmssp_unseal(struct dcerpc_security *dcerpc_security,
- TALLOC_CTX *mem_ctx,
- uint8_t *data, size_t length, DATA_BLOB *sig)
-{
- struct ntlmssp_state *ntlmssp_state = dcerpc_security->private_data;
-
- return ntlmssp_unseal_packet(ntlmssp_state, mem_ctx, data, length, sig);
-}
-
-static NTSTATUS dcerpc_ntlmssp_check_sig(struct dcerpc_security *dcerpc_security,
- TALLOC_CTX *mem_ctx,
- const uint8_t *data, size_t length,
- const DATA_BLOB *sig)
-{
- struct ntlmssp_state *ntlmssp_state = dcerpc_security->private_data;
-
- return ntlmssp_check_packet(ntlmssp_state, mem_ctx, data, length, sig);
-}
-
-static NTSTATUS dcerpc_ntlmssp_seal(struct dcerpc_security *dcerpc_security,
- TALLOC_CTX *mem_ctx,
- uint8_t *data, size_t length,
- DATA_BLOB *sig)
-{
- struct ntlmssp_state *ntlmssp_state = dcerpc_security->private_data;
-
- return ntlmssp_seal_packet(ntlmssp_state, mem_ctx, data, length, sig);
-}
-
-static NTSTATUS dcerpc_ntlmssp_sign(struct dcerpc_security *dcerpc_security,
- TALLOC_CTX *mem_ctx,
- const uint8_t *data, size_t length,
- DATA_BLOB *sig)
-{
- struct ntlmssp_state *ntlmssp_state = dcerpc_security->private_data;
-
- return ntlmssp_sign_packet(ntlmssp_state, mem_ctx, data, length, sig);
-}
-
-static NTSTATUS dcerpc_ntlmssp_session_key(struct dcerpc_security *dcerpc_security,
- DATA_BLOB *session_key)
-{
- struct ntlmssp_state *ntlmssp_state = dcerpc_security->private_data;
-
- if (!ntlmssp_state->session_key.data) {
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
- *session_key = ntlmssp_state->session_key;
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS dcerpc_ntlmssp_start(struct dcerpc_pipe *dce_pipe, struct dcerpc_security *dcerpc_security)
-{
- struct ntlmssp_state *ntlmssp_state = NULL;
- NTSTATUS status;
-
- status = ntlmssp_client_start(&ntlmssp_state);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = ntlmssp_set_domain(ntlmssp_state, dcerpc_security->user.domain);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = ntlmssp_set_username(ntlmssp_state, dcerpc_security->user.name);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = ntlmssp_set_password(ntlmssp_state, dcerpc_security->user.password);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- dcerpc_security->private_data = ntlmssp_state;
-
- return status;
-}
-
-static NTSTATUS dcerpc_ntlmssp_update(struct dcerpc_security *dcerpc_security, TALLOC_CTX *out_mem_ctx,
- const DATA_BLOB in, DATA_BLOB *out)
-{
- struct ntlmssp_state *ntlmssp_state = dcerpc_security->private_data;
-
- return ntlmssp_update(ntlmssp_state, out_mem_ctx, in, out);
-}
-
-static void dcerpc_ntlmssp_end(struct dcerpc_security *dcerpc_security)
-{
- struct ntlmssp_state *ntlmssp_state = dcerpc_security->private_data;
-
- ntlmssp_end(&ntlmssp_state);
-
- dcerpc_security->private_data = NULL;
-}
-
-static const struct dcesrv_security_ops dcerpc_ntlmssp_security_ops = {
- .name = "ntlmssp",
- .auth_type = DCERPC_AUTH_TYPE_NTLMSSP,
- .start = dcerpc_ntlmssp_start,
- .update = dcerpc_ntlmssp_update,
- .seal = dcerpc_ntlmssp_seal,
- .sign = dcerpc_ntlmssp_sign,
- .check_sig = dcerpc_ntlmssp_check_sig,
- .unseal = dcerpc_ntlmssp_unseal,
- .session_key = dcerpc_ntlmssp_session_key,
- .end = dcerpc_ntlmssp_end
-};
-
-const struct dcesrv_security_ops *dcerpc_ntlmssp_security_get_ops(void)
-{
- return &dcerpc_ntlmssp_security_ops;
-}
-
-/*
- do ntlm style authentication on a dcerpc pipe
+ do ntlm style authentication on a gensec pipe
*/
NTSTATUS dcerpc_bind_auth_ntlm(struct dcerpc_pipe *p,
const char *uuid, uint_t version,
@@ -153,12 +33,12 @@ NTSTATUS dcerpc_bind_auth_ntlm(struct dcerpc_pipe *p,
{
NTSTATUS status;
+ p->security_state.generic_state.user.domain = domain;
+ p->security_state.generic_state.user.name = username;
+ p->security_state.generic_state.user.password = password;
+
status = dcerpc_bind_auth(p, DCERPC_AUTH_TYPE_NTLMSSP,
- uuid, version,
- domain, username,
- password);
+ uuid, version);
return status;
}
-
-
diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c
index df15edfb6f..b43dd0788a 100644
--- a/source4/librpc/rpc/dcerpc_schannel.c
+++ b/source4/librpc/rpc/dcerpc_schannel.c
@@ -32,109 +32,68 @@ struct dcerpc_schannel_state {
struct schannel_state *schannel_state;
};
+static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
+ const char *domain,
+ const char *username,
+ const char *password,
+ int chan_type,
+ uint8_t new_session_key[16]);
+
/*
wrappers for the schannel_*() functions
+
+ These will become static again, when we get dynamic registration, and
+ decrpc_schannel_security_ops come back here.
*/
-static NTSTATUS dcerpc_schannel_unseal(struct dcerpc_security *dcerpc_security,
+static NTSTATUS dcerpc_schannel_unseal(struct gensec_security *gensec_security,
TALLOC_CTX *mem_ctx,
uint8_t *data, size_t length, DATA_BLOB *sig)
{
- struct dcerpc_schannel_state *dce_schan_state = dcerpc_security->private_data;
+ struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
return schannel_unseal_packet(dce_schan_state->schannel_state, mem_ctx, data, length, sig);
}
-static NTSTATUS dcerpc_schannel_check_sig(struct dcerpc_security *dcerpc_security,
+static NTSTATUS dcerpc_schannel_check_sig(struct gensec_security *gensec_security,
TALLOC_CTX *mem_ctx,
const uint8_t *data, size_t length,
const DATA_BLOB *sig)
{
- struct dcerpc_schannel_state *dce_schan_state = dcerpc_security->private_data;
+ struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
return schannel_check_packet(dce_schan_state->schannel_state, data, length, sig);
}
-static NTSTATUS dcerpc_schannel_seal(struct dcerpc_security *dcerpc_security,
+static NTSTATUS dcerpc_schannel_seal(struct gensec_security *gensec_security,
TALLOC_CTX *mem_ctx,
uint8_t *data, size_t length,
DATA_BLOB *sig)
{
- struct dcerpc_schannel_state *dce_schan_state = dcerpc_security->private_data;
+ struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
return schannel_seal_packet(dce_schan_state->schannel_state, mem_ctx, data, length, sig);
}
-static NTSTATUS dcerpc_schannel_sign(struct dcerpc_security *dcerpc_security,
+static NTSTATUS dcerpc_schannel_sign(struct gensec_security *gensec_security,
TALLOC_CTX *mem_ctx,
const uint8_t *data, size_t length,
DATA_BLOB *sig)
{
- struct dcerpc_schannel_state *dce_schan_state = dcerpc_security->private_data;
+ struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
return schannel_sign_packet(dce_schan_state->schannel_state, mem_ctx, data, length, sig);
}
-static NTSTATUS dcerpc_schannel_session_key(struct dcerpc_security *dcerpc_security,
+static NTSTATUS dcerpc_schannel_session_key(struct gensec_security *gensec_security,
DATA_BLOB *session_key)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS dcerpc_schannel_start(struct dcerpc_pipe *p, struct dcerpc_security *dcerpc_security)
-{
- struct dcerpc_schannel_state *dce_schan_state;
- TALLOC_CTX *mem_ctx;
- NTSTATUS status;
- uint8_t session_key[16];
- int chan_type = 0;
-
- if (p->flags & DCERPC_SCHANNEL_BDC) {
- chan_type = SEC_CHAN_BDC;
- } else if (p->flags & DCERPC_SCHANNEL_WORKSTATION) {
- chan_type = SEC_CHAN_WKSTA;
- } else if (p->flags & DCERPC_SCHANNEL_DOMAIN) {
- chan_type = SEC_CHAN_DOMAIN;
- }
-
- status = dcerpc_schannel_key(p, dcerpc_security->user.domain,
- dcerpc_security->user.name,
- dcerpc_security->user.password,
- chan_type, session_key);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- mem_ctx = talloc_init("dcerpc_schannel_start");
- if (!mem_ctx) {
- return NT_STATUS_NO_MEMORY;
- }
-
- dce_schan_state = talloc_p(mem_ctx, struct dcerpc_schannel_state);
- if (!dce_schan_state) {
- talloc_destroy(mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- dce_schan_state->mem_ctx = mem_ctx;
-
- status = schannel_start(&dce_schan_state->schannel_state, session_key, True);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- dce_schan_state->state = DCERPC_SCHANNEL_STATE_START;
-
- dcerpc_security->private_data = dce_schan_state;
-
- dump_data_pw("session key:\n", dce_schan_state->schannel_state->session_key, 16);
-
- return status;
-}
-
-static NTSTATUS dcerpc_schannel_update(struct dcerpc_security *dcerpc_security, TALLOC_CTX *out_mem_ctx,
+static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx,
const DATA_BLOB in, DATA_BLOB *out)
{
- struct dcerpc_schannel_state *dce_schan_state = dcerpc_security->private_data;
+ struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
NTSTATUS status;
struct schannel_bind bind_schannel;
@@ -148,14 +107,14 @@ static NTSTATUS dcerpc_schannel_update(struct dcerpc_security *dcerpc_security,
#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 = dcerpc_security->user.domain;
- bind_schannel.u.info23.account_name = dcerpc_security->user.name;
+ bind_schannel.u.info23.domain = gensec_security->user.domain;
+ bind_schannel.u.info23.account_name = gensec_security->user.name;
bind_schannel.u.info23.dnsdomain = str_format_nbt_domain(dce_schan_state->mem_ctx, fulldomainname);
- bind_schannel.u.info23.workstation = str_format_nbt_domain(dce_schan_state->mem_ctx, dcerpc_security->user.name);
+ bind_schannel.u.info23.workstation = str_format_nbt_domain(dce_schan_state->mem_ctx, gensec_security->user.name);
#else
bind_schannel.bind_type = 3;
- bind_schannel.u.info3.domain = dcerpc_security->user.domain;
- bind_schannel.u.info3.account_name = dcerpc_security->user.name;
+ bind_schannel.u.info3.domain = gensec_security->user.domain;
+ bind_schannel.u.info3.account_name = gensec_security->user.name;
#endif
status = ndr_push_struct_blob(out, dce_schan_state->mem_ctx, &bind_schannel,
@@ -167,27 +126,39 @@ static NTSTATUS dcerpc_schannel_update(struct dcerpc_security *dcerpc_security,
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
-static void dcerpc_schannel_end(struct dcerpc_security *dcerpc_security)
+static void dcerpc_schannel_end(struct gensec_security *gensec_security)
{
- struct dcerpc_schannel_state *dce_schan_state = dcerpc_security->private_data;
+ struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
schannel_end(&dce_schan_state->schannel_state);
talloc_destroy(dce_schan_state->mem_ctx);
- dcerpc_security->private_data = NULL;
+ gensec_security->private_data = NULL;
}
+static const struct gensec_security_ops gensec_dcerpc_schannel_security_ops = {
+ .name = "dcerpc_schannel",
+ .auth_type = DCERPC_AUTH_TYPE_SCHANNEL,
+ .update = dcerpc_schannel_update,
+ .seal = dcerpc_schannel_seal,
+ .sign = dcerpc_schannel_sign,
+ .check_sig = dcerpc_schannel_check_sig,
+ .unseal = dcerpc_schannel_unseal,
+ .session_key = dcerpc_schannel_session_key,
+ .end = dcerpc_schannel_end
+};
+
/*
get a schannel key using a netlogon challenge on a secondary pipe
*/
-NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
- const char *domain,
- const char *username,
- const char *password,
- int chan_type,
- uint8_t new_session_key[16])
+static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
+ const char *domain,
+ const char *username,
+ const char *password,
+ int chan_type,
+ uint8_t new_session_key[16])
{
NTSTATUS status;
struct dcerpc_pipe *p2;
@@ -269,24 +240,6 @@ NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
return NT_STATUS_OK;
}
-const struct dcesrv_security_ops dcerpc_schannel_security_ops = {
- .name = "schannel",
- .auth_type = DCERPC_AUTH_TYPE_SCHANNEL,
- .start = dcerpc_schannel_start,
- .update = dcerpc_schannel_update,
- .seal = dcerpc_schannel_seal,
- .sign = dcerpc_schannel_sign,
- .check_sig = dcerpc_schannel_check_sig,
- .unseal = dcerpc_schannel_unseal,
- .session_key = dcerpc_schannel_session_key,
- .end = dcerpc_schannel_end
-};
-
-const struct dcesrv_security_ops *dcerpc_schannel_security_get_ops(void)
-{
- return &dcerpc_schannel_security_ops;
-}
-
/*
do a schannel style bind on a dcerpc pipe. The username is usually
of the form HOSTNAME$ and the password is the domain trust password
@@ -298,11 +251,58 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
const char *password)
{
NTSTATUS status;
+ struct dcerpc_schannel_state *dce_schan_state;
+ TALLOC_CTX *mem_ctx;
+ uint8_t session_key[16];
+ int chan_type = 0;
+
+ if (p->flags & DCERPC_SCHANNEL_BDC) {
+ chan_type = SEC_CHAN_BDC;
+ } else if (p->flags & DCERPC_SCHANNEL_WORKSTATION) {
+ chan_type = SEC_CHAN_WKSTA;
+ } else if (p->flags & DCERPC_SCHANNEL_DOMAIN) {
+ chan_type = SEC_CHAN_DOMAIN;
+ }
+
+ status = dcerpc_schannel_key(p, domain,
+ username,
+ password,
+ chan_type, session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ mem_ctx = talloc_init("dcerpc_schannel_start");
+ if (!mem_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ dce_schan_state = talloc_p(mem_ctx, struct dcerpc_schannel_state);
+ if (!dce_schan_state) {
+ talloc_destroy(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ dce_schan_state->mem_ctx = mem_ctx;
+
+ status = schannel_start(&dce_schan_state->schannel_state, session_key, True);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ dce_schan_state->state = DCERPC_SCHANNEL_STATE_START;
+
+ p->security_state.generic_state.user.domain = domain;
+ p->security_state.generic_state.user.name = username;
+ p->security_state.generic_state.user.password = password;
+
+ p->security_state.generic_state.ops = &gensec_dcerpc_schannel_security_ops;
+ p->security_state.generic_state.private_data = dce_schan_state;
+
+ dump_data_pw("session key:\n", dce_schan_state->schannel_state->session_key, 16);
status = dcerpc_bind_auth(p, DCERPC_AUTH_TYPE_SCHANNEL,
- uuid, version,
- domain, username,
- password);
+ uuid, version);
return status;
}
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index 8c9b273896..82aa5aa1f3 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -697,8 +697,8 @@ NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p,
{
struct cli_tree *tree;
- if (p->security_state.ops) {
- return p->security_state.ops->session_key(&p->security_state, session_key);
+ if (p->security_state.generic_state.ops) {
+ return p->security_state.generic_state.ops->session_key(&p->security_state.generic_state, session_key);
}
tree = dcerpc_smb_tree(p);