diff options
| author | Gordon Ross <Gordon.Ross@Sun.COM> | 2009-07-02 12:58:38 -0400 |
|---|---|---|
| committer | Gordon Ross <Gordon.Ross@Sun.COM> | 2009-07-02 12:58:38 -0400 |
| commit | 613a2f6ba31e891e3d947a356daf5e563d43c1ce (patch) | |
| tree | 0f7f3438a5792c05ed156a43e8cd84f25695d7f2 /usr/src/cmd/fs.d/smbclnt | |
| parent | bf73eaa5a8ea69ac16a1e6e7b736f09286d073f9 (diff) | |
| download | illumos-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/Makefile | 16 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/lsacl/Makefile | 6 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c | 9 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/mount/Makefile | 19 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/mount/mount.c | 193 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbiod/Makefile | 70 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c | 362 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbutil/Makefile | 31 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbutil/common.h | 34 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbutil/lookup.c | 9 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbutil/print.c | 182 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c | 12 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbutil/status.c | 19 | ||||
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbutil/view.c | 185 |
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); } |
