summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/fs.d/smbclnt/test/Makefile56
-rw-r--r--usr/src/cmd/fs.d/smbclnt/test/srvenum.c436
-rw-r--r--usr/src/cmd/fs.d/smbclnt/test/srvinfo.c (renamed from usr/src/cmd/fs.d/smbclnt/test/testnp.c)15
-rw-r--r--usr/src/cmd/fs.d/smbclnt/test/tconn.c171
-rw-r--r--usr/src/cmd/power/Makefile3
-rw-r--r--usr/src/cmd/power/handlers.c8
-rw-r--r--usr/src/cmd/power/parse.c9
-rw-r--r--usr/src/cmd/power/pm_pam_conv.c2
-rw-r--r--usr/src/cmd/power/powerd.c8
-rw-r--r--usr/src/cmd/power/sys-suspend.c14
-rw-r--r--usr/src/cmd/ps/Makefile.com2
-rw-r--r--usr/src/cmd/ps/ps.c4
-rw-r--r--usr/src/cmd/ps/ucbps.c2
-rw-r--r--usr/src/lib/libsmbfs/netsmb/smb_lib.h5
-rw-r--r--usr/src/lib/libsmbfs/netsmb/smbfs_api.h3
-rw-r--r--usr/src/lib/libsmbfs/smb/connect.c95
-rw-r--r--usr/src/lib/libsmbfs/smb/crypt.c99
-rw-r--r--usr/src/lib/libsmbfs/smb/ctx.c15
-rw-r--r--usr/src/lib/libsmbfs/smb/negprot.c34
-rw-r--r--usr/src/lib/libsmbfs/smb/ntlm.c178
-rw-r--r--usr/src/lib/libsmbfs/smb/ntlm.h11
-rw-r--r--usr/src/lib/libsmbfs/smb/ntlmssp.c257
-rw-r--r--usr/src/lib/libsmbfs/smb/ntlmssp.h15
-rw-r--r--usr/src/lib/libsmbfs/smb/smb_crypt.h19
-rw-r--r--usr/src/lib/libsmbfs/smb/ssnsetup.c73
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/mapfile-vers3
-rw-r--r--usr/src/man/man3c/Makefile34
-rw-r--r--usr/src/man/man3c/ucred.3c (renamed from usr/src/man/man3c/ucred_get.3c)9
-rw-r--r--usr/src/pkg/manifests/system-library.man3c.inc33
-rw-r--r--usr/src/tools/ctf/cvt/ctftools.h6
30 files changed, 1263 insertions, 356 deletions
diff --git a/usr/src/cmd/fs.d/smbclnt/test/Makefile b/usr/src/cmd/fs.d/smbclnt/test/Makefile
index 40f12dfc39..62eb716f5f 100644
--- a/usr/src/cmd/fs.d/smbclnt/test/Makefile
+++ b/usr/src/cmd/fs.d/smbclnt/test/Makefile
@@ -19,41 +19,63 @@
# 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.
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
#
-FSTYPE= smbfs
-LIBPROG= testnp
-ROOTFS_PROG= $(LIBPROG)
+include $(SRC)/cmd/Makefile.cmd
-include ../../Makefile.fstype
+PROG= srvenum srvinfo tconn
+OBJS = $(PROG:%=%.o)
+SRCS = $(OBJS:%.o=%.c)
-OBJS= $(LIBPROG).o
-SRCS= $(LIBPROG).c $(FSLIBSRC)
+# ROOTFS_PROG= $(LIBPROG)
+# include ../../Makefile.fstype
+ROOTOPTPKG = $(ROOT)/opt/smbcl-tests
+TESTDIR = $(ROOTOPTPKG)/tests
+INST_CMDS = $(PROG:%=$(TESTDIR)/%)
+
+# OBJS= $(LIBPROG).o
+# SRCS= $(LIBPROG).c $(FSLIBSRC)
+
+CPPFLAGS += -I../../../../uts/common
+CPPFLAGS += -I../../../../lib/libsmbfs
+
+LDLIBS += -R '$$ORIGIN/../../../usr/lib'
LDLIBS += -lsmbfs
+LINTLIBS= -L$(ROOTLIB) -lsmbfs
CFLAGS += $(CCVERBOSE)
CERRWARN += -_gcc=-Wno-unused-variable
C99MODE= $(C99_ENABLE)
-CLOBBERFILES += $(LIBPROG)
+LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2
+
+# CLOBBERFILES += $(LIBPROG)
-# uncomment these for dbx debugging
-#COPTFLAG = -g
-#CTF_FLAGS =
-#CTFCONVERT_O=
-#CTFMERGE_LIB=
+all: $(PROG)
-all: $(ROOTFS_PROG)
+install: all $(ROOTOPTPKG) $(TESTDIR) $(INST_CMDS)
-install: $(ROOTLIBFSTYPEPROG)
+lint:
+ for f in $(SRCS); do ;\
+ $(LINT.c) $$f $(LINTLIBS) ; done
-lint: lint_SRCS
+clobber: clean
+ -$(RM) $(PROG)
clean:
- $(RM) $(OBJS)
+ -$(RM) $(OBJS)
+
+$(ROOTOPTPKG):
+ $(INS.dir)
+
+$(TESTDIR):
+ $(INS.dir)
+
+$(TESTDIR)/%: %
+ $(INS.file)
.KEEP_STATE:
diff --git a/usr/src/cmd/fs.d/smbclnt/test/srvenum.c b/usr/src/cmd/fs.d/smbclnt/test/srvenum.c
new file mode 100644
index 0000000000..ee3aeba014
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/test/srvenum.c
@@ -0,0 +1,436 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * Test program for the smbfs named pipe API.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <libintl.h>
+
+#include <netsmb/smbfs_api.h>
+
+/*
+ * This is a quick hack for testing client-side named pipes.
+ * Its purpose is to test the ability to connect to a server,
+ * open a pipe, send and receive data. The "hack" aspect is
+ * the use of hand-crafted RPC messages, which allows testing
+ * of the named pipe API separately from the RPC libraries.
+ *
+ * I captured the two small name pipe messages sent when
+ * requesting a share list via RPC over /pipe/srvsvc and
+ * dropped them into the arrays below (bind and enum).
+ * This program sends the two messages (with adjustments)
+ * and just dumps whatever comes back over the pipe.
+ * Use wireshark if you want to see decoded messages.
+ */
+
+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 "enum servers" call, in two parts */
+static const uchar_t
+srvsvc_enum1[] = {
+ 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
+#define ENUM_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, 0x0f, 0x00,
+#define ENUM_SLEN1_OFF 28
+#define ENUM_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 const uchar_t
+srvsvc_enum2[] = {
+ 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
+
+static uchar_t sendbuf[1024];
+static uchar_t recvbuf[4096];
+static char *server;
+
+static int pipetest(struct smb_ctx *);
+
+static void
+srvenum_usage(void)
+{
+ printf("usage: srvenum [-d domain][-u user][-p passwd] server\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c, error;
+ struct smb_ctx *ctx = NULL;
+ char *dom = NULL;
+ char *usr = NULL;
+ char *pw = NULL;
+
+ while ((c = getopt(argc, argv, "vd:u:p:")) != -1) {
+ switch (c) {
+ case 'v':
+ smb_verbose = 1;
+ break;
+
+ case 'd':
+ dom = optarg;
+ break;
+ case 'u':
+ usr = optarg;
+ break;
+ case 'p':
+ pw = optarg;
+ break;
+ case '?':
+ srvenum_usage();
+ break;
+ }
+ }
+ if (optind >= argc)
+ srvenum_usage();
+ server = argv[optind];
+
+ if (pw != NULL && (dom == NULL || usr == NULL)) {
+ fprintf(stderr, "%s: -p arg requires -d dom -u usr\n",
+ argv[0]);
+ srvenum_usage();
+ }
+
+ /*
+ * This section is intended to demonstrate how an
+ * RPC client library might use this interface.
+ */
+ error = smb_ctx_alloc(&ctx);
+ if (error) {
+ fprintf(stderr, "%s: smb_ctx_alloc failed\n", argv[0]);
+ goto out;
+ }
+
+ /*
+ * Set server, share, domain, user
+ * (in the ctx handle).
+ */
+ smb_ctx_setfullserver(ctx, server);
+ smb_ctx_setshare(ctx, "IPC$", USE_IPC);
+ if (dom)
+ smb_ctx_setdomain(ctx, dom, B_TRUE);
+ if (usr)
+ smb_ctx_setuser(ctx, usr, B_TRUE);
+ if (pw)
+ smb_ctx_setpassword(ctx, pw, NULL);
+
+
+ /*
+ * If this code were in smbutil or mount_smbfs, it would
+ * get system and $HOME/.nsmbrc settings here, like this:
+ */
+#if 0
+ error = smb_ctx_readrc(ctx);
+ if (error) {
+ fprintf(stderr, "%s: smb_ctx_readrc failed\n", argv[0]);
+ goto out;
+ }
+#endif
+
+ /*
+ * Resolve the server address,
+ * setup derived defaults.
+ */
+ error = smb_ctx_resolve(ctx);
+ if (error) {
+ fprintf(stderr, "%s: smb_ctx_resolve failed\n", argv[0]);
+ goto out;
+ }
+
+ /*
+ * Get the session and tree.
+ */
+ error = smb_ctx_get_ssn(ctx);
+ if (error) {
+ fprintf(stderr, "//%s: login failed, error %d\n",
+ server, error);
+ goto out;
+ }
+ error = smb_ctx_get_tree(ctx);
+ if (error) {
+ fprintf(stderr, "//%s/%s: tree connect failed, %d\n",
+ server, "IPC$", error);
+ goto out;
+ }
+
+ /*
+ * Do some named pipe I/O.
+ */
+ error = pipetest(ctx);
+ if (error) {
+ fprintf(stderr, "pipetest, %d\n", error);
+ goto out;
+ }
+
+out:
+ smb_ctx_free(ctx);
+
+ return ((error) ? 1 : 0);
+}
+
+static void
+hexdump(const uchar_t *buf, int len) {
+ int idx;
+ char ascii[24];
+ char *pa = ascii;
+
+ memset(ascii, '\0', sizeof (ascii));
+
+ idx = 0;
+ while (len--) {
+ if ((idx & 15) == 0) {
+ printf("[%04X] ", idx);
+ pa = ascii;
+ }
+ if (*buf > ' ' && *buf <= '~')
+ *pa++ = *buf;
+ else
+ *pa++ = '.';
+ printf("%02x ", *buf++);
+
+ idx++;
+ if ((idx & 7) == 0) {
+ *pa++ = ' ';
+ putchar(' ');
+ }
+ if ((idx & 15) == 0) {
+ *pa = '\0';
+ printf("%s\n", ascii);
+ }
+ }
+
+ if ((idx & 15) != 0) {
+ *pa = '\0';
+ /* column align the last ascii row */
+ do {
+ printf(" ");
+ idx++;
+ if ((idx & 7) == 0)
+ putchar(' ');
+ } while ((idx & 15) != 0);
+ printf("%s\n", ascii);
+ }
+}
+
+/*
+ * Put a unicode UNC server name, including the null.
+ * Quick-n-dirty, just for this test...
+ */
+static int
+put_uncserver(const char *s, uchar_t *buf)
+{
+ uchar_t *p = buf;
+ char c;
+
+ *p++ = '\\'; *p++ = '\0';
+ *p++ = '\\'; *p++ = '\0';
+
+ do {
+ c = *s++;
+ if (c == '/')
+ c = '\\';
+ *p++ = c;
+ *p++ = '\0';
+
+ } while (c != 0);
+
+ return (p - buf);
+}
+
+/*
+ * 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 enum resp, err=%d\n", err);
+ return (err);
+ }
+ if (smb_verbose) {
+ printf("bind ack (more), len=%d\n", len);
+ hexdump(recvbuf, len);
+ }
+ }
+
+ return (0);
+}
+
+static int
+do_enum(int fid)
+{
+ int err, len, rlen, wlen;
+ uchar_t *p;
+
+ /*
+ * Build the enum request - three parts.
+ * See above: srvsvc_enum1, srvsvc_enum2
+ *
+ * First part: RPC header, etc.
+ */
+ p = sendbuf;
+ len = sizeof (srvsvc_enum1); /* 40 */
+ memcpy(p, srvsvc_enum1, len);
+ p += len;
+
+ /* Second part: UNC server name */
+ len = put_uncserver(server, p);
+ p += len;
+ sendbuf[ENUM_SLEN1_OFF] = len / 2;
+ sendbuf[ENUM_SLEN2_OFF] = len / 2;
+
+ /* Third part: level, etc. (align4) */
+ for (len = (p - sendbuf) & 3; len; len--)
+ *p++ = '\0';
+ len = sizeof (srvsvc_enum2); /* 28 */
+ memcpy(p, srvsvc_enum2, len);
+ p += len;
+
+ /*
+ * Compute total length, and fixup RPC header.
+ */
+ len = p - sendbuf;
+ sendbuf[ENUM_RPCLEN_OFF] = len;
+
+ /*
+ * Send the enum 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 enum req, err=%d\n", err);
+ return (err);
+ }
+ if (wlen != len) {
+ printf("write enum 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 enum resp, err=%d\n", err);
+ return (err);
+ }
+
+ /* Just dump the response data. */
+ printf("enum recv, len=%d\n", rlen);
+ hexdump(recvbuf, rlen);
+
+ 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_enum(fd);
+ if (err)
+ printf("do_enum: %d\n", err);
+
+out:
+ smb_fh_close(fd);
+ return (0);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/test/testnp.c b/usr/src/cmd/fs.d/smbclnt/test/srvinfo.c
index 7b28194b0b..81ba8c9afc 100644
--- a/usr/src/cmd/fs.d/smbclnt/test/testnp.c
+++ b/usr/src/cmd/fs.d/smbclnt/test/srvinfo.c
@@ -20,8 +20,8 @@
*/
/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -93,9 +93,9 @@ static char *server;
static int pipetest(struct smb_ctx *);
static void
-testnp_usage(void)
+srvinfo_usage(void)
{
- printf("usage: testnp [-d domain][-u user][-p passwd] server\n");
+ printf("usage: srvinfo [-d domain][-u user][-p passwd] server\n");
exit(1);
}
@@ -124,18 +124,18 @@ main(int argc, char *argv[])
pw = optarg;
break;
case '?':
- testnp_usage();
+ srvinfo_usage();
break;
}
}
if (optind >= argc)
- testnp_usage();
+ srvinfo_usage();
server = argv[optind];
if (pw != NULL && (dom == NULL || usr == NULL)) {
- fprintf(stderr, "%0: -p arg requires -d dom -u usr\n",
+ fprintf(stderr, "%s: -p arg requires -d dom -u usr\n",
argv[0]);
- testnp_usage();
+ srvinfo_usage();
}
/*
@@ -236,7 +236,6 @@ static int
put_uncserver(const char *s, uchar_t *buf)
{
uchar_t *p = buf;
- int slashcnt = 0;
char c;
*p++ = '\\'; *p++ = '\0';
diff --git a/usr/src/cmd/fs.d/smbclnt/test/tconn.c b/usr/src/cmd/fs.d/smbclnt/test/tconn.c
new file mode 100644
index 0000000000..bfeac98fe0
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/test/tconn.c
@@ -0,0 +1,171 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * Test program for opening an SMB connection directly.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <libintl.h>
+
+#include <netsmb/smb_lib.h>
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+extern int smb_iod_connect(struct smb_ctx *);
+
+static char *server;
+
+static void
+tconn_usage(void)
+{
+ printf("usage: tconn [-d domain][-u user][-p passwd] server\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c, error, aflags;
+ struct smb_ctx *ctx = NULL;
+ char *dom = NULL;
+ char *usr = NULL;
+ char *pw = NULL;
+ char *secopt = NULL;
+ struct addrinfo *ai;
+
+ while ((c = getopt(argc, argv, "vd:p:s:u:")) != -1) {
+ switch (c) {
+ case 'v':
+ smb_debug = 1;
+ smb_verbose = 1;
+ break;
+
+ case 'd':
+ dom = optarg;
+ break;
+ case 'u':
+ usr = optarg;
+ break;
+ case 'p':
+ pw = optarg;
+ break;
+ case 's':
+ secopt = optarg;
+ break;
+ case '?':
+ tconn_usage();
+ break;
+ }
+ }
+ if (optind >= argc)
+ tconn_usage();
+ server = argv[optind];
+
+ if (pw != NULL && (dom == NULL || usr == NULL)) {
+ fprintf(stderr, "%s: -p arg requires -d dom -u usr\n",
+ argv[0]);
+ tconn_usage();
+ }
+
+ /*
+ * This section is intended to demonstrate how an
+ * RPC client library might use this interface.
+ */
+ error = smb_ctx_alloc(&ctx);
+ if (error) {
+ fprintf(stderr, "%s: smb_ctx_alloc failed\n", argv[0]);
+ goto out;
+ }
+
+ /*
+ * Set server, share, domain, user
+ * (in the ctx handle).
+ */
+ smb_ctx_setfullserver(ctx, server);
+ smb_ctx_setshare(ctx, "IPC$", USE_IPC);
+ if (dom)
+ smb_ctx_setdomain(ctx, dom, B_TRUE);
+ if (usr)
+ smb_ctx_setuser(ctx, usr, B_TRUE);
+ if (pw)
+ smb_ctx_setpassword(ctx, pw, NULL);
+
+ /*
+ * Hackish option to override the Authentication Type flags.
+ * Sorry about exposing the flag values here, but this is
+ * really a programmer's test tool. See smbfs_api.h for
+ * the SMB_AT_... flag values.
+ */
+ if (secopt != NULL) {
+ aflags = atoi(secopt);
+ if (aflags < 1 || aflags > 0x1f) {
+ fprintf(stderr, "%s: -s {0..31}\n", argv[0]);
+ tconn_usage();
+ }
+ smb_ctx_setauthflags(ctx, aflags);
+ }
+
+ /*
+ * Resolve the server address,
+ * setup derived defaults.
+ */
+ error = smb_ctx_resolve(ctx);
+ if (error) {
+ fprintf(stderr, "%s: smb_ctx_resolve failed\n", argv[0]);
+ goto out;
+ }
+
+ if ((ai = ctx->ct_addrinfo) == NULL) {
+ fprintf(stderr, "%s: no ct_addrinfo\n", argv[0]);
+ goto out;
+ }
+ memcpy(&ctx->ct_srvaddr, ai->ai_addr, ai->ai_addrlen);
+
+ /*
+ * If this code were in smbutil or mount_smbfs, it would
+ * get system and $HOME/.nsmbrc settings here, like this:
+ */
+ error = smb_iod_connect(ctx);
+ if (error) {
+ fprintf(stderr, "%s: smb_iod_connect failed\n", argv[0]);
+ goto out;
+ }
+
+ printf("Yea, we connected!\n");
+
+out:
+ smb_ctx_free(ctx);
+
+ return ((error) ? 1 : 0);
+}
diff --git a/usr/src/cmd/power/Makefile b/usr/src/cmd/power/Makefile
index 85e903e3ec..3496ab78df 100644
--- a/usr/src/cmd/power/Makefile
+++ b/usr/src/cmd/power/Makefile
@@ -90,9 +90,6 @@ $(ROOTUSRSBINSYSIDPM) := FILEMODE= 755
# lint pass one enforcement
#
CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-unused-value
.PARALLEL: $(OBJS)
diff --git a/usr/src/cmd/power/handlers.c b/usr/src/cmd/power/handlers.c
index c17158c40e..b74004955a 100644
--- a/usr/src/cmd/power/handlers.c
+++ b/usr/src/cmd/power/handlers.c
@@ -585,7 +585,7 @@ devpath(char **destp, char *src, int *errp)
* When the path has ":anything", display an error for
* a non-device or truncate a resolved+modifed path.
*/
- if (cp = strchr(src, ':')) {
+ if ((cp = strchr(src, ':')) != NULL) {
if (devok == 0) {
mesg(MERR, "physical path may not contain "
"a minor string (%s)\n", src);
@@ -714,7 +714,7 @@ static int
vlist_append(int **vlistp, int *vcntp, int value)
{
(*vcntp)++;
- if (*vlistp = realloc(*vlistp, *vcntp * sizeof (**vlistp)))
+ if ((*vlistp = realloc(*vlistp, *vcntp * sizeof (**vlistp))) != NULL)
*(*vlistp + *vcntp - 1) = value;
else
mesg(MERR, alloc_fmt, "threshold list", strerror(errno));
@@ -735,13 +735,13 @@ vlist_append(int **vlistp, int *vcntp, int value)
static int
get_thresh(int **vlistp, int *vcntp)
{
- int argn, value, gci, grp_cnt = 0, paren = 0, nerr = 0;
+ int argn, value, gci = 0, grp_cnt = 0, paren = 0, nerr = 0;
char *rp, *src;
for (argn = 2; (src = LINEARG(argn)) != NULL; argn++) {
if (*src == LPAREN) {
gci = *vcntp;
- if (nerr = vlist_append(vlistp, vcntp, 0))
+ if ((nerr = vlist_append(vlistp, vcntp, 0)) != 0)
break;
paren = 1;
src++;
diff --git a/usr/src/cmd/power/parse.c b/usr/src/cmd/power/parse.c
index 97e46fdb06..f524d8dca6 100644
--- a/usr/src/cmd/power/parse.c
+++ b/usr/src/cmd/power/parse.c
@@ -104,7 +104,8 @@ set_perm(char *defstr, char *user, int *perm, int cons)
else if (user != NULL &&
(*dinfo == '<') && (tk = strrchr(++dinfo, '>'))) {
/* Scan dinfo for a matching user. */
- for (*tk = '\0'; tk = strtok(dinfo, ", "); dinfo = NULL) {
+ for (*tk = '\0'; (tk = strtok(dinfo, ", ")) != NULL;
+ dinfo = NULL) {
mesg(MDEBUG, "match_user: cmp (\"%s\", \"%s\")\n",
tk, user);
if (strcmp(tk, user) == 0) {
@@ -353,7 +354,7 @@ find_line_end(char *line, int *lcnt)
*lcnt = 0;
next = line;
- while (lf = strchr(next, '\n')) {
+ while ((lf = strchr(next, '\n')) != NULL) {
(*lcnt)++;
if (lf == line || (*(lf - 1) != '\\') || *(lf + 1) == '\0')
break;
@@ -391,7 +392,7 @@ parse_conf_file(char *name, vact_t action, boolean_t first_parse)
lineno = 1;
line = file_buf;
- while (lend = find_line_end(line, &linc)) {
+ while ((lend = find_line_end(line, &linc)) != NULL) {
/*
* Each line should start with valid data
* but leading white-space can be ignored
@@ -429,7 +430,7 @@ parse_conf_file(char *name, vact_t action, boolean_t first_parse)
mesg(MDEBUG, "\nline %d, blank...\n", lineno);
else if (*line == '#')
mesg(MDEBUG, "\nline %d, comment...\n", lineno);
- else if (cnt = build_args(cline, cline + llen)) {
+ else if ((cnt = build_args(cline, cline + llen)) != 0) {
if ((cip = get_cinfo()) == NULL) {
mesg(MEXIT, "unrecognized keyword \"%s\"\n",
LINEARG(0));
diff --git a/usr/src/cmd/power/pm_pam_conv.c b/usr/src/cmd/power/pm_pam_conv.c
index 488f5c825e..cef797e990 100644
--- a/usr/src/cmd/power/pm_pam_conv.c
+++ b/usr/src/cmd/power/pm_pam_conv.c
@@ -66,7 +66,7 @@ static char *
getinput(int noecho)
{
struct termio tty;
- unsigned short tty_flags;
+ unsigned short tty_flags = 0;
char input[PAM_MAX_RESP_SIZE + 1];
int c;
int i = 0;
diff --git a/usr/src/cmd/power/powerd.c b/usr/src/cmd/power/powerd.c
index 2d4a3ae274..c24fa9d7f8 100644
--- a/usr/src/cmd/power/powerd.c
+++ b/usr/src/cmd/power/powerd.c
@@ -397,7 +397,7 @@ autos3_monitor(void)
fd = open(SRN, O_RDWR|O_EXCL|O_NDELAY);
if (fd == -1) {
logerror("Unable to open %s: %s", SRN, strerror(errno));
- thr_exit((void *) errno);
+ thr_exit((void *)(intptr_t)errno);
}
/*
@@ -407,7 +407,7 @@ autos3_monitor(void)
if (ret == -1) {
logerror("Ioctl SRN_IOC_AUTOSX failed: %s", strerror(errno));
(void) close(fd);
- thr_exit((void *) errno);
+ thr_exit((void *)(intptr_t)errno);
}
poll_fd.fd = fd;
/*CONSTCOND*/
@@ -422,7 +422,7 @@ autos3_monitor(void)
default:
logerror("Poll error: %s", strerror(errno));
(void) close(fd);
- thr_exit((void *) errno);
+ thr_exit((void *)(intptr_t)errno);
}
}
@@ -430,7 +430,7 @@ autos3_monitor(void)
if (ret == -1) {
logerror("ioctl error: %s", strerror(errno));
(void) close(fd);
- thr_exit((void *) errno);
+ thr_exit((void *)(intptr_t)errno);
}
switch (srn_event.ae_type) {
case 3: /* S3 */
diff --git a/usr/src/cmd/power/sys-suspend.c b/usr/src/cmd/power/sys-suspend.c
index c9116cd23a..9d055c7f66 100644
--- a/usr/src/cmd/power/sys-suspend.c
+++ b/usr/src/cmd/power/sys-suspend.c
@@ -576,12 +576,12 @@ main(int argc, char **argv)
char xauthority[MAXPATHLEN + 12] = "XAUTHORITY=";
struct passwd *pw;
- (void *) signal(SIGHUP, SIG_IGN);
- (void *) signal(SIGINT, SIG_IGN);
- (void *) signal(SIGQUIT, SIG_IGN);
- (void *) signal(SIGTSTP, SIG_IGN);
- (void *) signal(SIGTTIN, SIG_IGN);
- (void *) signal(SIGTTOU, SIG_IGN);
+ (void) signal(SIGHUP, SIG_IGN);
+ (void) signal(SIGINT, SIG_IGN);
+ (void) signal(SIGQUIT, SIG_IGN);
+ (void) signal(SIGTSTP, SIG_IGN);
+ (void) signal(SIGTTIN, SIG_IGN);
+ (void) signal(SIGTTOU, SIG_IGN);
/*
* If suspend is invoked from a daemon (case 1 above), it
@@ -721,7 +721,7 @@ main(int argc, char **argv)
* In case of "suspend" being called from daemon "powerd",
* signal SIGALRM is blocked so use "sigset()" instead of "signal()".
*/
- (void *) sigset(SIGALRM, alarm_handler);
+ (void) sigset(SIGALRM, alarm_handler);
/* Call the "suspend" function to do the last of the work */
pm_suspend();
diff --git a/usr/src/cmd/ps/Makefile.com b/usr/src/cmd/ps/Makefile.com
index 48e187ef48..aa7a2bec45 100644
--- a/usr/src/cmd/ps/Makefile.com
+++ b/usr/src/cmd/ps/Makefile.com
@@ -34,8 +34,6 @@ SRCS= $(OBJS:%.o=../%.c)
include ../../Makefile.cmd
CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
LDLIBS += -lproject
.KEEP_STATE:
diff --git a/usr/src/cmd/ps/ps.c b/usr/src/cmd/ps/ps.c
index 0a43a92fcb..78dabbccfe 100644
--- a/usr/src/cmd/ps/ps.c
+++ b/usr/src/cmd/ps/ps.c
@@ -911,7 +911,7 @@ stdmain(int argc, char **argv)
}
/* for each active process --- */
- while (dentp = readdir(dirp)) {
+ while ((dentp = readdir(dirp)) != NULL) {
if (dentp->d_name[0] == '.') /* skip . and .. */
continue;
if (print_proc(dentp->d_name) == 0)
@@ -1659,7 +1659,7 @@ print_field(psinfo_t *psinfo, struct field *f, const char *ttyp)
char *cp;
int length;
ulong_t mask;
- char c, *csave;
+ char c = '\0', *csave = NULL;
int zombie_lwp;
zombie_lwp = (Lflg && psinfo->pr_lwp.pr_sname == 'Z');
diff --git a/usr/src/cmd/ps/ucbps.c b/usr/src/cmd/ps/ucbps.c
index 67ca1629d7..3110e95313 100644
--- a/usr/src/cmd/ps/ucbps.c
+++ b/usr/src/cmd/ps/ucbps.c
@@ -396,7 +396,7 @@ ucbmain(int argc, char **argv)
psname[pdlen++] = '/';
/* for each active process --- */
- while (dentp = readdir(dirp)) {
+ while ((dentp = readdir(dirp)) != NULL) {
int psfd; /* file descriptor for /proc/nnnnn/psinfo */
int asfd; /* file descriptor for /proc/nnnnn/as */
diff --git a/usr/src/lib/libsmbfs/netsmb/smb_lib.h b/usr/src/lib/libsmbfs/netsmb/smb_lib.h
index 02eb6106c2..c1dc6886ac 100644
--- a/usr/src/lib/libsmbfs/netsmb/smb_lib.h
+++ b/usr/src/lib/libsmbfs/netsmb/smb_lib.h
@@ -33,8 +33,8 @@
*/
/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _NETSMB_SMB_LIB_H_
@@ -115,10 +115,11 @@ struct smb_ctx {
/* Strings from the SMB negotiate response. */
char *ct_srv_OS;
char *ct_srv_LM;
+ uint32_t ct_clnt_caps;
/* NTLM auth. stuff */
uchar_t ct_clnonce[NTLM_CHAL_SZ];
- uchar_t ct_ntlm_chal[NTLM_CHAL_SZ];
+ uchar_t ct_srv_chal[NTLM_CHAL_SZ];
char ct_password[SMBIOC_MAX_NAME];
/* See ssp.c */
diff --git a/usr/src/lib/libsmbfs/netsmb/smbfs_api.h b/usr/src/lib/libsmbfs/netsmb/smbfs_api.h
index bc320ee8ab..8436318b4c 100644
--- a/usr/src/lib/libsmbfs/netsmb/smbfs_api.h
+++ b/usr/src/lib/libsmbfs/netsmb/smbfs_api.h
@@ -20,9 +20,9 @@
*/
/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _NETSMB_SMBFS_API_H
@@ -90,7 +90,6 @@ typedef enum {
#define SMB_AT_NTLM1 4 /* NTLM (v1) */
#define SMB_AT_NTLM2 8 /* NTLMv2 */
#define SMB_AT_KRB5 0x10 /* Kerberos5 (AD) */
-#define SMB_AT_DEFAULT (SMB_AT_KRB5 | SMB_AT_NTLM2)
struct smb_ctx; /* anonymous here; real one in smb_lib.h */
typedef struct smb_ctx smb_ctx_t;
diff --git a/usr/src/lib/libsmbfs/smb/connect.c b/usr/src/lib/libsmbfs/smb/connect.c
index d0f4e2b228..c2ccc3361d 100644
--- a/usr/src/lib/libsmbfs/smb/connect.c
+++ b/usr/src/lib/libsmbfs/smb/connect.c
@@ -22,6 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -460,76 +461,68 @@ smb_iod_connect(smb_ctx_t *ctx)
}
/*
- * SMB Negotiate Protocol and
- * SMB Session Setup, one of 3 ways:
- * NULL session
- * Extended security,
- * NTLM (v2, v1)
- *
+ * Do SMB Negotiate Protocol.
+ */
+ err = smb_negprot(ctx, &blob);
+ if (err)
+ goto out;
+
+ /*
* Empty user name means an explicit request for
- * NULL session setup. No fall-back logic here.
- *
- * For NULL session, don't offer extended security.
- * That's a lot simpler than dealing with NTLMSSP.
+ * NULL session setup, which is a special case.
+ * If negotiate determined that we want to do
+ * SMB signing, we have to turn that off for a
+ * NULL session. [MS-SMB 3.3.5.3].
*/
if (ctx->ct_user[0] == '\0') {
- ctx->ct_vopt &= ~SMBVOPT_EXT_SEC;
- err = smb_negprot(ctx, &blob);
- if (err)
- goto out;
- err = smb_ssnsetup_null(ctx);
- } else {
- /*
- * Do SMB Negotiate Protocol.
- */
- err = smb_negprot(ctx, &blob);
- if (err)
- goto out;
+ /* Null user should have null domain too. */
+ ctx->ct_domain[0] = '\0';
+ ctx->ct_authflags = SMB_AT_ANON;
+ ctx->ct_clnt_caps &= ~SMB_CAP_EXT_SECURITY;
+ ctx->ct_vcflags &= ~SMBV_WILL_SIGN;
+ }
+ /*
+ * Do SMB Session Setup (authenticate)
+ *
+ * If the server negotiated extended security,
+ * run the SPNEGO state machine, otherwise do
+ * one of the old-style variants.
+ */
+ if (ctx->ct_clnt_caps & SMB_CAP_EXT_SECURITY) {
+ err = smb_ssnsetup_spnego(ctx, &blob);
+ } else {
/*
- * Do SMB Session Setup (authenticate)
- *
- * If the server negotiated extended security,
- * run the SPNEGO state machine.
+ * Server did NOT negotiate extended security.
+ * Try NTLMv2, NTLMv1, or ANON (if enabled).
*/
- if (ctx->ct_sopt.sv_caps & SMB_CAP_EXT_SECURITY) {
- err = smb_ssnsetup_spnego(ctx, &blob);
+ if (ctx->ct_authflags & SMB_AT_NTLM2) {
+ err = smb_ssnsetup_ntlm2(ctx);
+ } else if (ctx->ct_authflags & SMB_AT_NTLM1) {
+ err = smb_ssnsetup_ntlm1(ctx);
+ } else if (ctx->ct_authflags & SMB_AT_ANON) {
+ err = smb_ssnsetup_null(ctx);
} else {
/*
- * Server did NOT negotiate extended security.
- * Try NTLMv2, NTLMv1 (if enabled).
+ * Don't return EAUTH, because a new
+ * password prompt will not help.
*/
- if ((ctx->ct_authflags &
- (SMB_AT_NTLM2 | SMB_AT_NTLM1)) == 0) {
- /*
- * Don't return EAUTH, because a
- * new password will not help.
- */
- DPRINT("No NTLM authflags");
- err = ENOTSUP;
- goto out;
- }
- if (ctx->ct_authflags & SMB_AT_NTLM2)
- err = smb_ssnsetup_ntlm2(ctx);
- else
- err = EAUTH;
- if (err == EAUTH && 0 !=
- (ctx->ct_authflags & SMB_AT_NTLM1))
- err = smb_ssnsetup_ntlm1(ctx);
+ DPRINT("No NTLM authflags");
+ err = ENOTSUP;
}
}
- /* Tell library code we have a session. */
- ctx->ct_flags |= SMBCF_RESOLVED | SMBCF_SSNACTIVE;
-
out:
mb_done(&blob);
if (err) {
close(ctx->ct_tran_fd);
ctx->ct_tran_fd = -1;
- } else
+ } else {
+ /* Tell library code we have a session. */
+ ctx->ct_flags |= SMBCF_SSNACTIVE;
DPRINT("tran_fd = %d", ctx->ct_tran_fd);
+ }
return (err);
}
diff --git a/usr/src/lib/libsmbfs/smb/crypt.c b/usr/src/lib/libsmbfs/smb/crypt.c
index ea1d7e6dd1..13569c1b8c 100644
--- a/usr/src/lib/libsmbfs/smb/crypt.c
+++ b/usr/src/lib/libsmbfs/smb/crypt.c
@@ -22,6 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -29,7 +30,7 @@
*
* Some code copied from the server: libsmb smb_crypt.c
* with minor changes, i.e. errno.h return values.
- * XXX: Move this to a common library (later).
+ * XXX: Later, make the server use these.
*/
#include <sys/types.h>
@@ -67,13 +68,21 @@ smb_encrypt_DES(uchar_t *Result, int ResultLen,
int K, D;
int k, d;
- /* Calculate proper number of iterations */
+ /*
+ * Calculate proper number of iterations.
+ * Known call cases include:
+ * ResultLen=16, KeyLen=14, DataLen=8
+ * ResultLen=24, KeyLen=21, DataLen=8
+ * ResultLen=16, KeyLen=14, DataLen=16
+ */
K = KeyLen / 7;
D = DataLen / 8;
-
- if (ResultLen < (K * 8 * D)) {
+ if ((KeyLen % 7) || (DataLen % 8))
+ return (EINVAL);
+ if (K == 0 || D == 0)
+ return (EINVAL);
+ if (ResultLen < (K * 8))
return (EINVAL);
- }
/*
* Use SUNW convenience function to initialize the cryptoki
@@ -88,7 +97,10 @@ smb_encrypt_DES(uchar_t *Result, int ResultLen,
return (ENOTSUP);
}
- for (k = 0; k < K; k++) {
+ for (d = k = 0; k < K; k++, d++) {
+ /* Cycle the input again, as necessary. */
+ if (d == D)
+ d = 0;
smb_initlmkey(des_key, &Key[k * 7]);
rv = SUNW_C_KeyToObject(hSession, mechanism.mechanism,
des_key, 8, &hKey);
@@ -102,18 +114,18 @@ smb_encrypt_DES(uchar_t *Result, int ResultLen,
error = EIO;
goto exit_encrypt;
}
- ciphertext_len = DataLen;
- for (d = 0; d < D; d++) {
- /* Read in the data and encrypt this portion */
- rv = C_EncryptUpdate(hSession,
- (CK_BYTE_PTR)Data + (d * 8), 8,
- &Result[(k * (8 * D)) + (d * 8)],
- &ciphertext_len);
- if (rv != CKR_OK) {
- error = EIO;
- goto exit_encrypt;
- }
+ ciphertext_len = 8;
+
+ /* Read in the data and encrypt this portion */
+ rv = C_EncryptUpdate(hSession,
+ (CK_BYTE_PTR)Data + (d * 8), 8,
+ (CK_BYTE_PTR)Result + (k * 8),
+ &ciphertext_len);
+ if (rv != CKR_OK) {
+ error = EIO;
+ goto exit_encrypt;
}
+
(void) C_DestroyObject(hSession, hKey);
}
goto exit_session;
@@ -149,6 +161,59 @@ smb_initlmkey(uchar_t *keyout, const uchar_t *keyin)
}
/*
+ * CKM_RC4
+ */
+int
+smb_encrypt_RC4(uchar_t *Result, int ResultLen,
+ const uchar_t *Key, int KeyLen,
+ const uchar_t *Data, int DataLen)
+{
+ CK_RV rv;
+ CK_MECHANISM mechanism;
+ CK_OBJECT_HANDLE hKey;
+ CK_SESSION_HANDLE hSession;
+ CK_ULONG ciphertext_len;
+ int error = EIO;
+
+ /*
+ * Use SUNW convenience function to initialize the cryptoki
+ * library, and open a session with a slot that supports
+ * the mechanism we plan on using.
+ */
+ mechanism.mechanism = CKM_RC4;
+ mechanism.pParameter = NULL;
+ mechanism.ulParameterLen = 0;
+ rv = SUNW_C_GetMechSession(mechanism.mechanism, &hSession);
+ if (rv != CKR_OK) {
+ return (ENOTSUP);
+ }
+
+ rv = SUNW_C_KeyToObject(hSession, mechanism.mechanism,
+ Key, KeyLen, &hKey);
+ if (rv != CKR_OK)
+ goto exit_session;
+
+ /* Initialize the encryption operation in the session */
+ rv = C_EncryptInit(hSession, &mechanism, hKey);
+ if (rv != CKR_OK)
+ goto exit_encrypt;
+
+ ciphertext_len = ResultLen;
+ rv = C_EncryptUpdate(hSession,
+ (CK_BYTE_PTR)Data, DataLen,
+ (CK_BYTE_PTR)Result, &ciphertext_len);
+ if (rv == CKR_OK)
+ error = 0;
+
+exit_encrypt:
+ (void) C_DestroyObject(hSession, hKey);
+exit_session:
+ (void) C_CloseSession(hSession);
+
+ return (error);
+}
+
+/*
* Get some random bytes from /dev/urandom
*
* There may be a preferred way to call this via libpkcs11
diff --git a/usr/src/lib/libsmbfs/smb/ctx.c b/usr/src/lib/libsmbfs/smb/ctx.c
index 5681aa7226..e68213b6ef 100644
--- a/usr/src/lib/libsmbfs/smb/ctx.c
+++ b/usr/src/lib/libsmbfs/smb/ctx.c
@@ -33,8 +33,8 @@
*/
/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/param.h>
@@ -75,6 +75,9 @@
#define TRUE 1
#endif
+#define SMB_AT_DEFAULT (SMB_AT_KRB5 | SMB_AT_NTLM2)
+#define SMB_AT_MINAUTH (SMB_AT_KRB5 | SMB_AT_NTLM2 | SMB_AT_NTLM1)
+
struct nv {
char *name;
int value;
@@ -260,7 +263,7 @@ smb_ctx_init(struct smb_ctx *ctx)
ctx->ct_vopt = SMBVOPT_EXT_SEC;
ctx->ct_owner = SMBM_ANY_OWNER;
ctx->ct_authflags = SMB_AT_DEFAULT;
- ctx->ct_minauth = SMB_AT_DEFAULT;
+ ctx->ct_minauth = SMB_AT_MINAUTH;
/*
* Default domain, user, ...
@@ -1118,13 +1121,7 @@ smb_ctx_resolve(struct smb_ctx *ctx)
* check for a keychain entry.
* XXX: Only for auth NTLM?
*/
- if (ctx->ct_user[0] == '\0') {
- /*
- * No user name (anonymous session).
- * The minauth checks do not apply.
- */
- ctx->ct_authflags = SMB_AT_ANON;
- } else {
+ if (ctx->ct_user[0] != '\0') {
/*
* Have a user name.
* If we don't have a p/w yet,
diff --git a/usr/src/lib/libsmbfs/smb/negprot.c b/usr/src/lib/libsmbfs/smb/negprot.c
index 9345cd8c47..770b742c44 100644
--- a/usr/src/lib/libsmbfs/smb/negprot.c
+++ b/usr/src/lib/libsmbfs/smb/negprot.c
@@ -32,11 +32,11 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
* SMB Negotiate Protocol, and related.
- * Copied from the driver: smb_smb.c
*/
#include <errno.h>
@@ -66,6 +66,7 @@
#include <netsmb/smb_dev.h>
#include "charsets.h"
+#include "smb_crypt.h"
#include "private.h"
/*
@@ -87,6 +88,13 @@ static struct smb_dialect smb_dialects[] = {
#define SMB_DIALECT_MAX \
(sizeof (smb_dialects) / sizeof (struct smb_dialect) - 2)
+static const uint32_t smb_clnt_caps_mask =
+ SMB_CAP_UNICODE |
+ SMB_CAP_LARGE_FILES |
+ SMB_CAP_NT_SMBS |
+ SMB_CAP_STATUS32 |
+ SMB_CAP_EXT_SECURITY;
+
/*
* SMB Negotiate Protocol
* Based on code from the driver: smb_smb.c
@@ -118,9 +126,16 @@ smb_negprot(struct smb_ctx *ctx, struct mbdata *oblob)
* if we find out it doesn't. Need to do this because
* some servers reject all non-Unicode requests.
*/
- ctx->ct_hflags = SMB_FLAGS_CASELESS;
- ctx->ct_hflags2 = SMB_FLAGS2_KNOWS_LONG_NAMES |
- SMB_FLAGS2_ERR_STATUS | SMB_FLAGS2_UNICODE;
+ ctx->ct_hflags =
+ SMB_FLAGS_CASELESS |
+ SMB_FLAGS_CANONICAL_PATHNAMES;
+ ctx->ct_hflags2 =
+ SMB_FLAGS2_KNOWS_LONG_NAMES |
+ SMB_FLAGS2_KNOWS_EAS |
+ /* SMB_FLAGS2_IS_LONG_NAME |? */
+ /* EXT_SEC (see below) */
+ SMB_FLAGS2_ERR_STATUS |
+ SMB_FLAGS2_UNICODE;
/*
* Sould we offer extended security?
@@ -362,7 +377,7 @@ smb_negprot(struct smb_ctx *ctx, struct mbdata *oblob)
err = EBADRPC;
goto errout;
}
- err = md_get_mem(mbp, ctx->ct_ntlm_chal,
+ err = md_get_mem(mbp, ctx->ct_srv_chal,
NTLM_CHAL_SZ, MB_MSYSTEM);
/*
* Server domain follows (ignored)
@@ -423,6 +438,15 @@ smb_negprot(struct smb_ctx *ctx, struct mbdata *oblob)
is->is_rxmax = len;
is->is_wxmax = len;
+ /*
+ * Most of the "capability" bits we offer in session setup
+ * are just copied from those offered by the server.
+ */
+ ctx->ct_clnt_caps = sv->sv_caps & smb_clnt_caps_mask;
+
+ /* Get the client nonce. */
+ (void) smb_get_urandom(ctx->ct_clnonce, NTLM_CHAL_SZ);
+
return (0);
errout:
diff --git a/usr/src/lib/libsmbfs/smb/ntlm.c b/usr/src/lib/libsmbfs/smb/ntlm.c
index bee189561e..9f08a2eaca 100644
--- a/usr/src/lib/libsmbfs/smb/ntlm.c
+++ b/usr/src/lib/libsmbfs/smb/ntlm.c
@@ -34,6 +34,7 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -62,10 +63,11 @@
/*
* ntlm_compute_lm_hash
*
- * Compute an LM hash given a password
+ * Given a password, compute the LM hash.
+ * a.k.a. ResponseKeyLM in [MS-NLMP]
*
* Output:
- * hash: 16-byte "LanMan" (LM) hash.
+ * hash: 16-byte "LanMan" (LM) hash (normally ctx->ct_lmhash)
* Inputs:
* ucpw: User's password, upper-case UTF-8 string.
*
@@ -102,10 +104,11 @@ ntlm_compute_lm_hash(uchar_t *hash, const char *pass)
/*
* ntlm_compute_nt_hash
*
- * Compute an NT hash given a password in UTF-8.
+ * Given a password, compute the NT hash.
+ * a.k.a. the ResponseKeyNT in [MS-NLMP]
*
* Output:
- * hash: 16-byte "NT" hash.
+ * hash: 16-byte "NT" hash (normally ctx->ct_nthash)
* Inputs:
* upw: User's password, mixed-case UCS-2LE.
* pwlen: Size (in bytes) of upw
@@ -134,6 +137,7 @@ ntlm_compute_nt_hash(uchar_t *hash, const char *pass)
/*
* ntlm_v1_response
+ * a.k.a. DESL() in [MS-NLMP]
*
* Create an LM response from the given LM hash and challenge,
* or an NTLM repsonse from a given NTLM hash and challenge.
@@ -194,32 +198,103 @@ ntlm_put_v1_responses(struct smb_ctx *ctx,
return (err);
/*
- * Compute the LM response, derived
- * from the challenge and the ASCII
- * password (if authflags allow).
+ * Compute the NTLM response, derived from
+ * the challenge and the NT hash (a.k.a ResponseKeyNT)
+ */
+ err = mb_fit(nt_mbp, NTLM_V1_RESP_SZ, (char **)&ntresp);
+ if (err)
+ return (err);
+ bzero(ntresp, NTLM_V1_RESP_SZ);
+ err = ntlm_v1_response(ntresp, ctx->ct_nthash,
+ ctx->ct_srv_chal, NTLM_CHAL_SZ);
+
+ /*
+ * Compute the LM response, derived from
+ * the challenge and the ASCII password.
+ * Per. [MS-NLMP 3.3.1] if NoLmResponse,
+ * send the NT response for both NT+LM.
*/
err = mb_fit(lm_mbp, NTLM_V1_RESP_SZ, (char **)&lmresp);
if (err)
return (err);
- bzero(lmresp, NTLM_V1_RESP_SZ);
+ memcpy(lmresp, ntresp, NTLM_V1_RESP_SZ);
if (ctx->ct_authflags & SMB_AT_LM1) {
/* They asked to send the LM hash too. */
err = ntlm_v1_response(lmresp, ctx->ct_lmhash,
- ctx->ct_ntlm_chal, NTLM_CHAL_SZ);
+ ctx->ct_srv_chal, NTLM_CHAL_SZ);
if (err)
return (err);
}
/*
- * Compute the NTLM response, derived from
- * the challenge and the NT hash.
+ * Compute the session key
+ */
+ ntlm_v1_session_key(ctx->ct_ssn_key, ctx->ct_nthash);
+
+ return (err);
+}
+
+/*
+ * Compute both the LM(v1x) response and the NTLM(v1x) response,
+ * and put them in the mbdata chains passed. "v1x" here refers to
+ * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY used with NTLMSSP,
+ * also known by its shorter alias NTLMSSP_NEGOTIATE_NTLM2.
+ * [MS-NLMP 3.3.1]
+ *
+ * This allocates mbuf chains in the output args (caller frees).
+ */
+int
+ntlm_put_v1x_responses(struct smb_ctx *ctx,
+ struct mbdata *lm_mbp, struct mbdata *nt_mbp)
+{
+ MD5_CTX context;
+ uchar_t challenges[2 * NTLM_CHAL_SZ];
+ uchar_t digest[NTLM_HASH_SZ];
+ uchar_t *lmresp, *ntresp;
+ int err;
+
+ /* Get mbuf chain for the LM response. */
+ if ((err = mb_init_sz(lm_mbp, NTLM_V1_RESP_SZ)) != 0)
+ return (err);
+
+ /* Get mbuf chain for the NT response. */
+ if ((err = mb_init_sz(nt_mbp, NTLM_V1_RESP_SZ)) != 0)
+ return (err);
+
+ /*
+ * challenges = ConcatenationOf(ServerChallenge, ClientChallenge)
+ */
+ memcpy(challenges, ctx->ct_srv_chal, NTLM_CHAL_SZ);
+ memcpy(challenges + NTLM_CHAL_SZ, ctx->ct_clnonce, NTLM_CHAL_SZ);
+
+ /*
+ * digest = MD5(challenges)
+ */
+ MD5Init(&context);
+ MD5Update(&context, challenges, sizeof (challenges));
+ MD5Final(digest, &context);
+
+ /*
+ * Compute the NTLM response, derived from the
+ * NT hash (a.k.a ResponseKeyNT) and the first
+ * 8 bytes of the MD5 digest of the challenges.
*/
err = mb_fit(nt_mbp, NTLM_V1_RESP_SZ, (char **)&ntresp);
if (err)
return (err);
bzero(ntresp, NTLM_V1_RESP_SZ);
err = ntlm_v1_response(ntresp, ctx->ct_nthash,
- ctx->ct_ntlm_chal, NTLM_CHAL_SZ);
+ digest, NTLM_CHAL_SZ);
+
+ /*
+ * With "Extended Session Security", the LM response
+ * is simply the client challenge (nonce) padded out.
+ */
+ err = mb_fit(lm_mbp, NTLM_V1_RESP_SZ, (char **)&lmresp);
+ if (err)
+ return (err);
+ bzero(lmresp, NTLM_V1_RESP_SZ);
+ memcpy(lmresp, ctx->ct_clnonce, NTLM_CHAL_SZ);
/*
* Compute the session key
@@ -410,22 +485,22 @@ ntlm_put_v2_responses(struct smb_ctx *ctx, struct mbdata *ti_mbp,
uchar_t v2hash[NTLM_HASH_SZ];
struct mbuf *tim = ti_mbp->mb_top;
- if ((err = mb_init(lm_mbp)) != 0)
- return (err);
- if ((err = mb_init(nt_mbp)) != 0)
- return (err);
-
/*
* Convert the user name to upper-case, as
* that's what's used when computing LMv2
* and NTLMv2 responses. Note that the
* domain name is NOT upper-cased!
*/
+ if (ctx->ct_user[0] == '\0')
+ return (EINVAL);
ucuser = utf8_str_toupper(ctx->ct_user);
- if (ucuser == NULL) {
- err = ENOMEM;
+ if (ucuser == NULL)
+ return (ENOMEM);
+
+ if ((err = mb_init(lm_mbp)) != 0)
+ goto out;
+ if ((err = mb_init(nt_mbp)) != 0)
goto out;
- }
/*
* Compute the NTLMv2 hash
@@ -444,10 +519,9 @@ ntlm_put_v2_responses(struct smb_ctx *ctx, struct mbdata *ti_mbp,
* 1: 16-byte response hash
* 2: Client nonce
*/
- lmresp = (uchar_t *)lm_mbp->mb_pos;
- mb_put_mem(lm_mbp, NULL, NTLM_HASH_SZ, MB_MSYSTEM);
+ lmresp = mb_reserve(lm_mbp, NTLM_HASH_SZ);
err = ntlm_v2_resp_hash(lmresp,
- v2hash, ctx->ct_ntlm_chal,
+ v2hash, ctx->ct_srv_chal,
ctx->ct_clnonce, NTLM_CHAL_SZ);
if (err)
goto out;
@@ -462,10 +536,9 @@ ntlm_put_v2_responses(struct smb_ctx *ctx, struct mbdata *ti_mbp,
* 1: 16-byte response hash
* 2: "target info." blob
*/
- ntresp = (uchar_t *)nt_mbp->mb_pos;
- mb_put_mem(nt_mbp, NULL, NTLM_HASH_SZ, MB_MSYSTEM);
+ ntresp = mb_reserve(nt_mbp, NTLM_HASH_SZ);
err = ntlm_v2_resp_hash(ntresp,
- v2hash, ctx->ct_ntlm_chal,
+ v2hash, ctx->ct_srv_chal,
(uchar_t *)tim->m_data, tim->m_len);
if (err)
goto out;
@@ -533,14 +606,6 @@ ntlm_build_target_info(struct smb_ctx *ctx, struct mbuf *names,
return (err);
/*
- * Construct the client nonce by getting
- * some random data from /dev/urandom
- */
- err = smb_get_urandom(ctx->ct_clnonce, NTLM_CHAL_SZ);
- if (err)
- goto out;
-
- /*
* Get the "NT time" for the target info header.
*/
(void) gettimeofday(&now, 0);
@@ -583,3 +648,48 @@ out:
free(ucdom);
return (err);
}
+
+/*
+ * Build the MAC key (for SMB signing)
+ */
+int
+ntlm_build_mac_key(struct smb_ctx *ctx, struct mbdata *ntresp_mbp)
+{
+ struct mbuf *m;
+ size_t len;
+ char *p;
+
+ /*
+ * MAC_key = concat(session_key, nt_response)
+ */
+ m = ntresp_mbp->mb_top;
+ len = NTLM_HASH_SZ + m->m_len;
+ if ((p = malloc(len)) == NULL)
+ return (ENOMEM);
+ ctx->ct_mackeylen = len;
+ ctx->ct_mackey = p;
+ memcpy(p, ctx->ct_ssn_key, NTLM_HASH_SZ);
+ memcpy(p + NTLM_HASH_SZ, m->m_data, m->m_len);
+
+ return (0);
+}
+
+/*
+ * Helper for ntlmssp_put_type3 - Build the "key exchange key"
+ * used when we have both NTLM(v1) and NTLMSSP_NEGOTIATE_NTLM2.
+ * HMAC_MD5(SessionBaseKey, concat(ServerChallenge, LmResponse[0..7]))
+ */
+void
+ntlm2_kxkey(struct smb_ctx *ctx, struct mbdata *lm_mbp, uchar_t *kxkey)
+{
+ uchar_t data[NTLM_HASH_SZ];
+ uchar_t *p = mtod(lm_mbp->mb_top, uchar_t *);
+
+ /* concat(ServerChallenge, LmResponse[0..7]) */
+ memcpy(data, ctx->ct_srv_chal, NTLM_CHAL_SZ);
+ memcpy(data + NTLM_CHAL_SZ, p, NTLM_CHAL_SZ);
+
+ /* HMAC_MD5(SessionBaseKey, concat(...)) */
+ HMACT64(kxkey, ctx->ct_ssn_key, NTLM_HASH_SZ,
+ data, NTLM_HASH_SZ);
+}
diff --git a/usr/src/lib/libsmbfs/smb/ntlm.h b/usr/src/lib/libsmbfs/smb/ntlm.h
index e8eae559e9..447033b516 100644
--- a/usr/src/lib/libsmbfs/smb/ntlm.h
+++ b/usr/src/lib/libsmbfs/smb/ntlm.h
@@ -22,6 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _NTLM_H
@@ -59,7 +60,17 @@ ntlm_put_v1_responses(struct smb_ctx *ctx,
struct mbdata *lm_mbp, struct mbdata *nt_mbp);
int
+ntlm_put_v1x_responses(struct smb_ctx *ctx,
+ struct mbdata *lm_mbp, struct mbdata *nt_mbp);
+
+int
ntlm_put_v2_responses(struct smb_ctx *ctx, struct mbdata *ti_mbp,
struct mbdata *lm_mbp, struct mbdata *nt_mbp);
+int
+ntlm_build_mac_key(struct smb_ctx *ctx, struct mbdata *ntresp_mbp);
+
+void
+ntlm2_kxkey(struct smb_ctx *ctx, struct mbdata *lm_mbp, uchar_t *kxkey);
+
#endif /* _NTLM_H */
diff --git a/usr/src/lib/libsmbfs/smb/ntlmssp.c b/usr/src/lib/libsmbfs/smb/ntlmssp.c
index 5766ec835c..f39fa594ec 100644
--- a/usr/src/lib/libsmbfs/smb/ntlmssp.c
+++ b/usr/src/lib/libsmbfs/smb/ntlmssp.c
@@ -20,8 +20,8 @@
*/
/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -59,16 +59,22 @@
#include "private.h"
#include "charsets.h"
+#include "smb_crypt.h"
#include "spnego.h"
#include "derparse.h"
#include "ssp.h"
#include "ntlm.h"
#include "ntlmssp.h"
+/* A shorter alias for a crazy long name from [MS-NLMP] */
+#define NTLMSSP_NEGOTIATE_NTLM2 \
+ NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
+
typedef struct ntlmssp_state {
uint32_t ss_flags;
- char *ss_target_name;
+ char *ss_target_name; /* Primary domain or server name */
struct mbuf *ss_target_info;
+ uchar_t ss_kxkey[NTLM_HASH_SZ];
} ntlmssp_state_t;
/*
@@ -83,6 +89,10 @@ struct sec_buf {
#define ID_SZ 8
static const char ntlmssp_id[ID_SZ] = "NTLMSSP";
+static int
+ntlm_rand_ssn_key(struct smb_ctx *ctx,
+ ntlmssp_state_t *ssp_st, struct mbdata *ek_mbp);
+
/*
* Get a "security buffer" (header part)
*/
@@ -147,10 +157,12 @@ mb_put_sb_hdr(struct mbdata *mbp, struct sec_buf *sb)
static int
mb_put_sb_data(struct mbdata *mbp, struct sec_buf *sb, struct mbuf *m)
{
- int cnt0, err;
+ int cnt0;
+ int err = 0;
sb->sb_offset = cnt0 = mbp->mb_count;
- err = mb_put_mbuf(mbp, m);
+ if (m != NULL)
+ err = mb_put_mbuf(mbp, m);
sb->sb_maxlen = sb->sb_length = mbp->mb_count - cnt0;
return (err);
@@ -164,31 +176,35 @@ mb_put_sb_data(struct mbdata *mbp, struct sec_buf *sb, struct mbuf *m)
*/
static int
mb_put_sb_string(struct mbdata *mbp, struct sec_buf *sb,
- const char *s, int unicode)
+ const char *str, int unicode)
{
int err, trim;
struct mbdata tmp_mb;
- /*
- * Put the string into a temp. mbuf,
- * then chop off the null terminator
- * before appending to caller's mbp.
- */
- err = mb_init(&tmp_mb);
- if (err)
- return (err);
- err = mb_put_string(&tmp_mb, s, unicode);
- if (err)
- return (err);
+ bzero(&tmp_mb, sizeof (tmp_mb));
- trim = (unicode) ? 2 : 1;
- if (tmp_mb.mb_cur->m_len < trim)
- return (EFAULT);
- tmp_mb.mb_cur->m_len -= trim;
+ if (str != NULL && *str != '\0') {
+ /*
+ * Put the string into a temp. mbuf,
+ * then chop off the null terminator
+ * before appending to caller's mbp.
+ */
+ err = mb_init(&tmp_mb);
+ if (err)
+ return (err);
+ err = mb_put_string(&tmp_mb, str, unicode);
+ if (err)
+ return (err);
+
+ trim = (unicode) ? 2 : 1;
+ if (tmp_mb.mb_cur->m_len < trim)
+ trim = 0;
+ tmp_mb.mb_cur->m_len -= trim;
+ }
err = mb_put_sb_data(mbp, sb, tmp_mb.mb_top);
/*
- * Note: tmp_mb.mb_top is consumed,
+ * Note: tmp_mb.mb_top (if any) is consumed,
* so do NOT free it (no mb_done)
*/
return (err);
@@ -215,60 +231,47 @@ ntlmssp_put_type1(struct ssp_ctx *sp, struct mbdata *out_mb)
int err;
struct smb_ctx *ctx = sp->smb_ctx;
ntlmssp_state_t *ssp_st = sp->sp_private;
- char *ucdom = NULL;
- char *ucwks = NULL;
if ((err = mb_init(&mb2)) != 0)
return (err);
mb2.mb_count = sizeof (hdr);
/*
- * Initialize the negotiation flags, and
- * save what we sent. For reference:
- * [MS-NLMP] spec. (also ntlmssp.h)
+ * The initial negotiation flags represent the union of all
+ * options we support. The server selects from these.
+ * See: [MS-NLMP 2.2.2.5 NEGOTIATE]
*/
ssp_st->ss_flags =
+ NTLMSSP_NEGOTIATE_UNICODE |
+ NTLMSSP_NEGOTIATE_OEM |
NTLMSSP_REQUEST_TARGET |
+ NTLMSSP_NEGOTIATE_SIGN |
+ NTLMSSP_NEGOTIATE_SEAL |
+ /* NTLMSSP_NEGOTIATE_LM_KEY (never) */
NTLMSSP_NEGOTIATE_NTLM |
- NTLMSSP_NEGOTIATE_TARGET_INFO |
+ /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN (set below) */
+ NTLMSSP_NEGOTIATE_NTLM2 |
NTLMSSP_NEGOTIATE_128 |
+ NTLMSSP_NEGOTIATE_KEY_EXCH |
NTLMSSP_NEGOTIATE_56;
- if (ctx->ct_hflags2 & SMB_FLAGS2_UNICODE)
- ssp_st->ss_flags |= NTLMSSP_NEGOTIATE_UNICODE;
- else
- ssp_st->ss_flags |= NTLMSSP_NEGOTIATE_OEM;
-
if (ctx->ct_vcflags & SMBV_WILL_SIGN) {
ssp_st->ss_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
ctx->ct_hflags2 |= SMB_FLAGS2_SECURITY_SIGNATURE;
}
- if (ctx->ct_authflags & SMB_AT_NTLM2)
- ssp_st->ss_flags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY;
- if (ctx->ct_authflags & SMB_AT_NTLM1)
- ssp_st->ss_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
-
bcopy(ntlmssp_id, &hdr.h_id, ID_SZ);
- hdr.h_type = 1; /* Type 1 */
+ hdr.h_type = NTLMSSP_MSGTYPE_NEGOTIATE;
hdr.h_flags = ssp_st->ss_flags;
/*
- * Put the client domain, client name strings.
- * These are always in OEM format, upper-case.
+ * We could put the client domain, client name strings
+ * here, (always in OEM format, upper-case), and set
+ * NTLMSSP_NEGOTIATE_OEM_..._SUPPLIED, but Windows
+ * leaves these NULL so let's do the same.
*/
- ucdom = utf8_str_toupper(ctx->ct_domain);
- ucwks = utf8_str_toupper(ctx->ct_locname);
- if (ucdom == NULL || ucwks == NULL) {
- err = ENOMEM;
- goto out;
- }
- err = mb_put_sb_string(&mb2, &hdr.h_cldom, ucdom, 0);
- if (err)
- goto out;
- err = mb_put_sb_string(&mb2, &hdr.h_wksta, ucwks, 0);
- if (err)
- goto out;
+ (void) mb_put_sb_string(&mb2, &hdr.h_cldom, NULL, 0);
+ (void) mb_put_sb_string(&mb2, &hdr.h_wksta, NULL, 0);
/*
* Marshal the header (in LE order)
@@ -282,10 +285,6 @@ ntlmssp_put_type1(struct ssp_ctx *sp, struct mbdata *out_mb)
err = mb_put_mbuf(out_mb, mb2.mb_top);
-out:
- free(ucdom);
- free(ucwks);
-
return (err);
}
@@ -329,7 +328,7 @@ ntlmssp_get_type2(struct ssp_ctx *sp, struct mbdata *in_mb)
bzero(&hdr, sizeof (hdr));
(void) md_get_mem(in_mb, &hdr.h_id, ID_SZ, MB_MSYSTEM);
(void) md_get_uint32le(in_mb, &hdr.h_type);
- if (hdr.h_type != 2) {
+ if (hdr.h_type != NTLMSSP_MSGTYPE_CHALLENGE) {
err = EPROTO;
goto out;
}
@@ -338,11 +337,17 @@ ntlmssp_get_type2(struct ssp_ctx *sp, struct mbdata *in_mb)
(void) md_get_mem(in_mb, &hdr.h_challenge, NTLM_CHAL_SZ, MB_MSYSTEM);
/*
- * Save flags, challenge for later.
+ * Save flags, server challenge for later.
*/
ssp_st->ss_flags = hdr.h_flags;
+ bcopy(&hdr.h_challenge, ctx->ct_srv_chal, NTLM_CHAL_SZ);
+
+ /*
+ * Turn off flags that might have been given but
+ * that we don't want to send with authenticate.
+ */
uc = hdr.h_flags & NTLMSSP_NEGOTIATE_UNICODE;
- bcopy(&hdr.h_challenge, ctx->ct_ntlm_chal, NTLM_CHAL_SZ);
+ ssp_st->ss_flags &= ~NTLMSSP_NEGOTIATE_VERSION;
/*
* Now find out if the optional parts are there.
@@ -355,8 +360,9 @@ ntlmssp_get_type2(struct ssp_ctx *sp, struct mbdata *in_mb)
}
/*
- * Get the target name string. First get a copy of
- * the data from the offset/length indicated in the
+ * Get the target name string. (Server name or
+ * Primary domain name.) First get a copy of the
+ * data from the offset/length indicated in the
* security buffer header; then parse the string.
*/
err = md_get_sb_data(&top_mb, &hdr.h_target_name, &m);
@@ -401,19 +407,24 @@ ntlmssp_put_type3(struct ssp_ctx *sp, struct mbdata *out_mb)
struct sec_buf h_wksta;
struct sec_buf h_ssn_key;
uint32_t h_flags;
+ /* Version struct (ommitted) */
+ uchar_t h_mic[NTLM_HASH_SZ];
} hdr;
struct mbdata lm_mbc; /* LM response */
struct mbdata nt_mbc; /* NT response */
struct mbdata ti_mbc; /* target info */
+ struct mbdata ek_mbc; /* encrypted session key */
struct mbdata mb2; /* payload */
int err, uc;
struct smb_ctx *ctx = sp->smb_ctx;
ntlmssp_state_t *ssp_st = sp->sp_private;
+ uchar_t *pmic;
bzero(&hdr, sizeof (hdr));
bzero(&lm_mbc, sizeof (lm_mbc));
bzero(&nt_mbc, sizeof (nt_mbc));
bzero(&ti_mbc, sizeof (ti_mbc));
+ bzero(&ek_mbc, sizeof (ek_mbc));
bzero(&mb2, sizeof (mb2));
/*
@@ -425,27 +436,78 @@ ntlmssp_put_type3(struct ssp_ctx *sp, struct mbdata *out_mb)
uc = ssp_st->ss_flags & NTLMSSP_NEGOTIATE_UNICODE;
bcopy(ntlmssp_id, &hdr.h_id, ID_SZ);
- hdr.h_type = 3; /* Type 3 */
+ hdr.h_type = NTLMSSP_MSGTYPE_AUTHENTICATE;
hdr.h_flags = ssp_st->ss_flags;
/*
- * Put the LMv2,NTLMv2 responses, or
- * possibly LM, NTLM (v1) responses.
+ * Put the NTLMv2/LMv2 or NTLM/LM (v1) responses,
+ * and compute the session key, etc.
*/
- if (ctx->ct_authflags & SMB_AT_NTLM2) {
- /* Build the NTLMv2 "target info" blob. */
+ if (ctx->ct_authflags & SMB_AT_ANON) {
+ /*
+ * We're setting up a NULL session, meaning
+ * the lm_mbc, nt_mbc parts remain empty.
+ * Let's add the "anon" flag (hint).
+ * As there is no session key, disable the
+ * fancy session key stuff.
+ */
+ hdr.h_flags |= NTLMSSP_NEGOTIATE_NULL_SESSION;
+ ssp_st->ss_flags &= ~(
+ NTLMSSP_NEGOTIATE_NTLM2 |
+ NTLMSSP_NEGOTIATE_KEY_EXCH);
+ err = 0;
+ } else if (ctx->ct_authflags & SMB_AT_NTLM2) {
+ /*
+ * Doing NTLMv2/LMv2
+ */
err = ntlm_build_target_info(ctx,
ssp_st->ss_target_info, &ti_mbc);
if (err)
goto out;
err = ntlm_put_v2_responses(ctx, &ti_mbc,
&lm_mbc, &nt_mbc);
+ if (err)
+ goto out;
+ /* The "key exg. key" is the session base key */
+ memcpy(ssp_st->ss_kxkey, ctx->ct_ssn_key, NTLM_HASH_SZ);
+
+ } else if (ssp_st->ss_flags & NTLMSSP_NEGOTIATE_NTLM2) {
+ /*
+ * Doing NTLM ("v1x") which is NTLM with
+ * "Extended Session Security"
+ */
+ err = ntlm_put_v1x_responses(ctx,
+ &lm_mbc, &nt_mbc);
+ if (err)
+ goto out;
+ /* Compute the "Key exchange key". */
+ ntlm2_kxkey(ctx, &lm_mbc, ssp_st->ss_kxkey);
} else {
+ /*
+ * Doing plain old NTLM (and LM if enabled)
+ */
err = ntlm_put_v1_responses(ctx,
&lm_mbc, &nt_mbc);
+ if (err)
+ goto out;
+ /* The "key exg. key" is the session base key */
+ memcpy(ssp_st->ss_kxkey, ctx->ct_ssn_key, NTLM_HASH_SZ);
+ }
+
+ /*
+ * Compute the "Exported Session Key" and (possibly)
+ * the "Encrypted Random Sesion Key".
+ * [MS-NLMP 3.1.5.1.2]
+ */
+ if (ssp_st->ss_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
+ err = ntlm_rand_ssn_key(ctx, ssp_st, &ek_mbc);
+ if (err)
+ goto out;
+ } else {
+ /* ExportedSessionKey is the KeyExchangeKey */
+ memcpy(ctx->ct_ssn_key, ssp_st->ss_kxkey, NTLM_HASH_SZ);
+ /* EncryptedRandomSessionKey remains NULL */
}
- if (err)
- goto out;
err = mb_put_sb_data(&mb2, &hdr.h_lm_resp, lm_mbc.mb_top);
lm_mbc.mb_top = NULL; /* consumed */
@@ -470,12 +532,13 @@ ntlmssp_put_type3(struct ssp_ctx *sp, struct mbdata *out_mb)
goto out;
/*
- * Put the "Random Session Key". We don't set
- * NTLMSSP_NEGOTIATE_KEY_EXCH, so it's empty.
- * (In-line mb_put_sb_data here.)
+ * Put the "Encrypted Random Session Key", if any.
+ * (ek_mbc.mb_top may be NULL)
*/
- hdr.h_ssn_key.sb_maxlen = hdr.h_ssn_key.sb_length = 0;
- hdr.h_ssn_key.sb_offset = mb2.mb_count;
+ err = mb_put_sb_data(&mb2, &hdr.h_ssn_key, ek_mbc.mb_top);
+ ek_mbc.mb_top = NULL; /* consumed (if any) */
+ if (err)
+ goto out;
/*
* Marshal the header (in LE order)
@@ -494,14 +557,58 @@ ntlmssp_put_type3(struct ssp_ctx *sp, struct mbdata *out_mb)
(void) mb_put_sb_hdr(out_mb, &hdr.h_ssn_key);
(void) mb_put_uint32le(out_mb, hdr.h_flags);
+ /* Put zeros for the MIC - filled in later */
+ pmic = mb_reserve(out_mb, NTLM_HASH_SZ);
+
+ /* Put the payload. */
err = mb_put_mbuf(out_mb, mb2.mb_top);
mb2.mb_top = NULL; /* consumed */
+ /*
+ * Compute the MIC and stuff that in...
+ * The MIC is apparently optional.
+ */
+ (void) pmic;
+
out:
mb_done(&mb2);
mb_done(&lm_mbc);
mb_done(&nt_mbc);
mb_done(&ti_mbc);
+ mb_done(&ek_mbc);
+
+ return (err);
+}
+
+/*
+ * Helper for ntlmssp_put_type3 when doing key exchange.
+ *
+ * "ExportedSessionKey" is what we give to the "application"
+ * layer, which in here means the MAC key for SMB signing.
+ * With "key exchange", we replace the ExportedSessionKey
+ * with random data and send that (encrypted) to the peer.
+ */
+static int
+ntlm_rand_ssn_key(
+ struct smb_ctx *ctx,
+ ntlmssp_state_t *ssp_st,
+ struct mbdata *ek_mbp)
+{
+
+ uchar_t *encr_ssn_key;
+ int err;
+
+ if ((err = mb_init(ek_mbp)) != 0)
+ return (err);
+ encr_ssn_key = mb_reserve(ek_mbp, NTLM_HASH_SZ);
+
+ /* Set "ExportedSessionKey to NONCE(16) */
+ (void) smb_get_urandom(ctx->ct_ssn_key, NTLM_HASH_SZ);
+
+ /* Set "EncryptedRandomSessionKey" to RC4(...) */
+ err = smb_encrypt_RC4(encr_ssn_key, NTLM_HASH_SZ,
+ ssp_st->ss_kxkey, NTLM_HASH_SZ,
+ ctx->ct_ssn_key, NTLM_HASH_SZ);
return (err);
}
@@ -623,9 +730,9 @@ ntlmssp_init_client(struct ssp_ctx *sp)
ntlmssp_state_t *ssp_st;
if ((sp->smb_ctx->ct_authflags &
- (SMB_AT_NTLM2 | SMB_AT_NTLM1)) == 0) {
+ (SMB_AT_NTLM2 | SMB_AT_NTLM1 | SMB_AT_ANON)) == 0) {
DPRINT("No NTLM authflags");
- return (ENOTSUP);
+ return (EINVAL);
}
ssp_st = calloc(1, sizeof (*ssp_st));
diff --git a/usr/src/lib/libsmbfs/smb/ntlmssp.h b/usr/src/lib/libsmbfs/smb/ntlmssp.h
index 591b1ab088..5f3e09ac0d 100644
--- a/usr/src/lib/libsmbfs/smb/ntlmssp.h
+++ b/usr/src/lib/libsmbfs/smb/ntlmssp.h
@@ -22,6 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _NTLMSSP_H
@@ -37,6 +38,14 @@
*/
/*
+ * NTLMSSP Message Types
+ * [MS-NLMP] sec. 2.2.1
+ */
+#define NTLMSSP_MSGTYPE_NEGOTIATE 1
+#define NTLMSSP_MSGTYPE_CHALLENGE 2
+#define NTLMSSP_MSGTYPE_AUTHENTICATE 3
+
+/*
* NTLMSSP Negotiate Flags
* [MS-NLMP] sec. 2.2.2.5
*/
@@ -48,13 +57,13 @@
#define NTLMSSP_NEGOTIATE_SEAL 0x00000020
#define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040
#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
-/* reserved 0x00000100 */
+/* reserved (netware) 0x00000100 */
#define NTLMSSP_NEGOTIATE_NTLM 0x00000200
#define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400
-/* old anonymous_session (ignored by servers) 0x00000800 */
+#define NTLMSSP_NEGOTIATE_NULL_SESSION 0x00000800
#define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000
#define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000
-/* reserved 0x00004000 */
+/* reserved (local caller) 0x00004000 */
#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
#define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000
#define NTLMSSP_TARGET_TYPE_SERVER 0x00020000
diff --git a/usr/src/lib/libsmbfs/smb/smb_crypt.h b/usr/src/lib/libsmbfs/smb/smb_crypt.h
index 15005ddab6..a3ebd69e22 100644
--- a/usr/src/lib/libsmbfs/smb/smb_crypt.h
+++ b/usr/src/lib/libsmbfs/smb/smb_crypt.h
@@ -33,17 +33,36 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
+#ifndef _SMB_CRYPT_H
+#define _SMB_CRYPT_H
+
/*
* Various crypto stuff.
* from the driver: smb_crypt.c
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int
smb_encrypt_DES(uchar_t *Result, int ResultLen,
const uchar_t *Key, int KeyLen,
const uchar_t *Data, int DataLen);
int
+smb_encrypt_RC4(uchar_t *Result, int ResultLen,
+ const uchar_t *Key, int KeyLen,
+ const uchar_t *Data, int DataLen);
+
+int
smb_get_urandom(void *data, size_t dlen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SMB_CRYPT_H */
diff --git a/usr/src/lib/libsmbfs/smb/ssnsetup.c b/usr/src/lib/libsmbfs/smb/ssnsetup.c
index 03f92dc62c..68e7ce1337 100644
--- a/usr/src/lib/libsmbfs/smb/ssnsetup.c
+++ b/usr/src/lib/libsmbfs/smb/ssnsetup.c
@@ -32,11 +32,11 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
* SMB Session Setup, and related.
- * Copied from the driver: smb_smb.c
*/
#include <errno.h>
@@ -88,7 +88,7 @@ smb_ssnsetup_null(struct smb_ctx *ctx)
uint32_t ntstatus;
uint16_t action = 0;
- if (ctx->ct_sopt.sv_caps & SMB_CAP_EXT_SECURITY) {
+ if (ctx->ct_clnt_caps & SMB_CAP_EXT_SECURITY) {
/* Should not get here with... */
err = EINVAL;
goto out;
@@ -118,7 +118,7 @@ smb_ssnsetup_ntlm1(struct smb_ctx *ctx)
uint32_t ntstatus;
uint16_t action = 0;
- if (ctx->ct_sopt.sv_caps & SMB_CAP_EXT_SECURITY) {
+ if (ctx->ct_clnt_caps & SMB_CAP_EXT_SECURITY) {
/* Should not get here with... */
err = EINVAL;
goto out;
@@ -133,30 +133,11 @@ smb_ssnsetup_ntlm1(struct smb_ctx *ctx)
if (err)
goto out;
- /*
- * If we negotiated signing, compute the MAC key
- * and start signing messages, but only on the
- * first non-null session login.
- */
- if ((ctx->ct_vcflags & SMBV_WILL_SIGN) &&
+ if ((ctx->ct_vcflags & SMBV_WILL_SIGN) != 0 &&
(ctx->ct_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE) == 0) {
- struct mbuf *m = nt_mbc.mb_top;
- char *p;
-
- /*
- * MAC_key = concat(session_key, nt_response)
- */
- ctx->ct_mackeylen = NTLM_HASH_SZ + m->m_len;
- ctx->ct_mackey = malloc(ctx->ct_mackeylen);
- if (ctx->ct_mackey == NULL) {
- ctx->ct_mackeylen = 0;
- err = ENOMEM;
+ err = ntlm_build_mac_key(ctx, &nt_mbc);
+ if (err)
goto out;
- }
- p = ctx->ct_mackey;
- memcpy(p, ctx->ct_ssn_key, NTLM_HASH_SZ);
- memcpy(p + NTLM_HASH_SZ, m->m_data, m->m_len);
-
/* OK, start signing! */
ctx->ct_hflags2 |= SMB_FLAGS2_SECURITY_SIGNATURE;
}
@@ -187,7 +168,7 @@ smb_ssnsetup_ntlm2(struct smb_ctx *ctx)
uint32_t ntstatus;
uint16_t action = 0;
- if (ctx->ct_sopt.sv_caps & SMB_CAP_EXT_SECURITY) {
+ if (ctx->ct_clnt_caps & SMB_CAP_EXT_SECURITY) {
/* Should not get here with... */
err = EINVAL;
goto out;
@@ -208,30 +189,11 @@ smb_ssnsetup_ntlm2(struct smb_ctx *ctx)
if (err)
goto out;
- /*
- * If we negotiated signing, compute the MAC key
- * and start signing messages, but only on the
- * first non-null session login.
- */
- if ((ctx->ct_vcflags & SMBV_WILL_SIGN) &&
+ if ((ctx->ct_vcflags & SMBV_WILL_SIGN) != 0 &&
(ctx->ct_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE) == 0) {
- struct mbuf *m = nt_mbc.mb_top;
- char *p;
-
- /*
- * MAC_key = concat(session_key, nt_response)
- */
- ctx->ct_mackeylen = NTLM_HASH_SZ + m->m_len;
- ctx->ct_mackey = malloc(ctx->ct_mackeylen);
- if (ctx->ct_mackey == NULL) {
- ctx->ct_mackeylen = 0;
- err = ENOMEM;
+ err = ntlm_build_mac_key(ctx, &nt_mbc);
+ if (err)
goto out;
- }
- p = ctx->ct_mackey;
- memcpy(p, ctx->ct_ssn_key, NTLM_HASH_SZ);
- memcpy(p + NTLM_HASH_SZ, m->m_data, m->m_len);
-
/* OK, start signing! */
ctx->ct_hflags2 |= SMB_FLAGS2_SECURITY_SIGNATURE;
}
@@ -334,20 +296,7 @@ smb__ssnsetup(struct smb_ctx *ctx,
uint16_t bc, len1, len2, sblen;
uint8_t wc;
- /*
- * Some of the "capability" bits we offer will be copied
- * from those offered by the server, with a mask applied.
- * This is the mask of capabilies copied from the server.
- * Some others get special handling below.
- */
- static const uint32_t caps_mask =
- SMB_CAP_UNICODE |
- SMB_CAP_LARGE_FILES |
- SMB_CAP_NT_SMBS |
- SMB_CAP_STATUS32 |
- SMB_CAP_EXT_SECURITY;
-
- caps = ctx->ct_sopt.sv_caps & caps_mask;
+ caps = ctx->ct_clnt_caps;
uc = ctx->ct_hflags2 & SMB_FLAGS2_UNICODE;
err = smb_rq_init(ctx, SMB_COM_SESSION_SETUP_ANDX, &rqp);
diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
index 7b7f222d2d..63f2543780 100644
--- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
@@ -19,7 +19,7 @@
#
#
# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
#
#
@@ -79,7 +79,6 @@ SYMBOL_VERSION SUNWprivate {
smb_auth_ntlm_hash;
smb_auth_ntlmv2_hash;
smb_auth_qnd_unicode;
- smb_auth_set_info;
smb_auth_validate_lm;
smb_auth_validate_nt;
smb_buf32_xdr;
diff --git a/usr/src/man/man3c/Makefile b/usr/src/man/man3c/Makefile
index 17be98f410..bb75c1d4b6 100644
--- a/usr/src/man/man3c/Makefile
+++ b/usr/src/man/man3c/Makefile
@@ -482,7 +482,7 @@ MANFILES= __fbufsize.3c \
u8_validate.3c \
ualarm.3c \
uconv_u16tou32.3c \
- ucred_get.3c \
+ ucred.3c \
ungetc.3c \
ungetwc.3c \
unlockpt.3c \
@@ -1198,6 +1198,7 @@ MANLINKS= FD_CLR.3c \
uconv_u8tou16.3c \
uconv_u8tou32.3c \
ucred_free.3c \
+ ucred_get.3c \
ucred_getegid.3c \
ucred_geteuid.3c \
ucred_getgroups.3c \
@@ -2212,21 +2213,22 @@ uconv_u32tou8.3c := LINKSRC = uconv_u16tou32.3c
uconv_u8tou16.3c := LINKSRC = uconv_u16tou32.3c
uconv_u8tou32.3c := LINKSRC = uconv_u16tou32.3c
-ucred_free.3c := LINKSRC = ucred_get.3c
-ucred_getegid.3c := LINKSRC = ucred_get.3c
-ucred_geteuid.3c := LINKSRC = ucred_get.3c
-ucred_getgroups.3c := LINKSRC = ucred_get.3c
-ucred_getlabel.3c := LINKSRC = ucred_get.3c
-ucred_getpflags.3c := LINKSRC = ucred_get.3c
-ucred_getpid.3c := LINKSRC = ucred_get.3c
-ucred_getprivset.3c := LINKSRC = ucred_get.3c
-ucred_getprojid.3c := LINKSRC = ucred_get.3c
-ucred_getrgid.3c := LINKSRC = ucred_get.3c
-ucred_getruid.3c := LINKSRC = ucred_get.3c
-ucred_getsgid.3c := LINKSRC = ucred_get.3c
-ucred_getsuid.3c := LINKSRC = ucred_get.3c
-ucred_getzoneid.3c := LINKSRC = ucred_get.3c
-ucred_size.3c := LINKSRC = ucred_get.3c
+ucred_free.3c := LINKSRC = ucred.3c
+ucred_get.3c := LINKSRC = ucred.3c
+ucred_getegid.3c := LINKSRC = ucred.3c
+ucred_geteuid.3c := LINKSRC = ucred.3c
+ucred_getgroups.3c := LINKSRC = ucred.3c
+ucred_getlabel.3c := LINKSRC = ucred.3c
+ucred_getpflags.3c := LINKSRC = ucred.3c
+ucred_getpid.3c := LINKSRC = ucred.3c
+ucred_getprivset.3c := LINKSRC = ucred.3c
+ucred_getprojid.3c := LINKSRC = ucred.3c
+ucred_getrgid.3c := LINKSRC = ucred.3c
+ucred_getruid.3c := LINKSRC = ucred.3c
+ucred_getsgid.3c := LINKSRC = ucred.3c
+ucred_getsuid.3c := LINKSRC = ucred.3c
+ucred_getzoneid.3c := LINKSRC = ucred.3c
+ucred_size.3c := LINKSRC = ucred.3c
vswprintf.3c := LINKSRC = vfwprintf.3c
vwprintf.3c := LINKSRC = vfwprintf.3c
diff --git a/usr/src/man/man3c/ucred_get.3c b/usr/src/man/man3c/ucred.3c
index 9123e91dec..9333e8b0e6 100644
--- a/usr/src/man/man3c/ucred_get.3c
+++ b/usr/src/man/man3c/ucred.3c
@@ -3,9 +3,9 @@
.\" 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]
-.TH UCRED_GET 3C "Apr 4, 2008"
+.TH UCRED 3C "Nov 6, 2014"
.SH NAME
-ucred_get, ucred_free, ucred_geteuid, ucred_getruid, ucred_getsuid,
+ucred, ucred_get, ucred_free, ucred_geteuid, ucred_getruid, ucred_getsuid,
ucred_getegid, ucred_getrgid, ucred_getsgid, ucred_getgroups, ucred_getprivset,
ucred_getpid, ucred_getprojid, ucred_getzoneid, ucred_getpflags,
ucred_getlabel, ucred_size \- user credential functions
@@ -94,7 +94,6 @@ ucred_getlabel, ucred_size \- user credential functions
.fi
.SH DESCRIPTION
-.sp
.LP
These functions return or act on a user credential, \fBucred_t\fR. User
credentials are returned by various functions and describe the credentials of a
@@ -169,11 +168,9 @@ is constant only until the next boot, at which time it could change. The
needed to receive a credential option with \fBSO_RECVUCRED\fR. See
\fBsocket.h\fR(3HEAD).
.SH RETURN VALUES
-.sp
.LP
See DESCRIPTION.
.SH ERRORS
-.sp
.LP
The \fBucred_get()\fR function will fail if:
.sp
@@ -269,7 +266,6 @@ credential.
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -287,7 +283,6 @@ MT-Level MT-Safe
.TE
.SH SEE ALSO
-.sp
.LP
\fBgetpflags\fR(2), \fBgetppriv\fR(2), \fBdoor_ucred\fR(3C),
\fBgetpeerucred\fR(3C), \fBpriv_set\fR(3C), \fBsocket.h\fR(3HEAD),
diff --git a/usr/src/pkg/manifests/system-library.man3c.inc b/usr/src/pkg/manifests/system-library.man3c.inc
index 8b32d6af19..8e0c16eefb 100644
--- a/usr/src/pkg/manifests/system-library.man3c.inc
+++ b/usr/src/pkg/manifests/system-library.man3c.inc
@@ -471,7 +471,7 @@ file path=usr/share/man/man3c/u8_textprep_str.3c
file path=usr/share/man/man3c/u8_validate.3c
file path=usr/share/man/man3c/ualarm.3c
file path=usr/share/man/man3c/uconv_u16tou32.3c
-file path=usr/share/man/man3c/ucred_get.3c
+file path=usr/share/man/man3c/ucred.3c
file path=usr/share/man/man3c/ungetc.3c
file path=usr/share/man/man3c/ungetwc.3c
file path=usr/share/man/man3c/unlockpt.3c
@@ -1258,21 +1258,22 @@ link path=usr/share/man/man3c/uconv_u32tou16.3c target=uconv_u16tou32.3c
link path=usr/share/man/man3c/uconv_u32tou8.3c target=uconv_u16tou32.3c
link path=usr/share/man/man3c/uconv_u8tou16.3c target=uconv_u16tou32.3c
link path=usr/share/man/man3c/uconv_u8tou32.3c target=uconv_u16tou32.3c
-link path=usr/share/man/man3c/ucred_free.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getegid.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_geteuid.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getgroups.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getlabel.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getpflags.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getpid.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getprivset.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getprojid.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getrgid.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getruid.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getsgid.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getsuid.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_getzoneid.3c target=ucred_get.3c
-link path=usr/share/man/man3c/ucred_size.3c target=ucred_get.3c
+link path=usr/share/man/man3c/ucred_free.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_get.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getegid.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_geteuid.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getgroups.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getlabel.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getpflags.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getpid.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getprivset.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getprojid.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getrgid.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getruid.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getsgid.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getsuid.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_getzoneid.3c target=ucred.3c
+link path=usr/share/man/man3c/ucred_size.3c target=ucred.3c
link path=usr/share/man/man3c/ulckpwdf.3c target=lckpwdf.3c
link path=usr/share/man/man3c/ulltostr.3c target=strtol.3c
link path=usr/share/man/man3c/unordered.3c target=isnand.3c
diff --git a/usr/src/tools/ctf/cvt/ctftools.h b/usr/src/tools/ctf/cvt/ctftools.h
index f586236ccf..fd9d454e06 100644
--- a/usr/src/tools/ctf/cvt/ctftools.h
+++ b/usr/src/tools/ctf/cvt/ctftools.h
@@ -37,6 +37,8 @@
#include <gelf.h>
#include <pthread.h>
+#include <sys/ccompile.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -443,8 +445,8 @@ int streq(const char *, const char *);
int findelfsecidx(Elf *, const char *, const char *);
size_t elf_ptrsz(Elf *);
char *mktmpname(const char *, const char *);
-void terminate(char *, ...);
-void aborterr(char *, ...);
+void terminate(char *, ...) __NORETURN;
+void aborterr(char *, ...) __NORETURN;
void set_terminate_cleanup(void (*)());
void elfterminate(const char *, const char *, ...);
void warning(char *, ...);