--- old/usr/src/cmd/fs.d/smbclnt/smbutil/Makefile	Sun Mar 18 01:13:11 2018
+++ new/usr/src/cmd/fs.d/smbclnt/smbutil/Makefile	Sun Mar 18 01:13:11 2018
@@ -23,6 +23,8 @@
 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
+# Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+#
 
 #
 # cmd/fs.d/smbclnt/smbutil/Makefile
@@ -30,18 +32,22 @@
 
 PROG=		smbutil
 
-include		$(SRC)/cmd/Makefile.cmd
+OBJS=   smbutil.o info.o login.o lookup.o print.o status.o view.o \
+	shares_rap.o shares_rpc.o srvsvc1_clnt.o srvsvc1_ndr.o
 
-OBJS=   smbutil.o login.o lookup.o print.o status.o view.o
-
 SRCS=	$(OBJS:%.o=%.c)
+
+include		$(SRC)/cmd/Makefile.cmd
+
 POFILE=	smbutil_all.po
 POFILES= $(OBJS:%.o=%.po)
+
+CLEANFILES +=  srvsvc1_ndr.c
 CLOBBERFILES+=  $(POFILE) $(POFILES)
 
 CSTD= $(CSTD_GNU99)
 
-LDLIBS += -lsmbfs -lnsl
+LDLIBS += -lmlrpc -lsmbfs -lnsl
 
 CPPFLAGS += -I$(SRC)/lib/libsmbfs \
 	-I$(SRC)/uts/common/smbclnt -I$(SRC)/uts/common
@@ -78,9 +84,12 @@
 
 lint:	lint_SRCS
 
-clean :
-	$(RM) $(OBJS)
+clean:
+	$(RM) $(OBJS) $(CLEANFILES)
 
-.KEEP_STATE:
-
 include ../../../Makefile.targ
+
+srvsvc1_ndr.c : srvsvc1.ndl
+	$(NDRGEN) -Y $(ANSI_CPP) $(CPPFLAGS) srvsvc1.ndl
+
+.KEEP_STATE:
--- old/usr/src/cmd/fs.d/smbclnt/smbutil/common.h	Sun Mar 18 01:13:11 2018
+++ new/usr/src/cmd/fs.d/smbclnt/smbutil/common.h	Sun Mar 18 01:13:11 2018
@@ -30,6 +30,10 @@
  * SUCH DAMAGE.
  */
 
+/*
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
+
 #ifndef _SMBUTIL_COMMON_H
 #define	_SMBUTIL_COMMON_H
 
@@ -42,6 +46,7 @@
 
 int  cmd_crypt(int argc, char *argv[]);
 int  cmd_help(int argc, char *argv[]);
+int  cmd_info(int argc, char *argv[]);
 int  cmd_login(int argc, char *argv[]);
 int  cmd_logout(int argc, char *argv[]);
 int  cmd_logoutall(int argc, char *argv[]);
@@ -50,8 +55,9 @@
 int  cmd_status(int argc, char *argv[]);
 int  cmd_view(int argc, char *argv[]);
 
-/* No crypt_usage? */
+void crypt_usage(void);
 void help_usage(void);
+void info_usage(void);
 void login_usage(void);
 void logout_usage(void);
 void logoutall_usage(void);
@@ -60,7 +66,10 @@
 void status_usage(void);
 void view_usage(void);
 
-extern int loadsmbvfs();
+/* See view.c */
+int share_enum_rap(struct smb_ctx *ctx);
+int share_enum_rpc(struct smb_ctx *ctx, char *server);
+void view_print_share(char *share, int type, char *comment);
 
 #ifdef __cplusplus
 }
--- /dev/null	Sun Mar 18 01:13:11 2018
+++ new/usr/src/cmd/fs.d/smbclnt/smbutil/info.c	Sun Mar 18 01:13:11 2018
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+
+/*
+ * Show information about the remote server, as offered by
+ * NetServerGetInfo with SERVER_INFO_101
+ */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libintl.h>
+
+#include <libmlrpc/libmlrpc.h>
+#include <netsmb/smb_lib.h>
+#include "srvsvc1_clnt.h"
+#include "common.h"
+
+
+static int get_info(smb_ctx_t *);
+
+void
+info_usage(void)
+{
+	printf(gettext("usage: smbutil info [connection options] //"
+	    "[workgroup;][user[:password]@]server\n"));
+	exit(1);
+}
+
+int
+cmd_info(int argc, char *argv[])
+{
+	struct smb_ctx *ctx;
+	int error, err2, opt;
+
+	if (argc < 2)
+		info_usage();
+
+	error = smb_ctx_alloc(&ctx);
+	if (error)
+		return (error);
+
+	error = smb_ctx_scan_argv(ctx, argc, argv,
+	    SMBL_SERVER, SMBL_SERVER, USE_WILDCARD);
+	if (error)
+		goto out;
+
+	error = smb_ctx_readrc(ctx);
+	if (error)
+		goto out;
+
+	while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
+		if (opt == '?')
+			info_usage();
+		error = smb_ctx_opt(ctx, opt, optarg);
+		if (error)
+			goto out;
+	}
+
+	smb_ctx_setshare(ctx, "IPC$", USE_IPC);
+
+	/*
+	 * Resolve the server address,
+	 * setup derived defaults.
+	 */
+	error = smb_ctx_resolve(ctx);
+	if (error)
+		goto out;
+
+	/*
+	 * Have server, share, etc. from above:
+	 * smb_ctx_scan_argv, option settings.
+	 * Get the session and tree.
+	 */
+again:
+	error = smb_ctx_get_ssn(ctx);
+	if (error == EAUTH) {
+		err2 = smb_get_authentication(ctx);
+		if (err2 == 0)
+			goto again;
+	}
+	if (error) {
+		smb_error(gettext("//%s: login failed"),
+		    error, ctx->ct_fullserver);
+		goto out;
+	}
+
+	error = smb_ctx_get_tree(ctx);
+	if (error) {
+		smb_error(gettext("//%s/%s: tree connect failed"),
+		    error, ctx->ct_fullserver, ctx->ct_origshare);
+		goto out;
+	}
+
+	/*
+	 * Have IPC$ tcon.  Get the server info.
+	 */
+	error = get_info(ctx);
+	if (error)
+		smb_error("cannot get server info.", error);
+
+out:
+	smb_ctx_free(ctx);
+	return (error);
+}
+
+int
+get_info(smb_ctx_t *ctx)
+{
+	char pf_unk[32];
+	mlrpc_handle_t handle;
+	ndr_service_t *svc;
+	union mslm_NetServerGetInfo_ru res;
+	struct mslm_SERVER_INFO_101 *sv101;
+	char *platform_name;
+	int err;
+
+	/*
+	 * Create an RPC handle using the smb_ctx we already have.
+	 * Just local allocation and initialization.
+	 */
+	srvsvc1_initialize();
+	svc = ndr_svc_lookup_name("srvsvc");
+	if (svc == NULL)
+		return (ENOENT);
+
+	err = mlrpc_clh_create(&handle, ctx);
+	if (err)
+		return (err);
+
+	/*
+	 * Try to bind to the RPC service.  If it fails,
+	 * just return the error and the caller will
+	 * fall back to RAP.
+	 */
+	err = mlrpc_clh_bind(&handle, svc);
+	if (err)
+		goto out;
+
+	err = srvsvc_net_server_getinfo(&handle,
+	    ctx->ct_fullserver, 101, &res);
+	if (err)
+		goto out;
+
+	sv101 = res.info101;
+
+	switch (sv101->sv101_platform_id) {
+	case SV_PLATFORM_ID_DOS:
+		platform_name = "DOS";
+		break;
+	case SV_PLATFORM_ID_OS2:
+		platform_name = "OS2";
+		break;
+	case SV_PLATFORM_ID_NT:
+		platform_name = "NT";
+		break;
+	case SV_PLATFORM_ID_OSF:
+		platform_name = "OSF";
+		break;
+	case SV_PLATFORM_ID_VMS:
+		platform_name = "VMS";
+		break;
+	default:
+		platform_name = pf_unk;
+		snprintf(pf_unk, sizeof (pf_unk), "(%d)",
+		    sv101->sv101_platform_id);
+		break;
+	}
+
+	printf("server info:\n");
+	printf(" platform_id %s\n", platform_name);
+	printf(" vers.major  %d\n", sv101->sv101_version_major);
+	printf(" vers.minor  %d\n", sv101->sv101_version_minor);
+
+	if (smb_verbose)
+		printf(" type_flags  0x%x\n", sv101->sv101_type);
+
+	printf(" name    \"%s\"\n", sv101->sv101_name);
+	printf(" comment \"%s\"\n", sv101->sv101_comment);
+
+out:
+	(void) mlrpc_clh_free(&handle);
+	return (err);
+}
--- /dev/null	Sun Mar 18 01:13:11 2018
+++ new/usr/src/cmd/fs.d/smbclnt/smbutil/shares_rap.c	Sun Mar 18 01:13:11 2018
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2000-2002, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Id: view.c,v 1.9 2002/02/20 09:26:42 bp Exp
+ */
+
+/*
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netsmb/mchain.h>	/* letohs, etc. */
+#include <netsmb/smb.h>
+#include <netsmb/smb_lib.h>
+#include <netsmb/smb_rap.h>
+
+#include "common.h"
+
+/*
+ * Enumerate shares using Remote Administration Protocol (RAP)
+ * Was in libsmbfs netshareenum.c
+ */
+
+struct smb_share_info_1 {
+	char		shi1_netname[13];
+	char		shi1_pad;
+	uint16_t	shi1_type;
+	uint32_t	shi1_remark;		/* char * */
+};
+
+static int
+smb_rap_NetShareEnum(struct smb_ctx *ctx, int sLevel, void *pbBuffer,
+	int *cbBuffer, int *pcEntriesRead, int *pcTotalAvail)
+{
+	struct smb_rap *rap;
+	long lval = -1;
+	int error;
+
+	error = smb_rap_create(0, "WrLeh", "B13BWz", &rap);
+	if (error)
+		return (error);
+	smb_rap_setNparam(rap, sLevel);		/* W - sLevel */
+	smb_rap_setPparam(rap, pbBuffer);	/* r - pbBuffer */
+	smb_rap_setNparam(rap, *cbBuffer);	/* L - cbBuffer */
+	error = smb_rap_request(rap, ctx);
+	if (error == 0) {
+		*pcEntriesRead = rap->r_entries;
+		error = smb_rap_getNparam(rap, &lval);
+		*pcTotalAvail = lval;
+		/* Copy the data length into the IN/OUT variable. */
+		*cbBuffer = rap->r_rcvbuflen;
+	}
+	error = smb_rap_error(rap, error);
+	smb_rap_done(rap);
+	return (error);
+}
+
+int
+share_enum_rap(smb_ctx_t *ctx)
+{
+	struct smb_share_info_1 *shi;
+	void *rpbuf;
+	char *cp;
+	int error, bufsize, i, rcnt, total;
+	int lbound, rbound;
+	uint16_t type;
+
+	bufsize = 0xffe0;	/* samba notes win2k bug for 65535 */
+	rpbuf = malloc(bufsize);
+	if (rpbuf == NULL)
+		return (errno);
+
+	error = smb_rap_NetShareEnum(ctx, 1, rpbuf, &bufsize, &rcnt, &total);
+	if (error &&
+	    error != (ERROR_MORE_DATA | SMB_RAP_ERROR))
+		goto out;
+
+	/*
+	 * Bounds for offsets to comments strings.
+	 * After the array, and before the end.
+	 */
+	lbound = rcnt * (sizeof (struct smb_share_info_1));
+	rbound = bufsize;
+
+	/* Print the header line. */
+	view_print_share(NULL, 0, NULL);
+
+	for (shi = rpbuf, i = 0; i < rcnt; i++, shi++) {
+		type = letohs(shi->shi1_type);
+
+		shi->shi1_pad = '\0'; /* ensure null termination */
+
+		/*
+		 * Offsets to comment strings can be trash.
+		 * Only print when the offset is valid.
+		 */
+		if (shi->shi1_remark >= lbound &&
+		    shi->shi1_remark < rbound) {
+			cp = (char *)rpbuf + shi->shi1_remark;
+		} else
+			cp = NULL;
+
+		/* Convert from OEM to local codeset? */
+		view_print_share(shi->shi1_netname, type, cp);
+	}
+	error = 0;
+
+out:
+	free(rpbuf);
+	return (error);
+}
--- /dev/null	Sun Mar 18 01:13:11 2018
+++ new/usr/src/cmd/fs.d/smbclnt/smbutil/shares_rpc.c	Sun Mar 18 01:13:11 2018
@@ -0,0 +1,83 @@
+/*
+ * 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 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
+
+/*
+ * Share enumeration using Remote Procedure Call (RPC)
+ */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libmlrpc/libmlrpc.h>
+#include <netsmb/smbfs_api.h>
+#include "srvsvc1_clnt.h"
+#include "common.h"
+
+int
+share_enum_rpc(struct smb_ctx *ctx, char *server)
+{
+	mlrpc_handle_t handle;
+	ndr_service_t *svc;
+	union mslm_NetShareEnum_ru res;
+	struct mslm_NetShareInfo_1 *nsi1;
+	int err, i, count;
+
+	/*
+	 * Create an RPC handle using the smb_ctx we already have.
+	 * Just local allocation and initialization.
+	 */
+	srvsvc1_initialize();
+	svc = ndr_svc_lookup_name("srvsvc");
+	if (svc == NULL)
+		return (ENOENT);
+
+	err = mlrpc_clh_create(&handle, ctx);
+	if (err)
+		return (err);
+
+	/*
+	 * Try to bind to the RPC service.  If it fails,
+	 * just return the error and the caller will
+	 * fall back to RAP.
+	 */
+	err = mlrpc_clh_bind(&handle, svc);
+	if (err)
+		goto out;
+
+	err = srvsvc_net_share_enum(&handle, server, 1, &res);
+	if (err)
+		goto out;
+
+	/* Print the header line. */
+	view_print_share(NULL, 0, NULL);
+
+	/* Print the share list. */
+	count = res.bufptr1->entriesread;
+	i = 0, nsi1 = res.bufptr1->entries;
+	while (i < count) {
+		/* Convert UTF-8 to local code set? */
+		view_print_share((char *)nsi1->shi1_netname,
+		    nsi1->shi1_type, (char *)nsi1->shi1_comment);
+		i++, nsi1++;
+	}
+
+out:
+	(void) mlrpc_clh_free(&handle);
+	return (err);
+}
--- old/usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c	Sun Mar 18 01:13:11 2018
+++ new/usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c	Sun Mar 18 01:13:11 2018
@@ -33,6 +33,8 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <sys/param.h>
@@ -70,6 +72,7 @@
 } commands[] = {
 	{"crypt",	cmd_crypt,	NULL, CMDFL_NO_KMOD},
 	{"help",	cmd_help,	help_usage, CMDFL_NO_KMOD},
+	{"info",	cmd_info,	info_usage, 0},
 	{"login",	cmd_login,	login_usage, 0},
 	{"logout",	cmd_logout,	logout_usage, 0},
 	{"logoutall",	cmd_logoutall,	logoutall_usage, 0},
@@ -189,6 +192,7 @@
 	" crypt		slightly obscure password\n"
 	" help		display help on specified subcommand\n"
 	/* " lc 		display active connections\n" */
+	" info		display server type and version\n"
 	" login		login to specified host\n"
 	" logout 	logout from specified host\n"
 	" logoutall	logout all users (requires privilege)\n"
--- /dev/null	Sun Mar 18 01:13:11 2018
+++ new/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1.ndl	Sun Mar 18 01:13:11 2018
@@ -0,0 +1,177 @@
+/*
+ * 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 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
+
+/*
+ * SRVSVC - Server Service (partial)
+ *
+ * This module needs only NetShareEnum (levels 0, 1)
+ * and NetServerGetInfo (levels 100, 101)
+ */
+
+#include <libmlrpc/ndrtypes.ndl>
+
+/*
+ * SRVSVC - Server Service
+ */
+
+#define SRVSVC_OPNUM_NetShareEnum                0x0f
+#define SRVSVC_OPNUM_NetServerGetInfo            0x15
+
+/*
+ * SRVSVC NetShareEnum (
+ *	IN  LPTSTR	servername,
+ *	IN  DWORD	level;
+ *	OUT union switch(level) {
+ *		case 0: struct {
+ *				DWORD entriesread;
+ *			     [size_is(entriesread)]
+ *				_SHARE_INFO_0 *entries;
+ *			} *bufptr0;
+ *		case 1: struct {
+ *				DWORD entriesread;
+ *			     [size_is(entriesread)]
+ *				_SHARE_INFO_1 *entries;
+ *			} *bufptr1;
+ *		...
+ *	    }		bufptr,
+ *	IN  DWORD	prefmaxlen,
+ *	OUT DWORD	totalentries,
+ *	IN OUT DWORD ?*	resume_handle,
+ *	OUT DWORD	status
+ *      )
+ */
+
+struct mslm_NetShareInfo_0 {
+	LPTSTR shi0_netname;
+};
+struct mslm_NetShareInfo_0_result {
+	DWORD	entriesread;
+	SIZE_IS(entriesread)
+	struct mslm_NetShareInfo_0 *entries;
+};
+
+struct mslm_NetShareInfo_1 {
+	LPTSTR	shi1_netname;
+	DWORD	shi1_type; /* type of resource such as IPC$ */
+	LPTSTR	shi1_comment;
+};
+struct mslm_NetShareInfo_1_result {
+	DWORD	entriesread;
+	SIZE_IS(entriesread)
+	struct mslm_NetShareInfo_1 *entries;
+};
+
+union mslm_NetShareEnum_ru {
+	CASE(0)		struct mslm_NetShareInfo_0_result *bufptr0;
+	CASE(1)		struct mslm_NetShareInfo_1_result *bufptr1;
+	DEFAULT		char *nullptr;
+};
+struct mslm_NetShareEnum_result {
+	DWORD	level;
+	SWITCH(level)
+	union mslm_NetShareEnum_ru ru;
+};
+
+
+OPERATION(SRVSVC_OPNUM_NetShareEnum)
+struct mslm_NetShareEnum {
+	IN  		LPTSTR	servername;
+	INOUT  		DWORD	level;
+	INOUT 		struct mslm_NetShareEnum_result result;
+	IN  		DWORD	prefmaxlen;
+	OUT 		DWORD	totalentries;
+	INOUT 		DWORD	*resume_handle;
+	OUT 		DWORD	status;
+};
+
+
+/*
+ * SRVSVC NetServerGetInfo (
+ *	IN LPTSTR	servername,
+ *	IN DWORD	level,
+ *	OUT union switch(level) {
+ *		case 100: _SERVER_INFO_100 *	p100;
+ *		case 101: _SERVER_INFO_101 *	p101;
+ *		case 102: _SERVER_INFO_102 *	p102;
+ *	    }		bufptr,
+ *	OUT DWORD	status
+ *      )
+ */
+
+/* for svX_platform (note: decimal!) */
+#define	SV_PLATFORM_ID_DOS	300
+#define	SV_PLATFORM_ID_OS2	400
+#define	SV_PLATFORM_ID_NT	500
+#define	SV_PLATFORM_ID_OSF	600
+#define	SV_PLATFORM_ID_VMS	700
+
+struct mslm_SERVER_INFO_100 {
+	DWORD		sv100_platform_id;
+	LPTSTR		sv100_name;
+};
+
+struct mslm_SERVER_INFO_101 {
+	DWORD		sv101_platform_id;
+	LPTSTR		sv101_name;
+	DWORD		sv101_version_major;
+	DWORD		sv101_version_minor;
+	DWORD		sv101_type;
+	LPTSTR		sv101_comment;
+};
+
+union mslm_NetServerGetInfo_ru {
+	CASE(100)	struct mslm_SERVER_INFO_100 *info100;
+	CASE(101)	struct mslm_SERVER_INFO_101 *info101;
+	DEFAULT		char *nullptr;
+};
+
+struct mslm_NetServerGetInfo_result {
+	DWORD level;
+	SWITCH(level)
+	union mslm_NetServerGetInfo_ru ru;
+};
+
+
+OPERATION(SRVSVC_OPNUM_NetServerGetInfo)
+struct mslm_NetServerGetInfo {
+	IN  LPTSTR	servername;
+	IN  DWORD	level;
+	OUT struct mslm_NetServerGetInfo_result result;
+	OUT DWORD	status;
+};
+
+
+/*
+ * The SRVSVC interface
+ */
+INTERFACE(0)
+union srvsvc_interface {
+	CASE(SRVSVC_OPNUM_NetShareEnum)
+		struct mslm_NetShareEnum	NetShareEnum;
+	CASE(SRVSVC_OPNUM_NetServerGetInfo)
+		struct mslm_NetServerGetInfo	NetServerGetInfo;
+};
+typedef union srvsvc_interface	srvsvc_interface_t;
+EXTERNTYPEINFO(srvsvc_interface)
--- /dev/null	Sun Mar 18 01:13:11 2018
+++ new/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1_clnt.c	Sun Mar 18 01:13:11 2018
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+/*
+ * A few excerpts from lib/smbsrv/libmlsvc
+ * See longer comment in srvsvc1.ndl
+ */
+
+#include <sys/errno.h>
+#include <stdio.h>
+#include <time.h>
+#include <strings.h>
+#include <time.h>
+
+#include <libmlrpc/libmlrpc.h>
+#include "srvsvc1_clnt.h"
+
+static ndr_service_t srvsvc_service = {
+	"SRVSVC",			/* name */
+	"Server services",		/* desc */
+	"\\srvsvc",			/* endpoint */
+	"\\PIPE\\ntsvcs",		/* sec_addr_port */
+	"4b324fc8-1670-01d3-1278-5a47bf6ee188", 3,	/* abstract */
+	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
+	0,				/* no bind_instance_size */
+	0,				/* no bind_req() */
+	0,				/* no unbind_and_close() */
+	0,				/* use generic_call_stub() */
+	&TYPEINFO(srvsvc_interface),	/* interface_ti */
+	NULL				/* stub_table */
+};
+
+/*
+ * srvsvc_initialize
+ *
+ * This function registers the SRVSVC RPC interface with the RPC runtime
+ * library. It must be called in order to use either the client side
+ * or the server side functions.
+ */
+void
+srvsvc1_initialize(void)
+{
+	static int init_done;
+	if (init_done)
+		return;
+	init_done = 1;
+	(void) ndr_svc_register(&srvsvc_service);
+}
+
+/*
+ * Client-side stub for NetServerGetInfo
+ */
+int
+srvsvc_net_server_getinfo(mlrpc_handle_t *handle, char *server,
+	int level, union mslm_NetServerGetInfo_ru *resp)
+{
+	struct mslm_NetServerGetInfo arg;
+	int len, opnum, rc;
+
+	opnum = SRVSVC_OPNUM_NetServerGetInfo;
+	bzero(&arg, sizeof (arg));
+
+	len = strlen(server) + 4;
+	arg.servername = ndr_rpc_malloc(handle, len);
+	if (arg.servername == NULL)
+		return (ENOMEM);
+
+	(void) snprintf((char *)arg.servername, len, "\\\\%s", server);
+	arg.level = level;
+
+	rc = ndr_rpc_call(handle, opnum, &arg);
+	if ((rc != 0) || (arg.status != 0))
+		return (EIO);
+
+	*resp = arg.result.ru;
+	return (0);
+}
+
+/*
+ * Client-side stub for NetShareEnum
+ */
+int
+srvsvc_net_share_enum(mlrpc_handle_t *handle, char *server,
+	int level, union mslm_NetShareEnum_ru *resp)
+{
+	/* Any enum result type is OK for nres. */
+	struct mslm_NetShareInfo_0_result nres;
+	struct mslm_NetShareEnum arg;
+	int len, opnum, rc;
+
+	opnum = SRVSVC_OPNUM_NetShareEnum;
+	bzero(&nres, sizeof (nres));
+	bzero(&arg, sizeof (arg));
+
+	len = strlen(server) + 4;
+	arg.servername = ndr_rpc_malloc(handle, len);
+	if (arg.servername == NULL)
+		return (ENOMEM);
+
+	(void) snprintf((char *)arg.servername, len, "\\\\%s", server);
+	arg.level = level;
+	arg.result.level = level;
+	arg.result.ru.bufptr0 = &nres;
+	arg.prefmaxlen = 0xFFFFFFFF;
+	arg.resume_handle = NULL;
+
+	rc = ndr_rpc_call(handle, opnum, &arg);
+	if ((rc != 0) || (arg.status != 0))
+		return (EIO);
+
+	*resp = arg.result.ru;
+	return (0);
+}
--- /dev/null	Sun Mar 18 01:13:11 2018
+++ new/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1_clnt.h	Sun Mar 18 01:13:11 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 _SRVSVC1_CLNT_H
+#define	_SRVSVC1_CLNT_H
+
+/*
+ * Excerpts from lib/smbsrv/libmlsvc
+ * Just enough for share enumeration.
+ */
+
+#include <libmlrpc/libmlrpc.h>
+#include "srvsvc1.ndl"
+
+void srvsvc1_initialize(void);
+int srvsvc_net_share_enum(mlrpc_handle_t *handle, char *server,
+	int level, union mslm_NetShareEnum_ru *resp);
+int srvsvc_net_server_getinfo(mlrpc_handle_t *handle, char *server,
+	int level, union mslm_NetServerGetInfo_ru *resp);
+
+#endif	/* _SRVSVC1_CLNT_H */
--- old/usr/src/cmd/fs.d/smbclnt/smbutil/view.c	Sun Mar 18 01:13:12 2018
+++ new/usr/src/cmd/fs.d/smbclnt/smbutil/view.c	Sun Mar 18 01:13:12 2018
@@ -34,6 +34,7 @@
 
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <sys/types.h>
@@ -48,12 +49,9 @@
 
 #include <netsmb/smb.h>
 #include <netsmb/smb_lib.h>
-#include <netsmb/smb_netshareenum.h>
-
 #include "common.h"
 
-int enum_shares(smb_ctx_t *);
-void print_shares(int, int, struct share_info *);
+static int use_rap;
 
 void
 view_usage(void)
@@ -79,18 +77,27 @@
 	error = smb_ctx_scan_argv(ctx, argc, argv,
 	    SMBL_SERVER, SMBL_SERVER, USE_WILDCARD);
 	if (error)
-		return (error);
+		goto out;
 
 	error = smb_ctx_readrc(ctx);
 	if (error)
-		return (error);
+		goto out;
 
 	while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
 		if (opt == '?')
 			view_usage();
+		/*
+		 * This is an undocumented option, just for testing.
+		 * Use the old LanMan Remote API Protocol (RAP) for
+		 * enumerating shares.
+		 */
+		if (opt == 'B') {
+			use_rap++;
+			continue;
+		}
 		error = smb_ctx_opt(ctx, opt, optarg);
 		if (error)
-			return (error);
+			goto out;
 	}
 
 	smb_ctx_setshare(ctx, "IPC$", USE_IPC);
@@ -101,7 +108,7 @@
 	 */
 	error = smb_ctx_resolve(ctx);
 	if (error)
-		return (error);
+		goto out;
 
 	/*
 	 * Have server, share, etc. from above:
@@ -118,7 +125,7 @@
 	if (error) {
 		smb_error(gettext("//%s: login failed"),
 		    error, ctx->ct_fullserver);
-		return (error);
+		goto out;
 	}
 
 	error = smb_ctx_get_tree(ctx);
@@ -125,17 +132,19 @@
 	if (error) {
 		smb_error(gettext("//%s/%s: tree connect failed"),
 		    error, ctx->ct_fullserver, ctx->ct_origshare);
-		return (error);
+		goto out;
 	}
 
 	/*
 	 * Have IPC$ tcon, now list shares.
-	 * This prints its own errors.
+	 * Try RPC; if that fails, do RAP.
 	 */
-	error = enum_shares(ctx);
-	if (error)
-		return (error);
+	if (!use_rap)
+		error = share_enum_rpc(ctx, ctx->ct_fullserver);
+	if (error || use_rap)
+		error = share_enum_rap(ctx);
 
+out:
 	smb_ctx_free(ctx);
 	return (0);
 }
@@ -158,48 +167,29 @@
 };
 #endif
 
-int
-enum_shares(smb_ctx_t *ctx)
+/*
+ * Print one line of the share list, or
+ * if SHARE is null, print the header line.
+ */
+void
+view_print_share(char *share, int type, char *comment)
 {
-	struct share_info *share_info;
-	int error, entries, total;
+	char *stname;
+	int stindex;
 
-	/*
-	 * XXX: Later, try RPC first,
-	 * then fall back to RAP...
-	 */
-	error = smb_netshareenum(ctx, &entries, &total, &share_info);
-	if (error) {
-		smb_error(gettext("//%s failed to list shares"),
-		    error, ctx->ct_fullserver);
-		return (error);
+	if (share == NULL) {
+		printf(gettext("Share        Type       Comment\n"));
+		printf("-------------------------------\n");
+		return;
 	}
-	print_shares(entries, total, share_info);
-	return (0);
-}
 
-void
-print_shares(int entries, int total,
-	struct share_info *share_info)
-{
-	struct share_info *ep;
-	int i;
+	stindex = type & STYPE_MASK;
+	if (stindex > STYPE_UNKNOWN)
+		stindex = STYPE_UNKNOWN;
+	stname = gettext(shtype[stindex]);
 
-	printf(gettext("Share        Type       Comment\n"));
-	printf("-------------------------------\n");
+	if (comment == NULL)
+		comment = "";
 
-	for (ep = share_info, i = 0; i < entries; i++, ep++) {
-		int sti = ep->type & STYPE_MASK;
-		if (sti > STYPE_UNKNOWN)
-			sti = STYPE_UNKNOWN;
-		printf("%-12s %-10s %s\n", ep->netname,
-		    gettext(shtype[sti]),
-		    ep->remark ? ep->remark : "");
-		free(ep->netname);
-		free(ep->remark);
-	}
-	printf(gettext("\n%d shares listed from %d available\n"),
-	    entries, total);
-
-	free(share_info);
+	printf("%-12s %-10s %s\n", share, stname, comment);
 }
--- old/usr/src/lib/libsmbfs/Makefile.com	Sun Mar 18 01:13:12 2018
+++ new/usr/src/lib/libsmbfs/Makefile.com	Sun Mar 18 01:13:12 2018
@@ -59,7 +59,6 @@
 	nb_ssn.o \
 	nbns_rq.o \
 	negprot.o \
-	netshareenum.o \
 	newvc.o \
 	nls.o \
 	ntlm.o \
--- old/usr/src/lib/libsmbfs/netsmb/smb_netshareenum.h	Sun Mar 18 01:13:12 2018
+++ /dev/null	Sun Mar 18 01:13:11 2018
@@ -1,18 +0,0 @@
-
-#ifndef _NETSMB_SMB_NETSHAREENUM_H_
-#define	_NETSMB_SMB_NETSHAREENUM_H_
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/* This is from Apple.  See ../smb/netshareenum.c */
-
-struct share_info {
-	uint16_t	type;
-	char		*netname;
-	char		*remark;
-};
-typedef struct share_info share_info_t;
-
-int  smb_netshareenum(struct smb_ctx *, int *, int *, struct share_info **);
-
-#endif /* _NETSMB_SMB_NETSHAREENUM_H_ */
--- old/usr/src/lib/libsmbfs/smb/llib-lsmbfs	Sun Mar 18 01:13:12 2018
+++ new/usr/src/lib/libsmbfs/smb/llib-lsmbfs	Sun Mar 18 01:13:12 2018
@@ -34,7 +34,6 @@
 
 #include <netsmb/smb_lib.h>
 #include <netsmb/smb_keychain.h>
-#include <netsmb/smb_netshareenum.h>
 #include <netsmb/smb_rap.h>
 #include <netsmb/spnego.h>
 
--- old/usr/src/lib/libsmbfs/smb/mapfile-vers	Sun Mar 18 01:13:12 2018
+++ new/usr/src/lib/libsmbfs/smb/mapfile-vers	Sun Mar 18 01:13:12 2018
@@ -111,7 +111,6 @@
 	smb_iod_start;
 	smb_iod_work;
 	smb_lib_init;
-	smb_netshareenum;	# will move to libnetapi
 	smb_open_printer;
 	smb_open_rcfile;
 	smb_simplecrypt;
--- old/usr/src/lib/libsmbfs/smb/netshareenum.c	Sun Mar 18 01:13:12 2018
+++ /dev/null	Sun Mar 18 01:13:11 2018
@@ -1,378 +0,0 @@
-/*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/* BEGIN CSTYLED */
-/*
- *      @(#)ui.c      *
- *      (c) 2004   Apple Computer, Inc.  All Rights Reserved
- *
- *
- *      netshareenum.c -- Routines for getting a list of share information
- *			  from a server.
- *
- *      MODIFICATION HISTORY:
- *       27-Nov-2004     Guy Harris	New today
- */
-/* END CSTYLED */
-
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include <netsmb/mchain.h>
-#include <netsmb/smb.h>
-#include <netsmb/smb_lib.h>
-#include <netsmb/smb_rap.h>
-#include <netsmb/smb_netshareenum.h>
-#include <smb/charsets.h>
-
-#if 0 /* XXX see below */
-#include <dce/exc_handling.h>
-#include <rpc/attrb.h>
-#include "srvsvc.h"
-#endif
-
-/*
- * Don't want RPC client-side code in here.
- * It's good code; just doesn't belong here.
- *
- * The API provided by this library should be
- * just files and pipes (and not much more).
- * It MAY be useful to provide some of the
- * RAP (remote API) functions functions like
- * rap_netshareenum below...
- *
- * XXX: Not sure this file belongs here at all.
- * smb_rap.h looks like a reasonable API
- * for this library to export.
- */
-#if 0 /* XXX */
-
-static int
-rpc_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
-    struct share_info **entries_listp)
-{
-	char ctx_string[2+16+1];	/* enough for 64-bit pointer, in hex */
-	unsigned_char_p_t binding;
-	unsigned32 binding_status;
-	rpc_binding_handle_t binding_h;
-	int error, i, entries;
-	char *addrstr, *srvnamestr;
-	unsigned short *usrvnamestr;
-	unsigned32 level;
-	SHARE_ENUM_STRUCT share_info;
-	SHARE_INFO_1_CONTAINER share_info_1_container;
-	SHARE_INFO_1 *shares, *share;
-	unsigned32 total_entries;
-	unsigned32 status, free_status;
-	struct share_info *entry_list, *elp;
-	static EXCEPTION rpc_x_connect_rejected;
-	static int exceptions_initialized;
-
-	sprintf(ctx_string, "%p", ctx);
-	rpc_string_binding_compose(NULL, "ncacn_np", ctx_string,
-	    "srvsvc", NULL, &binding, &binding_status);
-	if (binding_status != rpc_s_ok) {
-		smb_error(dgettext(TEXT_DOMAIN,
-		    "rpc_string_binding_compose failed with %d"),
-		    0, binding_status);
-		return (EINVAL);
-	}
-	rpc_binding_from_string_binding(binding, &binding_h, &status);
-	rpc_string_free(&binding, (unsigned32 *)&free_status);
-	if (binding_status != rpc_s_ok) {
-		smb_error(dgettext(TEXT_DOMAIN,
-		    "rpc_binding_from_string_binding failed with %d"), 0,
-		    binding_status);
-		return (EINVAL);
-	}
-	level = 1;
-	share_info.share_union.level = 1;
-	share_info.share_union.tagged_union.share1 = &share_info_1_container;
-	share_info_1_container.share_count = 0;
-	share_info_1_container.shares = NULL;
-	/*
-	 * Convert the server IP address to a string, and send that as
-	 * the "server name" - that's what Windows appears to do, and
-	 * that avoids problems with NetBIOS names containing
-	 * non-ASCII characters.
-	 */
-	addrstr = inet_ntoa(ctx->ct_srvinaddr.sin_addr);
-	srvnamestr = malloc(strlen(addrstr) + 3);
-	if (srvnamestr == NULL) {
-		status = errno;
-		smb_error(dgettext(TEXT_DOMAIN,
-		    "can't allocate string for server address"), status);
-		rpc_binding_free(&binding_h, &free_status);
-		return (status);
-	}
-	strcpy(srvnamestr, "\\\\");
-	strcat(srvnamestr, addrstr);
-	usrvnamestr = convert_utf8_to_leunicode(srvnamestr);
-	if (usrvnamestr == NULL) {
-		smb_error(dgettext(TEXT_DOMAIN,
-		    "can't convert string for server address to Unicode"), 0);
-		rpc_binding_free(&binding_h, &free_status);
-		free(srvnamestr);
-		return (EINVAL);
-	}
-	if (!exceptions_initialized) {
-		EXCEPTION_INIT(rpc_x_connect_rejected);
-		exc_set_status(&rpc_x_connect_rejected, rpc_s_connect_rejected);
-		exceptions_initialized = 1;
-	}
-	/* printf("Calling NetrShareEnum.."); XXX */
-	TRY
-		status = NetrShareEnum(binding_h, usrvnamestr, &level,
-		    &share_info, 4294967295U, &total_entries, NULL);
-		if (status != 0)
-			smb_error(dgettext(TEXT_DOMAIN,
-			    "error from NetrShareEnum call: status = 0x%08x"),
-			    0, status);
-	/*CSTYLED*/
-	CATCH (rpc_x_connect_rejected)
-		/*
-		 * This is what we get if we can't open the pipe.
-		 * That's a normal occurrence when we're talking
-		 * to a system that (presumably) doesn't support
-		 * DCE RPC on the server side, such as Windows 95/98/Me,
-		 * so we don't log an error.
-		 */
-		/*CSTYLED*/
-		status = ENOTSUP;
-	CATCH_ALL
-		/*
-		 * XXX - should we handle some exceptions differently,
-		 * returning different errors, and try RAP only for
-		 * ENOTSUP?
-		 */
-		smb_error(dgettext(TEXT_DOMAIN,
-		    "error from NetrShareEnum call: exception = %u"),
-		    0, THIS_CATCH->match.value);
-		status = ENOTSUP;
-	ENDTRY
-	rpc_binding_free(&binding_h, &free_status);
-	free(srvnamestr);
-	free(usrvnamestr);
-	if (status != 0)
-		return (ENOTSUP);
-
-	/*
-	 * XXX - if the IDL is correct, it's not clear whether the
-	 * unmarshalling code will properly handle the case where
-	 * a packet where "share_count" and the max count for the
-	 * array of shares don't match; a valid DCE RPC implementation
-	 * won't marshal something like that, but there's no guarantee
-	 * that the server we're talking to has a valid implementation
-	 * (which could be a *malicious* implementation!).
-	 */
-	entries = share_info.share_union.tagged_union.share1->share_count;
-	shares = share_info.share_union.tagged_union.share1->shares;
-	entry_list = calloc(entries, sizeof (struct share_info));
-	if (entry_list == NULL) {
-		error = errno;
-		goto cleanup_and_return;
-	}
-	for (share = shares, elp = entry_list, i = 0; i < entries;
-	    i++, share++) {
-		elp->type = share->shi1_type;
-		elp->netname = convert_unicode_to_utf8(share->shi1_share);
-		if (elp->netname == NULL)
-			goto fail;
-		elp->remark = convert_unicode_to_utf8(share->shi1_remark);
-		if (elp->remark == NULL)
-			goto fail;
-		elp++;
-	}
-	*entriesp = entries;
-	*totalp = total_entries;
-	*entries_listp = entry_list;
-	error = 0;
-	goto cleanup_and_return;
-
-fail:
-	error = errno;
-	for (elp = entry_list, i = 0; i < entries; i++, elp++) {
-		/*
-		 * elp->netname is set before elp->remark, so if
-		 * elp->netname is null, elp->remark is also null.
-		 * If either of them is null, we haven't done anything
-		 * to any entries after this one.
-		 */
-		if (elp->netname == NULL)
-			break;
-		free(elp->netname);
-		if (elp->remark == NULL)
-			break;
-		free(elp->remark);
-	}
-	free(entry_list);
-
-cleanup_and_return:
-	for (share = shares, i = 0; i < entries; i++, share++) {
-		free(share->shi1_share);
-		free(share->shi1_remark);
-	}
-	free(shares);
-	/*
-	 * XXX - "share1" should be a unique pointer, but we haven't
-	 * changed the marshalling code to support non-full pointers
-	 * in unions, so we leave it as a full pointer.
-	 *
-	 * That means that this might, or might not, be changed from
-	 * pointing to "share_info_1_container" to pointing to a
-	 * mallocated structure, according to the DCE RPC 1.1 IDL spec;
-	 * we free it only if it's changed.
-	 */
-	if (share_info.share_union.tagged_union.share1 !=
-	    &share_info_1_container)
-		free(share_info.share_union.tagged_union.share1);
-	return (error);
-}
-#endif /* XXX */
-
-/*
- * Enumerate shares using RAP
- */
-
-struct smb_share_info_1 {
-	char		shi1_netname[13];
-	char		shi1_pad;
-	uint16_t	shi1_type;
-	uint32_t	shi1_remark;		/* char * */
-};
-
-static int
-smb_rap_NetShareEnum(struct smb_ctx *ctx, int sLevel, void *pbBuffer,
-	int *cbBuffer, int *pcEntriesRead, int *pcTotalAvail)
-{
-	struct smb_rap *rap;
-	long lval = -1;
-	int error;
-
-	error = smb_rap_create(0, "WrLeh", "B13BWz", &rap);
-	if (error)
-		return (error);
-	(void) smb_rap_setNparam(rap, sLevel);		/* W - sLevel */
-	(void) smb_rap_setPparam(rap, pbBuffer);	/* r - pbBuffer */
-	(void) smb_rap_setNparam(rap, *cbBuffer);	/* L - cbBuffer */
-	error = smb_rap_request(rap, ctx);
-	if (error == 0) {
-		*pcEntriesRead = rap->r_entries;
-		error = smb_rap_getNparam(rap, &lval);
-		*pcTotalAvail = lval;
-		/* Copy the data length into the IN/OUT variable. */
-		*cbBuffer = rap->r_rcvbuflen;
-	}
-	error = smb_rap_error(rap, error);
-	smb_rap_done(rap);
-	return (error);
-}
-
-static int
-rap_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
-    struct share_info **entries_listp)
-{
-	int error, bufsize, i, entries, total, nreturned;
-	struct smb_share_info_1 *rpbuf, *ep;
-	struct share_info *entry_list, *elp;
-	char *cp;
-	int lbound, rbound;
-
-	bufsize = 0xffe0;	/* samba notes win2k bug for 65535 */
-	rpbuf = malloc(bufsize);
-	if (rpbuf == NULL)
-		return (errno);
-
-	error = smb_rap_NetShareEnum(ctx, 1, rpbuf, &bufsize, &entries, &total);
-	if (error &&
-	    error != (ERROR_MORE_DATA | SMB_RAP_ERROR)) {
-		free(rpbuf);
-		return (error);
-	}
-	entry_list = malloc(entries * sizeof (struct share_info));
-	if (entry_list == NULL) {
-		error = errno;
-		free(rpbuf);
-		return (error);
-	}
-	lbound = entries * (sizeof (struct smb_share_info_1));
-	rbound = bufsize;
-	for (ep = rpbuf, elp = entry_list, i = 0, nreturned = 0; i < entries;
-	    i++, ep++) {
-		elp->type = letohs(ep->shi1_type);
-		ep->shi1_pad = '\0'; /* ensure null termination */
-		elp->netname = convert_wincs_to_utf8(ep->shi1_netname);
-		if (elp->netname == NULL)
-			continue;	/* punt on this entry */
-		/*
-		 * Check for validity of offset.
-		 */
-		if (ep->shi1_remark >= lbound && ep->shi1_remark < rbound) {
-			cp = (char *)rpbuf + ep->shi1_remark;
-			elp->remark = convert_wincs_to_utf8(cp);
-		} else
-			elp->remark = NULL;
-		elp++;
-		nreturned++;
-	}
-	*entriesp = nreturned;
-	*totalp = total;
-	*entries_listp = entry_list;
-	free(rpbuf);
-	return (0);
-}
-
-/*
- * First we try the RPC-based NetrShareEnum, and, if that fails, we fall
- * back on the RAP-based NetShareEnum.
- */
-int
-smb_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
-    struct share_info **entry_listp)
-{
-	int error;
-
-#ifdef NOTYETDEFINED
-	/*
-	 * Try getting a list of shares with the SRVSVC RPC service.
-	 */
-	error = rpc_netshareenum(ctx, entriesp, totalp, entry_listp);
-	if (error == 0)
-		return (0);
-#endif
-
-	/*
-	 * OK, that didn't work - try RAP.
-	 * XXX - do so only if it failed because we couldn't open
-	 * the pipe?
-	 */
-	error = rap_netshareenum(ctx, entriesp, totalp, entry_listp);
-	return (error);
-}
--- old/usr/src/pkg/manifests/service-file-system-smb.mf	Sun Mar 18 01:13:12 2018
+++ new/usr/src/pkg/manifests/service-file-system-smb.mf	Sun Mar 18 01:13:12 2018
@@ -73,7 +73,6 @@
 file path=usr/kernel/kmdb/$(ARCH64)/smbsrv group=sys mode=0555
 file path=usr/lib/fs/smb/$(ARCH64)/libshare_smb.so.1
 file path=usr/lib/fs/smb/libshare_smb.so.1
-file path=usr/lib/libmlrpc.so.2
 file path=usr/lib/mdb/kvm/$(ARCH64)/smbsrv.so group=sys mode=0555
 file path=usr/lib/reparse/libreparse_smb.so.1
 file path=usr/lib/security/pam_smb_passwd.so.1
--- old/usr/src/pkg/manifests/system-file-system-smb.mf	Sun Mar 18 01:13:12 2018
+++ new/usr/src/pkg/manifests/system-file-system-smb.mf	Sun Mar 18 01:13:12 2018
@@ -79,6 +79,7 @@
 file path=usr/lib/fs/smbfs/share mode=0555
 file path=usr/lib/fs/smbfs/umount mode=4555
 file path=usr/lib/fs/smbfs/unshare mode=0555
+file path=usr/lib/libmlrpc.so.2
 file path=usr/lib/libsmbfs.so.1
 file path=usr/lib/mdb/kvm/$(ARCH64)/nsmb.so mode=0555
 file path=usr/lib/mdb/kvm/$(ARCH64)/smbfs.so mode=0555
