diff options
Diffstat (limited to 'source4/rpc_server/dcesrv_crypto_schannel.c')
-rw-r--r-- | source4/rpc_server/dcesrv_crypto_schannel.c | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/source4/rpc_server/dcesrv_crypto_schannel.c b/source4/rpc_server/dcesrv_crypto_schannel.c index fba882e2a4..5da1a171f9 100644 --- a/source4/rpc_server/dcesrv_crypto_schannel.c +++ b/source4/rpc_server/dcesrv_crypto_schannel.c @@ -28,6 +28,36 @@ struct srv_schannel_state { struct schannel_state *state; }; +static NTSTATUS schannel_setup_session_info(struct srv_schannel_state *schannel, + const char *account_name, + struct auth_session_info **session_info) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("schannel_setup"); + if (mem_ctx == NULL) { + return NT_STATUS_NO_MEMORY; + } + + (*session_info) = talloc_p(mem_ctx, struct auth_session_info); + if (*session_info == NULL) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + ZERO_STRUCTP(*session_info); + + (*session_info)->workstation = talloc_strdup(mem_ctx, account_name); + if ((*session_info)->workstation == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* TODO: fill in the rest of the session_info structure */ + + return NT_STATUS_OK; +} + + /* start crypto state */ @@ -36,9 +66,9 @@ static NTSTATUS dcesrv_crypto_schannel_start(struct dcesrv_auth *auth, DATA_BLOB struct srv_schannel_state *schannel = NULL; NTSTATUS status; TALLOC_CTX *mem_ctx; - uint8_t session_key[16]; const char *account_name; struct schannel_bind_ack ack; + struct creds_CredentialState creds; mem_ctx = talloc_init("schannel_start"); if (!mem_ctx) { @@ -58,7 +88,7 @@ static NTSTATUS dcesrv_crypto_schannel_start(struct dcesrv_auth *auth, DATA_BLOB (ndr_pull_flags_fn_t)ndr_pull_schannel_bind); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); - return NT_STATUS_INVALID_PARAMETER; + return status; } if (schannel->bind_info.bind_type == 23) { @@ -68,23 +98,25 @@ static NTSTATUS dcesrv_crypto_schannel_start(struct dcesrv_auth *auth, DATA_BLOB } /* pull the session key for this client */ - status = schannel_fetch_session_key(mem_ctx, account_name, session_key); + status = schannel_fetch_session_key(mem_ctx, account_name, &creds); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); - return NT_STATUS_INVALID_HANDLE; + return status; } - + /* start up the schannel server code */ - status = schannel_start(&schannel->state, session_key, False); + status = schannel_start(&schannel->state, creds.session_key, False); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); - return NT_STATUS_INVALID_HANDLE; + return status; } - /* TODO: here we need to set the session_info - * what should happen when te session_info is already set - */ - auth->session_info = NULL; + status = schannel_setup_session_info(schannel, account_name, + &auth->session_info); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + return status; + } auth->crypto_ctx.private_data = schannel; @@ -156,6 +188,18 @@ static NTSTATUS dcesrv_crypto_schannel_unseal(struct dcesrv_auth *auth, TALLOC_C } /* + get the session key +*/ +static NTSTATUS dcesrv_crypto_schannel_session_key(struct dcesrv_auth *auth, uint8_t session_key[16]) +{ + struct srv_schannel_state *srv_schannel_state = auth->crypto_ctx.private_data; + + memcpy(session_key, srv_schannel_state->state->session_key, 16); + + return NT_STATUS_OK; +} + +/* end crypto state */ static void dcesrv_crypto_schannel_end(struct dcesrv_auth *auth) @@ -182,6 +226,7 @@ static const struct dcesrv_crypto_ops dcesrv_crypto_schannel_ops = { .sign = dcesrv_crypto_schannel_sign, .check_sig = dcesrv_crypto_schannel_check_sig, .unseal = dcesrv_crypto_schannel_unseal, + .session_key = dcesrv_crypto_schannel_session_key, .end = dcesrv_crypto_schannel_end }; |