s3:rpc: Fix is_known_pipename for dynamically loaded pipes
[sfrench/samba-autobuild/.git] / source3 / rpc_server / srv_pipe.c
index 040831c98f50a87fdcb336f88dfc837dab67631c..a246b6db50d6d795c37d893825d73c352975fe40 100644 (file)
@@ -32,6 +32,7 @@
 #include "../librpc/gen_ndr/ndr_schannel.h"
 #include "../libcli/auth/schannel.h"
 #include "../libcli/auth/schannel_proto.h"
+#include "../libcli/auth/spnego.h"
 
 extern struct current_user current_user;
 
@@ -84,11 +85,11 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
        memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
 
        /* Change the incoming request header to a response. */
-       p->hdr.pkt_type = RPC_RESPONSE;
+       p->hdr.pkt_type = DCERPC_PKT_RESPONSE;
 
        /* Set up rpc header flags. */
        if (p->out_data.data_sent_length == 0) {
-               p->hdr.flags = RPC_FLG_FIRST;
+               p->hdr.flags = DCERPC_PFC_FLAG_FIRST;
        } else {
                p->hdr.flags = 0;
        }
@@ -130,7 +131,7 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
         */
 
        if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
-               p->hdr.flags |= RPC_FLG_LAST;
+               p->hdr.flags |= DCERPC_PFC_FLAG_LAST;
                if (data_len_left % 8) {
                        ss_padding_len = 8 - (data_len_left % 8);
                        DEBUG(10,("create_next_pdu_ntlmssp: adding sign/seal padding of %u\n",
@@ -302,11 +303,11 @@ static bool create_next_pdu_schannel(pipes_struct *p)
        memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
 
        /* Change the incoming request header to a response. */
-       p->hdr.pkt_type = RPC_RESPONSE;
+       p->hdr.pkt_type = DCERPC_PKT_RESPONSE;
 
        /* Set up rpc header flags. */
        if (p->out_data.data_sent_length == 0) {
-               p->hdr.flags = RPC_FLG_FIRST;
+               p->hdr.flags = DCERPC_PFC_FLAG_FIRST;
        } else {
                p->hdr.flags = 0;
        }
@@ -349,7 +350,7 @@ static bool create_next_pdu_schannel(pipes_struct *p)
         */
 
        if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
-               p->hdr.flags |= RPC_FLG_LAST;
+               p->hdr.flags |= DCERPC_PFC_FLAG_LAST;
                if (data_len_left % 8) {
                        ss_padding_len = 8 - (data_len_left % 8);
                        DEBUG(10,("create_next_pdu_schannel: adding sign/seal padding of %u\n",
@@ -411,6 +412,7 @@ static bool create_next_pdu_schannel(pipes_struct *p)
                 */
                RPC_HDR_AUTH auth_info;
                DATA_BLOB blob;
+               uint8_t *data;
 
                /* Check it's the type of reply we were expecting to decode */
 
@@ -427,20 +429,24 @@ static bool create_next_pdu_schannel(pipes_struct *p)
                        return False;
                }
 
+               data = (uint8_t *)prs_data_p(&p->out_data.frag) + data_pos;
+
                switch (p->auth.auth_level) {
                case DCERPC_AUTH_LEVEL_PRIVACY:
-                       status = schannel_seal_packet(p->auth.a_u.schannel_auth,
-                                                     talloc_tos(),
-                                                     (uint8_t *)prs_data_p(&p->out_data.frag) + data_pos,
-                                                     data_len + ss_padding_len,
-                                                     &blob);
+                       status = netsec_outgoing_packet(p->auth.a_u.schannel_auth,
+                                                       talloc_tos(),
+                                                       true,
+                                                       data,
+                                                       data_len + ss_padding_len,
+                                                       &blob);
                        break;
                case DCERPC_AUTH_LEVEL_INTEGRITY:
-                       status = schannel_sign_packet(p->auth.a_u.schannel_auth,
-                                                     talloc_tos(),
-                                                     (uint8_t *)prs_data_p(&p->out_data.frag) + data_pos,
-                                                     data_len + ss_padding_len,
-                                                     &blob);
+                       status = netsec_outgoing_packet(p->auth.a_u.schannel_auth,
+                                                       talloc_tos(),
+                                                       false,
+                                                       data,
+                                                       data_len + ss_padding_len,
+                                                       &blob);
                        break;
                default:
                        status = NT_STATUS_INTERNAL_ERROR;
@@ -501,11 +507,11 @@ static bool create_next_pdu_noauth(pipes_struct *p)
        memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
 
        /* Change the incoming request header to a response. */
-       p->hdr.pkt_type = RPC_RESPONSE;
+       p->hdr.pkt_type = DCERPC_PKT_RESPONSE;
 
        /* Set up rpc header flags. */
        if (p->out_data.data_sent_length == 0) {
-               p->hdr.flags = RPC_FLG_FIRST;
+               p->hdr.flags = DCERPC_PFC_FLAG_FIRST;
        } else {
                p->hdr.flags = 0;
        }
@@ -547,7 +553,7 @@ static bool create_next_pdu_noauth(pipes_struct *p)
         */
 
        if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
-               p->hdr.flags |= RPC_FLG_LAST;
+               p->hdr.flags |= DCERPC_PFC_FLAG_LAST;
        }
 
        /*
@@ -826,7 +832,7 @@ static bool setup_bind_nak(pipes_struct *p)
         * Initialize a bind_nak header.
         */
 
-       init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+       init_rpc_hdr(&nak_hdr, DCERPC_PKT_BIND_NAK, DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST,
                p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0);
 
        /*
@@ -886,7 +892,7 @@ bool setup_fault_pdu(pipes_struct *p, NTSTATUS status)
         * Initialize a fault header.
         */
 
-       init_rpc_hdr(&fault_hdr, RPC_FAULT, RPC_FLG_FIRST | RPC_FLG_LAST | RPC_FLG_NOCALL,
+       init_rpc_hdr(&fault_hdr, DCERPC_PKT_FAULT, DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
             p->hdr.call_id, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_FAULT_LEN, 0);
 
        /*
@@ -953,7 +959,7 @@ bool setup_cancel_ack_reply(pipes_struct *p, prs_struct *rpc_in_p)
         * Initialize a cancel_ack header.
         */
 
-       init_rpc_hdr(&ack_reply_hdr, RPC_CANCEL_ACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+       init_rpc_hdr(&ack_reply_hdr, DCERPC_PKT_CANCEL_ACK, DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST,
                        p->hdr.call_id, RPC_HEADER_LEN, 0);
 
        /*
@@ -1086,6 +1092,7 @@ bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
 {
        const char *pipename = cli_filename;
        int i;
+       NTSTATUS status;
 
        if (strnequal(pipename, "\\PIPE\\", 6)) {
                pipename += 5;
@@ -1107,7 +1114,27 @@ bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
                }
        }
 
-       DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
+       status = smb_probe_module("rpc", pipename);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
+               return false;
+       }
+       DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
+
+       /*
+        * Scan the list again for the interface id
+        */
+
+       for (i=0; i<rpc_lookup_size; i++) {
+               if (strequal(pipename, rpc_lookup[i].pipe.clnt)) {
+                       *syntax = rpc_lookup[i].rpc_interface;
+                       return true;
+               }
+       }
+
+       DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
+                  pipename));
+
        return false;
 }
 
@@ -1547,7 +1574,7 @@ static bool pipe_ntlmssp_auth_bind(pipes_struct *p, prs_struct *rpc_in_p,
 
        DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n"));
 
-       /* We can't set pipe_bound True yet - we need an RPC_AUTH3 response packet... */
+       /* We can't set pipe_bound True yet - we need an DCERPC_PKT_AUTH3 response packet... */
        return True;
 
   err:
@@ -1798,7 +1825,7 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
                auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
        }
 
-       init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+       init_rpc_hdr(&p->hdr, DCERPC_PKT_BIND_ACK, DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST,
                        p->hdr.call_id,
                        RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth),
                        auth_len);
@@ -1986,7 +2013,7 @@ bool api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p)
                auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
        }
 
-       init_rpc_hdr(&p->hdr, RPC_ALTCONTRESP, RPC_FLG_FIRST | RPC_FLG_LAST,
+       init_rpc_hdr(&p->hdr, DCERPC_PKT_ALTER_RESP, DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST,
                        p->hdr.call_id,
                        RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth),
                        auth_len);
@@ -2162,6 +2189,7 @@ bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss
        RPC_HDR_AUTH auth_info;
        DATA_BLOB blob;
        NTSTATUS status;
+       uint8_t *data;
 
        auth_len = p->hdr.auth_len;
 
@@ -2215,20 +2243,24 @@ bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss
                dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
        }
 
+       data = (uint8_t *)prs_data_p(rpc_in)+RPC_HDR_REQ_LEN;
+
        switch (auth_info.auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
-               status = schannel_unseal_packet(p->auth.a_u.schannel_auth,
+               status = netsec_incoming_packet(p->auth.a_u.schannel_auth,
                                                talloc_tos(),
-                                               (uint8_t *)prs_data_p(rpc_in)+RPC_HDR_REQ_LEN,
+                                               true,
+                                               data,
                                                data_len,
                                                &blob);
                break;
        case DCERPC_AUTH_LEVEL_INTEGRITY:
-               status = schannel_check_packet(p->auth.a_u.schannel_auth,
-                                              talloc_tos(),
-                                              (uint8_t *)prs_data_p(rpc_in)+RPC_HDR_REQ_LEN,
-                                              data_len,
-                                              &blob);
+               status = netsec_incoming_packet(p->auth.a_u.schannel_auth,
+                                               talloc_tos(),
+                                               false,
+                                               data,
+                                               data_len,
+                                               &blob);
                break;
        default:
                status = NT_STATUS_INTERNAL_ERROR;