summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/librpc/rpc/dcerpc.h6
-rw-r--r--source3/librpc/rpc/dcerpc_helpers.c172
-rw-r--r--source3/rpc_server/srv_pipe.c160
3 files changed, 178 insertions, 160 deletions
diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h
index 319acce990..d170daad9f 100644
--- a/source3/librpc/rpc/dcerpc.h
+++ b/source3/librpc/rpc/dcerpc.h
@@ -141,5 +141,11 @@ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
bool bigendian);
NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
size_t pad_len, DATA_BLOB *rpc_out);
+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);
#endif /* __DCERPC_H__ */
diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
index 0e43e7ad56..fc9915cf08 100644
--- a/source3/librpc/rpc/dcerpc_helpers.c
+++ b/source3/librpc/rpc/dcerpc_helpers.c
@@ -450,3 +450,175 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
return status;
}
+/**
+* @brief Check authentication for request/response packets
+*
+* @param auth The auth data for the connection
+* @param pkt The actual ncacn_packet
+* @param pkt_trailer The stub_and_verifier part of the packet
+* @param header_size The header size
+* @param raw_pkt The whole raw packet data blob
+* @param pad_len [out] The padding length used in the packet
+*
+* @return A NTSTATUS error code
+*/
+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;
+ struct dcerpc_auth auth_info;
+ uint32_t auth_length;
+ DATA_BLOB full_pkt;
+ DATA_BLOB data;
+
+ switch (auth->auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ DEBUG(10, ("Requested Privacy.\n"));
+ break;
+
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ DEBUG(10, ("Requested Integrity.\n"));
+ break;
+
+ case DCERPC_AUTH_LEVEL_CONNECT:
+ if (pkt->auth_length != 0) {
+ break;
+ }
+ *pad_len = 0;
+ return NT_STATUS_OK;
+
+ case DCERPC_AUTH_LEVEL_NONE:
+ if (pkt->auth_length != 0) {
+ DEBUG(3, ("Got non-zero auth len on non "
+ "authenticated connection!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ *pad_len = 0;
+ return NT_STATUS_OK;
+
+ default:
+ DEBUG(3, ("Unimplemented Auth Level %d",
+ auth->auth_level));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Paranioa checks for auth_length. */
+ if (pkt->auth_length > pkt->frag_length) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+ if ((pkt->auth_length
+ + DCERPC_AUTH_TRAILER_LENGTH < pkt->auth_length) ||
+ (pkt->auth_length
+ + DCERPC_AUTH_TRAILER_LENGTH < DCERPC_AUTH_TRAILER_LENGTH)) {
+ /* Integer wrap attempt. */
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+
+ status = dcerpc_pull_auth_trailer(pkt, pkt, pkt_trailer,
+ &auth_info, &auth_length, false);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ 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);
+
+ switch (auth->auth_type) {
+ case PIPE_AUTH_TYPE_NONE:
+ return NT_STATUS_OK;
+
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ case PIPE_AUTH_TYPE_NTLMSSP:
+
+ DEBUG(10, ("NTLMSSP auth\n"));
+
+ if (!auth->a_u.auth_ntlmssp_state) {
+ DEBUG(0, ("Invalid auth level, "
+ "failed to process packet auth.\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ switch (auth->auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ status = auth_ntlmssp_unseal_packet(
+ auth->a_u.auth_ntlmssp_state,
+ data.data, data.length,
+ full_pkt.data, full_pkt.length,
+ &auth_info.credentials);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ memcpy(pkt_trailer->data, data.data, data.length);
+ break;
+
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ status = auth_ntlmssp_check_packet(
+ auth->a_u.auth_ntlmssp_state,
+ data.data, data.length,
+ full_pkt.data, full_pkt.length,
+ &auth_info.credentials);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ break;
+
+ default:
+ DEBUG(0, ("Invalid auth level, "
+ "failed to process packet auth.\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ break;
+
+ case PIPE_AUTH_TYPE_SCHANNEL:
+
+ DEBUG(10, ("SCHANNEL auth\n"));
+
+ switch (auth->auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ status = netsec_incoming_packet(
+ auth->a_u.schannel_auth,
+ pkt, true,
+ data.data, data.length,
+ &auth_info.credentials);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ memcpy(pkt_trailer->data, data.data, data.length);
+ break;
+
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ status = netsec_incoming_packet(
+ auth->a_u.schannel_auth,
+ pkt, false,
+ data.data, data.length,
+ &auth_info.credentials);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ break;
+
+ default:
+ DEBUG(0, ("Invalid auth level, "
+ "failed to process packet auth.\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ break;
+
+ default:
+ DEBUG(0, ("process_request_pdu: "
+ "unknown auth type %u set.\n",
+ (unsigned int)auth->auth_type));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ *pad_len = auth_info.auth_pad_length;
+ data_blob_free(&auth_info.credentials);
+ return NT_STATUS_OK;
+}
+
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 8bb7a231d5..5ab64c2d37 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -1721,166 +1721,6 @@ void set_incoming_fault(struct pipes_struct *p)
get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
}
-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;
- struct dcerpc_auth auth_info;
- uint32_t auth_length;
- DATA_BLOB full_pkt;
- DATA_BLOB data;
-
- switch (auth->auth_level) {
- case DCERPC_AUTH_LEVEL_PRIVACY:
- DEBUG(10, ("Requested Privacy.\n"));
- break;
-
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- DEBUG(10, ("Requested Integrity.\n"));
- break;
-
- case DCERPC_AUTH_LEVEL_CONNECT:
- if (pkt->auth_length != 0) {
- break;
- }
- *pad_len = 0;
- return NT_STATUS_OK;
-
- case DCERPC_AUTH_LEVEL_NONE:
- if (pkt->auth_length != 0) {
- DEBUG(3, ("Got non-zero auth len on non "
- "authenticated connection!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- *pad_len = 0;
- return NT_STATUS_OK;
-
- default:
- DEBUG(3, ("Unimplemented Auth Level %d",
- auth->auth_level));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* Paranioa checks for auth_length. */
- if (pkt->auth_length > pkt->frag_length) {
- return NT_STATUS_INFO_LENGTH_MISMATCH;
- }
- if ((pkt->auth_length
- + DCERPC_AUTH_TRAILER_LENGTH < pkt->auth_length) ||
- (pkt->auth_length
- + DCERPC_AUTH_TRAILER_LENGTH < DCERPC_AUTH_TRAILER_LENGTH)) {
- /* Integer wrap attempt. */
- return NT_STATUS_INFO_LENGTH_MISMATCH;
- }
-
- status = dcerpc_pull_auth_trailer(pkt, pkt, pkt_trailer,
- &auth_info, &auth_length, false);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- 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);
-
- switch (auth->auth_type) {
- case PIPE_AUTH_TYPE_NONE:
- return NT_STATUS_OK;
-
- case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
- case PIPE_AUTH_TYPE_NTLMSSP:
-
- DEBUG(10, ("NTLMSSP auth\n"));
-
- if (!auth->a_u.auth_ntlmssp_state) {
- DEBUG(0, ("Invalid auth level, "
- "failed to process packet auth.\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- switch (auth->auth_level) {
- case DCERPC_AUTH_LEVEL_PRIVACY:
- status = auth_ntlmssp_unseal_packet(
- auth->a_u.auth_ntlmssp_state,
- data.data, data.length,
- full_pkt.data, full_pkt.length,
- &auth_info.credentials);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- memcpy(pkt_trailer->data, data.data, data.length);
- break;
-
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = auth_ntlmssp_check_packet(
- auth->a_u.auth_ntlmssp_state,
- data.data, data.length,
- full_pkt.data, full_pkt.length,
- &auth_info.credentials);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- break;
-
- default:
- DEBUG(0, ("Invalid auth level, "
- "failed to process packet auth.\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- break;
-
- case PIPE_AUTH_TYPE_SCHANNEL:
-
- DEBUG(10, ("SCHANNEL auth\n"));
-
- switch (auth->auth_level) {
- case DCERPC_AUTH_LEVEL_PRIVACY:
- status = netsec_incoming_packet(
- auth->a_u.schannel_auth,
- pkt, true,
- data.data, data.length,
- &auth_info.credentials);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- memcpy(pkt_trailer->data, data.data, data.length);
- break;
-
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = netsec_incoming_packet(
- auth->a_u.schannel_auth,
- pkt, false,
- data.data, data.length,
- &auth_info.credentials);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- break;
-
- default:
- DEBUG(0, ("Invalid auth level, "
- "failed to process packet auth.\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- break;
-
- default:
- DEBUG(0, ("process_request_pdu: "
- "unknown auth type %u set.\n",
- (unsigned int)auth->auth_type));
- 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)