STEP01: librpc/rpc/dcerpc_connection.c gensec
authorStefan Metzmacher <metze@samba.org>
Sun, 12 Jan 2014 00:16:14 +0000 (01:16 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 10:45:39 +0000 (12:45 +0200)
librpc/rpc/dcerpc_connection.c

index 7938af517b22f034c20bc39668417ba8ad529498..4819c887991d4efaa6c786a3071631e1267ed90c 100644 (file)
@@ -326,7 +326,7 @@ static NTSTATUS dcerpc_ncacn_push_auth(DATA_BLOB *blob,
        if (auth_info) {
                pkt->auth_length = auth_info->credentials.length;
        } else {
-               pkt->auth_length = 0;
+       //      pkt->auth_length = 0;
        }
 
        ndr_err = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
@@ -872,9 +872,8 @@ struct dcerpc_do_bind_out_frag {
 static void dcerpc_do_bind_cleanup(struct tevent_req *req,
                                   enum tevent_req_state req_state);
 
-static void dcerpc_do_bind_out_frag_next(struct tevent_req *req,
-                                           void *private_data);
 static void dcerpc_do_bind_sec_next(struct tevent_req *subreq);
+static void dcerpc_do_bind_out_frag_next(struct tevent_req *subreq);
 
 static NTSTATUS dcerpc_do_bind_handle_in_frag(void *private_data,
                                              struct ncacn_packet *pkt,
@@ -890,7 +889,7 @@ struct tevent_req *dcerpc_do_bind_send(TALLOC_CTX *mem_ctx,
 {
        struct tevent_req *req;
        struct dcerpc_do_bind_state *state;
-       bool ok;
+       struct tevent_req *subreq;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct dcerpc_do_bind_state);
@@ -911,8 +910,6 @@ struct tevent_req *dcerpc_do_bind_send(TALLOC_CTX *mem_ctx,
        tevent_req_set_cleanup_fn(req, dcerpc_do_bind_cleanup);
 
        if (state->sec != NULL && state->sec->gensec != NULL) {
-               struct tevent_req *subreq;
-
                subreq = gensec_update_send(state, ev,
                                            state->sec->gensec,
                                            state->sec_in);
@@ -925,15 +922,13 @@ struct tevent_req *dcerpc_do_bind_send(TALLOC_CTX *mem_ctx,
        }
 
        state->sec_status = NT_STATUS_OK;
-       ok = tevent_queue_add(state->conn->calls.out_queue,
-                             state->ev,
-                             req,
-                             dcerpc_do_bind_out_frag_next,
-                             NULL);
-       if (!ok) {
-               tevent_req_nomem(NULL, req);
+
+       subreq = tevent_queue_wait_send(state, state->ev,
+                                       state->conn->calls.out_queue);
+       if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
+       tevent_req_set_callback(subreq, dcerpc_do_bind_out_frag_next, req);
 
        return req;
 }
@@ -966,7 +961,6 @@ static void dcerpc_do_bind_sec_next(struct tevent_req *subreq)
                tevent_req_data(req,
                struct dcerpc_do_bind_state);
        NTSTATUS status;
-       bool ok;
 
        data_blob_free(&state->sec_out);
        status = gensec_update_recv(subreq, state, &state->sec_out);
@@ -981,24 +975,30 @@ static void dcerpc_do_bind_sec_next(struct tevent_req *subreq)
                return;
        }
 
-       ok = tevent_queue_add(state->conn->calls.out_queue,
-                             state->ev,
-                             req,
-                             dcerpc_do_bind_out_frag_next,
-                             NULL);
-       if (!ok) {
-               tevent_req_nomem(NULL, req);
+       if (NT_STATUS_IS_OK(state->sec_status) &&
+           state->sec_out.length == 0)
+       {
+               tevent_req_done(req);
                return;
        }
+
+       subreq = tevent_queue_wait_send(state, state->ev,
+                                       state->conn->calls.out_queue);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, dcerpc_do_bind_out_frag_next, req);
 }
 
 static void dcerpc_do_bind_out_frag_trans_wait1(struct tevent_req *subreq);
 static void dcerpc_do_bind_out_frag_done(struct tevent_req *subreq);
 static void dcerpc_do_bind_out_frag_trans_wait2(struct tevent_req *subreq);
 
-static void dcerpc_do_bind_out_frag_next(struct tevent_req *req,
-                                        void *private_data)
+static void dcerpc_do_bind_out_frag_next(struct tevent_req *subreq)
 {
+       struct tevent_req *req =
+               tevent_req_callback_data(subreq,
+               struct tevent_req);
        struct dcerpc_do_bind_state *state =
                tevent_req_data(req,
                struct dcerpc_do_bind_state);
@@ -1007,9 +1007,15 @@ static void dcerpc_do_bind_out_frag_next(struct tevent_req *req,
        NTSTATUS status;
        DATA_BLOB auth_info = data_blob_null;
        union dcerpc_payload u;
-       struct tevent_req *subreq;
        uint32_t i;
        bool use_trans = true;
+       bool ok;
+
+       ok = tevent_queue_wait_recv(subreq);
+       if (!ok) {
+
+       }
+       TALLOC_FREE(subreq);
 
        /*
         * the fragment belongs to the connection instead of the request
@@ -1040,7 +1046,7 @@ static void dcerpc_do_bind_out_frag_next(struct tevent_req *req,
                                          state->sec->auth_level,
                                          0, /* auth_pad_length */
                                          state->sec->context_id, /* auth_context_id */
-                                         &state->sec_in,
+                                         &state->sec_out,
                                          &auth_info);
                if (!NT_STATUS_IS_OK(status)) {
                        tevent_req_nterror(req, status);
@@ -1371,7 +1377,7 @@ static NTSTATUS dcerpc_do_bind_handle_in_frag(void *private_data,
        case DCERPC_PKT_BIND_ACK:
        case DCERPC_PKT_ALTER_RESP:
                if (pkt->auth_length != 0) {
-                       return NT_STATUS_NOT_IMPLEMENTED;
+               //      return NT_STATUS_NOT_IMPLEMENTED;
                }
 
                if (!state->conn->features.bind_done) {
@@ -1437,6 +1443,23 @@ static NTSTATUS dcerpc_do_bind_handle_in_frag(void *private_data,
                        }
                }
 
+               if (pkt->auth_length >= 8) {
+                       struct tevent_req *subreq;
+
+                       state->sec_in = data_blob_talloc(state,
+                                       pkt->u.bind_ack.auth_info.data + 8,
+                                       pkt->u.bind_ack.auth_info.length - 8);
+
+                       subreq = gensec_update_send(state, state->ev,
+                                                   state->sec->gensec,
+                                                   state->sec_in);
+                       if (tevent_req_nomem(subreq, req)) {
+                               return NT_STATUS_OK;
+                       }
+                       tevent_req_set_callback(subreq, dcerpc_do_bind_sec_next, req);
+                       return NT_STATUS_OK;
+               }
+
                tevent_req_done(req);
                return NT_STATUS_OK;