--- old/usr/src/Makefile.master	Sun Mar 18 01:12:57 2018
+++ new/usr/src/Makefile.master	Sun Mar 18 01:12:57 2018
@@ -169,6 +169,7 @@
 FLEX=		/usr/bin/flex
 YACC=		/usr/ccs/bin/yacc
 CPP=		/usr/lib/cpp
+ANSI_CPP=	$(GCC_ROOT)/bin/cpp
 JAVAC=		$(JAVA_ROOT)/bin/javac
 JAVAH=		$(JAVA_ROOT)/bin/javah
 JAVADOC=	$(JAVA_ROOT)/bin/javadoc
--- old/usr/src/lib/Makefile	Sun Mar 18 01:12:57 2018
+++ new/usr/src/lib/Makefile	Sun Mar 18 01:12:57 2018
@@ -163,6 +163,7 @@
 	libmapid	\
 	libmapmalloc	\
 	libmd5		\
+	libmlrpc	\
 	libmtmalloc	\
 	libmvec		\
 	libndmp		\
@@ -421,6 +422,7 @@
 	libmail		\
 	libmapid	\
 	libmd		\
+	libmlrpc	\
 	libmtmalloc	\
 	libndmp		\
 	libnsctl	\
@@ -625,6 +627,7 @@
 libkvm:		../cmd/sgs/libelf
 libldap5:	libsasl
 libmapid:	libresolv2 libscf
+libmlrpc:	libsmbfs libuuid
 libndmp:	libscf
 libnisdb:	libldap5
 libnwam:	libscf libbsm libdladm libipadm
@@ -694,7 +697,7 @@
 scsi:		libfru libumem libdevid libdevinfo
 smbsrv:		libxnet libpthread librt libshare libidmap pkcs11 libsqlite \
 		libcryptoutil libreparse libcmdutils libresolv2 libsmbfs \
-		libuuid libfakekernel libads libgss libldap5 krb5
+		libuuid libfakekernel libads libgss libldap5 krb5 libmlrpc
 storage:	libdevice libdevinfo libdevid
 sun_fc:		libdevinfo libsysevent
 sun_sas:	libdevinfo libsysevent libkstat libdevid
--- old/usr/src/lib/libmlrpc/Makefile	Sun Mar 18 01:12:57 2018
+++ new/usr/src/lib/libmlrpc/Makefile	Sun Mar 18 01:12:57 2018
@@ -22,9 +22,44 @@
 # Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
+# Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
 #
 
-HDRS=	libmlrpc.h
+include $(SRC)/lib/Makefile.lib
 
-include ../Makefile.smbsrv
+HDRS=		libmlrpc.h ndr.h ndrtypes.ndl rpcpdu.ndl
+HDRDIR=		common
+
+ROOTHDRDIR=	$(ROOT)/usr/include/libmlrpc
+ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%)
+
+# ISA targets
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all :=		TARGET = all
+install :=	TARGET = install
+clean :=	TARGET = clean
+clobber :=	TARGET = clobber
+lint :=		TARGET = lint
+
+.KEEP_STATE:
+
+all install clean clobber lint: $(SUBDIRS)
+
+install_h: $(ROOTHDRDIR) $(ROOTHDRS)
+
+check: $(CHECKHDRS)
+
+$(ROOTHDRDIR)/%: %
+	$(INS.file)
+
+$(ROOTHDRDIR):
+	$(INS.dir)
+
+$(SUBDIRS): FRC
+	@cd $@; pwd; VERSION='$(VERSION)' $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/lib/Makefile.targ
--- old/usr/src/lib/libmlrpc/Makefile.com	Sun Mar 18 01:12:57 2018
+++ new/usr/src/lib/libmlrpc/Makefile.com	Sun Mar 18 01:12:57 2018
@@ -18,15 +18,19 @@
 #
 # CDDL HEADER END
 #
+
 #
 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
+# Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+#
 
 LIBRARY =	libmlrpc.a
-VERS =		.1
+VERS =		.2
 
 OBJS_COMMON = 			\
+	mlrpc_clh.o		\
 	ndr_client.o		\
 	ndr_heap.o		\
 	ndr_marshal.o		\
@@ -33,24 +37,39 @@
 	ndr_ops.o		\
 	ndr_process.o		\
 	ndr_server.o		\
-	ndr_svc.o
+	ndr_svc.o		\
+	ndr_wchar.o
 
 NDLLIST = rpcpdu
 
-OBJECTS=	$(OBJS_COMMON) $(OBJS_SHARED) $(NDLLIST:%=%_ndr.o)
+OBJECTS=	$(OBJS_COMMON) $(NDLLIST:%=%_ndr.o)
+CLEANFILES += $(NDLLIST:%=%_ndr.c)
 
-include ../../../Makefile.lib
 include ../../Makefile.lib
 
-INCS += -I$(SRC)/common/smbsrv
+LIBS=		$(DYNLIB) $(LINTLIB)
 
-LDLIBS +=	$(MACH_LDLIBS)
-LDLIBS +=	-lsmb -luuid -lc
+LDLIBS +=	-lsmbfs -luuid -lc
 
+SRCDIR=		../common
+SRCS=   $(OBJS_COMMON:%.o=$(SRCDIR)/%.c)
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
+
+NDLDIR =	$(SRCDIR)
+
+CFLAGS +=	$(CCVERBOSE)
+INCS = -I. -I$(SRCDIR)
 CPPFLAGS += $(INCS) -D_REENTRANT
 
-SRCS=   $(OBJS_COMMON:%.o=$(SRCDIR)/%.c)		\
-	$(OBJS_SHARED:%.o=$(SRC)/common/smbsrv/%.c)
+all:	$(LIBS)
 
+lint:	lintcheck
+
 include ../../Makefile.targ
-include ../../../Makefile.targ
+
+objs/%_ndr.o pics/%_ndr.o : %_ndr.c
+
+%_ndr.c : $(NDLDIR)/%.ndl
+	$(NDRGEN) -Y $(ANSI_CPP) $(CPPFLAGS) $<
+
+.KEEP_STATE:
--- old/usr/src/lib/libmlrpc/amd64/Makefile	Sun Mar 18 01:12:57 2018
+++ new/usr/src/lib/libmlrpc/amd64/Makefile	Sun Mar 18 01:12:57 2018
@@ -22,14 +22,10 @@
 # Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
 
 MACH_LDLIBS +=	-L$(ROOT)/usr/lib/smbsrv/$(MACH64)
 
 include ../Makefile.com
-include ../../../Makefile.lib.64
+include ../../Makefile.lib.64
 
-DYNFLAGS +=	-R/usr/lib/smbsrv/$(MACH64)
-
 install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
--- old/usr/src/lib/libmlrpc/common/libmlrpc.h	Sun Mar 18 01:12:57 2018
+++ new/usr/src/lib/libmlrpc/common/libmlrpc.h	Sun Mar 18 01:12:58 2018
@@ -28,11 +28,10 @@
 
 #include <sys/types.h>
 #include <sys/uio.h>
-#include <smbsrv/wintypes.h>
-#include <smbsrv/ndr.h>
-#include <smbsrv/smb_sid.h>
-#include <smbsrv/smb_xdr.h>
 
+#include <smb/wintypes.h>
+#include <libmlrpc/ndr.h>
+
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -249,7 +248,7 @@
 typedef struct ndr_pipe {
 	void 			*np_listener;
 	const char		*np_endpoint;
-	smb_netuserinfo_t	*np_user;
+	struct smb_netuserinfo	*np_user;
 	int			(*np_send)(struct ndr_pipe *, void *, size_t);
 	int			(*np_recv)(struct ndr_pipe *, void *, size_t);
 	int			np_fid;
@@ -402,12 +401,12 @@
 
 ndr_heap_t *ndr_heap_create(void);
 void ndr_heap_destroy(ndr_heap_t *);
+void *ndr_heap_dupmem(ndr_heap_t *, const void *, size_t);
 void *ndr_heap_malloc(ndr_heap_t *, unsigned);
 void *ndr_heap_strdup(ndr_heap_t *, const char *);
 int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *);
 void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *);
 void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *);
-smb_sid_t *ndr_heap_siddup(ndr_heap_t *, smb_sid_t *);
 int ndr_heap_used(ndr_heap_t *);
 int ndr_heap_avail(ndr_heap_t *);
 
@@ -416,7 +415,7 @@
 #define	NDR_NEWN(XA, T, N)	ndr_heap_malloc((XA)->heap, sizeof (T)*(N))
 #define	NDR_STRDUP(XA, S)	ndr_heap_strdup((XA)->heap, (S))
 #define	NDR_MSTRING(XA, S, OUT)	ndr_heap_mstring((XA)->heap, (S), (OUT))
-#define	NDR_SIDDUP(XA, S)	ndr_heap_siddup((XA)->heap, (S))
+#define	NDR_SIDDUP(XA, S)	ndr_heap_dupmem((XA)->heap, (S), smb_sid_len(S))
 
 typedef struct ndr_xa {
 	unsigned short		ptype;		/* high bits special */
@@ -488,7 +487,7 @@
 void nds_show_state(ndr_stream_t *);
 
 /* ndr_client.c */
-int ndr_clnt_bind(ndr_client_t *, const char *, ndr_binding_t **);
+int ndr_clnt_bind(ndr_client_t *, ndr_service_t *, ndr_binding_t **);
 int ndr_clnt_call(ndr_binding_t *, int, void *);
 void ndr_clnt_free_heap(ndr_client_t *);
 
@@ -514,10 +513,6 @@
 
 int ndr_generic_call_stub(ndr_xa_t *);
 
-boolean_t ndr_is_admin(ndr_xa_t *);
-boolean_t ndr_is_poweruser(ndr_xa_t *);
-int32_t ndr_native_os(ndr_xa_t *);
-
 /* ndr_svc.c */
 ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int);
 ndr_service_t *ndr_svc_lookup_name(const char *);
@@ -538,6 +533,38 @@
 
 ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *);
 
+/*
+ * An ndr_client_t is created while binding a client connection to hold
+ * the context for calls made using that connection.
+ *
+ * Handles are RPC call specific and we use an inheritance mechanism to
+ * ensure that each handle has a pointer to the client_t.  When the top
+ * level (bind) handle is released, we close the connection.
+ *
+ * There are some places in libmlsvc where the code assumes that the
+ * handle member is first in this struct.  careful
+ */
+typedef struct mlrpc_handle {
+	ndr_hdid_t	handle;		/* keep first */
+	ndr_client_t	*clnt;
+} mlrpc_handle_t;
+
+int mlrpc_clh_create(mlrpc_handle_t *, void *);
+uint32_t mlrpc_clh_bind(mlrpc_handle_t *, ndr_service_t *);
+void mlrpc_clh_unbind(mlrpc_handle_t *);
+void *mlrpc_clh_free(mlrpc_handle_t *);
+
+int ndr_rpc_call(mlrpc_handle_t *, int, void *);
+int ndr_rpc_get_ssnkey(mlrpc_handle_t *, unsigned char *, size_t);
+void *ndr_rpc_malloc(mlrpc_handle_t *, size_t);
+ndr_heap_t *ndr_rpc_get_heap(mlrpc_handle_t *);
+void ndr_rpc_release(mlrpc_handle_t *);
+void ndr_rpc_set_nonull(mlrpc_handle_t *);
+
+boolean_t ndr_is_null_handle(mlrpc_handle_t *);
+boolean_t ndr_is_bind_handle(mlrpc_handle_t *);
+void ndr_inherit_handle(mlrpc_handle_t *, mlrpc_handle_t *);
+
 #ifdef	__cplusplus
 }
 #endif
--- old/usr/src/lib/libmlrpc/common/llib-lmlrpc	Sun Mar 18 01:12:58 2018
+++ new/usr/src/lib/libmlrpc/common/llib-lmlrpc	Sun Mar 18 01:12:58 2018
@@ -21,11 +21,11 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*LINTLIBRARY*/
 /*PROTOLIB1*/
 
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
--- old/usr/src/lib/libmlrpc/common/mapfile-vers	Sun Mar 18 01:12:58 2018
+++ new/usr/src/lib/libmlrpc/common/mapfile-vers	Sun Mar 18 01:12:58 2018
@@ -42,47 +42,74 @@
 
 SYMBOL_VERSION SUNWprivate {
     global:
-        ndr_buf_decode;
-        ndr_buf_fini;
-        ndr_buf_init;
-        ndr_clnt_bind;
-        ndr_clnt_call;
-        ndr_clnt_free_heap;
+	mlrpc_clh_bind;
+	mlrpc_clh_create;
+	mlrpc_clh_free;
+	mlrpc_clh_unbind;
+
+	# Allow debug/test programs to provide these.
+	ndo_printf		{ FLAGS = NODIRECT };
+	ndo_trace		{ FLAGS = NODIRECT };
+
+	ndr_buf_decode;
+	ndr_buf_fini;
+	ndr_buf_init;
+	ndr_clnt_bind;
+	ndr_clnt_call;
+	ndr_clnt_free_heap;
 	ndr_generic_call_stub;
-        ndr_heap_avail;
-        ndr_heap_create;
-        ndr_heap_destroy;
-        ndr_heap_malloc;
-        ndr_heap_mkvcb;
-        ndr_heap_mkvcs;
+	ndr_heap_avail;
+	ndr_heap_create;
+	ndr_heap_destroy;
+	ndr_heap_dupmem;
+	ndr_heap_malloc;
+	ndr_heap_mkvcb;
+	ndr_heap_mkvcs;
 	ndr_heap_mstring;
-	ndr_heap_siddup;
-        ndr_heap_strdup;
-        ndr_heap_used;
+	ndr_heap_strdup;
+	ndr_heap_used;
 	ndr_hdalloc;
+	ndr_hdclose;
 	ndr_hdfree;
 	ndr_hdlookup;
-        ndr_inner;
-	ndr_is_admin;
-	ndr_is_poweruser;
+	ndr_inherit_handle;
+	ndr_inner;
+	ndr_is_bind_handle;
+	ndr_is_null_handle;
 	ndr_mbstowcs;
-	ndr_mbtowc;
-	ndr_native_os;
-        ndr_params;
+	ndr_params;
 	ndr_pipe_worker;
-        ndr_svc_binding_pool_init;
+	ndr_rpc_call;
+	ndr_rpc_get_heap;
+	ndr_rpc_get_ssnkey;
+	ndr_rpc_malloc;
+	ndr_rpc_release;
+	ndr_rpc_set_nonull;
+	ndr_svc_binding_pool_init;
 	ndr_svc_lookup_name;
-        ndr_svc_register;
-        ndr_topmost;
+	ndr_svc_register;
+	ndr_topmost;
 	ndr_uuid_parse;
 	ndr_uuid_unparse;
-        nds_destruct;
-        nds_initialize;
-        ndt__char;
-        ndt_s_wchar;
-        ndt__uchar;
-        ndt__ulong;
-        ndt__ushort;
+
+	nds_destruct;
+	nds_initialize;
+
+	ndt__char;
+	ndt_s_char;
+	ndt__uchar;
+	ndt_s_uchar;
+	ndt__wchar;
+	ndt_s_wchar;
+	ndt__short;
+	ndt_s_short;
+	ndt__ushort;
+	ndt_s_ushort;
+	ndt__long;
+	ndt_s_long;
+	ndt__ulong;
+	ndt_s_ulong;
+
     local:
 	*;
 };
--- /dev/null	Sun Mar 18 01:12:58 2018
+++ new/usr/src/lib/libmlrpc/common/mlrpc_clh.c	Sun Mar 18 01:12:58 2018
@@ -0,0 +1,578 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
+
+/*
+ * ML-RPC Client handle interface and support functions.
+ */
+
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/poll.h>
+
+#include <errno.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include <netsmb/smbfs_api.h>
+#include <smb/ntstatus.h>
+#include <libmlrpc.h>
+
+#include <assert.h>
+
+static int ndr_xa_init(ndr_client_t *, ndr_xa_t *);
+static int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *);
+static int ndr_xa_read(ndr_client_t *, ndr_xa_t *);
+static void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *);
+static void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *);
+static void ndr_xa_release(ndr_client_t *);
+
+/* See notes in mlrpc_clh_bind */
+int rpc_pipe_open_retries = 10;
+
+/*
+ * Create an RPC client binding handle using the given smb_ctx.
+ * That context must already have a session and tree connected.
+ *
+ * Returns zero or an errno value.
+ */
+int
+mlrpc_clh_create(mlrpc_handle_t *handle, void *ctx)
+{
+	ndr_client_t	*clnt = NULL;
+
+	if (ctx == NULL)
+		return (EINVAL);
+
+	/*
+	 * Allocate...
+	 */
+	if ((clnt = malloc(sizeof (*clnt))) == NULL)
+		return (ENOMEM);
+	bzero(clnt, sizeof (*clnt));
+
+	clnt->xa_fd = -1;
+
+	/*
+	 * Setup the transport functions.
+	 * Always a named pipe (for now).
+	 */
+	clnt->xa_private = ctx;
+	clnt->xa_init = ndr_xa_init;
+	clnt->xa_exchange = ndr_xa_exchange;
+	clnt->xa_read = ndr_xa_read;
+	clnt->xa_preserve = ndr_xa_preserve;
+	clnt->xa_destruct = ndr_xa_destruct;
+	clnt->xa_release = ndr_xa_release;
+
+	/* See _is_bind_handle */
+	clnt->handle = &handle->handle;
+
+	ndr_svc_binding_pool_init(&clnt->binding_list,
+	    clnt->binding_pool, NDR_N_BINDING_POOL);
+
+	if ((clnt->heap = ndr_heap_create()) == NULL)
+		goto nomem;
+
+	/* success! */
+	bzero(handle, sizeof (*handle));
+	handle->clnt = clnt;
+	return (0);
+
+nomem:
+	free(clnt);
+	return (ENOMEM);
+}
+
+
+/*
+ * This call must be made to initialize an RPC client structure and bind
+ * to the remote service before any RPCs can be exchanged with that service.
+ *
+ * The mlrpc_handle_t is a wrapper that is used to associate an RPC handle
+ * with the client context for an instance of the interface.  The handle
+ * is zeroed to ensure that it doesn't look like a valid handle -
+ * handle content is provided by the remove service.
+ *
+ * The client points to this top-level handle so that we know when to
+ * unbind and teardown the connection.  As each handle is initialized it
+ * will inherit a reference to the client context.
+ *
+ *
+ * Similar to MSRPC RpcBindingBind()
+ *
+ * Returns 0 or an NT_STATUS:		(failed in...)
+ *
+ *	RPC_NT_SERVER_TOO_BUSY		(open pipe)
+ *	RPC_NT_SERVER_UNAVAILABLE	(open pipe)
+ *	NT_STATUS_ACCESS_DENIED		(open pipe)
+ *	NT_STATUS_INVALID_PARAMETER	(rpc bind)
+ *	NT_STATUS_INTERNAL_ERROR	(bad args etc)
+ *	NT_STATUS_NO_MEMORY
+ */
+uint32_t
+mlrpc_clh_bind(mlrpc_handle_t *handle, ndr_service_t *svc)
+{
+	ndr_client_t		*clnt = NULL;
+	struct smb_ctx		*ctx = NULL;
+	uint32_t		status = 0;
+	int			fd = -1;
+	int			rc, retries;
+
+	if ((clnt = handle->clnt) == NULL)
+		return (NT_STATUS_INTERNAL_ERROR);
+	if ((ctx = clnt->xa_private) == NULL)
+		return (NT_STATUS_INTERNAL_ERROR);
+	if (clnt->xa_fd != -1)
+		return (NT_STATUS_INTERNAL_ERROR);
+
+	/*
+	 * Open the named pipe.
+	 *
+	 * Sometimes a DC may return NT_STATUS_PIPE_NOT_AVAILABLE for
+	 * the first few seconds during service auto-start.  The client
+	 * translates that to EBUSY, so when we see that, wait a bit
+	 * and retry the open for up to rpc_pipe_open_retries.  If we
+	 * fail even after retries, return RPC_NT_SERVER_TOO_BUSY,
+	 * which is how callers of this layer expect that reported.
+	 * We try up to 10 times, with a 0.5 sec. wait after each
+	 * BUSY failure, giving a total wait here of 5 sec.
+	 */
+	retries = rpc_pipe_open_retries;
+retry_open:
+	fd = smb_fh_open(ctx, svc->endpoint, O_RDWR);
+	if (fd < 0) {
+		rc = errno;
+		switch (rc) {
+		case EBUSY:
+			if (--retries > 0) {
+				(void) poll(NULL, 0, 500);
+				goto retry_open;
+			}
+			status = RPC_NT_SERVER_TOO_BUSY;
+			break;
+		case EACCES:
+			status = NT_STATUS_ACCESS_DENIED;
+			break;
+		default:
+			status = RPC_NT_SERVER_UNAVAILABLE;
+			break;
+		}
+		return (status);
+	}
+
+	clnt->xa_fd = fd;
+
+	/* Paranoia, in case of re-bind. */
+	bzero(&handle->handle, sizeof (ndr_hdid_t));
+
+	/*
+	 * Do the OtW RPC bind.
+	 */
+	rc = ndr_clnt_bind(clnt, svc, &clnt->binding);
+	switch (rc) {
+	case NDR_DRC_FAULT_OUT_OF_MEMORY:
+		status = NT_STATUS_NO_MEMORY;
+		break;
+	case NDR_DRC_FAULT_API_SERVICE_INVALID:
+		/* svc->..._uuid parse errors */
+		status = NT_STATUS_INTERNAL_ERROR;
+		break;
+	default:
+		if (NDR_DRC_IS_FAULT(rc)) {
+			status = RPC_NT_PROTOCOL_ERROR;
+			break;
+		}
+		/* FALLTHROUGH */
+	case NDR_DRC_OK:
+		status = NT_STATUS_SUCCESS;
+	}
+
+	if (status != 0) {
+		if (fd != -1)
+			(void) smb_fh_close(fd);
+		clnt->xa_fd = -1;
+	}
+
+	return (status);
+}
+
+/*
+ * Unbind and close the pipe to an RPC service.
+ *
+ * Similar to MSRPC RpcBindingUnbind()
+ * This should be called after a dropped connection.
+ */
+void
+mlrpc_clh_unbind(mlrpc_handle_t *handle)
+{
+	ndr_client_t *clnt = handle->clnt;
+
+	if (clnt->xa_fd != -1) {
+		(void) smb_fh_close(clnt->xa_fd);
+		clnt->xa_fd = -1;
+	}
+}
+
+/*
+ * If the heap has been preserved we need to go through an xa release.
+ * The heap is preserved during an RPC call because that's where data
+ * returned from the server is stored.
+ *
+ * Otherwise we destroy the heap directly.
+ *
+ * Returns the xa_private pointer (if non-NULL) to inform the caller
+ * that it can now be destroyed.
+ */
+void *
+mlrpc_clh_free(mlrpc_handle_t *handle)
+{
+	ndr_client_t *clnt = handle->clnt;
+	void *private;
+
+	if (clnt == NULL)
+		return (NULL);
+
+	/*
+	 * Should never get an unbind on inherited handles.
+	 * Callers of ndr_inherit_handle() check handles
+	 * with ndr_is_bind_handle() before calling this.
+	 *
+	 * Maybe make this function more tolerant?
+	 */
+	assert(handle->clnt->handle == &handle->handle);
+
+	mlrpc_clh_unbind(handle);
+
+	if (clnt->heap_preserved)
+		ndr_clnt_free_heap(clnt); /* xa_release */
+	else
+		ndr_heap_destroy(clnt->heap);
+
+	/*
+	 * Note: Caller will free the smb_ctx stored in
+	 * clnt->xa_private (or possibly reuse it).
+	 */
+	private = clnt->xa_private;
+	free(clnt);
+	bzero(handle, sizeof (*handle));
+	return (private);
+}
+
+/*
+ * Call the RPC function identified by opnum.  The remote service is
+ * identified by the handle, which should have been initialized by
+ * ndr_rpc_bind.
+ *
+ * If the RPC call is successful (returns 0), the caller must call
+ * ndr_rpc_release to release the heap.  Otherwise, we release the
+ * heap here.
+ */
+int
+ndr_rpc_call(mlrpc_handle_t *handle, int opnum, void *params)
+{
+	ndr_client_t *clnt = handle->clnt;
+	int rc;
+
+	if (ndr_rpc_get_heap(handle) == NULL)
+		return (-1);
+
+	rc = ndr_clnt_call(clnt->binding, opnum, params);
+
+	/*
+	 * Always clear the nonull flag to ensure
+	 * it is not applied to subsequent calls.
+	 */
+	clnt->nonull = B_FALSE;
+
+	if (NDR_DRC_IS_FAULT(rc)) {
+		ndr_rpc_release(handle);
+		return (-1);
+	}
+
+	return (0);
+}
+
+/*
+ * Outgoing strings should not be null terminated.
+ */
+void
+ndr_rpc_set_nonull(mlrpc_handle_t *handle)
+{
+	handle->clnt->nonull = B_TRUE;
+}
+
+/*
+ * Get the session key from a bound RPC client handle.
+ *
+ * The key returned is the 16-byte "user session key"
+ * established by the underlying authentication protocol
+ * (either Kerberos or NTLM).  This key is needed for
+ * SAM RPC calls such as SamrSetInformationUser, etc.
+ * See [MS-SAMR] sections: 2.2.3.3, 2.2.7.21, 2.2.7.25.
+ *
+ * Returns zero (success) or an errno.
+ */
+int
+ndr_rpc_get_ssnkey(mlrpc_handle_t *handle, uchar_t *key, size_t len)
+{
+	ndr_client_t *clnt = handle->clnt;
+
+	if (clnt == NULL || clnt->xa_fd == -1)
+		return (EINVAL);
+
+	return (smb_fh_getssnkey(clnt->xa_fd, key, len));
+}
+
+void *
+ndr_rpc_malloc(mlrpc_handle_t *handle, size_t size)
+{
+	ndr_heap_t *heap;
+
+	if ((heap = ndr_rpc_get_heap(handle)) == NULL)
+		return (NULL);
+
+	return (ndr_heap_malloc(heap, size));
+}
+
+ndr_heap_t *
+ndr_rpc_get_heap(mlrpc_handle_t *handle)
+{
+	ndr_client_t *clnt = handle->clnt;
+
+	if (clnt->heap == NULL)
+		clnt->heap = ndr_heap_create();
+
+	return (clnt->heap);
+}
+
+/*
+ * Must be called by RPC clients to free the heap after a successful RPC
+ * call, i.e. ndr_rpc_call returned 0.  The caller should take a copy
+ * of any data returned by the RPC prior to calling this function because
+ * returned data is in the heap.
+ */
+void
+ndr_rpc_release(mlrpc_handle_t *handle)
+{
+	ndr_client_t *clnt = handle->clnt;
+
+	if (clnt->heap_preserved)
+		ndr_clnt_free_heap(clnt);
+	else
+		ndr_heap_destroy(clnt->heap);
+
+	clnt->heap = NULL;
+}
+
+/*
+ * Returns true if the handle is null.
+ * Otherwise returns false.
+ */
+boolean_t
+ndr_is_null_handle(mlrpc_handle_t *handle)
+{
+	static const ndr_hdid_t hdid0 = {0};
+
+	if (handle == NULL || handle->clnt == NULL)
+		return (B_TRUE);
+
+	if (!memcmp(&handle->handle, &hdid0, sizeof (hdid0)))
+		return (B_TRUE);
+
+	return (B_FALSE);
+}
+
+/*
+ * Returns true if the handle is the top level bind handle.
+ * Otherwise returns false.
+ */
+boolean_t
+ndr_is_bind_handle(mlrpc_handle_t *handle)
+{
+	return (handle->clnt->handle == &handle->handle);
+}
+
+/*
+ * Pass the client reference from parent to child.
+ */
+void
+ndr_inherit_handle(mlrpc_handle_t *child, mlrpc_handle_t *parent)
+{
+	child->clnt = parent->clnt;
+}
+
+/*
+ * ndr_rpc_status remains in libmlsvc mlsvc_client.c
+ */
+
+/*
+ * The following functions provide the client callback interface.
+ * If the caller hasn't provided a heap, create one here.
+ */
+static int
+ndr_xa_init(ndr_client_t *clnt, ndr_xa_t *mxa)
+{
+	ndr_stream_t *recv_nds = &mxa->recv_nds;
+	ndr_stream_t *send_nds = &mxa->send_nds;
+	ndr_heap_t *heap = clnt->heap;
+	int		rc;
+
+	if (heap == NULL) {
+		if ((heap = ndr_heap_create()) == NULL)
+			return (-1);
+
+		clnt->heap = heap;
+	}
+
+	mxa->heap = heap;
+
+	rc = nds_initialize(send_nds, 0, NDR_MODE_CALL_SEND, heap);
+	if (rc == 0)
+		rc = nds_initialize(recv_nds, NDR_PDU_SIZE_HINT_DEFAULT,
+		    NDR_MODE_RETURN_RECV, heap);
+
+	if (rc != 0) {
+		nds_destruct(&mxa->recv_nds);
+		nds_destruct(&mxa->send_nds);
+		ndr_heap_destroy(mxa->heap);
+		mxa->heap = NULL;
+		clnt->heap = NULL;
+		return (-1);
+	}
+
+	if (clnt->nonull)
+		NDS_SETF(send_nds, NDS_F_NONULL);
+
+	return (0);
+}
+
+/*
+ * This is the entry pointy for an RPC client call exchange with
+ * a server, which will result in an smbrdr SmbTransact request.
+ *
+ * SmbTransact should return the number of bytes received, which
+ * we record as the PDU size, or a negative error code.
+ */
+static int
+ndr_xa_exchange(ndr_client_t *clnt, ndr_xa_t *mxa)
+{
+	ndr_stream_t *recv_nds = &mxa->recv_nds;
+	ndr_stream_t *send_nds = &mxa->send_nds;
+	int err, more, nbytes;
+
+	nbytes = recv_nds->pdu_max_size;
+	err = smb_fh_xactnp(clnt->xa_fd,
+	    send_nds->pdu_size, (char *)send_nds->pdu_base_offset,
+	    &nbytes, (char *)recv_nds->pdu_base_offset, &more);
+	if (err) {
+		recv_nds->pdu_size = 0;
+		return (-1);
+	}
+
+	recv_nds->pdu_size = nbytes;
+	return (0);
+}
+
+/*
+ * This entry point will be invoked if the xa-exchange response contained
+ * only the first fragment of a multi-fragment response.  The RPC client
+ * code will then make repeated xa-read requests to obtain the remaining
+ * fragments, which will result in smbrdr SmbReadX requests.
+ *
+ * SmbReadX should return the number of bytes received, in which case we
+ * expand the PDU size to include the received data, or a negative error
+ * code.
+ */
+static int
+ndr_xa_read(ndr_client_t *clnt, ndr_xa_t *mxa)
+{
+	ndr_stream_t *nds = &mxa->recv_nds;
+	int len;
+	int nbytes;
+
+	if ((len = (nds->pdu_max_size - nds->pdu_size)) < 0)
+		return (-1);
+
+	nbytes = smb_fh_read(clnt->xa_fd, 0, len,
+	    (char *)nds->pdu_base_offset + nds->pdu_size);
+
+	if (nbytes < 0)
+		return (-1);
+
+	nds->pdu_size += nbytes;
+
+	if (nds->pdu_size > nds->pdu_max_size) {
+		nds->pdu_size = nds->pdu_max_size;
+		return (-1);
+	}
+
+	return (nbytes);
+}
+
+/*
+ * Preserve the heap so that the client application has access to data
+ * returned from the server after an RPC call.
+ */
+static void
+ndr_xa_preserve(ndr_client_t *clnt, ndr_xa_t *mxa)
+{
+	assert(clnt->heap == mxa->heap);
+
+	clnt->heap_preserved = B_TRUE;
+	mxa->heap = NULL;
+}
+
+/*
+ * Dispose of the transaction streams.  If the heap has not been
+ * preserved, we can destroy it here.
+ */
+static void
+ndr_xa_destruct(ndr_client_t *clnt, ndr_xa_t *mxa)
+{
+	nds_destruct(&mxa->recv_nds);
+	nds_destruct(&mxa->send_nds);
+
+	if (!clnt->heap_preserved) {
+		ndr_heap_destroy(mxa->heap);
+		mxa->heap = NULL;
+		clnt->heap = NULL;
+	}
+}
+
+/*
+ * Dispose of a preserved heap.
+ */
+static void
+ndr_xa_release(ndr_client_t *clnt)
+{
+	if (clnt->heap_preserved) {
+		ndr_heap_destroy(clnt->heap);
+		clnt->heap = NULL;
+		clnt->heap_preserved = B_FALSE;
+	}
+}
--- old/usr/src/lib/libmlrpc/common/ndr.h	Sun Mar 18 01:12:58 2018
+++ new/usr/src/lib/libmlrpc/common/ndr.h	Sun Mar 18 01:12:58 2018
@@ -40,19 +40,15 @@
  * ogspecs@opengroup.org
  */
 
-#if defined(_KERNEL) || defined(_FAKE_KERNEL)
-#error "not used in kernel code"
-#else /* _KERNEL */
 #include <sys/types.h>
 #include <sys/uio.h>
-#include <syslog.h>
 #include <stdlib.h>
 #include <string.h>
-#include <smbsrv/wintypes.h>
-#include <smbsrv/ndl/rpcpdu.ndl>
-#include <smbsrv/string.h>
-#endif	/* _KERNEL */
 
+#include <smb/wintypes.h>
+#include <libmlrpc/ndrtypes.ndl>
+#include <libmlrpc/rpcpdu.ndl>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -455,8 +451,7 @@
 int ndr_inner_reference(ndr_ref_t *);
 int ndr_inner_array(ndr_ref_t *);
 
-size_t ndr_mbstowcs(struct ndr_stream *, smb_wchar_t *, const char *, size_t);
-int ndr_mbtowc(struct ndr_stream *, smb_wchar_t *, const char *, size_t);
+size_t ndr_mbstowcs(struct ndr_stream *, ndr_wchar_t *, const char *, size_t);
 
 void nds_bswap(void *src, void *dst, size_t len);
 
--- old/usr/src/lib/libmlrpc/common/ndr_client.c	Sun Mar 18 01:12:58 2018
+++ new/usr/src/lib/libmlrpc/common/ndr_client.c	Sun Mar 18 01:12:58 2018
@@ -21,6 +21,8 @@
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <sys/errno.h>
@@ -27,8 +29,7 @@
 #include <string.h>
 #include <strings.h>
 
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
 
 #define	NDR_DEFAULT_FRAGSZ	8192
 #define	NDR_MULTI_FRAGSZ	(60 * 1024)
@@ -38,10 +39,9 @@
 static int ndr_clnt_get_frag(ndr_client_t *, ndr_xa_t *, ndr_common_header_t *);
 
 int
-ndr_clnt_bind(ndr_client_t *clnt, const char *service_name,
+ndr_clnt_bind(ndr_client_t *clnt, ndr_service_t *msvc,
     ndr_binding_t **ret_binding_p)
 {
-	ndr_service_t		*msvc;
 	ndr_binding_t		*mbind;
 	ndr_xa_t		mxa;
 	ndr_bind_hdr_t		*bhdr;
@@ -52,10 +52,6 @@
 
 	bzero(&mxa, sizeof (mxa));
 
-	msvc = ndr_svc_lookup_name(service_name);
-	if (msvc == NULL)
-		return (NDR_DRC_FAULT_API_SERVICE_INVALID);
-
 	mxa.binding_list = clnt->binding_list;
 	if ((mbind = ndr_svc_new_binding(&mxa)) == NULL)
 		return (NDR_DRC_FAULT_API_BIND_NO_SLOTS);
@@ -140,7 +136,6 @@
 ndr_clnt_call(ndr_binding_t *mbind, int opnum, void *params)
 {
 	ndr_client_t		*clnt = mbind->clnt;
-	ndr_service_t		*msvc = mbind->service;
 	ndr_xa_t		mxa;
 	ndr_request_hdr_t	*reqhdr;
 	ndr_common_header_t	*rsphdr;
@@ -147,9 +142,6 @@
 	unsigned long		recv_pdu_scan_offset;
 	int			rc;
 
-	if (ndr_svc_lookup_name(msvc->name) == NULL)
-		return (NDR_DRC_FAULT_API_SERVICE_INVALID);
-
 	bzero(&mxa, sizeof (mxa));
 	mxa.ptype = NDR_PTYPE_REQUEST;
 	mxa.opnum = opnum;
--- old/usr/src/lib/libmlrpc/common/ndr_heap.c	Sun Mar 18 01:12:58 2018
+++ new/usr/src/lib/libmlrpc/common/ndr_heap.c	Sun Mar 18 01:12:58 2018
@@ -21,6 +21,8 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -46,9 +48,8 @@
 #include <strings.h>
 #include <sys/uio.h>
 
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
-#include <smbsrv/smb_sid.h>
+#include <libmlrpc.h>
+#include <ndr_wchar.h>
 
 /*
  * Allocate a heap structure and the first heap block.  For many RPC
@@ -154,6 +155,23 @@
 }
 
 /*
+ * Convenience function to copy some memory into the heap.
+ */
+void *
+ndr_heap_dupmem(ndr_heap_t *heap, const void *mem, size_t len)
+{
+	void *p;
+
+	if (mem == NULL)
+		return (NULL);
+
+	if ((p = ndr_heap_malloc(heap, len)) != NULL)
+		(void) memcpy(p, mem, len);
+
+	return (p);
+}
+
+/*
  * Convenience function to do heap strdup.
  */
 void *
@@ -171,8 +189,7 @@
 	if ((len = strlen(s)) == 0)
 		return ("");
 
-	if ((p = ndr_heap_malloc(heap, len+1)) != NULL)
-		(void) strcpy((char *)p, s);
+	p = ndr_heap_dupmem(heap, s, len+1);
 
 	return (p);
 }
@@ -183,12 +200,22 @@
 int
 ndr_heap_mstring(ndr_heap_t *heap, const char *s, ndr_mstring_t *out)
 {
+	size_t slen;
+
 	if (s == NULL || out == NULL)
 		return (-1);
 
-	out->length = smb_wcequiv_strlen(s);
-	out->allosize = out->length + sizeof (smb_wchar_t);
+	/*
+	 * Determine the WC strlen of s
+	 * Was ndr__wcequiv_strlen(s)
+	 */
+	slen = ndr__mbstowcs(NULL, s, NDR_STRING_MAX);
+	if (slen == (size_t)-1)
+		return (-1);
 
+	out->length = slen * sizeof (ndr_wchar_t);
+	out->allosize = out->length + sizeof (ndr_wchar_t);
+
 	if ((out->str = ndr_heap_strdup(heap, s)) == NULL)
 		return (-1);
 
@@ -207,20 +234,31 @@
 void
 ndr_heap_mkvcs(ndr_heap_t *heap, char *s, ndr_vcstr_t *vc)
 {
+	size_t slen;
 	int mlen;
 
-	vc->wclen = smb_wcequiv_strlen(s);
+	/*
+	 * Determine the WC strlen of s
+	 * Was ndr__wcequiv_strlen(s)
+	 */
+	slen = ndr__mbstowcs(NULL, s, NDR_STRING_MAX);
+	if (slen == (size_t)-1)
+		slen = 0;
+
+	vc->wclen = slen * sizeof (ndr_wchar_t);
 	vc->wcsize = vc->wclen;
 
-	mlen = sizeof (ndr_vcs_t) + vc->wcsize + sizeof (smb_wchar_t);
-
+	/*
+	 * alloc one extra wchar for a null
+	 * See slen + 1 arg for mbstowcs
+	 */
+	mlen = sizeof (ndr_vcs_t) + vc->wcsize + sizeof (ndr_wchar_t);
 	vc->vcs = ndr_heap_malloc(heap, mlen);
 
 	if (vc->vcs) {
 		vc->vcs->vc_first_is = 0;
-		vc->vcs->vc_length_is = vc->wclen / sizeof (smb_wchar_t);
-		(void) smb_mbstowcs((smb_wchar_t *)vc->vcs->buffer, s,
-		    vc->vcs->vc_length_is);
+		vc->vcs->vc_length_is = slen;
+		(void) ndr__mbstowcs(vc->vcs->buffer, s, slen + 1);
 	}
 }
 
@@ -250,26 +288,9 @@
 }
 
 /*
- * Duplcate a SID in the heap.
+ * Removed ndr_heap_siddup(), now using ndr_heap_dupmem().
  */
-smb_sid_t *
-ndr_heap_siddup(ndr_heap_t *heap, smb_sid_t *sid)
-{
-	smb_sid_t *new_sid;
-	unsigned size;
 
-	if (sid == NULL)
-		return (NULL);
-
-	size = smb_sid_len(sid);
-
-	if ((new_sid = ndr_heap_malloc(heap, size)) == NULL)
-		return (NULL);
-
-	bcopy(sid, new_sid, size);
-	return (new_sid);
-}
-
 int
 ndr_heap_used(ndr_heap_t *heap)
 {
--- old/usr/src/lib/libmlrpc/common/ndr_marshal.c	Sun Mar 18 01:12:58 2018
+++ new/usr/src/lib/libmlrpc/common/ndr_marshal.c	Sun Mar 18 01:12:58 2018
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <assert.h>
@@ -26,8 +27,7 @@
 #include <strings.h>
 #include <sys/param.h>
 
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
 
 #ifdef _BIG_ENDIAN
 static const int ndr_native_byte_order = NDR_REPLAB_INTG_BIG_ENDIAN;
--- old/usr/src/lib/libmlrpc/common/ndr_ops.c	Sun Mar 18 01:12:58 2018
+++ new/usr/src/lib/libmlrpc/common/ndr_ops.c	Sun Mar 18 01:12:58 2018
@@ -49,8 +49,7 @@
 #include <string.h>
 #include <assert.h>
 
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
 
 #define	NDOBUFSZ		128
 
--- old/usr/src/lib/libmlrpc/common/ndr_process.c	Sun Mar 18 01:12:59 2018
+++ new/usr/src/lib/libmlrpc/common/ndr_process.c	Sun Mar 18 01:12:59 2018
@@ -22,6 +22,7 @@
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  * Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -34,14 +35,12 @@
 #include <strings.h>
 #include <assert.h>
 #include <string.h>
+#include <stdio.h>
 #include <stdlib.h>
 
-#include <smbsrv/libsmb.h>
-#include <smbsrv/string.h>
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
+#include <ndr_wchar.h>
 
-#define	NDR_STRING_MAX		4096
-
 #define	NDR_IS_UNION(T)	\
 	(((T)->type_flags & NDR_F_TYPEOP_MASK) == NDR_F_UNION)
 #define	NDR_IS_STRING(T)	\
@@ -1210,17 +1209,22 @@
 			/*
 			 * size_is is the number of characters in the
 			 * (multibyte) string, including the null.
+			 * In other words, symbols, not bytes.
 			 */
-			size_is = smb_wcequiv_strlen(valp) /
-			    sizeof (smb_wchar_t);
-
-			if (!(nds->flags & NDS_F_NONULL))
-				++size_is;
-
-			if (size_is > NDR_STRING_MAX) {
+			size_t wlen;
+			wlen = ndr__mbstowcs(NULL, valp, NDR_STRING_MAX);
+			if (wlen == (size_t)-1) {
+				/* illegal sequence error? */
 				NDR_SET_ERROR(outer_ref, NDR_ERR_STRLEN);
 				return (0);
 			}
+			if ((nds->flags & NDS_F_NONULL) == 0)
+				wlen++;
+			if (wlen > NDR_STRING_MAX) {
+				NDR_SET_ERROR(outer_ref, NDR_ERR_STRLEN);
+				return (0);
+			}
+			size_is = wlen;
 		} else {
 			valp = outer_ref->datum;
 			n_zeroes = 0;
@@ -1288,7 +1292,7 @@
 			 * be nice to use mbequiv_strlen but the string
 			 * may not be null terminated.
 			 */
-			n_alloc = (size_is + 1) * MTS_MB_CHAR_MAX;
+			n_alloc = (size_is + 1) * NDR_MB_CHAR_MAX;
 		} else {
 			n_alloc = (size_is + 1) * is_varlen;
 		}
@@ -1741,7 +1745,7 @@
 	myref.inner_flags = NDR_F_NONE;
 
 	for (i = 0; i < n_elem; i++) {
-		(void) sprintf(name, "[%lu]", i);
+		(void) snprintf(name, sizeof (name), "[%lu]", i);
 		myref.name = name;
 		myref.pdu_offset = pdu_offset + i * ti->pdu_size_fixed_part;
 		myref.datum = encl_ref->datum + i * ti->c_size_fixed_part;
@@ -1796,16 +1800,16 @@
 int ndr_basic_integer(ndr_ref_t *, unsigned);
 int ndr_string_basic_integer(ndr_ref_t *, ndr_typeinfo_t *);
 
+/* Comments to be nice to those searching for these types. */
+MAKE_BASIC_TYPE(_char, 1)	/* ndt__char,  ndt_s_char */
+MAKE_BASIC_TYPE(_uchar, 1)	/* ndt__uchar, ndt_s_uchar */
+MAKE_BASIC_TYPE(_short, 2)	/* ndt__short, ndt_s_short */
+MAKE_BASIC_TYPE(_ushort, 2)	/* ndt__ushort, ndt_s_ushort */
+MAKE_BASIC_TYPE(_long, 4)	/* ndt__long,  ndt_s_long */
+MAKE_BASIC_TYPE(_ulong, 4)	/* ndt__ulong, ndt_s_ulong */
 
-MAKE_BASIC_TYPE(_char, 1)
-MAKE_BASIC_TYPE(_uchar, 1)
-MAKE_BASIC_TYPE(_short, 2)
-MAKE_BASIC_TYPE(_ushort, 2)
-MAKE_BASIC_TYPE(_long, 4)
-MAKE_BASIC_TYPE(_ulong, 4)
+MAKE_BASIC_TYPE_BASE(_wchar, 2)	/* ndt__wchar, ndt_s_wchar */
 
-MAKE_BASIC_TYPE_BASE(_wchar, 2)
-
 int
 ndr_basic_integer(ndr_ref_t *ref, unsigned size)
 {
@@ -1854,7 +1858,7 @@
 	myref.name = name;
 
 	for (i = 0; i < NDR_STRING_MAX; i++) {
-		(void) sprintf(name, "[%lu]", i);
+		(void) snprintf(name, sizeof (name), "[%lu]", i);
 		myref.pdu_offset = pdu_offset + i * size;
 		valp = encl_ref->datum + i * size;
 		myref.datum = valp;
@@ -1897,28 +1901,28 @@
  * multi-byte to wide characters. During NDR_M_OP_UNMARSHALL, we
  * convert from wide characters to multi-byte.
  *
- * It appeared that NT would sometimes leave a spurious character
- * in the data stream before the null wide_char, which would get
- * included in the string decode because we processed until the
- * null character. It now looks like NT does not always terminate
- * RPC Unicode strings and the terminating null is a side effect
- * of field alignment. So now we rely on the strlen_is (set up in
- * ndr_outer_string) of the enclosing reference. This may or may
- * not include the null but it doesn't matter, the algorithm will
- * get it right.
+ * The most critical thing to get right in this function is to
+ * marshall or unmarshall _exactly_ the number of elements the
+ * OtW length specifies, as saved by the caller in: strlen_is.
+ * Doing otherwise would leave us positioned at the wrong place
+ * in the data stream for whatever follows this.  Note that the
+ * string data covered by strlen_is may or may not include any
+ * null termination, but the converted string provided by the
+ * caller or returned always has a null terminator.
  */
 int
 ndr_s_wchar(ndr_ref_t *encl_ref)
 {
 	ndr_stream_t		*nds = encl_ref->stream;
-	unsigned short		wide_char;
-	char 			*valp;
+	char 			*valp = encl_ref->datum;
 	ndr_ref_t		myref;
-	unsigned long		i;
 	char			name[30];
-	int			count;
-	int			char_count = 0;
+	ndr_wchar_t		wcs[NDR_STRING_MAX+1];
+	size_t			i, slen, wlen;
 
+	/* This is enforced in ndr_outer_string() */
+	assert(encl_ref->strlen_is <= NDR_STRING_MAX);
+
 	if (nds->m_op == NDR_M_OP_UNMARSHALL) {
 		/*
 		 * To avoid problems with zero length strings
@@ -1930,6 +1934,29 @@
 		}
 	}
 
+	/*
+	 * If we're marshalling, convert the given string
+	 * from UTF-8 into a local UCS-2 string.
+	 */
+	if (nds->m_op == NDR_M_OP_MARSHALL) {
+		wlen = ndr__mbstowcs(wcs, valp, NDR_STRING_MAX);
+		if (wlen == (size_t)-1)
+			return (0);
+		/*
+		 * Add a nulls to make strlen_is.
+		 * (always zero or one of them)
+		 * Then null terminate at wlen,
+		 * just for debug convenience.
+		 */
+		while (wlen < encl_ref->strlen_is)
+			wcs[wlen++] = 0;
+		wcs[wlen] = 0;
+	}
+
+	/*
+	 * Copy wire data to or from the local wc string.
+	 * Always exactly strlen_is elements.
+	 */
 	bzero(&myref, sizeof (myref));
 	myref.enclosing = encl_ref;
 	myref.stream = encl_ref->stream;
@@ -1936,53 +1963,31 @@
 	myref.packed_alignment = 0;
 	myref.ti = &ndt__wchar;
 	myref.inner_flags = NDR_F_NONE;
-	myref.datum = (char *)&wide_char;
 	myref.name = name;
 	myref.pdu_offset = encl_ref->pdu_offset;
+	myref.datum = (char *)wcs;
+	wlen = encl_ref->strlen_is;
 
-	valp = encl_ref->datum;
-	count = 0;
-
-	for (i = 0; i < NDR_STRING_MAX; i++) {
-		(void) sprintf(name, "[%lu]", i);
-
-		if (nds->m_op == NDR_M_OP_MARSHALL) {
-			count = smb_mbtowc((smb_wchar_t *)&wide_char, valp,
-			    MTS_MB_CHAR_MAX);
-			if (count < 0) {
-				return (0);
-			} else if (count == 0) {
-				if (encl_ref->strlen_is != encl_ref->size_is)
-					break;
-
-				/*
-				 * If the input char is 0, mbtowc
-				 * returns 0 without setting wide_char.
-				 * Set wide_char to 0 and a count of 1.
-				 */
-				wide_char = *valp;
-				count = 1;
-			}
-		}
-
+	for (i = 0; i < wlen; i++) {
+		(void) snprintf(name, sizeof (name), "[%lu]", i);
 		if (!ndr_inner(&myref))
 			return (0);
+		myref.pdu_offset += sizeof (ndr_wchar_t);
+		myref.datum	 += sizeof (ndr_wchar_t);
+	}
 
-		if (nds->m_op == NDR_M_OP_UNMARSHALL) {
-			count = smb_wctomb(valp, wide_char);
-
-			if ((++char_count) == encl_ref->strlen_is) {
-				valp += count;
-				*valp = '\0';
-				break;
-			}
-		}
-
-		if (!wide_char)
-			break;
-
-		myref.pdu_offset += sizeof (wide_char);
-		valp += count;
+	/*
+	 * If this is unmarshall, convert the local UCS-2 string
+	 * into a UTF-8 string in the caller's buffer.  The caller
+	 * previously determined the space required and provides a
+	 * buffer of sufficient size.
+	 */
+	if (nds->m_op == NDR_M_OP_UNMARSHALL) {
+		wcs[wlen] = 0;
+		slen = ndr__wcstombs(valp, wcs, wlen);
+		if (slen == (size_t)-1)
+			return (0);
+		valp[slen] = '\0';
 	}
 
 	return (1);
@@ -1997,51 +2002,20 @@
  * any terminating null wide character.  Returns -1 if an invalid
  * multibyte character is encountered.
  */
+/* ARGSUSED */
 size_t
-ndr_mbstowcs(ndr_stream_t *nds, smb_wchar_t *wcs, const char *mbs,
+ndr_mbstowcs(ndr_stream_t *nds, ndr_wchar_t *wcs, const char *mbs,
     size_t nwchars)
 {
-	smb_wchar_t *start = wcs;
-	int nbytes;
+	size_t len;
 
-	while (nwchars--) {
-		nbytes = ndr_mbtowc(nds, wcs, mbs, MTS_MB_CHAR_MAX);
-		if (nbytes < 0) {
-			*wcs = 0;
-			return ((size_t)-1);
-		}
-
-		if (*mbs == 0)
-			break;
-
-		++wcs;
-		mbs += nbytes;
-	}
-
-	return (wcs - start);
-}
-
-/*
- * Converts a multibyte character to a little-endian, wide-char, which
- * is stored in wcharp.  Up to nbytes bytes are examined.
- *
- * If mbchar is valid, returns the number of bytes processed in mbchar.
- * If mbchar is invalid, returns -1.  See also smb_mbtowc().
- */
-/*ARGSUSED*/
-int
-ndr_mbtowc(ndr_stream_t *nds, smb_wchar_t *wcharp, const char *mbchar,
-    size_t nbytes)
-{
-	int rc;
-
-	if ((rc = smb_mbtowc(wcharp, mbchar, nbytes)) < 0)
-		return (rc);
-
 #ifdef _BIG_ENDIAN
-	if (nds == NULL || NDR_MODE_MATCH(nds, NDR_MODE_RETURN_SEND))
-		*wcharp = BSWAP_16(*wcharp);
+	if (nds == NULL || NDR_MODE_MATCH(nds, NDR_MODE_RETURN_SEND)) {
+		/* Make WC string in LE order. */
+		len = ndr__mbstowcs_le(wcs, mbs, nwchars);
+	} else
 #endif
+		len = ndr__mbstowcs(wcs, mbs, nwchars);
 
-	return (rc);
+	return (len);
 }
--- old/usr/src/lib/libmlrpc/common/ndr_server.c	Sun Mar 18 01:12:59 2018
+++ new/usr/src/lib/libmlrpc/common/ndr_server.c	Sun Mar 18 01:12:59 2018
@@ -36,9 +36,7 @@
 #include <string.h>
 #include <thread.h>
 
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
-#include <smbsrv/ntaccess.h>
+#include <libmlrpc.h>
 
 #define	NDR_PIPE_SEND(np, buf, len) \
 	((np)->np_send)((np), (buf), (len))
@@ -131,42 +129,6 @@
 	return (rc);
 }
 
-/*
- * Check whether or not the specified user has administrator privileges,
- * i.e. is a member of Domain Admins or Administrators.
- * Returns true if the user is an administrator, otherwise returns false.
- */
-boolean_t
-ndr_is_admin(ndr_xa_t *xa)
-{
-	smb_netuserinfo_t *ctx = xa->pipe->np_user;
-
-	return (ctx->ui_flags & SMB_ATF_ADMIN);
-}
-
-/*
- * Check whether or not the specified user has power-user privileges,
- * i.e. is a member of Domain Admins, Administrators or Power Users.
- * This is typically required for operations such as managing shares.
- * Returns true if the user is a power user, otherwise returns false.
- */
-boolean_t
-ndr_is_poweruser(ndr_xa_t *xa)
-{
-	smb_netuserinfo_t *ctx = xa->pipe->np_user;
-
-	return ((ctx->ui_flags & SMB_ATF_ADMIN) ||
-	    (ctx->ui_flags & SMB_ATF_POWERUSER));
-}
-
-int32_t
-ndr_native_os(ndr_xa_t *xa)
-{
-	smb_netuserinfo_t *ctx = xa->pipe->np_user;
-
-	return (ctx->ui_native_os);
-}
-
 /*
  * Receive an entire RPC request (all fragments)
  * Returns zero or an NDR fault code.
--- old/usr/src/lib/libmlrpc/common/ndr_svc.c	Sun Mar 18 01:12:59 2018
+++ new/usr/src/lib/libmlrpc/common/ndr_svc.c	Sun Mar 18 01:12:59 2018
@@ -34,8 +34,7 @@
 #include <strings.h>
 #include <assert.h>
 
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
 
 
 /*
--- /dev/null	Sun Mar 18 01:12:59 2018
+++ new/usr/src/lib/libmlrpc/common/ndr_wchar.c	Sun Mar 18 01:12:59 2018
@@ -0,0 +1,162 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
+
+/*
+ * Some wchar support functions used by this library.
+ * Mostlly just wrappers that call sys/u8_textprep.h
+ * functions: uconv_u8tou16, uconv_u16tou8.
+ */
+
+#include <sys/types.h>
+#include <sys/u8_textprep.h>
+#include <string.h>
+
+#include "ndr_wchar.h"
+
+/*
+ * When we just want lengths, we need an output buffer to pass to the
+ * uconv_... functions.  Nothing ever reads this output, so we can
+ * use shared space for the unwanted output.
+ */
+static uint16_t junk_wcs[NDR_STRING_MAX];
+static char junk_mbs[NDR_MB_CUR_MAX * NDR_STRING_MAX];
+
+static size_t
+ndr__mbstowcs_x(uint16_t *, const char *, size_t, int);
+
+/*
+ * Like mbstowcs(3C), but with UCS-2 wchar_t
+ */
+size_t
+ndr__mbstowcs(uint16_t *wcs, const char *mbs, size_t nwchars)
+{
+	return (ndr__mbstowcs_x(wcs, mbs, nwchars,
+	    UCONV_OUT_SYSTEM_ENDIAN));
+}
+
+/*
+ * Like above, but put UCS-2 little-endian.
+ */
+size_t
+ndr__mbstowcs_le(uint16_t *wcs, const char *mbs, size_t nwchars)
+{
+	return (ndr__mbstowcs_x(wcs, mbs, nwchars,
+	    UCONV_OUT_LITTLE_ENDIAN));
+}
+
+/*
+ * Like mbstowcs(3C), but with UCS-2 wchar_t, and
+ * one extra arg for the byte order flags.
+ */
+static size_t
+ndr__mbstowcs_x(uint16_t *wcs, const char *mbs, size_t nwchars, int flags)
+{
+	size_t obytes, mbslen, wcslen;
+	int err;
+
+	/* NULL or empty input is allowed. */
+	if (mbs == NULL || *mbs == '\0') {
+		if (wcs != NULL && nwchars > 0)
+			*wcs = 0;
+		return (0);
+	}
+
+	/*
+	 * If wcs == NULL, caller just wants the length.
+	 * Convert into some throw-away space.
+	 */
+	obytes = nwchars * 2;
+	if (wcs == NULL) {
+		if (obytes > sizeof (junk_wcs))
+			return ((size_t)-1);
+		wcs = junk_wcs;
+	}
+
+	mbslen = strlen(mbs);
+	wcslen = nwchars;
+	err = uconv_u8tou16((const uchar_t *)mbs, &mbslen,
+	    wcs, &wcslen, flags);
+	if (err != 0)
+		return ((size_t)-1);
+
+	if (wcslen < nwchars)
+		wcs[wcslen] = 0;
+
+	return (wcslen);
+}
+
+/*
+ * Like wcstombs(3C), but with UCS-2 wchar_t.
+ */
+size_t
+ndr__wcstombs(char *mbs, const uint16_t *wcs, size_t nbytes)
+{
+	size_t mbslen, wcslen;
+	int err;
+
+	/* NULL or empty input is allowed. */
+	if (wcs == NULL || *wcs == 0) {
+		if (mbs != NULL && nbytes > 0)
+			*mbs = '\0';
+		return (0);
+	}
+
+	/*
+	 * If mbs == NULL, caller just wants the length.
+	 * Convert into some throw-away space.
+	 */
+	if (mbs == NULL) {
+		if (nbytes > sizeof (junk_mbs))
+			return ((size_t)-1);
+		mbs = junk_mbs;
+	}
+
+	wcslen = ndr__wcslen(wcs);
+	mbslen = nbytes;
+	err = uconv_u16tou8(wcs, &wcslen,
+	    (uchar_t *)mbs, &mbslen, UCONV_IN_SYSTEM_ENDIAN);
+	if (err != 0)
+		return ((size_t)-1);
+
+	if (mbslen < nbytes)
+		mbs[mbslen] = '\0';
+
+	return (mbslen);
+}
+
+/*
+ * Like wcslen(3C), but with UCS-2 wchar_t.
+ */
+size_t
+ndr__wcslen(const uint16_t *wc)
+{
+	size_t len = 0;
+	while (*wc++)
+		len++;
+	return (len);
+}
--- /dev/null	Sun Mar 18 01:12:59 2018
+++ new/usr/src/lib/libmlrpc/common/ndr_wchar.h	Sun Mar 18 01:12:59 2018
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
+
+#ifndef _NDR_WCHAR_H
+#define	_NDR_WCHAR_H
+
+/*
+ * Some ndr_wchar_t support stuff.
+ */
+
+#define	NDR_MB_CUR_MAX		3
+#define	NDR_MB_CHAR_MAX		NDR_MB_CUR_MAX
+#define	NDR_STRING_MAX		4096
+
+size_t ndr__mbstowcs(uint16_t *, const char *, size_t);
+size_t ndr__mbstowcs_le(uint16_t *, const char *, size_t);
+
+size_t ndr__wcslen(const uint16_t *);
+size_t ndr__wcstombs(char *, const uint16_t *, size_t);
+
+#endif /* _NDR_WCHAR_H */
--- old/usr/src/lib/libmlrpc/common/ndrtypes.ndl	Sun Mar 18 01:12:59 2018
+++ new/usr/src/lib/libmlrpc/common/ndrtypes.ndl	Sun Mar 18 01:12:59 2018
@@ -21,11 +21,18 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
-#ifndef _NDR_TYPES_NDL_
-#define _NDR_TYPES_NDL_
+#ifndef _NDRTYPES_NDL_
+#define _NDRTYPES_NDL_
 
+/*
+ * Type definitions (and related) used in NDL files and the
+ * NDL run-time support libraries.  See also: libmlrpc.h
+ */
+
 #define TYPEINFO(TYPE)  ndt__##TYPE
 
 #ifdef NDRGEN
@@ -69,20 +76,6 @@
 #define LPWORD  ushort *
 #define LPDWORD ulong *
 
-/*
- * Opaque context handle.
- */
-#ifndef CONTEXT_HANDLE
-#define CONTEXT_HANDLE(NAME)	\
-	struct NAME {		\
-		DWORD data1;    \
-		DWORD data2;    \
-		WORD  data3[2]; \
-		BYTE  data4[8];	\
-	};			\
-	typedef struct NAME
-#endif /* CONTEXT_HANDLE */
-
 #define EXTERNTYPEINFO(TYPE)
 
 #else /* NDRGEN */
@@ -116,7 +109,7 @@
 /*
  * When not using ndrgen, get BYTE, WORD, DWORD definitions from wintypes.h.
  */
-#include <smbsrv/wintypes.h>
+#include <smb/wintypes.h>
 
 #define EXTERNTYPEINFO(TYPE)	extern struct ndr_typeinfo TYPEINFO(TYPE);
 
@@ -167,4 +160,18 @@
 #define UNION_INFO_ENT(N,NAME) CASE(N) struct NAME##N info##N
 #define UNION_INFO_PTR(N,NAME) CASE(N) struct NAME##N *info##N
 
-#endif /* _NDR_TYPES_NDL_ */
+/*
+ * Opaque context handle.
+ */
+#ifndef CONTEXT_HANDLE
+#define CONTEXT_HANDLE(NAME)	\
+	struct NAME {		\
+		DWORD data1;    \
+		DWORD data2;    \
+		WORD  data3[2]; \
+		BYTE  data4[8];	\
+	};			\
+	typedef struct NAME
+#endif /* CONTEXT_HANDLE */
+
+#endif /* _NDRTYPES_NDL_ */
--- old/usr/src/lib/libmlrpc/common/rpcpdu.ndl	Sun Mar 18 01:12:59 2018
+++ new/usr/src/lib/libmlrpc/common/rpcpdu.ndl	Sun Mar 18 01:12:59 2018
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef _RPCPDU_NDL_
--- old/usr/src/lib/libmlrpc/i386/Makefile	Sun Mar 18 01:12:59 2018
+++ new/usr/src/lib/libmlrpc/i386/Makefile	Sun Mar 18 01:12:59 2018
@@ -22,11 +22,7 @@
 # Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
 
 include ../Makefile.com
 
-DYNFLAGS +=	-R/usr/lib/smbsrv
-
 install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
--- old/usr/src/lib/libmlrpc/sparc/Makefile	Sun Mar 18 01:12:59 2018
+++ new/usr/src/lib/libmlrpc/sparc/Makefile	Sun Mar 18 01:12:59 2018
@@ -22,11 +22,7 @@
 # Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
 
 include ../Makefile.com
 
-DYNFLAGS +=	-R/usr/lib/smbsrv
-
 install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
--- old/usr/src/lib/libmlrpc/sparcv9/Makefile	Sun Mar 18 01:13:00 2018
+++ new/usr/src/lib/libmlrpc/sparcv9/Makefile	Sun Mar 18 01:13:00 2018
@@ -22,14 +22,10 @@
 # Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
 
 MACH_LDLIBS +=	-L$(ROOT)/usr/lib/smbsrv/$(MACH64)
 
 include ../Makefile.com
-include ../../../Makefile.lib.64
+include ../../Makefile.lib.64
 
-DYNFLAGS +=	-R/usr/lib/smbsrv/$(MACH64)
-
 install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
--- old/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c	Sun Mar 18 01:13:00 2018
+++ new/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c	Sun Mar 18 01:13:00 2018
@@ -48,14 +48,7 @@
 #include <libsmbrdr.h>
 #include <mlsvc.h>
 
-static int ndr_xa_init(ndr_client_t *, ndr_xa_t *);
-static int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *);
-static int ndr_xa_read(ndr_client_t *, ndr_xa_t *);
-static void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *);
-static void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *);
-static void ndr_xa_release(ndr_client_t *);
 
-
 /*
  * This call must be made to initialize an RPC client structure and bind
  * to the remote service before any RPCs can be exchanged with that service.
@@ -244,153 +237,7 @@
 	bzero(handle, sizeof (mlsvc_handle_t));
 }
 
-/*
- * Call the RPC function identified by opnum.  The remote service is
- * identified by the handle, which should have been initialized by
- * ndr_rpc_bind.
- *
- * If the RPC call is successful (returns 0), the caller must call
- * ndr_rpc_release to release the heap.  Otherwise, we release the
- * heap here.
- */
-int
-ndr_rpc_call(mlsvc_handle_t *handle, int opnum, void *params)
-{
-	ndr_client_t *clnt = handle->clnt;
-	int rc;
-
-	if (ndr_rpc_get_heap(handle) == NULL)
-		return (-1);
-
-	rc = ndr_clnt_call(clnt->binding, opnum, params);
-
-	/*
-	 * Always clear the nonull flag to ensure
-	 * it is not applied to subsequent calls.
-	 */
-	clnt->nonull = B_FALSE;
-
-	if (NDR_DRC_IS_FAULT(rc)) {
-		ndr_rpc_release(handle);
-		return (-1);
-	}
-
-	return (0);
-}
-
-/*
- * Outgoing strings should not be null terminated.
- */
 void
-ndr_rpc_set_nonull(mlsvc_handle_t *handle)
-{
-	handle->clnt->nonull = B_TRUE;
-}
-
-/*
- * Get the session key from a bound RPC client handle.
- *
- * The key returned is the 16-byte "user session key"
- * established by the underlying authentication protocol
- * (either Kerberos or NTLM).  This key is needed for
- * SAM RPC calls such as SamrSetInformationUser, etc.
- * See [MS-SAMR] sections: 2.2.3.3, 2.2.7.21, 2.2.7.25.
- *
- * Returns zero (success) or an errno.
- */
-int
-ndr_rpc_get_ssnkey(mlsvc_handle_t *handle,
-	unsigned char *ssn_key, size_t len)
-{
-	ndr_client_t *clnt = handle->clnt;
-	int rc;
-
-	if (clnt == NULL)
-		return (EINVAL);
-
-	rc = smb_fh_getssnkey(clnt->xa_fd, ssn_key, len);
-	return (rc);
-}
-
-void *
-ndr_rpc_malloc(mlsvc_handle_t *handle, size_t size)
-{
-	ndr_heap_t *heap;
-
-	if ((heap = ndr_rpc_get_heap(handle)) == NULL)
-		return (NULL);
-
-	return (ndr_heap_malloc(heap, size));
-}
-
-ndr_heap_t *
-ndr_rpc_get_heap(mlsvc_handle_t *handle)
-{
-	ndr_client_t *clnt = handle->clnt;
-
-	if (clnt->heap == NULL)
-		clnt->heap = ndr_heap_create();
-
-	return (clnt->heap);
-}
-
-/*
- * Must be called by RPC clients to free the heap after a successful RPC
- * call, i.e. ndr_rpc_call returned 0.  The caller should take a copy
- * of any data returned by the RPC prior to calling this function because
- * returned data is in the heap.
- */
-void
-ndr_rpc_release(mlsvc_handle_t *handle)
-{
-	ndr_client_t *clnt = handle->clnt;
-
-	if (clnt->heap_preserved)
-		ndr_clnt_free_heap(clnt);
-	else
-		ndr_heap_destroy(clnt->heap);
-
-	clnt->heap = NULL;
-}
-
-/*
- * Returns true if the handle is null.
- * Otherwise returns false.
- */
-boolean_t
-ndr_is_null_handle(mlsvc_handle_t *handle)
-{
-	static ndr_hdid_t zero_handle;
-
-	if (handle == NULL || handle->clnt == NULL)
-		return (B_TRUE);
-
-	if (!memcmp(&handle->handle, &zero_handle, sizeof (ndr_hdid_t)))
-		return (B_TRUE);
-
-	return (B_FALSE);
-}
-
-/*
- * Returns true if the handle is the top level bind handle.
- * Otherwise returns false.
- */
-boolean_t
-ndr_is_bind_handle(mlsvc_handle_t *handle)
-{
-	return (handle->clnt->handle == &handle->handle);
-}
-
-/*
- * Pass the client reference from parent to child.
- */
-void
-ndr_inherit_handle(mlsvc_handle_t *child, mlsvc_handle_t *parent)
-{
-	child->clnt = parent->clnt;
-}
-
-void
 ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)
 {
 	ndr_service_t *svc;
@@ -419,151 +266,4 @@
 
 	smb_tracef("%s[0x%02x]: %s: %s (0x%08x)",
 	    name, opnum, s, xlate_nt_status(status), status);
-}
-
-/*
- * The following functions provide the client callback interface.
- * If the caller hasn't provided a heap, create one here.
- */
-static int
-ndr_xa_init(ndr_client_t *clnt, ndr_xa_t *mxa)
-{
-	ndr_stream_t	*recv_nds = &mxa->recv_nds;
-	ndr_stream_t	*send_nds = &mxa->send_nds;
-	ndr_heap_t	*heap = clnt->heap;
-	int		rc;
-
-	if (heap == NULL) {
-		if ((heap = ndr_heap_create()) == NULL)
-			return (-1);
-
-		clnt->heap = heap;
-	}
-
-	mxa->heap = heap;
-
-	rc = nds_initialize(send_nds, 0, NDR_MODE_CALL_SEND, heap);
-	if (rc == 0)
-		rc = nds_initialize(recv_nds, NDR_PDU_SIZE_HINT_DEFAULT,
-		    NDR_MODE_RETURN_RECV, heap);
-
-	if (rc != 0) {
-		nds_destruct(&mxa->recv_nds);
-		nds_destruct(&mxa->send_nds);
-		ndr_heap_destroy(mxa->heap);
-		mxa->heap = NULL;
-		clnt->heap = NULL;
-		return (-1);
-	}
-
-	if (clnt->nonull)
-		NDS_SETF(send_nds, NDS_F_NONULL);
-
-	return (0);
-}
-
-/*
- * This is the entry pointy for an RPC client call exchange with
- * a server, which will result in an smbrdr SmbTransact request.
- *
- * SmbTransact should return the number of bytes received, which
- * we record as the PDU size, or a negative error code.
- */
-static int
-ndr_xa_exchange(ndr_client_t *clnt, ndr_xa_t *mxa)
-{
-	ndr_stream_t *recv_nds = &mxa->recv_nds;
-	ndr_stream_t *send_nds = &mxa->send_nds;
-	int err, more, nbytes;
-
-	nbytes = recv_nds->pdu_max_size;
-	err = smb_fh_xactnp(clnt->xa_fd,
-	    send_nds->pdu_size, (char *)send_nds->pdu_base_offset,
-	    &nbytes, (char *)recv_nds->pdu_base_offset, &more);
-	if (err) {
-		recv_nds->pdu_size = 0;
-		return (-1);
-	}
-
-	recv_nds->pdu_size = nbytes;
-	return (0);
-}
-
-/*
- * This entry point will be invoked if the xa-exchange response contained
- * only the first fragment of a multi-fragment response.  The RPC client
- * code will then make repeated xa-read requests to obtain the remaining
- * fragments, which will result in smbrdr SmbReadX requests.
- *
- * SmbReadX should return the number of bytes received, in which case we
- * expand the PDU size to include the received data, or a negative error
- * code.
- */
-static int
-ndr_xa_read(ndr_client_t *clnt, ndr_xa_t *mxa)
-{
-	ndr_stream_t *nds = &mxa->recv_nds;
-	int len;
-	int nbytes;
-
-	if ((len = (nds->pdu_max_size - nds->pdu_size)) < 0)
-		return (-1);
-
-	nbytes = smb_fh_read(clnt->xa_fd, 0, len,
-	    (char *)nds->pdu_base_offset + nds->pdu_size);
-
-	if (nbytes < 0)
-		return (-1);
-
-	nds->pdu_size += nbytes;
-
-	if (nds->pdu_size > nds->pdu_max_size) {
-		nds->pdu_size = nds->pdu_max_size;
-		return (-1);
-	}
-
-	return (nbytes);
-}
-
-/*
- * Preserve the heap so that the client application has access to data
- * returned from the server after an RPC call.
- */
-static void
-ndr_xa_preserve(ndr_client_t *clnt, ndr_xa_t *mxa)
-{
-	assert(clnt->heap == mxa->heap);
-
-	clnt->heap_preserved = B_TRUE;
-	mxa->heap = NULL;
-}
-
-/*
- * Dispose of the transaction streams.  If the heap has not been
- * preserved, we can destroy it here.
- */
-static void
-ndr_xa_destruct(ndr_client_t *clnt, ndr_xa_t *mxa)
-{
-	nds_destruct(&mxa->recv_nds);
-	nds_destruct(&mxa->send_nds);
-
-	if (!clnt->heap_preserved) {
-		ndr_heap_destroy(mxa->heap);
-		mxa->heap = NULL;
-		clnt->heap = NULL;
-	}
-}
-
-/*
- * Dispose of a preserved heap.
- */
-static void
-ndr_xa_release(ndr_client_t *clnt)
-{
-	if (clnt->heap_preserved) {
-		ndr_heap_destroy(clnt->heap);
-		clnt->heap = NULL;
-		clnt->heap_preserved = B_FALSE;
-	}
 }
--- old/usr/src/tools/ndrgen/ndrgen.sh	Sun Mar 18 01:13:00 2018
+++ new/usr/src/tools/ndrgen/ndrgen.sh	Sun Mar 18 01:13:00 2018
@@ -19,17 +19,25 @@
 #
 # CDDL HEADER END
 #
+
 #
 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
+# Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+#
 
 # This is a wrapper script around the ndrgen compiler (ndrgen1).
-# CC must be defined in the environment or on the command line.
 
-NDRPROG="${0%/*}/ndrgen1"
-INCDIR=${ROOT}/usr/include/smbsrv
+NDRPROG="${0}1"
 
+# Note: most *.ndl files require an ANSI-compatible cpp,
+# so we can NOT use /usr/lib/cpp or /usr/ccs/lib/cpp
+# Wish there was an easier way to get an ANSI cpp.
+CPP="${CC} -E"
+CPPFLAGS="-DNDRGEN"
+V_FLAG=
+
 PROGNAME=`basename $0`
 
 ndrgen_usage()
@@ -38,62 +46,63 @@
 		print "$PROGNAME: ERROR: $1"
 	fi
 
-	echo "usage: $PROGNAME [-Y cpp-path] file [file]..."
+	echo "usage: $PROGNAME [options] file.ndl [file.ndl]..."
+	echo "	options: -Y cc-path -Ddefine -Iinclude"
 	exit 1
 }
 
-# Copy header text from the input ndl file to the generated ndr C file.
-ndrgen_copy_header()
+# Process the input ndl file ($1) generating C code on stdout.
+process()
 {
-	ndl_file=$1
-	ndr_file=$2
 
+	# Put the standard top matter
+	#
+	# Want the include directive to have just
+	# include "file.ndl" (no path) so...
+	inc_ndl=`basename $1`
+	cat - << EOF
+/*
+ * Please do not edit this file.
+ * It was generated using ndrgen.
+ */
+
+#include <strings.h>
+#include <libmlrpc/ndr.h>
+#include "$inc_ndl"
+EOF
+
+	# Put optional custom top matter
 	nawk 'BEGIN { copy=0; }
 	/^\/\* NDRGEN_HEADER_BEGIN \*\// { copy=1; next; }
 	/^\/\* NDRGEN_HEADER_END \*\// { copy=0; next; }
-	/./ { if (copy==1) print; }' < $ndl_file > $ndr_file
+	/./ { if (copy==1) print; }' $1
+
+	# now the real ndrgen output
+	[ -n "$V_FLAG" ] &&
+	  echo "$CPP $CPPFLAGS $1 | $NDRPROG" >&2
+	$CPP $CPPFLAGS $1 | $NDRPROG
 }
 
-if [[ $# -lt 1 ]] ; then
-	ndrgen_usage
-fi
 
-while getopts "Y" FLAG $*; do
+while getopts "D:I:Y:V" FLAG
+do
 	case $FLAG in
-	Y)
-		CC_FLAG="y"
-		;;
-	*)
-		ndrgen_usage
-		;;
+	D|I)	CPPFLAGS="$CPPFLAGS -${FLAG}${OPTARG}";;
+	Y)	CPP="$OPTARG";;
+	V)	V_FLAG="V";;
+	*)	ndrgen_usage;;
 	esac
 done
+shift $(($OPTIND - 1))
 
-if [[ $CC_FLAG = "y" ]] ; then
-	shift $(($OPTIND - 1))
-
-	if [[ $# -lt 1 ]] ; then
-		ndrgen_usage "C pre-processor path is missing"
-	else
-		CC=$1
-		shift $(($OPTIND - 1))
-
-		# Check for cw being invoked with -_cc or -_gcc
-		if [[ $1 = "-_cc" || $1 = "-_gcc" ]] ; then
-			CC_ARG=$1
-			shift $(($OPTIND - 1))
-		fi
-	fi
+if [[ $# -lt 1 ]] ; then
+	ndrgen_usage
 fi
 
-if [[ $CC = "" ]] ; then
-	ndrgen_usage "C pre-processor is not defined"
+if [ ! -x $CPP ] ; then
+	ndrgen_usage "cannot run $CPP"
 fi
 
-if [ ! -f $CC ] || [ ! -x $CC ] ; then
-	ndrgen_usage "cannot run $CC"
-fi
-
 for i
 do
 	if [[ ! -r $i ]] ; then
@@ -101,36 +110,9 @@
 		exit 1
 	fi
 
-	BASENAME=`basename $i .ndl`
-	TMP_NAME=$BASENAME.ndl.c
-
-	cp $i $TMP_NAME
-
-	if $CC $CC_ARG -E  -D__a64 -D__EXTENSIONS__ -D_FILE_OFFSET_BITS=64 \
-		-I. -I${INCDIR} -I${INCDIR}/ndl -DNDRGEN $TMP_NAME | \
-		$NDRPROG > $BASENAME.raw
-	then
-		touch ${BASENAME}_ndr.c
-		ndrgen_copy_header $i ${BASENAME}_ndr.c
-
-		cat - << EOF >> ${BASENAME}_ndr.c
-/*
- * Please do not edit this file.
- * It was generated using ndrgen.
- */
-
-#include <strings.h>
-#include <smbsrv/ndr.h>
-#include <smbsrv/ndl/$BASENAME.ndl>
-EOF
-
-		cat $BASENAME.raw >> ${BASENAME}_ndr.c
-
-		rm -f $BASENAME.raw
-		rm -f $TMP_NAME
-	else
-		rm -f $BASENAME.raw
-		rm -f $TMP_NAME
-		exit 1
-	fi
+	base=`basename $i .ndl`
+	process $i > ${base}_ndr.c || {
+	  echo "ndrgen error";
+	  rm ${base}_ndr.c;
+	}
 done
--- /dev/null	Sun Mar 18 01:13:00 2018
+++ new/usr/src/tools/quick/make-smbclnt	Sun Mar 18 01:13:00 2018
@@ -0,0 +1,303 @@
+#!/bin/ksh
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+#
+
+# Use distributed make (dmake) by default.
+make=${MAKE:-dmake}
+
+CLOSED_IS_PRESENT=no
+export CLOSED_IS_PRESENT
+
+# Do this if you want to use dbx or gdb
+# export SOURCEDEBUG=yes
+
+[ -n "$SRC" ] || {
+  echo "SRC not set.  Run 'ws' or 'bldenv' first."
+  exit 1
+}
+
+cpu=`uname -p`
+case $cpu in
+i386)
+	x=intel
+	kmdb_arch="amd64"
+	mdb_arch="ia32 amd64"
+	arch64=amd64
+	;;
+sparc)
+	x=sparc
+	kmdb_arch=v9
+	mdb_arch="v7 v9"
+	arch64=sparcv9
+	;;
+*)  echo "Huh?" ; exit 1;;
+esac
+
+################################################################
+
+build_tools() {
+  test -f $SRC/tools/proto/root_i386-nd/opt/onbld/bin/genoffsets ||
+    (cd $SRC/tools && $make install)
+  (cd $SRC/common/mapfiles; $make install)
+}
+
+clobber_tools() {
+  (cd $SRC/tools && $make clobber)
+  (cd $SRC/common/mapfiles; $make clobber)
+}
+
+################################################################
+
+do_hdrs() {
+
+targ=$1
+if [ "$targ" = clobber ]
+then
+  (cd $SRC/uts && $make -k clobber_h)
+  (cd $SRC/head && $make clobber)
+fi
+
+if [ "$targ" = install ]
+then
+  targ=install_h
+
+  # Just the parts of "make sgs" we need, and
+  # skip them if they appear to be done.
+  # ... stuff under $SRC
+  test -f $SRC/uts/common/sys/priv_names.h ||
+    (cd $SRC/uts && $make -k all_h)
+
+  test -f $SRC/head/rpcsvc/nispasswd.h ||
+    (cd $SRC/head && $make -k install_h)
+
+  # ... stuff under $ROOT (proto area)
+  test -d $ROOT/usr/include/sys ||
+    (cd $SRC && $make rootdirs)
+  test -f $ROOT/usr/include/sys/types.h ||
+    (cd $SRC/uts && $make -k install_h)
+  test -f $ROOT/usr/include/rpcsvc/daemon_utils.h ||
+    (cd $SRC/head && $make install_h)
+
+  # always update the netsmb headers to be safe
+  (cd $SRC/uts/common/sys && $make -k install_h)
+
+fi
+
+# Need some library headers too...
+for lib in \
+  libcryptoutil \
+  libpam \
+  libsec \
+  libshare \
+  libsmbfs \
+  passwdutil
+do
+  (cd $SRC/lib/$lib && $make $targ)
+done
+}
+
+################################################################
+
+do_kern() {
+  case $1 in
+  lint) targ=modlintlib ;;
+  *) targ=$1 ;;
+  esac
+  ( unset SOURCEDEBUG ;
+  (cd $SRC/uts/$x/nsmb && $make $targ) ;
+  (cd $SRC/uts/$x/smbfs && $make $targ) )
+}
+
+################################################################
+
+# Note lib1 builds prerequisite libraries not delivered by the
+# tar file we create below.  To accelerate clean/install, we
+# skip these on clean (but still nuke them for clobber)
+
+do_lib1() {
+  :
+}
+
+# lib2 builds stuff we include in the tar file,
+# or that we don't mind rebuilding after clean.
+
+do_lib2() {
+
+(cd $SRC/lib/libsmbfs && $make $1)
+[ "$1" = install ] &&
+  (cd $SRC/lib/libsmbfs && $make _msg)
+(cd $SRC/lib/libmlrpc && $make $1)
+(cd $SRC/lib/libshare && $make $1 PLUGINS=smbfs)
+(cd $SRC/lib/passwdutil && $make $1)
+(cd $SRC/lib/pam_modules/smbfs && $make $1)
+
+}
+
+################################################################
+
+do_cmds() {
+
+case $1 in
+install)
+  # mount programs need fslib.o
+  (cd $SRC/cmd/fs.d && $make fslib.o)
+  (cd $SRC/cmd/fs.d/smbclnt && $make $1 catalog)
+  ;;
+clean|clobber)
+  (cd $SRC/cmd/fs.d/smbclnt && $make $1)
+  (cd $SRC/cmd/fs.d && $make ${1}_local)
+  ;;
+esac
+
+# Build the MDB modules, WITH the linktest
+(cd $SRC/cmd/mdb/tools && $make $1)
+
+# kmdb_arch is 64-bit only
+for a in $kmdb_arch
+do
+  case $1 in
+  install|lint)
+    (cd $SRC/cmd/mdb/$x/$a/kmdb &&
+	$make kmdb_modlinktest.o )
+    ;;
+  clean|clobber)
+    (cd $SRC/cmd/mdb/$x/$a/kmdb &&
+	$make -k $1 )
+    ;;
+  esac
+
+  (cd $SRC/cmd/mdb/$x/$a/nsmb &&
+	$make $1 KMDB_LINKTEST_ENABLE= )
+  (cd $SRC/cmd/mdb/$x/$a/smbfs &&
+	$make $1 KMDB_LINKTEST_ENABLE= )
+done
+}
+
+
+################################################################
+# This builds $SRC/TAGS (and cscope.files) in a helpful order.
+
+do_tags() {
+	(cd $SRC ;
+	find uts/common/sys -name '*.[ch]' -print |sort
+	find uts/common/net -name '*.[ch]' -print |sort
+	find uts/common/netinet -name '*.[ch]' -print |sort
+	find uts/common/smb -name '*.[ch]' -print |sort
+	find uts/common/netsmb -name '*.[ch]' -print |sort
+	find uts/common/fs/smbclnt -name '*.[ch]' -print |sort
+	find head -name '*.h' -print |sort
+	find lib/libsmbfs -name '*.[ch]' -print |sort
+	find cmd/fs.d/smbclnt -name '*.[ch]' -print |sort
+	find common/smbclnt -name '*.[ch]' -print |sort
+	) > $SRC/cscope.files
+
+	(cd $SRC ;
+	exctags -e --langmap=c:+.ndl -h ndl -L - < cscope.files
+	cscope -b )
+}
+
+################################################################
+# This creates a tarfile one can use to update a test machine.
+
+do_tar() {
+	git_rev=`git rev-parse --short=8 HEAD`
+	files="
+lib/svc/manifest/network/smb/client.xml
+lib/svc/method/smb-client
+opt/smbcl-tests/tests/srvenum
+opt/smbcl-tests/tests/srvinfo
+opt/smbcl-tests/tests/tconn
+usr/bin/smbutil
+usr/kernel/drv/$arch64/nsmb
+usr/kernel/fs/$arch64/smbfs
+usr/kernel/kmdb/$arch64/nsmb
+usr/kernel/kmdb/$arch64/smbfs
+usr/lib/$arch64/libsmbfs.so.1
+usr/lib/fs/smbfs/$arch64/libshare_smbfs.so.1
+usr/lib/fs/smbfs/chacl
+usr/lib/fs/smbfs/dfshares
+usr/lib/fs/smbfs/libshare_smbfs.so.1
+usr/lib/fs/smbfs/lsacl
+usr/lib/fs/smbfs/mount
+usr/lib/fs/smbfs/share
+usr/lib/fs/smbfs/umount
+usr/lib/fs/smbfs/unshare
+usr/lib/libmlrpc.so.1
+usr/lib/libsmbfs.so.1
+usr/lib/mdb/kvm/$arch64/nsmb.so
+usr/lib/mdb/kvm/$arch64/smbfs.so
+usr/lib/mdb/kvm/nsmb.so
+usr/lib/mdb/kvm/smbfs.so
+usr/lib/security/$arch64/pam_smbfs_login.so.1
+usr/lib/security/pam_smbfs_login.so.1
+usr/lib/smbfs/smbiod
+usr/lib/smbfs/smbiod-svc
+"
+
+	(cd $ROOT && tar cfj ../../smbclnt-${git_rev}.tar.bz2 $files)
+}
+
+################################################################
+
+if [ "$1" = "" ]; then
+  set '?' # force usage
+fi
+
+set -x
+
+for arg
+do
+  case "$arg" in
+  install)
+    build_tools
+    set -e
+    do_hdrs $arg
+    do_kern $arg
+    do_lib1 $arg
+    do_lib2 $arg
+    do_cmds $arg
+    ;;
+  lint)
+    do_kern $arg
+    do_lib1 $arg
+    do_lib2 $arg
+    do_cmds $arg
+    ;;
+  clean)
+    # intentionally skip: lib1, hdrs, tools
+    do_cmds $arg
+    do_lib2 $arg
+    do_kern $arg
+    ;;
+  clobber)
+    do_cmds $arg
+    do_lib2 $arg
+    do_lib1 $arg
+    do_kern $arg
+    do_hdrs $arg
+    clobber_tools
+    ;;
+  tags)
+    do_tags
+    ;;
+  tar)
+    do_tar
+    ;;
+  *)
+    echo "Usage: $0 {install|lint|clean|clobber|tags|tar}";
+    exit 1;
+    ;;
+  esac
+done
--- old/usr/src/uts/common/smb/Makefile	Sun Mar 18 01:13:00 2018
+++ new/usr/src/uts/common/smb/Makefile	Sun Mar 18 01:13:00 2018
@@ -21,6 +21,7 @@
 
 #
 # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
 #
 
 include ../../../Makefile.master
@@ -29,7 +30,8 @@
 	doserror.h		\
 	lmerr.h			\
 	nterror.h		\
-	ntstatus.h
+	ntstatus.h		\
+	wintypes.h
 
 
 ROOTDIR= $(ROOT)/usr/include/smb
--- old/usr/src/uts/common/smb/wintypes.h	Sun Mar 18 01:13:00 2018
+++ new/usr/src/uts/common/smb/wintypes.h	Sun Mar 18 01:13:00 2018
@@ -18,13 +18,16 @@
  *
  * CDDL HEADER END
  */
+
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
-#ifndef _SMBSRV_WINTYPES_H
-#define	_SMBSRV_WINTYPES_H
+#ifndef _SMB_WINTYPES_H
+#define	_SMB_WINTYPES_H
 
 #include <sys/types.h>
 
@@ -42,36 +45,28 @@
 typedef	uint8_t BYTE;
 typedef	uint16_t WORD;
 typedef	uint32_t DWORD;
-typedef	uint32_t ntstatus_t;
+typedef	DWORD ntstatus_t;
+
+/* pointers to those types */
+typedef	BYTE *LPBYTE;
+typedef	WORD *LPWORD;
+typedef	DWORD *LPDWORD;
+
+/* Note: Internally, this is always a UTF-8 string. */
 typedef	uint8_t *LPTSTR;
-typedef	uint8_t *LPBYTE;
-typedef	uint16_t *LPWORD;
-typedef	uint32_t *LPDWORD;
 
 #endif /* UNSIGNED_TYPES_DEFINED */
 
 
+/* XXX This does not really belong here... */
 #ifndef ANY_SIZE_ARRAY
 #define	ANY_SIZE_ARRAY  1
 #endif /* ANY_SIZE_ARRAY */
 
-/*
- * Opaque context handle.
- */
-#ifndef CONTEXT_HANDLE
-#define	CONTEXT_HANDLE(NAME)	\
-	struct NAME {		\
-		DWORD data1;    \
-		DWORD data2;    \
-		WORD  data3[2]; \
-		BYTE  data4[8];	\
-	};			\
-	typedef struct NAME
-#endif /* CONTEXT_HANDLE */
+/* CONTEXT_HANDLE now in ndrtypes.ndl */
 
-
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* _SMBSRV_WINTYPES_H */
+#endif /* _SMB_WINTYPES_H */
