diff options
Diffstat (limited to 'usr/src/lib/smbsrv/libmlrpc')
| -rw-r--r-- | usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h | 13 | ||||
| -rw-r--r-- | usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c | 86 |
2 files changed, 79 insertions, 20 deletions
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h b/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h index 5ab647c0eb..7a5f3627f7 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h +++ b/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _LIBMLRPC_H @@ -159,18 +158,21 @@ extern "C" { #define NDR_DRC_FAULT_OUT_OF_MEMORY 0xF000 /* RPCHDR */ +#define NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH 0x81FF +#define NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT 0x83FF +#define NDR_DRC_FAULT_RPCHDR_DECODE_FAILED 0x86FF #define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID 0xC0FF /* PARAM_0_INVALID */ -#define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */ +#define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */ /* Request */ #define NDR_DRC_FAULT_REQUEST_PCONT_INVALID 0xC000 /* PARAM_0_INVALID */ #define NDR_DRC_FAULT_REQUEST_OPNUM_INVALID 0xC100 /* PARAM_1_INVALID */ /* Bind */ +#define NDR_DRC_BINDING_MADE 0x000B /* OK */ #define NDR_DRC_FAULT_BIND_PCONT_BUSY 0xC00B /* PARAM_0_INVALID */ #define NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE 0xC10B /* PARAM_1_INVALID */ #define NDR_DRC_FAULT_BIND_NO_SLOTS 0x910B /* RESOURCE_1 */ -#define NDR_DRC_BINDING_MADE 0x000B /* OK */ /* API */ #define NDR_DRC_FAULT_API_SERVICE_INVALID 0xC0AA /* PARAM_0_INVALID */ @@ -502,7 +504,8 @@ void ndr_clnt_free_heap(ndr_client_t *); /* ndr_marshal.c */ ndr_buf_t *ndr_buf_init(ndr_typeinfo_t *); void ndr_buf_fini(ndr_buf_t *); -int ndr_buf_decode(ndr_buf_t *, unsigned, const char *data, size_t, void *); +int ndr_buf_decode(ndr_buf_t *, unsigned, unsigned, const char *data, size_t, + void *); int ndr_decode_call(ndr_xa_t *, void *); int ndr_encode_return(ndr_xa_t *, void *); int ndr_encode_call(ndr_xa_t *, void *); diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c index 12fd0c0d52..a690dfb2e9 100644 --- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c +++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <assert.h> @@ -37,6 +36,7 @@ static const int ndr_native_byte_order = NDR_REPLAB_INTG_LITTLE_ENDIAN; #endif static int ndr_decode_hdr_common(ndr_stream_t *, ndr_common_header_t *); +static int ndr_decode_pac_hdr(ndr_stream_t *, ndr_pac_hdr_t *); static int ndr_encode_decode_common(ndr_stream_t *nds, unsigned opnum, @@ -122,10 +122,11 @@ ndr_buf_fini(ndr_buf_t *nbuf) * } */ int -ndr_buf_decode(ndr_buf_t *nbuf, unsigned opnum, const char *data, - size_t datalen, void *result) +ndr_buf_decode(ndr_buf_t *nbuf, unsigned hdr_type, unsigned opnum, + const char *data, size_t datalen, void *result) { ndr_common_header_t hdr; + ndr_pac_hdr_t pac_hdr; unsigned pdu_size_hint; int rc; @@ -145,12 +146,28 @@ ndr_buf_decode(ndr_buf_t *nbuf, unsigned opnum, const char *data, bcopy(data, nbuf->nb_nds.pdu_base_addr, datalen); - rc = ndr_decode_hdr_common(&nbuf->nb_nds, &hdr); - if (NDR_DRC_IS_FAULT(rc)) - return (rc); + switch (hdr_type) { + case NDR_PTYPE_COMMON: + rc = ndr_decode_hdr_common(&nbuf->nb_nds, &hdr); + if (NDR_DRC_IS_FAULT(rc)) + return (rc); + + if (!NDR_IS_SINGLE_FRAG(hdr.pfc_flags)) + return (NDR_DRC_FAULT_DECODE_FAILED); + break; + + case NDR_PTYPE_PAC: + rc = ndr_decode_pac_hdr(&nbuf->nb_nds, &pac_hdr); + if (NDR_DRC_IS_FAULT(rc)) + return (rc); - if (!NDR_IS_SINGLE_FRAG(hdr.pfc_flags)) - return (NDR_DRC_FAULT_DECODE_FAILED); + if (pac_hdr.common_hdr.hdrlen != sizeof (ndr_serialtype1_hdr_t)) + return (NDR_DRC_FAULT_DECODE_FAILED); + break; + + default: + return (NDR_ERR_UNIMPLEMENTED); + } rc = ndr_encode_decode_common(&nbuf->nb_nds, opnum, nbuf->nb_ti, result); @@ -244,7 +261,7 @@ ndr_decode_pdu_hdr(ndr_xa_t *mxa) * Verify the protocol version. */ if ((hdr->rpc_vers != 5) || (hdr->rpc_vers_minor != 0)) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); + return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); mxa->ptype = hdr->ptype; return (NDR_DRC_OK); @@ -259,21 +276,21 @@ ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr) int byte_order; if (nds->m_op != NDR_M_OP_UNMARSHALL) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_MODE_MISMATCH)); + return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH); /* * All PDU headers are at least this big */ rc = NDS_GROW_PDU(nds, sizeof (ndr_common_header_t), 0); if (!rc) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_RECEIVED_RUNT)); + return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT); /* * Peek at the first eight bytes to figure out what we're doing. */ rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0); if (!rc) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); + return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); /* * Check for ASCII as the character set. This is an ASCII @@ -281,7 +298,7 @@ ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr) */ charset = hdr->packed_drep.intg_char_rep & NDR_REPLAB_CHAR_MASK; if (charset != NDR_REPLAB_CHAR_ASCII) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); + return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); /* * Set the byte swap flag if the PDU byte-order @@ -301,6 +318,45 @@ ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr) return (NDR_DRC_PTYPE_RPCHDR(rc)); } +static int +ndr_decode_pac_hdr(ndr_stream_t *nds, ndr_pac_hdr_t *hdr) +{ + int rc; + + if (nds->m_op != NDR_M_OP_UNMARSHALL) + return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH); + + /* + * All PDU headers are at least this big + */ + rc = NDS_GROW_PDU(nds, sizeof (ndr_pac_hdr_t), 0); + if (!rc) + return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT); + + /* + * Peek at the first eight bytes to figure out what we're doing. + */ + rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0); + if (!rc) + return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); + + /* Must be set to 1 to indicate type serialization version 1. */ + if (hdr->common_hdr.version != 1) + return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); + + /* + * Set the byte swap flag if the PDU byte-order + * is different from the local byte-order. + */ + nds->swap = + (hdr->common_hdr.endianness != ndr_native_byte_order) ? 1 : 0; + + rc = ndr_encode_decode_common(nds, NDR_PTYPE_PAC, + &TYPEINFO(ndr_hdr), hdr); + + return (NDR_DRC_PTYPE_RPCHDR(rc)); +} + /* * Decode an RPC fragment header. Use ndr_decode_pdu_hdr() to process * the first fragment header then this function to process additional @@ -400,7 +456,7 @@ ndr_encode_pdu_hdr(ndr_xa_t *mxa) int rc; if (nds->m_op != NDR_M_OP_MARSHALL) - return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_MODE_MISMATCH)); + return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH); ptype = hdr->ptype; if (ptype == NDR_PTYPE_REQUEST && |
