summaryrefslogtreecommitdiff
path: root/usr/src/lib/smbsrv/libmlrpc
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/smbsrv/libmlrpc')
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h13
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c86
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 &&