--- a/exception_lists/copyright Fri Jun 24 08:44:32 2011 -0700
+++ b/exception_lists/copyright Thu Jun 30 17:58:05 2011 -0400
@@ -18,8 +18,8 @@
#
# CDDL HEADER END
#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright 2010 Nexenta Systems, Inc. All rights reserved.
#
syntax: glob
@@ -48,6 +48,7 @@
usr/src/cmd/krb5/ldap_util/kdb5_ldap_policy.h
usr/src/cmd/krb5/ldap_util/kdb5_ldap_realm.h
usr/src/cmd/krb5/ldap_util/kdb5_ldap_services.h
+usr/src/cmd/smbsrv/smbd/eventlog.dll
usr/src/common/bzip2/LICENSE
usr/src/common/bzip2/Solaris.README.txt
usr/src/common/bzip2/bzlib.h
@@ -328,6 +329,7 @@
usr/src/lib/libkmsagent/common/SOAP/*.*
usr/src/lib/librstp/common/*.[ch]
usr/src/lib/librstp/common/[CRT]*
+usr/src/uts/intel/nsmb/ioc_check.ref
usr/src/uts/intel/os/splashimage.xpm
usr/src/uts/common/gssapi/mechs/krb5/crypto/block_size.c
usr/src/uts/common/gssapi/mechs/krb5/crypto/checksum_length.c
@@ -354,4 +356,4 @@
usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c
usr/src/uts/common/gssapi/mechs/krb5/mech/util_seqnum.c
usr/src/uts/common/gssapi/mechs/krb5/mech/val_cred.c
-usr/src/cmd/smbsrv/smbd/eventlog.dll
+usr/src/uts/sparc/nsmb/ioc_check.ref
--- a/exception_lists/packaging Fri Jun 24 08:44:32 2011 -0700
+++ b/exception_lists/packaging Thu Jun 30 17:58:05 2011 -0400
@@ -821,6 +821,7 @@
#
usr/lib/fs/smbfs/chacl
usr/lib/fs/smbfs/lsacl
+usr/lib/fs/smbfs/testnp
#
# FC related files
kernel/kmdb/fcip i386
--- a/usr/src/cmd/fs.d/smbclnt/Makefile Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/cmd/fs.d/smbclnt/Makefile Thu Jun 30 17:58:05 2011 -0400
@@ -20,6 +20,7 @@
#
#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
@@ -32,7 +33,7 @@
SUBDIRS_CATALOG= smbutil mount umount share
SUBDIRS= $(SUBDIRS_CATALOG) chacl lsacl \
- smbiod smbiod-svc svc
+ smbiod smbiod-svc svc test
# for messaging catalog files
#
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/print.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/print.c Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -150,7 +151,7 @@
* Have the printer share connection.
* Print the file.
*/
- snprintf(titlebuf, sizeof (titlebuf), "%s_%s",
+ snprintf(titlebuf, sizeof (titlebuf), "%s %s",
ctx->ct_user, filename);
error = print_file(ctx, titlebuf, file);
@@ -185,13 +186,15 @@
print_file(smb_ctx_t *ctx, char *title, int file)
{
off_t offset;
- int error, rcnt, wcnt;
+ int rcnt, wcnt;
int setup_len = 0; /* No printer setup data */
int mode = MODE_GRAPHICS; /* treat as raw data */
- int fh = -1;
+ int error = 0;
+ int pfd = -1;
- error = smb_printer_open(ctx, setup_len, mode, title, &fh);
- if (error) {
+ pfd = smb_open_printer(ctx, title, setup_len, mode);
+ if (pfd < 0) {
+ error = errno;
smb_error("could not open print job", error);
return (error);
}
@@ -207,7 +210,7 @@
if (rcnt == 0)
break;
- wcnt = smb_fh_write(ctx, fh, offset, rcnt, databuf);
+ wcnt = smb_fh_write(pfd, offset, rcnt, databuf);
if (wcnt < 0) {
error = errno;
smb_error("error writing spool file\n", error);
@@ -221,6 +224,6 @@
offset += wcnt;
}
- (void) smb_printer_close(ctx, fh);
+ (void) smb_fh_close(pfd);
return (error);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fs.d/smbclnt/test/Makefile Thu Jun 30 17:58:05 2011 -0400
@@ -0,0 +1,58 @@
+#
+# 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 2011 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+FSTYPE= smbfs
+LIBPROG= testnp
+ROOTFS_PROG= $(LIBPROG)
+
+include ../../Makefile.fstype
+
+OBJS= $(LIBPROG).o
+SRCS= $(LIBPROG).c $(FSLIBSRC)
+
+LDLIBS += -lsmbfs
+
+CFLAGS += $(CCVERBOSE)
+C99MODE= $(C99_ENABLE)
+
+CLOBBERFILES += $(LIBPROG)
+
+# uncomment these for dbx debugging
+#COPTFLAG = -g
+#CTF_FLAGS =
+#CTFCONVERT_O=
+#CTFMERGE_LIB=
+
+all: $(ROOTFS_PROG)
+
+install: $(ROOTLIBFSTYPEPROG)
+
+lint: lint_SRCS
+
+clean:
+ $(RM) $(OBJS)
+
+.KEEP_STATE:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fs.d/smbclnt/test/testnp.c Thu Jun 30 17:58:05 2011 -0400
@@ -0,0 +1,416 @@
+/*
+ * 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 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2010, Oracle and/or its affiliates. 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
+testnp_usage(void)
+{
+ printf("usage: testnp [-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 '?':
+ testnp_usage();
+ break;
+ }
+ }
+ if (optind >= argc)
+ testnp_usage();
+ server = argv[optind];
+
+ if (pw != NULL && (dom == NULL || usr == NULL)) {
+ fprintf(stderr, "%0: -p arg requires -d dom -u usr\n",
+ argv[0]);
+ testnp_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;
+ int slashcnt = 0;
+ 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);
+}
--- a/usr/src/cmd/mdb/common/modules/nsmb/nsmb.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/cmd/mdb/common/modules/nsmb/nsmb.c Thu Jun 30 17:58:05 2011 -0400
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,9 +31,9 @@
#include <sys/types.h>
#include <sys/socket.h>
-#include "smb_conn.h"
-#include "smb_rq.h"
-#include "smb_pass.h"
+#include <netsmb/smb_conn.h>
+#include <netsmb/smb_rq.h>
+#include <netsmb/smb_pass.h>
#define OPT_VERBOSE 0x0001 /* Be [-v]erbose in dcmd's */
#define OPT_RECURSE 0x0002 /* recursive display */
--- a/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c Thu Jun 30 17:58:05 2011 -0400
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,8 +31,8 @@
#include <sys/vnode.h>
#include <sys/vfs.h>
-#include "smbfs.h"
-#include "smbfs_node.h"
+#include <smbfs/smbfs.h>
+#include <smbfs/smbfs_node.h>
#define OPT_VERBOSE 0x0001 /* Be [-v]erbose in dcmd's */
--- a/usr/src/cmd/mdb/intel/amd64/nsmb/Makefile Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/cmd/mdb/intel/amd64/nsmb/Makefile Thu Jun 30 17:58:05 2011 -0400
@@ -19,6 +19,7 @@
# CDDL HEADER END
#
#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
@@ -36,11 +37,10 @@
include ../../../Makefile.module
-CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt/netsmb
+CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt
CPPFLAGS += -I$(SRC)/uts/common
-C99MODE= -xc99=%all
-C99LMODE= -Xc99=%all
+C99MODE= $(C99_ENABLE)
# maybe not the best place for this, but
# we need to create this directory.
--- a/usr/src/cmd/mdb/intel/amd64/smbfs/Makefile Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/cmd/mdb/intel/amd64/smbfs/Makefile Thu Jun 30 17:58:05 2011 -0400
@@ -19,6 +19,7 @@
# CDDL HEADER END
#
#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
@@ -36,9 +37,11 @@
include ../../../Makefile.module
-CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt/smbfs
+CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt
CPPFLAGS += -I$(SRC)/uts/common
+C99MODE= $(C99_ENABLE)
+
# maybe not the best place for this, but
# we need to create this directory.
$(ROOTKMOD):
--- a/usr/src/cmd/mdb/intel/ia32/nsmb/Makefile Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/cmd/mdb/intel/ia32/nsmb/Makefile Thu Jun 30 17:58:05 2011 -0400
@@ -19,6 +19,7 @@
# CDDL HEADER END
#
#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
@@ -35,11 +36,10 @@
include ../../../Makefile.module
-CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt/netsmb
+CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt
CPPFLAGS += -I$(SRC)/uts/common
-C99MODE= -xc99=%all
-C99LMODE= -Xc99=%all
+C99MODE= $(C99_ENABLE)
# maybe not the best place for this, but
# we need to create this directory.
--- a/usr/src/cmd/mdb/intel/ia32/smbfs/Makefile Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/cmd/mdb/intel/ia32/smbfs/Makefile Thu Jun 30 17:58:05 2011 -0400
@@ -19,6 +19,7 @@
# CDDL HEADER END
#
#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
@@ -35,9 +36,11 @@
include ../../../Makefile.module
-CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt/smbfs
+CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt
CPPFLAGS += -I$(SRC)/uts/common
+C99MODE= $(C99_ENABLE)
+
# maybe not the best place for this, but
# we need to create this directory.
$(ROOTKMOD):
--- a/usr/src/cmd/mdb/sparc/v9/nsmb/Makefile Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/cmd/mdb/sparc/v9/nsmb/Makefile Thu Jun 30 17:58:05 2011 -0400
@@ -19,6 +19,7 @@
# CDDL HEADER END
#
#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
@@ -36,11 +37,10 @@
include ../../../Makefile.module
-CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt/netsmb
+CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt
CPPFLAGS += -I$(SRC)/uts/common
-C99MODE= -xc99=%all
-C99LMODE= -Xc99=%all
+C99MODE= $(C99_ENABLE)
# maybe not the best place for this, but
# we need to create this directory.
--- a/usr/src/cmd/mdb/sparc/v9/smbfs/Makefile Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/cmd/mdb/sparc/v9/smbfs/Makefile Thu Jun 30 17:58:05 2011 -0400
@@ -19,6 +19,7 @@
# CDDL HEADER END
#
#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
@@ -36,9 +37,11 @@
include ../../../Makefile.module
-CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt/smbfs
+CPPFLAGS += -I$(SRC)/uts/common/fs/smbclnt
CPPFLAGS += -I$(SRC)/uts/common
+C99MODE= $(C99_ENABLE)
+
# maybe not the best place for this, but
# we need to create this directory.
$(ROOTKMOD):
--- a/usr/src/lib/libsmbfs/Makefile Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/Makefile Thu Jun 30 17:58:05 2011 -0400
@@ -19,6 +19,7 @@
# CDDL HEADER END
#
#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -29,7 +30,7 @@
include $(SRC)/lib/Makefile.lib
-HDRS= smbfs_acl.h smbfs_api.h
+HDRS= smbfs_acl.h smbfs_api.h smb_keychain.h
HDRDIR= netsmb
ROOTHDRDIR= $(ROOT)/usr/include/netsmb
--- a/usr/src/lib/libsmbfs/netsmb/smb_keychain.h Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/netsmb/smb_keychain.h Thu Jun 30 17:58:05 2011 -0400
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -27,8 +28,6 @@
#ifndef _SMB_KEYCHAIN_H
#define _SMB_KEYCHAIN_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* External interface to the libsmbfs/netsmb keychain
* storage mechanism. This interface is consumed by
@@ -36,6 +35,10 @@
* and by the SMBFS PAM module.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define SMB_KEYCHAIN_SUCCESS 0
#define SMB_KEYCHAIN_BADPASSWD 300
#define SMB_KEYCHAIN_BADDOMAIN 301
@@ -47,6 +50,10 @@
int smbfs_keychain_add(uid_t uid, const char *domain, const char *user,
const char *password);
+/* Add an NT-hash (16-bytes) to the keychain. */
+int smbfs_keychain_addhash(uid_t uid, const char *domain, const char *user,
+ const uchar_t *nthash);
+
/* Delete a password from the keychain. */
int smbfs_keychain_del(uid_t uid, const char *domain, const char *user);
@@ -79,4 +86,8 @@
smbfs_default_dom_usr(const char *home, const char *server,
char *dom, int maxdom, char *usr, int maxusr);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _SMB_KEYCHAIN_H */
--- a/usr/src/lib/libsmbfs/netsmb/smb_lib.h Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/netsmb/smb_lib.h Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -108,6 +109,7 @@
int ct_shtype_req; /* share type wanted */
char *ct_origshare;
char *ct_home;
+ char *ct_rpath; /* remote file name */
/* Connection setup SMB stuff. */
/* Strings from the SMB negotiate response. */
--- a/usr/src/lib/libsmbfs/netsmb/smbfs_api.h Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/netsmb/smbfs_api.h Thu Jun 30 17:58:05 2011 -0400
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,8 +29,8 @@
#define _NETSMB_SMBFS_API_H
/*
- * Define the API exported to our commands and to the
- * MS-style RPC-over-named-pipes library (mlrpc).
+ * Define the API exported to our commands and to
+ * libraries doing DCE-RPC over SMB named pipes.
*/
#include <sys/types.h>
@@ -58,13 +59,14 @@
* Share type values for smb_ctx_new, _init
* Based on NetUseAdd() USE_INFO_[12] _asg_type values
* They also happen to match: STYPE_DISKTREE, etc.
+ * Note: these values appear on the wire.
*/
typedef enum {
- USE_WILDCARD = -1,
- USE_DISKDEV,
- USE_SPOOLDEV,
- USE_CHARDEV,
- USE_IPC
+ USE_DISKDEV = 0, /* also STYPE_DISKTREE */
+ USE_SPOOLDEV, /* also STYPE_PRINTQ */
+ USE_CHARDEV, /* also STYPE_DEVICE */
+ USE_IPC, /* also STYPE_IPC */
+ USE_WILDCARD /* also STYPE_UNKNOWN */
} smb_use_shtype_t;
/*
@@ -115,7 +117,6 @@
int smb_ctx_flags2(struct smb_ctx *);
int smb_ctx_resolve(struct smb_ctx *);
int smb_ctx_get_ssn(struct smb_ctx *);
-int smb_ctx_get_ssnkey(struct smb_ctx *, uchar_t *, size_t);
int smb_ctx_get_tree(struct smb_ctx *);
int smb_ctx_setauthflags(struct smb_ctx *, int);
@@ -138,20 +139,18 @@
typedef void (*smb_ctx_close_hook_t)(struct smb_ctx *);
void smb_ctx_set_close_hook(smb_ctx_close_hook_t);
-int smb_fh_close(struct smb_ctx *ctx, int);
-int smb_fh_open(struct smb_ctx *ctx, const char *, int, int *);
-int smb_fh_read(struct smb_ctx *, int, off_t, size_t, char *);
-int smb_fh_write(struct smb_ctx *, int, off_t, size_t, const char *);
-int smb_fh_xactnp(struct smb_ctx *, int, int, const char *,
+int smb_fh_close(int);
+int smb_fh_open(struct smb_ctx *ctx, const char *, int);
+int smb_fh_read(int, off_t, size_t, char *);
+int smb_fh_write(int, off_t, size_t, const char *);
+int smb_fh_xactnp(int, int, const char *,
int *, char *, int *);
+int smb_fh_getssnkey(int, uchar_t *, size_t);
-int smb_iod_start(struct smb_ctx *);
+int smb_open_printer(struct smb_ctx *, const char *, int, int);
-int smb_t2_request(struct smb_ctx *, int, uint16_t *, const char *,
- int, void *, int, void *, int *, void *, int *, void *, int *);
-
-int smb_printer_open(struct smb_ctx *, int, int, const char *, int *);
-int smb_printer_close(struct smb_ctx *, int);
+void smbfs_set_default_domain(const char *);
+void smbfs_set_default_user(const char *);
char *smb_strerror(int);
--- a/usr/src/lib/libsmbfs/smb/ctx.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/smb/ctx.c Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -64,8 +65,6 @@
#include <netsmb/smb_dev.h>
#include "charsets.h"
-#include "spnego.h"
-#include "derparse.h"
#include "private.h"
#include "ntlm.h"
@@ -90,6 +89,14 @@
const char smbutil_std_opts[] = "ABCD:E:I:L:M:NO:P:U:R:S:T:W:";
/*
+ * Defaults for new contexts (connections to servers).
+ * These are set by smbfs_set_default_...
+ */
+static char default_domain[SMBIOC_MAX_NAME];
+static char default_user[SMBIOC_MAX_NAME];
+
+
+/*
* Give the RPC library a callback hook that will be
* called whenever we destroy or reinit an smb_ctx_t.
* The name rpc_cleanup_smbctx() is legacy, and was
@@ -206,7 +213,8 @@
ctx->ct_origshare ? ctx->ct_origshare : "",
ctx->ct_shtype_req);
- /* dump_iod_work()? */
+ printf(" ct_home=\"%s\"\n", ctx->ct_home);
+ printf(" ct_rpath=\"%s\"\n", ctx->ct_rpath);
}
int
@@ -233,9 +241,7 @@
int
smb_ctx_init(struct smb_ctx *ctx)
{
- char pwbuf[NSS_BUFLEN_PASSWD];
- struct passwd pw;
- int error = 0;
+ int error;
bzero(ctx, sizeof (*ctx));
@@ -256,32 +262,15 @@
ctx->ct_authflags = SMB_AT_DEFAULT;
ctx->ct_minauth = SMB_AT_DEFAULT;
- error = nb_ctx_setscope(ctx->ct_nb, "");
- if (error)
- return (error);
-
/*
- * if the user name is not specified some other way,
- * use the current user name (built-in default)
+ * Default domain, user, ...
*/
- if (getpwuid_r(getuid(), &pw, pwbuf, sizeof (pwbuf)) != NULL) {
- error = smb_ctx_setuser(ctx, pw.pw_name, 0);
- if (error)
- return (error);
- ctx->ct_home = strdup(pw.pw_name);
- if (ctx->ct_home == NULL)
- return (ENOMEM);
- }
+ strlcpy(ctx->ct_domain, default_domain,
+ sizeof (ctx->ct_domain));
+ strlcpy(ctx->ct_user, default_user,
+ sizeof (ctx->ct_user));
- /*
- * Set a built-in default domain (workgroup).
- * Using the Windows/NT default for now.
- */
- error = smb_ctx_setdomain(ctx, "WORKGROUP", 0);
- if (error)
- return (error);
-
- return (error);
+ return (0);
}
/*
@@ -441,8 +430,14 @@
freeaddrinfo(ctx->ct_addrinfo);
ctx->ct_addrinfo = NULL;
}
- if (ctx->ct_home)
+ if (ctx->ct_home) {
free(ctx->ct_home);
+ ctx->ct_home = NULL;
+ }
+ if (ctx->ct_rpath) {
+ free(ctx->ct_rpath);
+ ctx->ct_rpath = NULL;
+ }
if (ctx->ct_srv_OS) {
free(ctx->ct_srv_OS);
ctx->ct_srv_OS = NULL;
@@ -457,26 +452,9 @@
}
}
-static int
-getsubstring(const char *p, uchar_t sep, char *dest, int maxlen,
- const char **next)
-{
- int len;
-
- maxlen--;
- for (len = 0; len < maxlen && *p != sep; p++, len++, dest++) {
- if (*p == 0)
- return (EINVAL);
- *dest = *p;
- }
- *dest = 0;
- *next = *p ? p + 1 : p;
- return (0);
-}
-
/*
* Parse the UNC path. Here we expect something like
- * "//[workgroup;][user[:password]@]host[/share[/path]]"
+ * "//[[domain;]user[:password]@]host[/share[/path]]"
* See http://ietf.org/internet-drafts/draft-crhertel-smb-url-07.txt
* Values found here are marked as "from CMD".
*/
@@ -485,9 +463,9 @@
int minlevel, int maxlevel, int sharetype,
const char **next)
{
- const char *p = unc;
- char *p1, *colon;
char tmp[1024];
+ char *host, *share, *path;
+ char *dom, *usr, *pw, *p;
int error;
/*
@@ -497,118 +475,146 @@
ctx->ct_minlevel = minlevel;
ctx->ct_maxlevel = maxlevel;
ctx->ct_shtype_req = sharetype;
+ ctx->ct_parsedlevel = SMBL_NONE;
- ctx->ct_parsedlevel = SMBL_NONE;
- if (*p++ != '/' || *p++ != '/') {
+ dom = usr = pw = host = NULL;
+
+ /* Work on a temporary copy, fix back slashes. */
+ strlcpy(tmp, unc, sizeof (tmp));
+ for (p = tmp; *p; p++)
+ if (*p == '\\')
+ *p = '/';
+
+ if (tmp[0] != '/' || tmp[1] != '/') {
smb_error(dgettext(TEXT_DOMAIN,
"UNC should start with '//'"), 0);
error = EINVAL;
goto out;
}
- p1 = tmp;
- error = getsubstring(p, ';', p1, sizeof (tmp), &p);
- if (!error) {
- if (*p1 == 0) {
+ p = tmp + 2; /* user@host... */
+
+ /* Find the share part, if any. */
+ share = strchr(p, '/');
+ if (share)
+ *share = '\0';
+ (void) unpercent(p); /* host component */
+
+ /*
+ * Parse the "host" stuff right to left:
+ * 1: trailing "@hostname" (or whole field)
+ * 2: trailing ":password"
+ * 3: trailing "domain;user" (or just user)
+ */
+ host = strrchr(p, '@');
+ if (host == NULL) {
+ host = p; /* no user@ prefix */
+ } else {
+ *host++ = '\0';
+
+ /* may have [[domain;]user[:passwd]] */
+ pw = strchr(p, ':');
+ if (pw)
+ *pw++ = '\0';
+ usr = strchr(p, ';');
+ if (usr) {
+ *usr++ = '\0';
+ dom = p;
+ } else
+ usr = p;
+ }
+
+ if (*host == '\0') {
+ smb_error(dgettext(TEXT_DOMAIN, "empty server name"), 0);
+ error = EINVAL;
+ goto out;
+ }
+ error = smb_ctx_setfullserver(ctx, host);
+ if (error)
+ goto out;
+ ctx->ct_parsedlevel = SMBL_VC;
+
+ if (dom != NULL) {
+ error = smb_ctx_setdomain(ctx, dom, TRUE);
+ if (error)
+ goto out;
+ }
+ if (usr != NULL) {
+ if (*usr == '\0') {
smb_error(dgettext(TEXT_DOMAIN,
- "empty workgroup name"), 0);
+ "empty user name"), 0);
error = EINVAL;
goto out;
}
- error = smb_ctx_setdomain(ctx, unpercent(tmp), TRUE);
- if (error)
- goto out;
- }
- colon = (char *)p;
- error = getsubstring(p, '@', p1, sizeof (tmp), &p);
- if (!error) {
if (ctx->ct_maxlevel < SMBL_VC) {
smb_error(dgettext(TEXT_DOMAIN,
"no user name required"), 0);
error = EINVAL;
goto out;
}
- p1 = strchr(tmp, ':');
- if (p1) {
- colon += p1 - tmp;
- *p1++ = (char)0;
- error = smb_ctx_setpassword(ctx, unpercent(p1), TRUE);
- if (error)
- goto out;
- if (p - colon > 2)
- memset(colon+1, '*', p - colon - 2);
- }
- p1 = tmp;
- if (*p1 == 0) {
+ error = smb_ctx_setuser(ctx, usr, TRUE);
+ if (error)
+ goto out;
+ }
+ if (pw != NULL) {
+ error = smb_ctx_setpassword(ctx, pw, TRUE);
+ if (error)
+ goto out;
+ }
+
+ if (share != NULL) {
+ /* restore the slash */
+ *share = '/';
+ p = share + 1;
+
+ /* Find the path part, if any. */
+ path = strchr(p, '/');
+ if (path)
+ *path = '\0';
+ (void) unpercent(p); /* share component */
+
+ if (*p == '\0') {
smb_error(dgettext(TEXT_DOMAIN,
- "empty user name"), 0);
+ "empty share name"), 0);
error = EINVAL;
goto out;
}
- error = smb_ctx_setuser(ctx, unpercent(tmp), TRUE);
+ if (ctx->ct_maxlevel < SMBL_SHARE) {
+ smb_error(dgettext(TEXT_DOMAIN,
+ "no share name required"), 0);
+ error = EINVAL;
+ goto out;
+ }
+
+ /*
+ * Special case UNC names like:
+ * //host/PIPE/endpoint
+ * to have share: IPC$
+ */
+ if (strcasecmp(p, "PIPE") == 0) {
+ sharetype = USE_IPC;
+ p = "IPC$";
+ }
+ error = smb_ctx_setshare(ctx, p, sharetype);
if (error)
goto out;
- ctx->ct_parsedlevel = SMBL_VC;
- }
- error = getsubstring(p, '/', p1, sizeof (tmp), &p);
- if (error) {
- error = getsubstring(p, '\0', p1, sizeof (tmp), &p);
- if (error) {
- smb_error(dgettext(TEXT_DOMAIN,
- "no server name found"), 0);
- goto out;
+ ctx->ct_parsedlevel = SMBL_SHARE;
+
+ if (path) {
+ /* restore the slash */
+ *path = '/';
+ p = path + 1;
+ (void) unpercent(p); /* remainder */
+ free(ctx->ct_rpath);
+ ctx->ct_rpath = strdup(path);
}
- }
- if (*p1 == 0) {
- smb_error(dgettext(TEXT_DOMAIN, "empty server name"), 0);
+ } else if (ctx->ct_minlevel >= SMBL_SHARE) {
+ smb_error(dgettext(TEXT_DOMAIN, "empty share name"), 0);
error = EINVAL;
goto out;
}
- /*
- * Save ct_fullserver without case conversion.
- */
- if (strchr(tmp, '%'))
- (void) unpercent(tmp);
- error = smb_ctx_setfullserver(ctx, tmp);
- if (error)
- goto out;
-
-#ifdef SMB_ST_NONE
- if (sharetype == SMB_ST_NONE) {
- if (next)
- *next = p;
- error = 0;
- goto out;
- }
-#endif
-
- if (*p != 0 && ctx->ct_maxlevel < SMBL_SHARE) {
- smb_error(dgettext(TEXT_DOMAIN, "no share name required"), 0);
- error = EINVAL;
- goto out;
- }
- error = getsubstring(p, '/', p1, sizeof (tmp), &p);
- if (error) {
- error = getsubstring(p, '\0', p1, sizeof (tmp), &p);
- if (error) {
- smb_error(dgettext(TEXT_DOMAIN,
- "unexpected end of line"), 0);
- goto out;
- }
- }
- if (*p1 == 0 && ctx->ct_minlevel >= SMBL_SHARE &&
- !(ctx->ct_flags & SMBCF_BROWSEOK)) {
- smb_error(dgettext(TEXT_DOMAIN, "empty share name"), 0);
- error = EINVAL;
- goto out;
- }
if (next)
- *next = p;
- if (*p1 == 0) {
- error = 0;
- goto out;
- }
- error = smb_ctx_setshare(ctx, unpercent(p1), sharetype);
+ *next = NULL;
out:
if (error == 0 && smb_debug > 0)
@@ -1147,27 +1153,10 @@
int
smb_open_driver()
{
- int err, fd;
- uint32_t version;
+ int fd;
fd = open("/dev/"NSMB_NAME, O_RDWR);
if (fd < 0) {
- err = errno;
- smb_error(dgettext(TEXT_DOMAIN,
- "failed to open driver"), err);
- return (-1);
- }
-
- /*
- * Check the driver version (paranoia)
- * Do this BEFORE any other ioctl calls.
- */
- if (ioctl(fd, SMBIOC_GETVERS, &version) < 0)
- version = 0;
- if (version != NSMB_VERSION) {
- smb_error(dgettext(TEXT_DOMAIN,
- "incorrect driver version"), 0);
- close(fd);
return (-1);
}
@@ -1180,7 +1169,8 @@
int
smb_ctx_gethandle(struct smb_ctx *ctx)
{
- int fd;
+ int fd, err;
+ uint32_t version;
if (ctx->ct_dev_fd != -1) {
rpc_cleanup_smbctx(ctx);
@@ -1190,8 +1180,24 @@
}
fd = smb_open_driver();
- if (fd < 0)
+ if (fd < 0) {
+ err = errno;
+ smb_error(dgettext(TEXT_DOMAIN,
+ "failed to open driver"), err);
+ return (err);
+ }
+
+ /*
+ * Check the driver version (paranoia)
+ */
+ if (ioctl(fd, SMBIOC_GETVERS, &version) < 0)
+ version = 0;
+ if (version != NSMB_VERSION) {
+ smb_error(dgettext(TEXT_DOMAIN,
+ "incorrect driver version"), 0);
+ close(fd);
return (ENODEV);
+ }
ctx->ct_dev_fd = fd;
return (0);
@@ -1241,43 +1247,12 @@
}
/*
- * Get the string representation of a share "use" type,
- * as needed for the "service" in tree connect.
- */
-static const char *
-smb_use_type_str(smb_use_shtype_t stype)
-{
- const char *pp;
-
- switch (stype) {
- default:
- case USE_WILDCARD:
- pp = "?????";
- break;
- case USE_DISKDEV:
- pp = "A:";
- break;
- case USE_SPOOLDEV:
- pp = "LPT1:";
- break;
- case USE_CHARDEV:
- pp = "COMM";
- break;
- case USE_IPC:
- pp = "IPC";
- break;
- }
- return (pp);
-}
-
-/*
* Find or create a tree connection
*/
int
smb_ctx_get_tree(struct smb_ctx *ctx)
{
smbioc_tcon_t *tcon = NULL;
- const char *stype;
int cmd, err = 0;
if (ctx->ct_dev_fd < 0 ||
@@ -1297,18 +1272,8 @@
strlcpy(tcon->tc_sh.sh_name, ctx->ct_origshare,
sizeof (tcon->tc_sh.sh_name));
- /*
- * Share password (unused - no share-level security)
- * MS-SMB 2.2.6 says this should be null terminated,
- * and the length includes the null. Did bzero above,
- * so just set length for the null.
- */
- tcon->tc_sh.sh_pwlen = 1;
-
/* The share "use" type. */
- stype = smb_use_type_str(ctx->ct_shtype_req);
- strlcpy(tcon->tc_sh.sh_type_req, stype,
- sizeof (tcon->tc_sh.sh_type_req));
+ tcon->tc_sh.sh_use = ctx->ct_shtype_req;
/*
* Todo: share passwords for share-level security.
@@ -1323,13 +1288,12 @@
/*
* Check the returned share type
*/
- DPRINT("ret. sh_type: \"%s\"", tcon->tc_sh.sh_type_ret);
+ DPRINT("ret. sh_type: \"%d\"", tcon->tc_sh.sh_type);
if (ctx->ct_shtype_req != USE_WILDCARD &&
- 0 != strcmp(stype, tcon->tc_sh.sh_type_ret)) {
+ ctx->ct_shtype_req != tcon->tc_sh.sh_type) {
smb_error(dgettext(TEXT_DOMAIN,
"%s: incompatible share type"),
0, ctx->ct_origshare);
- err = EINVAL;
}
out:
@@ -1360,12 +1324,12 @@
* Must already have an active SMB session.
*/
int
-smb_ctx_get_ssnkey(struct smb_ctx *ctx, uchar_t *key, size_t len)
+smb_fh_getssnkey(int dev_fd, uchar_t *key, size_t len)
{
if (len < SMBIOC_HASH_SZ)
return (EINVAL);
- if (ioctl(ctx->ct_dev_fd, SMBIOC_GETSSNKEY, key) == -1)
+ if (ioctl(dev_fd, SMBIOC_GETSSNKEY, key) == -1)
return (errno);
return (0);
@@ -1536,14 +1500,26 @@
int
smb_ctx_readrc(struct smb_ctx *ctx)
{
- char *home;
+ char pwbuf[NSS_BUFLEN_PASSWD];
+ struct passwd pw;
char *sname = NULL;
int sname_max;
int err = 0;
- if ((home = getenv("HOME")) == NULL)
- home = ctx->ct_home;
- if ((err = smb_open_rcfile(home)) != 0) {
+ /*
+ * If the user name is not specified some other way,
+ * use the current user name. Also save the homedir.
+ * NB: ct_home=NULL is allowed, and we don't want to
+ * bail out with an error for a missing ct_home.
+ */
+ if (getpwuid_r(getuid(), &pw, pwbuf, sizeof (pwbuf)) != NULL) {
+ if (ctx->ct_user[0] == 0)
+ (void) smb_ctx_setuser(ctx, pw.pw_name, B_FALSE);
+ if (ctx->ct_home == NULL)
+ ctx->ct_home = strdup(pw.pw_dir);
+ }
+
+ if ((err = smb_open_rcfile(ctx->ct_home)) != 0) {
DPRINT("smb_open_rcfile, err=%d", err);
/* ignore any error here */
return (0);
@@ -1614,3 +1590,15 @@
return (err);
}
+
+void
+smbfs_set_default_domain(const char *domain)
+{
+ strlcpy(default_domain, domain, sizeof (default_domain));
+}
+
+void
+smbfs_set_default_user(const char *user)
+{
+ strlcpy(default_user, user, sizeof (default_user));
+}
--- a/usr/src/lib/libsmbfs/smb/file.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/smb/file.c Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -62,133 +63,66 @@
#include "private.h"
int
-smb_fh_close(struct smb_ctx *ctx, int fh)
+smb_fh_close(int fd)
{
- struct smb_rq *rqp;
- struct mbdata *mbp;
- int error;
-
- error = smb_rq_init(ctx, SMB_COM_CLOSE, &rqp);
- if (error != 0)
- return (error);
- mbp = smb_rq_getrequest(rqp);
- smb_rq_wstart(rqp);
- mb_put_uint16le(mbp, (uint16_t)fh);
- mb_put_uint32le(mbp, 0); /* time stamp */
- smb_rq_wend(rqp);
- mb_put_uint16le(mbp, 0); /* byte count */
-
- error = smb_rq_simple(rqp);
- smb_rq_done(rqp);
-
- return (error);
+ return (close(fd));
}
int
smb_fh_ntcreate(
struct smb_ctx *ctx, char *path,
- int flags, int req_acc, int efattr,
- int share_acc, int open_disp,
- int create_opts, int impersonation,
- int *fhp, uint32_t *action_taken)
+ int req_acc, int efattr, int share_acc,
+ int open_disp, int create_opts)
{
- struct smb_rq *rqp;
- struct mbdata *mbp;
- char *pathsizep;
- int pathstart, pathsize;
- int error, flags2, uc;
- uint16_t fh;
- uint8_t wc;
-
- flags2 = smb_ctx_flags2(ctx);
- if (flags2 == -1)
- return (EIO);
- uc = flags2 & SMB_FLAGS2_UNICODE;
-
- error = smb_rq_init(ctx, SMB_COM_NT_CREATE_ANDX, &rqp);
- if (error != 0)
- return (error);
+ smbioc_ntcreate_t ioc;
+ int err, nmlen;
+ int new_fd = -1;
+ int32_t from_fd;
- mbp = smb_rq_getrequest(rqp);
- smb_rq_wstart(rqp);
- mb_put_uint16le(mbp, 0xff); /* secondary command */
- mb_put_uint16le(mbp, 0); /* offset to next command (none) */
- mb_put_uint8(mbp, 0); /* MBZ (pad?) */
- (void) mb_fit(mbp, 2, &pathsizep); /* path size - fill in below */
- mb_put_uint32le(mbp, flags); /* create flags (oplock) */
- mb_put_uint32le(mbp, 0); /* FID - basis for path if not root */
- mb_put_uint32le(mbp, req_acc);
- mb_put_uint64le(mbp, 0); /* initial alloc. size */
- mb_put_uint32le(mbp, efattr); /* ext. file attributes */
- mb_put_uint32le(mbp, share_acc); /* share access mode */
- mb_put_uint32le(mbp, open_disp); /* open disposition */
- mb_put_uint32le(mbp, create_opts); /* create_options */
- mb_put_uint32le(mbp, impersonation);
- mb_put_uint8(mbp, 0); /* security flags (?) */
- smb_rq_wend(rqp);
- smb_rq_bstart(rqp);
- if (uc) {
- /*
- * We're about to put a unicode string. We know
- * we're misaligned at this point, and need to
- * save the mb_count at the start of the string,
- * not at the alignment padding placed before it.
- * So add the algnment padding by hand here.
- */
- mb_put_uint8(mbp, 0);
+ nmlen = strlen(path);
+ if (nmlen >= SMBIOC_MAX_NAME) {
+ err = EINVAL;
+ goto errout;
+ }
+
+ /*
+ * Will represent this SMB-level open as a new
+ * open device handle. Get one, then duplicate
+ * the driver session and tree bindings.
+ */
+ new_fd = smb_open_driver();
+ if (new_fd < 0) {
+ err = errno;
+ goto errout;
}
- pathstart = mbp->mb_count;
- mb_put_string(mbp, path, uc);
- smb_rq_bend(rqp);
-
- /* Now go back and fill in pathsizep */
- pathsize = mbp->mb_count - pathstart;
- pathsizep[0] = pathsize & 0xFF;
- pathsizep[1] = (pathsize >> 8);
-
- error = smb_rq_simple(rqp);
- if (error)
- goto out;
-
- mbp = smb_rq_getreply(rqp);
- /*
- * spec says 26 for word count, but 34 words are defined
- * and observed from win2000
- */
- error = md_get_uint8(mbp, &wc);
- if (error || wc < 26) {
- smb_error(dgettext(TEXT_DOMAIN,
- "%s: open failed, bad word count"), 0, path);
- error = EBADRPC;
- goto out;
+ from_fd = ctx->ct_dev_fd;
+ if (ioctl(new_fd, SMBIOC_DUP_DEV, &from_fd) == -1) {
+ err = errno;
+ goto errout;
}
- md_get_uint8(mbp, NULL); /* secondary cmd */
- md_get_uint8(mbp, NULL); /* mbz */
- md_get_uint16le(mbp, NULL); /* andxoffset */
- md_get_uint8(mbp, NULL); /* oplock lvl granted */
- md_get_uint16le(mbp, &fh); /* FID */
- md_get_uint32le(mbp, action_taken);
-#if 0 /* skip decoding the rest */
- md_get_uint64le(mbp, NULL); /* creation time */
- md_get_uint64le(mbp, NULL); /* access time */
- md_get_uint64le(mbp, NULL); /* write time */
- md_get_uint64le(mbp, NULL); /* change time */
- md_get_uint32le(mbp, NULL); /* attributes */
- md_get_uint64le(mbp, NULL); /* allocation size */
- md_get_uint64le(mbp, NULL); /* EOF */
- md_get_uint16le(mbp, NULL); /* file type */
- md_get_uint16le(mbp, NULL); /* device state */
- md_get_uint8(mbp, NULL); /* directory (boolean) */
-#endif
- /* success! */
- *fhp = fh;
- error = 0;
+ /*
+ * Do the SMB-level open with the new dev handle.
+ */
+ bzero(&ioc, sizeof (ioc));
+ strlcpy(ioc.ioc_name, path, SMBIOC_MAX_NAME);
+ ioc.ioc_req_acc = req_acc;
+ ioc.ioc_efattr = efattr;
+ ioc.ioc_share_acc = share_acc;
+ ioc.ioc_open_disp = open_disp;
+ ioc.ioc_creat_opts = create_opts;
+ if (ioctl(new_fd, SMBIOC_NTCREATE, &ioc) == -1) {
+ err = errno;
+ goto errout;
+ }
-out:
- smb_rq_done(rqp);
+ return (new_fd);
- return (error);
+errout:
+ if (new_fd != -1)
+ close(new_fd);
+ errno = err;
+ return (-1);
}
/*
@@ -196,10 +130,21 @@
* Converts Unix-style open call to NTCreate.
*/
int
-smb_fh_open(struct smb_ctx *ctx, const char *path, int oflag, int *fhp)
+smb_fh_open(struct smb_ctx *ctx, const char *path, int oflag)
{
- int error, mode, open_disp, req_acc, share_acc;
+ int mode, open_disp, req_acc, share_acc;
char *p, *ntpath = NULL;
+ int fd = -1;
+
+ /*
+ * Convert Unix path to NT (backslashes)
+ */
+ ntpath = strdup(path);
+ if (ntpath == NULL)
+ return (-1); /* errno was set */
+ for (p = ntpath; *p; p++)
+ if (*p == '/')
+ *p = '\\';
/*
* Map O_RDONLY, O_WRONLY, O_RDWR
@@ -250,55 +195,43 @@
open_disp = NTCREATEX_DISP_OPEN;
}
- /*
- * Convert Unix path to NT (backslashes)
- */
- ntpath = strdup(path);
- if (ntpath == NULL)
- return (ENOMEM);
- for (p = ntpath; *p; p++)
- if (*p == '/')
- *p = '\\';
+ fd = smb_fh_ntcreate(ctx, ntpath,
+ req_acc, SMB_EFA_NORMAL, share_acc, open_disp,
+ NTCREATEX_OPTIONS_NON_DIRECTORY_FILE);
- error = smb_fh_ntcreate(ctx, ntpath, 0, /* flags */
- req_acc, SMB_EFA_NORMAL, share_acc, open_disp,
- NTCREATEX_OPTIONS_NON_DIRECTORY_FILE,
- NTCREATEX_IMPERSONATION_IMPERSONATION,
- fhp, NULL);
free(ntpath);
-
- return (error);
+ return (fd);
}
int
-smb_fh_read(struct smb_ctx *ctx, int fh, off_t offset, size_t count,
+smb_fh_read(int fd, off_t offset, size_t count,
char *dst)
{
struct smbioc_rw rwrq;
bzero(&rwrq, sizeof (rwrq));
- rwrq.ioc_fh = fh;
+ rwrq.ioc_fh = -1; /* tell driver to supply this */
rwrq.ioc_base = dst;
rwrq.ioc_cnt = count;
rwrq.ioc_offset = offset;
- if (ioctl(ctx->ct_dev_fd, SMBIOC_READ, &rwrq) == -1) {
+ if (ioctl(fd, SMBIOC_READ, &rwrq) == -1) {
return (-1);
}
return (rwrq.ioc_cnt);
}
int
-smb_fh_write(struct smb_ctx *ctx, int fh, off_t offset, size_t count,
+smb_fh_write(int fd, off_t offset, size_t count,
const char *src)
{
struct smbioc_rw rwrq;
bzero(&rwrq, sizeof (rwrq));
- rwrq.ioc_fh = fh;
+ rwrq.ioc_fh = -1; /* tell driver to supply this */
rwrq.ioc_base = (char *)src;
rwrq.ioc_cnt = count;
rwrq.ioc_offset = offset;
- if (ioctl(ctx->ct_dev_fd, SMBIOC_WRITE, &rwrq) == -1) {
+ if (ioctl(fd, SMBIOC_WRITE, &rwrq) == -1) {
return (-1);
}
return (rwrq.ioc_cnt);
@@ -313,7 +246,7 @@
* and on output *rdlen is the received length.
*/
int
-smb_fh_xactnp(struct smb_ctx *ctx, int fh,
+smb_fh_xactnp(int fd,
int tdlen, const char *tdata, /* transmit */
int *rdlen, char *rdata, /* receive */
int *more)
@@ -322,10 +255,10 @@
uint16_t setup[2];
setup[0] = TRANS_TRANSACT_NAMED_PIPE;
- setup[1] = fh;
+ setup[1] = 0xFFFF; /* driver replaces this */
rparamcnt = 0;
- err = smb_t2_request(ctx, 2, setup, "\\PIPE\\",
+ err = smb_t2_request(fd, 2, setup, "\\PIPE\\",
0, NULL, /* TX paramcnt, params */
tdlen, (void *)tdata,
&rparamcnt, NULL, /* no RX params */
--- a/usr/src/lib/libsmbfs/smb/keychain.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/smb/keychain.c Thu Jun 30 17:58:05 2011 -0400
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -173,6 +174,18 @@
return (err);
}
+/* Variant of the above that takes an NT hash. */
+int
+smbfs_keychain_addhash(uid_t uid, const char *dom, const char *usr,
+ const uchar_t *nthash)
+{
+ static const uchar_t lmhash[SMBIOC_HASH_SZ] = { 0 };
+ int err, cmd = SMBIOC_PK_ADD;
+ err = smbfs_keychain_cmn(cmd, uid, dom, usr,
+ (uchar_t *)lmhash, (uchar_t *)nthash);
+ return (err);
+}
+
/* Delete a password from the keychain. */
int
smbfs_keychain_del(uid_t uid, const char *dom, const char *usr)
--- a/usr/src/lib/libsmbfs/smb/mapfile-vers Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/smb/mapfile-vers Thu Jun 30 17:58:05 2011 -0400
@@ -18,6 +18,7 @@
# CDDL HEADER END
#
#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
@@ -66,7 +67,6 @@
smb_ctx_flags2;
smb_ctx_free;
smb_ctx_get_ssn;
- smb_ctx_get_ssnkey;
smb_ctx_get_tree;
smb_ctx_gethandle;
smb_ctx_init;
@@ -97,6 +97,7 @@
#
# Functions to support named pipes
smb_fh_close;
+ smb_fh_getssnkey;
smb_fh_open;
smb_fh_read;
smb_fh_write;
@@ -111,9 +112,8 @@
smb_iod_work;
smb_lib_init;
smb_netshareenum; # will move to libnetapi
+ smb_open_printer;
smb_open_rcfile;
- smb_printer_open;
- smb_printer_close;
smb_simplecrypt;
smb_simpledecrypt;
smb_strerror;
@@ -141,11 +141,15 @@
#
smbfs_default_dom_usr;
smbfs_keychain_add;
+ smbfs_keychain_addhash;
smbfs_keychain_chk;
smbfs_keychain_del;
smbfs_keychain_del_everyone;
smbfs_keychain_del_owner;
+ smbfs_set_default_domain;
+ smbfs_set_default_user;
+
smbutil_std_opts;
local:
*;
--- a/usr/src/lib/libsmbfs/smb/print.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/smb/print.c Thu Jun 30 17:58:05 2011 -0400
@@ -1,4 +1,5 @@
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2000, Boris Popov
* All rights reserved.
*
@@ -41,82 +42,61 @@
#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 <netsmb/smb.h>
#include <netsmb/smb_lib.h>
+
#include "private.h"
int
-smb_printer_open(struct smb_ctx *ctx, int setuplen, int mode,
- const char *ident, int *fhp)
+smb_open_printer(struct smb_ctx *ctx, const char *title,
+ int setuplen, int mode)
{
- struct smb_rq *rqp;
- struct mbdata *mbp;
- int error, flags2, uc;
- uint16_t fh;
- uint8_t wc;
-
- flags2 = smb_ctx_flags2(ctx);
- if (flags2 == -1)
- return (EIO);
- uc = flags2 & SMB_FLAGS2_UNICODE;
+ smbioc_printjob_t ioc;
+ int err, tlen, new_fd;
+ int32_t from_fd;
- error = smb_rq_init(ctx, SMB_COM_OPEN_PRINT_FILE, &rqp);
- if (error)
- return (error);
- mbp = smb_rq_getrequest(rqp);
- smb_rq_wstart(rqp);
- mb_put_uint16le(mbp, setuplen);
- mb_put_uint16le(mbp, mode);
- smb_rq_wend(rqp);
- smb_rq_bstart(rqp);
- mb_put_uint8(mbp, SMB_DT_ASCII);
- mb_put_string(mbp, ident, uc);
- smb_rq_bend(rqp);
- error = smb_rq_simple(rqp);
- if (error)
- goto out;
+ tlen = strlen(title);
+ if (tlen >= SMBIOC_MAX_NAME)
+ return (EINVAL);
- mbp = smb_rq_getreply(rqp);
- error = md_get_uint8(mbp, &wc);
- if (error || wc < 1) {
- error = EBADRPC;
- goto out;
+ /*
+ * Will represent this SMB-level open as a new
+ * open device handle. Get one, then duplicate
+ * the driver session and tree bindings.
+ */
+ new_fd = smb_open_driver();
+ if (new_fd < 0)
+ return (errno);
+ from_fd = ctx->ct_dev_fd;
+ if (ioctl(new_fd, SMBIOC_DUP_DEV, &from_fd) == -1) {
+ err = errno;
+ goto errout;
}
- md_get_uint16le(mbp, &fh);
- *fhp = fh;
- error = 0;
-
-out:
- smb_rq_done(rqp);
- return (error);
-}
-/*
- * Similar to smb_fh_close
- */
-int
-smb_printer_close(struct smb_ctx *ctx, int fh)
-{
- struct smb_rq *rqp;
- struct mbdata *mbp;
- int error;
+ /*
+ * Do the SMB-level open with the new dev handle.
+ */
+ bzero(&ioc, sizeof (ioc));
+ ioc.ioc_setuplen = setuplen;
+ ioc.ioc_prmode = mode;
+ strlcpy(ioc.ioc_title, title, SMBIOC_MAX_NAME);
- error = smb_rq_init(ctx, SMB_COM_CLOSE_PRINT_FILE, &rqp);
- if (error)
- return (error);
- mbp = smb_rq_getrequest(rqp);
- smb_rq_wstart(rqp);
- mb_put_uint16le(mbp, (uint16_t)fh);
- smb_rq_wend(rqp);
- mb_put_uint16le(mbp, 0); /* byte count */
+ if (ioctl(new_fd, SMBIOC_PRINTJOB, &ioc) == -1) {
+ err = errno;
+ goto errout;
+ }
- error = smb_rq_simple(rqp);
- smb_rq_done(rqp);
+ return (new_fd);
- return (error);
+errout:
+ close(new_fd);
+ errno = err;
+ return (-1);
}
--- a/usr/src/lib/libsmbfs/smb/private.h Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/smb/private.h Thu Jun 30 17:58:05 2011 -0400
@@ -31,6 +31,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -110,6 +111,8 @@
int smb_rq_internal(struct smb_ctx *, struct smb_rq *);
void smb_rq_sign(struct smb_rq *);
int smb_rq_verify(struct smb_rq *);
+int smb_t2_request(int, int, uint16_t *, const char *,
+ int, void *, int, void *, int *, void *, int *, void *, int *);
/*
* This library extends the mchain.h function set a little.
@@ -170,6 +173,8 @@
int smb_ctx_getaddr(struct smb_ctx *ctx);
int smb_ctx_gethandle(struct smb_ctx *ctx);
+int smb_iod_start(struct smb_ctx *);
+
int smb_ssn_send(struct smb_ctx *, struct mbdata *);
int smb_ssn_recv(struct smb_ctx *, struct mbdata *);
--- a/usr/src/lib/libsmbfs/smb/rap.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/smb/rap.c Thu Jun 30 17:58:05 2011 -0400
@@ -1,4 +1,5 @@
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2000, Boris Popov
* All rights reserved.
*
@@ -334,7 +335,8 @@
rdatacnt = rap->r_rcvbuflen;
rparamcnt = rap->r_plen;
- error = smb_t2_request(ctx, 0, NULL, "\\PIPE\\LANMAN",
+ error = smb_t2_request(ctx->ct_dev_fd,
+ 0, NULL, "\\PIPE\\LANMAN",
rap->r_plen, rap->r_pbuf, /* int tparamcnt,void *tparam */
0, NULL, /* int tdatacnt, void *tdata */
&rparamcnt, rap->r_pbuf, /* rparamcnt, void *rparam */
--- a/usr/src/lib/libsmbfs/smb/rq.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/lib/libsmbfs/smb/rq.c Thu Jun 30 17:58:05 2011 -0400
@@ -1,4 +1,5 @@
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2000, Boris Popov
* All rights reserved.
*
@@ -279,7 +280,7 @@
int
-smb_t2_request(struct smb_ctx *ctx, int setupcount, uint16_t *setup,
+smb_t2_request(int dev_fd, int setupcount, uint16_t *setup,
const char *name,
int tparamcnt, void *tparam,
int tdatacnt, void *tdata,
@@ -311,7 +312,7 @@
krq->ioc_rparam = rparam;
krq->ioc_rdata = rdata;
- if (ioctl(ctx->ct_dev_fd, SMBIOC_T2RQ, krq) == -1) {
+ if (ioctl(dev_fd, SMBIOC_T2RQ, krq) == -1) {
return (errno);
}
--- a/usr/src/uts/common/fs/smbclnt/netsmb/offsets.in Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/netsmb/offsets.in Thu Jun 30 17:58:05 2011 -0400
@@ -20,6 +20,7 @@
\
\
+\ Copyright 2011 Nexenta Systems, Inc. All rights reserved.
\ Copyright 2009 Sun Microsystems, Inc. All rights reserved.
\ Use is subject to license terms.
\
@@ -57,11 +58,10 @@
ssn_srvname
smbioc_oshare
- sh_pwlen
+ sh_use
+ sh_type
sh_name
sh_pass
- sh_type_req
- sh_type_ret
smbioc_tcon
tc_flags
@@ -114,7 +114,7 @@
smbioc_t2rq SIZEOF_SMBIOC_T2RQ
ioc_setup
ioc_setupcnt
- ioc_name
+ ioc_name IOC_T2_NAME
ioc_tparamcnt
ioc_tdatacnt
ioc_rparamcnt
@@ -139,6 +139,19 @@
_ioc_offset
_ioc_base
+smbioc_ntcreate SIZEOF_NTCREATE
+ ioc_req_acc
+ ioc_efattr
+ ioc_share_acc
+ ioc_open_disp
+ ioc_creat_opts
+ ioc_name IOC_NTCR_NAME
+
+smbioc_printjob SIZEOF_PRINTJOB
+ ioc_setuplen
+ ioc_prmode
+ ioc_title
+
smbioc_pk SIZEOF_SMBIOC_PK
pk_uid
pk_dom
--- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.h Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.h Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -236,11 +237,10 @@
#define ss_lock ss_co.co_lock
#define ss_flags ss_co.co_flags
+#define ss_use ss_ioc.sh_use
+#define ss_type ss_ioc.sh_type
#define ss_name ss_ioc.sh_name
-#define ss_pwlen ss_ioc.sh_pwlen
#define ss_pass ss_ioc.sh_pass
-#define ss_type_req ss_ioc.sh_type_req
-#define ss_type_ret ss_ioc.sh_type_ret
#define SMB_SS_LOCK(ssp) mutex_enter(&(ssp)->ss_lock)
#define SMB_SS_UNLOCK(ssp) mutex_exit(&(ssp)->ss_lock)
@@ -275,20 +275,19 @@
* Mostly used in: smb_dev.c, smb_usr.c
*/
typedef struct smb_dev {
- int sd_opened; /* Opened or not */
- int sd_level; /* Future use */
+ dev_info_t *sd_dip; /* ptr to dev_info node */
+ struct cred *sd_cred; /* per dev credentails */
struct smb_vc *sd_vc; /* Reference to VC */
struct smb_share *sd_share; /* Reference to share if any */
+ int sd_level; /* SMBL_VC, ... */
int sd_vcgenid; /* Generation of share or VC */
int sd_poll; /* Future use */
int sd_seq; /* Kind of minor number/instance no */
int sd_flags; /* State of connection */
#define NSMBFL_OPEN 0x0001
#define NSMBFL_IOD 0x0002
+ int sd_smbfid; /* library read/write */
zoneid_t zoneid; /* Zone id */
- dev_info_t *smb_dip; /* ptr to dev_info node */
- void *sd_devfs; /* Dont know how to use this. but */
- struct cred *smb_cred; /* per dev credentails. Future use */
} smb_dev_t;
extern const uint32_t nsmb_version;
@@ -304,10 +303,15 @@
*/
int smb_usr_get_flags2(smb_dev_t *sdp, intptr_t arg, int flags);
int smb_usr_get_ssnkey(smb_dev_t *sdp, intptr_t arg, int flags);
+int smb_usr_dup_dev(smb_dev_t *sdp, intptr_t arg, int flags);
int smb_usr_simplerq(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
int smb_usr_t2request(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
+
+int smb_usr_closefh(smb_dev_t *, cred_t *);
int smb_usr_rw(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr);
+int smb_usr_ntcreate(smb_dev_t *, intptr_t, int, cred_t *);
+int smb_usr_printjob(smb_dev_t *, intptr_t, int, cred_t *);
int smb_usr_get_ssn(smb_dev_t *, int, intptr_t, int, cred_t *);
int smb_usr_drop_ssn(smb_dev_t *sdp, int cmd);
@@ -378,14 +382,4 @@
void smb_share_invalidate(smb_share_t *ssp);
int smb_share_tcon(smb_share_t *, smb_cred_t *);
-/*
- * SMB protocol level functions
- */
-int smb_smb_echo(smb_vc_t *vcp, smb_cred_t *scred, int timo);
-int smb_smb_treeconnect(smb_share_t *ssp, smb_cred_t *scred);
-int smb_smb_treedisconnect(smb_share_t *ssp, smb_cred_t *scred);
-
-int smb_rwuio(smb_share_t *ssp, uint16_t fid, uio_rw_t rw,
- uio_t *uiop, smb_cred_t *scred, int timo);
-
#endif /* _SMB_CONN_H */
--- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_dev.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_dev.c Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -317,14 +318,9 @@
goto attach_failed;
}
- /*
- * Need to see if this field is required.
- * REVISIT
- */
- sdp->smb_dip = dip;
+ sdp->sd_dip = dip;
sdp->sd_seq = 0;
- sdp->sd_opened = 1;
-
+ sdp->sd_smbfid = -1;
mutex_exit(&dev_lck);
ddi_report_dev(dip);
return (DDI_SUCCESS);
@@ -397,6 +393,10 @@
err = smb_usr_get_ssnkey(sdp, arg, flags);
break;
+ case SMBIOC_DUP_DEV:
+ err = smb_usr_dup_dev(sdp, arg, flags);
+ break;
+
case SMBIOC_REQUEST:
err = smb_usr_simplerq(sdp, arg, flags, cr);
break;
@@ -410,6 +410,18 @@
err = smb_usr_rw(sdp, cmd, arg, flags, cr);
break;
+ case SMBIOC_NTCREATE:
+ err = smb_usr_ntcreate(sdp, arg, flags, cr);
+ break;
+
+ case SMBIOC_PRINTJOB:
+ err = smb_usr_printjob(sdp, arg, flags, cr);
+ break;
+
+ case SMBIOC_CLOSEFH:
+ err = smb_usr_closefh(sdp, cr);
+ break;
+
case SMBIOC_SSN_CREATE:
case SMBIOC_SSN_FIND:
err = smb_usr_get_ssn(sdp, cmd, arg, flags, cr);
@@ -523,9 +535,9 @@
return (ENXIO);
}
- sdp->sd_opened = 1;
sdp->sd_seq = nsmb_minor;
- sdp->smb_cred = cr;
+ sdp->sd_cred = cr;
+ sdp->sd_smbfid = -1;
sdp->sd_flags |= NSMBFL_OPEN;
sdp->zoneid = crgetzoneid(cr);
mutex_exit(&dev_lck);
@@ -570,12 +582,14 @@
{
struct smb_vc *vcp;
struct smb_share *ssp;
- struct smb_cred scred;
- smb_credinit(&scred, cr);
+ if (sdp->sd_smbfid != -1)
+ (void) smb_usr_closefh(sdp, cr);
+
ssp = sdp->sd_share;
if (ssp != NULL)
smb_share_rele(ssp);
+
vcp = sdp->sd_vc;
if (vcp != NULL) {
/*
@@ -588,10 +602,69 @@
smb_vc_rele(vcp);
}
- smb_credrele(&scred);
return (0);
}
+/*
+ * Helper for SMBIOC_DUP_DEV
+ * Duplicate state from the FD @arg ("from") onto
+ * the FD for this device instance.
+ */
+int
+smb_usr_dup_dev(smb_dev_t *sdp, intptr_t arg, int flags)
+{
+ file_t *fp = NULL;
+ vnode_t *vp;
+ smb_dev_t *from_sdp;
+ dev_t dev;
+ int32_t ufd;
+ int err;
+
+ /* Should be no VC */
+ if (sdp->sd_vc != NULL)
+ return (EISCONN);
+
+ /*
+ * Get from_sdp (what we will duplicate)
+ */
+ if (ddi_copyin((void *) arg, &ufd, sizeof (ufd), flags))
+ return (EFAULT);
+ if ((fp = getf(ufd)) == NULL)
+ return (EBADF);
+ /* rele fp below */
+ vp = fp->f_vnode;
+ dev = vp->v_rdev;
+ if (dev == 0 || dev == NODEV ||
+ getmajor(dev) != nsmb_major) {
+ err = EINVAL;
+ goto out;
+ }
+ from_sdp = ddi_get_soft_state(statep, getminor(dev));
+ if (from_sdp == NULL) {
+ err = EINVAL;
+ goto out;
+ }
+
+ /*
+ * Duplicate VC and share references onto this FD.
+ */
+ if ((sdp->sd_vc = from_sdp->sd_vc) != NULL)
+ smb_vc_hold(sdp->sd_vc);
+ if ((sdp->sd_share = from_sdp->sd_share) != NULL)
+ smb_share_hold(sdp->sd_share);
+ sdp->sd_level = from_sdp->sd_level;
+ err = 0;
+
+out:
+ if (fp)
+ releasef(ufd);
+ return (err);
+}
+
+
+/*
+ * Helper used by smbfs_mount
+ */
int
smb_dev2share(int fd, struct smb_share **sspp)
{
@@ -604,12 +677,13 @@
if ((fp = getf(fd)) == NULL)
return (EBADF);
+ /* rele fp below */
vp = fp->f_vnode;
dev = vp->v_rdev;
if (dev == 0 || dev == NODEV ||
getmajor(dev) != nsmb_major) {
- err = EBADF;
+ err = EINVAL;
goto out;
}
--- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_smb.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_smb.c Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -58,6 +59,8 @@
#include <netsmb/smb_subr.h>
#include <netsmb/smb_tran.h>
+#define STYPE_LEN 8 /* share type strings */
+
/*
* Largest size to use with LARGE_READ/LARGE_WRITE.
* Specs say up to 64k data bytes, but Windows traffic
@@ -88,6 +91,64 @@
static int smb_smb_writex(struct smb_share *ssp, uint16_t fid,
uint32_t *lenp, uio_t *uiop, smb_cred_t *scred, int timo);
+/*
+ * Get the string representation of a share "use" type,
+ * as needed for the "service" in tree connect.
+ */
+static const char *
+smb_share_typename(uint32_t stype)
+{
+ const char *p;
+
+ switch (stype) {
+ case STYPE_DISKTREE:
+ p = "A:";
+ break;
+ case STYPE_PRINTQ:
+ p = "LPT1:";
+ break;
+ case STYPE_DEVICE:
+ p = "COMM";
+ break;
+ case STYPE_IPC:
+ p = "IPC";
+ break;
+ case STYPE_UNKNOWN:
+ default:
+ p = "?????";
+ break;
+ }
+ return (p);
+}
+
+/*
+ * Parse a share type name (inverse of above)
+ */
+static uint32_t
+smb_share_parsetype(char *name)
+{
+ int stype;
+
+ switch (*name) {
+ case 'A': /* A: */
+ stype = STYPE_DISKTREE;
+ break;
+ case 'C': /* COMM */
+ stype = STYPE_DEVICE;
+ break;
+ case 'I': /* IPC */
+ stype = STYPE_IPC;
+ break;
+ case 'L': /* LPT: */
+ stype = STYPE_PRINTQ;
+ break;
+ default:
+ stype = STYPE_UNKNOWN;
+ break;
+ }
+ return (stype);
+}
+
int
smb_smb_treeconnect(struct smb_share *ssp, struct smb_cred *scred)
{
@@ -95,10 +156,12 @@
struct smb_rq *rqp = NULL;
struct mbchain *mbp;
struct mdchain *mdp;
+ const char *tname;
char *pbuf, *unc_name = NULL;
int error, tlen, plen, unc_len;
uint16_t bcnt, options;
uint8_t wc;
+ char stype_str[STYPE_LEN];
vcp = SSTOVC(ssp);
@@ -127,12 +190,14 @@
vcp->vc_srvname, ssp->ss_name);
SMBSDEBUG("unc_name: \"%s\"", unc_name);
+
/*
- * The password is now pre-computed in the
- * user-space helper process.
+ * Share-level password (pre-computed in user-space)
+ * MS-SMB 2.2.6 says this should be null terminated,
+ * and the pw length includes the null.
*/
- plen = ssp->ss_pwlen;
pbuf = ssp->ss_pass;
+ plen = strlen(pbuf) + 1;
/*
* Build the request.
@@ -161,8 +226,9 @@
* Put the type string (always ASCII),
* including the null.
*/
- tlen = strlen(ssp->ss_type_req) + 1;
- error = mb_put_mem(mbp, ssp->ss_type_req, tlen, MB_MSYSTEM);
+ tname = smb_share_typename(ssp->ss_use);
+ tlen = strlen(tname) + 1;
+ error = mb_put_mem(mbp, tname, tlen, MB_MSYSTEM);
if (error)
goto out;
@@ -210,15 +276,17 @@
goto out;
/*
- * Get the returned share type string,
- * i.e. "IPC" or whatever. Don't care
- * if we get an error reading the type.
+ * Get the returned share type string, i.e. "IPC" or whatever.
+ * (See smb_share_typename, smb_share_parsetype). If we get
+ * an error reading the type, just say STYPE_UNKNOWN.
*/
- tlen = sizeof (ssp->ss_type_ret);
- bzero(ssp->ss_type_ret, tlen--);
+ tlen = STYPE_LEN;
+ bzero(stype_str, tlen--);
if (tlen > bcnt)
tlen = bcnt;
- md_get_mem(mdp, ssp->ss_type_ret, tlen, MB_MSYSTEM);
+ md_get_mem(mdp, stype_str, tlen, MB_MSYSTEM);
+ stype_str[tlen] = '\0';
+ ssp->ss_type = smb_share_parsetype(stype_str);
/* Success! */
SMB_SS_LOCK(ssp);
@@ -281,6 +349,258 @@
}
/*
+ * Modern create/open of file or directory.
+ */
+int
+smb_smb_ntcreate(
+ struct smb_share *ssp,
+ struct mbchain *name_mb,
+ uint32_t cr_flags, /* create flags */
+ uint32_t req_acc, /* requested access */
+ uint32_t efa, /* ext. file attrs (DOS attr +) */
+ uint32_t share_acc,
+ uint32_t open_disp, /* open disposition */
+ uint32_t createopt, /* NTCREATEX_OPTIONS_ */
+ uint32_t impersonate, /* NTCREATEX_IMPERSONATION_... */
+ struct smb_cred *scrp,
+ uint16_t *fidp, /* returned FID */
+ uint32_t *cr_act_p, /* optional create action */
+ struct smbfattr *fap) /* optional attributes */
+{
+ struct smb_rq rq, *rqp = &rq;
+ struct smb_vc *vcp = SSTOVC(ssp);
+ struct mbchain *mbp;
+ struct mdchain *mdp;
+ struct smbfattr fa;
+ uint64_t llongint;
+ uint32_t longint, createact;
+ uint16_t fid;
+ uint8_t wc;
+ int error;
+
+ bzero(&fa, sizeof (fa));
+ error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_NT_CREATE_ANDX, scrp);
+ if (error)
+ return (error);
+ smb_rq_getrequest(rqp, &mbp);
+
+ /* Word parameters */
+ smb_rq_wstart(rqp);
+ mb_put_uint8(mbp, 0xff); /* secondary command */
+ mb_put_uint8(mbp, 0); /* MBZ */
+ mb_put_uint16le(mbp, 0); /* offset to next command (none) */
+ mb_put_uint8(mbp, 0); /* MBZ */
+ mb_put_uint16le(mbp, name_mb->mb_count);
+ mb_put_uint32le(mbp, cr_flags); /* NTCREATEX_FLAGS_* */
+ mb_put_uint32le(mbp, 0); /* FID - basis for path if not root */
+ mb_put_uint32le(mbp, req_acc);
+ mb_put_uint64le(mbp, 0); /* "initial allocation size" */
+ mb_put_uint32le(mbp, efa);
+ mb_put_uint32le(mbp, share_acc);
+ mb_put_uint32le(mbp, open_disp);
+ mb_put_uint32le(mbp, createopt);
+ mb_put_uint32le(mbp, impersonate);
+ mb_put_uint8(mbp, 0); /* security flags (?) */
+ smb_rq_wend(rqp);
+
+ /*
+ * Byte parameters: Just the path name, aligned.
+ * Note: mb_put_mbuf consumes mb_top, so clear it.
+ */
+ smb_rq_bstart(rqp);
+ if (SMB_UNICODE_STRINGS(vcp))
+ mb_put_padbyte(mbp);
+ mb_put_mbuf(mbp, name_mb->mb_top);
+ bzero(name_mb, sizeof (*name_mb));
+ smb_rq_bend(rqp);
+
+ /*
+ * Don't want to risk missing a successful
+ * open response, or we could "leak" FIDs.
+ */
+ rqp->sr_flags |= SMBR_NOINTR_RECV;
+ error = smb_rq_simple_timed(rqp, smb_timo_open);
+ if (error)
+ goto done;
+ smb_rq_getreply(rqp, &mdp);
+ /*
+ * spec says 26 for word count, but 34 words are defined
+ * and observed from win2000
+ */
+ error = md_get_uint8(mdp, &wc);
+ if (error)
+ goto done;
+ if (wc != 26 && wc < 34) {
+ error = EBADRPC;
+ goto done;
+ }
+ md_get_uint8(mdp, NULL); /* secondary cmd */
+ md_get_uint8(mdp, NULL); /* mbz */
+ md_get_uint16le(mdp, NULL); /* andxoffset */
+ md_get_uint8(mdp, NULL); /* oplock lvl granted */
+ md_get_uint16le(mdp, &fid); /* file ID */
+ md_get_uint32le(mdp, &createact); /* create_action */
+
+ md_get_uint64le(mdp, &llongint); /* creation time */
+ smb_time_NT2local(llongint, &fa.fa_createtime);
+ md_get_uint64le(mdp, &llongint); /* access time */
+ smb_time_NT2local(llongint, &fa.fa_atime);
+ md_get_uint64le(mdp, &llongint); /* write time */
+ smb_time_NT2local(llongint, &fa.fa_mtime);
+ md_get_uint64le(mdp, &llongint); /* change time */
+ smb_time_NT2local(llongint, &fa.fa_ctime);
+
+ md_get_uint32le(mdp, &longint); /* attributes */
+ fa.fa_attr = longint;
+ md_get_uint64le(mdp, &llongint); /* allocation size */
+ fa.fa_allocsz = llongint;
+ md_get_uint64le(mdp, &llongint); /* EOF position */
+ fa.fa_size = llongint;
+
+ error = md_get_uint16le(mdp, NULL); /* file type */
+ /* other stuff we don't care about */
+
+done:
+ smb_rq_done(rqp);
+ if (error)
+ return (error);
+
+ *fidp = fid;
+ if (cr_act_p)
+ *cr_act_p = createact;
+ if (fap)
+ *fap = fa; /* struct copy */
+
+ return (0);
+}
+
+int
+smb_smb_close(struct smb_share *ssp, uint16_t fid, struct timespec *mtime,
+ struct smb_cred *scrp)
+{
+ struct smb_rq rq, *rqp = &rq;
+ struct mbchain *mbp;
+ long time;
+ int error;
+
+ error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CLOSE, scrp);
+ if (error)
+ return (error);
+ smb_rq_getrequest(rqp, &mbp);
+ smb_rq_wstart(rqp);
+ mb_put_uint16le(mbp, fid);
+ if (mtime) {
+ int sv_tz = SSTOVC(ssp)->vc_sopt.sv_tz;
+ smb_time_local2server(mtime, sv_tz, &time);
+ } else {
+ time = 0;
+ }
+ mb_put_uint32le(mbp, time);
+ smb_rq_wend(rqp);
+ smb_rq_bstart(rqp);
+ smb_rq_bend(rqp);
+
+ /* Make sure we send it... */
+ rqp->sr_flags |= SMBR_NOINTR_SEND;
+ error = smb_rq_simple(rqp);
+ smb_rq_done(rqp);
+ return (error);
+}
+
+int
+smb_smb_open_prjob(
+ struct smb_share *ssp,
+ char *title,
+ uint16_t setuplen,
+ uint16_t mode,
+ struct smb_cred *scrp,
+ uint16_t *fidp)
+{
+ struct smb_rq rq, *rqp = &rq;
+ struct smb_vc *vcp = SSTOVC(ssp);
+ struct mbchain *mbp;
+ struct mdchain *mdp;
+ uint16_t fid;
+ uint8_t wc;
+ int error;
+
+ error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_OPEN_PRINT_FILE, scrp);
+ if (error)
+ return (error);
+ smb_rq_getrequest(rqp, &mbp);
+
+ /* Word parameters */
+ smb_rq_wstart(rqp);
+ mb_put_uint16le(mbp, setuplen);
+ mb_put_uint16le(mbp, mode);
+ smb_rq_wend(rqp);
+
+ /*
+ * Byte parameters: Just the title
+ */
+ smb_rq_bstart(rqp);
+ mb_put_uint8(mbp, SMB_DT_ASCII);
+ error = smb_put_dstring(mbp, vcp, title, SMB_CS_NONE);
+ smb_rq_bend(rqp);
+ if (error)
+ goto done;
+
+ /*
+ * Don't want to risk missing a successful
+ * open response, or we could "leak" FIDs.
+ */
+ rqp->sr_flags |= SMBR_NOINTR_RECV;
+ error = smb_rq_simple_timed(rqp, smb_timo_open);
+ if (error)
+ goto done;
+
+ smb_rq_getreply(rqp, &mdp);
+ error = md_get_uint8(mdp, &wc);
+ if (error || wc < 1) {
+ error = EBADRPC;
+ goto done;
+ }
+ error = md_get_uint16le(mdp, &fid);
+
+done:
+ smb_rq_done(rqp);
+ if (error)
+ return (error);
+
+ *fidp = fid;
+ return (0);
+}
+
+/*
+ * Like smb_smb_close, but for print shares.
+ */
+int
+smb_smb_close_prjob(struct smb_share *ssp, uint16_t fid,
+ struct smb_cred *scrp)
+{
+ struct smb_rq rq, *rqp = &rq;
+ struct mbchain *mbp;
+ int error;
+
+ error = smb_rq_init(rqp, SSTOCP(ssp),
+ SMB_COM_CLOSE_PRINT_FILE, scrp);
+ if (error)
+ return (error);
+ smb_rq_getrequest(rqp, &mbp);
+ smb_rq_wstart(rqp);
+ mb_put_uint16le(mbp, fid);
+ smb_rq_wend(rqp);
+ smb_rq_bstart(rqp);
+ smb_rq_bend(rqp);
+
+ /* Make sure we send it... */
+ rqp->sr_flags |= SMBR_NOINTR_SEND;
+ error = smb_rq_simple(rqp);
+ smb_rq_done(rqp);
+ return (error);
+}
+
+/*
* Common function for read/write with UIO.
* Called by netsmb smb_usr_rw,
* smbfs_readvnode, smbfs_writevnode
--- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_subr.h Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_subr.h Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -42,6 +43,7 @@
#include <sys/cmn_err.h>
#include <sys/lock.h>
#include <sys/note.h>
+#include <netsmb/smb_conn.h>
/* Helper function for SMBERROR */
/*PRINTFLIKE3*/
@@ -84,6 +86,27 @@
struct smb_vc;
/*
+ * These are the attributes we can get from the server via
+ * SMB commands such as TRANS2_QUERY_FILE_INFORMATION
+ * with info level SMB_QFILEINFO_ALL_INFO, and directory
+ * FindFirst/FindNext info. levels FIND_DIRECTORY_INFO
+ * and FIND_BOTH_DIRECTORY_INFO, etc.
+ *
+ * Values in this struct are always native endian,
+ * and times are converted converted to Unix form.
+ * Note: zero in any of the times means "unknown".
+ */
+typedef struct smbfattr {
+ timespec_t fa_createtime; /* Note, != ctime */
+ timespec_t fa_atime; /* these 3 are like unix */
+ timespec_t fa_mtime;
+ timespec_t fa_ctime;
+ u_offset_t fa_size; /* EOF position */
+ u_offset_t fa_allocsz; /* Allocated size. */
+ uint32_t fa_attr; /* Ext. file (DOS) attr */
+} smbfattr_t;
+
+/*
* Tunable timeout values. See: smb_smb.c
*/
extern int smb_timo_notice;
@@ -129,6 +152,39 @@
const uchar_t *, size_t);
void smb_crypto_mech_init(void);
+
+/*
+ * SMB protocol level functions
+ */
+int smb_smb_echo(smb_vc_t *vcp, smb_cred_t *scred, int timo);
+int smb_smb_treeconnect(smb_share_t *ssp, smb_cred_t *scred);
+int smb_smb_treedisconnect(smb_share_t *ssp, smb_cred_t *scred);
+
+int
+smb_smb_ntcreate(struct smb_share *ssp, struct mbchain *name_mb,
+ uint32_t crflag, uint32_t req_acc, uint32_t efa, uint32_t sh_acc,
+ uint32_t disp, uint32_t createopt, uint32_t impersonate,
+ struct smb_cred *scrp, uint16_t *fidp,
+ uint32_t *cr_act_p, struct smbfattr *fap);
+
+int smb_smb_close(struct smb_share *ssp, uint16_t fid,
+ struct timespec *mtime, struct smb_cred *scrp);
+
+int
+smb_smb_open_prjob(struct smb_share *ssp, char *title,
+ uint16_t setuplen, uint16_t mode,
+ struct smb_cred *scrp, uint16_t *fidp);
+
+int smb_smb_close_prjob(struct smb_share *ssp, uint16_t fid,
+ struct smb_cred *scrp);
+
+int smb_rwuio(smb_share_t *ssp, uint16_t fid, uio_rw_t rw,
+ uio_t *uiop, smb_cred_t *scred, int timo);
+
+/*
+ * time conversions
+ */
+
void smb_time_init(void);
void smb_time_fini(void);
--- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_usr.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_usr.c Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -199,8 +200,7 @@
out:
if (rqp != NULL)
smb_rq_done(rqp); /* free rqp */
- if (ioc != NULL)
- kmem_free(ioc, sizeof (*ioc));
+ kmem_free(ioc, sizeof (*ioc));
smb_credrele(&scred);
return (err);
@@ -239,14 +239,24 @@
goto out;
}
+ /*
+ * Fill in the FID for libsmbfs transact named pipe.
+ */
+ if (ioc->ioc_setupcnt > 1 && ioc->ioc_setup[1] == 0xFFFF) {
+ if (sdp->sd_vcgenid != ssp->ss_vcgenid) {
+ err = ESTALE;
+ goto out;
+ }
+ ioc->ioc_setup[1] = (uint16_t)sdp->sd_smbfid;
+ }
+
t2p = kmem_alloc(sizeof (*t2p), KM_SLEEP);
err = smb_t2_init(t2p, SSTOCP(ssp),
ioc->ioc_setup, ioc->ioc_setupcnt, &scred);
if (err)
goto out;
- len = t2p->t2_setupcount = ioc->ioc_setupcnt;
- if (len > 1)
- t2p->t2_setupdata = ioc->ioc_setup;
+ t2p->t2_setupcount = ioc->ioc_setupcnt;
+ t2p->t2_setupdata = ioc->ioc_setup;
/* This ioc member is a fixed-size array. */
if (ioc->ioc_name[0]) {
@@ -319,8 +329,7 @@
smb_t2_done(t2p);
kmem_free(t2p, sizeof (*t2p));
}
- if (ioc != NULL)
- kmem_free(ioc, sizeof (*ioc));
+ kmem_free(ioc, sizeof (*ioc));
smb_credrele(&scred);
return (err);
@@ -352,7 +361,7 @@
smbioc_rw_t *ioc = NULL;
struct iovec aiov[1];
struct uio auio;
- u_int16_t fh;
+ uint16_t fh;
int err;
uio_rw_t rw;
@@ -383,7 +392,14 @@
goto out;
}
- fh = ioc->ioc_fh;
+ /*
+ * If caller passes -1 in ioc_fh, then
+ * use the FID from SMBIOC_NTCREATE.
+ */
+ if (ioc->ioc_fh == -1)
+ fh = (uint16_t)sdp->sd_smbfid;
+ else
+ fh = (uint16_t)ioc->ioc_fh;
aiov[0].iov_base = ioc->ioc_base;
aiov[0].iov_len = (size_t)ioc->ioc_cnt;
@@ -407,8 +423,154 @@
(void) ddi_copyout(ioc, (void *)arg, sizeof (*ioc), flags);
out:
- if (ioc != NULL)
- kmem_free(ioc, sizeof (*ioc));
+ kmem_free(ioc, sizeof (*ioc));
+ smb_credrele(&scred);
+
+ return (err);
+}
+
+/*
+ * Helper for nsmb_ioctl case
+ * SMBIOC_NTCREATE
+ */
+int
+smb_usr_ntcreate(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr)
+{
+ struct smb_cred scred;
+ struct mbchain name_mb;
+ struct smb_share *ssp;
+ smbioc_ntcreate_t *ioc = NULL;
+ uint16_t fid;
+ int err, nmlen;
+
+ /* This ioctl requires a share. */
+ if ((ssp = sdp->sd_share) == NULL)
+ return (ENOTCONN);
+
+ /* Must not be already open. */
+ if (sdp->sd_smbfid != -1)
+ return (EINVAL);
+
+ mb_init(&name_mb);
+ smb_credinit(&scred, cr);
+ ioc = kmem_alloc(sizeof (*ioc), KM_SLEEP);
+ if (ddi_copyin((void *) arg, ioc, sizeof (*ioc), flags)) {
+ err = EFAULT;
+ goto out;
+ }
+
+ /* Build name_mb */
+ ioc->ioc_name[SMBIOC_MAX_NAME-1] = '\0';
+ nmlen = strnlen(ioc->ioc_name, SMBIOC_MAX_NAME-1);
+ err = smb_put_dmem(&name_mb, SSTOVC(ssp),
+ ioc->ioc_name, nmlen,
+ SMB_CS_NONE, NULL);
+ if (err != 0)
+ goto out;
+
+ /* Do the OtW open, save the FID. */
+ err = smb_smb_ntcreate(ssp, &name_mb,
+ 0, /* create flags */
+ ioc->ioc_req_acc,
+ ioc->ioc_efattr,
+ ioc->ioc_share_acc,
+ ioc->ioc_open_disp,
+ ioc->ioc_creat_opts,
+ NTCREATEX_IMPERSONATION_IMPERSONATION,
+ &scred,
+ &fid,
+ NULL,
+ NULL);
+ if (err != 0)
+ goto out;
+
+ sdp->sd_smbfid = fid;
+ sdp->sd_vcgenid = ssp->ss_vcgenid;
+
+out:
+ kmem_free(ioc, sizeof (*ioc));
+ smb_credrele(&scred);
+ mb_done(&name_mb);
+
+ return (err);
+}
+
+/*
+ * Helper for nsmb_ioctl case
+ * SMBIOC_PRINTJOB
+ */
+int
+smb_usr_printjob(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr)
+{
+ struct smb_cred scred;
+ struct smb_share *ssp;
+ smbioc_printjob_t *ioc = NULL;
+ uint16_t fid;
+ int err;
+
+ /* This ioctl requires a share. */
+ if ((ssp = sdp->sd_share) == NULL)
+ return (ENOTCONN);
+
+ /* The share must be a print queue. */
+ if (ssp->ss_type != STYPE_PRINTQ)
+ return (EINVAL);
+
+ /* Must not be already open. */
+ if (sdp->sd_smbfid != -1)
+ return (EINVAL);
+
+ smb_credinit(&scred, cr);
+ ioc = kmem_alloc(sizeof (*ioc), KM_SLEEP);
+ if (ddi_copyin((void *) arg, ioc, sizeof (*ioc), flags)) {
+ err = EFAULT;
+ goto out;
+ }
+ ioc->ioc_title[SMBIOC_MAX_NAME-1] = '\0';
+
+ /* Do the OtW open, save the FID. */
+ err = smb_smb_open_prjob(ssp, ioc->ioc_title,
+ ioc->ioc_setuplen, ioc->ioc_prmode,
+ &scred, &fid);
+ if (err != 0)
+ goto out;
+
+ sdp->sd_smbfid = fid;
+ sdp->sd_vcgenid = ssp->ss_vcgenid;
+
+out:
+ kmem_free(ioc, sizeof (*ioc));
+ smb_credrele(&scred);
+
+ return (err);
+}
+
+/*
+ * Helper for nsmb_ioctl case
+ * SMBIOC_CLOSEFH
+ */
+int
+smb_usr_closefh(smb_dev_t *sdp, cred_t *cr)
+{
+ struct smb_cred scred;
+ struct smb_share *ssp;
+ uint16_t fid;
+ int err;
+
+ /* This ioctl requires a share. */
+ if ((ssp = sdp->sd_share) == NULL)
+ return (ENOTCONN);
+
+ if (sdp->sd_smbfid == -1)
+ return (0);
+ fid = (uint16_t)sdp->sd_smbfid;
+ sdp->sd_smbfid = -1;
+
+ smb_credinit(&scred, cr);
+ if (ssp->ss_type == STYPE_PRINTQ)
+ err = smb_smb_close_prjob(ssp, fid, &scred);
+ else
+ err = smb_smb_close(ssp, fid, NULL, &scred);
smb_credrele(&scred);
return (err);
@@ -514,8 +676,7 @@
/* Error path: rele hold from _findcreate */
smb_vc_rele(vcp);
}
- if (ossn != NULL)
- kmem_free(ossn, sizeof (*ossn));
+ kmem_free(ossn, sizeof (*ossn));
smb_credrele(&scred);
return (error);
@@ -583,8 +744,6 @@
*/
tcon->tc_sh.sh_name[SMBIOC_MAX_NAME-1] = '\0';
tcon->tc_sh.sh_pass[SMBIOC_MAX_NAME-1] = '\0';
- tcon->tc_sh.sh_type_req[SMBIOC_STYPE_LEN-1] = '\0';
- bzero(tcon->tc_sh.sh_type_ret, SMBIOC_STYPE_LEN);
if (cmd == SMBIOC_TREE_CONNECT)
tcon->tc_opt |= SMBSOPT_CREATE;
@@ -612,8 +771,7 @@
* the tree connect response, so they can
* see if they got the requested type.
*/
- (void) memcpy(tcon->tc_sh.sh_type_ret,
- ssp->ss_type_ret, SMBIOC_STYPE_LEN);
+ tcon->tc_sh.sh_type = ssp->ss_type;
/*
* The share has a hold from _tcon
@@ -630,14 +788,12 @@
/* Error path: rele hold from _findcreate */
smb_share_rele(ssp);
}
- if (tcon) {
- /*
- * This structure may contain a
- * cleartext password, so zap it.
- */
- bzero(tcon, sizeof (*tcon));
- kmem_free(tcon, sizeof (*tcon));
- }
+ /*
+ * This structure may contain a
+ * cleartext password, so zap it.
+ */
+ bzero(tcon, sizeof (*tcon));
+ kmem_free(tcon, sizeof (*tcon));
smb_credrele(&scred);
return (error);
--- a/usr/src/uts/common/fs/smbclnt/netsmb/subr_mchain.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/netsmb/subr_mchain.c Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -109,9 +110,6 @@
* hurt transports that support larger frames.
* 4K fits nicely in 3 Ethernet frames (3 * 1500)
* leaving about 500 bytes for protocol headers.
- *
- * XXX: Would Ethernet drivers be happier
- * (more efficient) if we used 1K here?
*/
#define MLEN 4096
@@ -543,14 +541,36 @@
int
mb_put_mbuf(struct mbchain *mbp, mblk_t *m)
{
- mblk_t *mb;
+ mblk_t *nm, *tail_mb;
+ size_t size;
/* See: linkb(9f) */
- for (mb = mbp->mb_cur; mb->b_cont; mb = mb->b_cont)
- ;
- mb->b_cont = m;
- mbp->mb_cur = m;
- mbp->mb_count += msgdsize(m);
+ tail_mb = mbp->mb_cur;
+ while (tail_mb->b_cont != NULL)
+ tail_mb = tail_mb->b_cont;
+
+ /*
+ * Avoid small frags: Only link if the size of the
+ * new mbuf is larger than the space left in the last
+ * mblk of the chain (tail), otherwise just copy.
+ */
+ while (m != NULL) {
+ size = MBLKL(m);
+ if (size > MBLKTAIL(tail_mb)) {
+ /* Link */
+ tail_mb->b_cont = m;
+ mbp->mb_cur = m;
+ mbp->mb_count += msgdsize(m);
+ return (0);
+ }
+ /* Copy */
+ bcopy(m->b_rptr, tail_mb->b_wptr, size);
+ tail_mb->b_wptr += size;
+ mbp->mb_count += size;
+ nm = unlinkb(m);
+ freeb(m);
+ m = nm;
+ }
return (0);
}
--- a/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_node.h Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_node.h Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,35 +48,13 @@
#include <sys/avl.h>
#include <sys/list.h>
+#include <netsmb/smb_subr.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
- * These are the attributes we can get from the server via
- * SMB commands such as TRANS2_QUERY_FILE_INFORMATION
- * with info level SMB_QFILEINFO_ALL_INFO, and directory
- * FindFirst/FindNext info. levels FIND_DIRECTORY_INFO
- * and FIND_BOTH_DIRECTORY_INFO, etc.
- *
- * Values in this struct are always native endian,
- * and times are converted converted to Unix form.
- * Note: zero in any of the times means "unknown".
- *
- * XXX: Later, move this to nsmb
- */
-typedef struct smbfattr {
- timespec_t fa_createtime; /* Note, != ctime */
- timespec_t fa_atime; /* these 3 are like unix */
- timespec_t fa_mtime;
- timespec_t fa_ctime;
- u_offset_t fa_size; /* EOF position */
- u_offset_t fa_allocsz; /* Allocated size. */
- uint32_t fa_attr; /* Ext. file (DOS) attr */
-} smbfattr_t;
-
-/*
* Cache whole directories (not yet)
*/
typedef struct rddir_cache {
--- a/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_smb.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_smb.c Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -273,7 +274,7 @@
if (cmd == SMB_TRANS2_QUERY_PATH_INFORMATION) {
mb_put_uint32le(mbp, 0);
/* mb_put_uint8(mbp, SMB_DT_ASCII); specs are wrong */
- error = smbfs_fullpath(mbp, vcp, np, NULL, NULL, '\\');
+ error = smbfs_fullpath(mbp, vcp, np, NULL, 0, '\\');
if (error) {
smb_t2_done(t2p);
return (error);
@@ -800,7 +801,7 @@
mb_put_uint8(mbp, SMB_DT_ASCII);
error = smbfs_fullpath(mbp, SSTOVC(ssp), np,
- name, &nmlen, '\\');
+ name, nmlen, '\\');
if (error)
goto out;
smb_rq_bend(rqp);
@@ -865,7 +866,7 @@
smb_rq_bstart(rqp);
mb_put_uint8(mbp, SMB_DT_ASCII);
- error = smbfs_fullpath(mbp, SSTOVC(ssp), np, name, &len, '\\');
+ error = smbfs_fullpath(mbp, SSTOVC(ssp), np, name, len, '\\');
if (error)
goto out;
mb_put_uint8(mbp, SMB_DT_ASCII);
@@ -1057,7 +1058,7 @@
mb_put_uint32le(mbp, 0); /* MBZ */
if (cmd == SMB_TRANS2_SET_PATH_INFORMATION) {
- error = smbfs_fullpath(mbp, vcp, np, NULL, NULL, '\\');
+ error = smbfs_fullpath(mbp, vcp, np, NULL, 0, '\\');
if (error != 0)
goto out;
}
@@ -1096,21 +1097,6 @@
/*
* Modern create/open of file or directory.
- *
- * If disp is ..._DISP_OPEN, or ...DISP_OPEN_IF, or...
- * then this is an open attempt, and:
- * If xattr then name is the stream to be opened at np,
- * Else np should be opened.
- * ...we won't touch *fidp,
- * ...we will set or clear *attrcacheupdated.
- * Else this is a creation attempt, and:
- * If xattr then name is the stream to create at np,
- * Else name is the thing to create under directory np.
- * ...we will return *fidp,
- * ...we won't touch *attrcacheupdated.
- *
- * Note, We use: disp = ...OPEN_IF, ...OVERWRITE_IF, etc.
- * now too, which may or may not create a new object.
*/
int
smbfs_smb_ntcreatex(
@@ -1124,119 +1110,33 @@
uint32_t disp, /* open disposition */
uint32_t createopt, /* NTCREATEX_OPTIONS_ */
struct smb_cred *scrp,
- uint16_t *fidp,
- uint32_t *cr_act_p, /* create action */
- struct smbfattr *fap) /* optional */
+ uint16_t *fidp, /* returned FID */
+ uint32_t *cr_act_p, /* optional returned create action */
+ struct smbfattr *fap) /* optional returned attributes */
{
- struct smb_rq rq, *rqp = &rq;
+ struct mbchain name_mb;
struct smb_share *ssp = np->n_mount->smi_share;
- struct smb_vc *vcp = SSTOVC(ssp);
- struct mbchain *mbp;
- struct mdchain *mdp;
- struct smbfattr fa;
- uint8_t wc;
- uint32_t longint, createact;
- uint64_t llongint;
- int error;
- uint16_t fid, *namelenp;
+ int err;
- bzero(&fa, sizeof (fa));
- error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_NT_CREATE_ANDX, scrp);
- if (error)
- return (error);
- smb_rq_getrequest(rqp, &mbp);
- smb_rq_wstart(rqp);
- mb_put_uint8(mbp, 0xff); /* secondary command */
- mb_put_uint8(mbp, 0); /* MBZ */
- mb_put_uint16le(mbp, 0); /* offset to next command (none) */
- mb_put_uint8(mbp, 0); /* MBZ */
- namelenp = (uint16_t *)mb_reserve(mbp, sizeof (uint16_t));
- /*
- * XP to a W2K Server does not use NTCREATEX_FLAGS_OPEN_DIRECTORY
- * for creating nor for opening a directory. Samba ignores the bit.
- */
- mb_put_uint32le(mbp, 0); /* NTCREATEX_FLAGS_* */
- mb_put_uint32le(mbp, 0); /* FID - basis for path if not root */
- mb_put_uint32le(mbp, req_acc);
- mb_put_uint64le(mbp, 0); /* "initial allocation size" */
- mb_put_uint32le(mbp, efa);
- mb_put_uint32le(mbp, share_acc);
- mb_put_uint32le(mbp, disp);
- mb_put_uint32le(mbp, createopt);
- mb_put_uint32le(mbp, NTCREATEX_IMPERSONATION_IMPERSONATION); /* (?) */
- mb_put_uint8(mbp, 0); /* security flags (?) */
- smb_rq_wend(rqp);
- smb_rq_bstart(rqp);
+ mb_init(&name_mb);
if (name == NULL)
nmlen = 0;
- error = smbfs_fullpath(mbp, vcp, np, name, &nmlen,
- xattr ? ':' : '\\');
- if (error)
- goto done;
- *namelenp = htoles(nmlen); /* includes null */
- smb_rq_bend(rqp);
- /*
- * Don't want to risk missing a successful
- * open response, or we could "leak" FIDs.
- */
- rqp->sr_flags |= SMBR_NOINTR_RECV;
- error = smb_rq_simple_timed(rqp, smb_timo_open);
- if (error)
- goto done;
- smb_rq_getreply(rqp, &mdp);
- /*
- * spec says 26 for word count, but 34 words are defined
- * and observed from win2000
- */
- error = md_get_uint8(mdp, &wc);
- if (error)
- goto done;
- if (wc != 26 && wc != 34 && wc != 42) {
- error = EBADRPC;
- goto done;
- }
- md_get_uint8(mdp, NULL); /* secondary cmd */
- md_get_uint8(mdp, NULL); /* mbz */
- md_get_uint16le(mdp, NULL); /* andxoffset */
- md_get_uint8(mdp, NULL); /* oplock lvl granted */
- md_get_uint16le(mdp, &fid); /* file ID */
- md_get_uint32le(mdp, &createact); /* create_action */
+ err = smbfs_fullpath(&name_mb, SSTOVC(ssp),
+ np, name, nmlen, xattr ? ':' : '\\');
+ if (err)
+ goto out;
- md_get_uint64le(mdp, &llongint); /* creation time */
- smb_time_NT2local(llongint, &fa.fa_createtime);
- md_get_uint64le(mdp, &llongint); /* access time */
- smb_time_NT2local(llongint, &fa.fa_atime);
- md_get_uint64le(mdp, &llongint); /* write time */
- smb_time_NT2local(llongint, &fa.fa_mtime);
- md_get_uint64le(mdp, &llongint); /* change time */
- smb_time_NT2local(llongint, &fa.fa_ctime);
-
- md_get_uint32le(mdp, &longint); /* attributes */
- fa.fa_attr = longint;
-
- md_get_uint64le(mdp, &llongint); /* allocation size */
- fa.fa_allocsz = llongint;
+ err = smb_smb_ntcreate(ssp, &name_mb,
+ 0, /* NTCREATEX_FLAGS... */
+ req_acc, efa, share_acc, disp, createopt,
+ NTCREATEX_IMPERSONATION_IMPERSONATION,
+ scrp, fidp, cr_act_p, fap);
- md_get_uint64le(mdp, &llongint); /* EOF position */
- fa.fa_size = llongint;
-
- error = md_get_uint16le(mdp, NULL); /* file type */
- /* other stuff we don't care about */
+out:
+ mb_done(&name_mb);
-done:
- smb_rq_done(rqp);
- if (error)
- return (error);
-
- if (fidp)
- *fidp = fid;
- if (cr_act_p)
- *cr_act_p = createact;
- if (fap)
- *fap = fa; /* struct copy */
-
- return (0);
+ return (err);
}
static uint32_t
@@ -1335,7 +1235,7 @@
smb_rq_bstart(rqp);
mb_put_uint8(mbp, SMB_DT_ASCII);
- error = smbfs_fullpath(mbp, vcp, np, name, &nmlen,
+ error = smbfs_fullpath(mbp, vcp, np, name, nmlen,
xattr ? ':' : '\\');
if (error)
goto done;
@@ -1514,41 +1414,14 @@
}
int
-smbfs_smb_close(struct smb_share *ssp, uint16_t fid, struct timespec *mtime,
- struct smb_cred *scrp)
+smbfs_smb_close(struct smb_share *ssp, uint16_t fid,
+ struct timespec *mtime, struct smb_cred *scrp)
{
- struct smb_rq rq, *rqp = &rq;
- struct mbchain *mbp;
- long time;
int error;
- error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CLOSE, scrp);
- if (error)
- return (error);
- smb_rq_getrequest(rqp, &mbp);
- smb_rq_wstart(rqp);
- mb_put_uint16le(mbp, fid);
- if (mtime) {
- int sv_tz = SSTOVC(ssp)->vc_sopt.sv_tz;
- smb_time_local2server(mtime, sv_tz, &time);
- } else
- time = 0;
- mb_put_uint32le(mbp, time);
- smb_rq_wend(rqp);
- smb_rq_bstart(rqp);
- smb_rq_bend(rqp);
+ error = smb_smb_close(ssp, fid, mtime, scrp);
/*
- * We don't really care about the result here, but we
- * do need to make sure we send this out, or we could
- * "leak" open file handles on interrupt or timeout.
- * The NOINTR_SEND flag makes this request immune to
- * interrupt or timeout until the send is done.
- */
- rqp->sr_flags |= SMBR_NOINTR_SEND;
- error = smb_rq_simple(rqp);
- smb_rq_done(rqp);
- /*
* ENOTCONN isn't interesting - if the connection is closed,
* so are all our FIDs - and EIO is also not interesting,
* as it means a forced unmount was done. (was ENXIO)
@@ -1596,7 +1469,7 @@
smb_rq_wend(rqp);
smb_rq_bstart(rqp);
mb_put_uint8(mbp, SMB_DT_ASCII);
- error = smbfs_fullpath(mbp, SSTOVC(ssp), dnp, name, &nmlen,
+ error = smbfs_fullpath(mbp, SSTOVC(ssp), dnp, name, nmlen,
xattr ? ':' : '\\');
if (error)
goto out;
@@ -1680,7 +1553,7 @@
smb_rq_wend(rqp);
smb_rq_bstart(rqp);
mb_put_uint8(mbp, SMB_DT_ASCII);
- error = smbfs_fullpath(mbp, SSTOVC(ssp), np, name, &nmlen,
+ error = smbfs_fullpath(mbp, SSTOVC(ssp), np, name, nmlen,
xattr ? ':' : '\\');
if (!error) {
smb_rq_bend(rqp);
@@ -1718,7 +1591,7 @@
* passed sep is ignored, so just pass sep=0.
*/
mb_put_uint8(mbp, SMB_DT_ASCII);
- error = smbfs_fullpath(mbp, SSTOVC(ssp), src, NULL, NULL, 0);
+ error = smbfs_fullpath(mbp, SSTOVC(ssp), src, NULL, 0, 0);
if (error)
goto out;
@@ -1727,7 +1600,7 @@
*/
sep = (src->n_flag & N_XATTR) ? ':' : '\\';
mb_put_uint8(mbp, SMB_DT_ASCII);
- error = smbfs_fullpath(mbp, SSTOVC(ssp), tdnp, tname, &tnmlen, sep);
+ error = smbfs_fullpath(mbp, SSTOVC(ssp), tdnp, tname, tnmlen, sep);
if (error)
goto out;
@@ -1759,11 +1632,11 @@
smb_rq_bstart(rqp);
mb_put_uint8(mbp, SMB_DT_ASCII);
- error = smbfs_fullpath(mbp, SSTOVC(ssp), src, NULL, NULL, '\\');
+ error = smbfs_fullpath(mbp, SSTOVC(ssp), src, NULL, 0, '\\');
if (error)
goto out;
mb_put_uint8(mbp, SMB_DT_ASCII);
- error = smbfs_fullpath(mbp, SSTOVC(ssp), tdnp, tname, &tnmlen, '\\');
+ error = smbfs_fullpath(mbp, SSTOVC(ssp), tdnp, tname, tnmlen, '\\');
if (error)
goto out;
smb_rq_bend(rqp);
@@ -1791,7 +1664,7 @@
smb_rq_wend(rqp);
smb_rq_bstart(rqp);
mb_put_uint8(mbp, SMB_DT_ASCII);
- error = smbfs_fullpath(mbp, SSTOVC(ssp), dnp, name, &len, '\\');
+ error = smbfs_fullpath(mbp, SSTOVC(ssp), dnp, name, len, '\\');
if (!error) {
smb_rq_bend(rqp);
error = smb_rq_simple(rqp);
@@ -1850,7 +1723,7 @@
smb_rq_wend(rqp);
smb_rq_bstart(rqp);
mb_put_uint8(mbp, SMB_DT_ASCII);
- error = smbfs_fullpath(mbp, SSTOVC(ssp), np, NULL, NULL, '\\');
+ error = smbfs_fullpath(mbp, SSTOVC(ssp), np, NULL, 0, '\\');
if (!error) {
smb_rq_bend(rqp);
error = smb_rq_simple(rqp);
@@ -1868,7 +1741,7 @@
struct mdchain *mdp;
uint8_t wc, bt;
uint16_t ec, dlen, bc;
- int len, maxent, error, iseof = 0;
+ int maxent, error, iseof = 0;
maxent = min(ctx->f_left,
(vcp->vc_txmax - SMB_HDRLEN - 2*2) / SMB_DENTRYLEN);
@@ -1889,9 +1762,8 @@
smb_rq_bstart(rqp);
mb_put_uint8(mbp, SMB_DT_ASCII); /* buffer format */
if (ctx->f_flags & SMBFS_RDD_FINDFIRST) {
- len = ctx->f_wclen;
- error = smbfs_fullpath(mbp, vcp, ctx->f_dnp, ctx->f_wildcard,
- &len, '\\');
+ error = smbfs_fullpath(mbp, vcp, ctx->f_dnp,
+ ctx->f_wildcard, ctx->f_wclen, '\\');
if (error)
return (error);
mb_put_uint8(mbp, SMB_DT_VARIABLE);
@@ -2029,7 +1901,7 @@
struct mbchain *mbp;
struct mdchain *mdp;
uint16_t ecnt, eos, lno, flags;
- int len, error;
+ int error;
if (ctx->f_t2) {
smb_t2_done(ctx->f_t2);
@@ -2053,9 +1925,8 @@
mb_put_uint16le(mbp, flags);
mb_put_uint16le(mbp, ctx->f_infolevel);
mb_put_uint32le(mbp, 0);
- len = ctx->f_wclen;
- error = smbfs_fullpath(mbp, vcp, ctx->f_dnp, ctx->f_wildcard,
- &len, '\\');
+ error = smbfs_fullpath(mbp, vcp, ctx->f_dnp,
+ ctx->f_wildcard, ctx->f_wclen, '\\');
if (error)
return (error);
} else {
--- a/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_subr.c Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_subr.c Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -66,19 +67,15 @@
*/
int
smbfs_fullpath(struct mbchain *mbp, struct smb_vc *vcp, struct smbnode *dnp,
- const char *name, int *lenp, u_int8_t sep)
+ const char *name, int nmlen, u_int8_t sep)
{
int caseopt = SMB_CS_NONE;
- int error, len = 0;
int unicode = (SMB_UNICODE_STRINGS(vcp)) ? 1 : 0;
+ int error;
if (SMB_DIALECT(vcp) < SMB_DIALECT_LANMAN1_0)
caseopt |= SMB_CS_UPPER;
- if (lenp) {
- len = *lenp;
- *lenp = 0;
- }
if (unicode) {
error = mb_put_padbyte(mbp);
if (error)
@@ -87,7 +84,7 @@
error = smb_put_dmem(mbp, vcp,
dnp->n_rpath, dnp->n_rplen,
- caseopt, lenp);
+ caseopt, NULL);
if (name) {
/*
* Special case at share root:
@@ -116,14 +113,12 @@
error = mb_put_uint16le(mbp, sep);
else
error = mb_put_uint8(mbp, sep);
- if (!error && lenp)
- *lenp += (unicode + 1);
if (error)
return (error);
}
/* Put the name */
error = smb_put_dmem(mbp, vcp,
- name, len, caseopt, lenp);
+ name, nmlen, caseopt, NULL);
if (error)
return (error);
}
@@ -132,8 +127,6 @@
error = mb_put_uint16le(mbp, 0);
else
error = mb_put_uint8(mbp, 0);
- if (!error && lenp)
- *lenp += (unicode + 1);
return (error);
}
--- a/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_subr.h Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_subr.h Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,6 +43,8 @@
#include <sys/cmn_err.h>
#include <netsmb/mchain.h>
+#include <netsmb/smb_subr.h>
+#include <smbfs/smbfs_node.h>
#if defined(DEBUG) || defined(lint)
#define SMB_VNODE_DEBUG 1
@@ -196,7 +199,7 @@
struct smb_cred *scrp);
int smbfs_smb_findclose(struct smbfs_fctx *ctx, struct smb_cred *scrp);
int smbfs_fullpath(struct mbchain *mbp, struct smb_vc *vcp,
- struct smbnode *dnp, const char *name, int *nmlenp, uint8_t sep);
+ struct smbnode *dnp, const char *name, int nmlen, uint8_t sep);
int smbfs_smb_lookup(struct smbnode *dnp, const char **namep, int *nmlenp,
struct smbfattr *fap, struct smb_cred *scrp);
int smbfs_smb_hideit(struct smbnode *np, const char *name, int len,
--- a/usr/src/uts/common/netsmb/smb_dev.h Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/common/netsmb/smb_dev.h Thu Jun 30 17:58:05 2011 -0400
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -71,7 +72,7 @@
* make them incompatible with an old driver.
*/
#define NSMB_VERMAJ 1
-#define NSMB_VERMIN 3900
+#define NSMB_VERMIN 4000
#define NSMB_VERSION (NSMB_VERMAJ * 100000 + NSMB_VERMIN)
/*
@@ -217,14 +218,11 @@
/*
* Structure used with SMBIOC_TREE_FIND, _CONNECT
*/
-#define SMBIOC_STYPE_LEN 8
struct smbioc_oshare {
- uint32_t sh_pwlen;
+ uint32_t sh_use; /* requested */
+ uint32_t sh_type; /* returned */
char sh_name[SMBIOC_MAX_NAME];
char sh_pass[SMBIOC_MAX_NAME];
- /* share types, in ASCII form, i.e. "A:", "IPC", ... */
- char sh_type_req[SMBIOC_STYPE_LEN]; /* requested */
- char sh_type_ret[SMBIOC_STYPE_LEN]; /* returned */
};
typedef struct smbioc_oshare smbioc_oshare_t;
@@ -342,7 +340,7 @@
} smbioc_flags_t;
typedef struct smbioc_rw {
- uint32_t ioc_fh;
+ int32_t ioc_fh;
uint32_t ioc_cnt;
lloff_t _ioc_offset;
lptr_t _ioc_base;
@@ -350,6 +348,21 @@
#define ioc_offset _ioc_offset._f
#define ioc_base _ioc_base.lp_ptr
+typedef struct smbioc_ntcreate {
+ uint32_t ioc_req_acc;
+ uint32_t ioc_efattr;
+ uint32_t ioc_share_acc;
+ uint32_t ioc_open_disp;
+ uint32_t ioc_creat_opts;
+ char ioc_name[SMBIOC_MAX_NAME];
+} smbioc_ntcreate_t;
+
+typedef struct smbioc_printjob {
+ uint16_t ioc_setuplen;
+ uint16_t ioc_prmode;
+ char ioc_title[SMBIOC_MAX_NAME];
+} smbioc_printjob_t;
+
/* Password Keychain (PK) support. */
typedef struct smbioc_pk {
uid_t pk_uid; /* UID for PAM use */
@@ -375,11 +388,16 @@
SMBIOC_GETVERS = SMBIOC_BASE, /* keep first */
SMBIOC_FLAGS2, /* get hflags2 */
SMBIOC_GETSSNKEY, /* get SMB session key */
+ SMBIOC_DUP_DEV, /* duplicate dev handle */
SMBIOC_REQUEST, /* simple request */
SMBIOC_T2RQ, /* trans2 request */
+
SMBIOC_READ, /* read (pipe) */
SMBIOC_WRITE, /* write (pipe) */
+ SMBIOC_NTCREATE, /* open or create */
+ SMBIOC_PRINTJOB, /* open print job */
+ SMBIOC_CLOSEFH, /* from ntcreate or printjob */
SMBIOC_SSN_CREATE,
SMBIOC_SSN_FIND,
--- a/usr/src/uts/intel/nsmb/ioc_check.ref Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/intel/nsmb/ioc_check.ref Thu Jun 30 17:58:05 2011 -0400
@@ -8,15 +8,12 @@
#define SSN_ID 0x8
#define SSN_SRVNAME 0x228
#define SSN_SRVNAME_INCR 0x1
-#define SH_PWLEN 0x0
-#define SH_NAME 0x4
+#define SH_USE 0x0
+#define SH_TYPE 0x4
+#define SH_NAME 0x8
#define SH_NAME_INCR 0x1
-#define SH_PASS 0x104
+#define SH_PASS 0x108
#define SH_PASS_INCR 0x1
-#define SH_TYPE_REQ 0x204
-#define SH_TYPE_REQ_INCR 0x1
-#define SH_TYPE_RET 0x20c
-#define SH_TYPE_RET_INCR 0x1
#define TC_FLAGS 0x0
#define TC_OPT 0x4
#define TC_SH 0x8
@@ -61,8 +58,8 @@
#define IOC_SETUP 0x0
#define IOC_SETUP_INCR 0x2
#define IOC_SETUPCNT 0x8
-#define IOC_NAME 0xc
-#define IOC_NAME_INCR 0x1
+#define IOC_T2_NAME 0xc
+#define IOC_T2_NAME_INCR 0x1
#define IOC_TPARAMCNT 0x8c
#define IOC_TDATACNT 0x8e
#define IOC_RPARAMCNT 0x90
@@ -84,6 +81,19 @@
#define IOC_CNT 0x4
#define _IOC_OFFSET 0x8
#define _IOC_BASE 0x10
+#define SIZEOF_NTCREATE 0x114
+#define IOC_REQ_ACC 0x0
+#define IOC_EFATTR 0x4
+#define IOC_SHARE_ACC 0x8
+#define IOC_OPEN_DISP 0xc
+#define IOC_CREAT_OPTS 0x10
+#define IOC_NTCR_NAME 0x14
+#define IOC_NTCR_NAME_INCR 0x1
+#define SIZEOF_PRINTJOB 0x104
+#define IOC_SETUPLEN 0x0
+#define IOC_PRMODE 0x2
+#define IOC_TITLE 0x4
+#define IOC_TITLE_INCR 0x1
#define SIZEOF_SMBIOC_PK 0x224
#define PK_UID 0x0
#define PK_DOM 0x4
--- a/usr/src/uts/sparc/nsmb/ioc_check.ref Fri Jun 24 08:44:32 2011 -0700
+++ b/usr/src/uts/sparc/nsmb/ioc_check.ref Thu Jun 30 17:58:05 2011 -0400
@@ -8,15 +8,12 @@
#define SSN_ID 0x8
#define SSN_SRVNAME 0x228
#define SSN_SRVNAME_INCR 0x1
-#define SH_PWLEN 0x0
-#define SH_NAME 0x4
+#define SH_USE 0x0
+#define SH_TYPE 0x4
+#define SH_NAME 0x8
#define SH_NAME_INCR 0x1
-#define SH_PASS 0x104
+#define SH_PASS 0x108
#define SH_PASS_INCR 0x1
-#define SH_TYPE_REQ 0x204
-#define SH_TYPE_REQ_INCR 0x1
-#define SH_TYPE_RET 0x20c
-#define SH_TYPE_RET_INCR 0x1
#define TC_FLAGS 0x0
#define TC_OPT 0x4
#define TC_SH 0x8
@@ -61,8 +58,8 @@
#define IOC_SETUP 0x0
#define IOC_SETUP_INCR 0x2
#define IOC_SETUPCNT 0x8
-#define IOC_NAME 0xc
-#define IOC_NAME_INCR 0x1
+#define IOC_T2_NAME 0xc
+#define IOC_T2_NAME_INCR 0x1
#define IOC_TPARAMCNT 0x8c
#define IOC_TDATACNT 0x8e
#define IOC_RPARAMCNT 0x90
@@ -84,6 +81,19 @@
#define IOC_CNT 0x4
#define _IOC_OFFSET 0x8
#define _IOC_BASE 0x10
+#define SIZEOF_NTCREATE 0x114
+#define IOC_REQ_ACC 0x0
+#define IOC_EFATTR 0x4
+#define IOC_SHARE_ACC 0x8
+#define IOC_OPEN_DISP 0xc
+#define IOC_CREAT_OPTS 0x10
+#define IOC_NTCR_NAME 0x14
+#define IOC_NTCR_NAME_INCR 0x1
+#define SIZEOF_PRINTJOB 0x104
+#define IOC_SETUPLEN 0x0
+#define IOC_PRMODE 0x2
+#define IOC_TITLE 0x4
+#define IOC_TITLE_INCR 0x1
#define SIZEOF_SMBIOC_PK 0x224
#define PK_UID 0x0
#define PK_DOM 0x4