r26226: Avoid more uses of global_loadparm.
[bbaumbach/samba-autobuild/.git] / source4 / librpc / rpc / dcerpc.c
index 1f0cc3699a38f62570a815da13d746aab5c8b7a1..74dc2562ed11bfad396d3ed21b97d07412415c5a 100644 (file)
 #include "librpc/gen_ndr/ndr_dcerpc.h"
 #include "libcli/composite/composite.h"
 #include "auth/gensec/gensec.h"
+#include "param/param.h"
 
 NTSTATUS dcerpc_init(void)
 {
-       gensec_init();
+       gensec_init(global_loadparm);
 
        return NT_STATUS_OK;
 }
@@ -192,6 +193,7 @@ static NTSTATUS ncacn_pull(struct dcerpc_connection *c, DATA_BLOB *blob, TALLOC_
                            struct ncacn_packet *pkt)
 {
        struct ndr_pull *ndr;
+       enum ndr_err_code ndr_err;
 
        ndr = ndr_pull_init_flags(c, blob, mem_ctx);
        if (!ndr) {
@@ -202,7 +204,12 @@ static NTSTATUS ncacn_pull(struct dcerpc_connection *c, DATA_BLOB *blob, TALLOC_
                ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
        }
 
-       return ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+       ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               return ndr_map_error2ntstatus(ndr_err);
+       }
+
+       return NT_STATUS_OK;
 }
 
 /*
@@ -242,6 +249,7 @@ static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX
        NTSTATUS status;
        struct dcerpc_auth auth;
        DATA_BLOB auth_blob;
+       enum ndr_err_code ndr_err;
 
        if (pkt->auth_length == 0 &&
            c->security_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
@@ -270,11 +278,12 @@ static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX
                ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
        }
 
-       status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
+       ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               return ndr_map_error2ntstatus(ndr_err);
        }
-       
+       status = NT_STATUS_OK;
+
        /* check signature or unseal the packet */
        switch (c->security_state.auth_info->auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
@@ -333,6 +342,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
        struct ndr_push *ndr;
        DATA_BLOB creds2;
        size_t payload_length;
+       enum ndr_err_code ndr_err;
 
        /* non-signed packets are simpler */
        if (!c->security_state.auth_info || 
@@ -353,10 +363,11 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
                ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
        }
 
-       status = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
+       ndr_err = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+       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 */
@@ -398,10 +409,11 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
        }       
 
        /* add the auth verifier */
-       status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, c->security_state.auth_info);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
+       ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, c->security_state.auth_info);
+       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);
@@ -651,11 +663,15 @@ static void dcerpc_bind_recv_handler(struct rpc_request *req,
        /* the bind_ack might contain a reply set of credentials */
        if (conn->security_state.auth_info &&
            pkt->u.bind_ack.auth_info.length) {
-               c->status = ndr_pull_struct_blob(
+               enum ndr_err_code ndr_err;
+               ndr_err = ndr_pull_struct_blob(
                        &pkt->u.bind_ack.auth_info, conn,
                        conn->security_state.auth_info,
                        (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
-               if (!composite_is_ok(c)) return;
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
        }
 
        req->p->assoc_group_id = pkt->u.bind_ack.assoc_group_id;
@@ -803,7 +819,7 @@ NTSTATUS dcerpc_auth3(struct dcerpc_connection *c,
                return status;
        }
 
-       return status;  
+       return NT_STATUS_OK;    
 }
 
 
@@ -1155,8 +1171,8 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c,
        void *st;
        struct ndr_pull *pull;
        struct ndr_push *push;
-       NTSTATUS status;
        DATA_BLOB blob2;
+       enum ndr_err_code ndr_err;
 
        st = talloc_size(mem_ctx, struct_size);
        if (!st) {
@@ -1169,11 +1185,13 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c,
        }
        pull->flags |= LIBNDR_FLAG_REF_ALLOC;
 
-       status = ndr_pull(pull, NDR_IN, st);
-       if (!NT_STATUS_IS_OK(status)) {
-               return ndr_pull_error(pull, NDR_ERR_VALIDATE, 
-                                     "failed input validation pull - %s",
-                                     nt_errstr(status));
+       ndr_err = ndr_pull(pull, NDR_IN, st);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+               ndr_err = ndr_pull_error(pull, NDR_ERR_VALIDATE,
+                                        "failed input validation pull - %s",
+                                        nt_errstr(status));
+               return ndr_map_error2ntstatus(ndr_err);
        }
 
        push = ndr_push_init_ctx(mem_ctx);
@@ -1181,11 +1199,13 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c,
                return NT_STATUS_NO_MEMORY;
        }       
 
-       status = ndr_push(push, NDR_IN, st);
-       if (!NT_STATUS_IS_OK(status)) {
-               return ndr_push_error(push, NDR_ERR_VALIDATE, 
-                                     "failed input validation push - %s",
-                                     nt_errstr(status));
+       ndr_err = ndr_push(push, NDR_IN, st);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+               ndr_err = ndr_pull_error(pull, NDR_ERR_VALIDATE,
+                                        "failed input validation push - %s",
+                                        nt_errstr(status));
+               return ndr_map_error2ntstatus(ndr_err);
        }
 
        blob2 = ndr_push_blob(push);
@@ -1195,9 +1215,9 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c,
                dump_data(3, blob.data, blob.length);
                DEBUG(3,("secondary:\n"));
                dump_data(3, blob2.data, blob2.length);
-               return ndr_push_error(push, NDR_ERR_VALIDATE, 
-                                     "failed input validation data - %s",
-                                     nt_errstr(status));
+               ndr_err = ndr_pull_error(pull, NDR_ERR_VALIDATE,
+                                        "failed input validation blobs doesn't match");
+               return ndr_map_error2ntstatus(ndr_err);
        }
 
        return NT_STATUS_OK;
@@ -1221,10 +1241,10 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
        void *st;
        struct ndr_pull *pull;
        struct ndr_push *push;
-       NTSTATUS status;
        DATA_BLOB blob, blob2;
        TALLOC_CTX *mem_ctx = pull_in;
        char *s1, *s2;
+       enum ndr_err_code ndr_err;
 
        st = talloc_size(mem_ctx, struct_size);
        if (!st) {
@@ -1237,11 +1257,13 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
                return NT_STATUS_NO_MEMORY;
        }       
 
-       status = ndr_push(push, NDR_OUT, struct_ptr);
-       if (!NT_STATUS_IS_OK(status)) {
-               return ndr_push_error(push, NDR_ERR_VALIDATE, 
-                                     "failed output validation push - %s",
-                                     nt_errstr(status));
+       ndr_err = ndr_push(push, NDR_OUT, struct_ptr);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+               ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
+                                        "failed output validation push - %s",
+                                        nt_errstr(status));
+               return ndr_map_error2ntstatus(ndr_err);
        }
 
        blob = ndr_push_blob(push);
@@ -1252,11 +1274,13 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
        }
 
        pull->flags |= LIBNDR_FLAG_REF_ALLOC;
-       status = ndr_pull(pull, NDR_OUT, st);
-       if (!NT_STATUS_IS_OK(status)) {
-               return ndr_pull_error(pull, NDR_ERR_VALIDATE, 
-                                     "failed output validation pull - %s",
-                                     nt_errstr(status));
+       ndr_err = ndr_pull(pull, NDR_OUT, st);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+               ndr_err = ndr_pull_error(pull, NDR_ERR_VALIDATE,
+                                        "failed output validation pull - %s",
+                                        nt_errstr(status));
+               return ndr_map_error2ntstatus(ndr_err);
        }
 
        push = ndr_push_init_ctx(mem_ctx);
@@ -1264,11 +1288,13 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
                return NT_STATUS_NO_MEMORY;
        }       
 
-       status = ndr_push(push, NDR_OUT, st);
-       if (!NT_STATUS_IS_OK(status)) {
-               return ndr_push_error(push, NDR_ERR_VALIDATE, 
-                                     "failed output validation push2 - %s",
-                                     nt_errstr(status));
+       ndr_err = ndr_push(push, NDR_OUT, st);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+               ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
+                                        "failed output validation push2 - %s",
+                                        nt_errstr(status));
+               return ndr_map_error2ntstatus(ndr_err);
        }
 
        blob2 = ndr_push_blob(push);
@@ -1278,9 +1304,9 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
                dump_data(3, blob.data, blob.length);
                DEBUG(3,("secondary:\n"));
                dump_data(3, blob2.data, blob2.length);
-               return ndr_push_error(push, NDR_ERR_VALIDATE, 
-                                     "failed output validation data - %s",
-                                     nt_errstr(status));
+               ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
+                                        "failed output validation blobs doesn't match");
+               return ndr_map_error2ntstatus(ndr_err);
        }
 
        /* this checks the printed forms of the two structures, which effectively
@@ -1291,7 +1317,7 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
                                       NDR_OUT, st);
        if (strcmp(s1, s2) != 0) {
 #if 1
-               printf("VALIDATE ERROR:\nWIRE:\n%s\n GEN:\n%s\n", s1, s2);
+               DEBUG(3,("VALIDATE ERROR:\nWIRE:\n%s\n GEN:\n%s\n", s1, s2));
 #else
                /* this is sometimes useful */
                printf("VALIDATE ERROR\n");
@@ -1299,6 +1325,9 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
                file_save("gen.dat", s2, strlen(s2));
                system("diff -u wire.dat gen.dat");
 #endif
+               ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
+                                        "failed output validation strings doesn't match");
+               return ndr_map_error2ntstatus(ndr_err);
        }
 
        return NT_STATUS_OK;
@@ -1320,6 +1349,7 @@ struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
        NTSTATUS status;
        DATA_BLOB request;
        struct rpc_request *req;
+       enum ndr_err_code ndr_err;
 
        call = &table->calls[opnum];
 
@@ -1334,8 +1364,9 @@ struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
        }
 
        /* push the structure into a blob */
-       status = call->ndr_push(push, NDR_IN, r);
-       if (!NT_STATUS_IS_OK(status)) {
+       ndr_err = call->ndr_push(push, NDR_IN, r);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               status = ndr_map_error2ntstatus(ndr_err);
                DEBUG(2,("Unable to ndr_push structure in dcerpc_ndr_request_send - %s\n",
                         nt_errstr(status)));
                talloc_free(push);
@@ -1390,6 +1421,7 @@ _PUBLIC_ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req)
        uint32_t opnum = req->ndr.opnum;
        const struct ndr_interface_table *table = req->ndr.table;
        const struct ndr_interface_call *call = &table->calls[opnum];
+       enum ndr_err_code ndr_err;
 
        /* make sure the recv code doesn't free the request, as we
           need to grab the flags element before it is freed */
@@ -1425,8 +1457,9 @@ _PUBLIC_ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req)
        dump_data(10, pull->data, pull->data_size);
 
        /* pull the structure from the blob */
-       status = call->ndr_pull(pull, NDR_OUT, r);
-       if (!NT_STATUS_IS_OK(status)) {
+       ndr_err = call->ndr_pull(pull, NDR_OUT, r);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               status = ndr_map_error2ntstatus(ndr_err);
                dcerpc_log_packet(table, opnum, NDR_OUT, 
                                  &response);
                return status;
@@ -1545,11 +1578,15 @@ static void dcerpc_alter_recv_handler(struct rpc_request *req,
        /* the alter_resp might contain a reply set of credentials */
        if (recv_pipe->conn->security_state.auth_info &&
            pkt->u.alter_resp.auth_info.length) {
-               c->status = ndr_pull_struct_blob(
+               enum ndr_err_code ndr_err;
+               ndr_err = ndr_pull_struct_blob(
                        &pkt->u.alter_resp.auth_info, recv_pipe,
                        recv_pipe->conn->security_state.auth_info,
                        (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
-               if (!composite_is_ok(c)) return;
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
        }
 
        composite_done(c);