added a smb.conf flag "rpc big endian" that tells our rpc server to
authorAndrew Tridgell <tridge@samba.org>
Wed, 17 Dec 2003 02:06:44 +0000 (02:06 +0000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 17 Dec 2003 02:06:44 +0000 (02:06 +0000)
send packets in bigendian format.
(This used to be commit 44df662960e662a55a9f27627f838771503a7a59)

source4/librpc/rpc/dcerpc.c
source4/librpc/rpc/dcerpc_util.c
source4/param/loadparm.c
source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcesrv_auth.c

index f02bdb2a23550e020a1af255a9214a293a7fe21f..d00f2c2986945e893b90bcc2971c352105fd9c31 100644 (file)
@@ -75,7 +75,7 @@ void dcerpc_set_frag_length(DATA_BLOB *blob, uint16 v)
        }
 }
 
-uint16 dcerpc_get_frag_length(DATA_BLOB *blob)
+uint16 dcerpc_get_frag_length(const DATA_BLOB *blob)
 {
        if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
                return SVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
@@ -108,8 +108,8 @@ static NTSTATUS dcerpc_pull(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (! (CVAL(blob, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
-               ndr->flags |= DCERPC_PULL_BIGENDIAN;
+       if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
        }
 
        return ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
@@ -137,8 +137,8 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (! (CVAL(blob, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
-               ndr->flags |= DCERPC_PULL_BIGENDIAN;
+       if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
        }
 
        /* pull the basic packet */
@@ -169,8 +169,8 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (! (CVAL(blob, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
-               ndr->flags |= DCERPC_PULL_BIGENDIAN;
+       if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
        }
 
        status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
@@ -225,7 +225,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
 
        /* non-signed packets are simpler */
        if (!p->auth_info || !p->ntlmssp_state) {
-               return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info, p->flags);
+               return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info);
        }
 
        ndr = ndr_push_init_ctx(mem_ctx);
@@ -353,7 +353,7 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
        pkt.u.bind.auth_info = data_blob(NULL, 0);
 
        /* construct the NDR form of the packet */
-       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info, p->flags);
+       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -412,7 +412,7 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
        pkt.u.auth.auth_info = data_blob(NULL, 0);
 
        /* construct the NDR form of the packet */
-       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info, p->flags);
+       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index bc10f4e92d494b71db6ca64b7c8e990cae78ce71..e4e67b3cf052a21ccc4f35602eb981cc0f5756d2 100644 (file)
@@ -223,8 +223,7 @@ const struct dcerpc_interface_table *idl_iface_by_uuid(const char *uuid)
 */
 NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 
                          struct dcerpc_packet *pkt,
-                         struct dcerpc_auth *auth_info,
-                         unsigned flags)
+                         struct dcerpc_auth *auth_info)
 {
        NTSTATUS status;
        struct ndr_push *ndr;
@@ -234,7 +233,7 @@ NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (flags & DCERPC_PUSH_BIGENDIAN) {
+       if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
                ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
        }
 
index 6ec4842c6d3bdca03b77165cc077d94563231019..aff4a4f12a19ea1632eb00ee61df45bc1b8fda95 100644 (file)
@@ -278,6 +278,7 @@ typedef struct
        BOOL bUnixExtensions;
        BOOL bDisableNetbios;
        BOOL bKernelChangeNotify;
+       BOOL bRpcBigEndian;
        int restrict_anonymous;
        int name_cache_timeout;
        BOOL client_signing;
@@ -869,6 +870,7 @@ static struct parm_struct parm_table[] = {
        {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
        {"client signing", P_BOOL, P_GLOBAL, &Globals.client_signing, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
        {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_DEVELOPER},
+       {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
 
        {"Tuning Options", P_SEP, P_SEPARATOR},
        
@@ -1700,6 +1702,7 @@ FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
 FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
+FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
index 081b5b1d5abd040c4f47e080891abd7ea4cef2f6..d3e2f1917f8f6c04eb4213120acb3a6a1d7adb57 100644 (file)
@@ -178,6 +178,20 @@ void dcesrv_endpoint_disconnect(struct dcesrv_state *p)
        talloc_destroy(p->mem_ctx);
 }
 
+static void dcesrv_init_hdr(struct dcerpc_packet *pkt)
+{
+       pkt->rpc_vers = 5;
+       pkt->rpc_vers_minor = 0;
+       if (lp_rpc_big_endian()) {
+               pkt->drep[0] = 0;
+       } else {
+               pkt->drep[0] = DCERPC_DREP_LE;
+       }
+       pkt->drep[1] = 0;
+       pkt->drep[2] = 0;
+       pkt->drep[3] = 0;
+}
+
 /*
   return a dcerpc fault
 */
@@ -188,12 +202,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code)
        NTSTATUS status;
 
        /* setup a bind_ack */
-       pkt.rpc_vers = 5;
-       pkt.rpc_vers_minor = 0;
-       pkt.drep[0] = 0x10; /* Little endian */
-       pkt.drep[1] = 0;
-       pkt.drep[2] = 0;
-       pkt.drep[3] = 0;
+       dcesrv_init_hdr(&pkt);
        pkt.auth_length = 0;
        pkt.call_id = call->pkt.call_id;
        pkt.ptype = DCERPC_PKT_FAULT;
@@ -208,12 +217,12 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code)
                return NT_STATUS_NO_MEMORY;
        }
 
-       status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0);
+       status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       SSVAL(rep->data.data,  DCERPC_FRAG_LEN_OFFSET, rep->data.length);
+       dcerpc_set_frag_length(&rep->data, rep->data.length);
 
        DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *);
 
@@ -247,12 +256,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason)
        NTSTATUS status;
 
        /* setup a bind_ack */
-       pkt.rpc_vers = 5;
-       pkt.rpc_vers_minor = 0;
-       pkt.drep[0] = 0x10; /* Little endian */
-       pkt.drep[1] = 0;
-       pkt.drep[2] = 0;
-       pkt.drep[3] = 0;
+       dcesrv_init_hdr(&pkt);
        pkt.auth_length = 0;
        pkt.call_id = call->pkt.call_id;
        pkt.ptype = DCERPC_PKT_BIND_NAK;
@@ -265,12 +269,12 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason)
                return NT_STATUS_NO_MEMORY;
        }
 
-       status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0);
+       status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       SSVAL(rep->data.data,  DCERPC_FRAG_LEN_OFFSET, rep->data.length);
+       dcerpc_set_frag_length(&rep->data, rep->data.length);
 
        DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *);
 
@@ -328,12 +332,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        }
 
        /* setup a bind_ack */
-       pkt.rpc_vers = 5;
-       pkt.rpc_vers_minor = 0;
-       pkt.drep[0] = 0x10; /* Little endian */
-       pkt.drep[1] = 0;
-       pkt.drep[2] = 0;
-       pkt.drep[3] = 0;
+       dcesrv_init_hdr(&pkt);
        pkt.auth_length = 0;
        pkt.call_id = call->pkt.call_id;
        pkt.ptype = DCERPC_PKT_BIND_ACK;
@@ -368,12 +367,12 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        }
 
        status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, 
-                                 call->dce->auth_state.auth_info, 0);
+                                 call->dce->auth_state.auth_info);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       SSVAL(rep->data.data,  DCERPC_FRAG_LEN_OFFSET, rep->data.length);
+       dcerpc_set_frag_length(&rep->data, rep->data.length);
 
        DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *);
        DLIST_ADD_END(call->dce->call_list, call, struct dcesrv_call_state *);
@@ -428,6 +427,10 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
+               pull->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
        /* unravel the NDR for the packet */
        status = call->dce->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r);
        if (!NT_STATUS_IS_OK(status)) {
@@ -446,6 +449,10 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (lp_rpc_big_endian()) {
+               push->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
        status = call->dce->ndr->calls[opnum].ndr_push(push, NDR_OUT, r);
        if (!NT_STATUS_IS_OK(status)) {
                return dcesrv_fault(call, DCERPC_FAULT_NDR);
@@ -471,12 +478,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
                }
 
                /* form the dcerpc response packet */
-               pkt.rpc_vers = 5;
-               pkt.rpc_vers_minor = 0;
-               pkt.drep[0] = 0x10; /* Little endian */
-               pkt.drep[1] = 0;
-               pkt.drep[2] = 0;
-               pkt.drep[3] = 0;
+               dcesrv_init_hdr(&pkt);
                pkt.auth_length = 0;
                pkt.call_id = call->pkt.call_id;
                pkt.ptype = DCERPC_PKT_RESPONSE;
@@ -497,7 +499,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
                        return dcesrv_fault(call, DCERPC_FAULT_OTHER);          
                }
 
-               SSVAL(rep->data.data,  DCERPC_FRAG_LEN_OFFSET, rep->data.length);
+               dcerpc_set_frag_length(&rep->data, rep->data.length);
 
                DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *);
                
@@ -519,7 +521,7 @@ static BOOL dce_full_packet(const DATA_BLOB *data)
        if (data->length < DCERPC_FRAG_LEN_OFFSET+2) {
                return False;
        }
-       if (SVAL(data->data, DCERPC_FRAG_LEN_OFFSET) > data->length) {
+       if (dcerpc_get_frag_length(data) > data->length) {
                return False;
        }
        return True;
@@ -570,7 +572,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce)
        call->replies = NULL;
 
        blob = dce->partial_input;
-       blob.length = SVAL(blob.data, DCERPC_FRAG_LEN_OFFSET);
+       blob.length = dcerpc_get_frag_length(&blob);
 
        ndr = ndr_pull_init_blob(&blob, mem_ctx);
        if (!ndr) {
@@ -579,6 +581,10 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce)
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (!(CVAL(blob.data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
        status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(dce->mem_ctx, dce->partial_input.data);
index 0f4b22ee3d068a68d260d0ae8d14e5b7c9efd6ed..776d394e99a8f71deda14345adea3149743414c6 100644 (file)
@@ -184,6 +184,10 @@ BOOL dcesrv_auth_request(struct dcesrv_call_state *call)
                return False;
        }
 
+       if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
        status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
        if (!NT_STATUS_IS_OK(status)) {
                return False;
@@ -232,7 +236,7 @@ BOOL dcesrv_auth_response(struct dcesrv_call_state *call,
 
        /* non-signed packets are simple */
        if (!dce->auth_state.auth_info || !dce->auth_state.ntlmssp_state) {
-               status = dcerpc_push_auth(blob, call->mem_ctx, pkt, NULL, 0);
+               status = dcerpc_push_auth(blob, call->mem_ctx, pkt, NULL);
                return NT_STATUS_IS_OK(status);
        }
 
@@ -241,6 +245,10 @@ BOOL dcesrv_auth_response(struct dcesrv_call_state *call,
                return False;
        }
 
+       if (pkt->drep[0] & DCERPC_DREP_LE) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
        status = ndr_push_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
        if (!NT_STATUS_IS_OK(status)) {
                return False;
@@ -286,8 +294,8 @@ BOOL dcesrv_auth_response(struct dcesrv_call_state *call,
        /* fill in the fragment length and auth_length, we can't fill
           in these earlier as we don't know the signature length (it
           could be variable length) */
-       SSVAL(blob->data,  DCERPC_FRAG_LEN_OFFSET, blob->length);
-       SSVAL(blob->data,  DCERPC_AUTH_LEN_OFFSET, dce->auth_state.auth_info->credentials.length);
+       dcerpc_set_frag_length(blob, blob->length);
+       dcerpc_set_auth_length(blob, dce->auth_state.auth_info->credentials.length);
 
        data_blob_free(&dce->auth_state.auth_info->credentials);