The branch, master has been updated
       via  65116ad... s3-dcerpc: Fix ability to receive Big Endian PDUs
      from  ec25a00... smbtorture shell: Allow any config option to be set.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 65116adcebe23d3ae42a641515f6001268ed0ef0
Author: Simo Sorce <[email protected]>
Date:   Fri Jul 16 15:15:48 2010 -0400

    s3-dcerpc: Fix ability to receive Big Endian PDUs

-----------------------------------------------------------------------

Summary of changes:
 librpc/rpc/dcerpc_util.c            |    5 ++++
 source3/include/proto.h             |    1 +
 source3/librpc/rpc/dcerpc.h         |    6 +++-
 source3/librpc/rpc/dcerpc_helpers.c |   36 +++++++++++++++++++++++++++++-----
 source3/rpc_client/cli_pipe.c       |   12 +++++-----
 source3/rpc_server/srv_pipe.c       |    6 ++--
 source3/rpc_server/srv_pipe_hnd.c   |   24 ++++++++++++----------
 7 files changed, 62 insertions(+), 28 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c
index a4bc096..c79cfd5 100644
--- a/librpc/rpc/dcerpc_util.c
+++ b/librpc/rpc/dcerpc_util.c
@@ -52,6 +52,11 @@ void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v)
        }
 }
 
+uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob)
+{
+       return blob->data[DCERPC_DREP_OFFSET];
+}
+
 /*
   pull an dcerpc_auth structure, taking account of any auth padding in
   the blob at the end of the structure
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 6f8eebb..9471f63 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2937,6 +2937,7 @@ NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code);
 void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v);
 uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob);
 void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v);
+uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob);
 NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt,
                                  TALLOC_CTX *mem_ctx,
                                  DATA_BLOB *pkt_auth_blob,
diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h
index d18920c..bb7bd34 100644
--- a/source3/librpc/rpc/dcerpc.h
+++ b/source3/librpc/rpc/dcerpc.h
@@ -123,7 +123,8 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
                                  DATA_BLOB *blob);
 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
                                  const DATA_BLOB *blob,
-                                 struct ncacn_packet *r);
+                                 struct ncacn_packet *r,
+                                 bool bigendian);
 NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
                                   struct NL_AUTH_MESSAGE *r,
                                   DATA_BLOB *blob);
@@ -136,6 +137,7 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
                                 DATA_BLOB *blob);
 NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
                                 const DATA_BLOB *blob,
-                                struct dcerpc_auth *r);
+                                struct dcerpc_auth *r,
+                                bool bigendian);
 
 #endif /* __DCERPC_H__ */
diff --git a/source3/librpc/rpc/dcerpc_helpers.c 
b/source3/librpc/rpc/dcerpc_helpers.c
index ce48a69..5c92a79 100644
--- a/source3/librpc/rpc/dcerpc_helpers.c
+++ b/source3/librpc/rpc/dcerpc_helpers.c
@@ -92,15 +92,27 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
 */
 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
                                  const DATA_BLOB *blob,
-                                 struct ncacn_packet *r)
+                                 struct ncacn_packet *r,
+                                 bool bigendian)
 {
        enum ndr_err_code ndr_err;
+       struct ndr_pull *ndr;
+
+       ndr = ndr_pull_init_blob(blob, mem_ctx);
+       if (!ndr) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       if (bigendian) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
+       ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, r);
 
-       ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
-               (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               talloc_free(ndr);
                return ndr_map_error2ntstatus(ndr_err);
        }
+       talloc_free(ndr);
 
        if (DEBUGLEVEL >= 10) {
                NDR_PRINT_DEBUG(ncacn_packet, r);
@@ -194,15 +206,27 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
 */
 NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
                                 const DATA_BLOB *blob,
-                                struct dcerpc_auth *r)
+                                struct dcerpc_auth *r,
+                                bool bigendian)
 {
        enum ndr_err_code ndr_err;
+       struct ndr_pull *ndr;
+
+       ndr = ndr_pull_init_blob(blob, mem_ctx);
+       if (!ndr) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       if (bigendian) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
+       ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, r);
 
-       ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
-               (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               talloc_free(ndr);
                return ndr_map_error2ntstatus(ndr_err);
        }
+       talloc_free(ndr);
 
        if (DEBUGLEVEL >= 10) {
                NDR_PRINT_DEBUG(dcerpc_auth, r);
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index c90e060..411b12f 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -619,7 +619,7 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct 
rpc_pipe_client *cli,
                               DCERPC_AUTH_TRAILER_LENGTH
                                + pkt->auth_length);
 
-       status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
+       status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info, false);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall 
dcerpc_auth.\n"));
                return status;
@@ -749,7 +749,7 @@ static NTSTATUS cli_pipe_verify_schannel(struct 
rpc_pipe_client *cli,
                                + pkt->auth_length);
 
 
-       status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
+       status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info, false);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall 
dcerpc_auth.\n"));
                return status;
@@ -915,7 +915,7 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX 
*mem_ctx,
        NTSTATUS ret = NT_STATUS_OK;
        uint8 ss_padding_len = 0;
 
-       ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt);
+       ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt, false);
        if (!NT_STATUS_IS_OK(ret)) {
                return ret;
        }
@@ -2612,7 +2612,7 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct 
tevent_req *req,
 
        status = dcerpc_pull_dcerpc_auth(talloc_tos(),
                                         &r->u.bind_ack.auth_info,
-                                        &auth);
+                                        &auth, false);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
                          nt_errstr(status)));
@@ -2694,7 +2694,7 @@ static NTSTATUS 
rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
                                    DCERPC_AUTH_TRAILER_LENGTH
                                        + r->auth_length);
 
-       status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info);
+       status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info, false);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
                return status;
@@ -2778,7 +2778,7 @@ static void rpc_bind_ntlmssp_api_done(struct tevent_req 
*subreq)
 
        status = dcerpc_pull_dcerpc_auth(pkt,
                                         &pkt->u.alter_resp.auth_info,
-                                        &auth);
+                                        &auth, false);
        if (!NT_STATUS_IS_OK(status)) {
                tevent_req_nterror(req, status);
                return;
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 6d37ec2..968553a 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -568,7 +568,7 @@ bool api_pipe_bind_auth3(pipes_struct *p, struct 
ncacn_packet *pkt)
 
        status = dcerpc_pull_dcerpc_auth(pkt,
                                         &pkt->u.auth3.auth_info,
-                                        &auth_info);
+                                        &auth_info, p->endian);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
                goto err;
@@ -1303,7 +1303,7 @@ bool api_pipe_bind_req(pipes_struct *p, struct 
ncacn_packet *pkt)
                 */
                status = dcerpc_pull_dcerpc_auth(pkt,
                                                 &pkt->u.bind.auth_info,
-                                                &auth_info);
+                                                &auth_info, p->endian);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
                        goto err_exit;
@@ -1524,7 +1524,7 @@ bool api_pipe_alter_context(pipes_struct *p, struct 
ncacn_packet *pkt)
 
                status = dcerpc_pull_dcerpc_auth(pkt,
                                                 &pkt->u.bind.auth_info,
-                                                &auth_info);
+                                                &auth_info, p->endian);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
                        goto err_exit;
diff --git a/source3/rpc_server/srv_pipe_hnd.c 
b/source3/rpc_server/srv_pipe_hnd.c
index 3055e1a..51f30ce 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -406,25 +406,27 @@ static void process_complete_pdu(pipes_struct *p)
                goto done;
        }
 
-       status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu, pkt);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
-                         nt_errstr(status)));
-               goto done;
-       }
-
-       /* Store the call_id */
-       p->call_id = pkt->call_id;
-
        /*
         * Ensure we're using the corrent endianness for both the
         * RPC header flags and the raw data we will be reading from.
         */
-       if (pkt->drep[0] == DCERPC_DREP_LE) {
+       if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
                p->endian = RPC_LITTLE_ENDIAN;
        } else {
                p->endian = RPC_BIG_ENDIAN;
        }
+       DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
+
+       status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
+                                         pkt, p->endian);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
+                         nt_errstr(status)));
+               goto done;
+       }
+
+       /* Store the call_id */
+       p->call_id = pkt->call_id;
 
        DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
 


-- 
Samba Shared Repository

Reply via email to