libcli/named_pipe_auth: we need to hide length of the message mode header from the...
[metze/samba/wip.git] / libcli / named_pipe_auth / npa_tstream.c
index c1a293eac464282207f2f233a3645f25f19ce7a8..b41fa3eb6d5d5566b13c4024d2fec4ab33ac5203 100644 (file)
@@ -63,11 +63,12 @@ struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx,
                                        const char *directory,
                                        const char *npipe,
                                        const struct tsocket_address *client,
-                                       const char *client_name,
+                                       const char *client_name_in,
                                        const struct tsocket_address *server,
                                        const char *server_name,
-                                       const struct netr_SamInfo3 *info3,
-                                       DATA_BLOB session_key)
+                                       const struct netr_SamInfo3 *sam_info3,
+                                       DATA_BLOB session_key,
+                                       DATA_BLOB delegated_creds)
 {
        struct tevent_req *req;
        struct tstream_npa_connect_state *state;
@@ -109,45 +110,48 @@ struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx,
 
        ZERO_STRUCT(state->auth_req);
        if (client) {
-               struct named_pipe_auth_req_info2 *info2;
+               struct named_pipe_auth_req_info3 *info3;
 
                if (!server) {
                        tevent_req_error(req, EINVAL);
                        goto post;
                }
 
-               state->auth_req.level = 2;
-               info2 = &state->auth_req.info.info2;
+               state->auth_req.level = 3;
+               info3 = &state->auth_req.info.info3;
 
-               info2->client_name = client_name;
-               info2->client_addr = tsocket_address_inet_addr_string(client, state);
-               if (!info2->client_addr) {
+               info3->client_name = client_name_in;
+               info3->client_addr = tsocket_address_inet_addr_string(client, state);
+               if (!info3->client_addr) {
                        /* errno might be EINVAL */
                        tevent_req_error(req, errno);
                        goto post;
                }
-               info2->client_port = tsocket_address_inet_port(client);
-               if (!info2->client_name) {
-                       info2->client_name = info2->client_addr;
+               info3->client_port = tsocket_address_inet_port(client);
+               if (!info3->client_name) {
+                       info3->client_name = info3->client_addr;
                }
 
-               info2->server_addr = tsocket_address_inet_addr_string(server, state);
-               if (!info2->server_addr) {
+               info3->server_addr = tsocket_address_inet_addr_string(server, state);
+               if (!info3->server_addr) {
                        /* errno might be EINVAL */
                        tevent_req_error(req, errno);
                        goto post;
                }
-               info2->server_port = tsocket_address_inet_port(server);
-               if (!info2->server_name) {
-                       info2->server_name = info2->server_addr;
+               info3->server_port = tsocket_address_inet_port(server);
+               if (!info3->server_name) {
+                       info3->server_name = info3->server_addr;
                }
 
-               info2->sam_info3 = discard_const_p(struct netr_SamInfo3, info3);
-               info2->session_key_length = session_key.length;
-               info2->session_key = session_key.data;
-       } else if (info3) {
+               info3->sam_info3 = discard_const_p(struct netr_SamInfo3, sam_info3);
+               info3->session_key_length = session_key.length;
+               info3->session_key = session_key.data;
+               info3->gssapi_delegated_creds_length = delegated_creds.length;
+               info3->gssapi_delegated_creds = delegated_creds.data;
+
+       } else if (sam_info3) {
                state->auth_req.level = 1;
-               state->auth_req.info.info1 = *info3;
+               state->auth_req.info.info1 = *sam_info3;
        } else {
                state->auth_req.level = 0;
        }
@@ -429,6 +433,11 @@ int _tstream_npa_connect_recv(struct tevent_req *req,
                device_state = state->auth_rep.info.info2.device_state;
                allocation_size = state->auth_rep.info.info2.allocation_size;
                break;
+       case 3:
+               npas->file_type = state->auth_rep.info.info3.file_type;
+               device_state = state->auth_rep.info.info3.device_state;
+               allocation_size = state->auth_rep.info.info3.allocation_size;
+               break;
        }
 
        *_stream = stream;
@@ -458,6 +467,9 @@ static ssize_t tstream_npa_pending_bytes(struct tstream_context *stream)
        case FILE_TYPE_MESSAGE_MODE_PIPE:
                ret = npas->pending.iov_len;
                break;
+
+       default:
+               ret = -1;
        }
 
        return ret;
@@ -731,7 +743,7 @@ static int tstream_npa_readv_next_vector(struct tstream_context *unix_stream,
 
        if (left > 0) {
                /*
-                * if the message if longer than the buffers the caller
+                * if the message is longer than the buffers the caller
                 * requested, we need to consume the rest of the message
                 * into the pending buffer, where the next readv can
                 * be served from.
@@ -796,6 +808,7 @@ struct tstream_npa_writev_state {
        size_t count;
 
        /* the header for message mode */
+       bool hdr_used;
        uint8_t hdr[2];
 
        int ret;
@@ -832,6 +845,7 @@ static struct tevent_req *tstream_npa_writev_send(TALLOC_CTX *mem_ctx,
 
        switch (npas->file_type) {
        case FILE_TYPE_BYTE_MODE_PIPE:
+               state->hdr_used = false;
                state->vector   = vector;
                state->count    = count;
                break;
@@ -849,6 +863,7 @@ static struct tevent_req *tstream_npa_writev_send(TALLOC_CTX *mem_ctx,
                new_vector[0].iov_len = sizeof(state->hdr);
                memcpy(new_vector + 1, vector, sizeof(struct iovec)*count);
 
+               state->hdr_used = true;
                state->vector   = new_vector;
                state->count    = count + 1;
 
@@ -899,6 +914,14 @@ static void tstream_npa_writev_handler(struct tevent_req *subreq)
                return;
        }
 
+       /*
+        * in message mode we need to hide the length
+        * of the hdr from the caller
+        */
+       if (state->hdr_used) {
+               ret -= sizeof(state->hdr);
+       }
+
        state->ret = ret;
 
        tevent_req_done(req);