summaryrefslogtreecommitdiff
path: root/usr/src/cmd/fs.d/smbclnt
diff options
context:
space:
mode:
authorGordon Ross <gwr@nexenta.com>2017-08-12 10:54:18 -0400
committerGordon Ross <gwr@nexenta.com>2019-03-14 10:38:30 -0400
commit8329232e00f1048795bae53acb230316243aadb5 (patch)
tree0d9a71c0dd22bd5288debd1dcc2cd3f0e7131d67 /usr/src/cmd/fs.d/smbclnt
parentebee07ff4f102cbd3179db7c5070283da35a79f3 (diff)
downloadillumos-joyent-8329232e00f1048795bae53acb230316243aadb5.tar.gz
9874 Add fksmbcl development tool
Reviewed by: Evan Layton <evan.layton@nexenta.com> Reviewed by: Matt Barden <matt.barden@nexenta.com> Approved by: Joshua M. Clulow <josh@sysmgr.org>
Diffstat (limited to 'usr/src/cmd/fs.d/smbclnt')
-rw-r--r--usr/src/cmd/fs.d/smbclnt/Makefile4
-rw-r--r--usr/src/cmd/fs.d/smbclnt/fksmbcl/.dbxrc24
-rw-r--r--usr/src/cmd/fs.d/smbclnt/fksmbcl/Makefile104
-rw-r--r--usr/src/cmd/fs.d/smbclnt/fksmbcl/README99
-rwxr-xr-xusr/src/cmd/fs.d/smbclnt/fksmbcl/Run.sh32
-rw-r--r--usr/src/cmd/fs.d/smbclnt/fksmbcl/Watch-fksmbcl.d85
-rw-r--r--usr/src/cmd/fs.d/smbclnt/fksmbcl/fkdev.c98
-rw-r--r--usr/src/cmd/fs.d/smbclnt/fksmbcl/fkiod_cl.c150
-rw-r--r--usr/src/cmd/fs.d/smbclnt/fksmbcl/fknewvc.c143
-rw-r--r--usr/src/cmd/fs.d/smbclnt/fksmbcl/fksmbcl_main.c926
-rw-r--r--usr/src/cmd/fs.d/smbclnt/fksmbcl/shares.c (renamed from usr/src/cmd/fs.d/smbclnt/test/srvenum.c)236
-rw-r--r--usr/src/cmd/fs.d/smbclnt/test/Makefile85
-rw-r--r--usr/src/cmd/fs.d/smbclnt/test/srvinfo.c415
-rw-r--r--usr/src/cmd/fs.d/smbclnt/test/tconn.c171
14 files changed, 1704 insertions, 868 deletions
diff --git a/usr/src/cmd/fs.d/smbclnt/Makefile b/usr/src/cmd/fs.d/smbclnt/Makefile
index 5e26c570b3..e6b660643f 100644
--- a/usr/src/cmd/fs.d/smbclnt/Makefile
+++ b/usr/src/cmd/fs.d/smbclnt/Makefile
@@ -20,8 +20,8 @@
#
#
-# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2017 Nexenta Systems, Inc. All rights reserved.
#
#
@@ -33,7 +33,7 @@ include $(SRC)/Makefile.master
SUBDIRS_CATALOG= smbutil mount umount share
SUBDIRS= $(SUBDIRS_CATALOG) chacl lsacl \
- smbiod smbiod-svc svc test
+ smbiod smbiod-svc svc fksmbcl
# for messaging catalog files
#
diff --git a/usr/src/cmd/fs.d/smbclnt/fksmbcl/.dbxrc b/usr/src/cmd/fs.d/smbclnt/fksmbcl/.dbxrc
new file mode 100644
index 0000000000..8c05f688c5
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/fksmbcl/.dbxrc
@@ -0,0 +1,24 @@
+
+#
+# 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 2017 Nexenta Systems, Inc. All rights reserved.
+#
+
+# set -o emacs
+
+# fksmbcl is always 32-bit
+setenv LD_LIBRARY_PATH ${ROOT}/usr/lib/smbfs:${ROOT}/usr/lib:${ROOT}/lib
+
+echo 'Do one of: attach ${PID}'
+echo 'or: debug ${ROOT}/usr/lib/smbfs/fksmbcl'
+echo 'then: run -v //localhost'
diff --git a/usr/src/cmd/fs.d/smbclnt/fksmbcl/Makefile b/usr/src/cmd/fs.d/smbclnt/fksmbcl/Makefile
new file mode 100644
index 0000000000..5ae4f56e1b
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/fksmbcl/Makefile
@@ -0,0 +1,104 @@
+#
+# 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 (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+#
+
+PROG= fksmbcl
+
+OBJS_LOCAL = \
+ fksmbcl_main.o \
+ fkdev.o \
+ fknewvc.o \
+ fkiod_cl.o \
+ shares.o
+
+OBJS= ${OBJS_LOCAL}
+SRCS= ${OBJS_LOCAL:.o=.c}
+
+include ../../../Makefile.cmd
+include ../../../Makefile.ctf
+
+# Force SOURCEDEBUG
+CSOURCEDEBUGFLAGS = -g
+CCSOURCEDEBUGFLAGS = -g
+STRIP_STABS = :
+
+# Note: need our sys includes _before_ ENVCPPFLAGS, proto etc.
+# Also, like Makefile.uts, reset CPPFLAGS
+# CPPFLAGS.first += -I$(SRC)/lib/libfakekernel/common
+CPPFLAGS.first += -I$(SRC)/lib/smbclnt/libfknsmb/common
+CPPFLAGS= $(CPPFLAGS.first)
+
+INCS += -I$(SRC)/uts/common/fs/smbclnt
+INCS += -I$(SRC)/uts/common
+INCS += -I$(SRC)/common/smbclnt
+INCS += -I$(SRC)/common
+
+# Allow cpp to find libfknsmb.h etc. via
+# include <libfknsmb/common/libfknsmb.h>
+INCS += -I$(SRC)/lib/smbclnt
+INCS += -I$(SRC)/lib/libsmbfs
+INCS += -I$(SRC)/lib/libsmbfs/netsmb
+
+CPPFLAGS += $(INCS)
+CPPFLAGS += -D_REENTRANT
+CPPFLAGS += -D_FILE_OFFSET_BITS=64
+CPPFLAGS += -D_LARGEFILE64_SOURCE=1
+CPPFLAGS += -DFKSMBCL
+# Always want DEBUG here
+CPPFLAGS += -DDEBUG
+
+CSTD= $(CSTD_GNU99)
+
+CFLAGS += $(CCVERBOSE)
+CFLAGS64 += $(CCVERBOSE)
+
+LDFLAGS += $(ZNOLAZYLOAD)
+LDFLAGS += -R/usr/lib/smbfs
+LDLIBS += -L$(ROOT)/usr/lib/smbfs
+LDLIBS += -lsmbfs -lfksmbfs -lfknsmb
+LDLIBS += -lsocket
+
+ROOTSMBDDIR = $(ROOTLIB)/smbfs
+ROOTSMBDFILE = $(PROG:%=$(ROOTSMBDDIR)/%)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+clean:
+ -$(RM) $(OBJS)
+
+# lots of lint due to mixing kernel+user stuff. give up.
+lint: # lint_SRCS
+
+include ../../../Makefile.targ
+
+install: all $(ROOTSMBDFILE)
+
+$(ROOTSMBDDIR)/%: %
+ $(INS.file)
diff --git a/usr/src/cmd/fs.d/smbclnt/fksmbcl/README b/usr/src/cmd/fs.d/smbclnt/fksmbcl/README
new file mode 100644
index 0000000000..811401bc65
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/fksmbcl/README
@@ -0,0 +1,99 @@
+
+#
+# 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 2017 Nexenta Systems, Inc. All rights reserved.
+#
+
+This directory builds a program linking all of the SMB client code
+into a user-level process. The result is not a fully functional
+SMB client but is very useful for some kinds of development work.
+
+The architecture of this roughly parallels the in-kernel version,
+where the kernel modules are built as libraries including:
+ libfksmbfs, libfknsmb
+
+Just as with the kernel code, there are mdb modules that know
+how to walk data structures in libfksmbfs, etc.
+
+For debugging, etc. it's easiest to run this as a normal user,
+i.e. yourself (not root)
+
+Now you can run fksmbcl from the proto area using this script:
+ ./Run.sh -df
+
+You can also run it under dbx (see the .dbxrc file).
+To run it under mdb (with mdb modules build here):
+ mdb -L $ROOT/usr/lib/mdb/proc:/usr/lib/mdb/proc ...
+where ... is one of: fksmbcl, core.nnn, -p $PID
+
+There are also some dtrace scripts in here, and in ../dtrace
+for watching either all activity or only selected areas.
+Run these like: dtrace -s Watch-all.d -p $PID -o output
+
+These two (from over in ../dtrace) also work with fksmbcl:
+ dtrace -s fksmbcl.d -p `pgrep fksmbcl` -o output
+
+Here is the help output:
+
+ > help
+ Commands:
+ help
+ exit
+ logon [user [dom [pass]]]
+ logoff [close-driver]
+ shares
+ mount {share} [optstr]
+ umount
+ unmount
+ statfs
+ dir {rdir} [lfile]
+ dirx {rdir} [lfile]
+ get {rfile} [lfile]
+ put {lfile} [rfile]
+ mv {from} {to}
+ rm {rfile}
+ mkdir {rfile}
+ rmdir {rfile}
+ opt {option}
+
+
+Here is an example of how to connect, mount, and list a directory:
+
+ $ ./Run.sh //myserver
+ # Start with:
+ > logon [user [dom [pw]]]
+ > shares
+ > mount {share}
+
+ > logon test test test
+ > shares
+ open pipe: /srvsvc
+ enum strings
+ junk
+ c$
+ Default Share
+ test1
+ ipc$
+ Remote IPC
+ test
+ > mount test
+ > dir
+ 1224750917 .
+ 1224750917 ..
+ 900818955 test9.dat
+ 3908265151 lock1.txt
+ 2452346625 test_dir
+ > umount
+ > logoff
+ > exit
+ $
diff --git a/usr/src/cmd/fs.d/smbclnt/fksmbcl/Run.sh b/usr/src/cmd/fs.d/smbclnt/fksmbcl/Run.sh
new file mode 100755
index 0000000000..df731bf733
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/fksmbcl/Run.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+#
+# 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 2017 Nexenta Systems, Inc. All rights reserved.
+#
+
+# Helper program to run fksmbd (user-space smbd for debugging)
+# using binaries from the proto area.
+
+[ -n "$ROOT" ] || {
+ echo "Need a bldenv to set ROOT=..."
+ exit 1;
+}
+
+# OK, setup env. to run it.
+
+LD_LIBRARY_PATH=$ROOT/usr/lib/smbfs:$ROOT/usr/lib:$ROOT/lib
+export LD_LIBRARY_PATH
+
+# run with the passed options
+exec $ROOT/usr/lib/smbfs/fksmbcl "$@"
diff --git a/usr/src/cmd/fs.d/smbclnt/fksmbcl/Watch-fksmbcl.d b/usr/src/cmd/fs.d/smbclnt/fksmbcl/Watch-fksmbcl.d
new file mode 100644
index 0000000000..823115bf9c
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/fksmbcl/Watch-fksmbcl.d
@@ -0,0 +1,85 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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 2017 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * User-level dtrace for fksmbcl
+ * Usage: dtrace -s Watch-fksmbcl.d -p $PID
+ */
+
+self int trace;
+
+/*
+ * Trace almost everything
+ */
+pid$target:fksmbcl::entry
+{
+ self->trace++;
+}
+
+pid$target:fksmbcl::return
+{
+ self->trace--;
+}
+
+/*
+ * If traced, print entry/return
+ */
+pid$target:fksmbcl::entry,
+pid$target:libsmbfs.so.1::entry,
+pid$target:libfksmbfs.so.1::entry,
+pid$target:libfknsmb.so.1::entry,
+pid$target:libfakekernel.so.1::entry
+/self->trace > 0/
+{
+ printf("\t0x%x", arg0);
+ printf("\t0x%x", arg1);
+ printf("\t0x%x", arg2);
+ printf("\t0x%x", arg3);
+ printf("\t0x%x", arg4);
+ printf("\t0x%x", arg5);
+}
+
+pid$target:fksmbcl::return,
+pid$target:libsmbfs.so.1::return,
+pid$target:libfksmbfs.so.1::return,
+pid$target:libfknsmb.so.1::return,
+pid$target:libfakekernel.so.1::entry
+/self->trace > 0/
+{
+ printf("\t0x%x", arg1);
+}
+
+pid$target::smbfslookup:entry
+{
+ printf("\tname = %s\n", copyinstr(arg1));
+}
+
+pid$target:libfknsmb.so.1:smb_dtrace2:entry
+/copyinstr(arg0) == "debugmsg2"/
+{
+ this->f = copyinstr(arg1);
+ this->m = copyinstr(arg2);
+ printf("\n\t debugmsg2: %s: %s ", this->f, this->m);
+}
+
+pid$target:libfknsmb.so.1:smb_dtrace3:entry
+/copyinstr(arg0) == "debugmsg3"/
+{
+ this->f = copyinstr(arg1);
+ this->m = copyinstr(arg2);
+ printf("\n\t debugmsg3: %s: %s ", this->f, this->m);
+ trace(arg3);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/fksmbcl/fkdev.c b/usr/src/cmd/fs.d/smbclnt/fksmbcl/fkdev.c
new file mode 100644
index 0000000000..34da749e78
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/fksmbcl/fkdev.c
@@ -0,0 +1,98 @@
+/*
+ * 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 2017 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * This file implements device open/close/ioctl wrappers that
+ * redirect access from the real "nsmb" device to the in-process
+ * device simulation in libfknsmb.
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/byteorder.h>
+
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <assert.h>
+#include <nss_dbdefs.h>
+
+#include <cflib.h>
+#include <netsmb/smb_lib.h>
+#include <netsmb/netbios.h>
+#include <netsmb/nb_lib.h>
+#include <netsmb/smb_dev.h>
+
+#include <libfknsmb/common/libfknsmb.h>
+
+#include "smb/charsets.h"
+#include "smb/private.h"
+
+int
+smb_open_driver(void)
+{
+ dev32_t dev;
+ int fd;
+ int rc;
+
+ rc = nsmb_drv_open(&dev, 0, 0);
+ if (rc != 0) {
+ errno = rc;
+ return (-1);
+ }
+
+ assert((dev & 0xFFFF0000) != 0);
+ fd = (int)dev;
+
+ return (fd);
+}
+
+int
+nsmb_ioctl(int fd, int cmd, void *arg)
+{
+ dev32_t dev;
+ int err;
+
+ dev = (dev32_t)fd;
+ assert((dev & 0xFFFF0000) != 0);
+ err = nsmb_drv_ioctl(dev, cmd, (intptr_t)arg, 0);
+ if (err != 0) {
+ errno = err;
+ return (-1);
+ }
+ return (0);
+}
+
+int
+nsmb_close(int fd)
+{
+ dev32_t dev;
+
+ dev = (dev32_t)fd;
+ assert((dev & 0xFFFF0000) != 0);
+ (void) nsmb_drv_close(dev, 0, 0);
+ return (0);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/fksmbcl/fkiod_cl.c b/usr/src/cmd/fs.d/smbclnt/fksmbcl/fkiod_cl.c
new file mode 100644
index 0000000000..be26854bd3
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/fksmbcl/fkiod_cl.c
@@ -0,0 +1,150 @@
+/*
+ * 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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * Client-side interface to the IO Daemon (IOD)
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <libintl.h>
+#include <thread.h>
+
+#include <sys/byteorder.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+
+#include <netsmb/smb_lib.h>
+#include <netsmb/netbios.h>
+#include <netsmb/nb_lib.h>
+#include <netsmb/smb_dev.h>
+
+#include <assert.h>
+
+#include "smb/charsets.h"
+#include "smb/private.h"
+
+/*
+ * Make sure we don't call the real IOD here.
+ */
+int
+smb_iod_open_door(int *fdp)
+{
+ *fdp = -1;
+ return (ENOTSUP);
+}
+
+/*
+ * Get a door handle to the IOD...
+ */
+int
+smb_iod_start(smb_ctx_t *ctx)
+{
+ return (0);
+}
+
+void *
+iod_work(void *arg)
+{
+ smb_ctx_t *ctx = arg;
+ (void) smb_iod_work(ctx);
+ smb_ctx_free(ctx);
+ return (NULL);
+}
+
+/*
+ * Ask the IOD to connect using the info in ctx.
+ * Called by newvc.
+ *
+ * This function largely follows smbiod.c : iod_newvc()
+ */
+int
+smb_iod_cl_newvc(smb_ctx_t *cl_ctx)
+{
+ smb_ctx_t *ctx;
+ thread_t tid;
+ int err = 0;
+
+ /*
+ * Clone the context, like in smbiod.c
+ */
+ err = smb_ctx_alloc(&ctx);
+ if (err)
+ return (err);
+ bcopy(&cl_ctx->ct_iod_ssn, &ctx->ct_iod_ssn,
+ sizeof (ctx->ct_iod_ssn));
+
+ /*
+ * Create the driver session first...
+ */
+ if ((err = smb_ctx_gethandle(ctx)) != 0)
+ goto out;
+ if (nsmb_ioctl(ctx->ct_dev_fd, SMBIOC_SSN_CREATE, &ctx->ct_ssn) < 0) {
+ err = errno;
+ if (err == EEXIST)
+ err = 0; /* see above */
+ goto out;
+ }
+
+ /*
+ * Do the initial connection setup here, so we can
+ * report the outcome to the door client.
+ */
+ err = smb_iod_connect(ctx);
+ if (err != 0) {
+ fprintf(stderr, "smb_iod_connect, err=%d\n", err);
+ goto out;
+ }
+
+ /* The rest happens in the iod_work thread. */
+ err = thr_create(NULL, 0, iod_work, ctx, THR_DETACHED, &tid);
+ if (err == 0) {
+ /*
+ * Given to the new thread.
+ * free at end of iod_work
+ */
+ ctx = NULL;
+ }
+
+out:
+ if (ctx != NULL)
+ smb_ctx_free(ctx);
+
+ return (err);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/fksmbcl/fknewvc.c b/usr/src/cmd/fs.d/smbclnt/fksmbcl/fknewvc.c
new file mode 100644
index 0000000000..7f66b3b5bb
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/fksmbcl/fknewvc.c
@@ -0,0 +1,143 @@
+/*
+ * 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 2017 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * Create a new VC given a list of addresses.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <libintl.h>
+#include <xti.h>
+#include <assert.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/byteorder.h>
+#include <sys/socket.h>
+#include <sys/fcntl.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+
+#include <netsmb/smb.h>
+#include <netsmb/smb_lib.h>
+#include <netsmb/netbios.h>
+#include <netsmb/nb_lib.h>
+#include <netsmb/smb_dev.h>
+
+#include "smb/charsets.h"
+#include "smb/private.h"
+
+/*
+ * Ask the IOD to create a VC with this IP address.
+ */
+static int
+fknewvc(struct smb_ctx *ctx, struct addrinfo *ai)
+{
+ char host[256];
+ char svc[32];
+ smbioc_ossn_t *ssn = &ctx->ct_ssn;
+ int err;
+
+ if (smb_debug) {
+ err = getnameinfo(ai->ai_addr, ai->ai_addrlen,
+ host, sizeof (host), svc, sizeof (svc),
+ AI_NUMERICHOST);
+ if (err != 0) {
+ strlcpy(host, "(?)", sizeof (host));
+ strlcpy(svc, "?", sizeof (host));
+ }
+ printf("fknewvc: Try AF=%d %s:%s\n",
+ ai->ai_family, host, svc);
+ }
+
+ /*
+ * Copy the passed address into ssn_srvaddr,
+ * but first sanity-check lengths. Also,
+ * zero it first to avoid trailing junk.
+ */
+ if (ai->ai_addrlen > sizeof (ssn->ssn_srvaddr))
+ return (EINVAL);
+ bzero(&ssn->ssn_srvaddr, sizeof (ssn->ssn_srvaddr));
+ bcopy(ai->ai_addr, &ssn->ssn_srvaddr, ai->ai_addrlen);
+
+ /* Ask the IOD to connect using the info in ctx. */
+ err = smb_iod_cl_newvc(ctx);
+ if (smb_debug) {
+ printf("fknewvc: iod_cl_newvc err=%d\n", err);
+ }
+
+ return (err);
+}
+
+/*
+ * Setup a new VC via the IOD.
+ * Similar to findvc.c
+ */
+int
+smb_ctx_newvc(struct smb_ctx *ctx)
+{
+ struct addrinfo *ai;
+ int err;
+
+ /* Should already have the address list. */
+ if ((ctx->ct_flags & SMBCF_RESOLVED) == 0)
+ return (EINVAL);
+
+ err = EPROTONOSUPPORT; /* in case no AF match */
+ for (ai = ctx->ct_addrinfo; ai; ai = ai->ai_next) {
+
+ switch (ai->ai_family) {
+
+ case AF_INET:
+ case AF_INET6:
+ case AF_NETBIOS:
+ err = fknewvc(ctx, ai);
+ if (err == 0)
+ return (0);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /*
+ * In the error case, the caller may try again
+ * with new auth. info, so keep the door open.
+ * Error return will close in smb_ctx_done.
+ */
+ return (err);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/fksmbcl/fksmbcl_main.c b/usr/src/cmd/fs.d/smbclnt/fksmbcl/fksmbcl_main.c
new file mode 100644
index 0000000000..65b0312558
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/fksmbcl/fksmbcl_main.c
@@ -0,0 +1,926 @@
+/*
+ * 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 2017 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * Test & debug program for the SMB client
+ *
+ * This implements a simple command reader which accepts
+ * commands to simulate system calls into the file system.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <sys/dirent.h>
+#include <sys/strlog.h> /* SL_NOTE */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/fs/smbfs_mount.h>
+#include <netsmb/smb_lib.h>
+#include <libfknsmb/common/libfknsmb.h>
+#include <libfksmbfs/common/libfksmbfs.h>
+
+#if _FILE_OFFSET_BITS != 64
+#error "This calls (fake) VFS code which requires 64-bit off_t"
+#endif
+
+extern int list_shares(struct smb_ctx *);
+
+#define MAXARG 10
+
+struct cmd_tbl_ent {
+ void (*ce_func)(int, char **);
+ const char *ce_name;
+ const char *ce_argdesc;
+};
+static struct cmd_tbl_ent cmd_tbl[];
+
+static struct smb_ctx *ctx = NULL;
+static char *server = NULL;
+
+static vfs_t *vfsp = NULL;
+
+static void show_dents(vnode_t *, offset_t *, char *, int);
+static void run_cli(void);
+
+#define TBUFSZ 8192
+static char tbuf[TBUFSZ];
+
+static void
+fksmbcl_usage(void)
+{
+ printf("usage: fksmbcl //user@server (like smbutil)\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int error, opt;
+
+ /*
+ * Initializations
+ */
+ nsmb_drv_load();
+ nsmb_drv_init();
+ fksmbfs_init();
+
+ while ((opt = getopt(argc, argv, "dv")) != -1) {
+ switch (opt) {
+ case 'd':
+ smb_debug++;
+ break;
+ case 'v':
+ smb_verbose++;
+ break;
+ case '?':
+ fksmbcl_usage();
+ break;
+ }
+ }
+ if (optind >= argc)
+ fksmbcl_usage();
+ server = argv[optind];
+
+ /*
+ * Setup the libsmbfs context
+ */
+ error = smb_ctx_alloc(&ctx);
+ if (error) {
+ fprintf(stderr, "%s: smb_ctx_alloc failed (%d)\n",
+ argv[0], error);
+ return (1);
+ }
+
+ error = smb_ctx_scan_argv(ctx, argc, argv,
+ SMBL_SERVER, SMBL_SERVER, USE_WILDCARD);
+ if (error) {
+ fprintf(stderr, "logon: smb_ctx_scan_argv, error %d\n", error);
+ return (1);
+ }
+ error = smb_ctx_readrc(ctx);
+ if (error) {
+ fprintf(stderr, "logon: smb_ctx_readrc, error %d\n", error);
+ return (1);
+ }
+
+ /* Do smb_ctx_setshare later, and smb_ctx_resolve. */
+
+ /*
+ * Next would be smb_ctx_get_ssn() but don't do that until
+ * the "logon" command so one can set breakpoints etc.
+ */
+
+ /*
+ * Run the CLI
+ */
+ run_cli();
+
+ /*
+ * Cleanup
+ */
+ fksmbfs_fini();
+ nsmb_drv_fini();
+
+ return (0);
+}
+
+static void
+run_cli()
+{
+ static char cmdbuf[100];
+ int argc, i;
+ char *argv[MAXARG];
+ char *cmd;
+ char *savep = NULL;
+ char *sep = " \t\n";
+ char *prompt = NULL;
+ struct cmd_tbl_ent *ce;
+
+ if (isatty(0)) {
+ fputs("# Start with:\n"
+ "> logon [user [dom [pw]]]\n"
+ "> shares\n"
+ "> mount {share}\n\n",
+ stdout);
+ prompt = "> ";
+ }
+
+ for (;;) {
+ if (prompt) {
+ fputs(prompt, stdout);
+ fflush(stdout);
+ }
+
+ cmd = fgets(cmdbuf, sizeof (cmdbuf), stdin);
+ if (cmd == NULL)
+ break;
+ if (cmd[0] == '#')
+ continue;
+
+ if (prompt == NULL) {
+ /* Put commands in the output too. */
+ fprintf(stdout, "+ %s", cmdbuf);
+ }
+
+ argv[0] = strtok_r(cmd, sep, &savep);
+ if (argv[0] == NULL)
+ continue;
+ for (argc = 1; argc < MAXARG; argc++) {
+ argv[argc] = strtok_r(NULL, sep, &savep);
+ if (argv[argc] == NULL)
+ break;
+ }
+ for (i = argc; i < MAXARG; i++)
+ argv[i++] = NULL;
+
+ for (ce = cmd_tbl; ce->ce_name != NULL; ce++)
+ if (strcmp(ce->ce_name, argv[0]) == 0)
+ break;
+ if (ce->ce_name != NULL) {
+ ce->ce_func(argc, argv);
+ } else {
+ fprintf(stderr, "%s unknown command. Try help\n",
+ argv[0]);
+ }
+ }
+}
+
+/*
+ * Command handlers
+ */
+
+static void
+do_exit(int argc, char **argv)
+{
+ exit(0);
+}
+
+static void
+do_help(int argc, char **argv)
+{
+ struct cmd_tbl_ent *ce;
+
+ printf("Commands:\n");
+ for (ce = cmd_tbl; ce->ce_func != NULL; ce++)
+ printf("%s %s\n", ce->ce_name, ce->ce_argdesc);
+}
+
+static void
+do_logon(int argc, char **argv)
+{
+ int error;
+
+ if (argc > 1) {
+ if (argv[1][0] == '-') {
+ smb_ctx_setuser(ctx, "", B_TRUE);
+ ctx->ct_flags |= SMBCF_NOPWD;
+ } else {
+ smb_ctx_setuser(ctx, argv[1], B_TRUE);
+ }
+ }
+ if (argc > 2)
+ smb_ctx_setdomain(ctx, argv[2], B_TRUE);
+ if (argc > 3)
+ smb_ctx_setpassword(ctx, argv[3], NULL);
+
+ /*
+ * Resolve the server address, setup derived defaults.
+ */
+ error = smb_ctx_resolve(ctx);
+ if (error) {
+ fprintf(stderr, "logon: smb_ctx_resolve, error %d\n", error);
+ return;
+ }
+
+ /*
+ * Have server, share, etc. now.
+ * Get the logon session.
+ */
+again:
+ error = smb_ctx_get_ssn(ctx);
+ if (error == EAUTH) {
+ int err2;
+ err2 = smb_get_authentication(ctx);
+ if (err2 == 0)
+ goto again;
+ }
+ if (error) {
+ fprintf(stderr, "//%s: login failed, error %d\n",
+ ctx->ct_fullserver, error);
+ }
+}
+
+/*
+ * Drop session created by the "logon" command.
+ */
+static void
+do_logoff(int argc, char **argv)
+{
+
+ (void) nsmb_ioctl(ctx->ct_dev_fd, SMBIOC_SSN_RELE, NULL);
+ if (argc > 1) {
+ smb_ctx_done(ctx);
+ (void) smb_ctx_init(ctx);
+ }
+}
+
+/*
+ * List shares
+ */
+static void
+do_shares(int argc, char **argv)
+{
+ int error;
+
+ smb_ctx_setshare(ctx, "IPC$", USE_IPC);
+ error = smb_ctx_get_tree(ctx);
+ if (error) {
+ fprintf(stderr, "shares, tcon IPC$, error=%d\n", error);
+ return;
+ }
+
+ error = list_shares(ctx);
+ if (error) {
+ fprintf(stderr, "shares, enum, error=%d\n", error);
+ }
+
+ (void) nsmb_ioctl(ctx->ct_dev_fd, SMBIOC_TREE_RELE, NULL);
+}
+
+char mnt_opt_buf[MAX_MNTOPT_STR];
+char mnt_resource[MAXPATHLEN];
+
+/*
+ * Minimal excerpt from vfs.c:domount()
+ */
+void
+do_mount(int argc, char **argv)
+{
+ struct smbfs_args mdata;
+ struct mounta ma;
+ char *shrname;
+ int error;
+
+ if (vfsp != NULL) {
+ fprintf(stderr, "Already mounted\n");
+ return;
+ }
+
+ if (argc < 2) {
+ fprintf(stderr, "%s: missing share name\n", argv[0]);
+ return;
+ }
+ shrname = argv[1];
+ if (argc > 2)
+ strlcpy(mnt_opt_buf, argv[2], sizeof (mnt_opt_buf));
+ else
+ memset(mnt_opt_buf, 0, sizeof (mnt_opt_buf));
+
+ smb_ctx_setshare(ctx, shrname, USE_DISKDEV);
+ error = smb_ctx_get_tree(ctx);
+ if (error) {
+ fprintf(stderr, "//%s/%s: tree connect failed, %d\n",
+ server, shrname, error);
+ return;
+ }
+
+ (void) snprintf(mnt_resource, sizeof (mnt_resource),
+ "//%s/%s", ctx->ct_fullserver, shrname);
+
+ bzero(&mdata, sizeof (mdata));
+ mdata.version = SMBFS_VERSION; /* smbfs mount version */
+ mdata.file_mode = S_IRWXU;
+ mdata.dir_mode = S_IRWXU;
+ mdata.devfd = ctx->ct_dev_fd;
+
+ /* Build mount args */
+ bzero(&ma, sizeof (ma));
+ ma.spec = mnt_resource;
+ ma.dir = "/";
+ ma.flags = MS_DATA | MS_OPTIONSTR | MS_NOSPLICE | MS_NOSUID;
+ ma.fstype = "smbfs";
+ ma.dataptr = (void *) &mdata;
+ ma.datalen = sizeof (mdata);
+ ma.optptr = mnt_opt_buf;
+ ma.optlen = sizeof (mnt_opt_buf);
+
+ error = fake_domount("smbfs", &ma, &vfsp);
+ if (error != 0) {
+ fprintf(stderr, "domount error=%d\n", error);
+ }
+
+ /* Mount takes a ref, so always rele here. */
+ (void) nsmb_ioctl(ctx->ct_dev_fd, SMBIOC_TREE_RELE, NULL);
+}
+
+void
+do_unmount(int argc, char **argv)
+{
+ int error;
+
+ if (vfsp == NULL) {
+ fprintf(stderr, "Not mounted\n");
+ return;
+ }
+
+ error = fake_dounmount(vfsp, 0);
+ if (error != 0) {
+ fprintf(stderr, "dounmount error=%d\n", error);
+ return;
+ }
+ vfsp = NULL;
+}
+
+void
+do_statfs(int argc, char **argv)
+{
+ statvfs64_t st;
+ int error;
+
+ if (vfsp == NULL) {
+ fprintf(stderr, "Not mounted\n");
+ return;
+ }
+
+ error = fsop_statfs(vfsp, &st);
+ if (error != 0) {
+ fprintf(stderr, "df error=%d\n", error);
+ return;
+ }
+ printf("bsize=%ld\n", st.f_bsize);
+ printf("frsize=%ld\n", st.f_frsize);
+ printf("blocks=%" PRIu64 "\n", st.f_blocks);
+ printf(" bfree=%" PRIu64 "\n", st.f_bfree);
+ printf("bavail=%" PRIu64 "\n", st.f_bavail);
+}
+
+void
+do_dir(int argc, char **argv)
+{
+ char *rdir;
+ vnode_t *vp = NULL;
+ offset_t off;
+ int cnt;
+ int error;
+
+ if (vfsp == NULL) {
+ fprintf(stderr, "mnt required first\n");
+ return;
+ }
+ if (argc > 1)
+ rdir = argv[1];
+ else
+ rdir = "";
+
+ error = vn_open(rdir, 0, FREAD, 0, &vp, 0, 0);
+ if (error != 0) {
+ fprintf(stderr, "do_dir, vn_open error=%d\n", error);
+ return;
+ }
+
+ off = 0;
+ do {
+ cnt = fake_getdents(vp, &off, tbuf, TBUFSZ);
+ if (cnt < 0) {
+ fprintf(stderr, "do_dir, getdents %d\n", -cnt);
+ break;
+ }
+ show_dents(vp, &off, tbuf, cnt);
+ } while (cnt > 0);
+
+ if (vp != NULL)
+ vn_close_rele(vp, 0);
+}
+
+void
+do_dirx(int argc, char **argv)
+{
+ char *rdir;
+ vnode_t *vp = NULL;
+ offset_t off;
+ int cnt;
+ int error;
+
+ if (vfsp == NULL) {
+ fprintf(stderr, "mnt required first\n");
+ return;
+ }
+ if (argc > 1)
+ rdir = argv[1];
+ else
+ rdir = "";
+
+ error = vn_open(rdir, 0, FREAD|FXATTRDIROPEN, 0, &vp, 0, 0);
+ if (error != 0) {
+ fprintf(stderr, "do_dirx, vn_open error=%d\n", error);
+ return;
+ }
+
+ off = 0;
+ do {
+ cnt = fake_getdents(vp, &off, tbuf, TBUFSZ);
+ if (cnt < 0) {
+ fprintf(stderr, "do_dirx, getdents %d\n", -cnt);
+ break;
+ }
+ show_dents(vp, &off, tbuf, cnt);
+ } while (cnt > 0);
+
+ if (vp != NULL)
+ vn_close_rele(vp, 0);
+}
+
+static void
+show_dents(vnode_t *dvp, offset_t *offp, char *buf, int cnt)
+{
+ char time_buf[40];
+ struct stat64 st;
+ vnode_t *vp;
+ char *p;
+ dirent_t *d;
+ offset_t offset = (offset_t)-1L;
+ int error;
+ uint_t mode;
+ char type;
+
+ p = buf;
+ while (p < (buf + cnt)) {
+ d = (dirent_t *)(void *)p;
+ p += d->d_reclen;
+ offset = d->d_off;
+
+ error = fake_lookup(dvp, d->d_name, &vp);
+ if (error != 0) {
+ fprintf(stderr, "%s: lookup error=%d\n",
+ d->d_name, error);
+ continue;
+ }
+ error = fake_stat(vp, &st, 0);
+ vn_rele(vp);
+ if (error != 0) {
+ fprintf(stderr, "%s: stat error=%d\n",
+ d->d_name, error);
+ continue;
+ }
+
+ /*
+ * Print type, mode, size, name
+ * First mode (only dir, file expected here)
+ */
+ if (S_ISDIR(st.st_mode)) {
+ type = 'd';
+ } else if (S_ISREG(st.st_mode)) {
+ type = ' ';
+ } else {
+ type = '?';
+ }
+ mode = st.st_mode & 0777;
+ (void) strftime(time_buf, sizeof (time_buf),
+ "%b %e %T %Y", localtime(&st.st_mtime));
+
+ printf("%c 0%3o %9" PRIu64 " %s %s\n",
+ type, mode,
+ (uint64_t)st.st_size,
+ time_buf,
+ d->d_name);
+ }
+ *offp = offset;
+}
+
+/*
+ * get rname [lname]
+ */
+void
+do_get(int argc, char **argv)
+{
+ struct stat64 st;
+ char *rname;
+ char *lname;
+ vnode_t *vp = NULL;
+ offset_t off;
+ ssize_t cnt, x;
+ int oflg = O_RDWR | O_CREAT;
+ int lfd = -1;
+ int error;
+
+ if (vfsp == NULL) {
+ fprintf(stderr, "mnt required first\n");
+ return;
+ }
+ if (argc < 2) {
+ fprintf(stderr, "rname required\n");
+ return;
+ }
+ rname = argv[1];
+ if (argc > 2) {
+ lname = argv[2];
+ /*
+ * When local name is specified, overwrite.
+ * Convenient for scripts etc.
+ */
+ oflg |= O_TRUNC;
+ } else {
+ lname = rname;
+ /* Local file should not exist. */
+ oflg |= O_EXCL;
+ }
+
+ lfd = open(lname, oflg, 0644);
+ if (lfd < 0) {
+ perror(lname);
+ return;
+ }
+
+ error = vn_open(rname, 0, FREAD, 0, &vp, 0, 0);
+ if (error != 0) {
+ fprintf(stderr, "do_get, vn_open error=%d\n", error);
+ goto out;
+ }
+ error = fake_stat(vp, &st, 0);
+ if (error != 0) {
+ fprintf(stderr, "do_get, stat error=%d\n", error);
+ goto out;
+ }
+
+ off = 0;
+ do {
+ cnt = fake_pread(vp, tbuf, TBUFSZ, off);
+ if (cnt < 0) {
+ fprintf(stderr, "do_get, read %d\n", -cnt);
+ goto out;
+ }
+ x = write(lfd, tbuf, cnt);
+ if (x < 0) {
+ fprintf(stderr, "do_get, write %d\n", errno);
+ goto out;
+ }
+ off += x;
+ } while (off < st.st_size);
+
+out:
+ if (vp != NULL)
+ vn_close_rele(vp, 0);
+ if (lfd != -1)
+ close(lfd);
+}
+
+/*
+ * put lname [rname]
+ */
+void
+do_put(int argc, char **argv)
+{
+ struct stat64 rst;
+ struct stat st;
+ char *rname;
+ char *lname;
+ vnode_t *vp = NULL;
+ offset_t off;
+ ssize_t cnt, x;
+ int oflg = FREAD|FWRITE|FCREAT;
+ int lfd = -1;
+ int error;
+
+ if (vfsp == NULL) {
+ fprintf(stderr, "mnt required first\n");
+ return;
+ }
+ if (argc < 2) {
+ fprintf(stderr, "lname required\n");
+ return;
+ }
+ lname = argv[1];
+ if (argc > 2) {
+ rname = argv[2];
+ /*
+ * When remote name is specified, overwrite.
+ * Convenient for scripts etc.
+ */
+ oflg |= FTRUNC;
+ } else {
+ rname = lname;
+ /* Remote file should not exist. */
+ oflg |= FEXCL;
+ }
+
+ lfd = open(lname, O_RDONLY, 0);
+ if (lfd < 0) {
+ perror(lname);
+ return;
+ }
+ error = fstat(lfd, &st);
+ if (error != 0) {
+ fprintf(stderr, "do_put, stat error=%d\n", error);
+ goto out;
+ }
+
+ error = vn_open(rname, 0, oflg, 0, &vp, 0, 0);
+ if (error != 0) {
+ fprintf(stderr, "do_put, vn_open error=%d\n", error);
+ goto out;
+ }
+
+ off = 0;
+ do {
+ cnt = pread(lfd, tbuf, TBUFSZ, off);
+ if (cnt < 0) {
+ fprintf(stderr, "do_put, read %d\n", errno);
+ goto out;
+ }
+ x = fake_pwrite(vp, tbuf, cnt, off);
+ if (x < 0) {
+ fprintf(stderr, "do_put, write %d\n", -x);
+ goto out;
+ }
+ off += cnt;
+ } while (off < st.st_size);
+
+ /* This getattr should go OtW. */
+ error = fake_stat(vp, &rst, 0);
+ if (error != 0) {
+ fprintf(stderr, "do_put, stat error=%d\n", error);
+ goto out;
+ }
+ if (rst.st_size != st.st_size) {
+ fprintf(stderr, "do_put, wrong size?\n");
+ }
+
+out:
+ if (vp != NULL)
+ vn_close_rele(vp, 0);
+ if (lfd != -1)
+ close(lfd);
+}
+
+/*
+ * rm rname
+ */
+void
+do_rm(int argc, char **argv)
+{
+ char *rname;
+ int error;
+
+ if (vfsp == NULL) {
+ fprintf(stderr, "mnt required first\n");
+ return;
+ }
+ if (argc < 2) {
+ fprintf(stderr, "rname required\n");
+ return;
+ }
+ rname = argv[1];
+
+ error = fake_unlink(rname, 0);
+ if (error != 0) {
+ fprintf(stderr, "do_rm, unlink error=%d\n", error);
+ }
+}
+
+/*
+ * mv fromname toname
+ */
+void
+do_mv(int argc, char **argv)
+{
+ int error;
+
+ if (vfsp == NULL) {
+ fprintf(stderr, "mnt required first\n");
+ return;
+ }
+ if (argc < 3) {
+ fprintf(stderr, "from_name to_name required\n");
+ return;
+ }
+
+ error = fake_rename(argv[1], argv[2]);
+ if (error != 0) {
+ fprintf(stderr, "do_mv, rename error=%d\n", error);
+ }
+}
+
+/*
+ * mkdir rname
+ */
+void
+do_mkdir(int argc, char **argv)
+{
+ char *rname;
+ vnode_t *vp = NULL;
+ int error;
+
+ if (vfsp == NULL) {
+ fprintf(stderr, "mnt required first\n");
+ return;
+ }
+ if (argc < 2) {
+ fprintf(stderr, "rname required\n");
+ return;
+ }
+ rname = argv[1];
+
+ error = vn_open(rname, 0, FCREAT, 0, &vp, CRMKDIR, 0);
+ if (error != 0) {
+ fprintf(stderr, "do_mkdir, vn_open error=%d\n", error);
+ }
+
+ if (vp != NULL)
+ vn_close_rele(vp, 0);
+}
+
+/*
+ * rmdir rname
+ */
+void
+do_rmdir(int argc, char **argv)
+{
+ char *rname;
+ int error;
+
+ if (vfsp == NULL) {
+ fprintf(stderr, "mnt required first\n");
+ return;
+ }
+ if (argc < 2) {
+ fprintf(stderr, "rname required\n");
+ return;
+ }
+ rname = argv[1];
+
+ error = fake_unlink(rname, AT_REMOVEDIR);
+ if (error != 0) {
+ fprintf(stderr, "do_rmdir, unlink error=%d\n", error);
+ }
+}
+
+/*
+ * Simple option setting
+ *
+ * Each arg is handled as one line in .nsmbrc [default]
+ */
+void
+do_opt(int argc, char **argv)
+{
+ static char template[20] = "/tmp/fksmbclXXXXXX";
+ static char rcname[30];
+ char *tdname;
+ char *save_home;
+ FILE *fp;
+ int err, i;
+
+ if (argc < 2) {
+ fprintf(stderr, "opt {key}[=value]\n");
+ return;
+ }
+
+ tdname = mkdtemp(template);
+ if (tdname == NULL) {
+ perror("mkdtemp");
+ return;
+ }
+ (void) snprintf(rcname, sizeof (rcname),
+ "%s/.nsmbrc", tdname);
+
+ fp = fopen(rcname, "w");
+ if (fp == NULL) {
+ perror(rcname);
+ goto out;
+ }
+ fprintf(fp, "[default]\n");
+ for (i = 1; i < argc; i++)
+ fprintf(fp, "%s\n", argv[i]);
+ fclose(fp);
+
+ save_home = ctx->ct_home;
+ ctx->ct_home = tdname;
+ err = smb_ctx_readrc(ctx);
+ ctx->ct_home = save_home;
+
+ if (err != 0)
+ fprintf(stderr, "readrc, err=%d\n", err);
+
+out:
+ (void) unlink(rcname);
+ (void) rmdir(tdname);
+}
+
+/*
+ * Command table
+ */
+static struct cmd_tbl_ent
+cmd_tbl[] = {
+ { do_help, "help", "" },
+ { do_exit, "exit", "" },
+ { do_logon, "logon", "[user [dom [pass]]]" },
+ { do_logoff, "logoff", "[close-driver]" },
+ { do_shares, "shares", "" },
+ { do_mount, "mount", "{share} [optstr]" },
+ { do_unmount, "umount", "" },
+ { do_unmount, "unmount", "" },
+ { do_statfs, "statfs", "" },
+ { do_dir, "dir", "{rdir} [lfile]" },
+ { do_dirx, "dirx", "{rdir} [lfile]" },
+ { do_get, "get", "{rfile} [lfile]" },
+ { do_put, "put", "{lfile} [rfile]" },
+ { do_mv, "mv", "{from} {to}" },
+ { do_rm, "rm", "{rfile}" },
+ { do_mkdir, "mkdir", "{rfile}" },
+ { do_rmdir, "rmdir", "{rfile}" },
+ { do_opt, "opt", "{option}" },
+ { NULL, NULL, NULL }
+};
+
+/*
+ * Provide a real function (one that prints something) to replace
+ * the stub in libfakekernel. This prints cmn_err() messages.
+ */
+void
+fakekernel_putlog(char *msg, size_t len, int flags)
+{
+
+ /*
+ * [CE_CONT, CE_NOTE, CE_WARN, CE_PANIC] maps to
+ * [SL_NOTE, SL_NOTE, SL_WARN, SL_FATAL]
+ */
+ if (smb_debug == 0 && (flags & SL_NOTE))
+ return;
+ (void) fwrite(msg, 1, len, stdout);
+ (void) fflush(stdout);
+}
+
+/*
+ * Enable libumem debugging
+ */
+const char *
+_umem_debug_init(void)
+{
+ return ("default,verbose"); /* $UMEM_DEBUG setting */
+}
+
+const char *
+_umem_logging_init(void)
+{
+ return ("fail,contents"); /* $UMEM_LOGGING setting */
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/test/srvenum.c b/usr/src/cmd/fs.d/smbclnt/fksmbcl/shares.c
index ee3aeba014..2d8d0cf6da 100644
--- a/usr/src/cmd/fs.d/smbclnt/test/srvenum.c
+++ b/usr/src/cmd/fs.d/smbclnt/fksmbcl/shares.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -36,27 +36,17 @@
#include <string.h>
#include <unistd.h>
#include <libintl.h>
+#include <ctype.h>
-#include <netsmb/smbfs_api.h>
+#include <netsmb/smb_lib.h>
/*
* This is a quick hack for testing client-side named pipes.
- * Its purpose is to test the ability to connect to a server,
- * open a pipe, send and receive data. The "hack" aspect is
- * the use of hand-crafted RPC messages, which allows testing
- * of the named pipe API separately from the RPC libraries.
- *
- * I captured the two small name pipe messages sent when
- * requesting a share list via RPC over /pipe/srvsvc and
- * dropped them into the arrays below (bind and enum).
- * This program sends the two messages (with adjustments)
- * and just dumps whatever comes back over the pipe.
- * Use wireshark if you want to see decoded messages.
+ * Its purpose is to test SMB named-pipe interface separately
+ * from the RPC implementation. It's a "hack" because it uses
+ * hand-crafted RPC messages (extracted from network traffic).
*/
-extern char *optarg;
-extern int optind, opterr, optopt;
-
/* This is a DCE/RPC bind call for "srvsvc". */
static const uchar_t
srvsvc_bind[] = {
@@ -95,175 +85,35 @@ srvsvc_enum2[] = {
static uchar_t sendbuf[1024];
static uchar_t recvbuf[4096];
-static char *server;
-
-static int pipetest(struct smb_ctx *);
+/*
+ * Print strings found in the buffer.
+ */
static void
-srvenum_usage(void)
+pstrings(const uchar_t *buf, int len)
{
- printf("usage: srvenum [-d domain][-u user][-p passwd] server\n");
- exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
- int c, error;
- struct smb_ctx *ctx = NULL;
- char *dom = NULL;
- char *usr = NULL;
- char *pw = NULL;
-
- while ((c = getopt(argc, argv, "vd:u:p:")) != -1) {
- switch (c) {
- case 'v':
- smb_verbose = 1;
- break;
-
- case 'd':
- dom = optarg;
- break;
- case 'u':
- usr = optarg;
- break;
- case 'p':
- pw = optarg;
- break;
- case '?':
- srvenum_usage();
- break;
+ const uchar_t *p = buf;
+ uint16_t u2;
+ boolean_t instr = B_FALSE;
+
+ while (len > 2) {
+ u2 = *p++;
+ u2 |= (*p++) << 8;
+ len -= 2;
+
+ if ((u2 & 0xFF80) == 0 && isprint(u2)) {
+ /* printable */
+ instr = B_TRUE;
+ putchar(u2);
+ } else {
+ /* not printalbe */
+ if (instr)
+ putchar('\n');
+ instr = B_FALSE;
}
}
- if (optind >= argc)
- srvenum_usage();
- server = argv[optind];
-
- if (pw != NULL && (dom == NULL || usr == NULL)) {
- fprintf(stderr, "%s: -p arg requires -d dom -u usr\n",
- argv[0]);
- srvenum_usage();
- }
-
- /*
- * This section is intended to demonstrate how an
- * RPC client library might use this interface.
- */
- error = smb_ctx_alloc(&ctx);
- if (error) {
- fprintf(stderr, "%s: smb_ctx_alloc failed\n", argv[0]);
- goto out;
- }
-
- /*
- * Set server, share, domain, user
- * (in the ctx handle).
- */
- smb_ctx_setfullserver(ctx, server);
- smb_ctx_setshare(ctx, "IPC$", USE_IPC);
- if (dom)
- smb_ctx_setdomain(ctx, dom, B_TRUE);
- if (usr)
- smb_ctx_setuser(ctx, usr, B_TRUE);
- if (pw)
- smb_ctx_setpassword(ctx, pw, NULL);
-
-
- /*
- * If this code were in smbutil or mount_smbfs, it would
- * get system and $HOME/.nsmbrc settings here, like this:
- */
-#if 0
- error = smb_ctx_readrc(ctx);
- if (error) {
- fprintf(stderr, "%s: smb_ctx_readrc failed\n", argv[0]);
- goto out;
- }
-#endif
-
- /*
- * Resolve the server address,
- * setup derived defaults.
- */
- error = smb_ctx_resolve(ctx);
- if (error) {
- fprintf(stderr, "%s: smb_ctx_resolve failed\n", argv[0]);
- goto out;
- }
-
- /*
- * Get the session and tree.
- */
- error = smb_ctx_get_ssn(ctx);
- if (error) {
- fprintf(stderr, "//%s: login failed, error %d\n",
- server, error);
- goto out;
- }
- error = smb_ctx_get_tree(ctx);
- if (error) {
- fprintf(stderr, "//%s/%s: tree connect failed, %d\n",
- server, "IPC$", error);
- goto out;
- }
-
- /*
- * Do some named pipe I/O.
- */
- error = pipetest(ctx);
- if (error) {
- fprintf(stderr, "pipetest, %d\n", error);
- goto out;
- }
-
-out:
- smb_ctx_free(ctx);
-
- return ((error) ? 1 : 0);
-}
-
-static void
-hexdump(const uchar_t *buf, int len) {
- int idx;
- char ascii[24];
- char *pa = ascii;
-
- memset(ascii, '\0', sizeof (ascii));
-
- idx = 0;
- while (len--) {
- if ((idx & 15) == 0) {
- printf("[%04X] ", idx);
- pa = ascii;
- }
- if (*buf > ' ' && *buf <= '~')
- *pa++ = *buf;
- else
- *pa++ = '.';
- printf("%02x ", *buf++);
-
- idx++;
- if ((idx & 7) == 0) {
- *pa++ = ' ';
- putchar(' ');
- }
- if ((idx & 15) == 0) {
- *pa = '\0';
- printf("%s\n", ascii);
- }
- }
-
- if ((idx & 15) != 0) {
- *pa = '\0';
- /* column align the last ascii row */
- do {
- printf(" ");
- idx++;
- if ((idx & 7) == 0)
- putchar(' ');
- } while ((idx & 15) != 0);
- printf("%s\n", ascii);
- }
+ if (instr)
+ putchar('\n');
}
/*
@@ -309,10 +159,6 @@ do_bind(int fid)
printf("xact bind, err=%d\n", err);
return (err);
}
- if (smb_verbose) {
- printf("bind ack, len=%d\n", len);
- hexdump(recvbuf, len);
- }
if (more > 0) {
if (more > sizeof (recvbuf)) {
printf("bogus more=%d\n", more);
@@ -325,17 +171,13 @@ do_bind(int fid)
printf("read enum resp, err=%d\n", err);
return (err);
}
- if (smb_verbose) {
- printf("bind ack (more), len=%d\n", len);
- hexdump(recvbuf, len);
- }
}
return (0);
}
static int
-do_enum(int fid)
+do_enum(char *server, int fid)
{
int err, len, rlen, wlen;
uchar_t *p;
@@ -393,18 +235,22 @@ do_enum(int fid)
return (err);
}
- /* Just dump the response data. */
- printf("enum recv, len=%d\n", rlen);
- hexdump(recvbuf, rlen);
+ /*
+ * Just dump strings found in the response data.
+ * Skip the first 0x90 (RPC wrappers).
+ */
+ printf("enum strings\n");
+ pstrings(recvbuf + 0x90, rlen - 0x90);
return (0);
}
-static int
-pipetest(struct smb_ctx *ctx)
+int
+list_shares(struct smb_ctx *ctx)
{
static char path[] = "/srvsvc";
static uchar_t key[16];
+ char *server = ctx->ct_srvname;
int err, fd;
printf("open pipe: %s\n", path);
@@ -426,7 +272,7 @@ pipetest(struct smb_ctx *ctx)
printf("do_bind: %d\n", err);
goto out;
}
- err = do_enum(fd);
+ err = do_enum(server, fd);
if (err)
printf("do_enum: %d\n", err);
diff --git a/usr/src/cmd/fs.d/smbclnt/test/Makefile b/usr/src/cmd/fs.d/smbclnt/test/Makefile
deleted file mode 100644
index affd6d9a00..0000000000
--- a/usr/src/cmd/fs.d/smbclnt/test/Makefile
+++ /dev/null
@@ -1,85 +0,0 @@
-#
-# 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.
-# Copyright (c) 2019, Joyent, Inc.
-#
-
-include $(SRC)/cmd/Makefile.cmd
-
-PROG= srvenum srvinfo tconn
-OBJS = $(PROG:%=%.o)
-SRCS = $(OBJS:%.o=%.c)
-
-# ROOTFS_PROG= $(LIBPROG)
-# include ../../Makefile.fstype
-
-ROOTOPTPKG = $(ROOT)/opt/smbcl-tests
-TESTDIR = $(ROOTOPTPKG)/tests
-INST_CMDS = $(PROG:%=$(TESTDIR)/%)
-
-# OBJS= $(LIBPROG).o
-# SRCS= $(LIBPROG).c $(FSLIBSRC)
-
-CPPFLAGS += -I../../../../uts/common
-CPPFLAGS += -I../../../../lib/libsmbfs
-
-LDLIBS += -R'$$ORIGIN/../../../usr/lib'
-LDLIBS += -lsmbfs
-LINTLIBS= -L$(ROOTLIB) -lsmbfs
-
-CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-unused-variable
-CSTD= $(CSTD_GNU99)
-
-# not linted
-SMATCH=off
-
-LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2
-
-# CLOBBERFILES += $(LIBPROG)
-
-all: $(PROG)
-
-install: all $(ROOTOPTPKG) $(TESTDIR) $(INST_CMDS)
-
-lint:
- for f in $(SRCS); do ;\
- $(LINT.c) $$f $(LINTLIBS) ; done
-
-clobber: clean
- -$(RM) $(PROG)
-
-clean:
- -$(RM) $(OBJS)
-
-$(ROOTOPTPKG):
- $(INS.dir)
-
-$(TESTDIR):
- $(INS.dir)
-
-$(TESTDIR)/%: %
- $(INS.file)
-
-.KEEP_STATE:
diff --git a/usr/src/cmd/fs.d/smbclnt/test/srvinfo.c b/usr/src/cmd/fs.d/smbclnt/test/srvinfo.c
deleted file mode 100644
index 81ba8c9afc..0000000000
--- a/usr/src/cmd/fs.d/smbclnt/test/srvinfo.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
- */
-
-/*
- * Test program for the smbfs named pipe API.
- */
-
-#include <sys/types.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <libintl.h>
-
-#include <netsmb/smbfs_api.h>
-
-/*
- * This is a quick hack for testing client-side named pipes.
- * Its purpose is to test the ability to connect to a server,
- * open a pipe, send and receive data. The "hack" aspect is
- * the use of hand-crafted RPC messages, which allows testing
- * of the named pipe API separately from the RPC libraries.
- *
- * I captured the two small name pipe messages sent when
- * requesting a server info via RPC over /pipe/srvsvc and
- * dropped them into the arrays below (bind and info).
- * This program sends the two messages (with adjustments)
- * and just dumps whatever comes back over the pipe.
- * Use wireshark if you want to see decoded messages.
- */
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-
-/* This is a DCE/RPC bind call for "srvsvc". */
-static const uchar_t
-srvsvc_bind[] = {
- 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
- 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
- 0xc8, 0x4f, 0x32, 0x4b, 0x70, 0x16, 0xd3, 0x01,
- 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88,
- 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
- 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
- 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 };
-
-/* This is a srvsvc "get server info" call, in two parts */
-static const uchar_t
-srvsvc_info[] = {
- 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
-#define INFO_RPCLEN_OFF 8
- /* V - RPC frag length */
- 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* ... and the operation number is: VVVV */
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x15, 0x00,
-#define INFO_SLEN1_OFF 28
-#define INFO_SLEN2_OFF 36
- /* server name, length 14 vv ... */
- 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00 };
- /* UNC server here, i.e.: "\\192.168.1.6" */
-
-static uchar_t sendbuf[1024];
-static uchar_t recvbuf[1024];
-static char *server;
-
-static int pipetest(struct smb_ctx *);
-
-static void
-srvinfo_usage(void)
-{
- printf("usage: srvinfo [-d domain][-u user][-p passwd] server\n");
- exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
- int c, error;
- struct smb_ctx *ctx = NULL;
- char *dom = NULL;
- char *usr = NULL;
- char *pw = NULL;
-
- while ((c = getopt(argc, argv, "vd:u:p:")) != -1) {
- switch (c) {
- case 'v':
- smb_verbose = 1;
- break;
-
- case 'd':
- dom = optarg;
- break;
- case 'u':
- usr = optarg;
- break;
- case 'p':
- pw = optarg;
- break;
- case '?':
- srvinfo_usage();
- break;
- }
- }
- if (optind >= argc)
- srvinfo_usage();
- server = argv[optind];
-
- if (pw != NULL && (dom == NULL || usr == NULL)) {
- fprintf(stderr, "%s: -p arg requires -d dom -u usr\n",
- argv[0]);
- srvinfo_usage();
- }
-
- /*
- * This section is intended to demonstrate how an
- * RPC client library might use this interface.
- */
- error = smb_ctx_alloc(&ctx);
- if (error) {
- fprintf(stderr, "%s: smb_ctx_alloc failed\n", argv[0]);
- goto out;
- }
-
- /*
- * Set server, share, domain, user
- * (in the ctx handle).
- */
- smb_ctx_setfullserver(ctx, server);
- smb_ctx_setshare(ctx, "IPC$", USE_IPC);
- if (dom)
- smb_ctx_setdomain(ctx, dom, B_TRUE);
- if (usr)
- smb_ctx_setuser(ctx, usr, B_TRUE);
- if (pw)
- smb_ctx_setpassword(ctx, pw, NULL);
-
-
- /*
- * If this code were in smbutil or mount_smbfs, it would
- * get system and $HOME/.nsmbrc settings here, like this:
- */
-#if 0
- error = smb_ctx_readrc(ctx);
- if (error) {
- fprintf(stderr, "%s: smb_ctx_readrc failed\n", argv[0]);
- goto out;
- }
-#endif
-
- /*
- * Resolve the server address,
- * setup derived defaults.
- */
- error = smb_ctx_resolve(ctx);
- if (error) {
- fprintf(stderr, "%s: smb_ctx_resolve failed\n", argv[0]);
- goto out;
- }
-
- /*
- * Get the session and tree.
- */
- error = smb_ctx_get_ssn(ctx);
- if (error) {
- fprintf(stderr, "//%s: login failed, error %d\n",
- server, error);
- goto out;
- }
- error = smb_ctx_get_tree(ctx);
- if (error) {
- fprintf(stderr, "//%s/%s: tree connect failed, %d\n",
- server, "IPC$", error);
- goto out;
- }
-
- /*
- * Do some named pipe I/O.
- */
- error = pipetest(ctx);
- if (error) {
- fprintf(stderr, "pipetest, %d\n", error);
- goto out;
- }
-
-out:
- smb_ctx_free(ctx);
-
- return ((error) ? 1 : 0);
-}
-
-static void
-hexdump(const uchar_t *buf, int len) {
- int ofs = 0;
-
- while (len--) {
- if (ofs % 16 == 0)
- printf("\n%02X: ", ofs);
- printf("%02x ", *buf++);
- ofs++;
- }
- printf("\n");
-}
-
-/*
- * Put a unicode UNC server name, including the null.
- * Quick-n-dirty, just for this test...
- */
-static int
-put_uncserver(const char *s, uchar_t *buf)
-{
- uchar_t *p = buf;
- char c;
-
- *p++ = '\\'; *p++ = '\0';
- *p++ = '\\'; *p++ = '\0';
-
- do {
- c = *s++;
- if (c == '/')
- c = '\\';
- *p++ = c;
- *p++ = '\0';
-
- } while (c != 0);
-
- return (p - buf);
-}
-
-/* Get a little-endian int. Just for testing. */
-static int
-getint(const uchar_t *p)
-{
- return (p[0] + (p[1]<<8) + (p[2]<<16) + (p[3]<<24));
-}
-
-/*
- * Send the bind and read the ack.
- * This tests smb_fh_xactnp.
- */
-static int
-do_bind(int fid)
-{
- int err, len, more;
-
- more = 0;
- len = sizeof (recvbuf);
- err = smb_fh_xactnp(fid,
- sizeof (srvsvc_bind), (char *)srvsvc_bind,
- &len, (char *)recvbuf, &more);
- if (err) {
- printf("xact bind, err=%d\n", err);
- return (err);
- }
- if (smb_verbose) {
- printf("bind ack, len=%d\n", len);
- hexdump(recvbuf, len);
- }
- if (more > 0) {
- if (more > sizeof (recvbuf)) {
- printf("bogus more=%d\n", more);
- more = sizeof (recvbuf);
- }
- len = smb_fh_read(fid, 0,
- more, (char *)recvbuf);
- if (len == -1) {
- err = EIO;
- printf("read info resp, err=%d\n", err);
- return (err);
- }
- if (smb_verbose) {
- printf("bind ack (more), len=%d\n", len);
- hexdump(recvbuf, len);
- }
- }
-
- return (0);
-}
-
-static int
-do_info(int fid)
-{
- int err, len, rlen, wlen, x;
- uchar_t *p;
-
- /*
- * Build the info request - two parts.
- * See above: srvsvc_info
- *
- * First part: RPC header, etc.
- */
- p = sendbuf;
- len = sizeof (srvsvc_info); /* 40 */
- memcpy(p, srvsvc_info, len);
- p += len;
-
- /* Second part: UNC server name */
- len = put_uncserver(server, p);
- p += len;
- sendbuf[INFO_SLEN1_OFF] = len / 2;
- sendbuf[INFO_SLEN2_OFF] = len / 2;
-
- /* Third part: level, etc. (align4) */
- for (len = (p - sendbuf) & 3; len; len--)
- *p++ = '\0';
- *p++ = 101; /* the "level" */
- *p++ = 0; *p++ = 0; *p++ = 0;
-
- /*
- * Compute total length, and fixup RPC header.
- */
- len = p - sendbuf;
- sendbuf[INFO_RPCLEN_OFF] = len;
-
- /*
- * Send the info request, read the response.
- * This tests smb_fh_write, smb_fh_read.
- */
- wlen = smb_fh_write(fid, 0, len, (char *)sendbuf);
- if (wlen == -1) {
- err = errno;
- printf("write info req, err=%d\n", err);
- return (err);
- }
- if (wlen != len) {
- printf("write info req, short write %d\n", wlen);
- return (EIO);
- }
-
- rlen = smb_fh_read(fid, 0,
- sizeof (recvbuf), (char *)recvbuf);
- if (rlen == -1) {
- err = errno;
- printf("read info resp, err=%d\n", err);
- return (err);
- }
-
- if (smb_verbose) {
- printf("info recv, len=%d\n", rlen);
- hexdump(recvbuf, rlen);
- }
-
- x = getint(recvbuf + 4);
- if (x != 0x10) {
- printf("Data representation 0x%x not supported\n", x);
- return (ENOTSUP);
- }
- printf("Platform Id: %d\n", getint(recvbuf + 0x20));
- printf("Version Major: %d\n", getint(recvbuf + 0x28));
- printf("Version Minor: %d\n", getint(recvbuf + 0x2c));
- printf("Srv type flags: 0x%x\n", getint(recvbuf + 0x30));
-
- return (0);
-}
-
-static int
-pipetest(struct smb_ctx *ctx)
-{
- static char path[] = "/srvsvc";
- static uchar_t key[16];
- int err, fd;
-
- printf("open pipe: %s\n", path);
- fd = smb_fh_open(ctx, path, O_RDWR);
- if (fd < 0) {
- perror(path);
- return (errno);
- }
-
- /* Test this too. */
- err = smb_fh_getssnkey(fd, key, sizeof (key));
- if (err) {
- printf("getssnkey: %d\n", err);
- goto out;
- }
-
- err = do_bind(fd);
- if (err) {
- printf("do_bind: %d\n", err);
- goto out;
- }
- err = do_info(fd);
- if (err)
- printf("do_info: %d\n", err);
-
-out:
- smb_fh_close(fd);
- return (err);
-}
diff --git a/usr/src/cmd/fs.d/smbclnt/test/tconn.c b/usr/src/cmd/fs.d/smbclnt/test/tconn.c
deleted file mode 100644
index bfeac98fe0..0000000000
--- a/usr/src/cmd/fs.d/smbclnt/test/tconn.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
- */
-
-/*
- * Test program for opening an SMB connection directly.
- */
-
-#include <sys/types.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <libintl.h>
-
-#include <netsmb/smb_lib.h>
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-extern int smb_iod_connect(struct smb_ctx *);
-
-static char *server;
-
-static void
-tconn_usage(void)
-{
- printf("usage: tconn [-d domain][-u user][-p passwd] server\n");
- exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
- int c, error, aflags;
- struct smb_ctx *ctx = NULL;
- char *dom = NULL;
- char *usr = NULL;
- char *pw = NULL;
- char *secopt = NULL;
- struct addrinfo *ai;
-
- while ((c = getopt(argc, argv, "vd:p:s:u:")) != -1) {
- switch (c) {
- case 'v':
- smb_debug = 1;
- smb_verbose = 1;
- break;
-
- case 'd':
- dom = optarg;
- break;
- case 'u':
- usr = optarg;
- break;
- case 'p':
- pw = optarg;
- break;
- case 's':
- secopt = optarg;
- break;
- case '?':
- tconn_usage();
- break;
- }
- }
- if (optind >= argc)
- tconn_usage();
- server = argv[optind];
-
- if (pw != NULL && (dom == NULL || usr == NULL)) {
- fprintf(stderr, "%s: -p arg requires -d dom -u usr\n",
- argv[0]);
- tconn_usage();
- }
-
- /*
- * This section is intended to demonstrate how an
- * RPC client library might use this interface.
- */
- error = smb_ctx_alloc(&ctx);
- if (error) {
- fprintf(stderr, "%s: smb_ctx_alloc failed\n", argv[0]);
- goto out;
- }
-
- /*
- * Set server, share, domain, user
- * (in the ctx handle).
- */
- smb_ctx_setfullserver(ctx, server);
- smb_ctx_setshare(ctx, "IPC$", USE_IPC);
- if (dom)
- smb_ctx_setdomain(ctx, dom, B_TRUE);
- if (usr)
- smb_ctx_setuser(ctx, usr, B_TRUE);
- if (pw)
- smb_ctx_setpassword(ctx, pw, NULL);
-
- /*
- * Hackish option to override the Authentication Type flags.
- * Sorry about exposing the flag values here, but this is
- * really a programmer's test tool. See smbfs_api.h for
- * the SMB_AT_... flag values.
- */
- if (secopt != NULL) {
- aflags = atoi(secopt);
- if (aflags < 1 || aflags > 0x1f) {
- fprintf(stderr, "%s: -s {0..31}\n", argv[0]);
- tconn_usage();
- }
- smb_ctx_setauthflags(ctx, aflags);
- }
-
- /*
- * Resolve the server address,
- * setup derived defaults.
- */
- error = smb_ctx_resolve(ctx);
- if (error) {
- fprintf(stderr, "%s: smb_ctx_resolve failed\n", argv[0]);
- goto out;
- }
-
- if ((ai = ctx->ct_addrinfo) == NULL) {
- fprintf(stderr, "%s: no ct_addrinfo\n", argv[0]);
- goto out;
- }
- memcpy(&ctx->ct_srvaddr, ai->ai_addr, ai->ai_addrlen);
-
- /*
- * If this code were in smbutil or mount_smbfs, it would
- * get system and $HOME/.nsmbrc settings here, like this:
- */
- error = smb_iod_connect(ctx);
- if (error) {
- fprintf(stderr, "%s: smb_iod_connect failed\n", argv[0]);
- goto out;
- }
-
- printf("Yea, we connected!\n");
-
-out:
- smb_ctx_free(ctx);
-
- return ((error) ? 1 : 0);
-}