summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc/dcerpc_schannel.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2004-06-20 00:58:09 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:56:44 -0500
commitbe081037e09bb78c0308cd6c7a5d7ae563678b7c (patch)
tree4bdabbe93653433e696d4abc4ac3b2991e59aed6 /source4/librpc/rpc/dcerpc_schannel.c
parent8cb41badd4349b7d9d78ff8e25143929522e4749 (diff)
downloadsamba-be081037e09bb78c0308cd6c7a5d7ae563678b7c.tar.gz
samba-be081037e09bb78c0308cd6c7a5d7ae563678b7c.tar.bz2
samba-be081037e09bb78c0308cd6c7a5d7ae563678b7c.zip
r1200: Add 'gensec', our generic security layer.
This layer is used for DCERPC security, as well as ntlm_auth at this time. It expect things like SASL and the CIFS layer to use it as well. The particular purpose of this layer is to introduce SPENGO, which needs generic access to the actual implementation mechanisms. Schannel, due to it's 'interesting' setup properties is in GENSEC, but is only in the RPC code. Andrew Bartlett (This used to be commit 902af49006fb8cfecaadd3cc0c10e2e542083fb1)
Diffstat (limited to 'source4/librpc/rpc/dcerpc_schannel.c')
-rw-r--r--source4/librpc/rpc/dcerpc_schannel.c194
1 files changed, 97 insertions, 97 deletions
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;
}