Finish removal of iconv_convenience in public API's.
[bbaumbach/samba-autobuild/.git] / source4 / librpc / rpc / dcerpc.c
index e7b181c50bc09fa4e9ca5235104de4273be4eafb..7265105525a7986329b5108e9f80a2e9c63654ac 100644 (file)
@@ -55,8 +55,7 @@ static int dcerpc_connection_destructor(struct dcerpc_connection *conn)
    the event context is optional
 */
 static struct dcerpc_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx, 
-                                                struct tevent_context *ev,
-                                                struct smb_iconv_convenience *ic)
+                                                struct tevent_context *ev)
 {
        struct dcerpc_connection *c;
 
@@ -65,8 +64,6 @@ static struct dcerpc_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
-       c->iconv_convenience = talloc_reference(c, ic);
-
        c->event_ctx = ev;
 
        if (c->event_ctx == NULL) {
@@ -90,8 +87,7 @@ static struct dcerpc_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx,
 }
 
 /* initialise a dcerpc pipe. */
-_PUBLIC_ struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-                                    struct smb_iconv_convenience *ic)
+_PUBLIC_ struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev)
 {
        struct dcerpc_pipe *p;
 
@@ -100,7 +96,7 @@ _PUBLIC_ struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct tevent
                return NULL;
        }
 
-       p->conn = dcerpc_connection_init(p, ev, ic);
+       p->conn = dcerpc_connection_init(p, ev);
        if (p->conn == NULL) {
                talloc_free(p);
                return NULL;
@@ -118,6 +114,13 @@ _PUBLIC_ struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct tevent
                p->conn->flags |= DCERPC_DEBUG_PRINT_BOTH;
        }
 
+       p->binding_handle = talloc(p, struct dcerpc_binding_handle);
+       if (p->binding_handle == NULL) {
+               talloc_free(p);
+               return NULL;
+       }
+       p->binding_handle->private_data = p;
+
        return p;
 }
 
@@ -170,7 +173,7 @@ void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v)
 static struct ndr_pull *ndr_pull_init_flags(struct dcerpc_connection *c, 
                                            DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
 {
-       struct ndr_pull *ndr = ndr_pull_init_blob(blob, mem_ctx, c->iconv_convenience);
+       struct ndr_pull *ndr = ndr_pull_init_blob(blob, mem_ctx);
 
        if (ndr == NULL) return ndr;
 
@@ -321,7 +324,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
 
        /* non-signed packets are simpler */
        if (sig_size == 0) {
-               return ncacn_push_auth(blob, mem_ctx, c->iconv_convenience, pkt, NULL);
+               return ncacn_push_auth(blob, mem_ctx, pkt, NULL);
        }
 
        switch (c->security_state.auth_info->auth_level) {
@@ -331,16 +334,16 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
 
        case DCERPC_AUTH_LEVEL_CONNECT:
                /* TODO: let the gensec mech decide if it wants to generate a signature */
-               return ncacn_push_auth(blob, mem_ctx, c->iconv_convenience, pkt, NULL);
+               return ncacn_push_auth(blob, mem_ctx, pkt, NULL);
 
        case DCERPC_AUTH_LEVEL_NONE:
-               return ncacn_push_auth(blob, mem_ctx, c->iconv_convenience, pkt, NULL);
+               return ncacn_push_auth(blob, mem_ctx, pkt, NULL);
 
        default:
                return NT_STATUS_INVALID_LEVEL;
        }
 
-       ndr = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
+       ndr = ndr_push_init_ctx(mem_ctx);
        if (!ndr) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -362,17 +365,18 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                return ndr_map_error2ntstatus(ndr_err);
        }
-       status = NT_STATUS_OK;
 
        /* pad to 16 byte multiple in the payload portion of the
-          packet. This matches what w2k3 does */
-       c->security_state.auth_info->auth_pad_length = 
+          packet. This matches what w2k3 does. Note that we can't use
+          ndr_push_align() as that is relative to the start of the
+          whole packet, whereas w2k8 wants it relative to the start
+          of the stub */
+       c->security_state.auth_info->auth_pad_length =
                (16 - (pkt->u.request.stub_and_verifier.length & 15)) & 15;
        ndr_err = ndr_push_zero(ndr, c->security_state.auth_info->auth_pad_length);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                return ndr_map_error2ntstatus(ndr_err);
        }
-       status = NT_STATUS_OK;
 
        payload_length = pkt->u.request.stub_and_verifier.length + 
                c->security_state.auth_info->auth_pad_length;
@@ -385,7 +389,6 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                return ndr_map_error2ntstatus(ndr_err);
        }
-       status = NT_STATUS_OK;
 
        /* extract the whole packet as a blob */
        *blob = ndr_push_blob(ndr);
@@ -433,12 +436,17 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
        }
 
        if (creds2.length != sig_size) {
-               DEBUG(0,("ncacn_push_request_sign: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n",
+               /* this means the sig_size estimate for the signature
+                  was incorrect. We have to correct the packet
+                  sizes. That means we could go over the max fragment
+                  length */
+               DEBUG(3,("ncacn_push_request_sign: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n",
                        (unsigned) creds2.length,
                        (unsigned) sig_size,
                        (unsigned) c->security_state.auth_info->auth_pad_length,
                        (unsigned) pkt->u.request.stub_and_verifier.length));
-               return NT_STATUS_INTERNAL_ERROR;
+               dcerpc_set_frag_length(blob, blob->length + creds2.length);
+               dcerpc_set_auth_length(blob, creds2.length);
        }
 
        if (!data_blob_append(mem_ctx, blob, creds2.data, creds2.length)) {
@@ -599,6 +607,7 @@ static void dcerpc_bind_recv_handler(struct rpc_request *req,
        if ((pkt->ptype != DCERPC_PKT_BIND_ACK) ||
            (pkt->u.bind_ack.num_results == 0) ||
            (pkt->u.bind_ack.ctx_list[0].result != 0)) {
+               req->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
                composite_error(c, NT_STATUS_NET_WRITE_FAULT);
                return;
        }
@@ -705,7 +714,7 @@ struct composite_context *dcerpc_bind_send(struct dcerpc_pipe *p,
        pkt.u.bind.auth_info = data_blob(NULL, 0);
 
        /* construct the NDR form of the packet */
-       c->status = ncacn_push_auth(&blob, c, p->conn->iconv_convenience, &pkt,
+       c->status = ncacn_push_auth(&blob, c, &pkt,
                                    p->conn->security_state.auth_info);
        if (!composite_is_ok(c)) return c;
 
@@ -776,7 +785,6 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
 
        /* construct the NDR form of the packet */
        status = ncacn_push_auth(&blob, mem_ctx,
-                                p->conn->iconv_convenience,
                                 &pkt,
                                 p->conn->security_state.auth_info);
        if (!NT_STATUS_IS_OK(status)) {
@@ -1036,7 +1044,7 @@ static void dcerpc_ship_next_request(struct dcerpc_connection *c)
        if (req->object) {
                pkt.u.request.object.object = *req->object;
                pkt.pfc_flags |= DCERPC_PFC_FLAG_OBJECT_UUID;
-               chunk_size -= ndr_size_GUID(req->object,NULL,0);
+               chunk_size -= ndr_size_GUID(req->object,0);
        }
 
        /* we send a series of pdus without waiting for a reply */
@@ -1189,7 +1197,7 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c,
                return ndr_map_error2ntstatus(ndr_err);
        }
 
-       push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
+       push = ndr_push_init_ctx(mem_ctx);
        if (!push) {
                return NT_STATUS_NO_MEMORY;
        }       
@@ -1247,7 +1255,7 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
        }
        memcpy(st, struct_ptr, struct_size);
 
-       push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
+       push = ndr_push_init_ctx(mem_ctx);
        if (!push) {
                return NT_STATUS_NO_MEMORY;
        }       
@@ -1278,7 +1286,7 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
                return ndr_map_error2ntstatus(ndr_err);
        }
 
-       push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
+       push = ndr_push_init_ctx(mem_ctx);
        if (!push) {
                return NT_STATUS_NO_MEMORY;
        }       
@@ -1350,7 +1358,7 @@ struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
        call = &table->calls[opnum];
 
        /* setup for a ndr_push_* call */
-       push = ndr_push_init_ctx(mem_ctx, p->conn->iconv_convenience);
+       push = ndr_push_init_ctx(mem_ctx);
        if (!push) {
                return NULL;
        }
@@ -1572,9 +1580,17 @@ static void dcerpc_alter_recv_handler(struct rpc_request *req,
                return;
        }
 
+       if (pkt->ptype == DCERPC_PKT_FAULT) {
+               DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt->u.fault.status)));
+               recv_pipe->last_fault_code = pkt->u.fault.status;
+               composite_error(c, NT_STATUS_NET_WRITE_FAULT);
+               return;
+       }
+
        if (pkt->ptype != DCERPC_PKT_ALTER_RESP ||
            pkt->u.alter_resp.num_results == 0 ||
            pkt->u.alter_resp.ctx_list[0].result != 0) {
+               recv_pipe->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
                composite_error(c, NT_STATUS_NET_WRITE_FAULT);
                return;
        }
@@ -1645,7 +1661,7 @@ struct composite_context *dcerpc_alter_context_send(struct dcerpc_pipe *p,
        pkt.u.alter.auth_info = data_blob(NULL, 0);
 
        /* construct the NDR form of the packet */
-       c->status = ncacn_push_auth(&blob, mem_ctx, p->conn->iconv_convenience, &pkt,
+       c->status = ncacn_push_auth(&blob, mem_ctx, &pkt,
                                    p->conn->security_state.auth_info);
        if (!composite_is_ok(c)) return c;
 
@@ -1696,3 +1712,4 @@ _PUBLIC_ NTSTATUS dcerpc_alter_context(struct dcerpc_pipe *p,
        creq = dcerpc_alter_context_send(p, mem_ctx, syntax, transfer_syntax);
        return dcerpc_alter_context_recv(creq);
 }
+