s3-dcerpc: use dcerpc_push_ncacn_packet() for create_bind_or_alt_ctx_internal().
[kamenim/samba.git] / source3 / rpc_client / cli_pipe.c
index db6fdc5ba2fdb9afb33408fcc6f76d3dad40e809..d4ff89849be567ba9ce1cb4cc674da9ec87ad417 100644 (file)
@@ -335,6 +335,28 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
+/*******************************************************************
+*******************************************************************/
+
+NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
+                                 const DATA_BLOB *blob,
+                                 struct ncacn_packet *r)
+{
+       enum ndr_err_code ndr_err;
+
+       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)) {
+               return ndr_map_error2ntstatus(ndr_err);
+       }
+
+       if (DEBUGLEVEL >= 10) {
+               NDR_PRINT_DEBUG(ncacn_packet, r);
+       }
+
+       return NT_STATUS_OK;
+}
+
 /*******************************************************************
  Use SMBreadX to get rest of one fragment's worth of rpc data.
  Reads the whole size or give an error message
@@ -1118,27 +1140,25 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_H
 
                case DCERPC_PKT_FAULT:
                {
-                       RPC_HDR_RESP rhdr_resp;
-                       RPC_HDR_FAULT fault_resp;
+                       DATA_BLOB blob;
+                       struct ncacn_packet r;
 
-                       if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
-                               DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
-                               return NT_STATUS_BUFFER_TOO_SMALL;
-                       }
+                       blob = data_blob_const(prs_data_p(current_pdu),
+                                              prs_data_size(current_pdu));
 
-                       if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
-                               DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
-                               return NT_STATUS_BUFFER_TOO_SMALL;
+                       ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
+                       if (!NT_STATUS_IS_OK(ret)) {
+                               return ret;
                        }
-
                        DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
                                  "code %s received from %s!\n",
-                               dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp.status)),
+                               dcerpc_errstr(talloc_tos(), r.u.fault.status),
                                rpccli_pipe_txt(talloc_tos(), cli)));
-                       if (NT_STATUS_IS_OK(fault_resp.status)) {
+
+                       if (NT_STATUS_IS_OK(NT_STATUS(r.u.fault.status))) {
                                return NT_STATUS_UNSUCCESSFUL;
                        } else {
-                               return fault_resp.status;
+                               return NT_STATUS(r.u.fault.status);
                        }
                }
 
@@ -1825,11 +1845,38 @@ static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
        return NT_STATUS_OK;
 }
 
+/*******************************************************************
+ ********************************************************************/
+
+static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
+                                    const struct ndr_syntax_id *abstract_syntax,
+                                    const struct ndr_syntax_id *transfer_syntax,
+                                    struct dcerpc_ctx_list **ctx_list_p)
+{
+       struct dcerpc_ctx_list *ctx_list;
+
+       ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
+       NT_STATUS_HAVE_NO_MEMORY(ctx_list);
+
+       ctx_list[0].context_id                  = 0;
+       ctx_list[0].num_transfer_syntaxes       = 1;
+       ctx_list[0].abstract_syntax             = *abstract_syntax;
+       ctx_list[0].transfer_syntaxes           = talloc_array(ctx_list,
+                                                              struct ndr_syntax_id,
+                                                              ctx_list[0].num_transfer_syntaxes);
+       NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
+       ctx_list[0].transfer_syntaxes[0]        = *transfer_syntax;
+
+       *ctx_list_p = ctx_list;
+
+       return NT_STATUS_OK;
+}
+
 /*******************************************************************
  Creates the internals of a DCE/RPC bind request or alter context PDU.
  ********************************************************************/
 
-static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
+static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
                                                prs_struct *rpc_out, 
                                                uint32 rpc_call_id,
                                                const struct ndr_syntax_id *abstract,
@@ -1837,25 +1884,33 @@ static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
                                                RPC_HDR_AUTH *phdr_auth,
                                                prs_struct *pauth_info)
 {
-       RPC_HDR hdr;
-       RPC_HDR_RB hdr_rb;
-       RPC_CONTEXT rpc_ctx;
        uint16 auth_len = prs_offset(pauth_info);
        uint8 ss_padding_len = 0;
        uint16 frag_len = 0;
+       NTSTATUS status;
+       union dcerpc_payload u;
+       DATA_BLOB blob;
+       struct dcerpc_ctx_list *ctx_list;
 
-       /* create the RPC context. */
-       init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
+       status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
+                                     &ctx_list);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
-       /* create the bind request RPC_HDR_RB */
-       init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
+       u.bind.max_xmit_frag    = RPC_MAX_PDU_FRAG_LEN;
+       u.bind.max_recv_frag    = RPC_MAX_PDU_FRAG_LEN;
+       u.bind.assoc_group_id   = 0x0;
+       u.bind.num_contexts     = 1;
+       u.bind.ctx_list         = ctx_list;
+       u.bind.auth_info        = data_blob_null;
 
        /* Start building the frag length. */
-       frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
+       frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind);
 
        /* Do we need to pad ? */
        if (auth_len) {
-               uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
+               uint16_t data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind);
                if (data_len % CLIENT_NDR_PADDING_SIZE) {
                        ss_padding_len = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
                        phdr_auth->auth_pad_len = ss_padding_len;
@@ -1863,18 +1918,21 @@ static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
                frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
        }
 
-       /* Create the request RPC_HDR */
-       init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
-
-       /* Marshall the RPC header */
-       if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
-               DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
-               return NT_STATUS_NO_MEMORY;
+       status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
+                                         ptype,
+                                         DCERPC_PFC_FLAG_FIRST |
+                                         DCERPC_PFC_FLAG_LAST,
+                                         frag_len,
+                                         auth_len,
+                                         rpc_call_id,
+                                         u,
+                                         &blob);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
+               return status;
        }
 
-       /* Marshall the bind request data */
-       if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
-               DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
+       if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
                return NT_STATUS_NO_MEMORY;
        }