s4:rpc_server: implement bind time feature negotiation
authorStefan Metzmacher <metze@samba.org>
Tue, 6 Oct 2015 08:18:06 +0000 (10:18 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Wed, 26 Oct 2016 09:20:14 +0000 (11:20 +0200)
For now we don't really support any negotiated features.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcerpc_server.h

index be785e7122a43f8f1eaa66fed57a97d92ad88e74..ecc6929c5b56e753f42a20804370ed093cf51304 100644 (file)
@@ -683,6 +683,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        const char *ep_prefix = "";
        const char *endpoint = NULL;
        struct dcerpc_ack_ctx *ack_ctx_list = NULL;
+       struct dcerpc_ack_ctx *ack_features = NULL;
        size_t i;
 
        status = dcerpc_verify_ncacn_packet_header(&call->pkt,
@@ -751,6 +752,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
                const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
                struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
+               bool is_feature = false;
+               uint64_t features = 0;
 
                if (c->num_transfer_syntaxes == 0) {
                        return dcesrv_bind_nak(call, 0);
@@ -758,6 +761,35 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
 
                a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
                a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
+
+               /*
+                * It's only treated as bind time feature request, if the first
+                * transfer_syntax matches, all others are ignored.
+                */
+               is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
+                                                              &features);
+               if (!is_feature) {
+                       continue;
+               }
+
+               if (ack_features != NULL) {
+                       /*
+                        * Only one bind time feature context is allowed.
+                        */
+                       return dcesrv_bind_nak(call, 0);
+               }
+               ack_features = a;
+
+               a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
+               a->reason.negotiate = 0;
+               if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
+                       /* not supported yet */
+               }
+               if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
+                       /* not supported yet */
+               }
+
+               call->conn->bind_time_features = a->reason.negotiate;
        }
 
        /*
@@ -956,6 +988,7 @@ static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
 
        switch (ack->result) {
        case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
+       case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
                /*
                 * We is already completed.
                 */
index 9ec4dbb98443697362c337e021cc0a99db0b94fe..2533b64e37a6473273426cbd845d413275d44dc2 100644 (file)
@@ -276,6 +276,9 @@ struct dcesrv_connection {
         * Our preferred transfer syntax.
         */
        const struct ndr_syntax_id *preferred_transfer;
+
+       /* the negotiated bind time features */
+       uint16_t bind_time_features;
 };