summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-03-27 21:13:31 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:18:58 -0500
commit4a66d0e232271968ba96da50274428916a393975 (patch)
tree89e40c8ad86d96458905940839a5ddba4f1bd747 /source3/smbd
parent34dac35e48ca0c03d2744d9925566665285eb973 (diff)
downloadsamba-4a66d0e232271968ba96da50274428916a393975.tar.gz
samba-4a66d0e232271968ba96da50274428916a393975.tar.bz2
samba-4a66d0e232271968ba96da50274428916a393975.zip
r21991: I hate Steve French :-). Add support for encryption
contexts.... Jeremy. (This used to be commit ae8f3649f773b8a8dcb55921536d038d3475322e)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/seal.c96
-rw-r--r--source3/smbd/trans2.c12
2 files changed, 90 insertions, 18 deletions
diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c
index fbb0eade52..d5b956c53d 100644
--- a/source3/smbd/seal.c
+++ b/source3/smbd/seal.c
@@ -249,6 +249,14 @@ static struct smb_srv_trans_enc_ctx *make_srv_encryption_context(enum smb_trans_
void srv_free_enc_buffer(char *buf)
{
+ /* We know this is an smb buffer, and we
+ * didn't malloc, only copy, for a keepalive,
+ * so ignore session keepalives. */
+
+ if(CVAL(buf,0) == SMBkeepalive) {
+ return;
+ }
+
if (srv_trans_enc_ctx) {
common_free_enc_buffer(srv_trans_enc_ctx->es, buf);
}
@@ -260,9 +268,15 @@ void srv_free_enc_buffer(char *buf)
NTSTATUS srv_decrypt_buffer(char *buf)
{
+ /* Ignore session keepalives. */
+ if(CVAL(buf,0) == SMBkeepalive) {
+ return NT_STATUS_OK;
+ }
+
if (srv_trans_enc_ctx) {
return common_decrypt_buffer(srv_trans_enc_ctx->es, buf);
}
+
return NT_STATUS_OK;
}
@@ -270,13 +284,19 @@ NTSTATUS srv_decrypt_buffer(char *buf)
Encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
******************************************************************************/
-NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out)
+NTSTATUS srv_encrypt_buffer(char *buf, char **buf_out)
{
+ *buf_out = buf;
+
+ /* Ignore session keepalives. */
+ if(CVAL(buf,0) == SMBkeepalive) {
+ return NT_STATUS_OK;
+ }
+
if (srv_trans_enc_ctx) {
- return common_encrypt_buffer(srv_trans_enc_ctx->es, buffer, buf_out);
+ return common_encrypt_buffer(srv_trans_enc_ctx->es, buf, buf_out);
}
/* Not encrypting. */
- *buf_out = buffer;
return NT_STATUS_OK;
}
@@ -340,7 +360,11 @@ static NTSTATUS srv_enc_ntlm_negotiate(unsigned char **ppdata, size_t *p_data_si
Until success we do everything on the partial enc ctx.
******************************************************************************/
-static NTSTATUS srv_enc_spnego_negotiate(unsigned char **ppdata, size_t *p_data_size)
+static NTSTATUS srv_enc_spnego_negotiate(connection_struct *conn,
+ unsigned char **ppdata,
+ size_t *p_data_size,
+ unsigned char **pparam,
+ size_t *p_param_size)
{
NTSTATUS status;
DATA_BLOB blob = data_blob(NULL,0);
@@ -371,6 +395,17 @@ static NTSTATUS srv_enc_spnego_negotiate(unsigned char **ppdata, size_t *p_data_
if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
srv_free_encryption_context(&partial_srv_trans_enc_ctx);
+ return nt_status_squash(status);
+ }
+
+ if (NT_STATUS_IS_OK(status)) {
+ /* Return the context we're using for this encryption state. */
+ *pparam = SMB_MALLOC(2);
+ if (!*pparam) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ SSVAL(*pparam,0,partial_srv_trans_enc_ctx->es->enc_ctx_num);
+ *p_param_size = 2;
}
return status;
@@ -381,7 +416,11 @@ static NTSTATUS srv_enc_spnego_negotiate(unsigned char **ppdata, size_t *p_data_
We only get this for a NTLM auth second stage.
******************************************************************************/
-static NTSTATUS srv_enc_spnego_ntlm_auth(unsigned char **ppdata, size_t *p_data_size)
+static NTSTATUS srv_enc_spnego_ntlm_auth(connection_struct *conn,
+ unsigned char **ppdata,
+ size_t *p_data_size,
+ unsigned char **pparam,
+ size_t *p_param_size)
{
NTSTATUS status;
DATA_BLOB blob = data_blob(NULL,0);
@@ -409,6 +448,16 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(unsigned char **ppdata, size_t *p_data_
response = spnego_gen_auth_response(&auth_reply, status, OID_NTLMSSP);
data_blob_free(&auth_reply);
+ if (NT_STATUS_IS_OK(status)) {
+ /* Return the context we're using for this encryption state. */
+ *pparam = SMB_MALLOC(2);
+ if (!*pparam) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ SSVAL(*pparam,0,ec->es->enc_ctx_num);
+ *p_param_size = 2;
+ }
+
SAFE_FREE(*ppdata);
*ppdata = response.data;
*p_data_size = response.length;
@@ -420,7 +469,11 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(unsigned char **ppdata, size_t *p_data_
This function does both steps.
******************************************************************************/
-static NTSTATUS srv_enc_raw_ntlm_auth(unsigned char **ppdata, size_t *p_data_size)
+static NTSTATUS srv_enc_raw_ntlm_auth(connection_struct *conn,
+ unsigned char **ppdata,
+ size_t *p_data_size,
+ unsigned char **pparam,
+ size_t *p_param_size)
{
NTSTATUS status;
DATA_BLOB blob = data_blob_const(*ppdata, *p_data_size);
@@ -446,6 +499,16 @@ static NTSTATUS srv_enc_raw_ntlm_auth(unsigned char **ppdata, size_t *p_data_siz
/* Second step. */
status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, blob, &response);
+ if (NT_STATUS_IS_OK(status)) {
+ /* Return the context we're using for this encryption state. */
+ *pparam = SMB_MALLOC(2);
+ if (!*pparam) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ SSVAL(*pparam,0,ec->es->enc_ctx_num);
+ *p_param_size = 2;
+ }
+
/* Return the raw blob. */
SAFE_FREE(*ppdata);
*ppdata = response.data;
@@ -457,26 +520,29 @@ static NTSTATUS srv_enc_raw_ntlm_auth(unsigned char **ppdata, size_t *p_data_siz
Do the SPNEGO encryption negotiation. Parameters are in/out.
******************************************************************************/
-NTSTATUS srv_request_encryption_setup(unsigned char **ppdata, size_t *p_data_size)
+NTSTATUS srv_request_encryption_setup(connection_struct *conn,
+ unsigned char **ppdata,
+ size_t *p_data_size,
+ unsigned char **pparam,
+ size_t *p_param_size)
{
unsigned char *pdata = *ppdata;
+ SAFE_FREE(*pparam);
+ *p_param_size = 0;
+
if (*p_data_size < 1) {
return NT_STATUS_INVALID_PARAMETER;
}
if (pdata[0] == ASN1_APPLICATION(0)) {
- /*
- * Until success we do everything on the partial
- * enc state.
- */
/* its a negTokenTarg packet */
- return srv_enc_spnego_negotiate(ppdata, p_data_size);
+ return srv_enc_spnego_negotiate(conn, ppdata, p_data_size, pparam, p_param_size);
}
if (pdata[0] == ASN1_CONTEXT(1)) {
/* It's an auth packet */
- return srv_enc_spnego_ntlm_auth(ppdata, p_data_size);
+ return srv_enc_spnego_ntlm_auth(conn, ppdata, p_data_size, pparam, p_param_size);
}
/* Maybe it's a raw unwrapped auth ? */
@@ -485,7 +551,7 @@ NTSTATUS srv_request_encryption_setup(unsigned char **ppdata, size_t *p_data_siz
}
if (strncmp((char *)pdata, "NTLMSSP", 7) == 0) {
- return srv_enc_raw_ntlm_auth(ppdata, p_data_size);
+ return srv_enc_raw_ntlm_auth(conn, ppdata, p_data_size, pparam, p_param_size);
}
DEBUG(1,("srv_request_encryption_setup: Unknown packet\n"));
@@ -518,7 +584,7 @@ static NTSTATUS check_enc_good(struct smb_srv_trans_enc_ctx *ec)
Negotiation was successful - turn on server-side encryption.
******************************************************************************/
-NTSTATUS srv_encryption_start(void)
+NTSTATUS srv_encryption_start(connection_struct *conn)
{
NTSTATUS status;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 007ad50b10..df713db564 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -2765,6 +2765,7 @@ cap_low = 0x%x, cap_high = 0x%x\n",
case SMB_REQUEST_TRANSPORT_ENCRYPTION:
{
NTSTATUS status;
+ size_t param_len = 0;
size_t data_len = total_data;
if (!lp_unix_extensions()) {
@@ -2773,7 +2774,12 @@ cap_low = 0x%x, cap_high = 0x%x\n",
DEBUG( 4,("call_trans2setfsinfo: request transport encrption.\n"));
- status = srv_request_encryption_setup((unsigned char **)ppdata, &data_len);
+ status = srv_request_encryption_setup(conn,
+ (unsigned char **)ppdata,
+ &data_len,
+ (unsigned char **)pparams,
+ &param_len
+ );
if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
error_packet_set(outbuf, 0, 0, status, __LINE__,__FILE__);
@@ -2781,11 +2787,11 @@ cap_low = 0x%x, cap_high = 0x%x\n",
return ERROR_NT(status);
}
- send_trans2_replies( outbuf, bufsize, params, 0, *ppdata, data_len, max_data_bytes);
+ send_trans2_replies(outbuf, bufsize, *pparams, param_len, *ppdata, data_len, max_data_bytes);
if (NT_STATUS_IS_OK(status)) {
/* Server-side transport encryption is now *on*. */
- status = srv_encryption_start();
+ status = srv_encryption_start(conn);
if (!NT_STATUS_IS_OK(status)) {
exit_server_cleanly("Failure in setting up encrypted transport");
}