summaryrefslogtreecommitdiff
path: root/usr/src/cmd/fs.d/smbclnt
diff options
context:
space:
mode:
authorGordon Ross <Gordon.Ross@Sun.COM>2009-07-02 12:58:38 -0400
committerGordon Ross <Gordon.Ross@Sun.COM>2009-07-02 12:58:38 -0400
commit613a2f6ba31e891e3d947a356daf5e563d43c1ce (patch)
tree0f7f3438a5792c05ed156a43e8cd84f25695d7f2 /usr/src/cmd/fs.d/smbclnt
parentbf73eaa5a8ea69ac16a1e6e7b736f09286d073f9 (diff)
downloadillumos-joyent-613a2f6ba31e891e3d947a356daf5e563d43c1ce.tar.gz
6584198 SMB Client needs authentication improvements
6587713 Need to reconnect after server disconnect --HG-- rename : usr/src/lib/libsmbfs/netsmb/smbfs_isec.h => usr/src/lib/libsmbfs/smb/acl_nt.h
Diffstat (limited to 'usr/src/cmd/fs.d/smbclnt')
-rw-r--r--usr/src/cmd/fs.d/smbclnt/Makefile16
-rw-r--r--usr/src/cmd/fs.d/smbclnt/lsacl/Makefile6
-rw-r--r--usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c9
-rw-r--r--usr/src/cmd/fs.d/smbclnt/mount/Makefile19
-rw-r--r--usr/src/cmd/fs.d/smbclnt/mount/mount.c193
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbiod/Makefile70
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c362
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/Makefile31
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/common.h34
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/lookup.c9
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/print.c182
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c12
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/status.c19
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/view.c185
14 files changed, 924 insertions, 223 deletions
diff --git a/usr/src/cmd/fs.d/smbclnt/Makefile b/usr/src/cmd/fs.d/smbclnt/Makefile
index 8845071f42..9e66620c60 100644
--- a/usr/src/cmd/fs.d/smbclnt/Makefile
+++ b/usr/src/cmd/fs.d/smbclnt/Makefile
@@ -18,20 +18,20 @@
#
# CDDL HEADER END
#
+
#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# cmd/fs.d/smbclnt/Makefile
+
#
-# cmd/fs.d/smbclnt contains the CIFS client commands
+# cmd/fs.d/smbclnt/Makefile
+# contains the CIFS client commands
#
include $(SRC)/Makefile.master
-SUBDIRS_CATALOG= smbutil mount umount
+SUBDIRS_CATALOG= smbutil smbiod mount umount
SUBDIRS= $(SUBDIRS_CATALOG) lsacl svc
# for messaging catalog files
@@ -50,9 +50,9 @@ catalog:= TARGET= catalog
.PARALLEL: $(SUBDIRS)
-install clean clobber: $(SUBDIRS)
+all install clean clobber lint: $(SUBDIRS)
-all lint catalog: $(SUBDIRS_CATALOG)
+catalog: $(SUBDIRS_CATALOG)
$(RM) $(POFILE)
cat $(POFILES) > $(POFILE)
diff --git a/usr/src/cmd/fs.d/smbclnt/lsacl/Makefile b/usr/src/cmd/fs.d/smbclnt/lsacl/Makefile
index 22ce8510c0..4fbb347a73 100644
--- a/usr/src/cmd/fs.d/smbclnt/lsacl/Makefile
+++ b/usr/src/cmd/fs.d/smbclnt/lsacl/Makefile
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
FSTYPE= smbfs
LIBPROG= lsacl
@@ -38,8 +36,6 @@ LDLIBS += -lsmbfs -lsec
CFLAGS += $(CCVERBOSE)
C99MODE= $(C99_ENABLE)
-CPPFLAGS += -I$(SRC)/lib/libsmbfs \
- -I$(SRC)/uts/common/smbclnt -I$(SRC)/uts/common
CLOBBERFILES += $(LIBPROG)
diff --git a/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c b/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c
index 9f73f8eb1e..1285251898 100644
--- a/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c
+++ b/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* This is the smbfs/lsacl command.
* (just for testing - not installed)
@@ -42,7 +40,6 @@
#include <unistd.h>
#include <string.h>
-#include <netsmb/smb_lib.h>
#include <netsmb/smbfs_acl.h>
char *progname;
@@ -81,7 +78,7 @@ main(int argc, char **argv)
error = smbfs_acl_getsd(fd, 7, &sd);
if (error) {
fprintf(stderr, "getsd: %s\n",
- smb_strerror(error));
+ strerror(error));
exit(1);
}
@@ -101,7 +98,7 @@ main(int argc, char **argv)
error = smbfs_acl_get(fd, &acl, &uid, &gid);
if (error) {
fprintf(stderr, "getacl: %s\n",
- smb_strerror(error));
+ strerror(error));
exit(1);
}
printf("Solaris security data:\n");
diff --git a/usr/src/cmd/fs.d/smbclnt/mount/Makefile b/usr/src/cmd/fs.d/smbclnt/mount/Makefile
index d23874bf57..5d5da5ec5c 100644
--- a/usr/src/cmd/fs.d/smbclnt/mount/Makefile
+++ b/usr/src/cmd/fs.d/smbclnt/mount/Makefile
@@ -19,10 +19,10 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
+
#
# cmd/fs.d/smbclnt/mount/Makefile
#
@@ -36,15 +36,20 @@ include ../../Makefile.fstype
OBJS= $(LIBPROG).o
SRCS= $(LIBPROG).c $(FSLIBSRC)
POFILE= $(LIBPROG).po
-
-LDLIBS += -lsmbfs -lscf
+CLOBBERFILES += $(LIBPROG)
CFLAGS += $(CCVERBOSE)
C99MODE= $(C99_ENABLE)
-CPPFLAGS += -I$(SRC)/lib/libsmbfs \
- -I$(SRC)/uts/common/smbclnt -I$(SRC)/uts/common
-CLOBBERFILES += $(LIBPROG)
+LDLIBS += -lsmbfs -lscf
+
+CPPFLAGS += -I$(SRC)/uts/common -I$(SRC)/lib/libsmbfs
+
+# uncomment these for dbx debugging
+#COPTFLAG = -g
+#CTF_FLAGS =
+#CTFCONVERT_O=
+#CTFMERGE_LIB=
.KEEP_STATE:
diff --git a/usr/src/cmd/fs.d/smbclnt/mount/mount.c b/usr/src/cmd/fs.d/smbclnt/mount/mount.c
index 61bc463321..9068d093b6 100644
--- a/usr/src/cmd/fs.d/smbclnt/mount/mount.c
+++ b/usr/src/cmd/fs.d/smbclnt/mount/mount.c
@@ -37,11 +37,6 @@
* Use is subject to license terms.
*/
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-#include <sys/mount.h>
-
#include <stdio.h>
#include <string.h>
#include <strings.h>
@@ -57,33 +52,38 @@
#include <locale.h>
#include <libscf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <sys/mount.h>
#include <sys/mntent.h>
#include <sys/mnttab.h>
-#include <cflib.h>
-
-#include <netsmb/smb.h>
+/* This needs to know ctx->ct_dev_fd, etc. */
#include <netsmb/smb_lib.h>
#include <sys/fs/smbfs_mount.h>
#include "mntopts.h"
+extern char *optarg;
+extern int optind;
+
static char mount_point[MAXPATHLEN + 1];
static void usage(void);
-static int setsubopt(int, char *, struct smbfs_args *);
+static int setsubopt(smb_ctx_t *, struct smbfs_args *, int, char *);
/* smbfs options */
-#define MNTOPT_RETRY "retry"
-#define MNTOPT_TIMEOUT "timeout"
+#define MNTOPT_DOMAIN "domain"
+#define MNTOPT_USER "user"
#define MNTOPT_DIRPERMS "dirperms"
#define MNTOPT_FILEPERMS "fileperms"
#define MNTOPT_GID "gid"
#define MNTOPT_UID "uid"
#define MNTOPT_NOPROMPT "noprompt"
-#define OPT_RETRY 1
-#define OPT_TIMEOUT 2
+#define OPT_DOMAIN 1
+#define OPT_USER 2
#define OPT_DIRPERMS 3
#define OPT_FILEPERMS 4
#define OPT_GID 5
@@ -108,8 +108,8 @@ struct smbfsopts {
};
struct smbfsopts opts[] = {
- {MNTOPT_RETRY, OPT_RETRY},
- {MNTOPT_TIMEOUT, OPT_TIMEOUT},
+ {MNTOPT_DOMAIN, OPT_DOMAIN},
+ {MNTOPT_USER, OPT_USER},
{MNTOPT_DIRPERMS, OPT_DIRPERMS},
{MNTOPT_FILEPERMS, OPT_FILEPERMS},
{MNTOPT_GID, OPT_GID},
@@ -132,22 +132,20 @@ static int Oflg = 0; /* Overlay mounts */
static int qflg = 0; /* quiet - don't print warnings on bad options */
static int ro = 0; /* read-only mount */
static int noprompt = 0; /* don't prompt for password */
-static int retry = -1;
-static int timeout = -1;
#define RET_ERR 33
#define SERVICE "svc:/network/smb/client:default"
+struct smbfs_args mdata;
+struct mnttab mnt;
+char optbuf[MAX_MNTOPT_STR];
+
int
main(int argc, char *argv[])
{
- struct smb_ctx sctx, *ctx = &sctx;
- struct smbfs_args mdata;
+ struct smb_ctx *ctx = NULL;
struct stat st;
- int opt, error, mntflags;
- struct mnttab mnt;
- struct mnttab *mntp = &mnt;
- char optbuf[MAX_MNTOPT_STR];
+ int opt, error, err2, mntflags;
static char *fstype = MNTTYPE_SMBFS;
char *env, *state;
@@ -174,8 +172,9 @@ main(int argc, char *argv[])
fprintf(stderr,
gettext("mount_smbfs: service \"%s\" not enabled.\n"),
SERVICE);
- exit(1);
+ exit(RET_ERR);
}
+ free(state);
/* Debugging support. */
if ((env = getenv("SMBFS_DEBUG")) != NULL) {
@@ -186,22 +185,35 @@ main(int argc, char *argv[])
error = smb_lib_init();
if (error)
- exit(error);
+ exit(RET_ERR);
mnt.mnt_mntopts = optbuf;
mntflags = MS_DATA;
+
bzero(&mdata, sizeof (mdata));
+ mdata.version = SMBFS_VERSION; /* smbfs mount version */
mdata.uid = (uid_t)-1;
mdata.gid = (gid_t)-1;
mdata.caseopt = SMB_CS_NONE;
- error = smb_ctx_init(ctx, argc, argv, SMBL_SHARE, SMBL_SHARE,
- SMB_ST_DISK);
+ error = smb_ctx_alloc(&ctx);
if (error)
- exit(error);
+ exit(RET_ERR);
+
+ /*
+ * Parse the UNC path so we have the server (etc.)
+ * that we need during rcfile+sharectl parsing.
+ */
+ if (argc < 3)
+ usage();
+ error = smb_ctx_parseunc(ctx, argv[argc - 2],
+ SMBL_SHARE, SMBL_SHARE, USE_DISKDEV, NULL);
+ if (error)
+ exit(RET_ERR);
+
error = smb_ctx_readrc(ctx);
if (error)
- exit(error);
+ exit(RET_ERR);
while ((opt = getopt(argc, argv, "ro:Oq")) != -1) {
switch (opt) {
@@ -254,7 +266,8 @@ main(int argc, char *argv[])
*comma = ',';
continue;
}
- ret = setsubopt(opts[i].index, soptval, &mdata);
+ ret = setsubopt(ctx, &mdata,
+ opts[i].index, soptval);
if (ret != 0)
exit(RET_ERR);
if (equals)
@@ -280,24 +293,19 @@ main(int argc, char *argv[])
mntflags |= MS_RDONLY;
/* convert "rw"->"ro" */
- if (p = strstr(mntp->mnt_mntopts, "rw")) {
+ if (p = strstr(mnt.mnt_mntopts, "rw")) {
if (*(p+2) == ',' || *(p+2) == '\0')
*(p+1) = 'o';
}
}
+ if (optind + 2 != argc)
+ usage();
+
mnt.mnt_special = argv[optind];
mnt.mnt_mountp = argv[optind+1];
- mdata.version = SMBFS_VERSION; /* smbfs mount version */
-
- if (optind == argc - 2)
- optind++;
-
- if (optind != argc - 1)
- usage();
- realpath(unpercent(argv[optind]), mount_point);
-
+ realpath(argv[optind+1], mount_point);
if (stat(mount_point, &st) == -1)
err(EX_OSERR, gettext("could not find mount point %s"),
mount_point);
@@ -325,90 +333,76 @@ main(int argc, char *argv[])
mdata.dir_mode |= S_IXOTH;
}
- /*
- * XXX: The driver can fill these in more reliably,
- * so why do we set them here? (Just set both = -1)
- */
- ctx->ct_ssn.ioc_owner = ctx->ct_sh.ioc_owner = getuid();
- ctx->ct_ssn.ioc_group = ctx->ct_sh.ioc_group = getgid();
- opt = 0;
- if (mdata.dir_mode & S_IXGRP)
- opt |= SMBM_EXECGRP;
- if (mdata.dir_mode & S_IXOTH)
- opt |= SMBM_EXECOTH;
- ctx->ct_ssn.ioc_rights |= opt;
- ctx->ct_sh.ioc_rights |= opt;
+ ctx->ct_ssn.ssn_owner = SMBM_ANY_OWNER;
if (noprompt)
ctx->ct_flags |= SMBCF_NOPWD;
- if (retry != -1)
- ctx->ct_ssn.ioc_retrycount = retry;
- if (timeout != -1)
- ctx->ct_ssn.ioc_timeout = timeout;
/*
- * If we got our password from the keychain and get an
- * authorization error, we come back here to obtain a new
- * password from user input.
+ * Resolve the server address,
+ * setup derived defaults.
*/
-reauth:
error = smb_ctx_resolve(ctx);
if (error)
- exit(error);
-
- mdata.devfd = ctx->ct_fd; /* file descriptor */
+ exit(RET_ERR);
+ /*
+ * Have server, share, etc. from above:
+ * smb_ctx_scan_argv, option settings.
+ * Get the session and tree.
+ */
again:
- error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
- if (error == ENOENT && ctx->ct_origshare) {
- strcpy(ctx->ct_sh.ioc_share, ctx->ct_origshare);
- free(ctx->ct_origshare);
- ctx->ct_origshare = NULL;
- goto again; /* try again using share name as given */
+ error = smb_ctx_get_ssn(ctx);
+ if (error == EAUTH && noprompt == 0) {
+ err2 = smb_get_authentication(ctx);
+ if (err2 == 0)
+ goto again;
}
- if (ctx->ct_flags & SMBCF_KCFOUND && smb_autherr(error)) {
- ctx->ct_ssn.ioc_password[0] = '\0';
- smb_error(gettext("main(lookup): bad keychain entry"), 0);
- ctx->ct_flags |= SMBCF_KCBAD;
- goto reauth;
+ if (error) {
+ smb_error(gettext("//%s: login failed"),
+ error, ctx->ct_fullserver);
+ exit(RET_ERR);
+ }
+
+ error = smb_ctx_get_tree(ctx);
+ if (error) {
+ smb_error(gettext("//%s/%s: tree connect failed"),
+ error, ctx->ct_fullserver, ctx->ct_origshare);
+ exit(RET_ERR);
}
- if (error)
- exit(error);
- mdata.version = SMBFS_VERSION;
- mdata.devfd = ctx->ct_fd;
+ /*
+ * Have tree connection, now mount it.
+ */
+ mdata.devfd = ctx->ct_dev_fd;
- if (mount(mntp->mnt_special, mntp->mnt_mountp,
+ if (mount(mnt.mnt_special, mnt.mnt_mountp,
mntflags, fstype, &mdata, sizeof (mdata),
- mntp->mnt_mntopts, MAX_MNTOPT_STR) < 0) {
+ mnt.mnt_mntopts, MAX_MNTOPT_STR) < 0) {
if (errno != ENOENT) {
err(EX_OSERR, gettext("mount_smbfs: %s"),
- mntp->mnt_mountp);
+ mnt.mnt_mountp);
} else {
struct stat sb;
- if (stat(mntp->mnt_mountp, &sb) < 0 &&
+ if (stat(mnt.mnt_mountp, &sb) < 0 &&
errno == ENOENT)
err(EX_OSERR, gettext("mount_smbfs: %s"),
- mntp->mnt_mountp);
+ mnt.mnt_mountp);
else
err(EX_OSERR, gettext("mount_smbfs: %s"),
- mntp->mnt_special);
-
- error = smb_ctx_tdis(ctx);
- if (error) /* unable to clean up?! */
- exit(error);
+ mnt.mnt_special);
}
}
- smb_ctx_done(ctx);
+ smb_ctx_free(ctx);
if (error) {
smb_error(gettext("mount error: %s"), error, mount_point);
- exit(errno);
+ exit(RET_ERR);
}
return (0);
}
int
-setsubopt(int index, char *optarg, struct smbfs_args *mdatap)
+setsubopt(smb_ctx_t *ctx, struct smbfs_args *mdatap, int index, char *optarg)
{
struct passwd *pwd;
struct group *grp;
@@ -429,6 +423,15 @@ setsubopt(int index, char *optarg, struct smbfs_args *mdatap)
case OPT_NOEXEC:
/* We don't have to handle generic options here */
return (0);
+
+ case OPT_DOMAIN:
+ err = smb_ctx_setdomain(ctx, optarg, B_TRUE);
+ break;
+
+ case OPT_USER:
+ err = smb_ctx_setuser(ctx, optarg, B_TRUE);
+ break;
+
case OPT_UID:
pwd = isdigit(optarg[0]) ?
getpwuid(atoi(optarg)) : getpwnam(optarg);
@@ -474,12 +477,6 @@ setsubopt(int index, char *optarg, struct smbfs_args *mdatap)
mdatap->file_mode = l;
}
break;
- case OPT_RETRY:
- retry = atoi(optarg);
- break;
- case OPT_TIMEOUT:
- timeout = atoi(optarg);
- break;
case OPT_NOPROMPT:
noprompt++;
}
diff --git a/usr/src/cmd/fs.d/smbclnt/smbiod/Makefile b/usr/src/cmd/fs.d/smbclnt/smbiod/Makefile
new file mode 100644
index 0000000000..626304a88a
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/smbiod/Makefile
@@ -0,0 +1,70 @@
+#
+# 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.
+#
+
+#
+# cmd/fs.d/smbclnt/smbiod/Makefile
+#
+
+FSTYPE= smbfs
+TYPEPROG= smbiod
+
+include ../../Makefile.fstype
+
+OBJS= $(TYPEPROG).o
+SRCS= $(TYPEPROG).c
+POFILE= $(TYPEPROG).po
+
+CLOBBERFILES += $(TYPEPROG)
+
+CFLAGS += $(CCVERBOSE)
+C99MODE= $(C99_ENABLE)
+
+# This is a multi-thread program but Nevada
+# no longer needs -lthread
+LDLIBS += -lsmbfs -ldoor
+
+CPPFLAGS += -I$(SRC)/lib/libsmbfs \
+ -I$(SRC)/uts/common/smbclnt -I$(SRC)/uts/common
+
+# Debugging
+${NOT_RELEASE_BUILD} CPPFLAGS += -DDEBUG
+
+# uncomment these for dbx debugging
+#COPTFLAG = -g
+#CTF_FLAGS =
+#CTFCONVERT_O=
+#CTFMERGE_LIB=
+
+all: $(TYPEPROG)
+
+catalog: $(POFILE)
+
+lint: lint_SRCS
+
+clean:
+ $(RM) $(OBJS) $(POFILE)
+
+.KEEP_STATE:
diff --git a/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c b/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c
new file mode 100644
index 0000000000..27677874ac
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c
@@ -0,0 +1,362 @@
+/*
+ * 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.
+ */
+
+/*
+ * SMBFS I/O Deamon (smbiod)
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/note.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <synch.h>
+#include <time.h>
+#include <unistd.h>
+#include <ucred.h>
+
+#include <err.h>
+#include <door.h>
+#include <thread.h>
+
+#include <netsmb/smb_lib.h>
+
+#define ALARM_TIME 30 /* sec. */
+#define EXIT_FAIL 1
+#define EXIT_OK 0
+
+#if defined(DEBUG) || defined(__lint)
+#define DPRINT(...) do \
+{ \
+ if (smb_debug) \
+ fprintf(stderr, __VA_ARGS__); \
+ _NOTE(CONSTCOND) \
+} while (0)
+#else
+#define DPRINT(...) ((void)0)
+#endif
+
+mutex_t iod_mutex = DEFAULTMUTEX;
+int iod_thr_count; /* threads, excluding main */
+int iod_terminating;
+
+void iod_dispatch(void *cookie, char *argp, size_t argsz,
+ door_desc_t *dp, uint_t n_desc);
+int iod_newvc(smb_iod_ssn_t *clnt_ssn);
+void * iod_work(void *arg);
+
+int
+main(int argc, char **argv)
+{
+ static const int door_attrs =
+ DOOR_REFUSE_DESC | DOOR_NO_CANCEL;
+ sigset_t oldmask, tmpmask;
+ char *env, *door_path = NULL;
+ int door_fd = -1, tmp_fd = -1;
+ int err, i, sig;
+ int rc = EXIT_FAIL;
+
+ /* Debugging support. */
+ if ((env = getenv("SMBFS_DEBUG")) != NULL) {
+ smb_debug = atoi(env);
+ if (smb_debug < 1)
+ smb_debug = 1;
+ }
+
+ /*
+ * Find out if an IOD is already running.
+ * If so, we lost a harmless startup race.
+ * An IOD did start, so exit success.
+ */
+ err = smb_iod_open_door(&door_fd);
+ if (err == 0) {
+ close(door_fd);
+ door_fd = -1;
+ DPRINT("main: already running\n");
+ exit(EXIT_OK);
+ }
+
+ /*
+ * Create a file for the door.
+ */
+ door_path = smb_iod_door_path();
+ unlink(door_path);
+ tmp_fd = open(door_path, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (tmp_fd < 0) {
+ perror(door_path);
+ exit(EXIT_FAIL);
+ }
+ close(tmp_fd);
+ tmp_fd = -1;
+
+
+ /*
+ * Close FDs 0,1,2 so we don't have a TTY, and
+ * re-open them on /dev/null so they won't be
+ * used for device handles (etc.) later, and
+ * we don't have to worry about printf calls
+ * or whatever going to these FDs.
+ */
+ for (i = 0; i < 3; i++) {
+ /* Exception: If smb_debug, keep stderr */
+ if (smb_debug && i == 2)
+ break;
+ close(i);
+ tmp_fd = open("/dev/null", O_RDWR);
+ if (tmp_fd < 0)
+ perror("/dev/null");
+ if (tmp_fd != i)
+ DPRINT("Open /dev/null - wrong fd?\n");
+ }
+
+ /*
+ * Become session leader.
+ */
+ setsid();
+
+ /*
+ * Create door service threads with signals blocked.
+ */
+ sigfillset(&tmpmask);
+ sigprocmask(SIG_BLOCK, &tmpmask, &oldmask);
+
+ /* Setup the door service. */
+ door_fd = door_create(iod_dispatch, NULL, door_attrs);
+ if (door_fd < 0) {
+ fprintf(stderr, "%s: door_create failed\n", argv[0]);
+ rc = EXIT_FAIL;
+ goto errout;
+ }
+ fdetach(door_path);
+ if (fattach(door_fd, door_path) < 0) {
+ fprintf(stderr, "%s: fattach failed\n", argv[0]);
+ rc = EXIT_FAIL;
+ goto errout;
+ }
+
+ /*
+ * Post the initial alarm, and then just
+ * wait for signals.
+ */
+ alarm(ALARM_TIME);
+again:
+ sig = sigwait(&tmpmask);
+ DPRINT("main: sig=%d\n", sig);
+
+ /*
+ * If a door call races with the alarm, ignore the alarm.
+ * It will be rescheduled when the threads go away.
+ */
+ mutex_lock(&iod_mutex);
+ if (sig == SIGALRM && iod_thr_count > 0) {
+ mutex_unlock(&iod_mutex);
+ goto again;
+ }
+ iod_terminating = 1;
+ mutex_unlock(&iod_mutex);
+ rc = EXIT_OK;
+
+errout:
+ fdetach(door_path);
+ door_revoke(door_fd);
+ door_fd = -1;
+ unlink(door_path);
+
+ return (rc);
+}
+
+/*ARGSUSED*/
+void
+iod_dispatch(void *cookie, char *argp, size_t argsz,
+ door_desc_t *dp, uint_t n_desc)
+{
+ smb_iod_ssn_t *ssn;
+ ucred_t *ucred;
+ uid_t cl_uid;
+ int rc;
+
+ /*
+ * Verify that the calling process has the same UID.
+ * Paranoia: The door we created has mode 0600, so
+ * this check is probably redundant.
+ */
+ ucred = NULL;
+ if (door_ucred(&ucred) != 0) {
+ rc = EACCES;
+ goto out;
+ }
+ cl_uid = ucred_getruid(ucred);
+ ucred_free(ucred);
+ ucred = NULL;
+ if (cl_uid != getuid()) {
+ DPRINT("iod_dispatch: wrong UID\n");
+ rc = EACCES;
+ goto out;
+ }
+
+ /*
+ * The library uses a NULL arg call to check if
+ * the deamon is running. Just return zero.
+ */
+ if (argp == NULL) {
+ rc = 0;
+ goto out;
+ }
+
+ /*
+ * Otherwise, the arg must be the (fixed size)
+ * smb_iod_ssn_t
+ */
+ if (argsz != sizeof (*ssn)) {
+ rc = EINVAL;
+ goto out;
+ }
+
+ mutex_lock(&iod_mutex);
+ if (iod_terminating) {
+ mutex_unlock(&iod_mutex);
+ DPRINT("iod_dispatch: terminating\n");
+ rc = EINTR;
+ goto out;
+ }
+ if (iod_thr_count++ == 0) {
+ alarm(0);
+ DPRINT("iod_dispatch: cancelled alarm\n");
+ }
+ mutex_unlock(&iod_mutex);
+
+ ssn = (void *) argp;
+ rc = iod_newvc(ssn);
+
+ mutex_lock(&iod_mutex);
+ if (--iod_thr_count == 0) {
+ DPRINT("iod_dispatch: schedule alarm\n");
+ alarm(ALARM_TIME);
+ }
+ mutex_unlock(&iod_mutex);
+
+out:
+ door_return((void *)&rc, sizeof (rc), NULL, 0);
+}
+
+/*
+ * Try making a connection with the server described by
+ * the info in the smb_iod_ssn_t arg. If successful,
+ * start an IOD thread to service it, then return to
+ * the client side of the door.
+ */
+int
+iod_newvc(smb_iod_ssn_t *clnt_ssn)
+{
+ smb_ctx_t *ctx;
+ thread_t tid;
+ int err;
+
+
+ /*
+ * This needs to essentially "clone" the smb_ctx_t
+ * from the client side of the door, or at least
+ * as much of it as we need while creating a VC.
+ */
+ err = smb_ctx_alloc(&ctx);
+ if (err)
+ return (err);
+ bcopy(clnt_ssn, &ctx->ct_iod_ssn, sizeof (ctx->ct_iod_ssn));
+
+ /*
+ * Do the initial connection setup here, so we can
+ * report the outcome to the door client.
+ */
+ err = smb_iod_connect(ctx);
+ if (err != 0)
+ goto out;
+
+ /*
+ * Create the driver session now, so we don't
+ * race with the door client findvc call.
+ */
+ if ((err = smb_ctx_gethandle(ctx)) != 0)
+ goto out;
+ if (ioctl(ctx->ct_dev_fd, SMBIOC_SSN_CREATE, &ctx->ct_ssn) < 0) {
+ err = errno;
+ 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)
+ smb_ctx_free(ctx);
+
+ return (err);
+}
+
+/*
+ * Be the reader thread for some VC.
+ *
+ * This is started by a door call thread, which means
+ * this is always at least the 2nd thread, therefore
+ * it should never see thr_count==0 or terminating.
+ */
+void *
+iod_work(void *arg)
+{
+ smb_ctx_t *ctx = arg;
+
+ mutex_lock(&iod_mutex);
+ if (iod_thr_count++ == 0) {
+ alarm(0);
+ DPRINT("iod_work: cancelled alarm\n");
+ }
+ mutex_unlock(&iod_mutex);
+
+ (void) smb_iod_work(ctx);
+
+ mutex_lock(&iod_mutex);
+ if (--iod_thr_count == 0) {
+ DPRINT("iod_work: schedule alarm\n");
+ alarm(ALARM_TIME);
+ }
+ mutex_unlock(&iod_mutex);
+
+ smb_ctx_free(ctx);
+ return (NULL);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/Makefile b/usr/src/cmd/fs.d/smbclnt/smbutil/Makefile
index 9d6017b35b..31d52961fe 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/Makefile
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/Makefile
@@ -18,11 +18,12 @@
#
# CDDL HEADER END
#
+
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
+
#
# cmd/fs.d/smbclnt/smbutil/Makefile
#
@@ -32,14 +33,31 @@ PROG= smbutil
include $(SRC)/cmd/Makefile.cmd
OBJS= smbutil.o login.o lookup.o print.o status.o view.o
+
SRCS= $(OBJS:%.o=%.c)
POFILE= smbutil_all.po
POFILES= $(OBJS:%.o=%.po)
+CLOBBERFILES+= $(POFILE) $(POFILES)
C99MODE= $(C99_ENABLE)
+
+LDLIBS += -lsmbfs -lnsl
+
CPPFLAGS += -I$(SRC)/lib/libsmbfs \
-I$(SRC)/uts/common/smbclnt -I$(SRC)/uts/common
-LDLIBS += -lsmbfs -lnsl
+
+# Debugging
+${NOT_RELEASE_BUILD} CPPFLAGS += -DDEBUG
+
+# uncomment these for dbx debugging
+#COPTFLAG = -g
+#CTF_FLAGS =
+#CTFCONVERT_O=
+#CTFMERGE_LIB=
+
+# disable some of the less important lint
+LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2
+LINTFLAGS += -erroff=E_FUNC_RET_MAYBE_IGNORED2
all: $(PROG)
@@ -58,8 +76,11 @@ $(POFILE): $(POFILES)
$(RM) $@
$(CAT) $(POFILES) > $@
+lint: lint_SRCS
+
clean :
$(RM) $(OBJS)
-clobber: clean
- $(RM) $(PROG) $(POFILES)
+.KEEP_STATE:
+
+include ../../../Makefile.targ
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/common.h b/usr/src/cmd/fs.d/smbclnt/smbutil/common.h
index 280c4744f4..24cb1436a0 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/common.h
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/common.h
@@ -1,8 +1,38 @@
+/*
+ * Copyright (c) 2000, 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.
+ */
+
#ifndef _SMBUTIL_COMMON_H
#define _SMBUTIL_COMMON_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/lookup.c b/usr/src/cmd/fs.d/smbclnt/smbutil/lookup.c
index 199d785277..5e8049e71b 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/lookup.c
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/lookup.c
@@ -32,7 +32,10 @@
* $Id: lookup.c,v 1.1.1.1 2001/06/09 00:28:13 zarzycki Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#include <sys/param.h>
#include <sys/errno.h>
@@ -74,9 +77,9 @@ cmd_lookup(int argc, char *argv[])
exit(1);
}
if (smb_open_rcfile(NULL) == 0) {
- if (nb_ctx_readrcsection(smb_rc, ctx, "default", 0) != 0)
+ if (nb_ctx_readrcsection(NULL, ctx, "default", 0) != 0)
exit(1);
- rc_close(smb_rc);
+ smb_close_rcfile();
}
if ((ctx->nb_flags & NBCF_NS_ENABLE) == 0) {
fprintf(stderr,
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/print.c b/usr/src/cmd/fs.d/smbclnt/smbutil/print.c
index dd986e1b49..7379acfd90 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/print.c
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/print.c
@@ -29,21 +29,22 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: print.c,v 1.7 2004/03/19 01:49:48 lindak Exp $
+ * from: Id: print.c,v 1.4 2001/01/28 07:35:01 bp Exp
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
-#include <sys/param.h>
-#include <sys/errno.h>
-#include <sys/stat.h>
+#include <sys/types.h>
+#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
-#include <err.h>
-#include <unistd.h>
-#include <strings.h>
+#include <string.h>
#include <stdlib.h>
-#include <sysexits.h>
+#include <unistd.h>
#include <libintl.h>
#include <cflib.h>
@@ -52,13 +53,174 @@
#include "common.h"
+static char titlebuf[256];
+static char databuf[4096];
+static int print_file(smb_ctx_t *, char *, int);
void
print_usage(void)
{
printf(gettext("usage: smbutil print [connection options] //"
"[workgroup;][user[:password]@]"
- "server/share\n"));
+ "server/share {print_file|-}\n"));
exit(1);
}
+
+int
+cmd_print(int argc, char *argv[])
+{
+ struct smb_ctx *ctx = NULL;
+ char *filename;
+ int error, opt;
+ int file = -1;
+
+ /* last arg is the print file. */
+ if (argc < 3)
+ print_usage();
+
+ error = smb_ctx_alloc(&ctx);
+ if (error)
+ goto out;
+
+ error = smb_ctx_scan_argv(ctx, argc-1, argv,
+ SMBL_SHARE, SMBL_SHARE, USE_SPOOLDEV);
+ if (error)
+ goto out;
+
+ error = smb_ctx_readrc(ctx);
+ if (error)
+ goto out;
+
+ while ((opt = getopt(argc-1, argv, STDPARAM_OPT)) != EOF) {
+ if (opt == '?')
+ print_usage();
+ error = smb_ctx_opt(ctx, opt, optarg);
+ if (error)
+ goto out;
+ }
+ if (optind != argc-2)
+ print_usage();
+ filename = argv[argc-1];
+
+ if (strcmp(filename, "-") == 0) {
+ file = 0; /* stdin */
+ filename = "stdin";
+ } else {
+ file = open(filename, O_RDONLY, 0);
+ if (file < 0) {
+ smb_error("could not open file %s\n", errno, filename);
+ exit(1);
+ }
+ }
+
+ /*
+ * Resolve the server address,
+ * setup derived defaults.
+ */
+ error = smb_ctx_resolve(ctx);
+ if (error)
+ goto out;
+
+ /*
+ * Have server + share names, options etc.
+ * Get the session and tree.
+ */
+again:
+ error = smb_ctx_get_ssn(ctx);
+ if (error == EAUTH) {
+ int 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 the printer share connection.
+ * Print the file.
+ */
+ snprintf(titlebuf, sizeof (titlebuf), "%s_%s",
+ ctx->ct_user, filename);
+
+ error = print_file(ctx, titlebuf, file);
+
+
+out:
+ /* don't close stdin (file=0) */
+ if (file > 0)
+ close(file);
+
+ smb_ctx_free(ctx);
+
+ return (error);
+}
+
+/*
+ * Documentation for OPEN_PRINT_FILE is scarse.
+ * It's in a 1996 MS doc. entitled:
+ * SMB FILE SHARING PROTOCOL
+ *
+ * The extra parameters are:
+ * SetupLength: what part of the file is printer setup
+ * Mode: text or graphics (raw data)
+ * IdentifierString: job title
+ */
+enum {
+ MODE_TEXT = 0, /* TAB expansion, etc. */
+ MODE_GRAPHICS /* raw data */
+};
+
+static int
+print_file(smb_ctx_t *ctx, char *title, int file)
+{
+ off_t offset;
+ int error, rcnt, wcnt;
+ int setup_len = 0; /* No printer setup data */
+ int mode = MODE_GRAPHICS; /* treat as raw data */
+ int fh = -1;
+
+ error = smb_printer_open(ctx, setup_len, mode, title, &fh);
+ if (error) {
+ smb_error("could not open print job", error);
+ return (error);
+ }
+
+ offset = 0;
+ for (;;) {
+ rcnt = read(file, databuf, sizeof (databuf));
+ if (rcnt < 0) {
+ error = errno;
+ smb_error("error reading input file\n", error);
+ break;
+ }
+ if (rcnt == 0)
+ break;
+
+ wcnt = smb_fh_write(ctx, fh, offset, rcnt, databuf);
+ if (wcnt < 0) {
+ error = errno;
+ smb_error("error writing spool file\n", error);
+ break;
+ }
+ if (wcnt != rcnt) {
+ smb_error("incomplete write to spool file\n", 0);
+ error = EIO;
+ break;
+ }
+ offset += wcnt;
+ }
+
+ (void) smb_printer_close(ctx, fh);
+ return (error);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c b/usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c
index ca5eeb425d..404b436d16 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c
@@ -31,7 +31,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -74,7 +74,8 @@ static struct commands {
{"logout", cmd_logout, logout_usage, 0},
{"logoutall", cmd_logoutall, logoutall_usage, 0},
{"lookup", cmd_lookup, lookup_usage, CMDFL_NO_KMOD},
- {"status", cmd_status, status_usage, 0},
+ {"print", cmd_print, print_usage, 0},
+ {"status", cmd_status, status_usage, CMDFL_NO_KMOD},
{"view", cmd_view, view_usage, 0},
{NULL, NULL, NULL, 0}
};
@@ -134,7 +135,7 @@ main(int argc, char *argv[])
{
struct commands *cmd;
char *cp;
- int opt;
+ int err, opt;
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
@@ -176,7 +177,8 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
optind = 1;
- return (cmd->fn(argc, argv));
+ err = cmd->fn(argc, argv);
+ return ((err) ? 1 : 0);
}
static void
@@ -191,7 +193,7 @@ help(void) {
" logout logout from specified host\n"
" logoutall logout all users (requires privilege)\n"
" lookup resolve NetBIOS name to IP address\n"
- /* " print print file to the specified remote printer\n" */
+ " print print file to the specified remote printer\n"
" status resolve IP address or DNS name to NetBIOS names\n"
" view list resources on specified host\n"
"\n"));
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/status.c b/usr/src/cmd/fs.d/smbclnt/smbutil/status.c
index 9353c69e16..9707becaa6 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/status.c
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/status.c
@@ -32,7 +32,10 @@
* $Id: status.c,v 1.2 2001/08/18 05:44:50 conrad Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#include <sys/param.h>
#include <sys/errno.h>
@@ -62,10 +65,10 @@ int
cmd_status(int argc, char *argv[])
{
struct nb_ctx *ctx;
- struct sockaddr *sap;
+ struct in_addr ina;
char *hostname;
- char servername[SMB_MAXSRVNAMELEN + 1];
- char workgroupname[SMB_MAXUSERNAMELEN + 1];
+ char servername[NB_NAMELEN];
+ char workgroupname[NB_NAMELEN];
int error, opt;
if (argc < 2)
@@ -76,9 +79,9 @@ cmd_status(int argc, char *argv[])
exit(1);
}
if (smb_open_rcfile(NULL) == 0) {
- if (nb_ctx_readrcsection(smb_rc, ctx, "default", 0) != 0)
+ if (nb_ctx_readrcsection(NULL, ctx, "default", 0) != 0)
exit(1);
- rc_close(smb_rc);
+ smb_close_rcfile();
}
while ((opt = getopt(argc, argv, "")) != EOF) {
switch (opt) {
@@ -91,7 +94,7 @@ cmd_status(int argc, char *argv[])
status_usage();
hostname = argv[argc - 1];
- error = nb_resolvehost_in(hostname, &sap);
+ error = nb_resolvehost_in(hostname, &ina);
if (error) {
smb_error(gettext(
"unable to resolve DNS hostname %s"), error, hostname);
@@ -104,7 +107,7 @@ cmd_status(int argc, char *argv[])
}
servername[0] = (char)0;
workgroupname[0] = (char)0;
- error = nbns_getnodestatus(sap, ctx, servername, workgroupname);
+ error = nbns_getnodestatus(ctx, &ina, servername, workgroupname);
if (error) {
smb_error(
gettext("unable to get status from %s"), error, hostname);
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/view.c b/usr/src/cmd/fs.d/smbclnt/smbutil/view.c
index 035d15132d..365e5b6f37 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/view.c
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/view.c
@@ -32,9 +32,13 @@
* $Id: view.c,v 1.9 2004/12/13 00:25:39 lindak Exp $
*/
-#include <sys/param.h>
-#include <sys/errno.h>
-#include <sys/stat.h>
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
#include <stdio.h>
#include <err.h>
#include <unistd.h>
@@ -43,12 +47,101 @@
#include <sysexits.h>
#include <libintl.h>
-#include <cflib.h>
+#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 *);
+
+void
+view_usage(void)
+{
+ printf(gettext("usage: smbutil view [connection options] //"
+ "[workgroup;][user[:password]@]server\n"));
+ exit(1);
+}
+
+int
+cmd_view(int argc, char *argv[])
+{
+ struct smb_ctx *ctx;
+ int error, err2, opt;
+
+ if (argc < 2)
+ view_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)
+ return (error);
+
+ error = smb_ctx_readrc(ctx);
+ if (error)
+ return (error);
+
+ while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
+ if (opt == '?')
+ view_usage();
+ error = smb_ctx_opt(ctx, opt, optarg);
+ if (error)
+ return (error);
+ }
+
+ smb_ctx_setshare(ctx, "IPC$", USE_IPC);
+
+ /*
+ * Resolve the server address,
+ * setup derived defaults.
+ */
+ error = smb_ctx_resolve(ctx);
+ if (error)
+ return (error);
+
+ /*
+ * 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);
+ return (error);
+ }
+
+ error = smb_ctx_get_tree(ctx);
+ if (error) {
+ smb_error(gettext("//%s/%s: tree connect failed"),
+ error, ctx->ct_fullserver, ctx->ct_origshare);
+ return (error);
+ }
+
+ /*
+ * Have IPC$ tcon, now list shares.
+ */
+ error = enum_shares(ctx);
+ if (error) {
+ smb_error("cannot list shares", error);
+ return (error);
+ }
+
+ smb_ctx_free(ctx);
+ return (0);
+}
+
#ifdef I18N /* not defined, put here so xgettext(1) can find strings */
static char *shtype[] = {
gettext("disk"),
@@ -68,60 +161,34 @@ static char *shtype[] = {
#endif
int
-cmd_view(int argc, char *argv[])
+enum_shares(smb_ctx_t *ctx)
{
- struct smb_ctx sctx, *ctx = &sctx;
- struct share_info *share_info, *ep;
- int error, opt, i, entries, total;
+ struct share_info *share_info;
+ int error, entries, total;
- if (argc < 2)
- view_usage();
- error = smb_ctx_init(ctx, argc, argv, SMBL_VC, SMBL_VC, SMB_ST_ANY);
- if (error)
- exit(error);
- error = smb_ctx_readrc(ctx);
- if (error)
- exit(error);
- if (smb_rc)
- rc_close(smb_rc);
- while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
- switch (opt) {
- case STDPARAM_ARGS:
- error = smb_ctx_opt(ctx, opt, optarg);
- if (error)
- exit(error);
- break;
- default:
- view_usage();
- /*NOTREACHED*/
- }
- }
-#ifdef APPLE
- if (loadsmbvfs())
- fprintf(stderr, gettext("SMB filesystem is not available"));
-#endif
-reauth:
- smb_ctx_setshare(ctx, "IPC$", SMB_ST_ANY);
- error = smb_ctx_resolve(ctx);
- if (error)
- exit(error);
- error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
- if (ctx->ct_flags & SMBCF_KCFOUND && smb_autherr(error)) {
- ctx->ct_ssn.ioc_password[0] = '\0';
- goto reauth;
- }
- if (error) {
- smb_error(gettext("could not login to server %s"),
- error, ctx->ct_ssn.ioc_srvname);
- exit(error);
- }
- printf(gettext("Share Type Comment\n"));
- printf("-------------------------------\n");
+ /*
+ * XXX: Later, try RPC first,
+ * then fall back to RAP...
+ */
error = smb_netshareenum(ctx, &entries, &total, &share_info);
if (error) {
smb_error(gettext("unable to list resources"), error);
- exit(error);
+ return (error);
}
+ 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;
+
+ printf(gettext("Share Type Comment\n"));
+ printf("-------------------------------\n");
+
for (ep = share_info, i = 0; i < entries; i++, ep++) {
int sti = ep->type & STYPE_MASK;
if (sti > STYPE_UNKNOWN)
@@ -136,18 +203,4 @@ reauth:
entries, total);
free(share_info);
- smb_ctx_done(ctx);
-#ifdef APPLE
- smb_save2keychain(ctx);
-#endif
- return (0);
-}
-
-
-void
-view_usage(void)
-{
- printf(gettext("usage: smbutil view [connection options] //"
- "[workgroup;][user[:password]@]server\n"));
- exit(1);
}