summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2010-07-19 19:34:34 -0400
committerSimo Sorce <idra@samba.org>2010-07-28 12:16:58 -0400
commit49a8c2965d2982e6510609fa9772a56597494641 (patch)
tree9f6878ee39dc5d38fddf4f46da095f512ec2e54c
parent1fc71c9c6ff26f2d49f314b8425c6cd4c91683f3 (diff)
downloadsamba-49a8c2965d2982e6510609fa9772a56597494641.tar.gz
samba-49a8c2965d2982e6510609fa9772a56597494641.tar.bz2
samba-49a8c2965d2982e6510609fa9772a56597494641.zip
s3-dcerpc: Split auth checking into a generic function.
-rw-r--r--source3/rpc_server/srv_pipe.c81
1 files changed, 55 insertions, 26 deletions
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 98dc52d100..3b015f9e0f 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -1721,22 +1721,18 @@ void set_incoming_fault(struct pipes_struct *p)
get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
}
-static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
- struct ncacn_packet *pkt,
- DATA_BLOB *raw_pkt)
+static NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ struct ncacn_packet *pkt,
+ DATA_BLOB *pkt_trailer,
+ size_t header_size,
+ DATA_BLOB *raw_pkt,
+ size_t *pad_len)
{
NTSTATUS status;
- size_t hdr_size = DCERPC_REQUEST_LENGTH;
struct dcerpc_auth auth_info;
uint32_t auth_length;
- DATA_BLOB data;
DATA_BLOB full_pkt;
-
- DEBUG(10, ("Checking request auth.\n"));
-
- if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
- hdr_size += 16;
- }
+ DATA_BLOB data;
switch (auth->auth_level) {
case DCERPC_AUTH_LEVEL_PRIVACY:
@@ -1751,6 +1747,7 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
if (pkt->auth_length != 0) {
break;
}
+ *pad_len = 0;
return NT_STATUS_OK;
case DCERPC_AUTH_LEVEL_NONE:
@@ -1759,6 +1756,7 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
"authenticated connection!\n"));
return NT_STATUS_INVALID_PARAMETER;
}
+ *pad_len = 0;
return NT_STATUS_OK;
default:
@@ -1767,17 +1765,14 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
return NT_STATUS_INVALID_PARAMETER;
}
- status = dcerpc_pull_auth_trailer(pkt, pkt,
- &pkt->u.request.stub_and_verifier,
+ status = dcerpc_pull_auth_trailer(pkt, pkt, pkt_trailer,
&auth_info, &auth_length, false);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- pkt->u.request.stub_and_verifier.length -= auth_length;
-
- data = data_blob_const(raw_pkt->data + hdr_size,
- pkt->u.request.stub_and_verifier.length);
+ data = data_blob_const(raw_pkt->data + header_size,
+ pkt_trailer->length - auth_length);
full_pkt = data_blob_const(raw_pkt->data,
raw_pkt->length - auth_info.credentials.length);
@@ -1806,8 +1801,7 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- memcpy(pkt->u.request.stub_and_verifier.data,
- data.data, data.length);
+ memcpy(pkt_trailer->data, data.data, data.length);
break;
case DCERPC_AUTH_LEVEL_INTEGRITY:
@@ -1842,8 +1836,7 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- memcpy(pkt->u.request.stub_and_verifier.data,
- data.data, data.length);
+ memcpy(pkt_trailer->data, data.data, data.length);
break;
case DCERPC_AUTH_LEVEL_INTEGRITY:
@@ -1871,11 +1864,46 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
return NT_STATUS_INVALID_PARAMETER;
}
- /* remove the indicated amount of padding */
- if (pkt->u.request.stub_and_verifier.length < auth_info.auth_pad_length) {
- return NT_STATUS_INVALID_PARAMETER;
+ *pad_len = auth_info.auth_pad_length;
+ data_blob_free(&auth_info.credentials);
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
+ struct ncacn_packet *pkt,
+ DATA_BLOB *raw_pkt)
+{
+ NTSTATUS status;
+ size_t hdr_size = DCERPC_REQUEST_LENGTH;
+ size_t pad_len;
+
+ DEBUG(10, ("Checking request auth.\n"));
+
+ if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
+ hdr_size += 16;
+ }
+
+ /* in case of sealing this function will unseal the data in place */
+ status = dcerpc_check_auth(auth, pkt,
+ &pkt->u.request.stub_and_verifier,
+ hdr_size, raw_pkt,
+ &pad_len);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+
+ /* remove padding and auth trailer,
+ * this way the caller will get just the data */
+ if (pkt->auth_length) {
+ size_t trail_len = pad_len
+ + DCERPC_AUTH_TRAILER_LENGTH
+ + pkt->auth_length;
+ if (pkt->u.request.stub_and_verifier.length < trail_len) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+ pkt->u.request.stub_and_verifier.length -= trail_len;
}
- pkt->u.request.stub_and_verifier.length -= auth_info.auth_pad_length;
return NT_STATUS_OK;
}
@@ -1901,7 +1929,8 @@ static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt
status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("Failed to check packet auth.\n"));
+ DEBUG(0, ("Failed to check packet auth. (%s)\n",
+ nt_errstr(status)));
set_incoming_fault(p);
return false;
}